This commit is contained in:
Neale Pickett 2022-05-12 18:03:28 -06:00
commit eb08700dd1
6 changed files with 39 additions and 21 deletions

View File

@ -4,13 +4,14 @@ stages:
test: test:
stage: test stage: test
image: golang:1.18 image: golang:1.18
only: only:
refs: refs:
- main - main
- merge_requests - merge_requests
script: script:
- go test ./... - go test -race ./...
push: push:
stage: push stage: push

View File

@ -7,7 +7,6 @@ import (
"net/http/httptest" "net/http/httptest"
"net/url" "net/url"
"testing" "testing"
"time"
"github.com/spf13/afero" "github.com/spf13/afero"
) )
@ -34,8 +33,7 @@ func (hs *HTTPServer) TestRequest(path string, args map[string]string) *httptest
func TestHttpd(t *testing.T) { func TestHttpd(t *testing.T) {
server := NewTestServer() server := NewTestServer()
hs := NewHTTPServer("/", server) hs := NewHTTPServer("/", server.MothServer)
stateProvider := server.State.(*State)
if r := hs.TestRequest("/", nil); r.Result().StatusCode != 200 { if r := hs.TestRequest("/", nil); r.Result().StatusCode != 200 {
t.Error(r.Result()) t.Error(r.Result())
@ -72,7 +70,7 @@ func TestHttpd(t *testing.T) {
t.Error("Register failed", r.Body.String()) t.Error("Register failed", r.Body.String())
} }
time.Sleep(TestMaintenanceInterval) server.refresh()
if r := hs.TestRequest("/state", nil); r.Result().StatusCode != 200 { if r := hs.TestRequest("/state", nil); r.Result().StatusCode != 200 {
t.Error(r.Result()) t.Error(r.Result())
@ -114,8 +112,7 @@ func TestHttpd(t *testing.T) {
t.Error("Unexpected body", r.Body.String()) t.Error("Unexpected body", r.Body.String())
} }
time.Sleep(TestMaintenanceInterval) server.refresh()
stateProvider.refresh()
if r := hs.TestRequest("/content/pategory/2/puzzle.json", nil); r.Result().StatusCode != 200 { if r := hs.TestRequest("/content/pategory/2/puzzle.json", nil); r.Result().StatusCode != 200 {
t.Error(r.Result()) t.Error(r.Result())
@ -127,7 +124,7 @@ func TestHttpd(t *testing.T) {
} else if err := json.Unmarshal(r.Body.Bytes(), &state); err != nil { } else if err := json.Unmarshal(r.Body.Bytes(), &state); err != nil {
t.Error(err) t.Error(err)
} else if len(state.PointsLog) != 1 { } else if len(state.PointsLog) != 1 {
t.Error("Points log wrong length") t.Errorf("Points log wrong length. Wanted 1, got %v (length %d)", state.PointsLog, len(state.PointsLog))
} else if len(state.Puzzles["pategory"]) != 2 { } else if len(state.Puzzles["pategory"]) != 2 {
t.Error("Didn't unlock next puzzle") t.Error("Didn't unlock next puzzle")
} }
@ -143,7 +140,7 @@ func TestDevelMemHttpd(t *testing.T) {
srv := NewTestServer() srv := NewTestServer()
{ {
hs := NewHTTPServer("/", srv) hs := NewHTTPServer("/", srv.MothServer)
if r := hs.TestRequest("/mothballer/pategory.md", nil); r.Result().StatusCode != 404 { if r := hs.TestRequest("/mothballer/pategory.md", nil); r.Result().StatusCode != 404 {
t.Error("Should have gotten a 404 for mothballer in prod mode") t.Error("Should have gotten a 404 for mothballer in prod mode")
@ -152,7 +149,7 @@ func TestDevelMemHttpd(t *testing.T) {
{ {
srv.Config.Devel = true srv.Config.Devel = true
hs := NewHTTPServer("/", srv) hs := NewHTTPServer("/", srv.MothServer)
if r := hs.TestRequest("/mothballer/pategory.md", nil); r.Result().StatusCode != 500 { if r := hs.TestRequest("/mothballer/pategory.md", nil); r.Result().StatusCode != 500 {
t.Log(r.Body.String()) t.Log(r.Body.String())

View File

@ -68,6 +68,9 @@ type Maintainer interface {
// It will only be called once, when execution begins. // It will only be called once, when execution begins.
// It's okay to just exit if there's no maintenance to be done. // It's okay to just exit if there's no maintenance to be done.
Maintain(updateInterval time.Duration) Maintain(updateInterval time.Duration)
// refresh is a shortcut used internally for testing
refresh()
} }
// MothServer gathers together the providers that make up a MOTH server. // MothServer gathers together the providers that make up a MOTH server.

View File

@ -3,30 +3,40 @@ package main
import ( import (
"io/ioutil" "io/ioutil"
"testing" "testing"
"time"
"github.com/spf13/afero" "github.com/spf13/afero"
) )
const TestMaintenanceInterval = time.Millisecond * 1
const TestTeamID = "teamID" const TestTeamID = "teamID"
func NewTestServer() *MothServer { type TestServer struct {
*MothServer
}
// NewTestServer creates a new MothServer with NewTestMothballs and some initial state.
//
// See function definition for details.
func NewTestServer() TestServer {
puzzles := NewTestMothballs() puzzles := NewTestMothballs()
puzzles.refresh() puzzles.refresh()
go puzzles.Maintain(TestMaintenanceInterval)
state := NewTestState() state := NewTestState()
afero.WriteFile(state, "teamids.txt", []byte("teamID\n"), 0644) afero.WriteFile(state, "teamids.txt", []byte("teamID\n"), 0644)
afero.WriteFile(state, "messages.html", []byte("messages.html"), 0644) afero.WriteFile(state, "messages.html", []byte("messages.html"), 0644)
state.refresh() state.refresh()
go state.Maintain(TestMaintenanceInterval)
theme := NewTestTheme() theme := NewTestTheme()
afero.WriteFile(theme.Fs, "/index.html", []byte("index.html"), 0644) afero.WriteFile(theme.Fs, "/index.html", []byte("index.html"), 0644)
go theme.Maintain(TestMaintenanceInterval)
return NewMothServer(Configuration{}, theme, state, puzzles) return TestServer{NewMothServer(Configuration{}, theme, state, puzzles)}
}
func (ts TestServer) refresh() {
ts.State.(*State).refresh()
for _, pp := range ts.PuzzleProviders {
pp.(*Mothballs).refresh()
}
ts.Theme.(*Theme).refresh()
} }
func TestDevelServer(t *testing.T) { func TestDevelServer(t *testing.T) {
@ -82,8 +92,7 @@ func TestProdServer(t *testing.T) {
t.Error("index.html wrong contents", contents) t.Error("index.html wrong contents", contents)
} }
// Wait for refresh to pick everything up server.refresh()
time.Sleep(TestMaintenanceInterval)
{ {
es := handler.ExportState() es := handler.ExportState()
@ -136,7 +145,7 @@ func TestProdServer(t *testing.T) {
t.Error("Right answer marked wrong", err) t.Error("Right answer marked wrong", err)
} }
time.Sleep(TestMaintenanceInterval) server.refresh()
{ {
es := handler.ExportState() es := handler.ExportState()
@ -165,7 +174,7 @@ func TestProdServer(t *testing.T) {
t.Error("Right answer marked wrong:", err) t.Error("Right answer marked wrong:", err)
} }
time.Sleep(TestMaintenanceInterval) server.refresh()
{ {
es := anonHandler.ExportState() es := anonHandler.ExportState()

View File

@ -38,3 +38,7 @@ func (t *Theme) Open(name string) (ReadSeekCloser, time.Time, error) {
func (t *Theme) Maintain(i time.Duration) { func (t *Theme) Maintain(i time.Duration) {
// No periodic tasks for a theme // No periodic tasks for a theme
} }
func (t *Theme) refresh() {
// Nothing to do for a theme
}

View File

@ -79,3 +79,7 @@ func (p TranspilerProvider) Mothball(cat string, w io.Writer) error {
func (p TranspilerProvider) Maintain(updateInterval time.Duration) { func (p TranspilerProvider) Maintain(updateInterval time.Duration) {
// Nothing to do here. // Nothing to do here.
} }
func (p TranspilerProvider) refresh() {
// Nothing to do for a theme
}