main ece7682

snapshot_generation_test.go RawHistoryFolder

1package daemon
2
3import (
4	"context"
5	"errors"
6	"sync/atomic"
7	"testing"
8	"time"
9
10	"github.com/stretchr/testify/mock"
11	"github.com/stretchr/testify/require"
12
13	"github.com/bnema/vev/internal/ports"
14	portsmocks "github.com/bnema/vev/internal/ports/mocks"
15)
16
17func TestSnapshotMultipleMutationsPublishNextRepositoryGeneration(t *testing.T) {
18	d := newTestDaemon(t, portsmocks.NewMockPTYFactory(t), stubClock{})
19	repository := portsmocks.NewMockSnapshotRepository(t)
20	WithSnapshotRepository(repository)(d)
21	startSnapshotEncodeWorker(t, d)
22
23	publications := make(chan ports.SnapshotPublication, 1)
24	repository.EXPECT().Publish(mock.Anything, mock.Anything).RunAndReturn(func(_ context.Context, publication ports.SnapshotPublication) error {
25		publications <- publication
26		return nil
27	}).Once()
28
29	sess := newSnapshotTestSession(t, "work", false, "/work")
30	markSnapshotDirty(sess)
31	markSnapshotDirty(sess)
32	markSnapshotDirty(sess)
33	require.True(t, d.scheduleSnapshot(sess))
34
35	select {
36	case publication := <-publications:
37		require.Equal(t, uint64(1), publication.Generation)
38	case <-time.After(testWaitTimeout):
39		t.Fatal("snapshot was not published")
40	}
41	awaitSnapshotClean(t, sess)
42}
43
44func TestSnapshotRetryKeepsRepositoryGeneration(t *testing.T) {
45	d := newTestDaemon(t, portsmocks.NewMockPTYFactory(t), stubClock{})
46	repository := portsmocks.NewMockSnapshotRepository(t)
47	WithSnapshotRepository(repository)(d)
48	startSnapshotEncodeWorker(t, d)
49
50	publications := make(chan ports.SnapshotPublication, 2)
51	var attempts atomic.Int32
52	repository.EXPECT().Publish(mock.Anything, mock.Anything).RunAndReturn(func(_ context.Context, publication ports.SnapshotPublication) error {
53		publications <- publication
54		if attempts.Add(1) == 1 {
55			return errors.New("temporary repository failure")
56		}
57		return nil
58	}).Twice()
59
60	sess := newSnapshotTestSession(t, "work", false, "/work")
61	markSnapshotDirty(sess)
62	require.True(t, d.scheduleSnapshot(sess))
63	select {
64	case publication := <-publications:
65		require.Equal(t, uint64(1), publication.Generation)
66	case <-time.After(testWaitTimeout):
67		t.Fatal("first snapshot was not published")
68	}
69	awaitSnapshotIdle(t, sess)
70	require.True(t, sess.snapDirty.Load())
71
72	require.True(t, d.scheduleFinalSnapshot(sess))
73	select {
74	case publication := <-publications:
75		require.Equal(t, uint64(1), publication.Generation)
76	case <-time.After(testWaitTimeout):
77		t.Fatal("retry snapshot was not published")
78	}
79	awaitSnapshotClean(t, sess)
80}

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