metricsquerier_test.go 28 KB

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