aboutsummaryrefslogtreecommitdiff
path: root/internal/storage/pebble_store_batch_durability_test.go
blob: 9d881c30e0007666b33b85d6c948584dda5e7748 (plain) (blame)
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
64
65
66
package storage

import (
	"testing"
	"time"

	"github.com/Fuwn/plutia/internal/types"
)

func TestApplyOperationsBatch_DurabilityBetweenBatches(t *testing.T) {
	tmp := t.TempDir()
	store, err := OpenPebble(tmp)
	if err != nil {
		t.Fatalf("open pebble: %v", err)
	}

	makeMutation := func(did string, seq uint64) OperationMutation {
		return OperationMutation{
			State: types.StateV1{
				Version:      1,
				DID:          did,
				DIDDocument:  []byte(`{"id":"` + did + `"}`),
				ChainTipHash: "sha256:tip",
				LatestOpSeq:  seq,
				UpdatedAt:    time.Now().UTC(),
			},
			Ref: &types.BlockRefV1{
				Version: 1,
				BlockID: 1,
				OpSeq:   seq,
				DID:     did,
				CID:     "sha256:cid",
			},
		}
	}

	if err := store.ApplyOperationsBatch([]OperationMutation{
		makeMutation("did:plc:a", 1),
		makeMutation("did:plc:b", 2),
	}, []BlockHashEntry{{BlockID: 1, Hash: "abc"}}); err != nil {
		t.Fatalf("apply first batch: %v", err)
	}
	if err := store.Close(); err != nil {
		t.Fatalf("close store: %v", err)
	}

	// Simulate a crash before the second batch commit by reopening without applying it.
	reopened, err := OpenPebble(tmp)
	if err != nil {
		t.Fatalf("reopen pebble: %v", err)
	}
	defer reopened.Close()

	seq, err := reopened.GetGlobalSeq()
	if err != nil {
		t.Fatalf("get global seq: %v", err)
	}
	if seq != 2 {
		t.Fatalf("global seq mismatch after simulated crash: got %d want 2", seq)
	}
	if _, ok, err := reopened.GetOpSeqRef(3); err != nil {
		t.Fatalf("get opseq 3: %v", err)
	} else if ok {
		t.Fatalf("unexpected opseq ref for uncommitted sequence 3")
	}
}