v3.3.0 b164fe9

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}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 7

Tags 106

↑↓ moveenter openesc close