maintenance_test.go RawHistoryFolder

1package daemon
2
3import (
4	"context"
5	"errors"
6	"testing"
7	"testing/synctest"
8	"time"
9
10	"github.com/bnema/vev/internal/domain"
11	portsmocks "github.com/bnema/vev/internal/ports/mocks"
12	recoveryusecase "github.com/bnema/vev/internal/usecase/recovery"
13	"github.com/stretchr/testify/mock"
14	"github.com/stretchr/testify/require"
15)
16
17func TestSnapshotGarbageCollectionRunsAfterRestorationThenPeriodically(t *testing.T) {
18	committed := domain.CheckpointRef{Generation: 3, ManifestDigest: [32]byte{3}}
19	records := []domain.CatalogueRecord{{Name: "work", IncarnationID: domain.IncarnationID{1}, Committed: &committed}}
20	id := records[0].IncarnationID
21
22	tests := []struct {
23		name        string
24		recordsErr  error
25		wantCollect bool
26	}{
27		{name: "collects after restoration and on every tick", wantCollect: true},
28		{name: "unreadable catalogue never collects", recordsErr: errors.New("catalogue read failed")},
29	}
30	for _, tt := range tests {
31		t.Run(tt.name, func(t *testing.T) {
32			synctest.Test(t, func(t *testing.T) {
33				const passes = 2
34				catalogue := portsmocks.NewMockCatalogue(t)
35				repository := portsmocks.NewMockSnapshotRepository(t)
36				catalogue.EXPECT().Records().Return(records, tt.recordsErr).Times(passes)
37				repository.EXPECT().SnapshotIncarnations(mock.Anything).Return([]domain.IncarnationID{id}, nil).Times(passes)
38				collected := make(chan struct{}, passes)
39				if tt.wantCollect {
40					repository.EXPECT().CollectIncarnationGarbage(mock.Anything, id, &committed).
41						Run(func(context.Context, domain.IncarnationID, *domain.CheckpointRef) { collected <- struct{}{} }).
42						Return(nil).Times(passes)
43				}
44
45				clk := &signalClock{timers: make(chan *signalTimer, 1)}
46				d := newTestDaemon(t, portsmocks.NewMockPTYFactory(t), clk)
47				WithRecoveryCoordinator(recoveryusecase.NewCoordinator(catalogue, repository, nil))(d)
48				WithSnapshotGarbageCollection()(d)
49				d.startDurableMaintenance()
50
51				synctest.Wait()
52				require.Empty(t, clk.timers, "GC must wait for restoration to finish")
53				d.closeRestoreDone()
54
55				for pass := range passes {
56					synctest.Wait()
57					timer := <-clk.timers
58					require.Equal(t, snapshotGarbageCollectionInterval, timer.duration)
59					if tt.wantCollect {
60						require.Len(t, collected, 1)
61						<-collected
62					}
63					if pass < passes-1 {
64						timer.ch <- time.Time{}
65					}
66				}
67
68				d.serveCancel()
69				d.WaitDurableWriters()
70			})
71		})
72	}
73}
74
75func TestSnapshotGarbageCollectionRequiresExplicitOption(t *testing.T) {
76	d := newTestDaemon(t, portsmocks.NewMockPTYFactory(t), stubClock{})
77	coordinator := recoveryusecase.NewCoordinator(portsmocks.NewMockCatalogue(t), portsmocks.NewMockSnapshotRepository(t), nil)
78	WithRecoveryCoordinator(coordinator)(d)
79	d.startDurableMaintenance()
80
81	d.snapshotWorkerMu.Lock()
82	defer d.snapshotWorkerMu.Unlock()
83	require.Nil(t, d.maintenanceWorkerDone)
84}

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 12

Tags 11

↑↓ moveenter openesc close