github.com/cilium/cilium@v1.16.2/pkg/service/reconciler_test.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Cilium 3 4 package service 5 6 import ( 7 "context" 8 "errors" 9 "net/netip" 10 "testing" 11 "time" 12 13 "github.com/cilium/hive/cell" 14 "github.com/cilium/hive/hivetest" 15 "github.com/cilium/statedb" 16 "github.com/stretchr/testify/require" 17 "go.uber.org/goleak" 18 "k8s.io/apimachinery/pkg/util/sets" 19 20 "github.com/cilium/cilium/pkg/datapath/tables" 21 "github.com/cilium/cilium/pkg/hive" 22 "github.com/cilium/cilium/pkg/lock" 23 ) 24 25 type mockSyncNodePort struct { 26 lock.Mutex 27 errToReturn error 28 addrs sets.Set[netip.Addr] 29 success bool 30 } 31 32 // SyncNodePortFrontends implements syncNodePort. 33 func (m *mockSyncNodePort) SyncNodePortFrontends(addrs sets.Set[netip.Addr]) error { 34 m.Lock() 35 defer m.Unlock() 36 m.addrs = addrs 37 m.success = m.errToReturn == nil 38 return m.errToReturn 39 } 40 41 var _ syncNodePort = &mockSyncNodePort{} 42 43 func TestServiceReconciler(t *testing.T) { 44 defer goleak.VerifyNone(t, goleak.IgnoreCurrent()) 45 46 mock := &mockSyncNodePort{ 47 errToReturn: nil, 48 addrs: nil, 49 } 50 var ( 51 db *statedb.DB 52 nodeAddrs statedb.RWTable[tables.NodeAddress] 53 ) 54 55 h := hive.New( 56 cell.Module("test", "test", 57 cell.Provide( 58 tables.NewNodeAddressTable, 59 statedb.RWTable[tables.NodeAddress].ToTable, 60 ), 61 cell.Invoke(statedb.RegisterTable[tables.NodeAddress]), 62 cell.Provide(func() syncNodePort { return mock }), 63 cell.Invoke(registerServiceReconciler), 64 cell.Invoke(func(d *statedb.DB, na statedb.RWTable[tables.NodeAddress]) { 65 db = d 66 nodeAddrs = na 67 }), 68 ), 69 ) 70 71 tlog := hivetest.Logger(t) 72 require.NoError(t, h.Start(tlog, context.TODO()), "Start") 73 74 mock.Lock() 75 mock.errToReturn = errors.New("fail") 76 mock.Unlock() 77 78 wtxn := db.WriteTxn(nodeAddrs) 79 nodeAddrs.Insert( 80 wtxn, 81 tables.NodeAddress{ 82 Addr: netip.MustParseAddr("1.2.3.4"), 83 NodePort: true, 84 Primary: true, 85 DeviceName: "test", 86 }, 87 ) 88 wtxn.Commit() 89 90 require.Eventually(t, 91 func() bool { 92 mock.Lock() 93 defer mock.Unlock() 94 return len(mock.addrs) == 1 && !mock.success 95 }, time.Second, 10*time.Millisecond) 96 97 mock.Lock() 98 mock.errToReturn = nil 99 mock.Unlock() 100 101 require.Eventually(t, 102 func() bool { 103 mock.Lock() 104 defer mock.Unlock() 105 return mock.success 106 }, time.Second, 10*time.Millisecond) 107 108 require.NoError(t, h.Stop(tlog, context.TODO()), "Stop") 109 110 }