]> git.giacomolli.uk - onechat/commitdiff
Remove two timing gaps from the memory tests
authorAnderson A. Giacomolli <agiacomolli@gmail.com>
Fri, 6 Nov 2026 15:19:24 +0000 (12:19 -0300)
committerAnderson A. Giacomolli <agiacomolli@gmail.com>
Fri, 6 Nov 2026 15:19:24 +0000 (12:19 -0300)
The build limit test opens the gate of the fake summarizer only after
all 8 builds run, so its peak count no longer depends on goroutine
timing. The synthetic log test measures each view as the append did,
with the newest line as the pending mark, because the leaf of the new
message can be built before the check reads the view.

Issue: beb9a70

memory_test.go
replay_test.go

index e8682205933daa7feefea465948b999f3f6862f4..ddbb014030f7cc26bf7f63fc5b128cb047ad05a9 100644 (file)
@@ -11,6 +11,7 @@ import (
        "strings"
        "sync"
        "testing"
+       "time"
        "unicode/utf8"
 
        "github.com/stretchr/testify/require"
@@ -105,6 +106,10 @@ func TestMemoryRunsAtMostEightBuilds(t *testing.T) {
        })
        require.Equal(t, []nodeKey{{0, 0}, {0, 1}, {0, 2}, {0, 3}, {0, 4}, {0, 5}, {0, 6}, {0, 7}}, running)
 
+       require.Eventually(t, func() bool {
+               return summarizer.Active() == maxBuilds
+       }, 10*time.Second, time.Millisecond)
+
        close(summarizer.gate)
        require.NoError(t, memory.Wait(t.Context()))
        require.Equal(t, maxBuilds, summarizer.peak)
@@ -350,6 +355,14 @@ func (f *fakeSummarizer) SetFailing(failing bool) {
        f.failing = failing
 }
 
+// Active returns the number of tasks that run now.
+func (f *fakeSummarizer) Active() int {
+       f.mutex.Lock()
+       defer f.mutex.Unlock()
+
+       return f.active
+}
+
 // Tasks returns the tasks so far.
 func (f *fakeSummarizer) Tasks() []Task {
        f.mutex.Lock()
index 4151d7ee2337e568bce30aa7b88b7ddf41c5be35..f01cd639e5650dc01b5ebcc86b780d23814fdd5a 100644 (file)
@@ -96,19 +96,20 @@ func syntheticText(id, size int) string {
        return head + strings.Repeat(words, max(1, (size-len(head))/len(words)))
 }
 
-// requireViews checks the views after a new message, while no build changes the
-// tree. Each view is at most its high limit, and a batch merges the chat view
-// to its low limit. It returns the size of the chat view and if a batch merged
-// it, from the number of lines before the message.
+// requireViews checks the views after a new message. Each view is at most its
+// high limit, and a batch merges the chat view to its low limit. The leaf of
+// the new message can be built after the append, so the sizes count it as the
+// pending mark, as the append did. It returns the size of the chat view and if
+// a batch merged it, from the number of lines before the message.
 func requireViews(t *testing.T, memory *Memory, lines int) (int, bool) {
        t.Helper()
 
        memory.mutex.Lock()
        defer memory.mutex.Unlock()
 
-       size := memory.chat.Size(memory.tree)
+       size := appendSize(memory.chat, memory.tree)
        require.LessOrEqual(t, size, chatHigh)
-       require.LessOrEqual(t, memory.cview.Size(memory.tree), compactionHigh)
+       require.LessOrEqual(t, appendSize(memory.cview, memory.tree), compactionHigh)
 
        merged := len(memory.chat.lines) < lines
        if merged {
@@ -150,6 +151,12 @@ func requireOnlySummaries(t *testing.T, memory *Memory) {
        }
 }
 
+// appendSize returns the size of view with its last line as the pending mark.
+func appendSize(view *View, tree nodeReader) int {
+       last := view.lines[len(view.lines)-1]
+       return view.Size(tree) - lineSize(tree, last) + len(pending)
+}
+
 // viewLines returns the number of lines in the chat view of memory.
 func viewLines(memory *Memory) int {
        memory.mutex.Lock()