carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1package host
2
3import (
4 "os"
5 "strings"
6 "testing"
7
8 "github.com/carlosframework/platform/internal/lease"
9 "github.com/carlosframework/platform/internal/moves"
10 "github.com/carlosframework/platform/internal/provision"
11)
12
13// Final review finding 2, end to end: the target's fresh report priced
14// T11 and checked T6 for the database it saw, 16 KiB here. The database
15// then grows to 2.5 GiB before the target reports again, as the source's
16// local file or as its replica's newest LTX. The source's next round must
17// not promote on the old report, and the source's report must carry the
18// size it saw. The target's next report prices the new size.
19func TestPromotionWaitsForAReportCoveringTheGrownDatabase(t *testing.T) {
20 const grown = 2560 << 20
21 for name, grow := range map[string]func(t *testing.T, h *phase1Harness){
22 "local file": func(t *testing.T, h *phase1Harness) {
23 db, err := os.Create(provision.DefaultDBPath(h.cfg.DataDir, p1Host))
24 if err != nil {
25 t.Fatal(err)
26 }
27 if err := db.Truncate(grown); err != nil { // sparse
28 t.Fatal(err)
29 }
30 db.Close()
31 },
32 "replica": func(t *testing.T, h *phase1Harness) {
33 newest := ltxForTest(t, 4096, grown/4096, 3, 3)
34 key := "instances/" + p1Host + "/" + h.inc + "/g-cur/0000/0000000000000003-0000000000000003.ltx"
35 h.f.store("data-ie", key, fakeMoveObject{lease.MirrorObject{ETag: "grown", Size: int64(len(newest))}, string(newest)})
36 },
37 } {
38 t.Run(name, func(t *testing.T) {
39 h := newPhase1Harness(t)
40 h.start(t, "manual")
41 h.pass(t)
42 h.targetPass(t, h.targetCfg())
43 tr := h.targetReport(t)
44 if ok, why := tr.Passing(); !ok || tr.DBMiB*(1<<20) != 4*4096 {
45 t.Fatalf("the target's first report: %v %s, priced %v MiB", ok, why, tr.DBMiB)
46 }
47 grow(t, h)
48 h.pass(t)
49 if got := h.read(t, p1Host).Move.State; got != provision.MovePreparing {
50 t.Fatalf("promoted on a report that priced %v MiB after the database grew to 2.5 GiB: %s", tr.DBMiB, got)
51 }
52 sr := h.sourceReport(t)
53 if max(sr.DBBytes, sr.ReplicaBytes) != grown {
54 t.Fatalf("the source report carries DBBytes %d and ReplicaBytes %d, want %d", sr.DBBytes, sr.ReplicaBytes, int64(grown))
55 }
56 _, why := moves.Ready(0, h.cfg.ReadyDelta, h.targetReport(t), sr, h.clock.Now())
57 if !strings.HasPrefix(why, "T11: the database has grown to 2560 MiB") {
58 t.Fatalf("Ready's reason: %q", why)
59 }
60 h.targetPass(t, h.targetCfg())
61 if r := h.targetReport(t); r.DBMiB != 2560 {
62 t.Fatalf("the target's next report priced %v MiB", r.DBMiB)
63 }
64 })
65 }
66}
67
68// Without growth the same sequence promotes: the control for the test
69// above, and the replica's size is what the source reports.
70func TestSourceReportCarriesTheReplicaSize(t *testing.T) {
71 h := newPhase1Harness(t)
72 h.start(t, "manual")
73 h.pass(t)
74 if sr := h.sourceReport(t); sr.ReplicaBytes != 4*4096 {
75 t.Fatalf("ReplicaBytes %d, want the 16 KiB the newest header names", sr.ReplicaBytes)
76 }
77 h.targetPass(t, h.targetCfg())
78 h.pass(t)
79 if got := h.read(t, p1Host).Move.State; got != provision.MoveReady {
80 t.Fatalf("state %s, want ready", got)
81 }
82}
83