aboutsummaryrefslogtreecommitdiff
path: root/internal/game/hardening_shutdown_save_error_test.go
blob: c75f6fc005c23377b77fc3c2aaa983137ae3576f (plain)
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)
	}
}