ci: add acceptance test

This commit is contained in:
2019-09-20 00:23:56 +02:00
parent d4e8f34b0f
commit f707ddcf23
11 changed files with 225 additions and 70 deletions

View File

@@ -22,3 +22,6 @@ jobs:
- name: Testing
run: go test ./...
- name: Acceptance test
run: make

27
Dockerfile Normal file
View File

@@ -0,0 +1,27 @@
FROM golang:1.12-alpine as builder
# Remove the cache to avoid warning message during `apk info`
RUN rm -rf /var/cache/apk/* && \
rm -rf /tmp/*
RUN apk update
# GO and PATH env variables already set in golang image
# to reduce download time
RUN apk --no-cache add -U make git musl-dev gcc
COPY . .
RUN GO111MODULE=on make local-build
# final stage
FROM alpine:3.7
RUN apk --no-cache add ca-certificates
WORKDIR /app
COPY --from=builder /go/bin/HamsterTycoon .
EXPOSE 8080
ENTRYPOINT ["/app/HamsterTycoon"]
CMD ["serve", "--logformat", "json", "--loglevel", "debug"]

105
Makefile Normal file
View File

@@ -0,0 +1,105 @@
# Set an output prefix, which is the local directory if not specified
PREFIX?=$(shell pwd)
.DEFAULT_GOAL := build
# Version tag
VERSION := 1.0
# Setup name variables for the package/tool
NAME := hamster-tycoon
BIN_NAME := HamsterTycoon
PKG := github.com/kratisto/hamster-tycoon
DOCKER_IMAGE_NAME := $(NAME)
# GO env vars
ifeq ($(GOPATH),)
GOPATH:=~/go
endif
GO=$(firstword $(subst :, ,$(GOPATH)))
.PHONY: ensure-vendor
ensure-vendor: ## Get all vendor dependencies
@echo "+ $@"
dep ensure
.PHONY: update-vendor
update-vendor: ## Get all vendor dependencies
@echo "+ $@"
dep ensure -update
.PHONY: clean
clean: local-clean ## Clean your generated files
@echo "+ $@"
docker image rm poketools:$(VERSION) || true
.PHONY: local-build
local-build: local-clean local-format ## Build locally the binary
@echo "+ $@"
GO111MODULE=on go build -o $(GO)/bin/$(BIN_NAME) .
.PHONY: local-clean
local-clean: ## Cleanup locally any build binaries or packages
@echo "+ $@"
@$(RM) $(BIN_NAME)
.PHONY: local-format
local-format: ## format locally all files
@echo "+ $@"
gofmt -s -l -w .
.PHONY: build
build: sources-image ## Build the docker image with application binary
@echo "+ $@"
docker build --no-cache \
-f containers/Dockerfile \
--build-arg SOURCES_IMAGE=$(NAME)-sources:$(VERSION) \
-t poketools:$(VERSION) .
GIT_CREDENTIALS?=$(shell cat ~/.git-credentials 2> /dev/null)
.PHONY: sources-image
sources-image: ## Generate a Docker image with only the sources
@echo "+ $@"
docker build -t $(NAME)-sources:$(VERSION) -f containers/Dockerfile.sources .
.PHONY: local-run-dependencies
local-run-dependencies: ## Run the dependencies of the server (launch the containers/docker-compose.local.yml)
@echo "+ $@"
@docker-compose -p $(DOCKER_IMAGE_NAME)-uuid -f containers/docker-compose.local.yml down || true;
@docker-compose -p $(DOCKER_IMAGE_NAME)-uuid -f containers/docker-compose.local.yml pull;
@docker-compose -p $(DOCKER_IMAGE_NAME)-uuid -f containers/docker-compose.local.yml up -d --build
.PHONY: local-run-golang
local-run-golang: ## Build the server and run it
@echo "+ $@"
BUILD_GOLANG_CMD=local-build \
LAUNCH_GOLANG_CMD="$(GO)/bin/$(BIN_NAME)" \
$(MAKE) local-launch-golang
.PHONY: local-launch-golang
local-launch-golang: ## Build the server and run it
@echo "+ $@"
PID=`ps -ax | egrep "\b$(BIN_NAME)"| cut -d " " -f 1`; \
kill $$PID || true
$(MAKE) $(BUILD_GOLANG_CMD)
DB_PORT=`docker-compose -p $(DOCKER_IMAGE_NAME)-uuid -f containers/docker-compose.local.yml port database 5432 | cut -f2 -d':'`; \
$(LAUNCH_GOLANG_CMD) serve --loglevel debug --logformat text --postgreshost localhost:$$DB_PORT
.PHONY: local-run
local-run: local-run-dependencies local-run-golang ## Run the server with its dependencies
.PHONY: local-run-app
local-run-app: ## Run the app of the server (launch the containers/docker-compose.yml)
@echo "+ $@"
@docker-compose -p $(DOCKER_IMAGE_NAME)-uuid -f containers/docker-compose.yml down || true;
@docker-compose -p $(DOCKER_IMAGE_NAME)-uuid -f containers/docker-compose.yml pull;
@docker-compose -p $(DOCKER_IMAGE_NAME)-uuid -f containers/docker-compose.yml up -d --build
.PHONY: bdd-test
bdd-test: local-run-app
go get github.com/DATA-DOG/godog/cmd/godog
DB_PORT=`docker-compose -p $(DOCKER_IMAGE_NAME)-uuid -f containers/docker-compose.yml port database 5432 | cut -f2 -d':'`;
API_PORT=`docker-compose -p $(DOCKER_IMAGE_NAME)-uuid -f containers/docker-compose.yml port api 8080 | cut -f2 -d':'`;
$GOPATH/bin/godog

View File

@@ -0,0 +1,8 @@
version: "2.1"
services:
api:
build: ../.
ports:
- 8080

2
go.mod
View File

@@ -1,3 +1,5 @@
module hamster-tycoon
go 1.13
require github.com/DATA-DOG/godog v0.7.13

2
go.sum Normal file
View File

@@ -0,0 +1,2 @@
github.com/DATA-DOG/godog v0.7.13 h1:JmgpKcra7Vf3yzI9vPsWyoQRx13tyKziHtXWDCUUgok=
github.com/DATA-DOG/godog v0.7.13/go.mod h1:z2OZ6a3X0/YAKVqLfVzYBwFt3j6uSt3Xrqa7XTtcQE0=

View File

@@ -1,6 +1,5 @@
package hamster_tycoon
type Cage struct {
Hamsters []*Hamster
}

View File

@@ -1,8 +1,6 @@
package hamster_tycoon
type Game struct {
Cages []*Cage
Cages []*Cage
SelledHamster []*Hamster
}

View File

@@ -15,44 +15,43 @@ const (
)
const (
TotalGestationPeriod = 15
MinChild = 5
MaxCild = 9
GestationCooldown = (3*7) + 2
GestationMinAge = 10*6
MaxAge = 365*2
GestationLuck = 70
FEMALE = "F"
MALE = "M"
TotalGestationPeriod = 15
MinChild = 5
MaxCild = 9
GestationCooldown = (3 * 7) + 2
GestationMinAge = 10 * 6
MaxAge = 365 * 2
GestationLuck = 70
FEMALE = "F"
MALE = "M"
)
var GlobalHamsterNumber = 1
type Hamster struct {
Name string
Number int
Sexe string
Age int
Father *Hamster
Mother *Hamster
HungerLevel int8
ThirstLevel int8
Weight float64
Height float64
Alive bool
Selled bool
Gestation bool
GestationPeriod int8
Name string
Number int
Sexe string
Age int
Father *Hamster
Mother *Hamster
HungerLevel int8
ThirstLevel int8
Weight float64
Height float64
Alive bool
Selled bool
Gestation bool
GestationPeriod int8
GestationCooldown int8
Child []*Hamster
Child []*Hamster
}
func(h *Hamster) Die(){
func (h *Hamster) Die() {
h.Alive = false
}
func (h *Hamster) Fuck(another *Hamster) (bool,error){
func (h *Hamster) Fuck(another *Hamster) (bool, error) {
if h.Sexe == another.Sexe {
return false, errors.New("can't fuck together")
}
@@ -61,10 +60,16 @@ func (h *Hamster) Fuck(another *Hamster) (bool,error){
return false, errors.New("one of the hamster is too young")
}
rand := randNumber(1,100)
rand := randNumber(1, 100)
if rand <= GestationLuck {
female := func() *Hamster{if h.Sexe == FEMALE {return h } else {return another}}()
female := func() *Hamster {
if h.Sexe == FEMALE {
return h
} else {
return another
}
}()
female.Gestation = true
female.GestationPeriod = 0
female.GestationCooldown = TotalGestationPeriod + GestationCooldown
@@ -72,7 +77,7 @@ func (h *Hamster) Fuck(another *Hamster) (bool,error){
return rand <= GestationLuck, nil
}
func Born(father *Hamster, mother *Hamster)([]*Hamster,error){
func Born(father *Hamster, mother *Hamster) ([]*Hamster, error) {
if !mother.Alive || mother.Selled {
return nil, errors.New("the mother is not here")
}
@@ -85,43 +90,43 @@ func Born(father *Hamster, mother *Hamster)([]*Hamster,error){
mother.GestationPeriod = 0
numberOfChild := randNumberChild()
child := make([]*Hamster,numberOfChild)
for i := 1; i <= numberOfChild; i++{
child := make([]*Hamster, numberOfChild)
for i := 1; i <= numberOfChild; i++ {
child[i] = &Hamster{
Name: fmt.Sprintf("Hamster %d",GlobalHamsterNumber),
Number: GlobalHamsterNumber,
Age : 1,
Sexe: randSexe(),
Father: father,
Mother: mother,
HungerLevel: Full,
ThirstLevel: Full,
Alive: true,
Selled: false,
Gestation: false,
GestationPeriod: 0,
Name: fmt.Sprintf("Hamster %d", GlobalHamsterNumber),
Number: GlobalHamsterNumber,
Age: 1,
Sexe: randSexe(),
Father: father,
Mother: mother,
HungerLevel: Full,
ThirstLevel: Full,
Alive: true,
Selled: false,
Gestation: false,
GestationPeriod: 0,
GestationCooldown: 30,
}
}
mother.Child = append(mother.Child, child...)
father.Child = append(father.Child, child...)
return child,nil
return child, nil
}
func randNumberChild() int {
return randNumber(MinChild,MaxCild)
return randNumber(MinChild, MaxCild)
}
func randSexe() string {
return func () string{
if randNumber(1,2) == 2 {
return func() string {
if randNumber(1, 2) == 2 {
return MALE
} else {
return FEMALE
return FEMALE
}
}()
}
func randNumber(min int ,max int) int {
func randNumber(min int, max int) int {
return min + rand.Intn(max-min)
}

View File

@@ -7,8 +7,8 @@ import (
func TestDie(t *testing.T) {
testCases := []struct {
caseName string
hamster *Hamster
caseName string
hamster *Hamster
expectedAlive bool
}{
{
@@ -39,41 +39,41 @@ func TestDie(t *testing.T) {
func TestFuck(t *testing.T) {
testCases := []struct {
caseName string
hamster1 *Hamster
hamster2 *Hamster
caseName string
hamster1 *Hamster
hamster2 *Hamster
expectedResult bool
expectedError error
expectedError error
}{
{
caseName: "Hamster 1 too young",
hamster1: &Hamster{
Alive: true,
Sexe: MALE,
Age: GestationMinAge - 1,
Sexe: MALE,
Age: GestationMinAge - 1,
},
hamster2: &Hamster{
Alive: true,
Sexe: FEMALE,
Age: GestationMinAge + 1,
Sexe: FEMALE,
Age: GestationMinAge + 1,
},
expectedResult: false,
expectedError: errors.New("one of the hamster is too young"),
expectedError: errors.New("one of the hamster is too young"),
},
{
caseName: "Hamster 2 too young",
hamster1: &Hamster{
Alive: false,
Sexe: MALE,
Age: GestationMinAge + 1,
Sexe: MALE,
Age: GestationMinAge + 1,
},
hamster2: &Hamster{
Alive: true,
Sexe: FEMALE,
Age: GestationMinAge - 1,
Sexe: FEMALE,
Age: GestationMinAge - 1,
},
expectedResult: false,
expectedError: errors.New("one of the hamster is too young"),
expectedError: errors.New("one of the hamster is too young"),
},
}

View File

@@ -1,4 +1,5 @@
package main
import (
"fmt"
"math/rand"
@@ -9,4 +10,9 @@ func main() {
rand.Seed(time.Now().UTC().UnixNano())
fmt.Print("hello")
for {
fmt.Println("Infinite Loop 1")
time.Sleep(time.Second)
}
}