namespacemetrics_test.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. package metrics
  2. import (
  3. "testing"
  4. "github.com/opencost/opencost/core/pkg/clustercache"
  5. "github.com/prometheus/client_golang/prometheus"
  6. dto "github.com/prometheus/client_model/go"
  7. "k8s.io/apimachinery/pkg/types"
  8. )
  9. type mockNamespaceCache struct {
  10. clustercache.ClusterCache
  11. namespaces []*clustercache.Namespace
  12. }
  13. func (m mockNamespaceCache) GetAllNamespaces() []*clustercache.Namespace {
  14. return m.namespaces
  15. }
  16. func TestKubecostNamespaceCollector_Collect(t *testing.T) {
  17. // Test with namespace that has annotations
  18. cache := mockNamespaceCache{
  19. namespaces: []*clustercache.Namespace{
  20. {
  21. Name: "test-ns",
  22. UID: types.UID("test-uid"),
  23. Annotations: map[string]string{"team": "backend"},
  24. },
  25. },
  26. }
  27. collector := KubecostNamespaceCollector{
  28. KubeClusterCache: cache,
  29. metricsConfig: MetricsConfig{},
  30. }
  31. ch := make(chan prometheus.Metric, 10)
  32. go func() {
  33. collector.Collect(ch)
  34. close(ch)
  35. }()
  36. count := 0
  37. for range ch {
  38. count++
  39. }
  40. if count != 1 {
  41. t.Errorf("Expected 1 metric, got %d", count)
  42. }
  43. }
  44. func TestKubeNamespaceCollector_Collect(t *testing.T) {
  45. // Test with namespace that has labels
  46. cache := mockNamespaceCache{
  47. namespaces: []*clustercache.Namespace{
  48. {
  49. Name: "test-ns",
  50. UID: types.UID("test-uid"),
  51. Labels: map[string]string{"env": "prod"},
  52. },
  53. },
  54. }
  55. collector := KubeNamespaceCollector{
  56. KubeClusterCache: cache,
  57. metricsConfig: MetricsConfig{},
  58. }
  59. ch := make(chan prometheus.Metric, 10)
  60. go func() {
  61. collector.Collect(ch)
  62. close(ch)
  63. }()
  64. count := 0
  65. for range ch {
  66. count++
  67. }
  68. if count != 1 {
  69. t.Errorf("Expected 1 metric, got %d", count)
  70. }
  71. }
  72. func TestNamespaceAnnotationsMetric_Write(t *testing.T) {
  73. metric := newNamespaceAnnotationsMetric(
  74. "test_metric",
  75. "test-ns",
  76. "test-uid",
  77. []string{"team"},
  78. []string{"backend"},
  79. )
  80. pbMetric := &dto.Metric{}
  81. err := metric.Write(pbMetric)
  82. if err != nil {
  83. t.Fatalf("Write failed: %v", err)
  84. }
  85. if pbMetric.Gauge == nil || *pbMetric.Gauge.Value != 1.0 {
  86. t.Error("Expected gauge value 1.0")
  87. }
  88. if len(pbMetric.Label) != 3 { // team + namespace + uid
  89. t.Errorf("Expected 3 labels, got %d", len(pbMetric.Label))
  90. }
  91. // Verify UID label exists and has correct value
  92. foundUID := false
  93. for _, label := range pbMetric.Label {
  94. if *label.Name == "uid" && *label.Value == "test-uid" {
  95. foundUID = true
  96. break
  97. }
  98. }
  99. if !foundUID {
  100. t.Error("Expected uid label with value 'test-uid' not found")
  101. }
  102. }
  103. func TestKubeNamespaceLabelsMetric_Write(t *testing.T) {
  104. metric := newKubeNamespaceLabelsMetric(
  105. "test_metric",
  106. "test-ns",
  107. "test-uid",
  108. []string{"env"},
  109. []string{"prod"},
  110. )
  111. pbMetric := &dto.Metric{}
  112. err := metric.Write(pbMetric)
  113. if err != nil {
  114. t.Fatalf("Write failed: %v", err)
  115. }
  116. if pbMetric.Gauge == nil || *pbMetric.Gauge.Value != 1.0 {
  117. t.Error("Expected gauge value 1.0")
  118. }
  119. if len(pbMetric.Label) != 3 { // env + namespace + uid
  120. t.Errorf("Expected 3 labels, got %d", len(pbMetric.Label))
  121. }
  122. // Verify UID label exists and has correct value
  123. foundUID := false
  124. for _, label := range pbMetric.Label {
  125. if *label.Name == "uid" && *label.Value == "test-uid" {
  126. foundUID = true
  127. break
  128. }
  129. }
  130. if !foundUID {
  131. t.Error("Expected uid label with value 'test-uid' not found")
  132. }
  133. }
  134. func TestKubecostNamespaceCollector_Describe(t *testing.T) {
  135. collector := KubecostNamespaceCollector{metricsConfig: MetricsConfig{}}
  136. ch := make(chan *prometheus.Desc, 1)
  137. go func() {
  138. collector.Describe(ch)
  139. close(ch)
  140. }()
  141. count := 0
  142. for range ch {
  143. count++
  144. }
  145. if count != 1 {
  146. t.Errorf("Expected 1 descriptor, got %d", count)
  147. }
  148. }
  149. func TestKubeNamespaceCollector_Describe(t *testing.T) {
  150. collector := KubeNamespaceCollector{metricsConfig: MetricsConfig{}}
  151. ch := make(chan *prometheus.Desc, 1)
  152. go func() {
  153. collector.Describe(ch)
  154. close(ch)
  155. }()
  156. count := 0
  157. for range ch {
  158. count++
  159. }
  160. if count != 1 {
  161. t.Errorf("Expected 1 descriptor, got %d", count)
  162. }
  163. }