github.com/cilium/cilium@v1.16.2/pkg/node/local_node_store_test.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Cilium 3 4 package node_test 5 6 import ( 7 "context" 8 "slices" 9 "sync" 10 "testing" 11 "time" 12 13 "github.com/cilium/hive/cell" 14 "github.com/cilium/hive/hivetest" 15 16 "github.com/cilium/cilium/pkg/hive" 17 . "github.com/cilium/cilium/pkg/node" 18 ) 19 20 type testSynchronizer struct{ identity chan uint32 } 21 22 func (testSynchronizer) InitLocalNode(ctx context.Context, n *LocalNode) error { 23 n.NodeIdentity = 1 24 return nil 25 } 26 27 func (ts testSynchronizer) SyncLocalNode(ctx context.Context, lns *LocalNodeStore) { 28 id := <-ts.identity 29 lns.Update(func(n *LocalNode) { n.NodeIdentity = id }) 30 <-ctx.Done() 31 } 32 33 func TestLocalNodeStore(t *testing.T) { 34 var waitObserve sync.WaitGroup 35 var observed []uint32 36 expected := []uint32{1, 2, 3, 4, 5} 37 38 waitObserve.Add(1) 39 40 ts := testSynchronizer{identity: make(chan uint32, 1)} 41 42 // observe observes changes to the LocalNodeStore and completes 43 // waitObserve after the last change has been observed. 44 observe := func(store *LocalNodeStore) { 45 store.Observe(context.TODO(), 46 func(n LocalNode) { 47 observed = append(observed, n.NodeIdentity) 48 49 if n.NodeIdentity == expected[len(expected)-1] { 50 waitObserve.Done() 51 } 52 }, 53 func(err error) {}, 54 ) 55 } 56 57 // update adds a start hook to the application that modifies 58 // the local node. 59 update := func(lc cell.Lifecycle, store *LocalNodeStore) { 60 lc.Append(cell.Hook{ 61 OnStart: func(cell.HookContext) error { 62 // emit 2, 3, 4, 5 63 for _, i := range expected[1:] { 64 if i == 5 { 65 ts.identity <- i 66 continue 67 } 68 69 store.Update(func(n *LocalNode) { 70 n.NodeIdentity = i 71 }) 72 } 73 return nil 74 }, 75 }) 76 } 77 78 hive := hive.New( 79 cell.Provide(NewLocalNodeStore), 80 81 cell.Provide(func() LocalNodeSynchronizer { return ts }), 82 cell.Invoke(observe), 83 cell.Invoke(update), 84 ) 85 86 ctx, cancel := context.WithTimeout(context.Background(), time.Minute) 87 defer cancel() 88 89 tlog := hivetest.Logger(t) 90 if err := hive.Start(tlog, ctx); err != nil { 91 t.Fatalf("Failed to start: %s", err) 92 } 93 94 // Wait until all values have been observed 95 waitObserve.Wait() 96 97 if err := hive.Stop(tlog, ctx); err != nil { 98 t.Fatalf("Failed to stop: %s", err) 99 } 100 101 if !slices.Equal(observed, expected) { 102 t.Fatalf("Unexpected values observed: %v, expected: %v", observed, expected) 103 } 104 } 105 106 func BenchmarkLocalNodeStoreGet(b *testing.B) { 107 ctx := context.Background() 108 lns := NewTestLocalNodeStore(LocalNode{}) 109 110 b.ReportAllocs() 111 b.ResetTimer() 112 113 for i := 0; i < b.N; i++ { 114 _, _ = lns.Get(ctx) 115 } 116 }