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  }