types_test.go 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. package customcost
  2. import (
  3. "testing"
  4. "github.com/opencost/opencost/core/pkg/model/pb"
  5. )
  6. func TestSortByCostAsc(t *testing.T) {
  7. ccs := &CustomCostSet{
  8. CustomCosts: []*CustomCost{
  9. {Cost: 300.0},
  10. {Cost: 100.0},
  11. {Cost: 200.0},
  12. },
  13. }
  14. ccs.Sort(SortPropertyCost, SortDirectionAsc)
  15. expected := []float32{100.0, 200.0, 300.0}
  16. for i, cc := range ccs.CustomCosts {
  17. if cc.Cost != expected[i] {
  18. t.Errorf("expected cost %f, got %f", expected[i], cc.Cost)
  19. }
  20. }
  21. }
  22. func TestSortByCostDesc(t *testing.T) {
  23. ccs := &CustomCostSet{
  24. CustomCosts: []*CustomCost{
  25. {Cost: 300.0},
  26. {Cost: 100.0},
  27. {Cost: 200.0},
  28. },
  29. }
  30. ccs.Sort(SortPropertyCost, SortDirectionDesc)
  31. expected := []float32{300.0, 200.0, 100.0}
  32. for i, cc := range ccs.CustomCosts {
  33. if cc.Cost != expected[i] {
  34. t.Errorf("expected cost %f, got %f", expected[i], cc.Cost)
  35. }
  36. }
  37. }
  38. func TestSortByAggregateAsc(t *testing.T) {
  39. ccs := &CustomCostSet{
  40. CustomCosts: []*CustomCost{
  41. {Aggregate: "c"},
  42. {Aggregate: "a"},
  43. {Aggregate: "b"},
  44. },
  45. }
  46. ccs.Sort(SortPropertyAggregate, SortDirectionAsc)
  47. expected := []string{"a", "b", "c"}
  48. for i, cc := range ccs.CustomCosts {
  49. if cc.Aggregate != expected[i] {
  50. t.Errorf("expected aggregate %s, got %s", expected[i], cc.Aggregate)
  51. }
  52. }
  53. }
  54. func TestSortByAggregateDesc(t *testing.T) {
  55. ccs := &CustomCostSet{
  56. CustomCosts: []*CustomCost{
  57. {Aggregate: "c"},
  58. {Aggregate: "a"},
  59. {Aggregate: "b"},
  60. },
  61. }
  62. ccs.Sort(SortPropertyAggregate, SortDirectionDesc)
  63. expected := []string{"c", "b", "a"}
  64. for i, cc := range ccs.CustomCosts {
  65. if cc.Aggregate != expected[i] {
  66. t.Errorf("expected aggregate %s, got %s", expected[i], cc.Aggregate)
  67. }
  68. }
  69. }
  70. func TestSortByCostTypeAsc(t *testing.T) {
  71. ccs := &CustomCostSet{
  72. CustomCosts: []*CustomCost{
  73. {CostType: CostTypeBilled},
  74. {CostType: CostTypeList},
  75. {CostType: CostTypeBlended},
  76. },
  77. }
  78. ccs.Sort(SortPropertyCostType, SortDirectionAsc)
  79. expected := []CostType{CostTypeBilled, CostTypeBlended, CostTypeList}
  80. for i, cc := range ccs.CustomCosts {
  81. if cc.CostType != expected[i] {
  82. t.Errorf("expected cost type %s, got %s", expected[i], cc.CostType)
  83. }
  84. }
  85. }
  86. func TestSortByCostTypeDesc(t *testing.T) {
  87. ccs := &CustomCostSet{
  88. CustomCosts: []*CustomCost{
  89. {CostType: CostTypeBilled},
  90. {CostType: CostTypeList},
  91. {CostType: CostTypeBlended},
  92. },
  93. }
  94. ccs.Sort(SortPropertyCostType, SortDirectionDesc)
  95. expected := []CostType{CostTypeList, CostTypeBlended, CostTypeBilled}
  96. for i, cc := range ccs.CustomCosts {
  97. if cc.CostType != expected[i] {
  98. t.Errorf("expected cost type %s, got %s", expected[i], cc.CostType)
  99. }
  100. }
  101. }
  102. func TestParseCustomCostResponse(t *testing.T) {
  103. tests := []struct {
  104. name string
  105. ccResponse *pb.CustomCostResponse
  106. costType CostType
  107. expected []*CustomCost
  108. }{
  109. {
  110. name: "BlendedCost",
  111. ccResponse: &pb.CustomCostResponse{
  112. Costs: []*pb.CustomCost{
  113. {
  114. Id: "1",
  115. Zone: "us-east-1a",
  116. AccountName: "account1",
  117. ChargeCategory: "category1",
  118. Description: "description1",
  119. ResourceName: "resource1",
  120. ResourceType: "type1",
  121. ProviderId: "provider1",
  122. BilledCost: 100.0,
  123. ListCost: 120.0,
  124. ListUnitPrice: 1.2,
  125. UsageQuantity: 100,
  126. UsageUnit: "unit1",
  127. },
  128. },
  129. Domain: "domain1",
  130. CostSource: "source1",
  131. },
  132. costType: CostTypeBlended,
  133. expected: []*CustomCost{
  134. {
  135. Id: "1",
  136. Zone: "us-east-1a",
  137. AccountName: "account1",
  138. ChargeCategory: "category1",
  139. Description: "description1",
  140. ResourceName: "resource1",
  141. ResourceType: "type1",
  142. ProviderId: "provider1",
  143. Cost: 100.0,
  144. ListUnitPrice: 1.2,
  145. UsageQuantity: 100,
  146. UsageUnit: "unit1",
  147. Domain: "domain1",
  148. CostSource: "source1",
  149. CostType: CostTypeBilled,
  150. },
  151. },
  152. },
  153. {
  154. name: "ListCost",
  155. ccResponse: &pb.CustomCostResponse{
  156. Costs: []*pb.CustomCost{
  157. {
  158. Id: "2",
  159. Zone: "us-west-2b",
  160. AccountName: "account2",
  161. ChargeCategory: "category2",
  162. Description: "description2",
  163. ResourceName: "resource2",
  164. ResourceType: "type2",
  165. ProviderId: "provider2",
  166. BilledCost: 0.0,
  167. ListCost: 150.0,
  168. ListUnitPrice: 1.5,
  169. UsageQuantity: 100,
  170. UsageUnit: "unit2",
  171. },
  172. },
  173. Domain: "domain2",
  174. CostSource: "source2",
  175. },
  176. costType: CostTypeList,
  177. expected: []*CustomCost{
  178. {
  179. Id: "2",
  180. Zone: "us-west-2b",
  181. AccountName: "account2",
  182. ChargeCategory: "category2",
  183. Description: "description2",
  184. ResourceName: "resource2",
  185. ResourceType: "type2",
  186. ProviderId: "provider2",
  187. Cost: 150.0,
  188. ListUnitPrice: 1.5,
  189. UsageQuantity: 100,
  190. UsageUnit: "unit2",
  191. Domain: "domain2",
  192. CostSource: "source2",
  193. CostType: CostTypeList,
  194. },
  195. },
  196. },
  197. {
  198. name: "ZeroCost",
  199. ccResponse: &pb.CustomCostResponse{
  200. Costs: []*pb.CustomCost{
  201. {
  202. Id: "3",
  203. Zone: "us-central-1c",
  204. AccountName: "account3",
  205. ChargeCategory: "category3",
  206. Description: "description3",
  207. ResourceName: "resource3",
  208. ResourceType: "type3",
  209. ProviderId: "provider3",
  210. BilledCost: 0.0,
  211. ListCost: 0.0,
  212. ListUnitPrice: 0.0,
  213. UsageQuantity: 0,
  214. UsageUnit: "unit3",
  215. },
  216. },
  217. Domain: "domain3",
  218. CostSource: "source3",
  219. },
  220. costType: CostTypeBlended,
  221. expected: []*CustomCost{},
  222. },
  223. {
  224. name: "Non Matching cost",
  225. ccResponse: &pb.CustomCostResponse{
  226. Costs: []*pb.CustomCost{
  227. {
  228. Id: "3",
  229. Zone: "us-central-1c",
  230. AccountName: "account3",
  231. ChargeCategory: "category3",
  232. Description: "description3",
  233. ResourceName: "resource3",
  234. ResourceType: "type3",
  235. ProviderId: "provider3",
  236. BilledCost: 0.0,
  237. ListCost: 1.0,
  238. ListUnitPrice: 0.0,
  239. UsageQuantity: 0,
  240. UsageUnit: "unit3",
  241. },
  242. },
  243. Domain: "domain3",
  244. CostSource: "source3",
  245. },
  246. costType: CostTypeBilled,
  247. expected: []*CustomCost{},
  248. },
  249. }
  250. for _, tt := range tests {
  251. t.Run(tt.name, func(t *testing.T) {
  252. result := ParseCustomCostResponse(tt.ccResponse, tt.costType)
  253. if len(result) != len(tt.expected) {
  254. t.Errorf("expected %d custom costs, got %d", len(tt.expected), len(result))
  255. }
  256. for i, expectedCost := range tt.expected {
  257. if result[i].Id != expectedCost.Id ||
  258. result[i].Zone != expectedCost.Zone ||
  259. result[i].AccountName != expectedCost.AccountName ||
  260. result[i].ChargeCategory != expectedCost.ChargeCategory ||
  261. result[i].Description != expectedCost.Description ||
  262. result[i].ResourceName != expectedCost.ResourceName ||
  263. result[i].ResourceType != expectedCost.ResourceType ||
  264. result[i].ProviderId != expectedCost.ProviderId ||
  265. result[i].Cost != expectedCost.Cost ||
  266. result[i].ListUnitPrice != expectedCost.ListUnitPrice ||
  267. result[i].UsageQuantity != expectedCost.UsageQuantity ||
  268. result[i].UsageUnit != expectedCost.UsageUnit ||
  269. result[i].Domain != expectedCost.Domain ||
  270. result[i].CostSource != expectedCost.CostSource ||
  271. result[i].CostType != expectedCost.CostType {
  272. t.Errorf("expected %+v, got %+v", expectedCost, result[i])
  273. }
  274. }
  275. })
  276. }
  277. }