]> git.giacomolli.uk - onechat/blobdiff - memory_test.go
Fix two comments of the Telegram API and the view
[onechat] / memory_test.go
index 8b418d860d376f55f672fcb030215c0c34a1fba4..001f852293d427e053e5f6e964f6e741147cf0be 100644 (file)
@@ -1,18 +1,14 @@
 package main
 
 import (
 package main
 
 import (
-       "context"
-       "errors"
        "fmt"
        "maps"
        "os"
        "path/filepath"
        "slices"
        "strings"
        "fmt"
        "maps"
        "os"
        "path/filepath"
        "slices"
        "strings"
-       "sync"
        "testing"
        "time"
        "testing"
        "time"
-       "unicode/utf8"
 
        "github.com/stretchr/testify/require"
 )
 
        "github.com/stretchr/testify/require"
 )
@@ -121,17 +117,17 @@ func TestMemoryRunsAtMostEightBuilds(t *testing.T) {
        }()
 
        for n := range 12 {
        }()
 
        for n := range 12 {
-               _, err = memory.Append("echo", longText(n))
+               _, err = memory.Append("echo", memoryLongText(n))
                require.NoError(t, err)
        }
 
        memory.mutex.Lock()
        running := slices.Collect(maps.Keys(memory.queue.running))
        memory.mutex.Unlock()
                require.NoError(t, err)
        }
 
        memory.mutex.Lock()
        running := slices.Collect(maps.Keys(memory.queue.running))
        memory.mutex.Unlock()
-       slices.SortFunc(running, func(a, b nodeKey) int {
+       slices.SortFunc(running, func(a, b NodeKey) int {
                return a.index - b.index
        })
                return a.index - b.index
        })
-       require.Equal(t, []nodeKey{{0, 0}, {0, 1}, {0, 2}, {0, 3}, {0, 4}, {0, 5}, {0, 6}, {0, 7}}, running)
+       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() == buildMax
 
        require.Eventually(t, func() bool {
                return summarizer.Active() == buildMax
@@ -143,7 +139,7 @@ func TestMemoryRunsAtMostEightBuilds(t *testing.T) {
 
        for level, count := range []int{12, 6, 3, 1} {
                for index := range count {
 
        for level, count := range []int{12, 6, 3, 1} {
                for index := range count {
-                       require.True(t, isBuilt(t, memory.tree, level, index), "node (%d, %d)", level, index)
+                       require.True(t, treeIsBuilt(t, memory.tree, level, index), "node (%d, %d)", level, index)
                }
        }
 }
                }
        }
 }
@@ -159,7 +155,7 @@ func TestMemoryStartsALeafAfterFewerThanEightUnbuilt(t *testing.T) {
        }()
 
        for n := range 9 {
        }()
 
        for n := range 9 {
-               _, err = memory.Append("echo", longText(n))
+               _, err = memory.Append("echo", memoryLongText(n))
                require.NoError(t, err)
        }
 
                require.NoError(t, err)
        }
 
@@ -168,14 +164,14 @@ func TestMemoryStartsALeafAfterFewerThanEightUnbuilt(t *testing.T) {
                require.Less(t, task.Index, 8)
        }
 
                require.Less(t, task.Index, 8)
        }
 
-       require.False(t, isBuilt(t, memory.tree, 0, 8))
+       require.False(t, treeIsBuilt(t, memory.tree, 0, 8))
        summarizer.SetFailing(false)
 
        _, err = memory.Append("user", "retry")
        require.NoError(t, err)
        require.NoError(t, memory.Wait(t.Context()))
        summarizer.SetFailing(false)
 
        _, err = memory.Append("user", "retry")
        require.NoError(t, err)
        require.NoError(t, memory.Wait(t.Context()))
-       require.True(t, isBuilt(t, memory.tree, 0, 8))
-       require.True(t, isBuilt(t, memory.tree, 3, 0))
+       require.True(t, treeIsBuilt(t, memory.tree, 0, 8))
+       require.True(t, treeIsBuilt(t, memory.tree, 3, 0))
 }
 
 func TestMemoryMergesAfterBothHalves(t *testing.T) {
 }
 
 func TestMemoryMergesAfterBothHalves(t *testing.T) {
@@ -187,21 +183,21 @@ func TestMemoryMergesAfterBothHalves(t *testing.T) {
                require.NoError(t, memory.Close())
        }()
 
                require.NoError(t, memory.Close())
        }()
 
-       _, err = memory.Append("echo", longText(0))
+       _, err = memory.Append("echo", memoryLongText(0))
        require.NoError(t, err)
        require.NoError(t, memory.Wait(t.Context()))
 
        require.NoError(t, err)
        require.NoError(t, memory.Wait(t.Context()))
 
-       _, err = memory.Append("echo", longText(1))
+       _, err = memory.Append("echo", memoryLongText(1))
        require.NoError(t, err)
        require.NoError(t, memory.Wait(t.Context()))
        require.Len(t, summarizer.Tasks(), 3)
 
        require.NoError(t, err)
        require.NoError(t, memory.Wait(t.Context()))
        require.Len(t, summarizer.Tasks(), 3)
 
-       left := readNode(t, memory.tree, 0, 0)
-       right := readNode(t, memory.tree, 0, 1)
+       left := treeReadNode(t, memory.tree, 0, 0)
+       right := treeReadNode(t, memory.tree, 0, 1)
        merge := summarizer.Tasks()[2]
        require.Equal(t, []string{left.Text, right.Text}, merge.Input)
        require.Equal(t, "<chat>\n0+1|"+left.Text+"\n1+1|"+right.Text+"\n</chat>", merge.Context)
        merge := summarizer.Tasks()[2]
        require.Equal(t, []string{left.Text, right.Text}, merge.Input)
        require.Equal(t, "<chat>\n0+1|"+left.Text+"\n1+1|"+right.Text+"\n</chat>", merge.Context)
-       require.True(t, isBuilt(t, memory.tree, 1, 0))
+       require.True(t, treeIsBuilt(t, memory.tree, 1, 0))
 }
 
 func TestMemoryRestartRestoresTheQueue(t *testing.T) {
 }
 
 func TestMemoryRestartRestoresTheQueue(t *testing.T) {
@@ -213,7 +209,7 @@ func TestMemoryRestartRestoresTheQueue(t *testing.T) {
        require.NoError(t, err)
 
        for n := range 4 {
        require.NoError(t, err)
 
        for n := range 4 {
-               _, err = memory.Append("echo", longText(n))
+               _, err = memory.Append("echo", memoryLongText(n))
                require.NoError(t, err)
        }
 
                require.NoError(t, err)
        }
 
@@ -228,7 +224,7 @@ func TestMemoryRestartRestoresTheQueue(t *testing.T) {
        }()
 
        require.NoError(t, memory.Wait(t.Context()))
        }()
 
        require.NoError(t, memory.Wait(t.Context()))
-       require.True(t, isBuilt(t, memory.tree, 2, 0))
+       require.True(t, treeIsBuilt(t, memory.tree, 2, 0))
 }
 
 func TestMemoryBuildsFreeParents(t *testing.T) {
 }
 
 func TestMemoryBuildsFreeParents(t *testing.T) {
@@ -244,7 +240,7 @@ func TestMemoryBuildsFreeParents(t *testing.T) {
                require.NoError(t, err)
        }
 
                require.NoError(t, err)
        }
 
-       node := readNode(t, memory.tree, 2, 0)
+       node := treeReadNode(t, memory.tree, 2, 0)
        require.Equal(t, "user: a\nuser: b\nuser: c\nuser: d", node.Text)
 }
 
        require.Equal(t, "user: a\nuser: b\nuser: c\nuser: d", node.Text)
 }
 
@@ -258,7 +254,7 @@ func TestMemoryKeepsALongMessageOutOfTheView(t *testing.T) {
                require.NoError(t, memory.Close())
        }()
 
                require.NoError(t, memory.Close())
        }()
 
-       _, err = memory.Append("echo", longText(0))
+       _, err = memory.Append("echo", memoryLongText(0))
        require.NoError(t, err)
        require.NoError(t, memory.Wait(t.Context()))
        require.Equal(t, "<chat>\n0+1|"+viewPending+"\n</chat>", memory.View())
        require.NoError(t, err)
        require.NoError(t, memory.Wait(t.Context()))
        require.Equal(t, "<chat>\n0+1|"+viewPending+"\n</chat>", memory.View())
@@ -269,7 +265,7 @@ func TestMemoryKeepsALongMessageOutOfTheView(t *testing.T) {
        require.NoError(t, err)
        require.NoError(t, memory.Wait(t.Context()))
 
        require.NoError(t, err)
        require.NoError(t, memory.Wait(t.Context()))
 
-       task, err := memory.task(nodeKey{0, 0})
+       task, err := memory.task(NodeKey{0, 0})
        require.NoError(t, err)
        require.Equal(t, "<chat>\n0+1|"+fakeLine(task)+"\n1+1|user: again\n</chat>", memory.View())
 }
        require.NoError(t, err)
        require.Equal(t, "<chat>\n0+1|"+fakeLine(task)+"\n1+1|user: again\n</chat>", memory.View())
 }
@@ -309,93 +305,10 @@ func TestMemoryRefusesToRebuildAMissingView(t *testing.T) {
        require.NoError(t, os.Remove(filepath.Join(root, "view.json")))
 
        _, err = openMemory(t.Context(), root, clock.Now, newFakeSummarizer())
        require.NoError(t, os.Remove(filepath.Join(root, "view.json")))
 
        _, err = openMemory(t.Context(), root, clock.Now, newFakeSummarizer())
-       require.ErrorIs(t, err, errNoView)
+       require.ErrorIs(t, err, errMemoryNoView)
 }
 
 }
 
-// fakeSummarizer builds each node with a line of fakeLine. It fails each task
-// while failing is true, and each task waits for gate when gate is not nil.
-type fakeSummarizer struct {
-       mutex   sync.Mutex
-       gate    chan struct{}
-       failing bool
-       active  int
-       peak    int
-       tasks   []Task
-}
-
-func newFakeSummarizer() *fakeSummarizer {
-       return &fakeSummarizer{}
-}
-
-func (f *fakeSummarizer) Summarize(ctx context.Context, task Task) (string, error) {
-       f.mutex.Lock()
-       f.tasks = append(f.tasks, task)
-       f.active++
-       f.peak = max(f.peak, f.active)
-       fail := f.failing
-       f.mutex.Unlock()
-
-       defer func() {
-               f.mutex.Lock()
-               f.active--
-               f.mutex.Unlock()
-       }()
-
-       if f.gate != nil {
-               select {
-               case <-f.gate:
-               case <-ctx.Done():
-                       return "", ctx.Err()
-               }
-       }
-
-       if fail {
-               return "", errors.New("fake failure")
-       }
-
-       return fakeLine(task), nil
-}
-
-// fakeLine returns a line of nodeBytes bytes or less that names the node and
-// starts with the input. A real line of this size makes each merge a model
-// call.
-func fakeLine(task Task) string {
-       count := 1 << task.Level
-       line := fmt.Sprintf("summary %d+%d: %s", task.Index*count, count, strings.Join(task.Input, " "))
-       line = strings.ReplaceAll(line, "\n", " ")
-       for len(line) > nodeBytes-12 {
-               _, size := utf8.DecodeLastRuneInString(line)
-               line = line[:len(line)-size]
-       }
-
-       return line
-}
-
-// longText returns a text that is too long for its own node.
-func longText(n int) string {
+// memoryLongText returns a text that is too long for its own node.
+func memoryLongText(n int) string {
        return fmt.Sprintf("long %d ", n) + strings.Repeat("x", nodeBytes)
 }
        return fmt.Sprintf("long %d ", n) + strings.Repeat("x", nodeBytes)
 }
-
-// SetFailing makes the next tasks fail or not.
-func (f *fakeSummarizer) SetFailing(failing bool) {
-       f.mutex.Lock()
-       defer f.mutex.Unlock()
-
-       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()
-       defer f.mutex.Unlock()
-
-       return slices.Clone(f.tasks)
-}