metricsquerier_test.go 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056
  1. package collector
  2. import (
  3. "cmp"
  4. "reflect"
  5. "slices"
  6. "testing"
  7. "time"
  8. "github.com/opencost/opencost/core/pkg/source"
  9. "github.com/opencost/opencost/core/pkg/util"
  10. "github.com/opencost/opencost/modules/collector-source/pkg/metric"
  11. )
  12. var Start1Str = "2025-01-01T00:00:00Z"
  13. var End1Str = "2025-01-01T01:00:00Z"
  14. type MockStoreProvider struct {
  15. metricsCollector metric.MetricStore
  16. }
  17. func (m *MockStoreProvider) GetStore(start, end time.Time) metric.MetricStore {
  18. return m.metricsCollector
  19. }
  20. // QueryDataCoverage is not implemented for this mock
  21. func (m *MockStoreProvider) GetDailyDataCoverage(limitDays int) (time.Time, time.Time, error) {
  22. return time.Time{}, time.Time{}, nil
  23. }
  24. func GetMockCollectorProvider() StoreProvider {
  25. collector := NewOpenCostMetricStore()
  26. start, _ := time.Parse(time.RFC3339, Start1Str)
  27. time1 := time.Date(2025, 1, 1, 0, 30, 0, 0, time.UTC)
  28. end, _ := time.Parse(time.RFC3339, End1Str)
  29. node1Info := map[string]string{
  30. "node": "node1",
  31. "provider_id": "node1",
  32. }
  33. localStorage1Info := map[string]string{
  34. source.InstanceLabel: "node1",
  35. source.DeviceLabel: "local",
  36. }
  37. cluster1Info := map[string]string{
  38. "provisioner_name": "GKE",
  39. }
  40. gpu1Info := map[string]string{
  41. source.NamespaceLabel: "namespace1",
  42. source.PodLabel: "pod1",
  43. source.UIDLabel: "pod-uuid1",
  44. "container": "container1",
  45. "gpu": "0",
  46. "UUID": "GPU-1",
  47. "pci_bus_id": "00000000:00:0A.0",
  48. "device": "nvidia0",
  49. "modelName": "Tesla T4",
  50. "Hostname": "localhost",
  51. }
  52. pod1Info := map[string]string{
  53. source.NamespaceLabel: "namespace1",
  54. source.NodeLabel: "node1",
  55. source.InstanceLabel: "node1",
  56. source.PodLabel: "pod1",
  57. source.UIDLabel: "pod-uuid1",
  58. }
  59. container1Info := map[string]string{
  60. source.NamespaceLabel: "namespace1",
  61. source.NodeLabel: "node1",
  62. source.InstanceLabel: "node1",
  63. source.PodLabel: "pod1",
  64. source.UIDLabel: "pod-uuid1",
  65. source.ContainerLabel: "container1",
  66. }
  67. container2Info := map[string]string{
  68. source.NamespaceLabel: "kube-system",
  69. source.NodeLabel: "node1",
  70. source.InstanceLabel: "node1",
  71. source.PodLabel: "pod2",
  72. source.UIDLabel: "pod-uuid2",
  73. source.ContainerLabel: "container2",
  74. }
  75. networkZone1Info := map[string]string{
  76. source.PodNameLabel: "pod1",
  77. source.NamespaceLabel: "namespace1",
  78. source.InternetLabel: "false",
  79. source.SameRegionLabel: "true",
  80. source.SameZoneLabel: "false",
  81. source.ServiceLabel: "service1",
  82. }
  83. networkRegion1Info := map[string]string{
  84. source.PodNameLabel: "pod1",
  85. source.NamespaceLabel: "namespace1",
  86. source.InternetLabel: "false",
  87. source.SameRegionLabel: "false",
  88. source.SameZoneLabel: "false",
  89. source.ServiceLabel: "service1",
  90. }
  91. networkInternet1Info := map[string]string{
  92. source.PodNameLabel: "pod1",
  93. source.NamespaceLabel: "namespace1",
  94. source.InternetLabel: "true",
  95. source.SameRegionLabel: "false",
  96. source.SameZoneLabel: "false",
  97. source.ServiceLabel: "service1",
  98. }
  99. networkInternet2Info := map[string]string{
  100. source.PodNameLabel: "pod1",
  101. source.NamespaceLabel: "namespace1",
  102. source.InternetLabel: "true",
  103. source.SameRegionLabel: "false",
  104. source.SameZoneLabel: "false",
  105. source.ServiceLabel: "service2",
  106. }
  107. collector.Update(metric.KubeNodeLabels, node1Info, 0, start, nil)
  108. collector.Update(metric.KubeNodeLabels, node1Info, 0, end, nil)
  109. collector.Update(metric.NodeTotalHourlyCost, node1Info, 0, start, nil)
  110. collector.Update(metric.NodeTotalHourlyCost, node1Info, 0, end, nil)
  111. collector.Update(metric.NodeFSCapacityBytes, localStorage1Info, 2*GiB, start, nil)
  112. collector.Update(metric.ContainerFSUsageBytes, localStorage1Info, 1*GiB, start, nil)
  113. collector.Update(metric.ContainerFSUsageBytes, localStorage1Info, 1*GiB, end, nil)
  114. collector.Update(metric.KubeNodeStatusCapacityMemoryBytes, node1Info, 4*GiB, start, nil)
  115. collector.Update(metric.ContainerMemoryWorkingSetBytes, container1Info, 1*GiB, start, nil)
  116. collector.Update(metric.ContainerMemoryWorkingSetBytes, container2Info, 2*GiB, start, nil)
  117. collector.Update(metric.ContainerCPUUsageSecondsTotal, container1Info, 0, start, nil)
  118. collector.Update(metric.ContainerCPUUsageSecondsTotal, container1Info, 60*60*4, time1, nil)
  119. collector.Update(metric.ContainerCPUUsageSecondsTotal, container1Info, 60*60*10, end, nil)
  120. collector.Update(metric.KubecostClusterManagementCost, cluster1Info, 0.1, start, nil)
  121. collector.Update(metric.KubecostClusterManagementCost, cluster1Info, 0.1, end, nil)
  122. collector.Update(metric.DCGMFIDEVDECUTIL, gpu1Info, 0, start, nil)
  123. collector.Update(metric.DCGMFIPROFGRENGINEACTIVE, gpu1Info, 0, start, nil)
  124. collector.Update(metric.DCGMFIPROFGRENGINEACTIVE, gpu1Info, 1, end, nil)
  125. collector.Update(metric.KubecostNetworkZoneEgressCost, nil, 1, start, nil)
  126. collector.Update(metric.KubecostNetworkRegionEgressCost, nil, 2, start, nil)
  127. collector.Update(metric.KubecostNetworkInternetEgressCost, nil, 3, start, nil)
  128. collector.Update(metric.ContainerNetworkTransmitBytesTotal, pod1Info, 3*GiB, start, nil)
  129. collector.Update(metric.ContainerNetworkTransmitBytesTotal, pod1Info, 13*GiB, end, nil)
  130. collector.Update(metric.ContainerNetworkReceiveBytesTotal, pod1Info, 30*GiB, start, nil)
  131. collector.Update(metric.ContainerNetworkReceiveBytesTotal, pod1Info, 130*GiB, end, nil)
  132. collector.Update(metric.KubecostPodNetworkEgressBytesTotal, networkRegion1Info, 1*GiB, start, nil)
  133. collector.Update(metric.KubecostPodNetworkEgressBytesTotal, networkZone1Info, 0*GiB, start, nil)
  134. collector.Update(metric.KubecostPodNetworkEgressBytesTotal, networkInternet1Info, 1*GiB, start, nil)
  135. collector.Update(metric.KubecostPodNetworkEgressBytesTotal, networkInternet2Info, 1*GiB, start, nil)
  136. collector.Update(metric.KubecostPodNetworkEgressBytesTotal, networkRegion1Info, 2*GiB, end, nil)
  137. collector.Update(metric.KubecostPodNetworkEgressBytesTotal, networkZone1Info, 2*GiB, end, nil)
  138. collector.Update(metric.KubecostPodNetworkEgressBytesTotal, networkInternet1Info, 4*GiB, end, nil)
  139. collector.Update(metric.KubecostPodNetworkEgressBytesTotal, networkInternet2Info, 5*GiB, end, nil)
  140. collector.Update(metric.KubecostPodNetworkIngressBytesTotal, networkRegion1Info, 10*GiB, start, nil)
  141. collector.Update(metric.KubecostPodNetworkIngressBytesTotal, networkZone1Info, 0*GiB, start, nil)
  142. collector.Update(metric.KubecostPodNetworkIngressBytesTotal, networkInternet1Info, 10*GiB, start, nil)
  143. collector.Update(metric.KubecostPodNetworkIngressBytesTotal, networkInternet2Info, 10*GiB, start, nil)
  144. collector.Update(metric.KubecostPodNetworkIngressBytesTotal, networkRegion1Info, 20*GiB, end, nil)
  145. collector.Update(metric.KubecostPodNetworkIngressBytesTotal, networkZone1Info, 20*GiB, end, nil)
  146. collector.Update(metric.KubecostPodNetworkIngressBytesTotal, networkInternet1Info, 40*GiB, end, nil)
  147. collector.Update(metric.KubecostPodNetworkIngressBytesTotal, networkInternet2Info, 50*GiB, end, nil)
  148. return &MockStoreProvider{
  149. metricsCollector: collector,
  150. }
  151. }
  152. func TestCollectorMetricsQuerier_QueryLocalStorageCost(t *testing.T) {
  153. start1, _ := time.Parse(time.RFC3339, Start1Str)
  154. end1, _ := time.Parse(time.RFC3339, End1Str)
  155. c := collectorMetricsQuerier{
  156. collectorProvider: GetMockCollectorProvider(),
  157. }
  158. resCh := c.QueryLocalStorageCost(start1, end1)
  159. res, err := resCh.Await()
  160. if err != nil {
  161. t.Errorf("unexpected error: %v", err.Error())
  162. }
  163. expected := []*source.LocalStorageCostResult{
  164. {
  165. Cluster: "",
  166. Instance: "node1",
  167. Device: "local",
  168. Data: []*util.Vector{
  169. {
  170. Value: LocalStorageCostPerGiBHr * 2,
  171. },
  172. },
  173. },
  174. }
  175. if len(res) != len(expected) {
  176. t.Errorf("length of result was not as expected: got = %d, want %d", len(res), len(expected))
  177. }
  178. for i, got := range res {
  179. if !reflect.DeepEqual(got, expected[i]) {
  180. t.Errorf("result at index %d did not match: got = %v, want %v", i, got, expected[i])
  181. }
  182. }
  183. }
  184. func TestCollectorMetricsQuerier_QueryLocalStorageUsedCost(t *testing.T) {
  185. start1, _ := time.Parse(time.RFC3339, Start1Str)
  186. end1, _ := time.Parse(time.RFC3339, End1Str)
  187. c := collectorMetricsQuerier{
  188. collectorProvider: GetMockCollectorProvider(),
  189. }
  190. resCh := c.QueryLocalStorageUsedCost(start1, end1)
  191. res, err := resCh.Await()
  192. if err != nil {
  193. t.Errorf("unexpected error: %v", err.Error())
  194. }
  195. expected := []*source.LocalStorageUsedCostResult{
  196. {
  197. Cluster: "",
  198. Instance: "node1",
  199. Device: "local",
  200. Data: []*util.Vector{
  201. {
  202. Value: LocalStorageCostPerGiBHr,
  203. },
  204. },
  205. },
  206. }
  207. if len(res) != len(expected) {
  208. t.Errorf("length of result was not as expected: got = %d, want %d", len(res), len(expected))
  209. }
  210. for i, got := range res {
  211. if !reflect.DeepEqual(got, expected[i]) {
  212. t.Errorf("result at index %d did not match: got = %v, want %v", i, got, expected[i])
  213. }
  214. }
  215. }
  216. func TestCollectorMetricsQuerier_QueryNodeActiveMinutes(t *testing.T) {
  217. start1, _ := time.Parse(time.RFC3339, Start1Str)
  218. end1, _ := time.Parse(time.RFC3339, End1Str)
  219. c := collectorMetricsQuerier{
  220. collectorProvider: GetMockCollectorProvider(),
  221. }
  222. resCh := c.QueryNodeActiveMinutes(time.Now(), time.Now())
  223. res, err := resCh.Await()
  224. if err != nil {
  225. t.Errorf("unexpected error: %v", err.Error())
  226. }
  227. expected := []*source.NodeActiveMinutesResult{
  228. {
  229. Cluster: "",
  230. Node: "node1",
  231. ProviderID: "node1",
  232. Data: []*util.Vector{
  233. {
  234. Timestamp: float64(start1.Unix()),
  235. Value: 1,
  236. },
  237. {
  238. Timestamp: float64(end1.Unix()),
  239. Value: 1,
  240. },
  241. },
  242. },
  243. }
  244. if len(res) != len(expected) {
  245. t.Errorf("length of result was not as expected: got = %d, want %d", len(res), len(expected))
  246. }
  247. for i, got := range res {
  248. if !reflect.DeepEqual(got, expected[i]) {
  249. t.Errorf("result at index %d did not match: got = %v, want %v", i, got, expected[i])
  250. }
  251. }
  252. }
  253. func TestCollectorMetricsQuerier_QueryNodeRAMSystemPercent(t *testing.T) {
  254. start1, _ := time.Parse(time.RFC3339, Start1Str)
  255. end1, _ := time.Parse(time.RFC3339, End1Str)
  256. c := collectorMetricsQuerier{
  257. collectorProvider: GetMockCollectorProvider(),
  258. }
  259. resCh := c.QueryNodeRAMSystemPercent(start1, end1)
  260. res, err := resCh.Await()
  261. if err != nil {
  262. t.Errorf("unexpected error: %v", err.Error())
  263. }
  264. expected := []*source.NodeRAMSystemPercentResult{
  265. {
  266. UID: "pod-uuid2",
  267. Cluster: "",
  268. Instance: "node1",
  269. Data: []*util.Vector{
  270. {
  271. Value: .5,
  272. },
  273. },
  274. },
  275. }
  276. if len(res) != len(expected) {
  277. t.Errorf("length of result was not as expected: got = %d, want %d", len(res), len(expected))
  278. }
  279. for i, got := range res {
  280. if !reflect.DeepEqual(got, expected[i]) {
  281. t.Errorf("result at index %d did not match: got = %v, want %v", i, got, expected[i])
  282. }
  283. }
  284. }
  285. func TestCollectorMetricsQuerier_QueryNodeRAMUserPercent(t *testing.T) {
  286. start1, _ := time.Parse(time.RFC3339, Start1Str)
  287. end1, _ := time.Parse(time.RFC3339, End1Str)
  288. c := collectorMetricsQuerier{
  289. collectorProvider: GetMockCollectorProvider(),
  290. }
  291. resCh := c.QueryNodeRAMUserPercent(start1, end1)
  292. res, err := resCh.Await()
  293. if err != nil {
  294. t.Errorf("unexpected error: %v", err.Error())
  295. }
  296. expected := []*source.NodeRAMUserPercentResult{
  297. {
  298. UID: "pod-uuid1",
  299. Cluster: "",
  300. Instance: "node1",
  301. Data: []*util.Vector{
  302. {
  303. Value: .25,
  304. },
  305. },
  306. },
  307. }
  308. if len(res) != len(expected) {
  309. t.Errorf("length of result was not as expected: got = %d, want %d", len(res), len(expected))
  310. }
  311. for i, got := range res {
  312. if !reflect.DeepEqual(got, expected[i]) {
  313. t.Errorf("result at index %d did not match: got = %v, want %v", i, got, expected[i])
  314. }
  315. }
  316. }
  317. func TestCollectorMetricsQuerier_QueryClusterManagementDuration(t *testing.T) {
  318. start1, _ := time.Parse(time.RFC3339, Start1Str)
  319. end1, _ := time.Parse(time.RFC3339, End1Str)
  320. c := collectorMetricsQuerier{
  321. collectorProvider: GetMockCollectorProvider(),
  322. }
  323. resCh := c.QueryClusterManagementDuration(start1, end1)
  324. res, err := resCh.Await()
  325. if err != nil {
  326. t.Errorf("unexpected error: %v", err.Error())
  327. }
  328. expected := []*source.ClusterManagementDurationResult{
  329. {
  330. Cluster: "",
  331. Provisioner: "GKE",
  332. Data: []*util.Vector{
  333. {
  334. Timestamp: float64(start1.Unix()),
  335. Value: 1,
  336. },
  337. {
  338. Timestamp: float64(end1.Unix()),
  339. Value: 1,
  340. },
  341. },
  342. },
  343. }
  344. if len(res) != len(expected) {
  345. t.Errorf("length of result was not as expected: got = %d, want %d", len(res), len(expected))
  346. }
  347. for i, got := range res {
  348. if !reflect.DeepEqual(got, expected[i]) {
  349. t.Errorf("result at index %d did not match: got = %v, want %v", i, got, expected[i])
  350. }
  351. }
  352. }
  353. func Test_collectorMetricsQuerier_QueryCPUUsageAvg(t *testing.T) {
  354. start1, _ := time.Parse(time.RFC3339, Start1Str)
  355. end1, _ := time.Parse(time.RFC3339, End1Str)
  356. c := collectorMetricsQuerier{
  357. collectorProvider: GetMockCollectorProvider(),
  358. }
  359. resCh := c.QueryCPUUsageAvg(start1, end1)
  360. res, err := resCh.Await()
  361. if err != nil {
  362. t.Errorf("unexpected error: %v", err.Error())
  363. }
  364. expected := []*source.CPUUsageAvgResult{
  365. {
  366. UID: "pod-uuid1",
  367. Cluster: "",
  368. Namespace: "namespace1",
  369. Node: "node1",
  370. Instance: "node1",
  371. Pod: "pod1",
  372. Container: "container1",
  373. Data: []*util.Vector{
  374. {
  375. Value: 10,
  376. },
  377. },
  378. },
  379. }
  380. if len(res) != len(expected) {
  381. t.Errorf("length of result was not as expected: got = %d, want %d", len(res), len(expected))
  382. }
  383. for i, got := range res {
  384. if !reflect.DeepEqual(got, expected[i]) {
  385. t.Errorf("result at index %d did not match: got = %v, want %v", i, got, expected[i])
  386. }
  387. }
  388. }
  389. func Test_collectorMetricsQuerier_QueryCPUUsageMax(t *testing.T) {
  390. start1, _ := time.Parse(time.RFC3339, Start1Str)
  391. end1, _ := time.Parse(time.RFC3339, End1Str)
  392. c := collectorMetricsQuerier{
  393. collectorProvider: GetMockCollectorProvider(),
  394. }
  395. resCh := c.QueryCPUUsageMax(start1, end1)
  396. res, err := resCh.Await()
  397. if err != nil {
  398. t.Errorf("unexpected error: %v", err.Error())
  399. }
  400. expected := []*source.CPUUsageMaxResult{
  401. {
  402. UID: "pod-uuid1",
  403. Cluster: "",
  404. Namespace: "namespace1",
  405. Node: "node1",
  406. Instance: "node1",
  407. Pod: "pod1",
  408. Container: "container1",
  409. Data: []*util.Vector{
  410. {
  411. Value: 12,
  412. },
  413. },
  414. },
  415. }
  416. if len(res) != len(expected) {
  417. t.Errorf("length of result was not as expected: got = %d, want %d", len(res), len(expected))
  418. }
  419. for i, got := range res {
  420. if !reflect.DeepEqual(got, expected[i]) {
  421. t.Errorf("result at index %d did not match: got = %v, want %v", i, got, expected[i])
  422. }
  423. }
  424. }
  425. func TestCollectorMetricsQuerier_QueryGPUsUsageAvg(t *testing.T) {
  426. start1, _ := time.Parse(time.RFC3339, Start1Str)
  427. end1, _ := time.Parse(time.RFC3339, End1Str)
  428. c := collectorMetricsQuerier{
  429. collectorProvider: GetMockCollectorProvider(),
  430. }
  431. resCh := c.QueryGPUsUsageAvg(start1, end1)
  432. res, err := resCh.Await()
  433. if err != nil {
  434. t.Errorf("unexpected error: %v", err.Error())
  435. }
  436. expected := []*source.GPUsUsageAvgResult{
  437. {
  438. UID: "pod-uuid1",
  439. Cluster: "",
  440. Namespace: "namespace1",
  441. Pod: "pod1",
  442. Container: "container1",
  443. Data: []*util.Vector{
  444. {
  445. Value: 0.5,
  446. },
  447. },
  448. },
  449. }
  450. if len(res) != len(expected) {
  451. t.Errorf("length of result was not as expected: got = %d, want %d", len(res), len(expected))
  452. }
  453. for i, got := range res {
  454. if !reflect.DeepEqual(got, expected[i]) {
  455. t.Errorf("result at index %d did not match: got = %v, want %v", i, got, expected[i])
  456. }
  457. }
  458. }
  459. func TestCollectorMetricsQuerier_QueryGPUsUsageMax(t *testing.T) {
  460. start1, _ := time.Parse(time.RFC3339, Start1Str)
  461. end1, _ := time.Parse(time.RFC3339, End1Str)
  462. c := collectorMetricsQuerier{
  463. collectorProvider: GetMockCollectorProvider(),
  464. }
  465. resCh := c.QueryGPUsUsageMax(start1, end1)
  466. res, err := resCh.Await()
  467. if err != nil {
  468. t.Errorf("unexpected error: %v", err.Error())
  469. }
  470. expected := []*source.GPUsUsageMaxResult{
  471. {
  472. UID: "pod-uuid1",
  473. Cluster: "",
  474. Namespace: "namespace1",
  475. Pod: "pod1",
  476. Container: "container1",
  477. Data: []*util.Vector{
  478. {
  479. Value: 1.0,
  480. },
  481. },
  482. },
  483. }
  484. if len(res) != len(expected) {
  485. t.Errorf("length of result was not as expected: got = %d, want %d", len(res), len(expected))
  486. }
  487. for i, got := range res {
  488. if !reflect.DeepEqual(got, expected[i]) {
  489. t.Errorf("result at index %d did not match: got = %v, want %v", i, got, expected[i])
  490. }
  491. }
  492. }
  493. func TestCollectorMetricsQuerier_QueryGPUInfo(t *testing.T) {
  494. start1, _ := time.Parse(time.RFC3339, Start1Str)
  495. end1, _ := time.Parse(time.RFC3339, End1Str)
  496. c := collectorMetricsQuerier{
  497. collectorProvider: GetMockCollectorProvider(),
  498. }
  499. resCh := c.QueryGPUInfo(start1, end1)
  500. res, err := resCh.Await()
  501. if err != nil {
  502. t.Errorf("unexpected error: %v", err.Error())
  503. }
  504. expected := []*source.GPUInfoResult{
  505. {
  506. UID: "pod-uuid1",
  507. Cluster: "",
  508. Namespace: "namespace1",
  509. Pod: "pod1",
  510. Container: "container1",
  511. Device: "nvidia0",
  512. ModelName: "Tesla T4",
  513. UUID: "GPU-1",
  514. Data: []*util.Vector{
  515. {
  516. Value: 1,
  517. },
  518. },
  519. },
  520. }
  521. if len(res) != len(expected) {
  522. t.Errorf("length of result was not as expected: got = %d, want %d", len(res), len(expected))
  523. }
  524. for i, got := range res {
  525. if !reflect.DeepEqual(got, expected[i]) {
  526. t.Errorf("result at index %d did not match: got = %v, want %v", i, got, expected[i])
  527. }
  528. }
  529. }
  530. func Test_collectorMetricsQuerier_QueryNetZoneGiB(t *testing.T) {
  531. start1, _ := time.Parse(time.RFC3339, Start1Str)
  532. end1, _ := time.Parse(time.RFC3339, End1Str)
  533. c := collectorMetricsQuerier{
  534. collectorProvider: GetMockCollectorProvider(),
  535. }
  536. resCh := c.QueryNetZoneGiB(start1, end1)
  537. res, err := resCh.Await()
  538. if err != nil {
  539. t.Errorf("unexpected error: %v", err.Error())
  540. }
  541. expected := []*source.NetZoneGiBResult{
  542. {
  543. Cluster: "",
  544. Namespace: "namespace1",
  545. Pod: "pod1",
  546. Data: []*util.Vector{
  547. {
  548. Value: 2,
  549. },
  550. },
  551. },
  552. }
  553. if len(res) != len(expected) {
  554. t.Errorf("length of result was not as expected: got = %d, want %d", len(res), len(expected))
  555. }
  556. for i, got := range res {
  557. if !reflect.DeepEqual(got, expected[i]) {
  558. t.Errorf("result at index %d did not match: got = %v, want %v", i, got, expected[i])
  559. }
  560. }
  561. }
  562. func Test_collectorMetricsQuerier_QueryNetZonePricePerGiB(t *testing.T) {
  563. start1, _ := time.Parse(time.RFC3339, Start1Str)
  564. end1, _ := time.Parse(time.RFC3339, End1Str)
  565. c := collectorMetricsQuerier{
  566. collectorProvider: GetMockCollectorProvider(),
  567. }
  568. resCh := c.QueryNetZonePricePerGiB(start1, end1)
  569. res, err := resCh.Await()
  570. if err != nil {
  571. t.Errorf("unexpected error: %v", err.Error())
  572. }
  573. expected := []*source.NetZonePricePerGiBResult{
  574. {
  575. Cluster: "",
  576. Data: []*util.Vector{
  577. {
  578. Value: 1,
  579. },
  580. },
  581. },
  582. }
  583. if len(res) != len(expected) {
  584. t.Errorf("length of result was not as expected: got = %d, want %d", len(res), len(expected))
  585. }
  586. for i, got := range res {
  587. if !reflect.DeepEqual(got, expected[i]) {
  588. t.Errorf("result at index %d did not match: got = %v, want %v", i, got, expected[i])
  589. }
  590. }
  591. }
  592. func Test_collectorMetricsQuerier_QueryNetRegionGiB(t *testing.T) {
  593. start1, _ := time.Parse(time.RFC3339, Start1Str)
  594. end1, _ := time.Parse(time.RFC3339, End1Str)
  595. c := collectorMetricsQuerier{
  596. collectorProvider: GetMockCollectorProvider(),
  597. }
  598. resCh := c.QueryNetRegionGiB(start1, end1)
  599. res, err := resCh.Await()
  600. if err != nil {
  601. t.Errorf("unexpected error: %v", err.Error())
  602. }
  603. expected := []*source.NetRegionGiBResult{
  604. {
  605. Cluster: "",
  606. Namespace: "namespace1",
  607. Pod: "pod1",
  608. Data: []*util.Vector{
  609. {
  610. Value: 1,
  611. },
  612. },
  613. },
  614. }
  615. if len(res) != len(expected) {
  616. t.Errorf("length of result was not as expected: got = %d, want %d", len(res), len(expected))
  617. }
  618. for i, got := range res {
  619. if !reflect.DeepEqual(got, expected[i]) {
  620. t.Errorf("result at index %d did not match: got = %v, want %v", i, got, expected[i])
  621. }
  622. }
  623. }
  624. func Test_collectorMetricsQuerier_QueryNetRegionPricePerGiB(t *testing.T) {
  625. start1, _ := time.Parse(time.RFC3339, Start1Str)
  626. end1, _ := time.Parse(time.RFC3339, End1Str)
  627. c := collectorMetricsQuerier{
  628. collectorProvider: GetMockCollectorProvider(),
  629. }
  630. resCh := c.QueryNetRegionPricePerGiB(start1, end1)
  631. res, err := resCh.Await()
  632. if err != nil {
  633. t.Errorf("unexpected error: %v", err.Error())
  634. }
  635. expected := []*source.NetRegionPricePerGiBResult{
  636. {
  637. Cluster: "",
  638. Data: []*util.Vector{
  639. {
  640. Value: 2,
  641. },
  642. },
  643. },
  644. }
  645. if len(res) != len(expected) {
  646. t.Errorf("length of result was not as expected: got = %d, want %d", len(res), len(expected))
  647. }
  648. for i, got := range res {
  649. if !reflect.DeepEqual(got, expected[i]) {
  650. t.Errorf("result at index %d did not match: got = %v, want %v", i, got, expected[i])
  651. }
  652. }
  653. }
  654. func Test_collectorMetricsQuerier_QueryNetInternetGiB(t *testing.T) {
  655. start1, _ := time.Parse(time.RFC3339, Start1Str)
  656. end1, _ := time.Parse(time.RFC3339, End1Str)
  657. c := collectorMetricsQuerier{
  658. collectorProvider: GetMockCollectorProvider(),
  659. }
  660. resCh := c.QueryNetInternetGiB(start1, end1)
  661. res, err := resCh.Await()
  662. if err != nil {
  663. t.Errorf("unexpected error: %v", err.Error())
  664. }
  665. expected := []*source.NetInternetGiBResult{
  666. {
  667. Cluster: "",
  668. Namespace: "namespace1",
  669. Pod: "pod1",
  670. Data: []*util.Vector{
  671. {
  672. Value: 7,
  673. },
  674. },
  675. },
  676. }
  677. if len(res) != len(expected) {
  678. t.Errorf("length of result was not as expected: got = %d, want %d", len(res), len(expected))
  679. }
  680. for i, got := range res {
  681. if !reflect.DeepEqual(got, expected[i]) {
  682. t.Errorf("result at index %d did not match: got = %v, want %v", i, got, expected[i])
  683. }
  684. }
  685. }
  686. func Test_collectorMetricsQuerier_QueryNetInternetPricePerGiB(t *testing.T) {
  687. start1, _ := time.Parse(time.RFC3339, Start1Str)
  688. end1, _ := time.Parse(time.RFC3339, End1Str)
  689. c := collectorMetricsQuerier{
  690. collectorProvider: GetMockCollectorProvider(),
  691. }
  692. resCh := c.QueryNetInternetPricePerGiB(start1, end1)
  693. res, err := resCh.Await()
  694. if err != nil {
  695. t.Errorf("unexpected error: %v", err.Error())
  696. }
  697. expected := []*source.NetInternetPricePerGiBResult{
  698. {
  699. Cluster: "",
  700. Data: []*util.Vector{
  701. {
  702. Value: 3,
  703. },
  704. },
  705. },
  706. }
  707. if len(res) != len(expected) {
  708. t.Errorf("length of result was not as expected: got = %d, want %d", len(res), len(expected))
  709. }
  710. for i, got := range res {
  711. if !reflect.DeepEqual(got, expected[i]) {
  712. t.Errorf("result at index %d did not match: got = %v, want %v", i, got, expected[i])
  713. }
  714. }
  715. }
  716. func Test_collectorMetricsQuerier_QueryNetInternetServiceGiB(t *testing.T) {
  717. start1, _ := time.Parse(time.RFC3339, Start1Str)
  718. end1, _ := time.Parse(time.RFC3339, End1Str)
  719. c := collectorMetricsQuerier{
  720. collectorProvider: GetMockCollectorProvider(),
  721. }
  722. resCh := c.QueryNetInternetServiceGiB(start1, end1)
  723. res, err := resCh.Await()
  724. if err != nil {
  725. t.Errorf("unexpected error: %v", err.Error())
  726. }
  727. expected := []*source.NetInternetServiceGiBResult{
  728. {
  729. Cluster: "",
  730. Namespace: "namespace1",
  731. Pod: "pod1",
  732. Service: "service1",
  733. Data: []*util.Vector{
  734. {
  735. Value: 3,
  736. },
  737. },
  738. },
  739. {
  740. Cluster: "",
  741. Namespace: "namespace1",
  742. Pod: "pod1",
  743. Service: "service2",
  744. Data: []*util.Vector{
  745. {
  746. Value: 4,
  747. },
  748. },
  749. },
  750. }
  751. if len(res) != len(expected) {
  752. t.Errorf("length of result was not as expected: got = %d, want %d", len(res), len(expected))
  753. }
  754. slices.SortFunc(res, func(a, b *source.NetInternetServiceGiBResult) int {
  755. return cmp.Compare(a.Service, b.Service)
  756. })
  757. for i, got := range res {
  758. if !reflect.DeepEqual(got, expected[i]) {
  759. t.Errorf("result at index %d did not match: got = %v, want %v", i, got, expected[i])
  760. }
  761. }
  762. }
  763. func Test_collectorMetricsQuerier_QueryNetTransferBytes(t *testing.T) {
  764. start1, _ := time.Parse(time.RFC3339, Start1Str)
  765. end1, _ := time.Parse(time.RFC3339, End1Str)
  766. c := collectorMetricsQuerier{
  767. collectorProvider: GetMockCollectorProvider(),
  768. }
  769. resCh := c.QueryNetTransferBytes(start1, end1)
  770. res, err := resCh.Await()
  771. if err != nil {
  772. t.Errorf("unexpected error: %v", err.Error())
  773. }
  774. expected := []*source.NetTransferBytesResult{
  775. {
  776. UID: "pod-uuid1",
  777. Cluster: "",
  778. Namespace: "namespace1",
  779. Pod: "pod1",
  780. Data: []*util.Vector{
  781. {
  782. Value: 10 * GiB,
  783. },
  784. },
  785. },
  786. }
  787. if len(res) != len(expected) {
  788. t.Errorf("length of result was not as expected: got = %d, want %d", len(res), len(expected))
  789. }
  790. for i, got := range res {
  791. if !reflect.DeepEqual(got, expected[i]) {
  792. t.Errorf("result at index %d did not match: got = %v, want %v", i, got, expected[i])
  793. }
  794. }
  795. }
  796. func Test_collectorMetricsQuerier_QueryNetZoneIngressGiB(t *testing.T) {
  797. start1, _ := time.Parse(time.RFC3339, Start1Str)
  798. end1, _ := time.Parse(time.RFC3339, End1Str)
  799. c := collectorMetricsQuerier{
  800. collectorProvider: GetMockCollectorProvider(),
  801. }
  802. resCh := c.QueryNetZoneIngressGiB(start1, end1)
  803. res, err := resCh.Await()
  804. if err != nil {
  805. t.Errorf("unexpected error: %v", err.Error())
  806. }
  807. expected := []*source.NetZoneIngressGiBResult{
  808. {
  809. Cluster: "",
  810. Namespace: "namespace1",
  811. Pod: "pod1",
  812. Data: []*util.Vector{
  813. {
  814. Value: 20,
  815. },
  816. },
  817. },
  818. }
  819. if len(res) != len(expected) {
  820. t.Errorf("length of result was not as expected: got = %d, want %d", len(res), len(expected))
  821. }
  822. for i, got := range res {
  823. if !reflect.DeepEqual(got, expected[i]) {
  824. t.Errorf("result at index %d did not match: got = %v, want %v", i, got, expected[i])
  825. }
  826. }
  827. }
  828. func Test_collectorMetricsQuerier_QueryNetRegionIngressGiB(t *testing.T) {
  829. start1, _ := time.Parse(time.RFC3339, Start1Str)
  830. end1, _ := time.Parse(time.RFC3339, End1Str)
  831. c := collectorMetricsQuerier{
  832. collectorProvider: GetMockCollectorProvider(),
  833. }
  834. resCh := c.QueryNetRegionIngressGiB(start1, end1)
  835. res, err := resCh.Await()
  836. if err != nil {
  837. t.Errorf("unexpected error: %v", err.Error())
  838. }
  839. expected := []*source.NetRegionIngressGiBResult{
  840. {
  841. Cluster: "",
  842. Namespace: "namespace1",
  843. Pod: "pod1",
  844. Data: []*util.Vector{
  845. {
  846. Value: 10,
  847. },
  848. },
  849. },
  850. }
  851. if len(res) != len(expected) {
  852. t.Errorf("length of result was not as expected: got = %d, want %d", len(res), len(expected))
  853. }
  854. for i, got := range res {
  855. if !reflect.DeepEqual(got, expected[i]) {
  856. t.Errorf("result at index %d did not match: got = %v, want %v", i, got, expected[i])
  857. }
  858. }
  859. }
  860. func Test_collectorMetricsQuerier_QueryNetInternetIngressGiB(t *testing.T) {
  861. start1, _ := time.Parse(time.RFC3339, Start1Str)
  862. end1, _ := time.Parse(time.RFC3339, End1Str)
  863. c := collectorMetricsQuerier{
  864. collectorProvider: GetMockCollectorProvider(),
  865. }
  866. resCh := c.QueryNetInternetIngressGiB(start1, end1)
  867. res, err := resCh.Await()
  868. if err != nil {
  869. t.Errorf("unexpected error: %v", err.Error())
  870. }
  871. expected := []*source.NetInternetIngressGiBResult{
  872. {
  873. Cluster: "",
  874. Namespace: "namespace1",
  875. Pod: "pod1",
  876. Data: []*util.Vector{
  877. {
  878. Value: 70,
  879. },
  880. },
  881. },
  882. }
  883. if len(res) != len(expected) {
  884. t.Errorf("length of result was not as expected: got = %d, want %d", len(res), len(expected))
  885. }
  886. for i, got := range res {
  887. if !reflect.DeepEqual(got, expected[i]) {
  888. t.Errorf("result at index %d did not match: got = %v, want %v", i, got, expected[i])
  889. }
  890. }
  891. }
  892. func Test_collectorMetricsQuerier_QueryNetInternetServiceIngressGiB(t *testing.T) {
  893. start1, _ := time.Parse(time.RFC3339, Start1Str)
  894. end1, _ := time.Parse(time.RFC3339, End1Str)
  895. c := collectorMetricsQuerier{
  896. collectorProvider: GetMockCollectorProvider(),
  897. }
  898. resCh := c.QueryNetInternetServiceIngressGiB(start1, end1)
  899. res, err := resCh.Await()
  900. if err != nil {
  901. t.Errorf("unexpected error: %v", err.Error())
  902. }
  903. expected := []*source.NetInternetServiceIngressGiBResult{
  904. {
  905. Cluster: "",
  906. Namespace: "namespace1",
  907. Pod: "pod1",
  908. Service: "service1",
  909. Data: []*util.Vector{
  910. {
  911. Value: 30,
  912. },
  913. },
  914. },
  915. {
  916. Cluster: "",
  917. Namespace: "namespace1",
  918. Pod: "pod1",
  919. Service: "service2",
  920. Data: []*util.Vector{
  921. {
  922. Value: 40,
  923. },
  924. },
  925. },
  926. }
  927. if len(res) != len(expected) {
  928. t.Errorf("length of result was not as expected: got = %d, want %d", len(res), len(expected))
  929. }
  930. slices.SortFunc(res, func(a, b *source.NetInternetServiceIngressGiBResult) int {
  931. return cmp.Compare(a.Service, b.Service)
  932. })
  933. for i, got := range res {
  934. if !reflect.DeepEqual(got, expected[i]) {
  935. t.Errorf("result at index %d did not match: got = %v, want %v", i, got, expected[i])
  936. }
  937. }
  938. }
  939. func Test_collectorMetricsQuerier_QueryNetReceiveBytes(t *testing.T) {
  940. start1, _ := time.Parse(time.RFC3339, Start1Str)
  941. end1, _ := time.Parse(time.RFC3339, End1Str)
  942. c := collectorMetricsQuerier{
  943. collectorProvider: GetMockCollectorProvider(),
  944. }
  945. resCh := c.QueryNetReceiveBytes(start1, end1)
  946. res, err := resCh.Await()
  947. if err != nil {
  948. t.Errorf("unexpected error: %v", err.Error())
  949. }
  950. expected := []*source.NetReceiveBytesResult{
  951. {
  952. UID: "pod-uuid1",
  953. Cluster: "",
  954. Namespace: "namespace1",
  955. Pod: "pod1",
  956. Data: []*util.Vector{
  957. {
  958. Value: 100 * GiB,
  959. },
  960. },
  961. },
  962. }
  963. if len(res) != len(expected) {
  964. t.Errorf("length of result was not as expected: got = %d, want %d", len(res), len(expected))
  965. }
  966. for i, got := range res {
  967. if !reflect.DeepEqual(got, expected[i]) {
  968. t.Errorf("result at index %d did not match: got = %v, want %v", i, got, expected[i])
  969. }
  970. }
  971. }