github.com/kubewharf/katalyst-core@v0.5.3/pkg/controller/lifecycle/cnr_test.go (about)

     1  /*
     2  Copyright 2022 The Katalyst Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package lifecycle
    18  
    19  import (
    20  	"context"
    21  	"testing"
    22  	"time"
    23  
    24  	"github.com/stretchr/testify/assert"
    25  	"github.com/stretchr/testify/require"
    26  	corev1 "k8s.io/api/core/v1"
    27  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    28  	"k8s.io/apimachinery/pkg/runtime"
    29  	"k8s.io/client-go/tools/cache"
    30  	"k8s.io/utils/pointer"
    31  
    32  	nodeapis "github.com/kubewharf/katalyst-api/pkg/apis/node/v1alpha1"
    33  	katalyst_base "github.com/kubewharf/katalyst-core/cmd/base"
    34  	"github.com/kubewharf/katalyst-core/cmd/katalyst-controller/app/options"
    35  )
    36  
    37  func TestCNRLifecycle_Run(t *testing.T) {
    38  	t.Parallel()
    39  
    40  	type fields struct {
    41  		node *corev1.Node
    42  		cnr  *nodeapis.CustomNodeResource
    43  	}
    44  	tests := []struct {
    45  		name    string
    46  		fields  fields
    47  		wantCNR *nodeapis.CustomNodeResource
    48  	}{
    49  		{
    50  			name: "test-create",
    51  			fields: fields{
    52  				node: &corev1.Node{
    53  					ObjectMeta: metav1.ObjectMeta{
    54  						Name: "node1",
    55  						Labels: map[string]string{
    56  							"test": "test",
    57  						},
    58  					},
    59  				},
    60  			},
    61  			wantCNR: &nodeapis.CustomNodeResource{
    62  				ObjectMeta: metav1.ObjectMeta{
    63  					Name: "node1",
    64  					Labels: map[string]string{
    65  						"test": "test",
    66  					},
    67  					OwnerReferences: []metav1.OwnerReference{
    68  						{
    69  							APIVersion:         "v1",
    70  							Kind:               "Node",
    71  							Name:               "node1",
    72  							UID:                "",
    73  							Controller:         pointer.Bool(true),
    74  							BlockOwnerDeletion: pointer.Bool(true),
    75  						},
    76  					},
    77  				},
    78  			},
    79  		},
    80  		{
    81  			name: "test-update",
    82  			fields: fields{
    83  				node: &corev1.Node{
    84  					ObjectMeta: metav1.ObjectMeta{
    85  						Name: "node1",
    86  						Labels: map[string]string{
    87  							"test": "test-1",
    88  						},
    89  					},
    90  				},
    91  				cnr: &nodeapis.CustomNodeResource{
    92  					ObjectMeta: metav1.ObjectMeta{
    93  						Name: "node1",
    94  						Labels: map[string]string{
    95  							"test": "test",
    96  						},
    97  					},
    98  				},
    99  			},
   100  			wantCNR: &nodeapis.CustomNodeResource{
   101  				ObjectMeta: metav1.ObjectMeta{
   102  					Name: "node1",
   103  					Labels: map[string]string{
   104  						"test": "test-1",
   105  					},
   106  					OwnerReferences: []metav1.OwnerReference{
   107  						{
   108  							APIVersion:         "v1",
   109  							Kind:               "Node",
   110  							Name:               "node1",
   111  							UID:                "",
   112  							Controller:         pointer.Bool(true),
   113  							BlockOwnerDeletion: pointer.Bool(true),
   114  						},
   115  					},
   116  				},
   117  			},
   118  		},
   119  	}
   120  	for _, tt := range tests {
   121  		tt := tt
   122  		t.Run(tt.name, func(t *testing.T) {
   123  			t.Parallel()
   124  
   125  			genericCtx, err := katalyst_base.GenerateFakeGenericContext([]runtime.Object{tt.fields.node}, []runtime.Object{tt.fields.cnr})
   126  			assert.NoError(t, err)
   127  
   128  			conf, err := options.NewOptions().Config()
   129  			require.NoError(t, err)
   130  			require.NotNil(t, conf)
   131  
   132  			cl, err := NewCNRLifecycle(context.Background(),
   133  				conf.GenericConfiguration,
   134  				conf.GenericControllerConfiguration,
   135  				conf.ControllersConfiguration.CNRLifecycleConfig,
   136  				genericCtx.Client,
   137  				genericCtx.KubeInformerFactory.Core().V1().Nodes(),
   138  				genericCtx.InternalInformerFactory.Node().V1alpha1().CustomNodeResources(),
   139  				genericCtx.EmitterPool.GetDefaultMetricsEmitter(),
   140  			)
   141  			assert.NoError(t, err)
   142  
   143  			// test cache not synced
   144  			err = cl.sync(tt.fields.node.Name)
   145  			assert.NoError(t, err)
   146  
   147  			genericCtx.KubeInformerFactory.Start(cl.ctx.Done())
   148  			genericCtx.InternalInformerFactory.Start(cl.ctx.Done())
   149  			go cl.Run()
   150  
   151  			cache.WaitForCacheSync(cl.ctx.Done(), cl.nodeListerSynced, cl.cnrListerSynced)
   152  			time.Sleep(1 * time.Second)
   153  
   154  			gotCNR, err := cl.cnrLister.Get(tt.fields.node.Name)
   155  			assert.NoError(t, err)
   156  			assert.Equal(t, tt.wantCNR, gotCNR)
   157  
   158  			// test recreate
   159  			err = cl.client.InternalClient.NodeV1alpha1().CustomNodeResources().Delete(context.Background(), tt.fields.node.Name, metav1.DeleteOptions{})
   160  			assert.NoError(t, err)
   161  			time.Sleep(1 * time.Second)
   162  
   163  			gotCNR, err = cl.cnrLister.Get(tt.fields.node.Name)
   164  			assert.NoError(t, err)
   165  			assert.Equal(t, tt.wantCNR, gotCNR)
   166  		})
   167  	}
   168  }
   169  
   170  func TestCNRLifecycle_updateOrCreateCNR(t *testing.T) {
   171  	t.Parallel()
   172  
   173  	type fields struct {
   174  		node *corev1.Node
   175  		cnr  *nodeapis.CustomNodeResource
   176  	}
   177  	tests := []struct {
   178  		name    string
   179  		fields  fields
   180  		wantCNR *nodeapis.CustomNodeResource
   181  	}{
   182  		{
   183  			name: "test-update",
   184  			fields: fields{
   185  				node: &corev1.Node{
   186  					ObjectMeta: metav1.ObjectMeta{
   187  						Name: "node1",
   188  						Labels: map[string]string{
   189  							"test": "test-1",
   190  						},
   191  					},
   192  				},
   193  				cnr: &nodeapis.CustomNodeResource{
   194  					ObjectMeta: metav1.ObjectMeta{
   195  						Name: "node1",
   196  						Labels: map[string]string{
   197  							"test": "test",
   198  						},
   199  					},
   200  				},
   201  			},
   202  			wantCNR: &nodeapis.CustomNodeResource{
   203  				ObjectMeta: metav1.ObjectMeta{
   204  					Name: "node1",
   205  					Labels: map[string]string{
   206  						"test": "test-1",
   207  					},
   208  					OwnerReferences: []metav1.OwnerReference{
   209  						{
   210  							APIVersion:         "v1",
   211  							Kind:               "Node",
   212  							Name:               "node1",
   213  							UID:                "",
   214  							Controller:         pointer.Bool(true),
   215  							BlockOwnerDeletion: pointer.Bool(true),
   216  						},
   217  					},
   218  				},
   219  			},
   220  		},
   221  	}
   222  	for _, tt := range tests {
   223  		tt := tt
   224  		t.Run(tt.name, func(t *testing.T) {
   225  			t.Parallel()
   226  
   227  			genericCtx, err := katalyst_base.GenerateFakeGenericContext([]runtime.Object{tt.fields.node}, []runtime.Object{tt.fields.cnr})
   228  			assert.NoError(t, err)
   229  
   230  			conf, err := options.NewOptions().Config()
   231  			require.NoError(t, err)
   232  			require.NotNil(t, conf)
   233  
   234  			cl, err := NewCNRLifecycle(context.Background(),
   235  				conf.GenericConfiguration,
   236  				conf.GenericControllerConfiguration,
   237  				conf.ControllersConfiguration.CNRLifecycleConfig,
   238  				genericCtx.Client,
   239  				genericCtx.KubeInformerFactory.Core().V1().Nodes(),
   240  				genericCtx.InternalInformerFactory.Node().V1alpha1().CustomNodeResources(),
   241  				genericCtx.EmitterPool.GetDefaultMetricsEmitter(),
   242  			)
   243  			assert.NoError(t, err)
   244  
   245  			// test cache not synced
   246  			err = cl.updateOrCreateCNR(tt.fields.node)
   247  			assert.NoError(t, err)
   248  		})
   249  	}
   250  }