Skip to content

Commit

Permalink
in-memory db, play test, part 2.
Browse files Browse the repository at this point in the history
  • Loading branch information
schwarzlichtbezirk committed Dec 5, 2024
1 parent 8f461b1 commit 9a32a04
Show file tree
Hide file tree
Showing 14 changed files with 227 additions and 16 deletions.
32 changes: 32 additions & 0 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# This workflow will build a golang project
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go

name: Go

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

jobs:

build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.23.x'

- name: Test
run: go test -v ./util ./api

- name: Build
run: go build -v .
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ COPY go.mod go.sum ./
RUN go mod download
# Copy all files and subfolders in current state as is.
COPY . .
COPY ./confdata /go/bin/config
COPY ./appdata /go/bin/config

# Set executable rights to all shell-scripts.
RUN chmod +x ./task/*.sh
Expand Down
2 changes: 1 addition & 1 deletion api/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ var (
ErrBadJwtID = errors.New("jwt-token id does not refer to registered user")
ErrNoAuth = errors.New("authorization is required")
ErrNoScheme = errors.New("authorization does not have expected scheme")
ErrNoSecret = errors.New("expected password or SHA25 hash on it and current time as a nonce")
ErrNoSecret = errors.New("expected password or SHA256 hash on it and current time as a nonce")
ErrSmallKey = errors.New("password too small")
ErrNoCred = errors.New("user with given credentials does not registered")
ErrActivate = errors.New("activation required for this account")
Expand Down
166 changes: 166 additions & 0 deletions api/play_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
package api_test

import (
"bytes"
"encoding/json"
"io"
"math/rand"
"net/http"
"net/http/httptest"
"strings"
"testing"

"github.com/slotopol/server/api"
"github.com/slotopol/server/cmd"
cfg "github.com/slotopol/server/config"

"github.com/gin-gonic/gin"
)

const email, secret = "player@example.org", "iVI05M"

func ping(t *testing.T, r *gin.Engine) {
var req = httptest.NewRequest("GET", "/ping", nil)
var w = httptest.NewRecorder()
r.ServeHTTP(w, req)
if w.Code != http.StatusOK {
t.Error("ping is not ok")
}
var resp = w.Result()
if !strings.HasPrefix(resp.Header.Get("Server"), "slotopol/") {
t.Error("alien server")
}
}

func post(t *testing.T, r *gin.Engine, path string, token string, arg any) (ret gin.H) {
var err error
var b []byte

if b, err = json.Marshal(arg); err != nil {
t.Error(err)
}
var req = httptest.NewRequest("POST", path, bytes.NewReader(b))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Accept", "application/json")
if token != "" {
req.Header.Set("Authorization", "Bearer "+token)
}
var w = httptest.NewRecorder()
r.ServeHTTP(w, req)
if w.Code == http.StatusNoContent {
return
}
if w.Code != http.StatusOK {
t.Errorf("'%s' is not ok, status %d", path, w.Code)
}
var resp = w.Result()
if b, err = io.ReadAll(resp.Body); err != nil {
t.Error(err)
}
if err = json.Unmarshal(b, &ret); err != nil {
t.Error(err)
}
if w.Code != http.StatusOK {
t.Logf("message: %v, code: %v", ret["what"], ret["code"])
}
return
}

func TestPlay(t *testing.T) {
var err error
var arg, ret gin.H
var token string
var gid any

// Prepare in-memory database
cfg.CfgPath = "../appdata"
if err = cmd.Init(); err != nil {
t.Fatal(err)
}

gin.SetMode(gin.DebugMode)
var r = gin.New()
r.HandleMethodNotAllowed = true
api.Router(r)

// Send "ping" and check that server is our
ping(t, r)

// Sign-in player
arg = gin.H{
"email": email,
"secret": secret,
}
ret = post(t, r, "/signin", "", arg)
token = ret["access"].(string)

// Join game
arg = gin.H{
"cid": 1, // 'virtual' club
"uid": 3, // player ID
"alias": "Novomatic / Dolphins Pearl",
}
ret = post(t, r, "/game/join", token, arg)
gid = ret["gid"]

arg = gin.H{
"gid": gid,
"bet": 1,
}
post(t, r, "/slot/bet/set", token, arg)
arg = gin.H{
"gid": gid,
"sel": 5,
}
post(t, r, "/slot/sel/set", token, arg)

// Play the game with 50 spins
for range 50 {
// make spin
arg = gin.H{
"gid": gid,
}
ret = post(t, r, "/slot/spin", token, arg)
t.Logf("[spin] gid: %v, sid: %v, wallet: %v", gid, ret["sid"], ret["wallet"])
var game = ret["game"].(map[string]any)

// no any more actions on free spins
if _, ok := game["fsr"]; ok {
continue
}
if _, ok := game["gain"]; !ok {
continue
}
t.Logf("gain: %v", game["gain"])

// if there has a win, make double-ups sometime
if rand.Float64() < 0.3 {
for {
arg = gin.H{
"gid": gid,
"mult": 2,
}
ret = post(t, r, "/slot/doubleup", token, arg)
var gain = ret["gain"].(float64)
t.Logf("[doubleup] gid: %v, id: %v, wallet: %v, gain: %g", gid, ret["id"], ret["wallet"], gain)
if gain == 0 {
break
}
if rand.Float64() < 0.5 {
arg = gin.H{
"gid": gid,
}
post(t, r, "/slot/collect", token, arg)
t.Logf("[collect] gid: %v", gid)
break
}
}
}
}

// Part game
arg = gin.H{
"gid": gid,
}
post(t, r, "/game/part", token, arg)
}
16 changes: 14 additions & 2 deletions cmd/startup.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,13 @@ func InitStorage() (err error) {
}

if Cfg.DriverName == "sqlite3" {
cfg.XormStorage, err = xorm.NewEngine(Cfg.DriverName, util.JoinPath(cfg.SqlPath, Cfg.ClubSourceName))
var fpath string
if Cfg.ClubSourceName != ":memory:" {
fpath = util.JoinPath(cfg.SqlPath, Cfg.ClubSourceName)
} else {
fpath = Cfg.ClubSourceName
}
cfg.XormStorage, err = xorm.NewEngine(Cfg.DriverName, fpath)
} else {
cfg.XormStorage, err = xorm.NewEngine(Cfg.DriverName, Cfg.ClubSourceName)
}
Expand Down Expand Up @@ -226,7 +232,13 @@ func InitSpinlog() (err error) {
}

if Cfg.DriverName == "sqlite3" {
cfg.XormSpinlog, err = xorm.NewEngine(Cfg.DriverName, util.JoinPath(cfg.SqlPath, Cfg.SpinSourceName))
var fpath string
if Cfg.SpinSourceName != ":memory:" {
fpath = util.JoinPath(cfg.SqlPath, Cfg.SpinSourceName)
} else {
fpath = Cfg.SpinSourceName
}
cfg.XormSpinlog, err = xorm.NewEngine(Cfg.DriverName, fpath)
} else {
cfg.XormSpinlog, err = xorm.NewEngine(Cfg.DriverName, Cfg.SpinSourceName)
}
Expand Down
1 change: 1 addition & 0 deletions config/cfgpath.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ func InitConfig() {
viper.AddConfigPath(filepath.Join(ExePath, sub))
viper.AddConfigPath(ExePath)
viper.AddConfigPath(sub)
viper.AddConfigPath("appdata")
viper.AddConfigPath(".")
if home, err := os.UserHomeDir(); err == nil {
viper.AddConfigPath(filepath.Join(home, sub))
Expand Down
10 changes: 5 additions & 5 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,12 +131,12 @@ var Cfg = &Config{
},
CfgXormDrv: CfgXormDrv{
DriverName: "sqlite3",
ClubSourceName: "slot-club.sqlite",
SpinSourceName: "slot-spin.sqlite",
ClubSourceName: ":memory:",
SpinSourceName: ":memory:",
SqlFlushTick: 2500 * time.Millisecond,
ClubUpdateBuffer: 200,
ClubInsertBuffer: 150,
SpinInsertBuffer: 250,
ClubUpdateBuffer: 1,
ClubInsertBuffer: 1,
SpinInsertBuffer: 1,
},
CfgGameplay: CfgGameplay{
AdjunctLimit: 100000,
Expand Down
2 changes: 1 addition & 1 deletion task/build-linux-x64.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ rem This script compiles project for Linux amd64.
rem It produces static C-libraries linkage.

set wd=%~dp0..
xcopy %wd%\confdata %GOPATH%\bin\config /f /d /i /e /k /y
xcopy %wd%\appdata %GOPATH%\bin\config /f /d /i /e /k /y

for /F "tokens=*" %%g in ('git describe --tags') do (set buildvers=%%g)
for /f "tokens=2 delims==" %%g in ('wmic os get localdatetime /value') do set dt=%%g
Expand Down
2 changes: 1 addition & 1 deletion task/build-linux-x64.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# It produces static C-libraries linkage.

wd=$(realpath -s "$(dirname "$0")/..")
cp -ruv "$wd/confdata/"* "$GOPATH/bin/config"
cp -ruv "$wd/appdata/"* "$GOPATH/bin/config"

buildvers=$(git describe --tags)
# See https://tc39.es/ecma262/#sec-date-time-string-format
Expand Down
2 changes: 1 addition & 1 deletion task/build-win-x64-slotopol.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# It produces static C-libraries linkage.

wd=$(realpath -s "$(dirname "$0")/..")
cp -ruv "$wd/confdata/"* "$GOPATH/bin/config"
cp -ruv "$wd/appdata/"* "$GOPATH/bin/config"

buildvers=$(git describe --tags)
# See https://tc39.es/ecma262/#sec-date-time-string-format
Expand Down
2 changes: 1 addition & 1 deletion task/build-win-x64.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ rem This script compiles project for Windows amd64.
rem It produces static C-libraries linkage.

set wd=%~dp0..
xcopy %wd%\confdata %GOPATH%\bin\config /f /d /i /e /k /y
xcopy %wd%\appdata %GOPATH%\bin\config /f /d /i /e /k /y

for /F "tokens=*" %%g in ('git describe --tags') do (set buildvers=%%g)
for /f "tokens=2 delims==" %%g in ('wmic os get localdatetime /value') do set dt=%%g
Expand Down
2 changes: 1 addition & 1 deletion task/build-win-x64.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# It produces static C-libraries linkage.

wd=$(realpath -s "$(dirname "$0")/..")
cp -ruv "$wd/confdata/"* "$GOPATH/bin/config"
cp -ruv "$wd/appdata/"* "$GOPATH/bin/config"

buildvers=$(git describe --tags)
# See https://tc39.es/ecma262/#sec-date-time-string-format
Expand Down
2 changes: 1 addition & 1 deletion task/build-win-x86.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ rem This script compiles project for Windows x86.
rem It produces static C-libraries linkage.

set wd=%~dp0..
xcopy %wd%\confdata %GOPATH%\bin\config /f /d /i /e /k /y
xcopy %wd%\appdata %GOPATH%\bin\config /f /d /i /e /k /y

for /F "tokens=*" %%g in ('git describe --tags') do (set buildvers=%%g)
for /f "tokens=2 delims==" %%g in ('wmic os get localdatetime /value') do set dt=%%g
Expand Down
2 changes: 1 addition & 1 deletion task/build-win-x86.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# It produces static C-libraries linkage.

wd=$(realpath -s "$(dirname "$0")/..")
cp -ruv "$wd/confdata/"* "$GOPATH/bin/config"
cp -ruv "$wd/appdata/"* "$GOPATH/bin/config"

buildvers=$(git describe --tags)
# See https://tc39.es/ecma262/#sec-date-time-string-format
Expand Down

0 comments on commit 9a32a04

Please sign in to comment.