...

Source file src/edge-infra.dev/pkg/sds/ien/k8s/controllers/nodeagent/controller_test.go

Documentation: edge-infra.dev/pkg/sds/ien/k8s/controllers/nodeagent

     1  package nodeagent
     2  
     3  import (
     4  	"context"
     5  	"os"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/stretchr/testify/require"
    10  	"gotest.tools/v3/assert/cmp"
    11  	corev1 "k8s.io/api/core/v1"
    12  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    13  	ctrl "sigs.k8s.io/controller-runtime"
    14  	"sigs.k8s.io/controller-runtime/pkg/client"
    15  
    16  	"edge-infra.dev/pkg/k8s/runtime/conditions"
    17  	"edge-infra.dev/pkg/k8s/runtime/events"
    18  	"edge-infra.dev/pkg/k8s/testing/kmp"
    19  	"edge-infra.dev/pkg/lib/fog"
    20  	v1ien "edge-infra.dev/pkg/sds/ien/k8s/apis/v1"
    21  	"edge-infra.dev/pkg/sds/ien/k8s/controllers/nodeagent/config"
    22  	"edge-infra.dev/test/f2"
    23  	"edge-infra.dev/test/f2/x/ktest"
    24  )
    25  
    26  var f f2.Framework
    27  
    28  var (
    29  	ienodeName = "edge-worker"
    30  )
    31  
    32  var sdsNamespaceTest = corev1.Namespace{
    33  	ObjectMeta: metav1.ObjectMeta{
    34  		Name: "sds",
    35  	},
    36  }
    37  
    38  var (
    39  	flagsTest = config.Flags{
    40  		WatchAllNamespaces:  &watchAllNamespaces,
    41  		PluginsConfigMap:    &pluginsConfigMapNamespacedName,
    42  		ThinclientConfigMap: &thinclientConfigMapNotSet,
    43  		Pprof:               nil,
    44  		NodeRootPath:        &nodeRootPath,
    45  	}
    46  
    47  	watchAllNamespaces             = false
    48  	pluginsConfigMapNamespacedName = "nodeagent-plugins"
    49  	thinclientConfigMapNotSet      = ""
    50  	nodeRootPath                   = "/"
    51  
    52  	nodeAgentConfigMapTest = corev1.ConfigMap{
    53  		ObjectMeta: metav1.ObjectMeta{
    54  			Name:      "nodeagent-plugins",
    55  			Namespace: "sds",
    56  		},
    57  		Data: map[string]string{
    58  			"suspendAll":          "false",
    59  			"exampleIENode":       "true",
    60  			"exampleSecret":       "false",
    61  			"exampleConfigMap":    "true",
    62  			"exampleNodeFirewall": "true",
    63  		},
    64  	}
    65  	nodeInfo = corev1.Node{
    66  		ObjectMeta: metav1.ObjectMeta{
    67  			Name: "edge-worker",
    68  		},
    69  	}
    70  )
    71  
    72  var secretTest = corev1.Secret{ObjectMeta: metav1.ObjectMeta{Namespace: "sds", Name: "example-secret"}}
    73  
    74  var (
    75  	clusterFirewall  = v1ien.NewClusterFirewall("testClusterFirewall", []v1ien.ClusterRule{})
    76  	ownerRef         = *metav1.NewControllerRef(clusterFirewall, v1ien.ClusterFirewallGVK)
    77  	nodefirewallTest = v1ien.NewNodeFirewall("edge-worker-example-nodefirewall", []v1ien.NodeRule{}, ownerRef)
    78  )
    79  
    80  func TestMain(m *testing.M) {
    81  	ctrl.SetLogger(fog.New())
    82  	os.Setenv("HOSTNAME", ienodeName)
    83  
    84  	f = f2.New(
    85  		context.Background(),
    86  		f2.WithExtensions(
    87  			ktest.New(
    88  				ktest.WithCtrlManager(createControllerManager),
    89  			),
    90  		)).
    91  		Setup(func(ctx f2.Context) (f2.Context, error) {
    92  			k, err := ktest.FromContext(ctx)
    93  			if err != nil {
    94  				return ctx, err
    95  			}
    96  
    97  			// Override timeouts if we aren't using a live cluster
    98  			if !*k.Env.UseExistingCluster {
    99  				k.Timeout = 5 * time.Second
   100  				k.Tick = 10 * time.Millisecond
   101  			}
   102  
   103  			return ctx, nil
   104  		})
   105  
   106  	os.Exit(f.Run(m))
   107  }
   108  
   109  func TestControllerEntersReadyState(t *testing.T) {
   110  	status := f2.NewFeature("Reconciles its Status").
   111  		Setup("Register Controllers", func(ctx f2.Context, t *testing.T) f2.Context {
   112  			k := ktest.FromContextT(ctx, t)
   113  
   114  			eventRecorder := events.NewRecorder(k.Manager, ctrl.Log, "nodeagent")
   115  			_, err := registerControllers(flagsTest, k.Manager, eventRecorder)
   116  			require.NoError(t, err)
   117  
   118  			ns := sdsNamespaceTest.DeepCopy()
   119  			require.NoError(t, k.Client.Create(ctx, ns))
   120  
   121  			node := nodeInfo.DeepCopy()
   122  			require.NoError(t, k.Client.Create(ctx, node))
   123  
   124  			cm := nodeAgentConfigMapTest.DeepCopy()
   125  			require.NoError(t, k.Client.Create(ctx, cm))
   126  
   127  			secret := secretTest.DeepCopy()
   128  			require.NoError(t, k.Client.Create(ctx, secret))
   129  
   130  			nodefirewall := nodefirewallTest.DeepCopy()
   131  			require.NoError(t, k.Client.Create(ctx, nodefirewall))
   132  
   133  			return ctx
   134  		}).
   135  		Test("Check IEN becomes ready after reconciling", func(ctx f2.Context, t *testing.T) f2.Context {
   136  			k := ktest.FromContextT(ctx, t)
   137  
   138  			ienode := IENodeMock()
   139  			require.NoError(t, k.Client.Create(ctx, ienode))
   140  
   141  			k.WaitOn(t, k.Check(ienode, kmp.IsReady()))
   142  
   143  			return ctx
   144  		}).
   145  		Test("Check ConfigMap plugin is ready", func(ctx f2.Context, t *testing.T) f2.Context {
   146  			k := ktest.FromContextT(ctx, t)
   147  			ienode := IENodeMock()
   148  
   149  			k.WaitOn(t, k.Check(ienode, func(o client.Object) cmp.Result {
   150  				ienode, _ := o.(*v1ien.IENode)
   151  				if conditions.IsTrue(ienode, "exampleConfigMap") {
   152  					return cmp.ResultSuccess
   153  				}
   154  				return cmp.ResultFailure("exampleConfigMap conditions not true")
   155  			}))
   156  			return ctx
   157  		}).
   158  		Test("Check Secrets plugin is ready", func(ctx f2.Context, t *testing.T) f2.Context {
   159  			k := ktest.FromContextT(ctx, t)
   160  			ienode := IENodeMock()
   161  
   162  			k.WaitOn(t, k.Check(ienode, func(o client.Object) cmp.Result {
   163  				ienode, _ := o.(*v1ien.IENode)
   164  				if conditions.IsTrue(ienode, "exampleSecret") {
   165  					return cmp.ResultSuccess
   166  				}
   167  				return cmp.ResultFailure("exampleSecret conditions not true")
   168  			}))
   169  
   170  			return ctx
   171  		}).
   172  		Test("Check NodeFirewall plugin is ready", func(ctx f2.Context, t *testing.T) f2.Context {
   173  			k := ktest.FromContextT(ctx, t)
   174  			ienode := IENodeMock()
   175  
   176  			k.WaitOn(t, k.Check(ienode, func(o client.Object) cmp.Result {
   177  				ienode, _ := o.(*v1ien.IENode)
   178  				if conditions.IsTrue(ienode, "exampleNodeFirewall") {
   179  					return cmp.ResultSuccess
   180  				}
   181  				return cmp.ResultFailure("exampleNodeFirewall conditions not true")
   182  			}))
   183  
   184  			return ctx
   185  		}).
   186  		Feature()
   187  
   188  	f.Test(t, status)
   189  }
   190  
   191  func IENodeMock() *v1ien.IENode {
   192  	return &v1ien.IENode{
   193  		ObjectMeta: metav1.ObjectMeta{
   194  			Name: ienodeName,
   195  		},
   196  		Spec: v1ien.IENodeSpec{
   197  			Role: "worker",
   198  			Lane: "1",
   199  			Network: []v1ien.Network{
   200  				{
   201  					MacAddress: "90:74:c2:0f:d8:77",
   202  					Addresses:  make([]string, 0),
   203  					Gateway4:   "192.168.1.1",
   204  					DHCP4:      false,
   205  					DHCP6:      false,
   206  				},
   207  			},
   208  			PrimaryInterface: &v1ien.PrimaryInterface{
   209  				InterfaceID:  "9647e74f-aba3-447f-b327-31ecce7f8d4c",
   210  				MacAddresses: []string{"90:74:c2:0f:d8:77"},
   211  			},
   212  		},
   213  	}
   214  }
   215  

View as plain text