github.com/kubewharf/katalyst-core@v0.5.3/pkg/metaserver/agent/metric/provisioner/rodan/provisioner_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 rodan
    18  
    19  import (
    20  	"context"
    21  	"fmt"
    22  	"testing"
    23  
    24  	"github.com/stretchr/testify/require"
    25  	v1 "k8s.io/api/core/v1"
    26  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    27  
    28  	"github.com/kubewharf/katalyst-core/pkg/consts"
    29  	"github.com/kubewharf/katalyst-core/pkg/metaserver/agent/metric/provisioner/rodan/client"
    30  	"github.com/kubewharf/katalyst-core/pkg/metaserver/agent/metric/provisioner/rodan/types"
    31  	"github.com/kubewharf/katalyst-core/pkg/metrics"
    32  	utilmetric "github.com/kubewharf/katalyst-core/pkg/util/metric"
    33  )
    34  
    35  func TestSample(t *testing.T) {
    36  	t.Parallel()
    37  	testPod := &v1.Pod{
    38  		ObjectMeta: metav1.ObjectMeta{
    39  			UID:  "2126079c-8e0a-4cfe-9a0b-583199c14027",
    40  			Name: "testPod",
    41  		},
    42  		Status: v1.PodStatus{
    43  			ContainerStatuses: []v1.ContainerStatus{
    44  				{
    45  					Name:        "testContainer",
    46  					ContainerID: "containerd://1df178c3a7bddf1269d18b556c1d22a025bdf194c4617d9b411d0ef4b9229ec6",
    47  				},
    48  			},
    49  		},
    50  	}
    51  
    52  	podFetcher := &FakePodFetcher{
    53  		GetPodFunc: func(ctx context.Context, podUID string) (*v1.Pod, error) {
    54  			return testPod, nil
    55  		},
    56  		GetPodListFunc: func(ctx context.Context, podFilter func(*v1.Pod) bool) ([]*v1.Pod, error) {
    57  			return []*v1.Pod{
    58  				testPod,
    59  			}, nil
    60  		},
    61  	}
    62  
    63  	f := &RodanMetricsProvisioner{
    64  		metricStore: utilmetric.NewMetricStore(),
    65  		podFetcher:  podFetcher,
    66  		client:      client.NewRodanClient(podFetcher, makeTestMetricClient(), 9102),
    67  		emitter:     metrics.DummyMetrics{},
    68  		synced:      false,
    69  	}
    70  
    71  	f.Run(context.Background())
    72  
    73  	data, err := f.metricStore.GetNodeMetric(consts.MetricMemTotalSystem)
    74  	require.NoError(t, err)
    75  	require.Equal(t, float64(32614152<<10), data.Value)
    76  
    77  	data, err = f.metricStore.GetNodeMetric(consts.MetricMemFreeSystem)
    78  	require.NoError(t, err)
    79  	require.Equal(t, float64(12891380<<10), data.Value)
    80  
    81  	data, err = f.metricStore.GetNodeMetric(consts.MetricMemUsedSystem)
    82  	require.NoError(t, err)
    83  	require.Equal(t, float64(968376<<10), data.Value)
    84  
    85  	data, err = f.metricStore.GetNodeMetric(consts.MetricMemScaleFactorSystem)
    86  	require.NoError(t, err)
    87  	require.Equal(t, 1000.0, data.Value)
    88  
    89  	data, err = f.metricStore.GetNodeMetric(consts.MetricMemPageCacheSystem)
    90  	require.NoError(t, err)
    91  	require.Equal(t, float64(17783636<<10), data.Value)
    92  
    93  	data, err = f.metricStore.GetNodeMetric(consts.MetricMemBufferSystem)
    94  	require.NoError(t, err)
    95  	require.Equal(t, float64(365640<<10), data.Value)
    96  
    97  	data, err = f.metricStore.GetNodeMetric(consts.MetricMemKswapdstealSystem)
    98  	require.NoError(t, err)
    99  	require.Equal(t, 7067178.0, data.Value)
   100  
   101  	data, err = f.metricStore.GetNumaMetric(0, consts.MetricMemTotalNuma)
   102  	require.NoError(t, err)
   103  	require.Equal(t, 33396891648.0, data.Value)
   104  
   105  	data, err = f.metricStore.GetNumaMetric(0, consts.MetricMemFreeNuma)
   106  	require.NoError(t, err)
   107  	require.Equal(t, 13186412544.0, data.Value)
   108  
   109  	data, err = f.metricStore.GetCPUMetric(1, consts.MetricCPUUsageRatio)
   110  	require.NoError(t, err)
   111  	require.Equal(t, 0.04, data.Value)
   112  
   113  	data, err = f.metricStore.GetCPUMetric(6, consts.MetricCPUSchedwait)
   114  	require.NoError(t, err)
   115  	require.Equal(t, 0.0, data.Value)
   116  
   117  	data, err = f.metricStore.GetContainerMetric("2126079c-8e0a-4cfe-9a0b-583199c14027", "testContainer", consts.MetricLoad1MinContainer)
   118  	require.NoError(t, err)
   119  	require.Equal(t, 0.54, data.Value)
   120  
   121  	data, err = f.metricStore.GetContainerMetric("2126079c-8e0a-4cfe-9a0b-583199c14027", "testContainer", consts.MetricLoad5MinContainer)
   122  	require.NoError(t, err)
   123  	require.Equal(t, 0.54, data.Value)
   124  
   125  	data, err = f.metricStore.GetContainerMetric("2126079c-8e0a-4cfe-9a0b-583199c14027", "testContainer", consts.MetricCPUNrRunnableContainer)
   126  	require.NoError(t, err)
   127  	require.Equal(t, 54.0, data.Value)
   128  
   129  	data, err = f.metricStore.GetContainerMetric("2126079c-8e0a-4cfe-9a0b-583199c14027", "testContainer", consts.MetricCPUUsageContainer)
   130  	require.NoError(t, err)
   131  	require.Equal(t, 0.99, data.Value)
   132  
   133  	data, err = f.metricStore.GetContainerMetric("2126079c-8e0a-4cfe-9a0b-583199c14027", "testContainer", consts.MetricMemRssContainer)
   134  	require.NoError(t, err)
   135  	require.Equal(t, 16220160.0, data.Value)
   136  
   137  	data, err = f.metricStore.GetContainerMetric("2126079c-8e0a-4cfe-9a0b-583199c14027", "testContainer", consts.MetricMemCacheContainer)
   138  	require.NoError(t, err)
   139  	require.Equal(t, 0.0, data.Value)
   140  
   141  	data, err = f.metricStore.GetContainerMetric("2126079c-8e0a-4cfe-9a0b-583199c14027", "testContainer", consts.MetricMemShmemContainer)
   142  	require.NoError(t, err)
   143  	require.Equal(t, 0.0, data.Value)
   144  
   145  	data, err = f.metricStore.GetContainerNumaMetric("2126079c-8e0a-4cfe-9a0b-583199c14027", "testContainer", "0", consts.MetricsMemFilePerNumaContainer)
   146  	require.NoError(t, err)
   147  	require.Equal(t, float64(3352<<12), data.Value)
   148  }
   149  
   150  func makeTestMetricClient() client.MetricFunc {
   151  	return func(url string, params map[string]string) ([]byte, error) {
   152  		switch url {
   153  		case fmt.Sprintf("%s%s", "http://localhost:9102", types.NodeMemoryPath):
   154  			return []byte(`{"data":[{"key":"memory_memavailable","val":19583568},{"key":"memory_swapfree","val":0},{"key":"memory_pgsteal_kswapd","val":7067178},{"key":"memory_memused","val":968376},{"key":"memory_writeback","val":0},{"key":"memory_shmem","val":1708908},{"key":"memory_sreclaimable","val":605120},{"key":"memory_cached","val":17783636},{"key":"memory_swaptotal","val":0},{"key":"memory_dirty","val":956},{"key":"memory_memtotal","val":32614152},{"key":"memory_memfree","val":12891380},{"key":"memory_buffers","val":365640}]}`), nil
   155  		case fmt.Sprintf("%s%s", "http://localhost:9102", types.NodeSysctlPath):
   156  			return []byte(`{"data":[{"key":"sysctl_tcp_mem_pressure","val":507145},{"key":"sysctl_tcp_mem_original","val":380358},{"key":"sysctl_tcp_mem_extreme","val":760716},{"key":"sysctl_vm_watermark_scale_factor","val":1000}]}`), nil
   157  		case fmt.Sprintf("%s%s", "http://localhost:9102", types.NumaMemoryPath):
   158  			return []byte(`{"data":[{"key":"numastat_node0_memtotal","val":33396891648},{"key":"numastat_node0_memfree","val":13186412544}]}`), nil
   159  		case fmt.Sprintf("%s%s", "http://localhost:9102", types.NodeCgroupMemoryPath):
   160  			return []byte(`{"data":[{"key":"qosgroupmem_besteffort_memory_usage","val":1266978816},{"key":"qosgroupmem_burstable_memory_rss","val":185856000},{"key":"qosgroupmem_besteffort_memory_rss","val":112910336},{"key":"qosgroupmem_burstable_memory_usage","val":380174336}]}`), nil
   161  		case fmt.Sprintf("%s%s", "http://localhost:9102", types.NodeCPUPath):
   162  			return []byte(`{"data":[{"key":"percorecpu_cpu6_usage","val":21},{"key":"percorecpu_cpu0_sched_wait","val":0},{"key":"percorecpu_cpu2_sched_wait","val":0},{"key":"percorecpu_cpu1_usage","val":4},{"key":"percorecpu_cpu7_usage","val":22},{"key":"percorecpu_cpu6_sched_wait","val":0},{"key":"percorecpu_cpu7_sched_wait","val":0},{"key":"percorecpu_cpu5_usage","val":14},{"key":"percorecpu_cpu0_usage","val":5},{"key":"percorecpu_cpu3_usage","val":4},{"key":"percorecpu_cpu3_sched_wait","val":0},{"key":"percorecpu_cpu2_usage","val":5},{"key":"percorecpu_cpu5_sched_wait","val":0},{"key":"percorecpu_cpu4_usage","val":29},{"key":"percorecpu_cpu4_sched_wait","val":0},{"key":"percorecpu_cpu1_sched_wait","val":0}]}`), nil
   163  		case fmt.Sprintf("%s%s", "http://localhost:9102", types.ContainerCPUPath):
   164  			return []byte(`{"data":{"1df178c3a7bddf1269d18b556c1d22a025bdf194c4617d9b411d0ef4b9229ec6":[{"key":"cgcpu_nsecs","val":2015872049910},{"key":"cgcpu_sysusage","val":0},{"key":"cgcpu_userusage","val":99},{"key":"cgcpu_sys_nsecs","val":179907376},{"key":"cgcpu_user_nsecs","val":2015692142534},{"key":"cgcpu_usage","val":99}]}}`), nil
   165  		case fmt.Sprintf("%s%s", "http://localhost:9102", types.ContainerLoadPath):
   166  			return []byte(`{"data":{"1df178c3a7bddf1269d18b556c1d22a025bdf194c4617d9b411d0ef4b9229ec6":[{"key":"loadavg_nruninterruptible","val":54},{"key":"loadavg_loadavg15","val":54},{"key":"loadavg_loadavg5","val":54},{"key":"loadavg_nrrunning","val":54},{"key":"loadavg_nriowait","val":54},{"key":"loadavg_loadavg1","val":54},{"key":"loadavg_nrsleeping","val":54}]}}`), nil
   167  		case fmt.Sprintf("%s%s", "http://localhost:9102", types.ContainerCghardwarePath):
   168  			return []byte(`{"data":{"1df178c3a7bddf1269d18b556c1d22a025bdf194c4617d9b411d0ef4b9229ec6":[{"key":"cghardware_cycles","val":0},{"key":"cghardware_instructions","val":0}]}}`), nil
   169  		case fmt.Sprintf("%s%s", "http://localhost:9102", types.ContainerCgroupMemoryPath):
   170  			return []byte(`{"data":{"1df178c3a7bddf1269d18b556c1d22a025bdf194c4617d9b411d0ef4b9229ec6":[{"key":"cgmem_total_dirty","val":0},{"key":"cgmem_total_shmem","val":0},{"key":"cgmem_total_rss","val":16220160},{"key":"cgmem_total_cache","val":0}]}}`), nil
   171  		case fmt.Sprintf("%s%s", "http://localhost:9102", types.ContainerNumaStatPath):
   172  			return []byte(`{"data":{"1df178c3a7bddf1269d18b556c1d22a025bdf194c4617d9b411d0ef4b9229ec6":[{"key":"cgnumastat_filepage","val":3352},{"key":"cgnumastat_node0_filepage","val":3352}]}}`), nil
   173  		default:
   174  			return nil, fmt.Errorf("unknow url")
   175  		}
   176  	}
   177  }
   178  
   179  type FakePodFetcher struct {
   180  	GetPodFunc     func(ctx context.Context, podUID string) (*v1.Pod, error)
   181  	GetPodListFunc func(ctx context.Context, podFilter func(*v1.Pod) bool) ([]*v1.Pod, error)
   182  }
   183  
   184  func (f *FakePodFetcher) Run(ctx context.Context) {
   185  	return
   186  }
   187  
   188  func (f *FakePodFetcher) GetContainerID(podUID, containerName string) (string, error) {
   189  	return "", nil
   190  }
   191  
   192  func (f *FakePodFetcher) GetContainerSpec(podUID, containerName string) (*v1.Container, error) {
   193  	return nil, nil
   194  }
   195  
   196  func (f *FakePodFetcher) GetPod(ctx context.Context, podUID string) (*v1.Pod, error) {
   197  	return f.GetPodFunc(ctx, podUID)
   198  }
   199  
   200  func (f *FakePodFetcher) GetPodList(ctx context.Context, podFilter func(*v1.Pod) bool) ([]*v1.Pod, error) {
   201  	return f.GetPodListFunc(ctx, podFilter)
   202  }