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 - name: Testing
run: go test ./... 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 module hamster-tycoon
go 1.13 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 package hamster_tycoon
type Cage struct { type Cage struct {
Hamsters []*Hamster Hamsters []*Hamster
} }

View File

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

View File

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

View File

@@ -7,8 +7,8 @@ import (
func TestDie(t *testing.T) { func TestDie(t *testing.T) {
testCases := []struct { testCases := []struct {
caseName string caseName string
hamster *Hamster hamster *Hamster
expectedAlive bool expectedAlive bool
}{ }{
{ {
@@ -39,41 +39,41 @@ func TestDie(t *testing.T) {
func TestFuck(t *testing.T) { func TestFuck(t *testing.T) {
testCases := []struct { testCases := []struct {
caseName string caseName string
hamster1 *Hamster hamster1 *Hamster
hamster2 *Hamster hamster2 *Hamster
expectedResult bool expectedResult bool
expectedError error expectedError error
}{ }{
{ {
caseName: "Hamster 1 too young", caseName: "Hamster 1 too young",
hamster1: &Hamster{ hamster1: &Hamster{
Alive: true, Alive: true,
Sexe: MALE, Sexe: MALE,
Age: GestationMinAge - 1, Age: GestationMinAge - 1,
}, },
hamster2: &Hamster{ hamster2: &Hamster{
Alive: true, Alive: true,
Sexe: FEMALE, Sexe: FEMALE,
Age: GestationMinAge + 1, Age: GestationMinAge + 1,
}, },
expectedResult: false, 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", caseName: "Hamster 2 too young",
hamster1: &Hamster{ hamster1: &Hamster{
Alive: false, Alive: false,
Sexe: MALE, Sexe: MALE,
Age: GestationMinAge + 1, Age: GestationMinAge + 1,
}, },
hamster2: &Hamster{ hamster2: &Hamster{
Alive: true, Alive: true,
Sexe: FEMALE, Sexe: FEMALE,
Age: GestationMinAge - 1, Age: GestationMinAge - 1,
}, },
expectedResult: false, 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 package main
import ( import (
"fmt" "fmt"
"math/rand" "math/rand"
@@ -9,4 +10,9 @@ func main() {
rand.Seed(time.Now().UTC().UnixNano()) rand.Seed(time.Now().UTC().UnixNano())
fmt.Print("hello") fmt.Print("hello")
for {
fmt.Println("Infinite Loop 1")
time.Sleep(time.Second)
}
} }