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 }