github.com/verrazzano/verrazzano@v1.7.0/pkg/metricsutils/edit_scrapeconfig_test.go (about) 1 // Copyright (c) 2022, Oracle and/or its affiliates. 2 // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 3 4 package metricsutils 5 6 import ( 7 "os" 8 "testing" 9 10 "github.com/Jeffail/gabs/v2" 11 "github.com/stretchr/testify/assert" 12 "github.com/verrazzano/verrazzano/pkg/constants" 13 ) 14 15 const newJobName = "newjob" 16 const existingJobName = "prometheus" 17 const newScrapeJob = constants.PrometheusJobNameKey + `: ` + newJobName + ` 18 kubernetes_sd_configs: 19 - role: endpoints 20 relabel_configs: 21 - action: keep 22 regex: node-exporter 23 source_labels: 24 - __meta_kubernetes_endpoints_name 25 scrape_interval: 20s 26 scrape_timeout: 15s 27 ` 28 29 const replaceExistingScrapeJob = constants.PrometheusJobNameKey + `: ` + existingJobName + ` 30 scrape_interval: 20s 31 scrape_timeout: 15s 32 static_configs: 33 - targets: 34 - localhost:9191 35 ` 36 37 // TestEditScrapeJob tests the editing of a list of scrape configs (in the format expected in 38 // a Prometheus config map's "scrape_configs" section or additionalScrapeConfigs secret) 39 // GIVEN an updated scrape config job and its name 40 // WHEN the function is called 41 // THEN the scrape config job should be either added to the scrape configs list, or updated if a 42 // 43 // job with that name already exists. 44 func TestEditScrapeJob(t *testing.T) { 45 tests := []struct { 46 name string 47 editJobName string 48 editConfigData string 49 expectAdd bool // true if new job should be added, false if it's an existing job 50 expectRemove bool // true if existing job should be removed 51 }{ 52 {"add new job", newJobName, newScrapeJob, true, false}, 53 {"edit existing job", existingJobName, replaceExistingScrapeJob, false, false}, 54 {"remove job", existingJobName, "", false, true}, 55 } 56 for _, tt := range tests { 57 t.Run(tt.name, func(t *testing.T) { 58 scrapejobsBytes, err := os.ReadFile("testdata/scrapejobs.yaml") 59 if err != nil { 60 t.Errorf("Failed to read test scrape jobs file: %v", err) 61 } 62 63 newScrapeConfig, err := ParseScrapeConfig(tt.editConfigData) 64 if err != nil { 65 t.Errorf("Failed to parse the scrape config for job %s: %v", tt.editJobName, err) 66 } 67 68 scrapejobs, err := ParseScrapeConfig(string(scrapejobsBytes)) 69 if err != nil { 70 t.Errorf("Failed to parse the scrape jobs from test data: %v", err) 71 } 72 origNumScrapeJobs := len(scrapejobs.Children()) 73 updatedScrapeJobs, err := EditScrapeJob(scrapejobs, tt.editJobName, newScrapeConfig) 74 assert.Nil(t, err) 75 assertScrapeJobs(t, updatedScrapeJobs, newScrapeConfig, origNumScrapeJobs, tt.editJobName, tt.expectAdd, tt.expectRemove) 76 }) 77 } 78 } 79 80 // TestEditScrapeJobInPrometheusConfig tests the editing of a full Prometheus configuration (in the format expected in 81 // a Prometheus config map's "prometheus.yaml" field) 82 // GIVEN an updated scrape config job and its name 83 // WHEN the function is called 84 // THEN the scrape config job should be either added to the scrape configs list, or updated if a 85 // 86 // job with that name already exists. 87 func TestEditScrapeJobInPrometheusConfig(t *testing.T) { 88 tests := []struct { 89 name string 90 editJobName string 91 editConfigData string 92 expectAdd bool // true if new job should be added, false if it's an existing job 93 expectRemove bool // true if existing job should be removed 94 }{ 95 {"add new job", newJobName, newScrapeJob, true, false}, 96 {"edit existing job", existingJobName, replaceExistingScrapeJob, false, false}, 97 {"remove job", existingJobName, "", false, true}, 98 } 99 for _, tt := range tests { 100 t.Run(tt.name, func(t *testing.T) { 101 promConfigBytes, err := os.ReadFile("testdata/fullPromConfig.yaml") 102 if err != nil { 103 t.Errorf("Failed to read test scrape jobs file: %v", err) 104 } 105 106 newScrapeConfig, err := ParseScrapeConfig(tt.editConfigData) 107 if err != nil { 108 t.Errorf("Failed to parse the scrape config for job %s: %v", tt.editJobName, err) 109 } 110 111 promConfig, err := ParseScrapeConfig(string(promConfigBytes)) 112 if err != nil { 113 t.Errorf("Failed to parse the test prometheus config data: %v", err) 114 } 115 scrapejobs := promConfig.Search("scrape_configs") 116 origNumScrapeJobs := len(scrapejobs.Children()) 117 err = EditScrapeJobInPrometheusConfig(promConfig, "scrape_configs", tt.editJobName, newScrapeConfig) 118 assert.Nil(t, err) 119 updatedScrapeJobs := promConfig.Search("scrape_configs") 120 assertScrapeJobs(t, updatedScrapeJobs, newScrapeConfig, origNumScrapeJobs, tt.editJobName, tt.expectAdd, tt.expectRemove) 121 }) 122 } 123 } 124 125 func assertScrapeJobs(t *testing.T, updatedScrapeJobs *gabs.Container, newScrapeConfig *gabs.Container, origNumScrapeJobs int, jobName string, expectAdd bool, expectRemove bool) { 126 foundJobIndex := FindScrapeJob(updatedScrapeJobs, jobName) 127 if expectAdd { 128 // should have been added as a new job 129 assert.Equal(t, origNumScrapeJobs+1, len(updatedScrapeJobs.Children())) 130 } else if expectRemove { 131 // should have been removed 132 assert.Equal(t, origNumScrapeJobs-1, len(updatedScrapeJobs.Children())) 133 assert.Less(t, foundJobIndex, 0) 134 // nothing more to assert for remove case 135 return 136 } else { 137 // should have edited an existing job 138 assert.Equal(t, origNumScrapeJobs, len(updatedScrapeJobs.Children())) 139 } 140 // for cases other than removal, scrape config job should exist and be equal to the updated value 141 assert.GreaterOrEqual(t, foundJobIndex, 0) 142 assert.Equal(t, newScrapeConfig, updatedScrapeJobs.Children()[foundJobIndex]) 143 144 }