func TestHandlerRelabel(t *testing.T) { h := New(&Options{ QueueCapacity: 3 * maxBatchSize, RelabelConfigs: []*config.RelabelConfig{ { SourceLabels: model.LabelNames{"alertname"}, Action: "drop", Regex: config.MustNewRegexp("drop"), }, { SourceLabels: model.LabelNames{"alertname"}, TargetLabel: "alertname", Action: "replace", Regex: config.MustNewRegexp("rename"), Replacement: "renamed", }, }, }) // This alert should be dropped due to the configuration h.Send(&model.Alert{ Labels: model.LabelSet{ "alertname": "drop", }, }) // This alert should be replaced due to the configuration h.Send(&model.Alert{ Labels: model.LabelSet{ "alertname": "rename", }, }) expected := []*model.Alert{ { Labels: model.LabelSet{ "alertname": "renamed", }, }, } if !alertsEqual(expected, h.queue) { t.Errorf("Expected alerts %v, got %v", expected, h.queue) } }
func TestExternalLabels(t *testing.T) { h := New(&Options{ QueueCapacity: 3 * maxBatchSize, ExternalLabels: model.LabelSet{"a": "b"}, RelabelConfigs: []*config.RelabelConfig{ { SourceLabels: model.LabelNames{"alertname"}, TargetLabel: "a", Action: "replace", Regex: config.MustNewRegexp("externalrelabelthis"), Replacement: "c", }, }, }) // This alert should get the external label attached. h.Send(&model.Alert{ Labels: model.LabelSet{ "alertname": "test", }, }) // This alert should get the external label attached, but then set to "c" // through relabelling. h.Send(&model.Alert{ Labels: model.LabelSet{ "alertname": "externalrelabelthis", }, }) expected := []*model.Alert{ { Labels: model.LabelSet{ "alertname": "test", "a": "b", }, }, { Labels: model.LabelSet{ "alertname": "externalrelabelthis", "a": "c", }, }, } if !alertsEqual(expected, h.queue) { t.Errorf("Expected alerts %v, got %v", expected, h.queue) } }
func TestTargetManagerConfigUpdate(t *testing.T) { testJob1 := &config.ScrapeConfig{ JobName: "test_job1", ScrapeInterval: config.Duration(1 * time.Minute), Params: url.Values{ "testParam": []string{"paramValue", "secondValue"}, }, TargetGroups: []*config.TargetGroup{{ Targets: []model.LabelSet{ {model.AddressLabel: "example.org:80"}, {model.AddressLabel: "example.com:80"}, }, }}, RelabelConfigs: []*config.RelabelConfig{ { // Copy out the URL parameter. SourceLabels: model.LabelNames{"__param_testParam"}, Regex: config.MustNewRegexp("(.*)"), TargetLabel: "testParam", Replacement: "$1", Action: config.RelabelReplace, }, }, } testJob2 := &config.ScrapeConfig{ JobName: "test_job2", ScrapeInterval: config.Duration(1 * time.Minute), TargetGroups: []*config.TargetGroup{ { Targets: []model.LabelSet{ {model.AddressLabel: "example.org:8080"}, {model.AddressLabel: "example.com:8081"}, }, Labels: model.LabelSet{ "foo": "bar", "boom": "box", }, }, { Targets: []model.LabelSet{ {model.AddressLabel: "test.com:1234"}, }, }, { Targets: []model.LabelSet{ {model.AddressLabel: "test.com:1235"}, }, Labels: model.LabelSet{"instance": "fixed"}, }, }, RelabelConfigs: []*config.RelabelConfig{ { SourceLabels: model.LabelNames{model.AddressLabel}, Regex: config.MustNewRegexp(`test\.(.*?):(.*)`), Replacement: "foo.${1}:${2}", TargetLabel: model.AddressLabel, Action: config.RelabelReplace, }, { // Add a new label for example.* targets. SourceLabels: model.LabelNames{model.AddressLabel, "boom", "foo"}, Regex: config.MustNewRegexp("example.*?-b([a-z-]+)r"), TargetLabel: "new", Replacement: "$1", Separator: "-", Action: config.RelabelReplace, }, { // Drop an existing label. SourceLabels: model.LabelNames{"boom"}, Regex: config.MustNewRegexp(".*"), TargetLabel: "boom", Replacement: "", Action: config.RelabelReplace, }, }, } sequence := []struct { scrapeConfigs []*config.ScrapeConfig expected map[string][]model.LabelSet }{ { scrapeConfigs: []*config.ScrapeConfig{testJob1}, expected: map[string][]model.LabelSet{ "test_job1:static:0:0": { {model.JobLabel: "test_job1", model.InstanceLabel: "example.org:80", "testParam": "paramValue", model.SchemeLabel: "", model.MetricsPathLabel: "", model.AddressLabel: "example.org:80", model.ParamLabelPrefix + "testParam": "paramValue"}, {model.JobLabel: "test_job1", model.InstanceLabel: "example.com:80", "testParam": "paramValue", model.SchemeLabel: "", model.MetricsPathLabel: "", model.AddressLabel: "example.com:80", model.ParamLabelPrefix + "testParam": "paramValue"}, }, }, }, { scrapeConfigs: []*config.ScrapeConfig{testJob1}, expected: map[string][]model.LabelSet{ "test_job1:static:0:0": { {model.JobLabel: "test_job1", model.InstanceLabel: "example.org:80", "testParam": "paramValue", model.SchemeLabel: "", model.MetricsPathLabel: "", model.AddressLabel: "example.org:80", model.ParamLabelPrefix + "testParam": "paramValue"}, {model.JobLabel: "test_job1", model.InstanceLabel: "example.com:80", "testParam": "paramValue", model.SchemeLabel: "", model.MetricsPathLabel: "", model.AddressLabel: "example.com:80", model.ParamLabelPrefix + "testParam": "paramValue"}, }, }, }, { scrapeConfigs: []*config.ScrapeConfig{testJob1, testJob2}, expected: map[string][]model.LabelSet{ "test_job1:static:0:0": { {model.JobLabel: "test_job1", model.InstanceLabel: "example.org:80", "testParam": "paramValue", model.SchemeLabel: "", model.MetricsPathLabel: "", model.AddressLabel: "example.org:80", model.ParamLabelPrefix + "testParam": "paramValue"}, {model.JobLabel: "test_job1", model.InstanceLabel: "example.com:80", "testParam": "paramValue", model.SchemeLabel: "", model.MetricsPathLabel: "", model.AddressLabel: "example.com:80", model.ParamLabelPrefix + "testParam": "paramValue"}, }, "test_job2:static:0:0": { {model.JobLabel: "test_job2", model.InstanceLabel: "example.org:8080", "foo": "bar", "new": "ox-ba", model.SchemeLabel: "", model.MetricsPathLabel: "", model.AddressLabel: "example.org:8080"}, {model.JobLabel: "test_job2", model.InstanceLabel: "example.com:8081", "foo": "bar", "new": "ox-ba", model.SchemeLabel: "", model.MetricsPathLabel: "", model.AddressLabel: "example.com:8081"}, }, "test_job2:static:0:1": { {model.JobLabel: "test_job2", model.InstanceLabel: "foo.com:1234", model.SchemeLabel: "", model.MetricsPathLabel: "", model.AddressLabel: "foo.com:1234"}, }, "test_job2:static:0:2": { {model.JobLabel: "test_job2", model.InstanceLabel: "fixed", model.SchemeLabel: "", model.MetricsPathLabel: "", model.AddressLabel: "foo.com:1235"}, }, }, }, { scrapeConfigs: []*config.ScrapeConfig{}, expected: map[string][]model.LabelSet{}, }, { scrapeConfigs: []*config.ScrapeConfig{testJob2}, expected: map[string][]model.LabelSet{ "test_job2:static:0:0": { {model.JobLabel: "test_job2", model.InstanceLabel: "example.org:8080", "foo": "bar", "new": "ox-ba", model.SchemeLabel: "", model.MetricsPathLabel: "", model.AddressLabel: "example.org:8080"}, {model.JobLabel: "test_job2", model.InstanceLabel: "example.com:8081", "foo": "bar", "new": "ox-ba", model.SchemeLabel: "", model.MetricsPathLabel: "", model.AddressLabel: "example.com:8081"}, }, "test_job2:static:0:1": { {model.JobLabel: "test_job2", model.InstanceLabel: "foo.com:1234", model.SchemeLabel: "", model.MetricsPathLabel: "", model.AddressLabel: "foo.com:1234"}, }, "test_job2:static:0:2": { {model.JobLabel: "test_job2", model.InstanceLabel: "fixed", model.SchemeLabel: "", model.MetricsPathLabel: "", model.AddressLabel: "foo.com:1235"}, }, }, }, } conf := &config.Config{} *conf = config.DefaultConfig targetManager := NewTargetManager(nopAppender{}) targetManager.ApplyConfig(conf) targetManager.Run() defer targetManager.Stop() for i, step := range sequence { conf.ScrapeConfigs = step.scrapeConfigs targetManager.ApplyConfig(conf) time.Sleep(50 * time.Millisecond) if len(targetManager.targets) != len(step.expected) { t.Fatalf("step %d: sources mismatch: expected %v, got %v", i, step.expected, targetManager.targets) } for source, actTargets := range targetManager.targets { expTargets, ok := step.expected[source] if !ok { t.Fatalf("step %d: unexpected source %q: %v", i, source, actTargets) } for _, expt := range expTargets { found := false for _, actt := range actTargets { if reflect.DeepEqual(expt, actt.fullLabels()) { found = true break } } if !found { t.Errorf("step %d: expected target %v for %q not found in actual targets", i, expt, source) } } } } }
func TestTargetScrapeMetricRelabelConfigs(t *testing.T) { server := httptest.NewServer( http.HandlerFunc( func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", `text/plain; version=0.0.4`) w.Write([]byte("test_metric_drop 0\n")) w.Write([]byte("test_metric_relabel 1\n")) }, ), ) defer server.Close() testTarget := newTestTarget(server.URL, 10*time.Millisecond, model.LabelSet{}) testTarget.metricRelabelConfigs = []*config.RelabelConfig{ { SourceLabels: model.LabelNames{"__name__"}, Regex: config.MustNewRegexp(".*drop.*"), Action: config.RelabelDrop, }, { SourceLabels: model.LabelNames{"__name__"}, Regex: config.MustNewRegexp(".*(relabel|up).*"), TargetLabel: "foo", Replacement: "bar", Action: config.RelabelReplace, }, } appender := &collectResultAppender{} testTarget.scrape(appender) // Remove variables part of result. for _, sample := range appender.result { sample.Timestamp = 0 sample.Value = 0 } expected := []*model.Sample{ { Metric: model.Metric{ model.MetricNameLabel: "test_metric_relabel", "foo": "bar", model.InstanceLabel: model.LabelValue(testTarget.url.Host), }, Timestamp: 0, Value: 0, }, // The metrics about the scrape are not affected. { Metric: model.Metric{ model.MetricNameLabel: scrapeHealthMetricName, model.InstanceLabel: model.LabelValue(testTarget.url.Host), }, Timestamp: 0, Value: 0, }, { Metric: model.Metric{ model.MetricNameLabel: scrapeDurationMetricName, model.InstanceLabel: model.LabelValue(testTarget.url.Host), }, Timestamp: 0, Value: 0, }, } if !appender.result.Equal(expected) { t.Fatalf("Expected and actual samples not equal. Expected: %s, actual: %s", expected, appender.result) } }
func TestRelabel(t *testing.T) { tests := []struct { input model.LabelSet relabel []*config.RelabelConfig output model.LabelSet }{ { input: model.LabelSet{ "a": "foo", "b": "bar", "c": "baz", }, relabel: []*config.RelabelConfig{ { SourceLabels: model.LabelNames{"a"}, Regex: config.MustNewRegexp("f(.*)"), TargetLabel: model.LabelName("d"), Separator: ";", Replacement: "ch${1}-ch${1}", Action: config.RelabelReplace, }, }, output: model.LabelSet{ "a": "foo", "b": "bar", "c": "baz", "d": "choo-choo", }, }, { input: model.LabelSet{ "a": "foo", "b": "bar", "c": "baz", }, relabel: []*config.RelabelConfig{ { SourceLabels: model.LabelNames{"a", "b"}, Regex: config.MustNewRegexp("f(.*);(.*)r"), TargetLabel: model.LabelName("a"), Separator: ";", Replacement: "b${1}${2}m", // boobam Action: config.RelabelReplace, }, { SourceLabels: model.LabelNames{"c", "a"}, Regex: config.MustNewRegexp("(b).*b(.*)ba(.*)"), TargetLabel: model.LabelName("d"), Separator: ";", Replacement: "$1$2$2$3", Action: config.RelabelReplace, }, }, output: model.LabelSet{ "a": "boobam", "b": "bar", "c": "baz", "d": "boooom", }, }, { input: model.LabelSet{ "a": "foo", }, relabel: []*config.RelabelConfig{ { SourceLabels: model.LabelNames{"a"}, Regex: config.MustNewRegexp(".*o.*"), Action: config.RelabelDrop, }, { SourceLabels: model.LabelNames{"a"}, Regex: config.MustNewRegexp("f(.*)"), TargetLabel: model.LabelName("d"), Separator: ";", Replacement: "ch$1-ch$1", Action: config.RelabelReplace, }, }, output: nil, }, { input: model.LabelSet{ "a": "abc", }, relabel: []*config.RelabelConfig{ { SourceLabels: model.LabelNames{"a"}, Regex: config.MustNewRegexp(".*(b).*"), TargetLabel: model.LabelName("d"), Separator: ";", Replacement: "$1", Action: config.RelabelReplace, }, }, output: model.LabelSet{ "a": "abc", "d": "b", }, }, { input: model.LabelSet{ "a": "foo", }, relabel: []*config.RelabelConfig{ { SourceLabels: model.LabelNames{"a"}, Regex: config.MustNewRegexp("no-match"), Action: config.RelabelDrop, }, }, output: model.LabelSet{ "a": "foo", }, }, { input: model.LabelSet{ "a": "foo", }, relabel: []*config.RelabelConfig{ { SourceLabels: model.LabelNames{"a"}, Regex: config.MustNewRegexp("f|o"), Action: config.RelabelDrop, }, }, output: model.LabelSet{ "a": "foo", }, }, { input: model.LabelSet{ "a": "foo", }, relabel: []*config.RelabelConfig{ { SourceLabels: model.LabelNames{"a"}, Regex: config.MustNewRegexp("no-match"), Action: config.RelabelKeep, }, }, output: nil, }, { input: model.LabelSet{ "a": "foo", }, relabel: []*config.RelabelConfig{ { SourceLabels: model.LabelNames{"a"}, Regex: config.MustNewRegexp("f.*"), Action: config.RelabelKeep, }, }, output: model.LabelSet{ "a": "foo", }, }, { // No replacement must be applied if there is no match. input: model.LabelSet{ "a": "boo", }, relabel: []*config.RelabelConfig{ { SourceLabels: model.LabelNames{"a"}, Regex: config.MustNewRegexp("f"), TargetLabel: model.LabelName("b"), Replacement: "bar", Action: config.RelabelReplace, }, }, output: model.LabelSet{ "a": "boo", }, }, { input: model.LabelSet{ "a": "foo", "b": "bar", "c": "baz", }, relabel: []*config.RelabelConfig{ { SourceLabels: model.LabelNames{"c"}, TargetLabel: model.LabelName("d"), Separator: ";", Action: config.RelabelHashMod, Modulus: 1000, }, }, output: model.LabelSet{ "a": "foo", "b": "bar", "c": "baz", "d": "976", }, }, { input: model.LabelSet{ "a": "foo", "b1": "bar", "b2": "baz", }, relabel: []*config.RelabelConfig{ { Regex: config.MustNewRegexp("(b.*)"), Replacement: "bar_${1}", Action: config.RelabelLabelMap, }, }, output: model.LabelSet{ "a": "foo", "b1": "bar", "b2": "baz", "bar_b1": "bar", "bar_b2": "baz", }, }, { input: model.LabelSet{ "a": "foo", "__meta_my_bar": "aaa", "__meta_my_baz": "bbb", "__meta_other": "ccc", }, relabel: []*config.RelabelConfig{ { Regex: config.MustNewRegexp("__meta_(my.*)"), Replacement: "${1}", Action: config.RelabelLabelMap, }, }, output: model.LabelSet{ "a": "foo", "__meta_my_bar": "aaa", "__meta_my_baz": "bbb", "__meta_other": "ccc", "my_bar": "aaa", "my_baz": "bbb", }, }, } for i, test := range tests { res, err := Relabel(test.input, test.relabel...) if err != nil { t.Errorf("Test %d: error relabeling: %s", i+1, err) } if !reflect.DeepEqual(res, test.output) { t.Errorf("Test %d: relabel output mismatch: expected %#v, got %#v", i+1, test.output, res) } } }
func TestRelabel(t *testing.T) { tests := []struct { input model.LabelSet relabel []*config.RelabelConfig output model.LabelSet }{ { input: model.LabelSet{ "a": "foo", "b": "bar", "c": "baz", }, relabel: []*config.RelabelConfig{ { SourceLabels: model.LabelNames{"a"}, Regex: config.MustNewRegexp("f(.*)"), TargetLabel: "d", Separator: ";", Replacement: "ch${1}-ch${1}", Action: config.RelabelReplace, }, }, output: model.LabelSet{ "a": "foo", "b": "bar", "c": "baz", "d": "choo-choo", }, }, { input: model.LabelSet{ "a": "foo", "b": "bar", "c": "baz", }, relabel: []*config.RelabelConfig{ { SourceLabels: model.LabelNames{"a", "b"}, Regex: config.MustNewRegexp("f(.*);(.*)r"), TargetLabel: "a", Separator: ";", Replacement: "b${1}${2}m", // boobam Action: config.RelabelReplace, }, { SourceLabels: model.LabelNames{"c", "a"}, Regex: config.MustNewRegexp("(b).*b(.*)ba(.*)"), TargetLabel: "d", Separator: ";", Replacement: "$1$2$2$3", Action: config.RelabelReplace, }, }, output: model.LabelSet{ "a": "boobam", "b": "bar", "c": "baz", "d": "boooom", }, }, { input: model.LabelSet{ "a": "foo", }, relabel: []*config.RelabelConfig{ { SourceLabels: model.LabelNames{"a"}, Regex: config.MustNewRegexp(".*o.*"), Action: config.RelabelDrop, }, { SourceLabels: model.LabelNames{"a"}, Regex: config.MustNewRegexp("f(.*)"), TargetLabel: "d", Separator: ";", Replacement: "ch$1-ch$1", Action: config.RelabelReplace, }, }, output: nil, }, { input: model.LabelSet{ "a": "foo", "b": "bar", }, relabel: []*config.RelabelConfig{ { SourceLabels: model.LabelNames{"a"}, Regex: config.MustNewRegexp(".*o.*"), Action: config.RelabelDrop, }, }, output: nil, }, { input: model.LabelSet{ "a": "abc", }, relabel: []*config.RelabelConfig{ { SourceLabels: model.LabelNames{"a"}, Regex: config.MustNewRegexp(".*(b).*"), TargetLabel: "d", Separator: ";", Replacement: "$1", Action: config.RelabelReplace, }, }, output: model.LabelSet{ "a": "abc", "d": "b", }, }, { input: model.LabelSet{ "a": "foo", }, relabel: []*config.RelabelConfig{ { SourceLabels: model.LabelNames{"a"}, Regex: config.MustNewRegexp("no-match"), Action: config.RelabelDrop, }, }, output: model.LabelSet{ "a": "foo", }, }, { input: model.LabelSet{ "a": "foo", }, relabel: []*config.RelabelConfig{ { SourceLabels: model.LabelNames{"a"}, Regex: config.MustNewRegexp("f|o"), Action: config.RelabelDrop, }, }, output: model.LabelSet{ "a": "foo", }, }, { input: model.LabelSet{ "a": "foo", }, relabel: []*config.RelabelConfig{ { SourceLabels: model.LabelNames{"a"}, Regex: config.MustNewRegexp("no-match"), Action: config.RelabelKeep, }, }, output: nil, }, { input: model.LabelSet{ "a": "foo", }, relabel: []*config.RelabelConfig{ { SourceLabels: model.LabelNames{"a"}, Regex: config.MustNewRegexp("f.*"), Action: config.RelabelKeep, }, }, output: model.LabelSet{ "a": "foo", }, }, { // No replacement must be applied if there is no match. input: model.LabelSet{ "a": "boo", }, relabel: []*config.RelabelConfig{ { SourceLabels: model.LabelNames{"a"}, Regex: config.MustNewRegexp("f"), TargetLabel: "b", Replacement: "bar", Action: config.RelabelReplace, }, }, output: model.LabelSet{ "a": "boo", }, }, { input: model.LabelSet{ "a": "foo", "b": "bar", "c": "baz", }, relabel: []*config.RelabelConfig{ { SourceLabels: model.LabelNames{"c"}, TargetLabel: "d", Separator: ";", Action: config.RelabelHashMod, Modulus: 1000, }, }, output: model.LabelSet{ "a": "foo", "b": "bar", "c": "baz", "d": "976", }, }, { input: model.LabelSet{ "a": "foo", "b1": "bar", "b2": "baz", }, relabel: []*config.RelabelConfig{ { Regex: config.MustNewRegexp("(b.*)"), Replacement: "bar_${1}", Action: config.RelabelLabelMap, }, }, output: model.LabelSet{ "a": "foo", "b1": "bar", "b2": "baz", "bar_b1": "bar", "bar_b2": "baz", }, }, { input: model.LabelSet{ "a": "foo", "__meta_my_bar": "aaa", "__meta_my_baz": "bbb", "__meta_other": "ccc", }, relabel: []*config.RelabelConfig{ { Regex: config.MustNewRegexp("__meta_(my.*)"), Replacement: "${1}", Action: config.RelabelLabelMap, }, }, output: model.LabelSet{ "a": "foo", "__meta_my_bar": "aaa", "__meta_my_baz": "bbb", "__meta_other": "ccc", "my_bar": "aaa", "my_baz": "bbb", }, }, { // valid case input: model.LabelSet{ "a": "some-name-value", }, relabel: []*config.RelabelConfig{ { SourceLabels: model.LabelNames{"a"}, Regex: config.MustNewRegexp("some-([^-]+)-([^,]+)"), Action: config.RelabelReplace, Replacement: "${2}", TargetLabel: "${1}", }, }, output: model.LabelSet{ "a": "some-name-value", "name": "value", }, }, { // invalid replacement "" input: model.LabelSet{ "a": "some-name-value", }, relabel: []*config.RelabelConfig{ { SourceLabels: model.LabelNames{"a"}, Regex: config.MustNewRegexp("some-([^-]+)-([^,]+)"), Action: config.RelabelReplace, Replacement: "${3}", TargetLabel: "${1}", }, }, output: model.LabelSet{ "a": "some-name-value", }, }, { // invalid target_labels input: model.LabelSet{ "a": "some-name-value", }, relabel: []*config.RelabelConfig{ { SourceLabels: model.LabelNames{"a"}, Regex: config.MustNewRegexp("some-([^-]+)-([^,]+)"), Action: config.RelabelReplace, Replacement: "${1}", TargetLabel: "${3}", }, { SourceLabels: model.LabelNames{"a"}, Regex: config.MustNewRegexp("some-([^-]+)-([^,]+)"), Action: config.RelabelReplace, Replacement: "${1}", TargetLabel: "0${3}", }, { SourceLabels: model.LabelNames{"a"}, Regex: config.MustNewRegexp("some-([^-]+)-([^,]+)"), Action: config.RelabelReplace, Replacement: "${1}", TargetLabel: "-${3}", }, }, output: model.LabelSet{ "a": "some-name-value", }, }, { // more complex real-life like usecase input: model.LabelSet{ "__meta_sd_tags": "path:/secret,job:some-job,label:foo=bar", }, relabel: []*config.RelabelConfig{ { SourceLabels: model.LabelNames{"__meta_sd_tags"}, Regex: config.MustNewRegexp("(?:.+,|^)path:(/[^,]+).*"), Action: config.RelabelReplace, Replacement: "${1}", TargetLabel: "__metrics_path__", }, { SourceLabels: model.LabelNames{"__meta_sd_tags"}, Regex: config.MustNewRegexp("(?:.+,|^)job:([^,]+).*"), Action: config.RelabelReplace, Replacement: "${1}", TargetLabel: "job", }, { SourceLabels: model.LabelNames{"__meta_sd_tags"}, Regex: config.MustNewRegexp("(?:.+,|^)label:([^=]+)=([^,]+).*"), Action: config.RelabelReplace, Replacement: "${2}", TargetLabel: "${1}", }, }, output: model.LabelSet{ "__meta_sd_tags": "path:/secret,job:some-job,label:foo=bar", "__metrics_path__": "/secret", "job": "some-job", "foo": "bar", }, }, { input: model.LabelSet{ "a": "foo", "b1": "bar", "b2": "baz", }, relabel: []*config.RelabelConfig{ { Regex: config.MustNewRegexp("(b.*)"), Action: config.RelabelLabelKeep, }, }, output: model.LabelSet{ "b1": "bar", "b2": "baz", }, }, { input: model.LabelSet{ "a": "foo", "b1": "bar", "b2": "baz", }, relabel: []*config.RelabelConfig{ { Regex: config.MustNewRegexp("(b.*)"), Action: config.RelabelLabelDrop, }, }, output: model.LabelSet{ "a": "foo", }, }, } for i, test := range tests { res := Process(test.input, test.relabel...) if !reflect.DeepEqual(res, test.output) { t.Errorf("Test %d: relabel output mismatch: expected %#v, got %#v", i+1, test.output, res) } } }