github.com/kubewharf/katalyst-core@v0.5.3/pkg/agent/resourcemanager/reporter/manager_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 reporter
    18  
    19  import (
    20  	"context"
    21  	"reflect"
    22  	"testing"
    23  
    24  	"github.com/stretchr/testify/require"
    25  	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    26  	"k8s.io/apimachinery/pkg/runtime"
    27  	dynamicfake "k8s.io/client-go/dynamic/fake"
    28  	"k8s.io/client-go/kubernetes/fake"
    29  
    30  	internalfake "github.com/kubewharf/katalyst-api/pkg/client/clientset/versioned/fake"
    31  	"github.com/kubewharf/katalyst-api/pkg/protocol/reporterplugin/v1alpha1"
    32  	"github.com/kubewharf/katalyst-core/cmd/katalyst-agent/app/options"
    33  	"github.com/kubewharf/katalyst-core/pkg/client"
    34  	"github.com/kubewharf/katalyst-core/pkg/config"
    35  	"github.com/kubewharf/katalyst-core/pkg/metaserver"
    36  	"github.com/kubewharf/katalyst-core/pkg/metaserver/agent"
    37  	"github.com/kubewharf/katalyst-core/pkg/metaserver/agent/cnr"
    38  	"github.com/kubewharf/katalyst-core/pkg/metaserver/agent/node"
    39  	"github.com/kubewharf/katalyst-core/pkg/metrics"
    40  )
    41  
    42  var (
    43  	testGroupVersionKindFirst = v1.GroupVersionKind{
    44  		Group:   "test-group",
    45  		Kind:    "test-kind",
    46  		Version: "test-version",
    47  	}
    48  
    49  	testGroupVersionKindSecond = v1.GroupVersionKind{
    50  		Group:   "test-group-2",
    51  		Kind:    "test-kind-2",
    52  		Version: "test-version-2",
    53  	}
    54  )
    55  
    56  type testConverter struct {
    57  	ConvertFunc func(ctx context.Context, reportFields []*v1alpha1.ReportField) (*v1alpha1.ReportContent, error)
    58  }
    59  
    60  func (c *testConverter) Convert(ctx context.Context, reportFields []*v1alpha1.ReportField) (*v1alpha1.ReportContent, error) {
    61  	return c.ConvertFunc(ctx, reportFields)
    62  }
    63  
    64  func generateTestGenericClientSet(objects ...runtime.Object) *client.GenericClientSet {
    65  	return &client.GenericClientSet{
    66  		KubeClient:     fake.NewSimpleClientset(objects...),
    67  		InternalClient: internalfake.NewSimpleClientset(objects...),
    68  		DynamicClient:  dynamicfake.NewSimpleDynamicClient(runtime.NewScheme(), objects...),
    69  	}
    70  }
    71  
    72  func generateTestMetaServer(clientSet *client.GenericClientSet, conf *config.Configuration) *metaserver.MetaServer {
    73  	return &metaserver.MetaServer{
    74  		MetaAgent: &agent.MetaAgent{
    75  			NodeFetcher: node.NewRemoteNodeFetcher(conf.BaseConfiguration, conf.NodeConfiguration,
    76  				clientSet.KubeClient.CoreV1().Nodes()),
    77  			CNRFetcher: cnr.NewCachedCNRFetcher(conf.BaseConfiguration, conf.CNRConfiguration,
    78  				clientSet.InternalClient.NodeV1alpha1().CustomNodeResources()),
    79  		},
    80  	}
    81  }
    82  
    83  func generateTestConfiguration(t *testing.T) *config.Configuration {
    84  	testConfiguration, err := options.NewOptions().Config()
    85  	require.NoError(t, err)
    86  	require.NotNil(t, testConfiguration)
    87  	return testConfiguration
    88  }
    89  
    90  func TestNewReporterManager(t *testing.T) {
    91  	t.Parallel()
    92  
    93  	testClientSet := generateTestGenericClientSet()
    94  	testMetricEmitter := &metrics.DummyMetrics{}
    95  	testConfiguration := generateTestConfiguration(t)
    96  
    97  	testMetaServer := generateTestMetaServer(testClientSet, testConfiguration)
    98  	require.NotNil(t, testMetaServer)
    99  
   100  	testManager, err := NewReporterManager(generateTestGenericClientSet(), testMetaServer, testMetricEmitter, testConfiguration)
   101  	require.NoError(t, err)
   102  	require.NotNil(t, testManager)
   103  }
   104  
   105  func Test_aggregateReportFieldsByGVK(t *testing.T) {
   106  	t.Parallel()
   107  
   108  	type args struct {
   109  		reportResponses map[string]*v1alpha1.GetReportContentResponse
   110  	}
   111  	tests := []struct {
   112  		name string
   113  		args args
   114  		want map[v1.GroupVersionKind][]*v1alpha1.ReportField
   115  	}{
   116  		{
   117  			name: "test-1",
   118  			args: args{
   119  				reportResponses: map[string]*v1alpha1.GetReportContentResponse{
   120  					"agent-1": {
   121  						Content: []*v1alpha1.ReportContent{
   122  							{
   123  								GroupVersionKind: &testGroupVersionKindFirst,
   124  								Field: []*v1alpha1.ReportField{
   125  									{
   126  										FieldType: v1alpha1.FieldType_Spec,
   127  										FieldName: "fieldName_a",
   128  										Value:     []byte("Value_a"),
   129  									},
   130  								},
   131  							},
   132  						},
   133  					},
   134  				},
   135  			},
   136  			want: map[v1.GroupVersionKind][]*v1alpha1.ReportField{
   137  				testGroupVersionKindFirst: {
   138  					{
   139  						FieldType: v1alpha1.FieldType_Spec,
   140  						FieldName: "fieldName_a",
   141  						Value:     []byte("Value_a"),
   142  					},
   143  				},
   144  			},
   145  		},
   146  	}
   147  	for _, tt := range tests {
   148  		tt := tt
   149  		t.Run(tt.name, func(t *testing.T) {
   150  			t.Parallel()
   151  			if got := aggregateReportFieldsByGVK(tt.args.reportResponses); !reflect.DeepEqual(got, tt.want) {
   152  				t.Errorf("aggregateReportFieldsByGVK() = %v, want %v", got, tt.want)
   153  			}
   154  		})
   155  	}
   156  }
   157  
   158  func Test_managerImpl_PushContents(t *testing.T) {
   159  	t.Parallel()
   160  
   161  	type fields struct {
   162  		conf      *config.Configuration
   163  		reporters map[v1.GroupVersionKind]Reporter
   164  	}
   165  	type args struct {
   166  		ctx       context.Context
   167  		responses map[string]*v1alpha1.GetReportContentResponse
   168  	}
   169  	tests := []struct {
   170  		name    string
   171  		fields  fields
   172  		args    args
   173  		wantErr bool
   174  	}{
   175  		{
   176  			name: "test-1",
   177  			fields: fields{
   178  				conf: generateTestConfiguration(t),
   179  				reporters: map[v1.GroupVersionKind]Reporter{
   180  					testGroupVersionKindFirst: NewReporterStub(),
   181  				},
   182  			},
   183  			args: args{
   184  				ctx: context.TODO(),
   185  				responses: map[string]*v1alpha1.GetReportContentResponse{
   186  					"agent-1": {
   187  						Content: []*v1alpha1.ReportContent{
   188  							{
   189  								GroupVersionKind: &testGroupVersionKindFirst,
   190  								Field: []*v1alpha1.ReportField{
   191  									{
   192  										FieldType: v1alpha1.FieldType_Spec,
   193  										FieldName: "fieldName_a",
   194  										Value:     []byte("Value_a"),
   195  									},
   196  								},
   197  							},
   198  						},
   199  					},
   200  				},
   201  			},
   202  			wantErr: false,
   203  		},
   204  	}
   205  	for _, tt := range tests {
   206  		tt := tt
   207  		t.Run(tt.name, func(t *testing.T) {
   208  			t.Parallel()
   209  			r := &managerImpl{
   210  				conf:      tt.fields.conf,
   211  				reporters: tt.fields.reporters,
   212  			}
   213  			if err := r.PushContents(tt.args.ctx, tt.args.responses); (err != nil) != tt.wantErr {
   214  				t.Errorf("PushContents() error = %v, wantErr %v", err, tt.wantErr)
   215  			}
   216  		})
   217  	}
   218  }
   219  
   220  func Test_managerImpl_Run(t *testing.T) {
   221  	t.Parallel()
   222  
   223  	type fields struct {
   224  		conf      *config.Configuration
   225  		reporters map[v1.GroupVersionKind]Reporter
   226  	}
   227  	type args struct {
   228  		ctx context.Context
   229  	}
   230  	tests := []struct {
   231  		name   string
   232  		fields fields
   233  		args   args
   234  	}{
   235  		{
   236  			name:   "test-1",
   237  			fields: fields{},
   238  			args: args{
   239  				ctx: context.TODO(),
   240  			},
   241  		},
   242  	}
   243  	for _, tt := range tests {
   244  		tt := tt
   245  		t.Run(tt.name, func(t *testing.T) {
   246  			t.Parallel()
   247  			r := &managerImpl{
   248  				conf:      tt.fields.conf,
   249  				reporters: tt.fields.reporters,
   250  			}
   251  			go r.Run(tt.args.ctx)
   252  		})
   253  	}
   254  }
   255  
   256  func Test_managerImpl_convertReportFieldsIfNeeded(t *testing.T) {
   257  	t.Parallel()
   258  
   259  	type fields struct {
   260  		converters map[v1.GroupVersionKind]Converter
   261  	}
   262  	type args struct {
   263  		reportFieldsByGVK map[v1.GroupVersionKind][]*v1alpha1.ReportField
   264  	}
   265  	tests := []struct {
   266  		name    string
   267  		fields  fields
   268  		args    args
   269  		want    map[v1.GroupVersionKind][]*v1alpha1.ReportField
   270  		wantErr bool
   271  	}{
   272  		{
   273  			name: "test-1",
   274  			fields: fields{
   275  				converters: map[v1.GroupVersionKind]Converter{
   276  					testGroupVersionKindFirst: &testConverter{
   277  						func(ctx context.Context, reportFields []*v1alpha1.ReportField) (*v1alpha1.ReportContent, error) {
   278  							return &v1alpha1.ReportContent{
   279  								GroupVersionKind: &testGroupVersionKindSecond,
   280  								Field:            reportFields,
   281  							}, nil
   282  						},
   283  					},
   284  				},
   285  			},
   286  			args: args{
   287  				reportFieldsByGVK: map[v1.GroupVersionKind][]*v1alpha1.ReportField{
   288  					testGroupVersionKindFirst: {
   289  						{
   290  							FieldType: v1alpha1.FieldType_Spec,
   291  							FieldName: "fieldName_a",
   292  							Value:     []byte("Value_a"),
   293  						},
   294  					},
   295  				},
   296  			},
   297  			want: map[v1.GroupVersionKind][]*v1alpha1.ReportField{
   298  				testGroupVersionKindSecond: {
   299  					{
   300  						FieldType: v1alpha1.FieldType_Spec,
   301  						FieldName: "fieldName_a",
   302  						Value:     []byte("Value_a"),
   303  					},
   304  				},
   305  			},
   306  		},
   307  	}
   308  	for _, tt := range tests {
   309  		tt := tt
   310  		t.Run(tt.name, func(t *testing.T) {
   311  			t.Parallel()
   312  			r := &managerImpl{
   313  				converters: tt.fields.converters,
   314  			}
   315  			got, err := r.convertReportFieldsIfNeeded(context.Background(), tt.args.reportFieldsByGVK)
   316  			if (err != nil) != tt.wantErr {
   317  				t.Errorf("convertReportFieldsIfNeeded() error = %v, wantErr %v", err, tt.wantErr)
   318  				return
   319  			}
   320  			if !reflect.DeepEqual(got, tt.want) {
   321  				t.Errorf("convertReportFieldsIfNeeded() got = %v, want %v", got, tt.want)
   322  			}
   323  		})
   324  	}
   325  }