github.com/kubewharf/katalyst-core@v0.5.3/pkg/custom-metric/store/data/cache_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 data
    18  
    19  import (
    20  	"encoding/json"
    21  	"testing"
    22  	"time"
    23  
    24  	"github.com/stretchr/testify/assert"
    25  	"k8s.io/apimachinery/pkg/labels"
    26  	"k8s.io/apimachinery/pkg/runtime/schema"
    27  
    28  	"github.com/kubewharf/katalyst-api/pkg/metric"
    29  	"github.com/kubewharf/katalyst-core/pkg/custom-metric/store/data/types"
    30  	"github.com/kubewharf/katalyst-core/pkg/metrics"
    31  )
    32  
    33  func TestCache(t *testing.T) {
    34  	t.Parallel()
    35  
    36  	c := NewCachedMetric(metrics.DummyMetrics{}, ObjectMetricStoreTypeBucket)
    37  
    38  	var (
    39  		exist      bool
    40  		names      []string
    41  		metaList   []types.MetricMeta
    42  		metricList []types.Metric
    43  	)
    44  
    45  	t.Log("#### 1: Add with none-namespaced metric")
    46  
    47  	s1 := &types.SeriesMetric{
    48  		MetricMetaImp: types.MetricMetaImp{
    49  			Name: "m-1",
    50  		},
    51  		ObjectMetaImp: types.ObjectMetaImp{},
    52  		BasicMetric: types.BasicMetric{
    53  			Labels: map[string]string{
    54  				"Name": "m-1",
    55  			},
    56  		},
    57  	}
    58  	s1.AddMetric(&types.SeriesItem{
    59  		Value:     1,
    60  		Timestamp: 1,
    61  	})
    62  	c.AddSeriesMetric(s1)
    63  
    64  	names = c.ListAllMetricNames()
    65  	assert.ElementsMatch(t, []string{"m-1"}, names)
    66  
    67  	var err error
    68  
    69  	metricList, exist, err = c.GetMetric("", "m-1", "", nil, false, nil, nil, false)
    70  	assert.NoError(t, err)
    71  	assert.Equal(t, true, exist)
    72  	assert.Equal(t, s1, metricList[0])
    73  
    74  	_, exist, err = c.GetMetric("", "m-2", "", nil, false, nil, nil, false)
    75  	assert.NoError(t, err)
    76  	assert.Equal(t, false, exist)
    77  
    78  	t.Log("#### 2: Add with namespaced metric")
    79  
    80  	s2 := &types.SeriesMetric{
    81  		MetricMetaImp: types.MetricMetaImp{
    82  			Name:       "m-2",
    83  			Namespaced: true,
    84  		},
    85  		ObjectMetaImp: types.ObjectMetaImp{
    86  			ObjectNamespace: "n-2",
    87  		},
    88  		BasicMetric: types.BasicMetric{
    89  			Labels: map[string]string{
    90  				"Name": "m-2",
    91  			},
    92  		},
    93  	}
    94  	s2.AddMetric(&types.SeriesItem{
    95  		Value:     2,
    96  		Timestamp: 3,
    97  	})
    98  	c.AddSeriesMetric(s2)
    99  
   100  	names = c.ListAllMetricNames()
   101  	assert.ElementsMatch(t, []string{"m-1", "m-2"}, names)
   102  
   103  	metricList, exist, err = c.GetMetric("", "m-1", "", nil, false, nil, nil, false)
   104  	assert.NoError(t, err)
   105  	assert.Equal(t, true, exist)
   106  	assert.Equal(t, s1, metricList[0])
   107  
   108  	metricList, exist, err = c.GetMetric("n-2", "m-2", "", nil, false, nil, nil, false)
   109  	assert.NoError(t, err)
   110  	assert.Equal(t, true, exist)
   111  	assert.Equal(t, s2, metricList[0])
   112  
   113  	t.Log("#### 3: Add pod with objected metric")
   114  
   115  	s3 := &types.SeriesMetric{
   116  		MetricMetaImp: types.MetricMetaImp{
   117  			Name:       "m-3",
   118  			Namespaced: true,
   119  			ObjectKind: "pod",
   120  		},
   121  		ObjectMetaImp: types.ObjectMetaImp{
   122  			ObjectNamespace: "n-3",
   123  			ObjectName:      "pod-3",
   124  		},
   125  		BasicMetric: types.BasicMetric{
   126  			Labels: map[string]string{
   127  				"Name": "m-3",
   128  			},
   129  		},
   130  	}
   131  	s3.AddMetric(&types.SeriesItem{
   132  		Value:     4,
   133  		Timestamp: 5,
   134  	})
   135  	c.AddSeriesMetric(s3)
   136  
   137  	names = c.ListAllMetricNames()
   138  	assert.ElementsMatch(t, []string{"m-1", "m-2", "m-3"}, names)
   139  
   140  	metaList = c.ListAllMetricMeta(false)
   141  	assert.ElementsMatch(t, []types.MetricMetaImp{
   142  		{
   143  			Name: "m-1",
   144  		},
   145  		{
   146  			Name:       "m-2",
   147  			Namespaced: true,
   148  		},
   149  	}, metaList)
   150  
   151  	metaList = c.ListAllMetricMeta(true)
   152  	assert.ElementsMatch(t, []types.MetricMetaImp{
   153  		{
   154  			Name:       "m-3",
   155  			Namespaced: true,
   156  			ObjectKind: "pod",
   157  		},
   158  	}, metaList)
   159  
   160  	_, exist, err = c.GetMetric("n-4", "m-3", "", nil, false, &schema.GroupResource{Resource: "pod"}, nil, false)
   161  	assert.NoError(t, err)
   162  	assert.Equal(t, true, exist)
   163  
   164  	metricList, exist, err = c.GetMetric("n-3", "m-3", "", nil, false, &schema.GroupResource{Resource: "pod"}, nil, false)
   165  	assert.NoError(t, err)
   166  	assert.Equal(t, true, exist)
   167  	assert.Equal(t, s3, metricList[0])
   168  
   169  	t.Log("#### 4: Add pod with the same metric Name")
   170  
   171  	s3_1 := &types.SeriesMetric{
   172  		MetricMetaImp: types.MetricMetaImp{
   173  			Name:       "m-3",
   174  			Namespaced: true,
   175  			ObjectKind: "pod",
   176  		},
   177  		ObjectMetaImp: types.ObjectMetaImp{
   178  			ObjectNamespace: "n-3",
   179  			ObjectName:      "pod-3",
   180  		},
   181  		BasicMetric: types.BasicMetric{
   182  			Labels: map[string]string{
   183  				"Name": "m-3",
   184  			},
   185  		},
   186  	}
   187  	s3_1.AddMetric(&types.SeriesItem{
   188  		Value:     7,
   189  		Timestamp: 8,
   190  	})
   191  	c.AddSeriesMetric(s3_1)
   192  
   193  	names = c.ListAllMetricNames()
   194  	assert.ElementsMatch(t, []string{"m-1", "m-2", "m-3"}, names)
   195  
   196  	s3 = &types.SeriesMetric{
   197  		MetricMetaImp: types.MetricMetaImp{
   198  			Name:       "m-3",
   199  			Namespaced: true,
   200  			ObjectKind: "pod",
   201  		},
   202  		ObjectMetaImp: types.ObjectMetaImp{
   203  			ObjectNamespace: "n-3",
   204  			ObjectName:      "pod-3",
   205  		},
   206  		BasicMetric: types.BasicMetric{
   207  			Labels: map[string]string{
   208  				"Name": "m-3",
   209  			},
   210  		},
   211  	}
   212  	s3.AddMetric(&types.SeriesItem{
   213  		Value:     4,
   214  		Timestamp: 5,
   215  	})
   216  	s3.AddMetric(&types.SeriesItem{
   217  		Value:     7,
   218  		Timestamp: 8,
   219  	})
   220  	metricList, exist, err = c.GetMetric("n-3", "m-3", "", nil, false, &schema.GroupResource{Resource: "pod"}, nil, false)
   221  	assert.NoError(t, err)
   222  	assert.Equal(t, true, exist)
   223  	assert.Equal(t, s3, metricList[0])
   224  
   225  	t.Log("#### 5: Add pod another meta")
   226  
   227  	s4 := &types.SeriesMetric{
   228  		MetricMetaImp: types.MetricMetaImp{
   229  			Name:       "m-3",
   230  			Namespaced: true,
   231  			ObjectKind: "pod",
   232  		},
   233  		ObjectMetaImp: types.ObjectMetaImp{
   234  			ObjectNamespace: "n-3",
   235  			ObjectName:      "pod-4",
   236  		},
   237  		BasicMetric: types.BasicMetric{
   238  			Labels: map[string]string{
   239  				"Name": "m-3",
   240  			},
   241  		},
   242  	}
   243  	s4.AddMetric(&types.SeriesItem{
   244  		Value:     10,
   245  		Timestamp: 12,
   246  	})
   247  	c.AddSeriesMetric(s4)
   248  
   249  	names = c.ListAllMetricNames()
   250  	assert.ElementsMatch(t, []string{"m-1", "m-2", "m-3"}, names)
   251  
   252  	metricList, exist, err = c.GetMetric("n-3", "m-3", "", nil, false, &schema.GroupResource{Resource: "pod"}, nil, false)
   253  	assert.NoError(t, err)
   254  	assert.Equal(t, true, exist)
   255  	assert.ElementsMatch(t, []*types.SeriesMetric{s3, s4}, metricList)
   256  
   257  	metricList, exist, err = c.GetMetric("n-3", "m-3", "pod-3", nil, false, &schema.GroupResource{Resource: "pod"}, nil, false)
   258  	assert.NoError(t, err)
   259  	assert.Equal(t, true, exist)
   260  	assert.ElementsMatch(t, []*types.SeriesMetric{s3}, metricList)
   261  
   262  	metricList, exist, err = c.GetMetric("n-3", "m-3", "pod-4", nil, false, &schema.GroupResource{Resource: "pod"}, nil, false)
   263  	assert.NoError(t, err)
   264  	assert.Equal(t, true, exist)
   265  	assert.ElementsMatch(t, []*types.SeriesMetric{s4}, metricList)
   266  
   267  	t.Log("#### 6: Add pod with the duplicated Timestamp")
   268  
   269  	s3_2 := &types.SeriesMetric{
   270  		MetricMetaImp: types.MetricMetaImp{
   271  			Name:       "m-3",
   272  			Namespaced: true,
   273  			ObjectKind: "pod",
   274  		},
   275  		ObjectMetaImp: types.ObjectMetaImp{
   276  			ObjectNamespace: "n-3",
   277  			ObjectName:      "pod-3",
   278  		},
   279  		BasicMetric: types.BasicMetric{
   280  			Labels: map[string]string{
   281  				"Name":  "m-3",
   282  				"extra": "m-3",
   283  			},
   284  		},
   285  	}
   286  	s3_2.AddMetric(&types.SeriesItem{
   287  		Value:     10,
   288  		Timestamp: 9,
   289  	})
   290  	s3_2.AddMetric(&types.SeriesItem{
   291  		Value:     9,
   292  		Timestamp: 8,
   293  	})
   294  	c.AddSeriesMetric(s3_2)
   295  
   296  	names = c.ListAllMetricNames()
   297  	assert.ElementsMatch(t, []string{"m-1", "m-2", "m-3"}, names)
   298  
   299  	s3 = &types.SeriesMetric{
   300  		MetricMetaImp: types.MetricMetaImp{
   301  			Name:       "m-3",
   302  			Namespaced: true,
   303  			ObjectKind: "pod",
   304  		},
   305  		ObjectMetaImp: types.ObjectMetaImp{
   306  			ObjectNamespace: "n-3",
   307  			ObjectName:      "pod-3",
   308  		},
   309  		BasicMetric: types.BasicMetric{
   310  			Labels: map[string]string{
   311  				"Name": "m-3",
   312  			},
   313  		},
   314  	}
   315  	s3.AddMetric(&types.SeriesItem{
   316  		Value:     4,
   317  		Timestamp: 5,
   318  	})
   319  	s3.AddMetric(&types.SeriesItem{
   320  		Value:     7,
   321  		Timestamp: 8,
   322  	})
   323  
   324  	s3_1 = &types.SeriesMetric{
   325  		MetricMetaImp: types.MetricMetaImp{
   326  			Name:       "m-3",
   327  			Namespaced: true,
   328  			ObjectKind: "pod",
   329  		},
   330  		ObjectMetaImp: types.ObjectMetaImp{
   331  			ObjectNamespace: "n-3",
   332  			ObjectName:      "pod-3",
   333  		},
   334  		BasicMetric: types.BasicMetric{
   335  			Labels: map[string]string{
   336  				"Name":  "m-3",
   337  				"extra": "m-3",
   338  			},
   339  		},
   340  	}
   341  	s3_1.AddMetric(&types.SeriesItem{
   342  		Value:     9,
   343  		Timestamp: 8,
   344  	})
   345  	s3_1.AddMetric(&types.SeriesItem{
   346  		Value:     10,
   347  		Timestamp: 9,
   348  	})
   349  	metricList, exist, err = c.GetMetric("n-3", "m-3", "", nil, false, &schema.GroupResource{Resource: "pod"}, nil, false)
   350  	assert.NoError(t, err)
   351  	assert.Equal(t, true, exist)
   352  	assert.ElementsMatch(t, []*types.SeriesMetric{s3, s3_1, s4}, metricList)
   353  
   354  	selector, _ := labels.Parse("extra=m-3")
   355  	metricList, exist, err = c.GetMetric("n-3", "m-3", "", nil, false, &schema.GroupResource{Resource: "pod"}, selector, false)
   356  	assert.NoError(t, err)
   357  	assert.Equal(t, true, exist)
   358  	assert.ElementsMatch(t, []*types.SeriesMetric{s3_1}, metricList)
   359  
   360  	s3_latest := &types.SeriesMetric{
   361  		MetricMetaImp: types.MetricMetaImp{
   362  			Name:       "m-3",
   363  			Namespaced: true,
   364  			ObjectKind: "pod",
   365  		},
   366  		ObjectMetaImp: types.ObjectMetaImp{
   367  			ObjectNamespace: "n-3",
   368  			ObjectName:      "pod-3",
   369  		},
   370  		BasicMetric: types.BasicMetric{
   371  			Labels: map[string]string{
   372  				"Name":  "m-3",
   373  				"extra": "m-3",
   374  			},
   375  		},
   376  	}
   377  	s3_latest.AddMetric(&types.SeriesItem{
   378  		Value:     10,
   379  		Timestamp: 9,
   380  	})
   381  	metricList, exist, err = c.GetMetric("n-3", "m-3", "", nil, false, &schema.GroupResource{Resource: "pod"}, nil, true)
   382  	assert.NoError(t, err)
   383  	assert.Equal(t, true, exist)
   384  	assert.ElementsMatch(t, []*types.SeriesMetric{s3_latest, s4}, metricList)
   385  
   386  	t.Log("#### 7: list all metric")
   387  
   388  	metricList = c.GetAllMetricsInNamespace("")
   389  	assert.ElementsMatch(t, []*types.SeriesMetric{s1}, metricList)
   390  
   391  	metricList = c.GetAllMetricsInNamespace("n-2")
   392  	assert.ElementsMatch(t, []*types.SeriesMetric{s2}, metricList)
   393  
   394  	metricList = c.GetAllMetricsInNamespace("n-3")
   395  	assert.ElementsMatch(t, []*types.SeriesMetric{s3, s3_1, s4}, metricList)
   396  
   397  	t.Log("#### 8: gcMetric")
   398  	c.gcWithTimestamp(3)
   399  	c.Purge()
   400  	names = c.ListAllMetricNames()
   401  	assert.ElementsMatch(t, []string{"m-3"}, names)
   402  
   403  	metricList = c.GetAllMetricsInNamespace("")
   404  	assert.ElementsMatch(t, []*types.SeriesMetric{}, metricList)
   405  
   406  	metricList = c.GetAllMetricsInNamespace("n-2")
   407  	assert.ElementsMatch(t, []*types.SeriesMetric{}, metricList)
   408  
   409  	metricList = c.GetAllMetricsInNamespace("n-3")
   410  	assert.ElementsMatch(t, []*types.SeriesMetric{s3, s3_1, s4}, metricList)
   411  
   412  	c.gcWithTimestamp(8)
   413  	names = c.ListAllMetricNames()
   414  	assert.ElementsMatch(t, []string{"m-3"}, names)
   415  
   416  	s3 = &types.SeriesMetric{
   417  		MetricMetaImp: types.MetricMetaImp{
   418  			Name:       "m-3",
   419  			Namespaced: true,
   420  			ObjectKind: "pod",
   421  		},
   422  		ObjectMetaImp: types.ObjectMetaImp{
   423  			ObjectNamespace: "n-3",
   424  			ObjectName:      "pod-3",
   425  		},
   426  		BasicMetric: types.BasicMetric{
   427  			Labels: map[string]string{
   428  				"Name":  "m-3",
   429  				"extra": "m-3",
   430  			},
   431  		},
   432  	}
   433  	s3.AddMetric(&types.SeriesItem{
   434  		Value:     10,
   435  		Timestamp: 9,
   436  	})
   437  
   438  	s4 = &types.SeriesMetric{
   439  		MetricMetaImp: types.MetricMetaImp{
   440  			Name:       "m-3",
   441  			Namespaced: true,
   442  			ObjectKind: "pod",
   443  		},
   444  		ObjectMetaImp: types.ObjectMetaImp{
   445  			ObjectNamespace: "n-3",
   446  			ObjectName:      "pod-4",
   447  		},
   448  		BasicMetric: types.BasicMetric{
   449  			Labels: map[string]string{
   450  				"Name": "m-3",
   451  			},
   452  		},
   453  	}
   454  	s4.AddMetric(&types.SeriesItem{
   455  		Value:     10,
   456  		Timestamp: 12,
   457  	})
   458  	metricList = c.GetAllMetricsInNamespace("n-3")
   459  	assert.ElementsMatch(t, []*types.SeriesMetric{s3, s4}, metricList)
   460  
   461  	bytes, err := json.Marshal(metricList)
   462  	assert.NoError(t, err)
   463  	t.Logf("%v", string(bytes))
   464  
   465  	res, err := types.UnmarshalMetricList(bytes)
   466  	assert.NoError(t, err)
   467  	assert.ElementsMatch(t, metricList, res)
   468  
   469  	t.Log("#### 9: get agg metric")
   470  
   471  	s5 := &types.SeriesMetric{
   472  		MetricMetaImp: types.MetricMetaImp{
   473  			Name:       "m-3",
   474  			Namespaced: true,
   475  			ObjectKind: "pod",
   476  		},
   477  		ObjectMetaImp: types.ObjectMetaImp{
   478  			ObjectNamespace: "n-3",
   479  			ObjectName:      "pod-5",
   480  		},
   481  		BasicMetric: types.BasicMetric{
   482  			Labels: map[string]string{
   483  				"Name": "m-3",
   484  			},
   485  		},
   486  	}
   487  	s5.AddMetric(&types.SeriesItem{
   488  		Value:     4,
   489  		Timestamp: 12 * time.Second.Milliseconds(),
   490  	})
   491  	s5.AddMetric(&types.SeriesItem{
   492  		Value:     7,
   493  		Timestamp: 14 * time.Second.Milliseconds(),
   494  	})
   495  
   496  	s5_1 := &types.SeriesMetric{
   497  		MetricMetaImp: types.MetricMetaImp{
   498  			Name:       "m-3",
   499  			Namespaced: true,
   500  			ObjectKind: "pod",
   501  		},
   502  		ObjectMetaImp: types.ObjectMetaImp{
   503  			ObjectNamespace: "n-3",
   504  			ObjectName:      "pod-5",
   505  		},
   506  		BasicMetric: types.BasicMetric{
   507  			Labels: map[string]string{
   508  				"Name":  "m-3",
   509  				"extra": "m-3",
   510  			},
   511  		},
   512  	}
   513  
   514  	s5_1.AddMetric(&types.SeriesItem{
   515  		Value:     12,
   516  		Timestamp: 18 * time.Second.Milliseconds(),
   517  	})
   518  	s5_1.AddMetric(&types.SeriesItem{
   519  		Value:     10,
   520  		Timestamp: 20 * time.Second.Milliseconds(),
   521  	})
   522  	c.AddSeriesMetric(s5)
   523  	c.AddSeriesMetric(s5_1)
   524  
   525  	metricList, exist, err = c.GetMetric("n-3", "m-3", "pod-5", nil, false, &schema.GroupResource{Resource: "pod"}, nil, false)
   526  	assert.NoError(t, err)
   527  	assert.Equal(t, true, exist)
   528  	assert.ElementsMatch(t, []*types.SeriesMetric{s5, s5_1}, metricList)
   529  
   530  	agg := &types.AggregatedMetric{
   531  		MetricMetaImp: types.MetricMetaImp{
   532  			Name:       "m-3",
   533  			Namespaced: true,
   534  			ObjectKind: "pod",
   535  		},
   536  		ObjectMetaImp: types.ObjectMetaImp{
   537  			ObjectNamespace: "n-3",
   538  			ObjectName:      "pod-5",
   539  		},
   540  		AggregatedIdentity: types.AggregatedIdentity{
   541  			Count:         4,
   542  			Timestamp:     20 * time.Second.Milliseconds(),
   543  			WindowSeconds: 8,
   544  		},
   545  	}
   546  
   547  	matchedAgg := &types.AggregatedMetric{
   548  		MetricMetaImp: types.MetricMetaImp{
   549  			Name:       "m-3",
   550  			Namespaced: true,
   551  			ObjectKind: "pod",
   552  		},
   553  		ObjectMetaImp: types.ObjectMetaImp{
   554  			ObjectNamespace: "n-3",
   555  			ObjectName:      "pod-5",
   556  		},
   557  		AggregatedIdentity: types.AggregatedIdentity{
   558  			Count:         2,
   559  			Timestamp:     20 * time.Second.Milliseconds(),
   560  			WindowSeconds: 2,
   561  		},
   562  	}
   563  
   564  	agg.Name = "m-3" + metric.AggregateFunctionAvg
   565  	agg.Value = 8.25
   566  	metricList, exist, err = c.GetMetric("n-3", "m-3"+metric.AggregateFunctionAvg, "pod-5", nil, false, &schema.GroupResource{Resource: "pod"}, nil, false)
   567  	assert.NoError(t, err)
   568  	assert.Equal(t, true, exist)
   569  	assert.ElementsMatch(t, []*types.AggregatedMetric{agg}, metricList)
   570  
   571  	matchedAgg.Name = "m-3" + metric.AggregateFunctionAvg
   572  	matchedAgg.Value = 11
   573  	matchedAgg.Labels = map[string]string{}
   574  	metricList, exist, err = c.GetMetric("n-3", "m-3"+metric.AggregateFunctionAvg, "pod-5", nil, false, &schema.GroupResource{Resource: "pod"}, selector, false)
   575  	assert.NoError(t, err)
   576  	assert.Equal(t, true, exist)
   577  	assert.ElementsMatch(t, []*types.AggregatedMetric{matchedAgg}, metricList)
   578  
   579  	agg.Name = "m-3" + metric.AggregateFunctionMax
   580  	agg.Value = 12
   581  	metricList, exist, err = c.GetMetric("n-3", "m-3"+metric.AggregateFunctionMax, "pod-5", nil, false, &schema.GroupResource{Resource: "pod"}, nil, false)
   582  	assert.NoError(t, err)
   583  	assert.Equal(t, true, exist)
   584  	assert.ElementsMatch(t, []*types.AggregatedMetric{agg}, metricList)
   585  
   586  	matchedAgg.Name = "m-3" + metric.AggregateFunctionMax
   587  	matchedAgg.Value = 12
   588  	metricList, exist, err = c.GetMetric("n-3", "m-3"+metric.AggregateFunctionMax, "pod-5", nil, false, &schema.GroupResource{Resource: "pod"}, selector, false)
   589  	assert.NoError(t, err)
   590  	assert.Equal(t, true, exist)
   591  	assert.ElementsMatch(t, []*types.AggregatedMetric{matchedAgg}, metricList)
   592  
   593  	agg.Name = "m-3" + metric.AggregateFunctionMin
   594  	agg.Value = 4
   595  	metricList, exist, err = c.GetMetric("n-3", "m-3"+metric.AggregateFunctionMin, "pod-5", nil, false, &schema.GroupResource{Resource: "pod"}, nil, false)
   596  	assert.NoError(t, err)
   597  	assert.Equal(t, true, exist)
   598  	assert.ElementsMatch(t, []*types.AggregatedMetric{agg}, metricList)
   599  
   600  	matchedAgg.Name = "m-3" + metric.AggregateFunctionMin
   601  	matchedAgg.Value = 10
   602  	metricList, exist, err = c.GetMetric("n-3", "m-3"+metric.AggregateFunctionMin, "pod-5", nil, false, &schema.GroupResource{Resource: "pod"}, selector, false)
   603  	assert.NoError(t, err)
   604  	assert.Equal(t, true, exist)
   605  	assert.ElementsMatch(t, []*types.AggregatedMetric{matchedAgg}, metricList)
   606  
   607  	agg.Name = "m-3" + metric.AggregateFunctionP99
   608  	agg.Value = 11
   609  	metricList, exist, err = c.GetMetric("n-3", "m-3"+metric.AggregateFunctionP99, "pod-5", nil, false, &schema.GroupResource{Resource: "pod"}, nil, false)
   610  	assert.NoError(t, err)
   611  	assert.Equal(t, true, exist)
   612  	assert.ElementsMatch(t, []*types.AggregatedMetric{agg}, metricList)
   613  
   614  	matchedAgg.Name = "m-3" + metric.AggregateFunctionP99
   615  	matchedAgg.Value = 11
   616  	metricList, exist, err = c.GetMetric("n-3", "m-3"+metric.AggregateFunctionP99, "pod-5", nil, false, &schema.GroupResource{Resource: "pod"}, selector, false)
   617  	assert.NoError(t, err)
   618  	assert.Equal(t, true, exist)
   619  	assert.ElementsMatch(t, []*types.AggregatedMetric{matchedAgg}, metricList)
   620  
   621  	agg.Name = "m-3" + metric.AggregateFunctionP90
   622  	agg.Value = 11
   623  	metricList, exist, err = c.GetMetric("n-3", "m-3"+metric.AggregateFunctionP90, "pod-5", nil, false, &schema.GroupResource{Resource: "pod"}, nil, false)
   624  	assert.NoError(t, err)
   625  	assert.Equal(t, true, exist)
   626  	assert.ElementsMatch(t, []*types.AggregatedMetric{agg}, metricList)
   627  
   628  	matchedAgg.Name = "m-3" + metric.AggregateFunctionP90
   629  	matchedAgg.Value = 11
   630  	metricList, exist, err = c.GetMetric("n-3", "m-3"+metric.AggregateFunctionP90, "pod-5", nil, false, &schema.GroupResource{Resource: "pod"}, selector, false)
   631  	assert.NoError(t, err)
   632  	assert.Equal(t, true, exist)
   633  	assert.ElementsMatch(t, []*types.AggregatedMetric{matchedAgg}, metricList)
   634  
   635  	agg.Name = "m-3" + metric.AggregateFunctionLatest
   636  	agg.Value = 10
   637  	metricList, exist, err = c.GetMetric("n-3", "m-3"+metric.AggregateFunctionLatest, "pod-5", nil, false, &schema.GroupResource{Resource: "pod"}, nil, false)
   638  	assert.NoError(t, err)
   639  	assert.Equal(t, true, exist)
   640  	assert.ElementsMatch(t, []*types.AggregatedMetric{agg}, metricList)
   641  
   642  	matchedAgg.Name = "m-3" + metric.AggregateFunctionLatest
   643  	matchedAgg.Value = 10
   644  	metricList, exist, err = c.GetMetric("n-3", "m-3"+metric.AggregateFunctionLatest, "pod-5", nil, false, &schema.GroupResource{Resource: "pod"}, selector, false)
   645  	assert.NoError(t, err)
   646  	assert.Equal(t, true, exist)
   647  	assert.ElementsMatch(t, []*types.AggregatedMetric{matchedAgg}, metricList)
   648  }
   649  
   650  func TestMergeInternalMetricList(t *testing.T) {
   651  	t.Parallel()
   652  
   653  	type args struct {
   654  		metricName  string
   655  		metricLists [][]types.Metric
   656  	}
   657  	tests := []struct {
   658  		name string
   659  		args args
   660  		want []types.Metric
   661  	}{
   662  		{
   663  			args: args{
   664  				metricName: "pod_cpu_usage_agg_max",
   665  				metricLists: [][]types.Metric{
   666  					{
   667  						&types.AggregatedMetric{
   668  							MetricMetaImp: types.MetricMetaImp{
   669  								Name:       "pod_cpu_usage_agg_max",
   670  								Namespaced: true,
   671  								ObjectKind: "pod",
   672  							},
   673  							ObjectMetaImp: types.ObjectMetaImp{
   674  								ObjectNamespace: "n-1",
   675  								ObjectName:      "pod-1",
   676  							},
   677  							BasicMetric: types.BasicMetric{
   678  								Labels: map[string]string{
   679  									"Name": "m-1",
   680  								},
   681  							},
   682  							AggregatedIdentity: types.AggregatedIdentity{
   683  								Count:         4,
   684  								Timestamp:     12 * time.Second.Milliseconds(),
   685  								WindowSeconds: 8,
   686  							},
   687  							Value: 10,
   688  						},
   689  					},
   690  					{
   691  						&types.AggregatedMetric{
   692  							MetricMetaImp: types.MetricMetaImp{
   693  								Name:       "pod_cpu_usage_agg_max",
   694  								Namespaced: true,
   695  								ObjectKind: "pod",
   696  							},
   697  							ObjectMetaImp: types.ObjectMetaImp{
   698  								ObjectNamespace: "n-1",
   699  								ObjectName:      "pod-1",
   700  							},
   701  							BasicMetric: types.BasicMetric{
   702  								Labels: map[string]string{
   703  									"Name": "m-1",
   704  								},
   705  							},
   706  							AggregatedIdentity: types.AggregatedIdentity{
   707  								Count:         4,
   708  								Timestamp:     12 * time.Second.Milliseconds(),
   709  								WindowSeconds: 8,
   710  							},
   711  							Value: 10,
   712  						},
   713  					},
   714  				},
   715  			},
   716  			want: []types.Metric{
   717  				&types.AggregatedMetric{
   718  					MetricMetaImp: types.MetricMetaImp{
   719  						Name:       "pod_cpu_usage_agg_max",
   720  						Namespaced: true,
   721  						ObjectKind: "pod",
   722  					},
   723  					ObjectMetaImp: types.ObjectMetaImp{
   724  						ObjectNamespace: "n-1",
   725  						ObjectName:      "pod-1",
   726  					},
   727  					BasicMetric: types.BasicMetric{
   728  						Labels: map[string]string{
   729  							"Name": "m-1",
   730  						},
   731  					},
   732  					AggregatedIdentity: types.AggregatedIdentity{
   733  						Count:         4,
   734  						Timestamp:     12 * time.Second.Milliseconds(),
   735  						WindowSeconds: 8,
   736  					},
   737  					Value: 10,
   738  				},
   739  			},
   740  		},
   741  	}
   742  	for _, tt := range tests {
   743  		tt := tt
   744  		t.Run(tt.name, func(t *testing.T) {
   745  			t.Parallel()
   746  			got := MergeInternalMetricList(tt.args.metricName, tt.args.metricLists...)
   747  			assert.Equalf(t, tt.want, got, "MergeInternalMetricList(%v, %v)", tt.args.metricName, tt.args.metricLists)
   748  		})
   749  	}
   750  }