2
0

summaryallocation_json_test.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. package opencost
  2. import (
  3. "encoding/json"
  4. "math"
  5. "testing"
  6. "time"
  7. "github.com/opencost/opencost/core/pkg/util/timeutil"
  8. )
  9. func TestSummaryAllocationSetRangeResponse_MarshalJSON(t *testing.T) {
  10. // Set a 1-day (start, end)
  11. s := time.Date(2023, time.March, 13, 0, 0, 0, 0, time.UTC)
  12. e := s.Add(timeutil.Day)
  13. // Set some basic numbers that can be used to asset accuracy later
  14. adjustment := -0.14
  15. bytes := 2183471523842.00
  16. cores := 2.78
  17. cost := 12.50
  18. gpus := 1.00
  19. // Test a normal allocation for numerical accuracy
  20. alloc := &Allocation{
  21. Name: "cluster/node/namespace/pod/alloc",
  22. Properties: &AllocationProperties{
  23. Cluster: "cluster",
  24. Node: "node",
  25. Namespace: "namespace",
  26. Pod: "pod",
  27. Container: "alloc",
  28. },
  29. CPUCoreHours: cores,
  30. CPUCoreRequestAverage: cores,
  31. CPUCoreUsageAverage: cores,
  32. CPUCost: cost,
  33. CPUCostAdjustment: adjustment,
  34. GPUHours: gpus,
  35. GPUCost: cost,
  36. GPUCostAdjustment: adjustment,
  37. NetworkTransferBytes: bytes,
  38. NetworkReceiveBytes: bytes,
  39. NetworkCost: cost,
  40. NetworkCrossZoneCost: cost,
  41. NetworkCrossRegionCost: cost,
  42. NetworkInternetCost: cost,
  43. NetworkCostAdjustment: adjustment,
  44. LoadBalancerCost: cost,
  45. LoadBalancerCostAdjustment: adjustment,
  46. PVs: PVAllocations{
  47. PVKey{Cluster: "cluster", Name: "pv"}: &PVAllocation{
  48. ByteHours: bytes,
  49. Cost: cost,
  50. },
  51. },
  52. PVCostAdjustment: adjustment,
  53. RAMByteHours: bytes,
  54. RAMBytesRequestAverage: bytes,
  55. RAMBytesUsageAverage: bytes,
  56. RAMCost: cost,
  57. RAMCostAdjustment: adjustment,
  58. SharedCost: cost,
  59. ExternalCost: cost,
  60. }
  61. // Test an allocation with NaN values for JSON marshal errors
  62. allocWithNaN := &Allocation{
  63. Name: "cluster/node/namespace/pod/nan",
  64. Properties: &AllocationProperties{
  65. Cluster: "cluster",
  66. Node: "node",
  67. Namespace: "namespace",
  68. Pod: "pod",
  69. Container: "nan",
  70. },
  71. CPUCoreHours: math.NaN(),
  72. CPUCoreRequestAverage: math.NaN(),
  73. CPUCoreUsageAverage: math.NaN(),
  74. CPUCost: math.NaN(),
  75. CPUCostAdjustment: math.NaN(),
  76. GPUHours: gpus,
  77. GPUCost: cost,
  78. GPUCostAdjustment: adjustment,
  79. NetworkTransferBytes: bytes,
  80. NetworkReceiveBytes: bytes,
  81. NetworkCost: cost,
  82. NetworkCrossZoneCost: cost,
  83. NetworkCrossRegionCost: cost,
  84. NetworkInternetCost: cost,
  85. NetworkCostAdjustment: adjustment,
  86. LoadBalancerCost: cost,
  87. LoadBalancerCostAdjustment: adjustment,
  88. PVs: PVAllocations{
  89. PVKey{Cluster: "cluster", Name: "pv"}: &PVAllocation{
  90. ByteHours: bytes,
  91. Cost: cost,
  92. },
  93. },
  94. PVCostAdjustment: adjustment,
  95. RAMByteHours: bytes,
  96. RAMBytesRequestAverage: bytes,
  97. RAMBytesUsageAverage: bytes,
  98. RAMCost: cost,
  99. RAMCostAdjustment: adjustment,
  100. SharedCost: cost,
  101. ExternalCost: cost,
  102. }
  103. // Convert to SummaryAllocationSetRange
  104. as := NewAllocationSet(s, e, alloc, allocWithNaN)
  105. sas := NewSummaryAllocationSet(as, nil, nil, true, true)
  106. sasr := NewSummaryAllocationSetRange(sas)
  107. // Confirm that SummaryAllocationSetRange does error because on NaN
  108. _, err := json.Marshal(sasr)
  109. if err == nil {
  110. t.Fatalf("expected NaN values to cause error")
  111. }
  112. // Convert to response
  113. sasrr := sasr.ToResponse()
  114. // Confirm that same SummaryAllocationSetRangeResponse does NOT error
  115. _, err = json.Marshal(sasrr)
  116. if err != nil {
  117. t.Fatalf("unexpected error: %v", err)
  118. }
  119. }