metricsquerier_test.go 29 KB

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