github.com/kubewharf/katalyst-core@v0.5.3/pkg/metaserver/spd/fetcher_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 spd
    18  
    19  import (
    20  	"context"
    21  	"io/ioutil"
    22  	"os"
    23  	"testing"
    24  	"time"
    25  
    26  	"github.com/stretchr/testify/require"
    27  	v1 "k8s.io/api/core/v1"
    28  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    29  	"k8s.io/apimachinery/pkg/runtime"
    30  
    31  	"github.com/kubewharf/katalyst-api/pkg/apis/config/v1alpha1"
    32  	workloadapis "github.com/kubewharf/katalyst-api/pkg/apis/workload/v1alpha1"
    33  	"github.com/kubewharf/katalyst-api/pkg/consts"
    34  	katalyst_base "github.com/kubewharf/katalyst-core/cmd/base"
    35  	"github.com/kubewharf/katalyst-core/cmd/katalyst-agent/app/options"
    36  	pkgconfig "github.com/kubewharf/katalyst-core/pkg/config"
    37  	pkgconsts "github.com/kubewharf/katalyst-core/pkg/consts"
    38  	"github.com/kubewharf/katalyst-core/pkg/metaserver/agent/cnc"
    39  	"github.com/kubewharf/katalyst-core/pkg/metrics"
    40  )
    41  
    42  func generateTestConfiguration(t *testing.T, nodeName string, checkpoint string) *pkgconfig.Configuration {
    43  	testConfiguration, err := options.NewOptions().Config()
    44  	require.NoError(t, err)
    45  	require.NotNil(t, testConfiguration)
    46  
    47  	testConfiguration.NodeName = nodeName
    48  	testConfiguration.CheckpointManagerDir = checkpoint
    49  	return testConfiguration
    50  }
    51  
    52  func Test_spdManager_GetSPD(t *testing.T) {
    53  	t.Parallel()
    54  
    55  	type fields struct {
    56  		nodeName string
    57  		spd      *workloadapis.ServiceProfileDescriptor
    58  		cnc      *v1alpha1.CustomNodeConfig
    59  	}
    60  	type args struct {
    61  		pod *v1.Pod
    62  	}
    63  	tests := []struct {
    64  		name    string
    65  		fields  fields
    66  		args    args
    67  		want    *workloadapis.ServiceProfileDescriptor
    68  		wantErr bool
    69  	}{
    70  		{
    71  			name: "test-1",
    72  			fields: fields{
    73  				nodeName: "node-1",
    74  				spd: &workloadapis.ServiceProfileDescriptor{
    75  					ObjectMeta: metav1.ObjectMeta{
    76  						Name:      "spd-1",
    77  						Namespace: "default",
    78  						Annotations: map[string]string{
    79  							pkgconsts.ServiceProfileDescriptorAnnotationKeyConfigHash: "3c7e3ff3f218",
    80  						},
    81  					},
    82  				},
    83  				cnc: &v1alpha1.CustomNodeConfig{
    84  					ObjectMeta: metav1.ObjectMeta{
    85  						Name: "node-1",
    86  					},
    87  					Status: v1alpha1.CustomNodeConfigStatus{
    88  						ServiceProfileConfigList: []v1alpha1.TargetConfig{
    89  							{
    90  								ConfigName:      "spd-1",
    91  								ConfigNamespace: "default",
    92  								Hash:            "3c7e3ff3f218",
    93  							},
    94  						},
    95  					},
    96  				},
    97  			},
    98  			args: args{
    99  				pod: &v1.Pod{
   100  					ObjectMeta: metav1.ObjectMeta{
   101  						Name:      "pod-1",
   102  						Namespace: "default",
   103  						Annotations: map[string]string{
   104  							consts.PodAnnotationSPDNameKey: "spd-1",
   105  						},
   106  					},
   107  				},
   108  			},
   109  			want: &workloadapis.ServiceProfileDescriptor{
   110  				ObjectMeta: metav1.ObjectMeta{
   111  					Name:      "spd-1",
   112  					Namespace: "default",
   113  					Annotations: map[string]string{
   114  						pkgconsts.ServiceProfileDescriptorAnnotationKeyConfigHash: "3c7e3ff3f218",
   115  					},
   116  				},
   117  			},
   118  		},
   119  		{
   120  			name: "test-2",
   121  			fields: fields{
   122  				nodeName: "node-1",
   123  				spd: &workloadapis.ServiceProfileDescriptor{
   124  					ObjectMeta: metav1.ObjectMeta{
   125  						Name:      "spd-1",
   126  						Namespace: "default",
   127  						Annotations: map[string]string{
   128  							pkgconsts.ServiceProfileDescriptorAnnotationKeyConfigHash: "3c7e3ff3f218",
   129  						},
   130  					},
   131  					Spec: workloadapis.ServiceProfileDescriptorSpec{
   132  						BusinessIndicator: []workloadapis.ServiceBusinessIndicatorSpec{
   133  							{
   134  								Name: workloadapis.ServiceBusinessIndicatorNameRPCLatency,
   135  							},
   136  						},
   137  					},
   138  				},
   139  				cnc: &v1alpha1.CustomNodeConfig{
   140  					ObjectMeta: metav1.ObjectMeta{
   141  						Name: "node-1",
   142  					},
   143  					Status: v1alpha1.CustomNodeConfigStatus{
   144  						ServiceProfileConfigList: []v1alpha1.TargetConfig{
   145  							{
   146  								ConfigName:      "spd-1",
   147  								ConfigNamespace: "default",
   148  								Hash:            "3c7e3ff3f218",
   149  							},
   150  						},
   151  					},
   152  				},
   153  			},
   154  			args: args{
   155  				pod: &v1.Pod{
   156  					ObjectMeta: metav1.ObjectMeta{
   157  						Name:      "pod-1",
   158  						Namespace: "default",
   159  						Annotations: map[string]string{
   160  							consts.PodAnnotationSPDNameKey: "spd-1",
   161  						},
   162  					},
   163  				},
   164  			},
   165  			want: &workloadapis.ServiceProfileDescriptor{
   166  				ObjectMeta: metav1.ObjectMeta{
   167  					Name:      "spd-1",
   168  					Namespace: "default",
   169  					Annotations: map[string]string{
   170  						pkgconsts.ServiceProfileDescriptorAnnotationKeyConfigHash: "3c7e3ff3f218",
   171  					},
   172  				},
   173  				Spec: workloadapis.ServiceProfileDescriptorSpec{
   174  					BusinessIndicator: []workloadapis.ServiceBusinessIndicatorSpec{
   175  						{
   176  							Name: workloadapis.ServiceBusinessIndicatorNameRPCLatency,
   177  						},
   178  					},
   179  				},
   180  			},
   181  		},
   182  	}
   183  	for _, tt := range tests {
   184  		tt := tt
   185  		t.Run(tt.name, func(t *testing.T) {
   186  			t.Parallel()
   187  
   188  			dir, err := ioutil.TempDir("", "checkpoint-Test_spdManager_GetSPD")
   189  			require.NoError(t, err)
   190  			defer os.RemoveAll(dir)
   191  
   192  			conf := generateTestConfiguration(t, tt.fields.nodeName, dir)
   193  			genericCtx, err := katalyst_base.GenerateFakeGenericContext(nil, []runtime.Object{
   194  				tt.fields.spd,
   195  				tt.fields.cnc,
   196  			})
   197  			require.NoError(t, err)
   198  
   199  			cncFetcher := cnc.NewCachedCNCFetcher(conf.BaseConfiguration, conf.CNCConfiguration, genericCtx.Client.InternalClient.ConfigV1alpha1().CustomNodeConfigs())
   200  			s, err := NewSPDFetcher(genericCtx.Client, metrics.DummyMetrics{}, cncFetcher, conf)
   201  			require.NoError(t, err)
   202  			require.NotNil(t, s)
   203  
   204  			ctx := context.TODO()
   205  
   206  			_, _ = s.GetSPD(ctx, tt.args.pod.ObjectMeta)
   207  			go s.Run(ctx)
   208  			time.Sleep(1 * time.Second)
   209  
   210  			got, err := s.GetSPD(ctx, tt.args.pod.ObjectMeta)
   211  			if (err != nil) != tt.wantErr {
   212  				t.Errorf("GetSPD() error = %v, wantErr %v", err, tt.wantErr)
   213  				return
   214  			}
   215  			require.Equal(t, tt.want.Spec, got.Spec)
   216  			require.Equal(t, tt.want.Status, got.Status)
   217  
   218  			// second GetSPD from local cache
   219  			got, err = s.GetSPD(ctx, tt.args.pod.ObjectMeta)
   220  			if (err != nil) != tt.wantErr {
   221  				t.Errorf("GetSPD() error = %v, wantErr %v", err, tt.wantErr)
   222  				return
   223  			}
   224  			require.Equal(t, tt.want.Spec, got.Spec)
   225  			require.Equal(t, tt.want.Status, got.Status)
   226  		})
   227  	}
   228  }