github.com/muhammadn/cortex@v1.9.1-0.20220510110439-46bb7000d03d/pkg/configs/userconfig/config_test.go (about)

     1  package userconfig
     2  
     3  import (
     4  	"encoding/json"
     5  	"strconv"
     6  	"strings"
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/go-kit/log"
    11  	"github.com/prometheus/common/model"
    12  	"github.com/prometheus/prometheus/pkg/labels"
    13  	"github.com/prometheus/prometheus/pkg/rulefmt"
    14  	"github.com/prometheus/prometheus/promql/parser"
    15  	"github.com/prometheus/prometheus/rules"
    16  	"github.com/stretchr/testify/assert"
    17  	"github.com/stretchr/testify/require"
    18  	"gopkg.in/yaml.v3"
    19  
    20  	util_log "github.com/cortexproject/cortex/pkg/util/log"
    21  )
    22  
    23  var legacyRulesFile = `ALERT TestAlert
    24  IF up == 0
    25  FOR 5m
    26  LABELS { severity = "critical" }
    27  ANNOTATIONS {
    28  	message = "I am a message"
    29  }`
    30  
    31  var ruleFile = `groups:
    32  - name: example
    33    rules:
    34    - alert: TestAlert
    35      expr: up == 0
    36      for: 5m
    37      labels:
    38        severity: critical
    39      annotations:
    40        message: I am a message`
    41  
    42  func TestUnmarshalJSONLegacyConfigWithMissingRuleFormatVersionSucceeds(t *testing.T) {
    43  	actual := Config{}
    44  	buf := []byte(`{"rules_files": {"a": "b"}}`)
    45  	assert.Nil(t, json.Unmarshal(buf, &actual))
    46  
    47  	expected := Config{
    48  		RulesConfig: RulesConfig{
    49  			Files: map[string]string{
    50  				"a": "b",
    51  			},
    52  			FormatVersion: RuleFormatV1,
    53  		},
    54  	}
    55  
    56  	assert.Equal(t, expected, actual)
    57  }
    58  
    59  func TestUnmarshalYAMLLegacyConfigWithMissingRuleFormatVersionSucceeds(t *testing.T) {
    60  	actual := Config{}
    61  	buf := []byte(strings.TrimSpace(`
    62  rule_format_version: '1'
    63  rules_files:
    64    a: b
    65  `))
    66  	assert.Nil(t, yaml.Unmarshal(buf, &actual))
    67  
    68  	expected := Config{
    69  		RulesConfig: RulesConfig{
    70  			Files: map[string]string{
    71  				"a": "b",
    72  			},
    73  			FormatVersion: RuleFormatV1,
    74  		},
    75  	}
    76  
    77  	assert.Equal(t, expected, actual)
    78  }
    79  
    80  func TestParseLegacyAlerts(t *testing.T) {
    81  	parsed, err := parser.ParseExpr("up == 0")
    82  	require.NoError(t, err)
    83  	rule := rules.NewAlertingRule(
    84  		"TestAlert",
    85  		parsed,
    86  		5*time.Minute,
    87  		labels.Labels{
    88  			labels.Label{Name: "severity", Value: "critical"},
    89  		},
    90  		labels.Labels{
    91  			labels.Label{Name: "message", Value: "I am a message"},
    92  		},
    93  		nil,
    94  		"",
    95  		true,
    96  		log.With(util_log.Logger, "alert", "TestAlert"),
    97  	)
    98  
    99  	for i, tc := range []struct {
   100  		cfg      RulesConfig
   101  		expected map[string][]rules.Rule
   102  	}{
   103  		{
   104  			cfg: RulesConfig{
   105  				FormatVersion: RuleFormatV1,
   106  				Files: map[string]string{
   107  					"legacy.rules": `
   108  		ALERT TestAlert
   109  		IF up == 0
   110  		FOR 5m
   111  		LABELS { severity = "critical" }
   112  		ANNOTATIONS {
   113  			message = "I am a message"
   114  		}
   115  		`,
   116  				},
   117  			},
   118  			expected: map[string][]rules.Rule{
   119  				"legacy.rules": {rule},
   120  			},
   121  		},
   122  		{
   123  			cfg: RulesConfig{
   124  				FormatVersion: RuleFormatV2,
   125  				Files: map[string]string{
   126  					"alerts.yaml": `
   127  groups:
   128  - name: example
   129    rules:
   130    - alert: TestAlert
   131      expr: up == 0
   132      for: 5m
   133      labels:
   134        severity: critical
   135      annotations:
   136        message: I am a message
   137  `,
   138  				},
   139  			},
   140  			expected: map[string][]rules.Rule{
   141  				"example;alerts.yaml": {rule},
   142  			},
   143  		},
   144  	} {
   145  		t.Run(strconv.Itoa(i), func(t *testing.T) {
   146  			rules, err := tc.cfg.Parse()
   147  			require.NoError(t, err)
   148  			require.Equal(t, tc.expected, rules)
   149  		})
   150  	}
   151  }
   152  
   153  func TestParseFormatted(t *testing.T) {
   154  	dur, err := model.ParseDuration("5m")
   155  	require.NoError(t, err)
   156  
   157  	rulesV1 := []rulefmt.RuleNode{
   158  		{
   159  			Alert: yaml.Node{Value: "TestAlert"},
   160  			Expr:  yaml.Node{Value: "up == 0"},
   161  			For:   dur,
   162  			Labels: map[string]string{
   163  				"severity": "critical",
   164  			},
   165  			Annotations: map[string]string{
   166  				"message": "I am a message",
   167  			},
   168  		},
   169  	}
   170  
   171  	alertNode := yaml.Node{Line: 4, Column: 12}
   172  	alertNode.SetString("TestAlert")
   173  	exprNode := yaml.Node{Line: 5, Column: 11}
   174  	exprNode.SetString("up == 0")
   175  	rulesV2 := []rulefmt.RuleNode{
   176  		{
   177  			Alert: alertNode,
   178  			Expr:  exprNode,
   179  			For:   dur,
   180  			Labels: map[string]string{
   181  				"severity": "critical",
   182  			},
   183  			Annotations: map[string]string{
   184  				"message": "I am a message",
   185  			},
   186  		},
   187  	}
   188  
   189  	for i, tc := range []struct {
   190  		cfg      RulesConfig
   191  		expected map[string]rulefmt.RuleGroups
   192  	}{
   193  		{
   194  			cfg: RulesConfig{
   195  				FormatVersion: RuleFormatV1,
   196  				Files: map[string]string{
   197  					"legacy.rules": legacyRulesFile,
   198  				},
   199  			},
   200  			expected: map[string]rulefmt.RuleGroups{
   201  				"legacy.rules": {
   202  					Groups: []rulefmt.RuleGroup{
   203  						{
   204  							Name:  "rg:legacy.rules",
   205  							Rules: rulesV1,
   206  						},
   207  					},
   208  				},
   209  			},
   210  		},
   211  		{
   212  			cfg: RulesConfig{
   213  				FormatVersion: RuleFormatV2,
   214  				Files: map[string]string{
   215  					"alerts.yaml": ruleFile,
   216  				},
   217  			},
   218  			expected: map[string]rulefmt.RuleGroups{
   219  				"alerts.yaml": {
   220  					Groups: []rulefmt.RuleGroup{
   221  						{
   222  							Name:  "example",
   223  							Rules: rulesV2,
   224  						},
   225  					},
   226  				},
   227  			},
   228  		},
   229  	} {
   230  		t.Run(strconv.Itoa(i), func(t *testing.T) {
   231  			rules, err := tc.cfg.ParseFormatted()
   232  			require.NoError(t, err)
   233  			require.Equal(t, tc.expected, rules)
   234  		})
   235  	}
   236  }