clone

a self-hosted multitenant nostr relay with sites, file storage, git hosting, and inbox and outbox delivery

feat/ui-updates
tinyrelay / tinygit / journal_test.go
journal_test.go 2.0K
1package tinygit23import (4 "context"5 "errors"6 "os"7 "path/filepath"8 "strings"9 "testing"1011 "github.com/FelineStateMachine/tinyrelay/protocol/nostr"12)1314type unavailableMetadataStore struct {15 Store16 err error17}1819func (s unavailableMetadataStore) Latest(context.Context, int, string, string) (Event, bool, error) {20 return Event{}, false, s.err21}2223func TestJournalRecoveryPreservesIntentWhenStorageReadFails(t *testing.T) {24 ctx := context.Background()25 root := t.TempDir()26 store, err := OpenStore(ctx, filepath.Join(root, "events.db"))27 if err != nil {28 t.Fatal(err)29 }30 t.Cleanup(func() { _ = store.Close() })31 g, err := New(Config{Store: store, Root: filepath.Join(root, "git")})32 if err != nil {33 t.Fatal(err)34 }35 state := Event{Kind: 30618, CreatedAt: 1, Tags: [][]string{{"d", "demo"}, {"refs/heads/main", strings.Repeat("c", 40)}}}36 if err := nostr.Sign(&state, strings.Repeat("0", 63)+"1"); err != nil {37 t.Fatal(err)38 }39 if err := store.Save(ctx, state, 1); err != nil {40 t.Fatal(err)41 }42 repo := Repository{Owner: state.PubKey, Identifier: "demo", Refs: map[string]string{"refs/heads/main": strings.Repeat("c", 40)}}43 journal := journalRecord{Repository: key(repo.Owner, repo.Identifier), EventID: state.ID, Kind: 30618, Refs: repo.Refs}44 if err := g.writeJournal(repo, journal); err != nil {45 t.Fatal(err)46 }47 unavailable := errors.New("metadata temporarily unavailable")48 g.store = unavailableMetadataStore{Store: store, err: unavailable}49 if err := g.recoverJournals(); !errors.Is(err, unavailable) {50 t.Errorf("recovery error=%v; want storage failure", err)51 }52 if _, err := os.Stat(g.journalPath(journal)); err != nil {53 t.Fatalf("recovery discarded the journal after a read failure: %v", err)54 }55 g.store = store56 if err := g.recoverJournals(); err != nil {57 t.Fatal(err)58 }59 pending, err := os.ReadFile(filepath.Join(g.repoPath(repo), "tinyrelay.pending"))60 if err != nil || !strings.Contains(string(pending), "refs/heads/main "+strings.Repeat("c", 40)) {61 t.Fatalf("retry did not recover pending state: %q, %v", pending, err)62 }63}