export_test.go RawHistoryFolder
1package appstate
2
3// Test-only hooks live here instead of the production API: they rewrite
4// durable records to reproduce corrupt or version-skewed states that
5// production code can never create.
6
7import (
8 "errors"
9 "fmt"
10
11 bolt "go.etcd.io/bbolt"
12 bolterrors "go.etcd.io/bbolt/errors"
13
14 "github.com/bnema/gordon/internal/domain"
15)
16
17// CorruptCheckpointForTest rewrites the checkpoint record. Tests use it
18// to simulate corrupt or version-skewed state.db payloads.
19func CorruptCheckpointForTest(s *Store, rewrite func([]byte) []byte) error {
20 return s.db.Update(func(tx *bolt.Tx) error {
21 bucket := tx.Bucket(bucketCheckpoint)
22 if bucket == nil {
23 return nil
24 }
25 raw := append([]byte(nil), bucket.Get(keyStoreRecord)...)
26 return bucket.Put(keyStoreRecord, rewrite(raw))
27 })
28}
29
30// SeedDesiredRecordForTest writes an exact desired-record payload, creating
31// the app bucket when absent. Tests use it to plant records written by an
32// older Gordon, whose JSON omits fields the current schema has.
33func SeedDesiredRecordForTest(s *Store, app string, raw []byte) error {
34 return s.db.Update(func(tx *bolt.Tx) error {
35 bucket, err := appBucket(tx, app, true)
36 if err != nil {
37 return err
38 }
39 return bucket.Put(keyDesired, raw)
40 })
41}
42
43// CorruptDesiredForTest rewrites one app's desired record. Tests use it
44// to simulate a corrupt desired payload with other apps unaffected.
45func CorruptDesiredForTest(s *Store, app string, rewrite func([]byte) []byte) error {
46 return s.db.Update(func(tx *bolt.Tx) error {
47 bucket, err := appBucket(tx, app, false)
48 if err != nil {
49 return err
50 }
51 if bucket == nil {
52 return nil
53 }
54 raw := append([]byte(nil), bucket.Get(keyDesired)...)
55 return bucket.Put(keyDesired, rewrite(raw))
56 })
57}
58
59// ResetOwnershipHistoryForTest drops the incarnation-indexed ownership
60// history and its migration marker. Tests use it to reproduce a
61// pre-migration database that already holds current-shaped records.
62func ResetOwnershipHistoryForTest(s *Store) error {
63 return s.db.Update(func(tx *bolt.Tx) error {
64 if err := tx.DeleteBucket(bucketOwnershipHistory); err != nil && !errors.Is(err, bolterrors.ErrBucketNotFound) {
65 return fmt.Errorf("appstate: reset ownership history: %w", domain.ErrAppStateIO)
66 }
67 meta := tx.Bucket(bucketMeta)
68 if meta == nil {
69 return nil
70 }
71 if err := meta.Delete(keyOwnershipMigration); err != nil {
72 return fmt.Errorf("appstate: reset ownership migration: %w", domain.ErrAppStateIO)
73 }
74 return nil
75 })
76}