From 6de64911fb91e7ac2dea8c5545f312c07ef88ab0 Mon Sep 17 00:00:00 2001 From: Michael Eischer Date: Sat, 22 Nov 2025 22:14:46 +0100 Subject: [PATCH] data: test TreeFinder --- internal/data/tree.go | 5 ++++ internal/data/tree_test.go | 52 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/internal/data/tree.go b/internal/data/tree.go index e5777673f..eafb23adf 100644 --- a/internal/data/tree.go +++ b/internal/data/tree.go @@ -123,6 +123,7 @@ type TreeFinder struct { next func() (NodeOrError, bool) stop func() current *Node + last string } func NewTreeFinder(tree TreeNodeIterator) *TreeFinder { @@ -139,6 +140,10 @@ func (t *TreeFinder) Find(name string) (*Node, error) { if t.next == nil { return nil, nil } + if name <= t.last { + return nil, errors.Errorf("name %q is not greater than last name %q", name, t.last) + } + t.last = name // loop until `t.current.Name` is >= name for t.current == nil || t.current.Name < name { current, ok := t.next() diff --git a/internal/data/tree_test.go b/internal/data/tree_test.go index 56752850e..ba1698227 100644 --- a/internal/data/tree_test.go +++ b/internal/data/tree_test.go @@ -224,6 +224,58 @@ func benchmarkLoadTree(t *testing.B, version uint) { } } +func TestTreeFinderNilIterator(t *testing.T) { + finder := data.NewTreeFinder(nil) + defer finder.Close() + node, err := finder.Find("foo") + rtest.OK(t, err) + rtest.Equals(t, node, nil, "finder should return nil node") +} + +func TestTreeFinderError(t *testing.T) { + testErr := errors.New("error") + finder := data.NewTreeFinder(slices.Values([]data.NodeOrError{ + {Node: &data.Node{Name: "a"}, Error: nil}, + {Node: &data.Node{Name: "b"}, Error: nil}, + {Node: nil, Error: testErr}, + })) + defer finder.Close() + node, err := finder.Find("b") + rtest.OK(t, err) + rtest.Equals(t, node.Name, "b", "finder should return node with name b") + + node, err = finder.Find("c") + rtest.Equals(t, err, testErr, "finder should return correcterror") + rtest.Equals(t, node, nil, "finder should return nil node") +} + +func TestTreeFinderNotFound(t *testing.T) { + finder := data.NewTreeFinder(slices.Values([]data.NodeOrError{ + {Node: &data.Node{Name: "a"}, Error: nil}, + })) + defer finder.Close() + node, err := finder.Find("b") + rtest.OK(t, err) + rtest.Equals(t, node, nil, "finder should return nil node") + // must also be ok multiple times + node, err = finder.Find("c") + rtest.OK(t, err) + rtest.Equals(t, node, nil, "finder should return nil node") +} + +func TestTreeFinderWrongOrder(t *testing.T) { + finder := data.NewTreeFinder(slices.Values([]data.NodeOrError{ + {Node: &data.Node{Name: "d"}, Error: nil}, + })) + defer finder.Close() + node, err := finder.Find("b") + rtest.OK(t, err) + rtest.Equals(t, node, nil, "finder should return nil node") + node, err = finder.Find("a") + rtest.Assert(t, strings.Contains(err.Error(), "is not greater than"), "unexpected error: %v", err) + rtest.Equals(t, node, nil, "finder should return nil node") +} + func TestFindTreeDirectory(t *testing.T) { repo := repository.TestRepository(t) sn := data.TestCreateSnapshot(t, repo, parseTimeUTC("2017-07-07 07:07:08"), 3)