1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
package game
// Regression coverage for the shutdown final-save report: runShutdown records
// a failed saveAllOnlineCharacters on the Game, and ShutdownSaveError exposes
// it so main can exit non-zero instead of losing online state silently.
import (
"os"
"path/filepath"
"strings"
"testing"
)
// TestShutdownSaveErrorReportsFailedFinalSave makes the character save fail
// (the character file is replaced by a directory, so the atomic replace cannot
// land) and requires the shutdown sequence to record the failure on the Game.
func TestShutdownSaveErrorReportsFailedFinalSave(t *testing.T) {
h := newHarness(t)
h.seedAccount("alice")
h.seedCharacter("alice", "alice")
h.connect("alice")
charPath := filepath.Join(h.dir, "players", "characters", "alice.yaml")
if err := os.Remove(charPath); err != nil {
t.Fatalf("remove character file: %v", err)
}
if err := os.Mkdir(charPath, 0o755); err != nil {
t.Fatalf("block character path: %v", err)
}
h.g.runShutdown()
err := h.g.ShutdownSaveError()
if err == nil {
t.Fatal("a failed final save was not recorded")
}
if !strings.Contains(err.Error(), "alice") {
t.Fatalf("shutdown save error does not name the unsaved character: %v", err)
}
}
// TestShutdownSaveErrorNilWhenFinalSaveSucceeds pins the other direction:
// nothing is reported when every online character was persisted, so main does
// not exit non-zero on a clean shutdown.
func TestShutdownSaveErrorNilWhenFinalSaveSucceeds(t *testing.T) {
h := newHarness(t)
h.seedAccount("alice")
h.seedCharacter("alice", "alice")
h.connect("alice")
if err := h.g.ShutdownSaveError(); err != nil {
t.Fatalf("ShutdownSaveError before any shutdown = %v, want nil", err)
}
h.g.runShutdown()
if err := h.g.ShutdownSaveError(); err != nil {
t.Fatalf("clean shutdown recorded a save failure: %v", err)
}
if _, err := h.g.AccountStore.LoadCharacter("alice"); err != nil {
t.Fatalf("online character was not saved: %v", err)
}
}
|