github.com/kubewharf/katalyst-core@v0.5.3/pkg/agent/evictionmanager/plugin/rootfs/rootfs_pressure_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 rootfs
    18  
    19  import (
    20  	"context"
    21  	"testing"
    22  	"time"
    23  
    24  	"github.com/stretchr/testify/assert"
    25  	v1 "k8s.io/api/core/v1"
    26  	"k8s.io/apimachinery/pkg/api/resource"
    27  	k8smetav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    28  	"k8s.io/apimachinery/pkg/types"
    29  	evictionapi "k8s.io/kubernetes/pkg/kubelet/eviction/api"
    30  
    31  	pluginapi "github.com/kubewharf/katalyst-api/pkg/protocol/evictionplugin/v1alpha1"
    32  	"github.com/kubewharf/katalyst-core/pkg/agent/evictionmanager/plugin"
    33  	"github.com/kubewharf/katalyst-core/pkg/config"
    34  	"github.com/kubewharf/katalyst-core/pkg/consts"
    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/metric"
    38  	metrictypes "github.com/kubewharf/katalyst-core/pkg/metaserver/agent/metric/types"
    39  	"github.com/kubewharf/katalyst-core/pkg/metrics"
    40  	utilmetric "github.com/kubewharf/katalyst-core/pkg/util/metric"
    41  )
    42  
    43  type testConf struct {
    44  	minimumImageFsFreeThreshold                *evictionapi.ThresholdValue
    45  	minimumImageFsInodesFreeThreshold          *evictionapi.ThresholdValue
    46  	podMinimumUsedThreshold                    *evictionapi.ThresholdValue
    47  	podMinimumInodesUsedThreshold              *evictionapi.ThresholdValue
    48  	reclaimedQoSPodUsedPriorityThreshold       *evictionapi.ThresholdValue
    49  	reclaimedQosPodInodesUsedPriorityThreshold *evictionapi.ThresholdValue
    50  }
    51  
    52  func makeConf(tc *testConf) *config.Configuration {
    53  	conf := config.NewConfiguration()
    54  	// conf.EvictionManagerSyncPeriod = evictionManagerSyncPeriod
    55  	conf.GetDynamicConfiguration().EnableRootfsPressureEviction = true
    56  	conf.GetDynamicConfiguration().MinimumImageFsFreeThreshold = tc.minimumImageFsFreeThreshold
    57  	conf.GetDynamicConfiguration().MinimumImageFsInodesFreeThreshold = tc.minimumImageFsInodesFreeThreshold
    58  	conf.GetDynamicConfiguration().PodMinimumUsedThreshold = tc.podMinimumUsedThreshold
    59  	conf.GetDynamicConfiguration().PodMinimumInodesUsedThreshold = tc.podMinimumInodesUsedThreshold
    60  	conf.GetDynamicConfiguration().ReclaimedQoSPodUsedPriorityThreshold = tc.reclaimedQoSPodUsedPriorityThreshold
    61  	conf.GetDynamicConfiguration().ReclaimedQoSPodInodesUsedPriorityThreshold = tc.reclaimedQosPodInodesUsedPriorityThreshold
    62  
    63  	return conf
    64  }
    65  
    66  func createRootfsPressureEvictionPlugin(tc *testConf, emitter metrics.MetricEmitter, metricsFetcher metrictypes.MetricsFetcher) plugin.EvictionPlugin {
    67  	metaServer := &metaserver.MetaServer{
    68  		MetaAgent: &agent.MetaAgent{
    69  			MetricsFetcher: metricsFetcher,
    70  		},
    71  	}
    72  	conf := makeConf(tc)
    73  	return NewPodRootfsPressureEvictionPlugin(nil, nil, metaServer, emitter, conf)
    74  }
    75  
    76  func TestPodRootfsPressureEvictionPlugin_ThresholdMetNoMetricDataNoConf(t *testing.T) {
    77  	t.Parallel()
    78  	emitter := metrics.DummyMetrics{}
    79  	fakeFetcher := metric.NewFakeMetricsFetcher(emitter).(*metric.FakeMetricsFetcher)
    80  	tc := &testConf{}
    81  	rootfsPlugin := createRootfsPressureEvictionPlugin(tc, emitter, fakeFetcher)
    82  	res, err := rootfsPlugin.ThresholdMet(context.TODO())
    83  	assert.NoError(t, err)
    84  	assert.Equal(t, pluginapi.ThresholdMetType_NOT_MET, res.MetType)
    85  }
    86  
    87  func TestPodRootfsPressureEvictionPlugin_ThresholdMetNoMetricData(t *testing.T) {
    88  	t.Parallel()
    89  	emitter := metrics.DummyMetrics{}
    90  	fakeFetcher := metric.NewFakeMetricsFetcher(emitter).(*metric.FakeMetricsFetcher)
    91  	tc := &testConf{
    92  		minimumImageFsFreeThreshold:       &evictionapi.ThresholdValue{Percentage: 0.9},
    93  		minimumImageFsInodesFreeThreshold: &evictionapi.ThresholdValue{Percentage: 0.9},
    94  	}
    95  	rootfsPlugin := createRootfsPressureEvictionPlugin(tc, emitter, fakeFetcher)
    96  	res, err := rootfsPlugin.ThresholdMet(context.TODO())
    97  	assert.NoError(t, err)
    98  	assert.Equal(t, pluginapi.ThresholdMetType_NOT_MET, res.MetType)
    99  }
   100  
   101  func TestPodRootfsPressureEvictionPlugin_ThresholdMetNotMet(t *testing.T) {
   102  	t.Parallel()
   103  	emitter := metrics.DummyMetrics{}
   104  	fakeFetcher := metric.NewFakeMetricsFetcher(emitter).(*metric.FakeMetricsFetcher)
   105  	// create metric data without time.
   106  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsAvailable, utilmetric.MetricData{Value: 2000})
   107  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsUsed, utilmetric.MetricData{Value: 8000})
   108  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsCapacity, utilmetric.MetricData{Value: 10000})
   109  
   110  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsInodesFree, utilmetric.MetricData{Value: 2000})
   111  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsInodesUsed, utilmetric.MetricData{Value: 8000})
   112  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsInodes, utilmetric.MetricData{Value: 10000})
   113  
   114  	tc := &testConf{
   115  		minimumImageFsFreeThreshold:       &evictionapi.ThresholdValue{Percentage: 0.1},
   116  		minimumImageFsInodesFreeThreshold: &evictionapi.ThresholdValue{Percentage: 0.1},
   117  	}
   118  	rootfsPlugin := createRootfsPressureEvictionPlugin(tc, emitter, fakeFetcher)
   119  
   120  	res, err := rootfsPlugin.ThresholdMet(context.TODO())
   121  	assert.NoError(t, err)
   122  	assert.Equal(t, pluginapi.ThresholdMetType_NOT_MET, res.MetType)
   123  
   124  	tc = &testConf{
   125  		minimumImageFsFreeThreshold:       &evictionapi.ThresholdValue{Quantity: resource.NewQuantity(1000, resource.DecimalSI)},
   126  		minimumImageFsInodesFreeThreshold: &evictionapi.ThresholdValue{Quantity: resource.NewQuantity(1000, resource.DecimalSI)},
   127  	}
   128  	rootfsPlugin = createRootfsPressureEvictionPlugin(tc, emitter, fakeFetcher)
   129  	res, err = rootfsPlugin.ThresholdMet(context.TODO())
   130  	assert.NoError(t, err)
   131  	assert.Equal(t, pluginapi.ThresholdMetType_NOT_MET, res.MetType)
   132  }
   133  
   134  func TestPodRootfsPressureEvictionPlugin_ThresholdMetUsedMet(t *testing.T) {
   135  	t.Parallel()
   136  	emitter := metrics.DummyMetrics{}
   137  	fakeFetcher := metric.NewFakeMetricsFetcher(emitter).(*metric.FakeMetricsFetcher)
   138  	// create metric data without time.
   139  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsAvailable, utilmetric.MetricData{Value: 2000})
   140  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsUsed, utilmetric.MetricData{Value: 8000})
   141  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsCapacity, utilmetric.MetricData{Value: 10000})
   142  
   143  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsInodesFree, utilmetric.MetricData{Value: 2000})
   144  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsInodesUsed, utilmetric.MetricData{Value: 8000})
   145  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsInodes, utilmetric.MetricData{Value: 10000})
   146  
   147  	tc := &testConf{
   148  		minimumImageFsFreeThreshold:       &evictionapi.ThresholdValue{Percentage: 0.3},
   149  		minimumImageFsInodesFreeThreshold: &evictionapi.ThresholdValue{Percentage: 0.1},
   150  	}
   151  	rootfsPlugin := createRootfsPressureEvictionPlugin(tc, emitter, fakeFetcher)
   152  
   153  	res, err := rootfsPlugin.ThresholdMet(context.TODO())
   154  	assert.NoError(t, err)
   155  	assert.Equal(t, pluginapi.ThresholdMetType_HARD_MET, res.MetType)
   156  
   157  	tc = &testConf{
   158  		minimumImageFsFreeThreshold:       &evictionapi.ThresholdValue{Quantity: resource.NewQuantity(3000, resource.DecimalSI)},
   159  		minimumImageFsInodesFreeThreshold: &evictionapi.ThresholdValue{Quantity: resource.NewQuantity(1000, resource.DecimalSI)},
   160  	}
   161  	rootfsPlugin = createRootfsPressureEvictionPlugin(tc, emitter, fakeFetcher)
   162  	res, err = rootfsPlugin.ThresholdMet(context.TODO())
   163  	assert.NoError(t, err)
   164  	assert.Equal(t, pluginapi.ThresholdMetType_HARD_MET, res.MetType)
   165  }
   166  
   167  func TestPodRootfsPressureEvictionPlugin_ThresholdMetInodesMet(t *testing.T) {
   168  	t.Parallel()
   169  	emitter := metrics.DummyMetrics{}
   170  	fakeFetcher := metric.NewFakeMetricsFetcher(emitter).(*metric.FakeMetricsFetcher)
   171  	// create metric data without time.
   172  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsAvailable, utilmetric.MetricData{Value: 2000})
   173  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsUsed, utilmetric.MetricData{Value: 8000})
   174  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsCapacity, utilmetric.MetricData{Value: 10000})
   175  
   176  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsInodesFree, utilmetric.MetricData{Value: 2000})
   177  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsInodesUsed, utilmetric.MetricData{Value: 8000})
   178  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsInodes, utilmetric.MetricData{Value: 10000})
   179  
   180  	tc := &testConf{
   181  		minimumImageFsFreeThreshold:       &evictionapi.ThresholdValue{Percentage: 0.1},
   182  		minimumImageFsInodesFreeThreshold: &evictionapi.ThresholdValue{Percentage: 0.3},
   183  	}
   184  	rootfsPlugin := createRootfsPressureEvictionPlugin(tc, emitter, fakeFetcher)
   185  
   186  	res, err := rootfsPlugin.ThresholdMet(context.TODO())
   187  	assert.NoError(t, err)
   188  	assert.Equal(t, pluginapi.ThresholdMetType_HARD_MET, res.MetType)
   189  
   190  	tc = &testConf{
   191  		minimumImageFsFreeThreshold:       &evictionapi.ThresholdValue{Quantity: resource.NewQuantity(1000, resource.DecimalSI)},
   192  		minimumImageFsInodesFreeThreshold: &evictionapi.ThresholdValue{Quantity: resource.NewQuantity(3000, resource.DecimalSI)},
   193  	}
   194  	rootfsPlugin = createRootfsPressureEvictionPlugin(tc, emitter, fakeFetcher)
   195  	res, err = rootfsPlugin.ThresholdMet(context.TODO())
   196  	assert.NoError(t, err)
   197  	assert.Equal(t, pluginapi.ThresholdMetType_HARD_MET, res.MetType)
   198  }
   199  
   200  func TestPodRootfsPressureEvictionPlugin_ThresholdMet(t *testing.T) {
   201  	t.Parallel()
   202  	emitter := metrics.DummyMetrics{}
   203  	fakeFetcher := metric.NewFakeMetricsFetcher(emitter).(*metric.FakeMetricsFetcher)
   204  	// create metric data without time.
   205  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsAvailable, utilmetric.MetricData{Value: 2000})
   206  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsUsed, utilmetric.MetricData{Value: 8000})
   207  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsCapacity, utilmetric.MetricData{Value: 10000})
   208  
   209  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsInodesFree, utilmetric.MetricData{Value: 2000})
   210  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsInodesUsed, utilmetric.MetricData{Value: 8000})
   211  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsInodes, utilmetric.MetricData{Value: 10000})
   212  
   213  	tc := &testConf{
   214  		minimumImageFsFreeThreshold:       &evictionapi.ThresholdValue{Percentage: 0.3},
   215  		minimumImageFsInodesFreeThreshold: &evictionapi.ThresholdValue{Percentage: 0.3},
   216  	}
   217  	rootfsPlugin := createRootfsPressureEvictionPlugin(tc, emitter, fakeFetcher)
   218  
   219  	res, err := rootfsPlugin.ThresholdMet(context.TODO())
   220  	assert.NoError(t, err)
   221  	assert.Equal(t, pluginapi.ThresholdMetType_HARD_MET, res.MetType)
   222  
   223  	tc = &testConf{
   224  		minimumImageFsFreeThreshold:       &evictionapi.ThresholdValue{Quantity: resource.NewQuantity(3000, resource.DecimalSI)},
   225  		minimumImageFsInodesFreeThreshold: &evictionapi.ThresholdValue{Quantity: resource.NewQuantity(3000, resource.DecimalSI)},
   226  	}
   227  	rootfsPlugin = createRootfsPressureEvictionPlugin(tc, emitter, fakeFetcher)
   228  	res, err = rootfsPlugin.ThresholdMet(context.TODO())
   229  	assert.NoError(t, err)
   230  	assert.Equal(t, pluginapi.ThresholdMetType_HARD_MET, res.MetType)
   231  }
   232  
   233  func TestPodRootfsPressureEvictionPlugin_ThresholdMetMetricDataExpire(t *testing.T) {
   234  	t.Parallel()
   235  	metricTime := time.Now().Add(-65 * time.Second)
   236  
   237  	emitter := metrics.DummyMetrics{}
   238  	fakeFetcher := metric.NewFakeMetricsFetcher(emitter).(*metric.FakeMetricsFetcher)
   239  	// create metric data without time.
   240  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsAvailable, utilmetric.MetricData{Value: 2000, Time: &metricTime})
   241  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsUsed, utilmetric.MetricData{Value: 8000, Time: &metricTime})
   242  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsCapacity, utilmetric.MetricData{Value: 10000, Time: &metricTime})
   243  
   244  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsInodesFree, utilmetric.MetricData{Value: 2000, Time: &metricTime})
   245  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsInodesUsed, utilmetric.MetricData{Value: 8000, Time: &metricTime})
   246  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsInodes, utilmetric.MetricData{Value: 10000, Time: &metricTime})
   247  
   248  	tc := &testConf{
   249  		minimumImageFsFreeThreshold:       &evictionapi.ThresholdValue{Percentage: 0.7},
   250  		minimumImageFsInodesFreeThreshold: &evictionapi.ThresholdValue{Percentage: 0.7},
   251  	}
   252  	rootfsPlugin := createRootfsPressureEvictionPlugin(tc, emitter, fakeFetcher)
   253  
   254  	res, err := rootfsPlugin.ThresholdMet(context.TODO())
   255  	assert.NoError(t, err)
   256  	assert.Equal(t, pluginapi.ThresholdMetType_NOT_MET, res.MetType)
   257  
   258  	tc = &testConf{
   259  		minimumImageFsFreeThreshold:       &evictionapi.ThresholdValue{Quantity: resource.NewQuantity(7000, resource.DecimalSI)},
   260  		minimumImageFsInodesFreeThreshold: &evictionapi.ThresholdValue{Quantity: resource.NewQuantity(7000, resource.DecimalSI)},
   261  	}
   262  	rootfsPlugin = createRootfsPressureEvictionPlugin(tc, emitter, fakeFetcher)
   263  	res, err = rootfsPlugin.ThresholdMet(context.TODO())
   264  	assert.NoError(t, err)
   265  	assert.Equal(t, pluginapi.ThresholdMetType_NOT_MET, res.MetType)
   266  }
   267  
   268  func makeGetTopNRequest() *pluginapi.GetTopEvictionPodsRequest {
   269  	return &pluginapi.GetTopEvictionPodsRequest{
   270  		TopN: 1,
   271  		ActivePods: []*v1.Pod{
   272  			{
   273  				ObjectMeta: k8smetav1.ObjectMeta{UID: "podUID1"},
   274  				Spec: v1.PodSpec{
   275  					Containers: []v1.Container{
   276  						{
   277  							Name: "containerName",
   278  						},
   279  					},
   280  				},
   281  			},
   282  			{
   283  				ObjectMeta: k8smetav1.ObjectMeta{UID: "podUID2"},
   284  				Spec: v1.PodSpec{
   285  					Containers: []v1.Container{
   286  						{
   287  							Name: "containerName",
   288  						},
   289  					},
   290  				},
   291  			},
   292  		},
   293  	}
   294  }
   295  
   296  func TestPodRootfsPressureEvictionPlugin_GetTopEvictionPodsNotMet(t *testing.T) {
   297  	t.Parallel()
   298  	emitter := metrics.DummyMetrics{}
   299  	fakeFetcher := metric.NewFakeMetricsFetcher(emitter).(*metric.FakeMetricsFetcher)
   300  	// create metric data without time.
   301  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsAvailable, utilmetric.MetricData{Value: 2000})
   302  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsUsed, utilmetric.MetricData{Value: 8000})
   303  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsCapacity, utilmetric.MetricData{Value: 10000})
   304  
   305  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsInodesFree, utilmetric.MetricData{Value: 2000})
   306  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsInodesUsed, utilmetric.MetricData{Value: 8000})
   307  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsInodes, utilmetric.MetricData{Value: 10000})
   308  
   309  	tc := &testConf{
   310  		minimumImageFsFreeThreshold:       &evictionapi.ThresholdValue{Percentage: 0.1},
   311  		minimumImageFsInodesFreeThreshold: &evictionapi.ThresholdValue{Percentage: 0.1},
   312  	}
   313  	rootfsPlugin := createRootfsPressureEvictionPlugin(tc, emitter, fakeFetcher)
   314  
   315  	res, err := rootfsPlugin.ThresholdMet(context.TODO())
   316  	assert.NoError(t, err)
   317  	assert.Equal(t, pluginapi.ThresholdMetType_NOT_MET, res.MetType)
   318  
   319  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 800})
   320  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 800})
   321  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 799})
   322  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 799})
   323  
   324  	req := makeGetTopNRequest()
   325  	resTop, err := rootfsPlugin.GetTopEvictionPods(context.TODO(), req)
   326  	assert.NoError(t, err)
   327  	assert.Equal(t, 0, len(resTop.TargetPods))
   328  }
   329  
   330  func TestPodRootfsPressureEvictionPlugin_GetTopEvictionPodsMet(t *testing.T) {
   331  	t.Parallel()
   332  	emitter := metrics.DummyMetrics{}
   333  	fakeFetcher := metric.NewFakeMetricsFetcher(emitter).(*metric.FakeMetricsFetcher)
   334  	// create metric data without time.
   335  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsAvailable, utilmetric.MetricData{Value: 2000})
   336  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsUsed, utilmetric.MetricData{Value: 8000})
   337  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsCapacity, utilmetric.MetricData{Value: 10000})
   338  
   339  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsInodesFree, utilmetric.MetricData{Value: 2000})
   340  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsInodesUsed, utilmetric.MetricData{Value: 8000})
   341  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsInodes, utilmetric.MetricData{Value: 10000})
   342  
   343  	tc := &testConf{
   344  		minimumImageFsFreeThreshold:       &evictionapi.ThresholdValue{Percentage: 0.3},
   345  		minimumImageFsInodesFreeThreshold: &evictionapi.ThresholdValue{Percentage: 0.3},
   346  	}
   347  	rootfsPlugin := createRootfsPressureEvictionPlugin(tc, emitter, fakeFetcher)
   348  
   349  	res, err := rootfsPlugin.ThresholdMet(context.TODO())
   350  	assert.NoError(t, err)
   351  	assert.Equal(t, pluginapi.ThresholdMetType_HARD_MET, res.MetType)
   352  
   353  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 800})
   354  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 800})
   355  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 799})
   356  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 799})
   357  
   358  	req := makeGetTopNRequest()
   359  	resTop, err := rootfsPlugin.GetTopEvictionPods(context.TODO(), req)
   360  	assert.NoError(t, err)
   361  	assert.Equal(t, 1, len(resTop.TargetPods))
   362  	assert.Equal(t, types.UID("podUID1"), resTop.TargetPods[0].UID)
   363  
   364  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 801})
   365  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 801})
   366  	resTop, err = rootfsPlugin.GetTopEvictionPods(context.TODO(), req)
   367  	assert.NoError(t, err)
   368  	assert.Equal(t, 1, len(resTop.TargetPods))
   369  	assert.Equal(t, types.UID("podUID2"), resTop.TargetPods[0].UID)
   370  }
   371  
   372  func TestPodRootfsPressureEvictionPlugin_GetTopEvictionPodsUsedMet(t *testing.T) {
   373  	t.Parallel()
   374  	emitter := metrics.DummyMetrics{}
   375  	fakeFetcher := metric.NewFakeMetricsFetcher(emitter).(*metric.FakeMetricsFetcher)
   376  	// create metric data without time.
   377  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsAvailable, utilmetric.MetricData{Value: 2000})
   378  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsUsed, utilmetric.MetricData{Value: 8000})
   379  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsCapacity, utilmetric.MetricData{Value: 10000})
   380  
   381  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsInodesFree, utilmetric.MetricData{Value: 2000})
   382  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsInodesUsed, utilmetric.MetricData{Value: 8000})
   383  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsInodes, utilmetric.MetricData{Value: 10000})
   384  
   385  	tc := &testConf{
   386  		minimumImageFsFreeThreshold:       &evictionapi.ThresholdValue{Percentage: 0.3},
   387  		minimumImageFsInodesFreeThreshold: &evictionapi.ThresholdValue{Percentage: 0.1},
   388  	}
   389  	rootfsPlugin := createRootfsPressureEvictionPlugin(tc, emitter, fakeFetcher)
   390  
   391  	res, err := rootfsPlugin.ThresholdMet(context.TODO())
   392  	assert.NoError(t, err)
   393  	assert.Equal(t, pluginapi.ThresholdMetType_HARD_MET, res.MetType)
   394  
   395  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 800})
   396  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 799})
   397  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 799})
   398  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 800})
   399  
   400  	req := makeGetTopNRequest()
   401  	resTop, err := rootfsPlugin.GetTopEvictionPods(context.TODO(), req)
   402  	assert.NoError(t, err)
   403  	assert.Equal(t, 1, len(resTop.TargetPods))
   404  	assert.Equal(t, types.UID("podUID1"), resTop.TargetPods[0].UID)
   405  
   406  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 801})
   407  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 699})
   408  	resTop, err = rootfsPlugin.GetTopEvictionPods(context.TODO(), req)
   409  	assert.NoError(t, err)
   410  	assert.Equal(t, 1, len(resTop.TargetPods))
   411  	assert.Equal(t, types.UID("podUID2"), resTop.TargetPods[0].UID)
   412  }
   413  
   414  func TestPodRootfsPressureEvictionPlugin_GetTopEvictionPodsInodesMet(t *testing.T) {
   415  	t.Parallel()
   416  	emitter := metrics.DummyMetrics{}
   417  	fakeFetcher := metric.NewFakeMetricsFetcher(emitter).(*metric.FakeMetricsFetcher)
   418  	// create metric data without time.
   419  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsAvailable, utilmetric.MetricData{Value: 2000})
   420  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsUsed, utilmetric.MetricData{Value: 8000})
   421  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsCapacity, utilmetric.MetricData{Value: 10000})
   422  
   423  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsInodesFree, utilmetric.MetricData{Value: 2000})
   424  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsInodesUsed, utilmetric.MetricData{Value: 8000})
   425  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsInodes, utilmetric.MetricData{Value: 10000})
   426  
   427  	tc := &testConf{
   428  		minimumImageFsFreeThreshold:       &evictionapi.ThresholdValue{Percentage: 0.1},
   429  		minimumImageFsInodesFreeThreshold: &evictionapi.ThresholdValue{Percentage: 0.3},
   430  	}
   431  	rootfsPlugin := createRootfsPressureEvictionPlugin(tc, emitter, fakeFetcher)
   432  
   433  	res, err := rootfsPlugin.ThresholdMet(context.TODO())
   434  	assert.NoError(t, err)
   435  	assert.Equal(t, pluginapi.ThresholdMetType_HARD_MET, res.MetType)
   436  
   437  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 799})
   438  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 800})
   439  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 800})
   440  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 799})
   441  
   442  	req := makeGetTopNRequest()
   443  	resTop, err := rootfsPlugin.GetTopEvictionPods(context.TODO(), req)
   444  	assert.NoError(t, err)
   445  	assert.Equal(t, 1, len(resTop.TargetPods))
   446  	assert.Equal(t, types.UID("podUID1"), resTop.TargetPods[0].UID)
   447  
   448  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 699})
   449  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 801})
   450  	resTop, err = rootfsPlugin.GetTopEvictionPods(context.TODO(), req)
   451  	assert.NoError(t, err)
   452  	assert.Equal(t, 1, len(resTop.TargetPods))
   453  	assert.Equal(t, types.UID("podUID2"), resTop.TargetPods[0].UID)
   454  }
   455  
   456  func TestPodRootfsPressureEvictionPlugin_GetTopEvictionPodsUsedMetProtection(t *testing.T) {
   457  	t.Parallel()
   458  	emitter := metrics.DummyMetrics{}
   459  	fakeFetcher := metric.NewFakeMetricsFetcher(emitter).(*metric.FakeMetricsFetcher)
   460  	// create metric data without time.
   461  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsAvailable, utilmetric.MetricData{Value: 2000})
   462  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsUsed, utilmetric.MetricData{Value: 8000})
   463  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsCapacity, utilmetric.MetricData{Value: 10000})
   464  
   465  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsInodesFree, utilmetric.MetricData{Value: 2000})
   466  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsInodesUsed, utilmetric.MetricData{Value: 8000})
   467  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsInodes, utilmetric.MetricData{Value: 10000})
   468  
   469  	tc := &testConf{
   470  		minimumImageFsFreeThreshold:       &evictionapi.ThresholdValue{Percentage: 0.3},
   471  		minimumImageFsInodesFreeThreshold: &evictionapi.ThresholdValue{Percentage: 0.1},
   472  		podMinimumUsedThreshold:           &evictionapi.ThresholdValue{Quantity: resource.NewQuantity(900, resource.DecimalSI)},
   473  	}
   474  	rootfsPlugin := createRootfsPressureEvictionPlugin(tc, emitter, fakeFetcher)
   475  
   476  	res, err := rootfsPlugin.ThresholdMet(context.TODO())
   477  	assert.NoError(t, err)
   478  	assert.Equal(t, pluginapi.ThresholdMetType_HARD_MET, res.MetType)
   479  
   480  	req := makeGetTopNRequest()
   481  
   482  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 800})
   483  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 799})
   484  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 799})
   485  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 800})
   486  	resTop, err := rootfsPlugin.GetTopEvictionPods(context.TODO(), req)
   487  	assert.NoError(t, err)
   488  	assert.Equal(t, 0, len(resTop.TargetPods))
   489  
   490  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 1000})
   491  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 1000})
   492  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 800})
   493  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 800})
   494  	resTop, err = rootfsPlugin.GetTopEvictionPods(context.TODO(), req)
   495  	assert.NoError(t, err)
   496  	assert.Equal(t, 1, len(resTop.TargetPods))
   497  	assert.Equal(t, types.UID("podUID1"), resTop.TargetPods[0].UID)
   498  
   499  	tc = &testConf{
   500  		minimumImageFsFreeThreshold:       &evictionapi.ThresholdValue{Percentage: 0.3},
   501  		minimumImageFsInodesFreeThreshold: &evictionapi.ThresholdValue{Percentage: 0.1},
   502  		podMinimumUsedThreshold:           &evictionapi.ThresholdValue{Percentage: 0.1},
   503  	}
   504  	rootfsPlugin = createRootfsPressureEvictionPlugin(tc, emitter, fakeFetcher)
   505  	res, err = rootfsPlugin.ThresholdMet(context.TODO())
   506  	assert.NoError(t, err)
   507  	assert.Equal(t, pluginapi.ThresholdMetType_HARD_MET, res.MetType)
   508  
   509  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 800})
   510  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 799})
   511  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 799})
   512  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 800})
   513  	resTop, err = rootfsPlugin.GetTopEvictionPods(context.TODO(), req)
   514  	assert.NoError(t, err)
   515  	assert.Equal(t, 0, len(resTop.TargetPods))
   516  
   517  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 1100})
   518  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 799})
   519  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 799})
   520  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 1100})
   521  	resTop, err = rootfsPlugin.GetTopEvictionPods(context.TODO(), req)
   522  	assert.NoError(t, err)
   523  	assert.Equal(t, 1, len(resTop.TargetPods))
   524  	assert.Equal(t, types.UID("podUID1"), resTop.TargetPods[0].UID)
   525  
   526  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 1100})
   527  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 799})
   528  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 1200})
   529  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 1100})
   530  	resTop, err = rootfsPlugin.GetTopEvictionPods(context.TODO(), req)
   531  	assert.NoError(t, err)
   532  	assert.Equal(t, 1, len(resTop.TargetPods))
   533  	assert.Equal(t, types.UID("podUID2"), resTop.TargetPods[0].UID)
   534  
   535  	tc = &testConf{
   536  		minimumImageFsFreeThreshold:       &evictionapi.ThresholdValue{Percentage: 0.3},
   537  		minimumImageFsInodesFreeThreshold: &evictionapi.ThresholdValue{Percentage: 0.1},
   538  	}
   539  	rootfsPlugin = createRootfsPressureEvictionPlugin(tc, emitter, fakeFetcher)
   540  	res, err = rootfsPlugin.ThresholdMet(context.TODO())
   541  	assert.NoError(t, err)
   542  	assert.Equal(t, pluginapi.ThresholdMetType_HARD_MET, res.MetType)
   543  
   544  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 2})
   545  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 799})
   546  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 1})
   547  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 800})
   548  	resTop, err = rootfsPlugin.GetTopEvictionPods(context.TODO(), req)
   549  	assert.NoError(t, err)
   550  	assert.Equal(t, 1, len(resTop.TargetPods))
   551  	assert.Equal(t, types.UID("podUID1"), resTop.TargetPods[0].UID)
   552  
   553  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 1})
   554  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 799})
   555  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 2})
   556  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 800})
   557  	resTop, err = rootfsPlugin.GetTopEvictionPods(context.TODO(), req)
   558  	assert.NoError(t, err)
   559  	assert.Equal(t, 1, len(resTop.TargetPods))
   560  	assert.Equal(t, types.UID("podUID2"), resTop.TargetPods[0].UID)
   561  }
   562  
   563  func TestPodRootfsPressureEvictionPlugin_GetTopEvictionPodsInodesMetProtection(t *testing.T) {
   564  	t.Parallel()
   565  	emitter := metrics.DummyMetrics{}
   566  	fakeFetcher := metric.NewFakeMetricsFetcher(emitter).(*metric.FakeMetricsFetcher)
   567  	// create metric data without time.
   568  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsAvailable, utilmetric.MetricData{Value: 2000})
   569  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsUsed, utilmetric.MetricData{Value: 8000})
   570  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsCapacity, utilmetric.MetricData{Value: 10000})
   571  
   572  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsInodesFree, utilmetric.MetricData{Value: 2000})
   573  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsInodesUsed, utilmetric.MetricData{Value: 8000})
   574  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsInodes, utilmetric.MetricData{Value: 10000})
   575  
   576  	tc := &testConf{
   577  		minimumImageFsFreeThreshold:       &evictionapi.ThresholdValue{Percentage: 0.1},
   578  		minimumImageFsInodesFreeThreshold: &evictionapi.ThresholdValue{Percentage: 0.3},
   579  		podMinimumInodesUsedThreshold:     &evictionapi.ThresholdValue{Quantity: resource.NewQuantity(900, resource.DecimalSI)},
   580  	}
   581  	rootfsPlugin := createRootfsPressureEvictionPlugin(tc, emitter, fakeFetcher)
   582  	res, err := rootfsPlugin.ThresholdMet(context.TODO())
   583  	assert.NoError(t, err)
   584  	assert.Equal(t, pluginapi.ThresholdMetType_HARD_MET, res.MetType)
   585  
   586  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 799})
   587  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 800})
   588  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 800})
   589  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 799})
   590  	req := makeGetTopNRequest()
   591  	resTop, err := rootfsPlugin.GetTopEvictionPods(context.TODO(), req)
   592  	assert.NoError(t, err)
   593  	assert.Equal(t, 0, len(resTop.TargetPods))
   594  
   595  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 800})
   596  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 1000})
   597  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 1000})
   598  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 800})
   599  	resTop, err = rootfsPlugin.GetTopEvictionPods(context.TODO(), req)
   600  	assert.NoError(t, err)
   601  	assert.Equal(t, 1, len(resTop.TargetPods))
   602  	assert.Equal(t, types.UID("podUID1"), resTop.TargetPods[0].UID)
   603  
   604  	tc = &testConf{
   605  		minimumImageFsFreeThreshold:       &evictionapi.ThresholdValue{Percentage: 0.1},
   606  		minimumImageFsInodesFreeThreshold: &evictionapi.ThresholdValue{Percentage: 0.3},
   607  		podMinimumInodesUsedThreshold:     &evictionapi.ThresholdValue{Percentage: 0.1},
   608  	}
   609  	rootfsPlugin = createRootfsPressureEvictionPlugin(tc, emitter, fakeFetcher)
   610  	res, err = rootfsPlugin.ThresholdMet(context.TODO())
   611  	assert.NoError(t, err)
   612  	assert.Equal(t, pluginapi.ThresholdMetType_HARD_MET, res.MetType)
   613  
   614  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 799})
   615  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 800})
   616  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 800})
   617  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 799})
   618  	resTop, err = rootfsPlugin.GetTopEvictionPods(context.TODO(), req)
   619  	assert.NoError(t, err)
   620  	assert.Equal(t, 0, len(resTop.TargetPods))
   621  
   622  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 799})
   623  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 1100})
   624  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 800})
   625  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 799})
   626  	resTop, err = rootfsPlugin.GetTopEvictionPods(context.TODO(), req)
   627  	assert.NoError(t, err)
   628  	assert.Equal(t, 1, len(resTop.TargetPods))
   629  	assert.Equal(t, types.UID("podUID1"), resTop.TargetPods[0].UID)
   630  
   631  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 799})
   632  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 1100})
   633  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 800})
   634  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 1200})
   635  	resTop, err = rootfsPlugin.GetTopEvictionPods(context.TODO(), req)
   636  	assert.NoError(t, err)
   637  	assert.Equal(t, 1, len(resTop.TargetPods))
   638  	assert.Equal(t, types.UID("podUID2"), resTop.TargetPods[0].UID)
   639  
   640  	tc = &testConf{
   641  		minimumImageFsFreeThreshold:       &evictionapi.ThresholdValue{Percentage: 0.1},
   642  		minimumImageFsInodesFreeThreshold: &evictionapi.ThresholdValue{Percentage: 0.3},
   643  	}
   644  	rootfsPlugin = createRootfsPressureEvictionPlugin(tc, emitter, fakeFetcher)
   645  	res, err = rootfsPlugin.ThresholdMet(context.TODO())
   646  	assert.NoError(t, err)
   647  	assert.Equal(t, pluginapi.ThresholdMetType_HARD_MET, res.MetType)
   648  
   649  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 799})
   650  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 2})
   651  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 800})
   652  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 1})
   653  	resTop, err = rootfsPlugin.GetTopEvictionPods(context.TODO(), req)
   654  	assert.NoError(t, err)
   655  	assert.Equal(t, 1, len(resTop.TargetPods))
   656  	assert.Equal(t, types.UID("podUID1"), resTop.TargetPods[0].UID)
   657  
   658  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 799})
   659  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 2})
   660  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 800})
   661  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 3})
   662  	resTop, err = rootfsPlugin.GetTopEvictionPods(context.TODO(), req)
   663  	assert.NoError(t, err)
   664  	assert.Equal(t, 1, len(resTop.TargetPods))
   665  	assert.Equal(t, types.UID("podUID2"), resTop.TargetPods[0].UID)
   666  }
   667  
   668  func TestPodRootfsPressureEvictionPlugin_GetTopEvictionPodsMetReclaimedPriority(t *testing.T) {
   669  	t.Parallel()
   670  	emitter := metrics.DummyMetrics{}
   671  	fakeFetcher := metric.NewFakeMetricsFetcher(emitter).(*metric.FakeMetricsFetcher)
   672  	// create metric data without time.
   673  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsAvailable, utilmetric.MetricData{Value: 2000})
   674  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsUsed, utilmetric.MetricData{Value: 8000})
   675  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsCapacity, utilmetric.MetricData{Value: 10000})
   676  
   677  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsInodesFree, utilmetric.MetricData{Value: 2000})
   678  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsInodesUsed, utilmetric.MetricData{Value: 8000})
   679  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsInodes, utilmetric.MetricData{Value: 10000})
   680  
   681  	tc := &testConf{
   682  		minimumImageFsFreeThreshold:          &evictionapi.ThresholdValue{Percentage: 0.3},
   683  		minimumImageFsInodesFreeThreshold:    &evictionapi.ThresholdValue{Percentage: 0.3},
   684  		reclaimedQoSPodUsedPriorityThreshold: &evictionapi.ThresholdValue{Quantity: resource.NewQuantity(500, resource.DecimalSI)},
   685  	}
   686  	rootfsPlugin := createRootfsPressureEvictionPlugin(tc, emitter, fakeFetcher)
   687  
   688  	res, err := rootfsPlugin.ThresholdMet(context.TODO())
   689  	assert.NoError(t, err)
   690  	assert.Equal(t, pluginapi.ThresholdMetType_HARD_MET, res.MetType)
   691  
   692  	req := makeGetTopNRequest()
   693  	req.ActivePods[0].Annotations = map[string]string{}
   694  	req.ActivePods[1].Annotations = map[string]string{"katalyst.kubewharf.io/qos_level": "reclaimed_cores"}
   695  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 800})
   696  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 800})
   697  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 799})
   698  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 799})
   699  	resTop, err := rootfsPlugin.GetTopEvictionPods(context.TODO(), req)
   700  	assert.NoError(t, err)
   701  	assert.Equal(t, 1, len(resTop.TargetPods))
   702  	assert.Equal(t, types.UID("podUID2"), resTop.TargetPods[0].UID)
   703  
   704  	req.ActivePods[0].Annotations = map[string]string{}
   705  	req.ActivePods[1].Annotations = map[string]string{"katalyst.kubewharf.io/qos_level": "reclaimed_cores"}
   706  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 800})
   707  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 800})
   708  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 400})
   709  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 400})
   710  	resTop, err = rootfsPlugin.GetTopEvictionPods(context.TODO(), req)
   711  	assert.NoError(t, err)
   712  	assert.Equal(t, 1, len(resTop.TargetPods))
   713  	assert.Equal(t, types.UID("podUID1"), resTop.TargetPods[0].UID)
   714  
   715  	req.ActivePods[0].Annotations = map[string]string{"katalyst.kubewharf.io/qos_level": "reclaimed_cores"}
   716  	req.ActivePods[1].Annotations = map[string]string{}
   717  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 800})
   718  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 800})
   719  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 801})
   720  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 801})
   721  	resTop, err = rootfsPlugin.GetTopEvictionPods(context.TODO(), req)
   722  	assert.NoError(t, err)
   723  	assert.Equal(t, 1, len(resTop.TargetPods))
   724  	assert.Equal(t, types.UID("podUID1"), resTop.TargetPods[0].UID)
   725  
   726  	req.ActivePods[0].Annotations = map[string]string{"katalyst.kubewharf.io/qos_level": "reclaimed_cores"}
   727  	req.ActivePods[1].Annotations = map[string]string{}
   728  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 400})
   729  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 400})
   730  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 801})
   731  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 801})
   732  	resTop, err = rootfsPlugin.GetTopEvictionPods(context.TODO(), req)
   733  	assert.NoError(t, err)
   734  	assert.Equal(t, 1, len(resTop.TargetPods))
   735  	assert.Equal(t, types.UID("podUID2"), resTop.TargetPods[0].UID)
   736  
   737  	tc = &testConf{
   738  		minimumImageFsFreeThreshold:          &evictionapi.ThresholdValue{Percentage: 0.3},
   739  		minimumImageFsInodesFreeThreshold:    &evictionapi.ThresholdValue{Percentage: 0.3},
   740  		reclaimedQoSPodUsedPriorityThreshold: &evictionapi.ThresholdValue{Percentage: 0.1},
   741  	}
   742  	rootfsPlugin = createRootfsPressureEvictionPlugin(tc, emitter, fakeFetcher)
   743  
   744  	res, err = rootfsPlugin.ThresholdMet(context.TODO())
   745  	assert.NoError(t, err)
   746  	assert.Equal(t, pluginapi.ThresholdMetType_HARD_MET, res.MetType)
   747  
   748  	req.ActivePods[0].Annotations = map[string]string{}
   749  	req.ActivePods[1].Annotations = map[string]string{"katalyst.kubewharf.io/qos_level": "reclaimed_cores"}
   750  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 1200})
   751  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 1200})
   752  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 1100})
   753  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 1100})
   754  	resTop, err = rootfsPlugin.GetTopEvictionPods(context.TODO(), req)
   755  	assert.NoError(t, err)
   756  	assert.Equal(t, 1, len(resTop.TargetPods))
   757  	assert.Equal(t, types.UID("podUID2"), resTop.TargetPods[0].UID)
   758  
   759  	req.ActivePods[0].Annotations = map[string]string{}
   760  	req.ActivePods[1].Annotations = map[string]string{"katalyst.kubewharf.io/qos_level": "reclaimed_cores"}
   761  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 1200})
   762  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 1200})
   763  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 900})
   764  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 900})
   765  	resTop, err = rootfsPlugin.GetTopEvictionPods(context.TODO(), req)
   766  	assert.NoError(t, err)
   767  	assert.Equal(t, 1, len(resTop.TargetPods))
   768  	assert.Equal(t, types.UID("podUID1"), resTop.TargetPods[0].UID)
   769  
   770  	req.ActivePods[0].Annotations = map[string]string{"katalyst.kubewharf.io/qos_level": "reclaimed_cores"}
   771  	req.ActivePods[1].Annotations = map[string]string{}
   772  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 1200})
   773  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 1200})
   774  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 1300})
   775  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 1300})
   776  	resTop, err = rootfsPlugin.GetTopEvictionPods(context.TODO(), req)
   777  	assert.NoError(t, err)
   778  	assert.Equal(t, 1, len(resTop.TargetPods))
   779  	assert.Equal(t, types.UID("podUID1"), resTop.TargetPods[0].UID)
   780  
   781  	req.ActivePods[0].Annotations = map[string]string{"katalyst.kubewharf.io/qos_level": "reclaimed_cores"}
   782  	req.ActivePods[1].Annotations = map[string]string{}
   783  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 900})
   784  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 900})
   785  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 1300})
   786  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 1300})
   787  	resTop, err = rootfsPlugin.GetTopEvictionPods(context.TODO(), req)
   788  	assert.NoError(t, err)
   789  	assert.Equal(t, 1, len(resTop.TargetPods))
   790  	assert.Equal(t, types.UID("podUID2"), resTop.TargetPods[0].UID)
   791  
   792  	tc = &testConf{
   793  		minimumImageFsFreeThreshold:       &evictionapi.ThresholdValue{Percentage: 0.3},
   794  		minimumImageFsInodesFreeThreshold: &evictionapi.ThresholdValue{Percentage: 0.3},
   795  	}
   796  	rootfsPlugin = createRootfsPressureEvictionPlugin(tc, emitter, fakeFetcher)
   797  
   798  	res, err = rootfsPlugin.ThresholdMet(context.TODO())
   799  	assert.NoError(t, err)
   800  	assert.Equal(t, pluginapi.ThresholdMetType_HARD_MET, res.MetType)
   801  
   802  	req.ActivePods[0].Annotations = map[string]string{}
   803  	req.ActivePods[1].Annotations = map[string]string{"katalyst.kubewharf.io/qos_level": "reclaimed_cores"}
   804  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 1200})
   805  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 1200})
   806  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 1100})
   807  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 1100})
   808  	resTop, err = rootfsPlugin.GetTopEvictionPods(context.TODO(), req)
   809  	assert.NoError(t, err)
   810  	assert.Equal(t, 1, len(resTop.TargetPods))
   811  	assert.Equal(t, types.UID("podUID1"), resTop.TargetPods[0].UID)
   812  
   813  	req.ActivePods[0].Annotations = map[string]string{"katalyst.kubewharf.io/qos_level": "reclaimed_cores"}
   814  	req.ActivePods[1].Annotations = map[string]string{}
   815  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 1200})
   816  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 1200})
   817  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 1300})
   818  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 1300})
   819  	resTop, err = rootfsPlugin.GetTopEvictionPods(context.TODO(), req)
   820  	assert.NoError(t, err)
   821  	assert.Equal(t, 1, len(resTop.TargetPods))
   822  	assert.Equal(t, types.UID("podUID2"), resTop.TargetPods[0].UID)
   823  }
   824  
   825  func TestPodRootfsPressureEvictionPlugin_GetTopEvictionPodsInodesMetReclaimedPriority(t *testing.T) {
   826  	t.Parallel()
   827  	emitter := metrics.DummyMetrics{}
   828  	fakeFetcher := metric.NewFakeMetricsFetcher(emitter).(*metric.FakeMetricsFetcher)
   829  	// create metric data without time.
   830  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsAvailable, utilmetric.MetricData{Value: 2000})
   831  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsUsed, utilmetric.MetricData{Value: 8000})
   832  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsCapacity, utilmetric.MetricData{Value: 10000})
   833  
   834  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsInodesFree, utilmetric.MetricData{Value: 2000})
   835  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsInodesUsed, utilmetric.MetricData{Value: 8000})
   836  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsInodes, utilmetric.MetricData{Value: 10000})
   837  
   838  	tc := &testConf{
   839  		minimumImageFsFreeThreshold:                &evictionapi.ThresholdValue{Percentage: 0.1},
   840  		minimumImageFsInodesFreeThreshold:          &evictionapi.ThresholdValue{Percentage: 0.3},
   841  		reclaimedQosPodInodesUsedPriorityThreshold: &evictionapi.ThresholdValue{Quantity: resource.NewQuantity(500, resource.DecimalSI)},
   842  	}
   843  	rootfsPlugin := createRootfsPressureEvictionPlugin(tc, emitter, fakeFetcher)
   844  
   845  	res, err := rootfsPlugin.ThresholdMet(context.TODO())
   846  	assert.NoError(t, err)
   847  	assert.Equal(t, pluginapi.ThresholdMetType_HARD_MET, res.MetType)
   848  
   849  	req := makeGetTopNRequest()
   850  	req.ActivePods[0].Annotations = map[string]string{}
   851  	req.ActivePods[1].Annotations = map[string]string{"katalyst.kubewharf.io/qos_level": "reclaimed_cores"}
   852  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 800})
   853  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 800})
   854  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 900})
   855  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 700})
   856  	resTop, err := rootfsPlugin.GetTopEvictionPods(context.TODO(), req)
   857  	assert.NoError(t, err)
   858  	assert.Equal(t, 1, len(resTop.TargetPods))
   859  	assert.Equal(t, types.UID("podUID2"), resTop.TargetPods[0].UID)
   860  
   861  	req.ActivePods[0].Annotations = map[string]string{}
   862  	req.ActivePods[1].Annotations = map[string]string{"katalyst.kubewharf.io/qos_level": "reclaimed_cores"}
   863  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 300})
   864  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 800})
   865  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 500})
   866  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 400})
   867  	resTop, err = rootfsPlugin.GetTopEvictionPods(context.TODO(), req)
   868  	assert.NoError(t, err)
   869  	assert.Equal(t, 1, len(resTop.TargetPods))
   870  	assert.Equal(t, types.UID("podUID1"), resTop.TargetPods[0].UID)
   871  
   872  	req.ActivePods[0].Annotations = map[string]string{"katalyst.kubewharf.io/qos_level": "reclaimed_cores"}
   873  	req.ActivePods[1].Annotations = map[string]string{}
   874  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 800})
   875  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 800})
   876  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 900})
   877  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 900})
   878  	resTop, err = rootfsPlugin.GetTopEvictionPods(context.TODO(), req)
   879  	assert.NoError(t, err)
   880  	assert.Equal(t, 1, len(resTop.TargetPods))
   881  	assert.Equal(t, types.UID("podUID1"), resTop.TargetPods[0].UID)
   882  
   883  	req.ActivePods[0].Annotations = map[string]string{"katalyst.kubewharf.io/qos_level": "reclaimed_cores"}
   884  	req.ActivePods[1].Annotations = map[string]string{}
   885  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 900})
   886  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 400})
   887  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 400})
   888  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 900})
   889  	resTop, err = rootfsPlugin.GetTopEvictionPods(context.TODO(), req)
   890  	assert.NoError(t, err)
   891  	assert.Equal(t, 1, len(resTop.TargetPods))
   892  	assert.Equal(t, types.UID("podUID2"), resTop.TargetPods[0].UID)
   893  
   894  	tc = &testConf{
   895  		minimumImageFsFreeThreshold:                &evictionapi.ThresholdValue{Percentage: 0.1},
   896  		minimumImageFsInodesFreeThreshold:          &evictionapi.ThresholdValue{Percentage: 0.3},
   897  		reclaimedQosPodInodesUsedPriorityThreshold: &evictionapi.ThresholdValue{Percentage: 0.1},
   898  	}
   899  	rootfsPlugin = createRootfsPressureEvictionPlugin(tc, emitter, fakeFetcher)
   900  
   901  	res, err = rootfsPlugin.ThresholdMet(context.TODO())
   902  	assert.NoError(t, err)
   903  	assert.Equal(t, pluginapi.ThresholdMetType_HARD_MET, res.MetType)
   904  
   905  	req.ActivePods[0].Annotations = map[string]string{}
   906  	req.ActivePods[1].Annotations = map[string]string{"katalyst.kubewharf.io/qos_level": "reclaimed_cores"}
   907  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 800})
   908  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 1200})
   909  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 900})
   910  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 1100})
   911  	resTop, err = rootfsPlugin.GetTopEvictionPods(context.TODO(), req)
   912  	assert.NoError(t, err)
   913  	assert.Equal(t, 1, len(resTop.TargetPods))
   914  	assert.Equal(t, types.UID("podUID2"), resTop.TargetPods[0].UID)
   915  
   916  	req.ActivePods[0].Annotations = map[string]string{}
   917  	req.ActivePods[1].Annotations = map[string]string{"katalyst.kubewharf.io/qos_level": "reclaimed_cores"}
   918  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 800})
   919  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 1200})
   920  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 900})
   921  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 900})
   922  	resTop, err = rootfsPlugin.GetTopEvictionPods(context.TODO(), req)
   923  	assert.NoError(t, err)
   924  	assert.Equal(t, 1, len(resTop.TargetPods))
   925  	assert.Equal(t, types.UID("podUID1"), resTop.TargetPods[0].UID)
   926  
   927  	req.ActivePods[0].Annotations = map[string]string{"katalyst.kubewharf.io/qos_level": "reclaimed_cores"}
   928  	req.ActivePods[1].Annotations = map[string]string{}
   929  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 1500})
   930  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 1200})
   931  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 1300})
   932  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 1300})
   933  	resTop, err = rootfsPlugin.GetTopEvictionPods(context.TODO(), req)
   934  	assert.NoError(t, err)
   935  	assert.Equal(t, 1, len(resTop.TargetPods))
   936  	assert.Equal(t, types.UID("podUID1"), resTop.TargetPods[0].UID)
   937  
   938  	req.ActivePods[0].Annotations = map[string]string{"katalyst.kubewharf.io/qos_level": "reclaimed_cores"}
   939  	req.ActivePods[1].Annotations = map[string]string{}
   940  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 1500})
   941  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 900})
   942  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 1300})
   943  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 1300})
   944  	resTop, err = rootfsPlugin.GetTopEvictionPods(context.TODO(), req)
   945  	assert.NoError(t, err)
   946  	assert.Equal(t, 1, len(resTop.TargetPods))
   947  	assert.Equal(t, types.UID("podUID2"), resTop.TargetPods[0].UID)
   948  
   949  	tc = &testConf{
   950  		minimumImageFsFreeThreshold:       &evictionapi.ThresholdValue{Percentage: 0.1},
   951  		minimumImageFsInodesFreeThreshold: &evictionapi.ThresholdValue{Percentage: 0.3},
   952  	}
   953  	rootfsPlugin = createRootfsPressureEvictionPlugin(tc, emitter, fakeFetcher)
   954  
   955  	res, err = rootfsPlugin.ThresholdMet(context.TODO())
   956  	assert.NoError(t, err)
   957  	assert.Equal(t, pluginapi.ThresholdMetType_HARD_MET, res.MetType)
   958  
   959  	req.ActivePods[0].Annotations = map[string]string{}
   960  	req.ActivePods[1].Annotations = map[string]string{"katalyst.kubewharf.io/qos_level": "reclaimed_cores"}
   961  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 1000})
   962  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 2})
   963  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 1100})
   964  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 1})
   965  	resTop, err = rootfsPlugin.GetTopEvictionPods(context.TODO(), req)
   966  	assert.NoError(t, err)
   967  	assert.Equal(t, 1, len(resTop.TargetPods))
   968  	assert.Equal(t, types.UID("podUID1"), resTop.TargetPods[0].UID)
   969  
   970  	req.ActivePods[0].Annotations = map[string]string{"katalyst.kubewharf.io/qos_level": "reclaimed_cores"}
   971  	req.ActivePods[1].Annotations = map[string]string{}
   972  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 1200})
   973  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 1})
   974  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 1000})
   975  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 2})
   976  	resTop, err = rootfsPlugin.GetTopEvictionPods(context.TODO(), req)
   977  	assert.NoError(t, err)
   978  	assert.Equal(t, 1, len(resTop.TargetPods))
   979  	assert.Equal(t, types.UID("podUID2"), resTop.TargetPods[0].UID)
   980  }
   981  
   982  func TestPodRootfsPressureEvictionPlugin_GetTopEvictionPodsMetExpire(t *testing.T) {
   983  	t.Parallel()
   984  	metricTime := time.Now().Add(-65 * time.Second)
   985  
   986  	emitter := metrics.DummyMetrics{}
   987  	fakeFetcher := metric.NewFakeMetricsFetcher(emitter).(*metric.FakeMetricsFetcher)
   988  	// create metric data without time.
   989  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsAvailable, utilmetric.MetricData{Value: 2000})
   990  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsUsed, utilmetric.MetricData{Value: 8000})
   991  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsCapacity, utilmetric.MetricData{Value: 10000})
   992  
   993  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsInodesFree, utilmetric.MetricData{Value: 2000})
   994  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsInodesUsed, utilmetric.MetricData{Value: 8000})
   995  	fakeFetcher.SetNodeMetric(consts.MetricsImageFsInodes, utilmetric.MetricData{Value: 10000})
   996  
   997  	tc := &testConf{
   998  		minimumImageFsFreeThreshold:       &evictionapi.ThresholdValue{Percentage: 0.3},
   999  		minimumImageFsInodesFreeThreshold: &evictionapi.ThresholdValue{Percentage: 0.3},
  1000  	}
  1001  	rootfsPlugin := createRootfsPressureEvictionPlugin(tc, emitter, fakeFetcher)
  1002  
  1003  	res, err := rootfsPlugin.ThresholdMet(context.TODO())
  1004  	assert.NoError(t, err)
  1005  	assert.Equal(t, pluginapi.ThresholdMetType_HARD_MET, res.MetType)
  1006  
  1007  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 800, Time: &metricTime})
  1008  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 800, Time: &metricTime})
  1009  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 799})
  1010  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 799})
  1011  
  1012  	req := makeGetTopNRequest()
  1013  	resTop, err := rootfsPlugin.GetTopEvictionPods(context.TODO(), req)
  1014  	assert.NoError(t, err)
  1015  	assert.Equal(t, 1, len(resTop.TargetPods))
  1016  	assert.Equal(t, types.UID("podUID2"), resTop.TargetPods[0].UID)
  1017  
  1018  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 800, Time: &metricTime})
  1019  	fakeFetcher.SetContainerMetric("podUID1", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 800, Time: &metricTime})
  1020  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsUsed, utilmetric.MetricData{Value: 799, Time: &metricTime})
  1021  	fakeFetcher.SetContainerMetric("podUID2", "containerName", consts.MetricsContainerRootfsInodesUsed, utilmetric.MetricData{Value: 799, Time: &metricTime})
  1022  	resTop, err = rootfsPlugin.GetTopEvictionPods(context.TODO(), req)
  1023  	assert.NoError(t, err)
  1024  	assert.Equal(t, 0, len(resTop.TargetPods))
  1025  }