github.com/cilium/cilium@v1.16.2/operator/pkg/ciliumendpointslice/controller_test.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Cilium
     3  
     4  package ciliumendpointslice
     5  
     6  import (
     7  	"context"
     8  	"fmt"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/cilium/hive/cell"
    13  	"github.com/cilium/hive/hivetest"
    14  	"github.com/stretchr/testify/assert"
    15  	"go.uber.org/goleak"
    16  	meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    17  
    18  	"github.com/cilium/cilium/operator/k8s"
    19  	tu "github.com/cilium/cilium/operator/pkg/ciliumendpointslice/testutils"
    20  	"github.com/cilium/cilium/pkg/hive"
    21  	cilium_v2 "github.com/cilium/cilium/pkg/k8s/apis/cilium.io/v2"
    22  	cilium_v2a1 "github.com/cilium/cilium/pkg/k8s/apis/cilium.io/v2alpha1"
    23  	k8sClient "github.com/cilium/cilium/pkg/k8s/client"
    24  	"github.com/cilium/cilium/pkg/k8s/resource"
    25  	"github.com/cilium/cilium/pkg/metrics"
    26  	"github.com/cilium/cilium/pkg/testutils"
    27  )
    28  
    29  func TestRegisterController(t *testing.T) {
    30  	defer goleak.VerifyNone(
    31  		t,
    32  		// To ignore goroutine started by the workqueue. It reports metrics
    33  		// on unfinished work with default tick period of 0.5s - it terminates
    34  		// no longer than 0.5s after the workqueue is stopped.
    35  		goleak.IgnoreTopFunction("k8s.io/client-go/util/workqueue.(*Type).updateUnfinishedWorkLoop"),
    36  	)
    37  	var fakeClient k8sClient.Clientset
    38  	var ciliumEndpoint resource.Resource[*cilium_v2.CiliumEndpoint]
    39  	var ciliumEndpointSlice resource.Resource[*cilium_v2a1.CiliumEndpointSlice]
    40  	hive := hive.New(
    41  		k8sClient.FakeClientBuilderCell,
    42  		k8s.ResourcesCell,
    43  		cell.Provide(func() Config {
    44  			return defaultConfig
    45  		}),
    46  		cell.Provide(func() SharedConfig {
    47  			return SharedConfig{
    48  				EnableCiliumEndpointSlice: true,
    49  			}
    50  		}),
    51  		metrics.Metric(NewMetrics),
    52  		cell.Invoke(func(p params) error {
    53  			registerController(p)
    54  			return nil
    55  		}),
    56  		cell.Provide(func(f k8sClient.ClientBuilderFunc) k8sClient.Clientset {
    57  			clientset, _ := f("test-ces-registered")
    58  			return clientset
    59  		}),
    60  		cell.Invoke(func(c k8sClient.Clientset, cep resource.Resource[*cilium_v2.CiliumEndpoint], ces resource.Resource[*cilium_v2a1.CiliumEndpointSlice]) error {
    61  			fakeClient = c
    62  			ciliumEndpoint = cep
    63  			ciliumEndpointSlice = ces
    64  			return nil
    65  		}),
    66  	)
    67  	tlog := hivetest.Logger(t)
    68  	if err := hive.Start(tlog, context.Background()); err != nil {
    69  		t.Fatalf("failed to start: %s", err)
    70  	}
    71  	cesCreated, err := createCEPandVerifyCESCreated(fakeClient, ciliumEndpoint, ciliumEndpointSlice)
    72  	if err != nil {
    73  		t.Fatalf("Couldn't verify if CES is created: %s", err)
    74  	}
    75  	// Verify CES is created when CES features is enabled
    76  	assert.Equal(t, true, cesCreated)
    77  	if err := hive.Stop(tlog, context.Background()); err != nil {
    78  		t.Fatalf("failed to stop: %s", err)
    79  	}
    80  }
    81  
    82  func TestNotRegisterControllerWithCESDisabled(t *testing.T) {
    83  	defer goleak.VerifyNone(
    84  		t,
    85  		// To ignore goroutine started by the workqueue. It reports metrics
    86  		// on unfinished work with default tick period of 0.5s - it terminates
    87  		// no longer than 0.5s after the workqueue is stopped.
    88  		goleak.IgnoreTopFunction("k8s.io/client-go/util/workqueue.(*Type).updateUnfinishedWorkLoop"),
    89  	)
    90  	var fakeClient k8sClient.Clientset
    91  	var ciliumEndpoint resource.Resource[*cilium_v2.CiliumEndpoint]
    92  	var ciliumEndpointSlice resource.Resource[*cilium_v2a1.CiliumEndpointSlice]
    93  	h := hive.New(
    94  		k8sClient.FakeClientBuilderCell,
    95  		k8s.ResourcesCell,
    96  		cell.Provide(func() Config {
    97  			return defaultConfig
    98  		}),
    99  		cell.Provide(func() SharedConfig {
   100  			return SharedConfig{
   101  				EnableCiliumEndpointSlice: false,
   102  			}
   103  		}),
   104  		metrics.Metric(NewMetrics),
   105  		cell.Invoke(func(p params) error {
   106  			registerController(p)
   107  			return nil
   108  		}),
   109  		cell.Provide(func(f k8sClient.ClientBuilderFunc) k8sClient.Clientset {
   110  			clientset, _ := f("test-ces-unregistered")
   111  			return clientset
   112  		}),
   113  		cell.Invoke(func(c k8sClient.Clientset, cep resource.Resource[*cilium_v2.CiliumEndpoint], ces resource.Resource[*cilium_v2a1.CiliumEndpointSlice]) error {
   114  			fakeClient = c
   115  			ciliumEndpoint = cep
   116  			ciliumEndpointSlice = ces
   117  			return nil
   118  		}),
   119  	)
   120  	tlog := hivetest.Logger(t)
   121  	if err := h.Start(tlog, context.Background()); err != nil {
   122  		t.Fatalf("failed to start: %s", err)
   123  	}
   124  	cesCreated, err := createCEPandVerifyCESCreated(fakeClient, ciliumEndpoint, ciliumEndpointSlice)
   125  	if err != nil {
   126  		t.Fatalf("Couldn't verify if CES is created: %s", err)
   127  	}
   128  	// Verify CES is NOT created when CES features is disabled
   129  	assert.Equal(t, false, cesCreated)
   130  	if err = h.Stop(tlog, context.Background()); err != nil {
   131  		t.Fatalf("failed to stop: %s", err)
   132  	}
   133  }
   134  
   135  func createCEPandVerifyCESCreated(fakeClient k8sClient.Clientset, ciliumEndpoint resource.Resource[*cilium_v2.CiliumEndpoint], ciliumEndpointSlice resource.Resource[*cilium_v2a1.CiliumEndpointSlice]) (bool, error) {
   136  	cep := tu.CreateStoreEndpoint("cep1", "ns", 1)
   137  	fakeClient.CiliumV2().CiliumEndpoints("ns").Create(context.Background(), cep, meta_v1.CreateOptions{})
   138  	cepStore, _ := ciliumEndpoint.Store(context.Background())
   139  	if err := testutils.WaitUntil(func() bool {
   140  		return len(cepStore.List()) > 0
   141  	}, time.Second); err != nil {
   142  		return false, fmt.Errorf("failed to get CEP: %w", err)
   143  	}
   144  	cesStore, _ := ciliumEndpointSlice.Store(context.Background())
   145  	err := testutils.WaitUntil(func() bool {
   146  		return len(cesStore.List()) > 0
   147  	}, time.Second)
   148  	// err == nil means CES was created
   149  	return err == nil, nil
   150  }