scraper_test.go 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. package scrape
  2. import (
  3. "testing"
  4. "github.com/stretchr/testify/assert"
  5. coreenv "github.com/opencost/opencost/core/pkg/env"
  6. "github.com/opencost/opencost/modules/collector-source/pkg/metric"
  7. )
  8. // staticScraper is a test double that returns a fixed set of updates.
  9. type staticScraper struct {
  10. updates []metric.Update
  11. }
  12. func (s *staticScraper) Scrape() []metric.Update { return s.updates }
  13. func updates(names ...string) []metric.Update {
  14. out := make([]metric.Update, len(names))
  15. for i, n := range names {
  16. out[i] = metric.Update{Name: n}
  17. }
  18. return out
  19. }
  20. func updateNames(us []metric.Update) []string {
  21. names := make([]string, len(us))
  22. for i, u := range us {
  23. names[i] = u.Name
  24. }
  25. return names
  26. }
  27. func TestWithFilter_EmptyFilterReturnsOriginalScraper(t *testing.T) {
  28. s := &staticScraper{}
  29. wrapped := withFilter(s, MetricFilter{})
  30. assert.Same(t, s, wrapped, "empty filter should return the original scraper unchanged")
  31. }
  32. func TestWithFilter_NilFilterReturnsOriginalScraper(t *testing.T) {
  33. s := &staticScraper{}
  34. wrapped := withFilter(s, nil)
  35. assert.Same(t, s, wrapped, "nil filter should return the original scraper unchanged")
  36. }
  37. func TestWithFilter_NonEmptyFilterWraps(t *testing.T) {
  38. s := &staticScraper{}
  39. f := MetricFilter{"some_metric": {}}
  40. wrapped := withFilter(s, f)
  41. _, isFiltered := wrapped.(*filteredScraper)
  42. assert.True(t, isFiltered, "non-empty filter should wrap in a filteredScraper")
  43. }
  44. func TestFilteredScraper_AllowsMetricsNotInFilter(t *testing.T) {
  45. s := &staticScraper{updates: updates("cpu_usage", "memory_usage")}
  46. f := MetricFilter{"kube_pod_annotations": {}}
  47. wrapped := withFilter(s, f)
  48. got := wrapped.Scrape()
  49. assert.Equal(t, []string{"cpu_usage", "memory_usage"}, updateNames(got))
  50. }
  51. func TestFilteredScraper_BlocksDeniedMetrics(t *testing.T) {
  52. s := &staticScraper{updates: updates("cpu_usage", metric.KubePodAnnotations, "memory_usage")}
  53. f := MetricFilter{metric.KubePodAnnotations: {}}
  54. wrapped := withFilter(s, f)
  55. got := wrapped.Scrape()
  56. assert.Equal(t, []string{"cpu_usage", "memory_usage"}, updateNames(got))
  57. }
  58. func TestFilteredScraper_BlocksMultipleDeniedMetrics(t *testing.T) {
  59. s := &staticScraper{updates: updates(
  60. metric.KubePodAnnotations,
  61. "cpu_usage",
  62. metric.KubeNamespaceAnnotations,
  63. "memory_usage",
  64. )}
  65. f := MetricFilter{
  66. metric.KubePodAnnotations: {},
  67. metric.KubeNamespaceAnnotations: {},
  68. }
  69. wrapped := withFilter(s, f)
  70. got := wrapped.Scrape()
  71. assert.Equal(t, []string{"cpu_usage", "memory_usage"}, updateNames(got))
  72. }
  73. func TestFilteredScraper_EmptyResultsPassThrough(t *testing.T) {
  74. s := &staticScraper{updates: []metric.Update{}}
  75. f := MetricFilter{metric.KubePodAnnotations: {}}
  76. wrapped := withFilter(s, f)
  77. got := wrapped.Scrape()
  78. assert.Empty(t, got)
  79. }
  80. func TestFilteredScraper_AllMetricsDenied(t *testing.T) {
  81. s := &staticScraper{updates: updates(metric.KubePodAnnotations, metric.KubeNamespaceAnnotations)}
  82. f := MetricFilter{
  83. metric.KubePodAnnotations: {},
  84. metric.KubeNamespaceAnnotations: {},
  85. }
  86. wrapped := withFilter(s, f)
  87. got := wrapped.Scrape()
  88. assert.Empty(t, got)
  89. }
  90. func TestGetDefaultMetricFilter_PodAnnotationsDisabled(t *testing.T) {
  91. t.Setenv(coreenv.EmitPodAnnotationsMetricEnvVar, "false")
  92. t.Setenv(coreenv.EmitNamespaceAnnotationsMetricEnvVar, "true")
  93. f := getDefaultMetricFilter()
  94. _, podDenied := f[metric.KubePodAnnotations]
  95. _, nsDenied := f[metric.KubeNamespaceAnnotations]
  96. assert.True(t, podDenied, "pod annotations should be denied when env var is false")
  97. assert.False(t, nsDenied, "namespace annotations should be allowed when env var is true")
  98. }
  99. func TestGetDefaultMetricFilter_NamespaceAnnotationsDisabled(t *testing.T) {
  100. t.Setenv(coreenv.EmitPodAnnotationsMetricEnvVar, "true")
  101. t.Setenv(coreenv.EmitNamespaceAnnotationsMetricEnvVar, "false")
  102. f := getDefaultMetricFilter()
  103. _, podDenied := f[metric.KubePodAnnotations]
  104. _, nsDenied := f[metric.KubeNamespaceAnnotations]
  105. assert.False(t, podDenied, "pod annotations should be allowed when env var is true")
  106. assert.True(t, nsDenied, "namespace annotations should be denied when env var is false")
  107. }
  108. func TestGetDefaultMetricFilter_BothDisabledByDefault(t *testing.T) {
  109. t.Setenv(coreenv.EmitPodAnnotationsMetricEnvVar, "")
  110. t.Setenv(coreenv.EmitNamespaceAnnotationsMetricEnvVar, "")
  111. f := getDefaultMetricFilter()
  112. _, podDenied := f[metric.KubePodAnnotations]
  113. _, nsDenied := f[metric.KubeNamespaceAnnotations]
  114. assert.True(t, podDenied, "pod annotations should be denied by default")
  115. assert.True(t, nsDenied, "namespace annotations should be denied by default")
  116. }
  117. func TestGetDefaultMetricFilter_AllEnabled(t *testing.T) {
  118. t.Setenv(coreenv.EmitPodAnnotationsMetricEnvVar, "true")
  119. t.Setenv(coreenv.EmitNamespaceAnnotationsMetricEnvVar, "true")
  120. t.Setenv(coreenv.EmitDeploymentLabelsMetricEnvVar, "true")
  121. t.Setenv(coreenv.EmitDeploymentAnnotationsMetricEnvVar, "true")
  122. t.Setenv(coreenv.EmitStatefulSetLabelsMetricEnvVar, "true")
  123. t.Setenv(coreenv.EmitStatefulSetAnnotationsMetricEnvVar, "true")
  124. t.Setenv(coreenv.EmitDaemonSetLabelsMetricEnvVar, "true")
  125. t.Setenv(coreenv.EmitDaemonSetAnnotationsMetricEnvVar, "true")
  126. t.Setenv(coreenv.EmitJobLabelsMetricEnvVar, "true")
  127. t.Setenv(coreenv.EmitJobAnnotationsMetricEnvVar, "true")
  128. t.Setenv(coreenv.EmitCronJobLabelsMetricEnvVar, "true")
  129. t.Setenv(coreenv.EmitCronJobAnnotationsMetricEnvVar, "true")
  130. t.Setenv(coreenv.EmitReplicaSetLabelsMetricEnvVar, "true")
  131. t.Setenv(coreenv.EmitReplicaSetAnnotationsMetricEnvVar, "true")
  132. f := getDefaultMetricFilter()
  133. assert.Empty(t, f, "filter should be empty when all metrics are enabled")
  134. }
  135. func TestGetDefaultMetricFilter_AnnotationsDefaultFalse(t *testing.T) {
  136. // Unset all env vars to exercise pure defaults.
  137. for _, v := range []string{
  138. coreenv.EmitPodAnnotationsMetricEnvVar,
  139. coreenv.EmitNamespaceAnnotationsMetricEnvVar,
  140. coreenv.EmitDeploymentAnnotationsMetricEnvVar,
  141. coreenv.EmitStatefulSetAnnotationsMetricEnvVar,
  142. coreenv.EmitDaemonSetAnnotationsMetricEnvVar,
  143. coreenv.EmitJobAnnotationsMetricEnvVar,
  144. coreenv.EmitCronJobAnnotationsMetricEnvVar,
  145. coreenv.EmitReplicaSetAnnotationsMetricEnvVar,
  146. } {
  147. t.Setenv(v, "")
  148. }
  149. f := getDefaultMetricFilter()
  150. for _, name := range []string{
  151. metric.KubePodAnnotations,
  152. metric.KubeNamespaceAnnotations,
  153. metric.DeploymentAnnotations,
  154. metric.StatefulSetAnnotations,
  155. metric.DaemonSetAnnotations,
  156. metric.JobAnnotations,
  157. metric.CronJobAnnotations,
  158. metric.ReplicaSetAnnotations,
  159. } {
  160. _, denied := f[name]
  161. assert.True(t, denied, "%s should be denied by default", name)
  162. }
  163. }
  164. func TestGetDefaultMetricFilter_LabelsDefaultTrue(t *testing.T) {
  165. // Unset all label env vars to exercise pure defaults.
  166. for _, v := range []string{
  167. coreenv.EmitDeploymentLabelsMetricEnvVar,
  168. coreenv.EmitStatefulSetLabelsMetricEnvVar,
  169. coreenv.EmitDaemonSetLabelsMetricEnvVar,
  170. coreenv.EmitJobLabelsMetricEnvVar,
  171. coreenv.EmitCronJobLabelsMetricEnvVar,
  172. coreenv.EmitReplicaSetLabelsMetricEnvVar,
  173. } {
  174. t.Setenv(v, "")
  175. }
  176. f := getDefaultMetricFilter()
  177. for _, name := range []string{
  178. metric.DeploymentLabels,
  179. metric.StatefulSetLabels,
  180. metric.DaemonSetLabels,
  181. metric.JobLabels,
  182. metric.CronJobLabels,
  183. metric.ReplicaSetLabels,
  184. } {
  185. _, denied := f[name]
  186. assert.False(t, denied, "%s should be allowed by default", name)
  187. }
  188. }