persistentvolumeclaim_test.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. package kubemodel
  2. import (
  3. "testing"
  4. "time"
  5. "github.com/stretchr/testify/assert"
  6. "github.com/stretchr/testify/require"
  7. "github.com/opencost/opencost/core/pkg/model/kubemodel"
  8. "github.com/opencost/opencost/core/pkg/source"
  9. "github.com/opencost/opencost/core/pkg/util"
  10. )
  11. func TestComputePersistentVolumeClaims(t *testing.T) {
  12. start := time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC)
  13. end := start.Add(time.Hour)
  14. tests := []struct {
  15. name string
  16. overrides map[string]any
  17. want map[string]*kubemodel.PersistentVolumeClaim
  18. }{
  19. {
  20. name: "no data returns empty pvc map",
  21. overrides: map[string]any{},
  22. want: map[string]*kubemodel.PersistentVolumeClaim{},
  23. },
  24. {
  25. name: "basic pvc info and uptime",
  26. overrides: map[string]any{
  27. source.QueryKMPVCInfo: []*source.PVCInfoResult{
  28. {UID: "pvc-1", PersistentVolumeClaim: "data-claim", NamespaceUID: "ns-1"},
  29. },
  30. source.QueryPVCUptime: []*source.UptimeResult{
  31. {UID: "pvc-1", First: start, Last: end},
  32. },
  33. },
  34. want: map[string]*kubemodel.PersistentVolumeClaim{
  35. "pvc-1": {
  36. UID: "pvc-1",
  37. Name: "data-claim",
  38. NamespaceUID: "ns-1",
  39. Start: start,
  40. End: end,
  41. },
  42. },
  43. },
  44. {
  45. name: "pvc without uptime is not registered",
  46. overrides: map[string]any{
  47. source.QueryKMPVCInfo: []*source.PVCInfoResult{
  48. {UID: "pvc-1", PersistentVolumeClaim: "data-claim", NamespaceUID: "ns-1"},
  49. },
  50. },
  51. want: map[string]*kubemodel.PersistentVolumeClaim{},
  52. },
  53. {
  54. name: "pvc with pv uid and storage class",
  55. overrides: map[string]any{
  56. source.QueryKMPVCInfo: []*source.PVCInfoResult{
  57. {UID: "pvc-1", PersistentVolumeClaim: "data-claim", NamespaceUID: "ns-1", PVUID: "pv-1", StorageClass: "gp2"},
  58. },
  59. source.QueryPVCUptime: []*source.UptimeResult{
  60. {UID: "pvc-1", First: start, Last: end},
  61. },
  62. },
  63. want: map[string]*kubemodel.PersistentVolumeClaim{
  64. "pvc-1": {
  65. UID: "pvc-1",
  66. Name: "data-claim",
  67. NamespaceUID: "ns-1",
  68. PersistentVolumeUID: "pv-1",
  69. StorageClass: "gp2",
  70. Start: start,
  71. End: end,
  72. },
  73. },
  74. },
  75. {
  76. name: "pvc requested bytes and usage are populated",
  77. overrides: map[string]any{
  78. source.QueryKMPVCInfo: []*source.PVCInfoResult{
  79. {UID: "pvc-1", PersistentVolumeClaim: "data-claim", NamespaceUID: "ns-1"},
  80. },
  81. source.QueryPVCUptime: []*source.UptimeResult{
  82. {UID: "pvc-1", First: start, Last: end},
  83. },
  84. source.QueryPVCBytesRequested: []*source.PVCBytesRequestedResult{
  85. {UID: "pvc-1", Data: []*util.Vector{{Value: 5 * 1024 * 1024 * 1024}}},
  86. },
  87. source.QueryPVCBytesUsedAverage: []*source.PVCUIDValueResult{
  88. {UID: "pvc-1", Value: 2 * 1024 * 1024 * 1024},
  89. },
  90. source.QueryPVCBytesUsedMax: []*source.PVCUIDValueResult{
  91. {UID: "pvc-1", Value: 4 * 1024 * 1024 * 1024},
  92. },
  93. },
  94. want: map[string]*kubemodel.PersistentVolumeClaim{
  95. "pvc-1": {
  96. UID: "pvc-1",
  97. Name: "data-claim",
  98. NamespaceUID: "ns-1",
  99. Start: start,
  100. End: end,
  101. RequestedBytes: 5 * 1024 * 1024 * 1024,
  102. UsageBytesAvg: 2 * 1024 * 1024 * 1024,
  103. UsageBytesMax: 4 * 1024 * 1024 * 1024,
  104. },
  105. },
  106. },
  107. {
  108. name: "bytes for unknown pvc are ignored",
  109. overrides: map[string]any{
  110. source.QueryKMPVCInfo: []*source.PVCInfoResult{
  111. {UID: "pvc-1", PersistentVolumeClaim: "data-claim", NamespaceUID: "ns-1"},
  112. },
  113. source.QueryPVCUptime: []*source.UptimeResult{
  114. {UID: "pvc-1", First: start, Last: end},
  115. },
  116. source.QueryPVCBytesUsedAverage: []*source.PVCUIDValueResult{
  117. {UID: "unknown-pvc", Value: 999},
  118. },
  119. },
  120. want: map[string]*kubemodel.PersistentVolumeClaim{
  121. "pvc-1": {
  122. UID: "pvc-1",
  123. Name: "data-claim",
  124. NamespaceUID: "ns-1",
  125. Start: start,
  126. End: end,
  127. },
  128. },
  129. },
  130. }
  131. for _, tt := range tests {
  132. t.Run(tt.name, func(t *testing.T) {
  133. ds := source.NewMockOpenCostDataSource()
  134. ds.ResolutionValue = 5 * time.Minute
  135. seedCluster(ds, start, end)
  136. for method, result := range tt.overrides {
  137. ds.Querier.SetOverride(method, result)
  138. }
  139. km, err := NewKubeModel(testClusterUID, false, ds)
  140. require.NoError(t, err)
  141. kms, err := km.ComputeKubeModelSet(start, end)
  142. require.NoError(t, err)
  143. assert.Equal(t, tt.want, kms.PersistentVolumeClaims)
  144. })
  145. }
  146. }