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  }