github.com/kubewharf/katalyst-core@v0.5.3/pkg/metaserver/agent/agent_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 agent
    18  
    19  import (
    20  	"context"
    21  	"testing"
    22  	"time"
    23  
    24  	"github.com/stretchr/testify/assert"
    25  	v1 "k8s.io/api/core/v1"
    26  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    27  	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
    28  	"k8s.io/apimachinery/pkg/runtime"
    29  	"k8s.io/apimachinery/pkg/types"
    30  	"k8s.io/client-go/kubernetes/fake"
    31  	corev1 "k8s.io/client-go/kubernetes/typed/core/v1"
    32  	kubeletconfigv1beta1 "k8s.io/kubelet/config/v1beta1"
    33  	"k8s.io/kubernetes/pkg/kubelet/apis/config"
    34  
    35  	"github.com/kubewharf/katalyst-api/pkg/apis/node/v1alpha1"
    36  	v1alpha1fake "github.com/kubewharf/katalyst-api/pkg/client/clientset/versioned/fake"
    37  	v1alpha1client "github.com/kubewharf/katalyst-api/pkg/client/clientset/versioned/typed/node/v1alpha1"
    38  	katalyst_base "github.com/kubewharf/katalyst-core/cmd/base"
    39  	"github.com/kubewharf/katalyst-core/cmd/katalyst-agent/app/options"
    40  	"github.com/kubewharf/katalyst-core/pkg/config/agent/global"
    41  	metaconfig "github.com/kubewharf/katalyst-core/pkg/config/agent/metaserver"
    42  	cnrmeta "github.com/kubewharf/katalyst-core/pkg/metaserver/agent/cnr"
    43  	"github.com/kubewharf/katalyst-core/pkg/metaserver/agent/kubeletconfig"
    44  	"github.com/kubewharf/katalyst-core/pkg/metaserver/agent/metric"
    45  	"github.com/kubewharf/katalyst-core/pkg/metaserver/agent/node"
    46  	"github.com/kubewharf/katalyst-core/pkg/metaserver/agent/pod"
    47  	"github.com/kubewharf/katalyst-core/pkg/metrics"
    48  )
    49  
    50  func constructNodeInterface(name string) corev1.NodeInterface {
    51  	objects := []runtime.Object{
    52  		&v1.Node{
    53  			ObjectMeta: metav1.ObjectMeta{
    54  				Name: name,
    55  			},
    56  		},
    57  	}
    58  	return fake.NewSimpleClientset(objects...).CoreV1().Nodes()
    59  }
    60  
    61  func constructCNRInterface(name string) v1alpha1client.CustomNodeResourceInterface {
    62  	objects := []runtime.Object{
    63  		&v1alpha1.CustomNodeResource{
    64  			ObjectMeta: metav1.ObjectMeta{
    65  				Name: name,
    66  			},
    67  		},
    68  	}
    69  	return v1alpha1fake.NewSimpleClientset(objects...).NodeV1alpha1().CustomNodeResources()
    70  }
    71  
    72  func constructPodFetcher(names []string) pod.PodFetcher {
    73  	var pods []*v1.Pod
    74  	for _, name := range names {
    75  		pods = append(pods, &v1.Pod{
    76  			ObjectMeta: metav1.ObjectMeta{
    77  				Name: name,
    78  				UID:  types.UID(name + "-uid"),
    79  			},
    80  		})
    81  	}
    82  
    83  	return &pod.PodFetcherStub{PodList: pods}
    84  }
    85  
    86  type ObjectFetcherTest struct {
    87  	obj *unstructured.Unstructured
    88  }
    89  
    90  func (o *ObjectFetcherTest) GetUnstructured(_ context.Context, _, _ string) (*unstructured.Unstructured, error) {
    91  	return o.obj, nil
    92  }
    93  
    94  func TestFetcher(t *testing.T) {
    95  	t.Parallel()
    96  
    97  	ctx, cancel := context.WithCancel(context.Background())
    98  	conf, _ := options.NewOptions().Config()
    99  	conf.CheckpointManagerDir = "/tmp/TestFetcher"
   100  	bCtx, _ := katalyst_base.GenerateFakeGenericContext(nil, nil, nil)
   101  
   102  	agent, err := NewMetaAgent(conf, bCtx.Client, metrics.DummyMetrics{})
   103  	assert.NoError(t, err)
   104  
   105  	// before start, we can set component implementations for metaServer
   106  	agent.SetPodFetcher(constructPodFetcher([]string{"test-pod-1", "test-pod-2"}))
   107  	agent.SetNodeFetcher(node.NewRemoteNodeFetcher(&global.BaseConfiguration{NodeName: "test-node-1"}, &metaconfig.NodeConfiguration{}, constructNodeInterface("test-node-1")))
   108  	agent.SetCNRFetcher(cnrmeta.NewCachedCNRFetcher(&global.BaseConfiguration{NodeName: "test-cnr-1"}, conf.CNRConfiguration, constructCNRInterface("test-cnr-1")))
   109  	agent.SetMetricFetcher(metric.NewFakeMetricsFetcher(metrics.DummyMetrics{}))
   110  	agent.SetKubeletConfigFetcher(kubeletconfig.NewKubeletConfigFetcher(conf.BaseConfiguration, metrics.DummyMetrics{}))
   111  
   112  	podObjList, err := agent.GetPodList(ctx, func(*v1.Pod) bool { return true })
   113  	assert.NoError(t, err)
   114  	assert.Equal(t, 2, len(podObjList))
   115  
   116  	pod1, err := agent.GetPod(ctx, "test-pod-1-uid")
   117  	assert.NoError(t, err)
   118  	assert.Equal(t, "test-pod-1", pod1.Name)
   119  
   120  	nodeObj, err := agent.GetNode(ctx)
   121  	assert.NoError(t, err)
   122  	assert.Equal(t, "test-node-1", nodeObj.Name)
   123  
   124  	cnrObj, err := agent.GetCNR(ctx)
   125  	assert.NoError(t, err)
   126  	assert.Equal(t, "test-cnr-1", cnrObj.Name)
   127  
   128  	_, err1 := agent.GetKubeletConfig(ctx)
   129  	assert.Error(t, err1)
   130  
   131  	gvr := metav1.GroupVersionResource{Group: "a", Version: "b", Resource: "c"}
   132  	_, gErr := agent.GetUnstructured(ctx, gvr, "", "aaa")
   133  	assert.NotNil(t, gErr)
   134  
   135  	// before start, we can set component implementations for metaServer
   136  	agent.SetPodFetcher(constructPodFetcher([]string{"test-pod-3", "test-pod-4", "test-pod-5"}))
   137  	agent.SetNodeFetcher(node.NewRemoteNodeFetcher(&global.BaseConfiguration{NodeName: "test-node-2"}, &metaconfig.NodeConfiguration{}, constructNodeInterface("test-node-2")))
   138  	agent.SetCNRFetcher(cnrmeta.NewCachedCNRFetcher(&global.BaseConfiguration{NodeName: "test-cnr-2"}, conf.CNRConfiguration, constructCNRInterface("test-cnr-2")))
   139  
   140  	conf.KubeletSecurePortEnabled = true
   141  	agent.SetKubeletConfigFetcher(kubeletconfig.NewKubeletConfigFetcher(conf.BaseConfiguration, metrics.DummyMetrics{}))
   142  
   143  	_ = agent.CNRFetcher.RegisterNotifier("test-cnr-2", cnrmeta.CNRNotifierStub{})
   144  	assert.NoError(t, err)
   145  	defer func() {
   146  		err := agent.CNRFetcher.UnregisterNotifier("test-cnr-2")
   147  		assert.NoError(t, err)
   148  	}()
   149  
   150  	podObjList, err = agent.GetPodList(ctx, func(*v1.Pod) bool { return true })
   151  	assert.NoError(t, err)
   152  	assert.Equal(t, 3, len(podObjList))
   153  
   154  	nodeObj, err = agent.GetNode(ctx)
   155  	assert.NoError(t, err)
   156  	assert.Equal(t, "test-node-2", nodeObj.Name)
   157  
   158  	cnrObj, err = agent.GetCNR(ctx)
   159  	assert.NoError(t, err)
   160  	assert.Equal(t, "test-cnr-2", cnrObj.Name)
   161  
   162  	_, err2 := agent.GetKubeletConfig(ctx)
   163  	assert.Error(t, err2)
   164  
   165  	obj := &unstructured.Unstructured{
   166  		Object: map[string]interface{}{
   167  			"lll": "bbb",
   168  		},
   169  	}
   170  	s := &ObjectFetcherTest{obj: obj}
   171  
   172  	fakeKubeletConfig := kubeletconfigv1beta1.KubeletConfiguration{
   173  		TopologyManagerPolicy: config.SingleNumaNodeTopologyManagerPolicy,
   174  		TopologyManagerScope:  config.ContainerTopologyManagerScope,
   175  	}
   176  	agent.SetKubeletConfigFetcher(kubeletconfig.NewFakeKubeletConfigFetcher(fakeKubeletConfig))
   177  
   178  	// after start, we can't set component implementations for metaServer
   179  	go agent.Run(ctx)
   180  	time.Sleep(time.Second)
   181  
   182  	agent.SetPodFetcher(constructPodFetcher([]string{"test-pod-6"}))
   183  	agent.SetNodeFetcher(node.NewRemoteNodeFetcher(&global.BaseConfiguration{NodeName: "test-node-3"}, &metaconfig.NodeConfiguration{}, constructNodeInterface("test-node-3")))
   184  	agent.SetCNRFetcher(cnrmeta.NewCachedCNRFetcher(&global.BaseConfiguration{NodeName: "test-cnr-3"}, conf.CNRConfiguration, constructCNRInterface("test-cnr-3")))
   185  	agent.SetObjectFetcher(gvr, s)
   186  
   187  	podObjList, err = agent.GetPodList(ctx, func(*v1.Pod) bool { return true })
   188  	assert.NoError(t, err)
   189  	assert.Equal(t, 3, len(podObjList))
   190  
   191  	nodeObj, err = agent.GetNode(ctx)
   192  	assert.NoError(t, err)
   193  	assert.Equal(t, "test-node-2", nodeObj.Name)
   194  
   195  	cnrObj, err = agent.GetCNR(ctx)
   196  	assert.NoError(t, err)
   197  	assert.Equal(t, "test-cnr-2", cnrObj.Name)
   198  
   199  	o, err := agent.GetUnstructured(ctx, gvr, "", "aaa")
   200  	assert.NoError(t, err)
   201  	assert.Equal(t, "bbb", o.Object["lll"])
   202  
   203  	kubeletConfig, err3 := agent.GetKubeletConfig(ctx)
   204  	assert.NoError(t, err3)
   205  	assert.Equal(t, config.SingleNumaNodeTopologyManagerPolicy, kubeletConfig.TopologyManagerPolicy)
   206  	assert.Equal(t, config.ContainerTopologyManagerScope, kubeletConfig.TopologyManagerScope)
   207  
   208  	cancel()
   209  }