Drive the archive reopen debounce test from a clock (closes #190)
check / check (push) Successful in 4m16s
check / check (push) Successful in 4m16s
The archive writer now reads the time its reopen debounce is measured on from a clock field, time.Now outside tests. The debounce test moves that clock instead of sleeping past a real 2 second window, so a slow host between the two quick writes can no longer turn a correct result red. Model: opus-5-5
This commit is contained in:
@@ -512,6 +512,12 @@ func (e *ExportArchiveWriter) Reopen(
|
|||||||
return e.w.reopen(expiry)
|
return e.w.reopen(expiry)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetNow replaces the clock the writer measures its reopen
|
||||||
|
// debounce on.
|
||||||
|
func (e *ExportArchiveWriter) SetNow(now func() time.Time) {
|
||||||
|
e.w.now = now
|
||||||
|
}
|
||||||
|
|
||||||
// Reopens reports how many times the file has been opened.
|
// Reopens reports how many times the file has been opened.
|
||||||
func (e *ExportArchiveWriter) Reopens() int {
|
func (e *ExportArchiveWriter) Reopens() int {
|
||||||
return e.w.reopens
|
return e.w.reopens
|
||||||
|
|||||||
@@ -194,6 +194,10 @@ type archiveWriter struct {
|
|||||||
lastReopen time.Time
|
lastReopen time.Time
|
||||||
reopens int
|
reopens int
|
||||||
|
|
||||||
|
// now is the clock the reopen debounce is measured on. It is
|
||||||
|
// time.Now outside tests.
|
||||||
|
now func() time.Time
|
||||||
|
|
||||||
// evicted marks a writer that has been removed from the
|
// evicted marks a writer that has been removed from the
|
||||||
// registry. Its handle is closed and it must never open the
|
// registry. Its handle is closed and it must never open the
|
||||||
// file again: nothing holds it any more, so a reopen would
|
// file again: nothing holds it any more, so a reopen would
|
||||||
@@ -228,6 +232,7 @@ func newArchiveWriter(
|
|||||||
path: path,
|
path: path,
|
||||||
log: log,
|
log: log,
|
||||||
debounce: archiveReopenDebounce,
|
debounce: archiveReopenDebounce,
|
||||||
|
now: time.Now,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -263,7 +268,7 @@ func (w *archiveWriter) write(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if time.Since(w.lastReopen) >= w.debounce {
|
if w.now().Sub(w.lastReopen) >= w.debounce {
|
||||||
return w.reopen(expiry)
|
return w.reopen(expiry)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -323,7 +328,7 @@ func (w *archiveWriter) openMode(
|
|||||||
}
|
}
|
||||||
|
|
||||||
w.db = gdb
|
w.db = gdb
|
||||||
w.lastReopen = time.Now()
|
w.lastReopen = w.now()
|
||||||
w.reopens++
|
w.reopens++
|
||||||
|
|
||||||
if expiry > 0 {
|
if expiry > 0 {
|
||||||
|
|||||||
@@ -184,13 +184,20 @@ func TestArchiveWriter_RecreatesAfterRemoval(
|
|||||||
func TestArchiveWriter_ReopenDebounce(t *testing.T) {
|
func TestArchiveWriter_ReopenDebounce(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
// A generous debounce keeps the two rapid writes inside
|
const debounce = 2 * time.Second
|
||||||
// the window even on a heavily loaded test machine.
|
|
||||||
path := filepath.Join(t.TempDir(), "archive-wh.db")
|
path := filepath.Join(t.TempDir(), "archive-wh.db")
|
||||||
w := delivery.NewExportArchiveWriter(
|
w := delivery.NewExportArchiveWriter(
|
||||||
path, archiveTestLogger(), 2*time.Second,
|
path, archiveTestLogger(), debounce,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// The writer reads the time from this clock, which only the
|
||||||
|
// test moves, so how long the host takes between writes
|
||||||
|
// cannot change the result.
|
||||||
|
now := time.Now()
|
||||||
|
|
||||||
|
w.SetNow(func() time.Time { return now })
|
||||||
|
|
||||||
require.NoError(t, w.Write(
|
require.NoError(t, w.Write(
|
||||||
delivery.ExportArchivedEvent{EventID: "a"}, 0,
|
delivery.ExportArchivedEvent{EventID: "a"}, 0,
|
||||||
))
|
))
|
||||||
@@ -202,7 +209,7 @@ func TestArchiveWriter_ReopenDebounce(t *testing.T) {
|
|||||||
// initial open — no extra close/reopen.
|
// initial open — no extra close/reopen.
|
||||||
assert.Equal(t, 1, w.Reopens())
|
assert.Equal(t, 1, w.Reopens())
|
||||||
|
|
||||||
time.Sleep(2100 * time.Millisecond)
|
now = now.Add(debounce)
|
||||||
|
|
||||||
require.NoError(t, w.Write(
|
require.NoError(t, w.Write(
|
||||||
delivery.ExportArchivedEvent{EventID: "c"}, 0,
|
delivery.ExportArchivedEvent{EventID: "c"}, 0,
|
||||||
|
|||||||
Reference in New Issue
Block a user