github.com/cilium/cilium@v1.16.2/pkg/endpointmanager/manager_test.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Cilium
     3  
     4  package endpointmanager
     5  
     6  import (
     7  	"context"
     8  	"net/netip"
     9  	"sync"
    10  	"testing"
    11  	"time"
    12  
    13  	"github.com/cilium/hive/cell"
    14  	"github.com/stretchr/testify/assert"
    15  	"github.com/stretchr/testify/require"
    16  
    17  	apiv1 "github.com/cilium/cilium/api/v1/models"
    18  	datapath "github.com/cilium/cilium/pkg/datapath/types"
    19  	"github.com/cilium/cilium/pkg/endpoint"
    20  	endpointid "github.com/cilium/cilium/pkg/endpoint/id"
    21  	"github.com/cilium/cilium/pkg/fqdn/restore"
    22  	"github.com/cilium/cilium/pkg/labels"
    23  	"github.com/cilium/cilium/pkg/labelsfilter"
    24  	monitorAPI "github.com/cilium/cilium/pkg/monitor/api"
    25  	"github.com/cilium/cilium/pkg/node"
    26  	"github.com/cilium/cilium/pkg/node/types"
    27  	"github.com/cilium/cilium/pkg/option"
    28  	"github.com/cilium/cilium/pkg/policy"
    29  	testidentity "github.com/cilium/cilium/pkg/testutils/identity"
    30  	testipcache "github.com/cilium/cilium/pkg/testutils/ipcache"
    31  )
    32  
    33  func (mgr *endpointManager) waitEndpointRemoved(ep *endpoint.Endpoint, conf endpoint.DeleteConfig) []error {
    34  	mgr.unexpose(ep)
    35  	ep.Stop()
    36  	return nil
    37  }
    38  
    39  // RemoveAll removes all endpoints from the global maps.
    40  func (mgr *endpointManager) RemoveAll(t testing.TB) {
    41  	mgr.mutex.Lock()
    42  	defer mgr.mutex.Unlock()
    43  	mgr.epIDAllocator.reallocatePool(t)
    44  	mgr.endpoints = map[uint16]*endpoint.Endpoint{}
    45  	mgr.endpointsAux = map[string]*endpoint.Endpoint{}
    46  }
    47  
    48  // WaitEndpointRemoved waits until all operations associated with Remove of
    49  // the endpoint have been completed.
    50  // Note: only used for unit tests, to avoid ep.Delete()
    51  func (mgr *endpointManager) WaitEndpointRemoved(ep *endpoint.Endpoint) {
    52  	mgr.waitEndpointRemoved(ep, endpoint.DeleteConfig{})
    53  }
    54  
    55  type EndpointManagerSuite struct {
    56  	repo *policy.Repository
    57  }
    58  
    59  func setupEndpointManagerSuite(tb testing.TB) *EndpointManagerSuite {
    60  	s := &EndpointManagerSuite{}
    61  	s.repo = policy.NewPolicyRepository(nil, nil, nil)
    62  
    63  	return s
    64  }
    65  
    66  func (s *EndpointManagerSuite) GetPolicyRepository() *policy.Repository {
    67  	return s.repo
    68  }
    69  
    70  func (s *EndpointManagerSuite) QueueEndpointBuild(ctx context.Context, epID uint64) (func(), error) {
    71  	return nil, nil
    72  }
    73  
    74  func (s *EndpointManagerSuite) GetCompilationLock() datapath.CompilationLock {
    75  	return nil
    76  }
    77  
    78  func (s *EndpointManagerSuite) GetCIDRPrefixLengths() (s6, s4 []int) {
    79  	return nil, nil
    80  }
    81  
    82  func (s *EndpointManagerSuite) SendNotification(msg monitorAPI.AgentNotifyMessage) error {
    83  	return nil
    84  }
    85  
    86  func (s *EndpointManagerSuite) Datapath() datapath.Datapath {
    87  	return nil
    88  }
    89  
    90  func (s *EndpointManagerSuite) GetDNSRules(epID uint16) restore.DNSRules {
    91  	return nil
    92  }
    93  
    94  func (s *EndpointManagerSuite) RemoveRestoredDNSRules(epID uint16) {
    95  }
    96  
    97  type DummyRuleCacheOwner struct{}
    98  
    99  func (d *DummyRuleCacheOwner) ClearPolicyConsumers(id uint16) *sync.WaitGroup {
   100  	return &sync.WaitGroup{}
   101  }
   102  
   103  type dummyEpSyncher struct{}
   104  
   105  func (epSync *dummyEpSyncher) RunK8sCiliumEndpointSync(e *endpoint.Endpoint, hr cell.Health) {
   106  }
   107  
   108  func (epSync *dummyEpSyncher) DeleteK8sCiliumEndpointSync(e *endpoint.Endpoint) {
   109  }
   110  
   111  func TestLookup(t *testing.T) {
   112  	s := setupEndpointManagerSuite(t)
   113  
   114  	type args struct {
   115  		id string
   116  	}
   117  	type want struct {
   118  		ep       bool
   119  		err      error
   120  		errCheck assert.ComparisonAssertionFunc
   121  	}
   122  	tests := []struct {
   123  		name      string
   124  		setupArgs func() args
   125  		setupWant func() want
   126  		cm        *apiv1.EndpointChangeRequest
   127  	}{
   128  		{
   129  			name: "endpoint does not exist",
   130  			setupArgs: func() args {
   131  				return args{
   132  					"1234",
   133  				}
   134  			},
   135  			setupWant: func() want {
   136  				return want{
   137  					ep:       false,
   138  					err:      nil,
   139  					errCheck: assert.EqualValues,
   140  				}
   141  			},
   142  		},
   143  		{
   144  			name: "endpoint by cilium local ID",
   145  			cm: &apiv1.EndpointChangeRequest{
   146  				ID: 1234,
   147  			},
   148  			setupArgs: func() args {
   149  				return args{
   150  					endpointid.NewCiliumID(1234),
   151  				}
   152  			},
   153  			setupWant: func() want {
   154  				return want{
   155  					ep:       true,
   156  					err:      nil,
   157  					errCheck: assert.EqualValues,
   158  				}
   159  			},
   160  		},
   161  		{
   162  			name: "endpoint by cilium global ID",
   163  			cm: &apiv1.EndpointChangeRequest{
   164  				ID: 1234,
   165  			},
   166  			setupArgs: func() args {
   167  				return args{
   168  					endpointid.NewID(endpointid.CiliumGlobalIdPrefix, "1234"),
   169  				}
   170  			},
   171  			setupWant: func() want {
   172  				return want{
   173  					err:      ErrUnsupportedID,
   174  					errCheck: assert.EqualValues,
   175  				}
   176  			},
   177  		},
   178  		{
   179  			name: "endpoint by CNI attachment ID",
   180  			cm: &apiv1.EndpointChangeRequest{
   181  				ContainerID:            "1234",
   182  				ContainerInterfaceName: "eth0",
   183  			},
   184  			setupArgs: func() args {
   185  				return args{
   186  					endpointid.NewCNIAttachmentID("1234", "eth0"),
   187  				}
   188  			},
   189  			setupWant: func() want {
   190  				return want{
   191  					ep:       true,
   192  					err:      nil,
   193  					errCheck: assert.EqualValues,
   194  				}
   195  			},
   196  		},
   197  		{
   198  			name: "endpoint by CNI attachment ID without interface",
   199  			cm: &apiv1.EndpointChangeRequest{
   200  				ContainerID: "1234",
   201  			},
   202  			setupArgs: func() args {
   203  				return args{
   204  					endpointid.NewCNIAttachmentID("1234", ""),
   205  				}
   206  			},
   207  			setupWant: func() want {
   208  				return want{
   209  					ep:       true,
   210  					err:      nil,
   211  					errCheck: assert.EqualValues,
   212  				}
   213  			},
   214  		},
   215  		{
   216  			name: "endpoint by container ID (deprecated)",
   217  			cm: &apiv1.EndpointChangeRequest{
   218  				ContainerID: "1234",
   219  			},
   220  			setupArgs: func() args {
   221  				return args{
   222  					endpointid.NewID(endpointid.ContainerIdPrefix, "1234"),
   223  				}
   224  			},
   225  			setupWant: func() want {
   226  				return want{
   227  					ep:       true,
   228  					err:      nil,
   229  					errCheck: assert.EqualValues,
   230  				}
   231  			},
   232  		},
   233  		{
   234  			name: "endpoint by docker endpoint ID",
   235  			cm: &apiv1.EndpointChangeRequest{
   236  				DockerEndpointID: "1234",
   237  			},
   238  			setupArgs: func() args {
   239  				return args{
   240  					endpointid.NewID(endpointid.DockerEndpointPrefix, "1234"),
   241  				}
   242  			},
   243  			setupWant: func() want {
   244  				return want{
   245  					ep:       true,
   246  					err:      nil,
   247  					errCheck: assert.EqualValues,
   248  				}
   249  			},
   250  		},
   251  		{
   252  			name: "endpoint by container name (deprecated)",
   253  			cm: &apiv1.EndpointChangeRequest{
   254  				ContainerName: "foo",
   255  			},
   256  			setupArgs: func() args {
   257  				return args{
   258  					endpointid.NewID(endpointid.ContainerNamePrefix, "foo"),
   259  				}
   260  			},
   261  			setupWant: func() want {
   262  				return want{
   263  					ep:       true,
   264  					err:      nil,
   265  					errCheck: assert.EqualValues,
   266  				}
   267  			},
   268  		},
   269  		{
   270  			name: "endpoint by pod name",
   271  			cm: &apiv1.EndpointChangeRequest{
   272  				K8sNamespace: "default",
   273  				K8sPodName:   "foo",
   274  			},
   275  			setupArgs: func() args {
   276  				return args{
   277  					endpointid.NewID(endpointid.PodNamePrefix, "default/foo"),
   278  				}
   279  			},
   280  			setupWant: func() want {
   281  				return want{
   282  					ep:       true,
   283  					err:      nil,
   284  					errCheck: assert.EqualValues,
   285  				}
   286  			},
   287  		},
   288  		{
   289  			name: "endpoint by cep name",
   290  			cm: &apiv1.EndpointChangeRequest{
   291  				K8sNamespace: "default",
   292  				K8sPodName:   "foo",
   293  			},
   294  			setupArgs: func() args {
   295  				return args{
   296  					endpointid.NewID(endpointid.CEPNamePrefix, "default/foo"),
   297  				}
   298  			},
   299  			setupWant: func() want {
   300  				return want{
   301  					ep:       true,
   302  					err:      nil,
   303  					errCheck: assert.EqualValues,
   304  				}
   305  			},
   306  		},
   307  		{
   308  			name: "endpoint by cep name with interface",
   309  			cm: &apiv1.EndpointChangeRequest{
   310  				K8sNamespace:           "default",
   311  				K8sPodName:             "foo",
   312  				ContainerInterfaceName: "net1",
   313  			},
   314  			setupArgs: func() args {
   315  				return args{
   316  					endpointid.NewID(endpointid.CEPNamePrefix, "default/foo"),
   317  				}
   318  			},
   319  			setupWant: func() want {
   320  				return want{
   321  					ep:       true,
   322  					err:      nil,
   323  					errCheck: assert.EqualValues}
   324  			},
   325  		},
   326  		{
   327  			name: "endpoint by cep name with interface and disabled legacy identifers",
   328  			cm: &apiv1.EndpointChangeRequest{
   329  				K8sNamespace:             "default",
   330  				K8sPodName:               "foo",
   331  				ContainerInterfaceName:   "net1",
   332  				DisableLegacyIdentifiers: true,
   333  			},
   334  			setupArgs: func() args {
   335  				return args{
   336  					endpointid.NewID(endpointid.CEPNamePrefix, "default/foo-net1"),
   337  				}
   338  			},
   339  			setupWant: func() want {
   340  				return want{
   341  					ep:       true,
   342  					err:      nil,
   343  					errCheck: assert.EqualValues,
   344  				}
   345  			},
   346  		},
   347  		{
   348  			name: "endpoint by ipv4",
   349  			cm: &apiv1.EndpointChangeRequest{
   350  				Addressing: &apiv1.AddressPair{
   351  					IPV4: "127.0.0.1",
   352  				},
   353  			},
   354  			setupArgs: func() args {
   355  				return args{
   356  					endpointid.NewID(endpointid.IPv4Prefix, "127.0.0.1"),
   357  				}
   358  			},
   359  			setupWant: func() want {
   360  				return want{
   361  					ep:       true,
   362  					err:      nil,
   363  					errCheck: assert.EqualValues,
   364  				}
   365  			},
   366  		},
   367  		{
   368  			name: "invalid ID",
   369  			setupArgs: func() args {
   370  				return args{
   371  					endpointid.NewID("foo", "bar"),
   372  				}
   373  			},
   374  			setupWant: func() want {
   375  				return want{
   376  					err:      nil,
   377  					errCheck: assert.NotEqualValues,
   378  				}
   379  			},
   380  		},
   381  		{
   382  			name: "invalid cilium ID",
   383  			setupArgs: func() args {
   384  				return args{
   385  					endpointid.NewID(endpointid.CiliumLocalIdPrefix, "bar"),
   386  				}
   387  			},
   388  			setupWant: func() want {
   389  				return want{
   390  					err:      nil,
   391  					errCheck: assert.NotEqualValues,
   392  				}
   393  			},
   394  		},
   395  		{
   396  			name: "invalid lookup with container id with disabled legacy identifiers",
   397  			cm: &apiv1.EndpointChangeRequest{
   398  				ContainerID:              "1234",
   399  				DisableLegacyIdentifiers: true,
   400  			},
   401  			setupArgs: func() args {
   402  				return args{
   403  					endpointid.NewID(endpointid.ContainerIdPrefix, "1234"),
   404  				}
   405  			},
   406  			setupWant: func() want {
   407  				return want{
   408  					ep:       false,
   409  					err:      nil,
   410  					errCheck: assert.EqualValues,
   411  				}
   412  			},
   413  		},
   414  	}
   415  	for _, tt := range tests {
   416  		t.Run(tt.name, func(t *testing.T) {
   417  			var ep *endpoint.Endpoint
   418  			var err error
   419  			mgr := New(&dummyEpSyncher{}, nil, nil)
   420  			if tt.cm != nil {
   421  				ep, err = endpoint.NewEndpointFromChangeModel(context.Background(), s, s, testipcache.NewMockIPCache(), &endpoint.FakeEndpointProxy{}, testidentity.NewMockIdentityAllocator(nil), tt.cm)
   422  				require.NoErrorf(t, err, "Test Name: %s", tt.name)
   423  				err = mgr.expose(ep)
   424  				require.NoErrorf(t, err, "Test Name: %s", tt.name)
   425  			}
   426  
   427  			args := tt.setupArgs()
   428  			want := tt.setupWant()
   429  			got, err := mgr.Lookup(args.id)
   430  			want.errCheck(t, want.err, err, "Test Name: %s", tt.name)
   431  			if want.ep {
   432  				require.EqualValuesf(t, ep, got, "Test Name: %s", tt.name)
   433  			} else {
   434  				require.Nilf(t, got, "Test Name: %s", tt.name)
   435  			}
   436  		})
   437  	}
   438  }
   439  
   440  func TestLookupCiliumID(t *testing.T) {
   441  	s := setupEndpointManagerSuite(t)
   442  
   443  	mgr := New(&dummyEpSyncher{}, nil, nil)
   444  	ep := endpoint.NewTestEndpointWithState(t, s, s, testipcache.NewMockIPCache(), &endpoint.FakeEndpointProxy{}, testidentity.NewMockIdentityAllocator(nil), 2, endpoint.StateReady)
   445  	type args struct {
   446  		id uint16
   447  	}
   448  	type want struct {
   449  		ep *endpoint.Endpoint
   450  	}
   451  	tests := []struct {
   452  		name        string
   453  		setupArgs   func() args
   454  		setupWant   func() want
   455  		preTestRun  func()
   456  		postTestRun func()
   457  	}{
   458  		{
   459  			name: "existing cilium ID",
   460  			preTestRun: func() {
   461  				ep.ID = 1
   462  				require.Nil(t, mgr.expose(ep))
   463  			},
   464  			setupArgs: func() args {
   465  				return args{
   466  					1,
   467  				}
   468  			},
   469  			setupWant: func() want {
   470  				return want{
   471  					ep: ep,
   472  				}
   473  			},
   474  			postTestRun: func() {
   475  				mgr.WaitEndpointRemoved(ep)
   476  				ep.ID = 0
   477  			},
   478  		},
   479  		{
   480  			name: "non-existing cilium ID",
   481  			preTestRun: func() {
   482  			},
   483  			setupArgs: func() args {
   484  				return args{
   485  					1,
   486  				}
   487  			},
   488  			setupWant: func() want {
   489  				return want{
   490  					ep: nil,
   491  				}
   492  			},
   493  			postTestRun: func() {
   494  			},
   495  		},
   496  	}
   497  	for _, tt := range tests {
   498  		tt.preTestRun()
   499  		args := tt.setupArgs()
   500  		want := tt.setupWant()
   501  		got := mgr.LookupCiliumID(args.id)
   502  		exists := mgr.EndpointExists(args.id)
   503  		require.EqualValuesf(t, want.ep, got, "Test Name: %s", tt.name)
   504  		require.Equal(t, want.ep != nil, exists, "Test Name: %s", tt.name)
   505  		tt.postTestRun()
   506  	}
   507  }
   508  
   509  func TestLookupCNIAttachmentID(t *testing.T) {
   510  	s := setupEndpointManagerSuite(t)
   511  
   512  	mgr := New(&dummyEpSyncher{}, nil, nil)
   513  	ep, err := endpoint.NewEndpointFromChangeModel(context.Background(), s, s, testipcache.NewMockIPCache(), &endpoint.FakeEndpointProxy{}, testidentity.NewMockIdentityAllocator(nil), &apiv1.EndpointChangeRequest{
   514  		ContainerID:            "foo",
   515  		ContainerInterfaceName: "bar",
   516  	})
   517  	require.Nil(t, err)
   518  	require.Nil(t, mgr.expose(ep))
   519  
   520  	good := mgr.LookupCNIAttachmentID("foo:bar")
   521  	require.EqualValues(t, ep, good)
   522  
   523  	bad := mgr.LookupCNIAttachmentID("foo")
   524  	require.Nil(t, bad)
   525  
   526  	bad = mgr.LookupCNIAttachmentID("asdf")
   527  	require.Nil(t, bad)
   528  }
   529  
   530  func TestLookupIPv4(t *testing.T) {
   531  	s := setupEndpointManagerSuite(t)
   532  
   533  	mgr := New(&dummyEpSyncher{}, nil, nil)
   534  	ep := endpoint.NewTestEndpointWithState(t, s, s, testipcache.NewMockIPCache(), &endpoint.FakeEndpointProxy{}, testidentity.NewMockIdentityAllocator(nil), 4, endpoint.StateReady)
   535  	type args struct {
   536  		ip string
   537  	}
   538  	type want struct {
   539  		ep *endpoint.Endpoint
   540  	}
   541  	tests := []struct {
   542  		name        string
   543  		setupArgs   func() args
   544  		setupWant   func() want
   545  		preTestRun  func()
   546  		postTestRun func()
   547  	}{
   548  		{
   549  			name: "existing LookupIPv4",
   550  			preTestRun: func() {
   551  				ep.IPv4 = netip.MustParseAddr("127.0.0.1")
   552  				require.Nil(t, mgr.expose(ep))
   553  			},
   554  			setupArgs: func() args {
   555  				return args{
   556  					"127.0.0.1",
   557  				}
   558  			},
   559  			setupWant: func() want {
   560  				return want{
   561  					ep: ep,
   562  				}
   563  			},
   564  			postTestRun: func() {
   565  				mgr.WaitEndpointRemoved(ep)
   566  				ep.IPv4 = netip.Addr{}
   567  			},
   568  		},
   569  		{
   570  			name: "non-existing LookupIPv4",
   571  			preTestRun: func() {
   572  			},
   573  			setupArgs: func() args {
   574  				return args{
   575  					"127.0.0.1",
   576  				}
   577  			},
   578  			setupWant: func() want {
   579  				return want{
   580  					ep: nil,
   581  				}
   582  			},
   583  			postTestRun: func() {
   584  			},
   585  		},
   586  	}
   587  	for _, tt := range tests {
   588  		tt.preTestRun()
   589  		args := tt.setupArgs()
   590  		want := tt.setupWant()
   591  		got := mgr.LookupIPv4(args.ip)
   592  		require.EqualValuesf(t, want.ep, got, "Test Name: %s", tt.name)
   593  		tt.postTestRun()
   594  	}
   595  }
   596  
   597  func TestLookupCEPName(t *testing.T) {
   598  	s := setupEndpointManagerSuite(t)
   599  	mgr := New(&dummyEpSyncher{}, nil, nil)
   600  	type args struct {
   601  		podName string
   602  	}
   603  	type want struct {
   604  		ep *endpoint.Endpoint
   605  	}
   606  	tests := []struct {
   607  		name        string
   608  		cm          apiv1.EndpointChangeRequest
   609  		setupArgs   func() args
   610  		setupWant   func(*endpoint.Endpoint) want
   611  		preTestRun  func(*endpoint.Endpoint)
   612  		postTestRun func(*endpoint.Endpoint)
   613  	}{
   614  		{
   615  			name: "existing pod name",
   616  			cm: apiv1.EndpointChangeRequest{
   617  				K8sNamespace: "default",
   618  				K8sPodName:   "foo",
   619  			},
   620  			preTestRun: func(ep *endpoint.Endpoint) {
   621  				require.Nil(t, mgr.expose(ep))
   622  			},
   623  			setupArgs: func() args {
   624  				return args{
   625  					"default/foo",
   626  				}
   627  			},
   628  			setupWant: func(ep *endpoint.Endpoint) want {
   629  				return want{
   630  					ep: ep,
   631  				}
   632  			},
   633  			postTestRun: func(ep *endpoint.Endpoint) {
   634  				mgr.WaitEndpointRemoved(ep)
   635  			},
   636  		},
   637  		{
   638  			name: "existing pod name with container interface name",
   639  			cm: apiv1.EndpointChangeRequest{
   640  				K8sNamespace:             "default",
   641  				K8sPodName:               "bar",
   642  				ContainerInterfaceName:   "eth1",
   643  				DisableLegacyIdentifiers: true,
   644  			},
   645  			preTestRun: func(ep *endpoint.Endpoint) {
   646  				require.Nil(t, mgr.expose(ep))
   647  			},
   648  			setupArgs: func() args {
   649  				return args{
   650  					"default/bar-eth1",
   651  				}
   652  			},
   653  			setupWant: func(ep *endpoint.Endpoint) want {
   654  				return want{
   655  					ep: ep,
   656  				}
   657  			},
   658  			postTestRun: func(ep *endpoint.Endpoint) {
   659  				mgr.WaitEndpointRemoved(ep)
   660  			},
   661  		},
   662  		{
   663  			name: "non-existing PodName",
   664  			preTestRun: func(ep *endpoint.Endpoint) {
   665  			},
   666  			setupArgs: func() args {
   667  				return args{
   668  					"default/foo",
   669  				}
   670  			},
   671  			setupWant: func(ep *endpoint.Endpoint) want {
   672  				return want{
   673  					ep: nil,
   674  				}
   675  			},
   676  			postTestRun: func(ep *endpoint.Endpoint) {
   677  			},
   678  		},
   679  	}
   680  	for _, tt := range tests {
   681  		ep, err := endpoint.NewEndpointFromChangeModel(context.Background(), s, s, testipcache.NewMockIPCache(), &endpoint.FakeEndpointProxy{}, testidentity.NewMockIdentityAllocator(nil), &tt.cm)
   682  		require.NoErrorf(t, err, "Test Name: %s", tt.name)
   683  		tt.preTestRun(ep)
   684  		args := tt.setupArgs()
   685  		want := tt.setupWant(ep)
   686  		got := mgr.LookupCEPName(args.podName)
   687  		require.EqualValues(t, want.ep, got, "Test Name: %s", tt.name)
   688  		tt.postTestRun(ep)
   689  	}
   690  }
   691  
   692  func TestUpdateReferences(t *testing.T) {
   693  	s := setupEndpointManagerSuite(t)
   694  	var ep *endpoint.Endpoint
   695  	type want struct {
   696  		ep *endpoint.Endpoint
   697  	}
   698  	tests := []struct {
   699  		name      string
   700  		cm        apiv1.EndpointChangeRequest
   701  		setupWant func() want
   702  	}{
   703  		{
   704  			name: "Updating all references",
   705  			cm: apiv1.EndpointChangeRequest{
   706  				K8sNamespace:     "default",
   707  				K8sPodName:       "foo",
   708  				ContainerID:      "container",
   709  				DockerEndpointID: "dockerendpointID",
   710  				Addressing: &apiv1.AddressPair{
   711  					IPV4: "127.0.0.1",
   712  				},
   713  				ContainerName: "containername",
   714  			},
   715  			setupWant: func() want {
   716  				return want{
   717  					ep: ep,
   718  				}
   719  			},
   720  		},
   721  	}
   722  	for _, tt := range tests {
   723  		var err error
   724  		ep, err = endpoint.NewEndpointFromChangeModel(context.Background(), s, s, testipcache.NewMockIPCache(), &endpoint.FakeEndpointProxy{}, testidentity.NewMockIdentityAllocator(nil), &tt.cm)
   725  		require.NoErrorf(t, err, "Test Name: %s", tt.name)
   726  		mgr := New(&dummyEpSyncher{}, nil, nil)
   727  
   728  		err = mgr.expose(ep)
   729  		require.NoErrorf(t, err, "Test Name: %s", tt.name)
   730  		want := tt.setupWant()
   731  		mgr.updateReferencesLocked(ep, ep.Identifiers())
   732  
   733  		ep = mgr.LookupCNIAttachmentID(want.ep.GetCNIAttachmentID())
   734  		require.EqualValues(t, want.ep, ep, "Test Name: %s", tt.name)
   735  
   736  		ep = mgr.lookupDockerEndpoint(want.ep.GetDockerEndpointID())
   737  		require.EqualValues(t, want.ep, ep, "Test Name: %s", tt.name)
   738  
   739  		ep = mgr.LookupIPv4(want.ep.IPv4.String())
   740  		require.EqualValues(t, want.ep, ep, "Test Name: %s", tt.name)
   741  
   742  		ep = mgr.lookupDockerContainerName(want.ep.GetContainerName())
   743  		require.EqualValues(t, want.ep, ep, "Test Name: %s", tt.name)
   744  
   745  		ep = mgr.LookupCEPName(want.ep.GetK8sNamespaceAndCEPName())
   746  		require.EqualValues(t, want.ep, ep, "Test Name: %s", tt.name)
   747  
   748  		eps := mgr.GetEndpointsByPodName(want.ep.GetK8sNamespaceAndPodName())
   749  		require.Len(t, eps, 1)
   750  		require.EqualValues(t, want.ep, eps[0], "Test Name: %s", tt.name)
   751  	}
   752  }
   753  
   754  func TestRemove(t *testing.T) {
   755  	s := setupEndpointManagerSuite(t)
   756  	mgr := New(&dummyEpSyncher{}, nil, nil)
   757  	ep := endpoint.NewTestEndpointWithState(t, s, s, testipcache.NewMockIPCache(), &endpoint.FakeEndpointProxy{}, testidentity.NewMockIdentityAllocator(nil), 7, endpoint.StateReady)
   758  	type args struct{}
   759  	type want struct{}
   760  	tests := []struct {
   761  		name        string
   762  		setupArgs   func() args
   763  		setupWant   func() want
   764  		preTestRun  func()
   765  		postTestRun func()
   766  	}{
   767  		{
   768  			name: "Updating all references",
   769  			preTestRun: func() {
   770  				ep.ID = 1
   771  				require.Nil(t, mgr.expose(ep))
   772  			},
   773  			setupArgs: func() args {
   774  				return args{}
   775  			},
   776  			setupWant: func() want {
   777  				return want{}
   778  			},
   779  			postTestRun: func() {
   780  			},
   781  		},
   782  	}
   783  	for _, tt := range tests {
   784  		tt.preTestRun()
   785  
   786  		mgr.RemoveAll(t)
   787  		require.Equal(t, 0, len(mgr.endpoints), "Test Name: %s", tt.name)
   788  		require.Equal(t, 0, len(mgr.endpointsAux), "Test Name: %s", tt.name)
   789  		tt.postTestRun()
   790  	}
   791  }
   792  
   793  func TestHasGlobalCT(t *testing.T) {
   794  	s := setupEndpointManagerSuite(t)
   795  
   796  	mgr := New(&dummyEpSyncher{}, nil, nil)
   797  	ep := endpoint.NewTestEndpointWithState(t, s, s, testipcache.NewMockIPCache(), &endpoint.FakeEndpointProxy{}, testidentity.NewMockIdentityAllocator(nil), 1, endpoint.StateReady)
   798  	type want struct {
   799  		result bool
   800  	}
   801  	tests := []struct {
   802  		name        string
   803  		setupWant   func() want
   804  		preTestRun  func()
   805  		postTestRun func()
   806  	}{
   807  		{
   808  			name: "Endpoint with Conntrack global",
   809  			preTestRun: func() {
   810  				ep.ID = 1
   811  				ep.Options = option.NewIntOptions(&endpoint.EndpointMutableOptionLibrary)
   812  				require.Nil(t, mgr.expose(ep))
   813  			},
   814  			setupWant: func() want {
   815  				return want{
   816  					result: true,
   817  				}
   818  			},
   819  			postTestRun: func() {
   820  				mgr.WaitEndpointRemoved(ep)
   821  				ep = endpoint.NewTestEndpointWithState(t, s, s, testipcache.NewMockIPCache(), &endpoint.FakeEndpointProxy{}, testidentity.NewMockIdentityAllocator(nil), 1, endpoint.StateReady)
   822  				ep.ID = 0
   823  				ep.Options = nil
   824  			},
   825  		},
   826  		{
   827  			name: "Endpoint with Conntrack local",
   828  			preTestRun: func() {
   829  				ep.ID = 1
   830  				ep.Options = option.NewIntOptions(&endpoint.EndpointMutableOptionLibrary)
   831  				ep.Options.SetIfUnset(option.ConntrackLocal, option.OptionEnabled)
   832  				require.Nil(t, mgr.expose(ep))
   833  			},
   834  			setupWant: func() want {
   835  				return want{
   836  					result: false,
   837  				}
   838  			},
   839  			postTestRun: func() {
   840  				mgr.WaitEndpointRemoved(ep)
   841  				ep = endpoint.NewTestEndpointWithState(t, s, s, testipcache.NewMockIPCache(), &endpoint.FakeEndpointProxy{}, testidentity.NewMockIdentityAllocator(nil), 1, endpoint.StateReady)
   842  				ep.ID = 0
   843  				ep.Options = nil
   844  			},
   845  		},
   846  	}
   847  	for _, tt := range tests {
   848  		tt.preTestRun()
   849  		want := tt.setupWant()
   850  		got := mgr.HasGlobalCT()
   851  		require.EqualValues(t, want.result, got, "Test Name: %s", tt.name)
   852  		tt.postTestRun()
   853  	}
   854  }
   855  
   856  func TestWaitForEndpointsAtPolicyRev(t *testing.T) {
   857  	s := setupEndpointManagerSuite(t)
   858  	mgr := New(&dummyEpSyncher{}, nil, nil)
   859  	ep := endpoint.NewTestEndpointWithState(t, s, s, testipcache.NewMockIPCache(), &endpoint.FakeEndpointProxy{}, testidentity.NewMockIdentityAllocator(nil), 1, endpoint.StateReady)
   860  	type args struct {
   861  		ctx    context.Context
   862  		rev    uint64
   863  		cancel context.CancelFunc
   864  	}
   865  	type want struct {
   866  		err      error
   867  		errCheck assert.ComparisonAssertionFunc
   868  	}
   869  	tests := []struct {
   870  		name        string
   871  		setupArgs   func() args
   872  		setupWant   func() want
   873  		preTestRun  func()
   874  		postTestRun func()
   875  	}{
   876  		{
   877  			name: "Endpoint with revision already set",
   878  			preTestRun: func() {
   879  				ep.ID = 1
   880  				ep.SetPolicyRevision(5)
   881  				require.Nil(t, mgr.expose(ep))
   882  			},
   883  			setupArgs: func() args {
   884  				return args{
   885  					ctx: context.Background(),
   886  					rev: 5,
   887  				}
   888  			},
   889  			setupWant: func() want {
   890  				return want{
   891  					err:      nil,
   892  					errCheck: assert.EqualValues,
   893  				}
   894  			},
   895  			postTestRun: func() {
   896  				mgr.WaitEndpointRemoved(ep)
   897  				ep = endpoint.NewTestEndpointWithState(t, s, s, testipcache.NewMockIPCache(), &endpoint.FakeEndpointProxy{}, testidentity.NewMockIdentityAllocator(nil), 1, endpoint.StateReady)
   898  			},
   899  		},
   900  		{
   901  			name: "Context already timed out",
   902  			preTestRun: func() {
   903  				ep.ID = 1
   904  				ep.SetPolicyRevision(5)
   905  				require.Nil(t, mgr.expose(ep))
   906  			},
   907  			setupArgs: func() args {
   908  				ctx, cancel := context.WithTimeout(context.Background(), 0)
   909  				return args{
   910  					ctx:    ctx,
   911  					rev:    5,
   912  					cancel: cancel,
   913  				}
   914  			},
   915  			setupWant: func() want {
   916  				return want{
   917  					err:      nil,
   918  					errCheck: assert.NotEqualValues,
   919  				}
   920  			},
   921  			postTestRun: func() {
   922  				mgr.WaitEndpointRemoved(ep)
   923  				ep = endpoint.NewTestEndpointWithState(t, s, s, testipcache.NewMockIPCache(), &endpoint.FakeEndpointProxy{}, testidentity.NewMockIdentityAllocator(nil), 1, endpoint.StateReady)
   924  			},
   925  		},
   926  		{
   927  			name: "Revision is will never be set to the waiting revision",
   928  			preTestRun: func() {
   929  				ep.ID = 1
   930  				ep.SetPolicyRevision(4)
   931  				require.Nil(t, mgr.expose(ep))
   932  			},
   933  			setupArgs: func() args {
   934  				ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
   935  				return args{
   936  					ctx:    ctx,
   937  					rev:    5,
   938  					cancel: cancel,
   939  				}
   940  			},
   941  			setupWant: func() want {
   942  				return want{
   943  					err:      nil,
   944  					errCheck: assert.NotEqualValues,
   945  				}
   946  			},
   947  			postTestRun: func() {
   948  				mgr.WaitEndpointRemoved(ep)
   949  				ep = endpoint.NewTestEndpointWithState(t, s, s, testipcache.NewMockIPCache(), &endpoint.FakeEndpointProxy{}, testidentity.NewMockIdentityAllocator(nil), 1, endpoint.StateReady)
   950  			},
   951  		},
   952  	}
   953  	for _, tt := range tests {
   954  		tt.preTestRun()
   955  		args := tt.setupArgs()
   956  		want := tt.setupWant()
   957  		got := mgr.WaitForEndpointsAtPolicyRev(args.ctx, args.rev)
   958  		want.errCheck(t, want.err, got, "Test Name: %s", tt.name)
   959  		if args.cancel != nil {
   960  			args.cancel()
   961  		}
   962  		tt.postTestRun()
   963  	}
   964  }
   965  
   966  func TestMissingNodeLabelsUpdate(t *testing.T) {
   967  	// Initialize label filter config.
   968  	labelsfilter.ParseLabelPrefixCfg(nil, nil, "")
   969  	s := setupEndpointManagerSuite(t)
   970  	mgr := New(&dummyEpSyncher{}, nil, nil)
   971  	hostEPID := uint16(17)
   972  
   973  	// Initialize the local node watcher before the host endpoint is created.
   974  	// These labels are not propagated to the endpoint manager.
   975  	mgr.localNodeStore = node.NewTestLocalNodeStore(node.LocalNode{Node: types.Node{}})
   976  	mgr.startNodeLabelsObserver(nil)
   977  	mgr.localNodeStore.Update(func(ln *node.LocalNode) { ln.Labels = map[string]string{"k1": "v1"} })
   978  	_, ok := mgr.endpoints[hostEPID]
   979  	require.EqualValues(t, ok, false)
   980  
   981  	// Create host endpoint and expose it in the endpoint manager.
   982  	ep := endpoint.NewTestEndpointWithState(t, s, s, testipcache.NewMockIPCache(), &endpoint.FakeEndpointProxy{}, testidentity.NewMockIdentityAllocator(nil), 1, endpoint.StateReady)
   983  	ep.SetIsHost(true)
   984  	ep.ID = hostEPID
   985  	require.Nil(t, mgr.expose(ep))
   986  
   987  	// Update node labels and verify that the node labels are updated correctly even if the old
   988  	// labels {k1=v1} are not present in the endpoint manager's state.
   989  	mgr.localNodeStore.Update(func(ln *node.LocalNode) { ln.Labels = map[string]string{"k2": "v2"} })
   990  	hostEP, ok := mgr.endpoints[hostEPID]
   991  	require.EqualValues(t, ok, true)
   992  	got := hostEP.OpLabels.IdentityLabels().K8sStringMap()
   993  	require.EqualValues(t, map[string]string{"k2": "v2"}, got)
   994  }
   995  
   996  func TestUpdateHostEndpointLabels(t *testing.T) {
   997  	// Initialize label filter config.
   998  	labelsfilter.ParseLabelPrefixCfg([]string{"k8s:!ignore1", "k8s:!ignore2"}, nil, "")
   999  	s := setupEndpointManagerSuite(t)
  1000  	mgr := New(&dummyEpSyncher{}, nil, nil)
  1001  	hostEPID := uint16(17)
  1002  	type args struct {
  1003  		oldLabels, newLabels map[string]string
  1004  	}
  1005  	type want struct {
  1006  		labels      map[string]string
  1007  		labelsCheck assert.ComparisonAssertionFunc
  1008  	}
  1009  	tests := []struct {
  1010  		name        string
  1011  		setupArgs   func() args
  1012  		setupWant   func() want
  1013  		preTestRun  func()
  1014  		postTestRun func()
  1015  	}{
  1016  		{
  1017  			name: "Add labels",
  1018  			preTestRun: func() {
  1019  				ep := endpoint.NewTestEndpointWithState(t, s, s, testipcache.NewMockIPCache(), &endpoint.FakeEndpointProxy{}, testidentity.NewMockIdentityAllocator(nil), 1, endpoint.StateReady)
  1020  				ep.SetIsHost(true)
  1021  				ep.ID = hostEPID
  1022  				require.Nil(t, mgr.expose(ep))
  1023  			},
  1024  			setupArgs: func() args {
  1025  				return args{
  1026  					newLabels: map[string]string{"k1": "v1"},
  1027  				}
  1028  			},
  1029  			setupWant: func() want {
  1030  				return want{
  1031  					labels:      map[string]string{"k1": "v1"},
  1032  					labelsCheck: assert.EqualValues,
  1033  				}
  1034  			},
  1035  			postTestRun: func() {
  1036  				if hostEP, ok := mgr.endpoints[hostEPID]; ok {
  1037  					mgr.WaitEndpointRemoved(hostEP)
  1038  				}
  1039  			},
  1040  		},
  1041  		{
  1042  			name: "Update labels",
  1043  			preTestRun: func() {
  1044  				ep := endpoint.NewTestEndpointWithState(t, s, s, testipcache.NewMockIPCache(), &endpoint.FakeEndpointProxy{}, testidentity.NewMockIdentityAllocator(nil), 1, endpoint.StateReady)
  1045  				ep.SetIsHost(true)
  1046  				ep.ID = hostEPID
  1047  				ep.OpLabels.Custom = labels.Labels{"k1": labels.NewLabel("k1", "v1", labels.LabelSourceK8s)}
  1048  				require.Nil(t, mgr.expose(ep))
  1049  			},
  1050  			setupArgs: func() args {
  1051  				return args{
  1052  					oldLabels: map[string]string{"k1": "v1"},
  1053  					newLabels: map[string]string{"k2": "v2"},
  1054  				}
  1055  			},
  1056  			setupWant: func() want {
  1057  				return want{
  1058  					labels:      map[string]string{"k2": "v2"},
  1059  					labelsCheck: assert.EqualValues,
  1060  				}
  1061  			},
  1062  			postTestRun: func() {
  1063  				if hostEP, ok := mgr.endpoints[hostEPID]; ok {
  1064  					mgr.WaitEndpointRemoved(hostEP)
  1065  				}
  1066  			},
  1067  		},
  1068  		{
  1069  			name: "Ignore labels",
  1070  			preTestRun: func() {
  1071  				ep := endpoint.NewTestEndpointWithState(t, s, s, testipcache.NewMockIPCache(), &endpoint.FakeEndpointProxy{}, testidentity.NewMockIdentityAllocator(nil), 1, endpoint.StateReady)
  1072  				ep.SetIsHost(true)
  1073  				ep.ID = hostEPID
  1074  				ep.OpLabels.Custom = labels.Labels{"k1": labels.NewLabel("k1", "v1", labels.LabelSourceK8s)}
  1075  				require.Nil(t, mgr.expose(ep))
  1076  			},
  1077  			setupArgs: func() args {
  1078  				return args{
  1079  					oldLabels: map[string]string{"k1": "v1"},
  1080  					newLabels: map[string]string{"k1": "v1", "ignore1": "v2", "ignore2": "v2"},
  1081  				}
  1082  			},
  1083  			setupWant: func() want {
  1084  				return want{
  1085  					labels:      map[string]string{"k1": "v1"},
  1086  					labelsCheck: assert.EqualValues,
  1087  				}
  1088  			},
  1089  			postTestRun: func() {
  1090  				if hostEP, ok := mgr.endpoints[hostEPID]; ok {
  1091  					mgr.WaitEndpointRemoved(hostEP)
  1092  				}
  1093  			},
  1094  		},
  1095  	}
  1096  	for _, tt := range tests {
  1097  		tt.preTestRun()
  1098  		args := tt.setupArgs()
  1099  		want := tt.setupWant()
  1100  		mgr.localNodeStore = node.NewTestLocalNodeStore(node.LocalNode{Node: types.Node{
  1101  			Labels: args.oldLabels,
  1102  		}})
  1103  		mgr.startNodeLabelsObserver(args.oldLabels)
  1104  		mgr.localNodeStore.Update(func(ln *node.LocalNode) { ln.Labels = args.newLabels })
  1105  
  1106  		hostEP, ok := mgr.endpoints[hostEPID]
  1107  		require.EqualValues(t, ok, true)
  1108  		got := hostEP.OpLabels.IdentityLabels().K8sStringMap()
  1109  		want.labelsCheck(t, want.labels, got, "Test Name: %s", tt.name)
  1110  		tt.postTestRun()
  1111  	}
  1112  }