Пример #1
0
func AppendSampleAsPureSparseAppendTests(p metric.Persistence, t test.Tester) {
	appendSample := func(x int) (success bool) {
		v := clientmodel.SampleValue(x)
		ts := clientmodel.TimestampFromUnix(int64(x))
		labelName := clientmodel.LabelName(x)
		labelValue := clientmodel.LabelValue(x)
		l := clientmodel.Metric{labelName: labelValue}

		sample := &clientmodel.Sample{
			Value:     v,
			Timestamp: ts,
			Metric:    l,
		}

		err := p.AppendSamples(clientmodel.Samples{sample})

		success = err == nil
		if !success {
			t.Error(err)
		}

		return
	}

	if err := quick.Check(appendSample, nil); err != nil {
		t.Error(err)
	}
}
Пример #2
0
func AppendRepeatingValuesTests(p metric.Persistence, t test.Tester) {
	m := clientmodel.Metric{
		clientmodel.MetricNameLabel: "errors_total",
		"controller":                "foo",
		"operation":                 "bar",
	}

	increments := 10
	repetitions := 500

	for i := 0; i < increments; i++ {
		for j := 0; j < repetitions; j++ {
			time := clientmodel.Timestamp(0).Add(time.Duration(i) * time.Hour).Add(time.Duration(j) * time.Second)
			testAppendSamples(p, &clientmodel.Sample{
				Value:     clientmodel.SampleValue(i),
				Timestamp: time,
				Metric:    m,
			}, t)
		}
	}

	v, ok := p.(metric.View)
	if !ok {
		// It's purely a benchmark for a Persistence that is not viewable.
		return
	}

	matchers := labelMatchersFromLabelSet(clientmodel.LabelSet{
		clientmodel.MetricNameLabel: "errors_total",
		"controller":                "foo",
		"operation":                 "bar",
	})

	for i := 0; i < increments; i++ {
		for j := 0; j < repetitions; j++ {
			fingerprints, err := p.GetFingerprintsForLabelMatchers(matchers)
			if err != nil {
				t.Fatal(err)
			}
			if len(fingerprints) != 1 {
				t.Fatalf("expected %d fingerprints, got %d", 1, len(fingerprints))
			}

			time := clientmodel.Timestamp(0).Add(time.Duration(i) * time.Hour).Add(time.Duration(j) * time.Second)
			samples := v.GetValueAtTime(fingerprints[0], time)
			if len(samples) == 0 {
				t.Fatal("expected at least one sample.")
			}

			expected := clientmodel.SampleValue(i)

			for _, sample := range samples {
				if sample.Value != expected {
					t.Fatalf("expected %v value, got %v", expected, sample.Value)
				}
			}
		}
	}
}
Пример #3
0
func storeMatrix(storage metric.Persistence, matrix ast.Matrix) (err error) {
	pendingSamples := clientmodel.Samples{}
	for _, sampleSet := range matrix {
		for _, sample := range sampleSet.Values {
			pendingSamples = append(pendingSamples, &clientmodel.Sample{
				Metric:    sampleSet.Metric,
				Value:     sample.Value,
				Timestamp: sample.Timestamp,
			})
		}
	}
	err = storage.AppendSamples(pendingSamples)
	return
}
Пример #4
0
func ReadEmptyTests(p metric.Persistence, t test.Tester) {
	hasLabelPair := func(x int) (success bool) {
		fingerprints, err := p.GetFingerprintsForLabelMatchers(metric.LabelMatchers{{
			Type:  metric.Equal,
			Name:  clientmodel.LabelName(string(x)),
			Value: clientmodel.LabelValue(string(x)),
		}})
		if err != nil {
			t.Error(err)
			return
		}

		success = len(fingerprints) == 0
		if !success {
			t.Errorf("unexpected fingerprint length %d, got %d", 0, len(fingerprints))
		}

		return
	}

	err := quick.Check(hasLabelPair, nil)
	if err != nil {
		t.Error(err)
		return
	}

	hasLabelName := func(x int) (success bool) {
		labelName := clientmodel.LabelName(string(x))

		values, err := p.GetLabelValuesForLabelName(labelName)
		if err != nil {
			t.Error(err)
			return
		}

		success = len(values) == 0
		if !success {
			t.Errorf("unexpected values length %d, got %d", 0, len(values))
		}

		return
	}

	err = quick.Check(hasLabelName, nil)
	if err != nil {
		t.Error(err)
		return
	}
}
Пример #5
0
func AppendSampleAsPureSingleEntityAppendTests(p metric.Persistence, t test.Tester) {
	appendSample := func(x int) bool {
		sample := &clientmodel.Sample{
			Value:     clientmodel.SampleValue(x),
			Timestamp: clientmodel.TimestampFromUnix(int64(x)),
			Metric:    clientmodel.Metric{clientmodel.MetricNameLabel: "my_metric"},
		}

		err := p.AppendSamples(clientmodel.Samples{sample})

		return err == nil
	}

	if err := quick.Check(appendSample, nil); err != nil {
		t.Error(err)
	}
}
Пример #6
0
func GetLabelValuesForLabelNameTests(p metric.Persistence, t test.Tester) {
	testAppendSamples(p, &clientmodel.Sample{
		Value:     0,
		Timestamp: 0,
		Metric: clientmodel.Metric{
			clientmodel.MetricNameLabel: "my_metric",
			"request_type":              "create",
			"result":                    "success",
		},
	}, t)

	testAppendSamples(p, &clientmodel.Sample{
		Value:     0,
		Timestamp: 0,
		Metric: clientmodel.Metric{
			clientmodel.MetricNameLabel: "my_metric",
			"request_type":              "delete",
			"outcome":                   "failure",
		},
	}, t)

	expectedIndex := map[clientmodel.LabelName]clientmodel.LabelValues{
		clientmodel.MetricNameLabel: {"my_metric"},
		"request_type":              {"create", "delete"},
		"result":                    {"success"},
		"outcome":                   {"failure"},
	}

	for name, expected := range expectedIndex {
		actual, err := p.GetLabelValuesForLabelName(name)
		if err != nil {
			t.Fatalf("Error getting values for label %s: %v", name, err)
		}
		if len(actual) != len(expected) {
			t.Fatalf("Number of values don't match for label %s: got %d; want %d", name, len(actual), len(expected))
		}
		for i := range expected {
			if actual[i] != expected[i] {
				t.Fatalf("%d. Got %s; want %s", i, actual[i], expected[i])
			}
		}
	}
}
Пример #7
0
func GetFingerprintsForLabelSetUsesAndForLabelMatchingTests(p metric.Persistence, t test.Tester) {
	metrics := []clientmodel.LabelSet{
		{clientmodel.MetricNameLabel: "request_metrics_latency_equal_tallying_microseconds", "instance": "http://localhost:9090/metrics.json", "percentile": "0.010000"},
		{clientmodel.MetricNameLabel: "requests_metrics_latency_equal_accumulating_microseconds", "instance": "http://localhost:9090/metrics.json", "percentile": "0.010000"},
		{clientmodel.MetricNameLabel: "requests_metrics_latency_logarithmic_accumulating_microseconds", "instance": "http://localhost:9090/metrics.json", "percentile": "0.010000"},
		{clientmodel.MetricNameLabel: "requests_metrics_latency_logarithmic_tallying_microseconds", "instance": "http://localhost:9090/metrics.json", "percentile": "0.010000"},
		{clientmodel.MetricNameLabel: "targets_healthy_scrape_latency_ms", "instance": "http://localhost:9090/metrics.json", "percentile": "0.010000"},
	}

	for _, metric := range metrics {
		m := clientmodel.Metric{}

		for k, v := range metric {
			m[clientmodel.LabelName(k)] = clientmodel.LabelValue(v)
		}

		testAppendSamples(p, &clientmodel.Sample{
			Value:     clientmodel.SampleValue(0.0),
			Timestamp: clientmodel.Now(),
			Metric:    m,
		}, t)
	}

	labelSet := clientmodel.LabelSet{
		clientmodel.MetricNameLabel: "targets_healthy_scrape_latency_ms",
		"percentile":                "0.010000",
	}

	fingerprints, err := p.GetFingerprintsForLabelMatchers(labelMatchersFromLabelSet(labelSet))
	if err != nil {
		t.Errorf("could not get labels: %s", err)
	}

	if len(fingerprints) != 1 {
		t.Errorf("did not get a single metric as is expected, got %s", fingerprints)
	}
}
Пример #8
0
func AppendSampleAsSparseAppendWithReadsTests(p metric.Persistence, t test.Tester) {
	appendSample := func(x int) (success bool) {
		v := clientmodel.SampleValue(x)
		ts := clientmodel.TimestampFromUnix(int64(x))
		labelName := clientmodel.LabelName(x)
		labelValue := clientmodel.LabelValue(x)
		l := clientmodel.Metric{labelName: labelValue}

		sample := &clientmodel.Sample{
			Value:     v,
			Timestamp: ts,
			Metric:    l,
		}

		err := p.AppendSamples(clientmodel.Samples{sample})
		if err != nil {
			t.Error(err)
			return
		}

		values, err := p.GetLabelValuesForLabelName(labelName)
		if err != nil {
			t.Error(err)
			return
		}
		if len(values) != 1 {
			t.Errorf("expected label values count of %d, got %d", 1, len(values))
			return
		}

		fingerprints, err := p.GetFingerprintsForLabelMatchers(metric.LabelMatchers{{
			Type:  metric.Equal,
			Name:  labelName,
			Value: labelValue,
		}})
		if err != nil {
			t.Error(err)
			return
		}
		if len(fingerprints) != 1 {
			t.Errorf("expected fingerprint count of %d, got %d", 1, len(fingerprints))
			return
		}

		return true
	}

	if err := quick.Check(appendSample, nil); err != nil {
		t.Error(err)
	}
}
Пример #9
0
func GetFingerprintsForLabelSetTests(p metric.Persistence, t test.Tester) {
	metrics := []clientmodel.Metric{
		{
			clientmodel.MetricNameLabel: "test_metric",
			"method":                    "get",
			"result":                    "success",
		},
		{
			clientmodel.MetricNameLabel: "test_metric",
			"method":                    "get",
			"result":                    "failure",
		},
		{
			clientmodel.MetricNameLabel: "test_metric",
			"method":                    "post",
			"result":                    "success",
		},
		{
			clientmodel.MetricNameLabel: "test_metric",
			"method":                    "post",
			"result":                    "failure",
		},
	}

	newTestLabelMatcher := func(matchType metric.MatchType, name clientmodel.LabelName, value clientmodel.LabelValue) *metric.LabelMatcher {
		m, err := metric.NewLabelMatcher(matchType, name, value)
		if err != nil {
			t.Fatalf("Couldn't create label matcher: %v", err)
		}
		return m
	}

	scenarios := []struct {
		in         metric.LabelMatchers
		outIndexes []int
	}{
		{
			in: metric.LabelMatchers{
				newTestLabelMatcher(metric.Equal, clientmodel.MetricNameLabel, "test_metric"),
			},
			outIndexes: []int{0, 1, 2, 3},
		},
		{
			in: metric.LabelMatchers{
				newTestLabelMatcher(metric.Equal, clientmodel.MetricNameLabel, "non_existent_metric"),
			},
			outIndexes: []int{},
		},
		{
			in: metric.LabelMatchers{
				newTestLabelMatcher(metric.Equal, clientmodel.MetricNameLabel, "non_existent_metric"),
				newTestLabelMatcher(metric.Equal, "result", "success"),
			},
			outIndexes: []int{},
		},
		{
			in: metric.LabelMatchers{
				newTestLabelMatcher(metric.Equal, clientmodel.MetricNameLabel, "test_metric"),
				newTestLabelMatcher(metric.Equal, "result", "success"),
			},
			outIndexes: []int{0, 2},
		},
		{
			in: metric.LabelMatchers{
				newTestLabelMatcher(metric.Equal, clientmodel.MetricNameLabel, "test_metric"),
				newTestLabelMatcher(metric.NotEqual, "result", "success"),
			},
			outIndexes: []int{1, 3},
		},
		{
			in: metric.LabelMatchers{
				newTestLabelMatcher(metric.Equal, clientmodel.MetricNameLabel, "test_metric"),
				newTestLabelMatcher(metric.RegexMatch, "result", "foo|success|bar"),
			},
			outIndexes: []int{0, 2},
		},
		{
			in: metric.LabelMatchers{
				newTestLabelMatcher(metric.Equal, clientmodel.MetricNameLabel, "test_metric"),
				newTestLabelMatcher(metric.RegexNoMatch, "result", "foo|success|bar"),
			},
			outIndexes: []int{1, 3},
		},
		{
			in: metric.LabelMatchers{
				newTestLabelMatcher(metric.Equal, clientmodel.MetricNameLabel, "test_metric"),
				newTestLabelMatcher(metric.RegexNoMatch, "result", "foo|success|bar"),
				newTestLabelMatcher(metric.RegexMatch, "method", "os"),
			},
			outIndexes: []int{3},
		},
	}

	for _, m := range metrics {
		testAppendSamples(p, &clientmodel.Sample{
			Value:     0,
			Timestamp: 0,
			Metric:    m,
		}, t)
	}

	for i, s := range scenarios {
		actualFps, err := p.GetFingerprintsForLabelMatchers(s.in)
		if err != nil {
			t.Fatalf("%d. Couldn't get fingerprints for label matchers: %v", i, err)
		}

		expectedFps := clientmodel.Fingerprints{}
		for _, i := range s.outIndexes {
			fp := &clientmodel.Fingerprint{}
			fp.LoadFromMetric(metrics[i])
			expectedFps = append(expectedFps, fp)
		}

		sort.Sort(actualFps)
		sort.Sort(expectedFps)

		if len(actualFps) != len(expectedFps) {
			t.Fatalf("%d. Got %d fingerprints; want %d", i, len(actualFps), len(expectedFps))
		}

		for j, actualFp := range actualFps {
			if !actualFp.Equal(expectedFps[j]) {
				t.Fatalf("%d.%d. Got fingerprint %v; want %v", i, j, actualFp, expectedFps[j])
			}
		}
	}
}
Пример #10
0
func GetMetricForFingerprintTests(p metric.Persistence, t test.Tester) {
	testAppendSamples(p, &clientmodel.Sample{
		Value:     0,
		Timestamp: 0,
		Metric: clientmodel.Metric{
			"request_type": "your_mom",
		},
	}, t)

	testAppendSamples(p, &clientmodel.Sample{
		Value:     0,
		Timestamp: 0,
		Metric: clientmodel.Metric{
			"request_type": "your_dad",
			"one-off":      "value",
		},
	}, t)

	result, err := p.GetFingerprintsForLabelMatchers(metric.LabelMatchers{{
		Type:  metric.Equal,
		Name:  "request_type",
		Value: "your_mom",
	}})

	if err != nil {
		t.Error(err)
	}

	if len(result) != 1 {
		t.Errorf("Expected one element.")
	}

	m, err := p.GetMetricForFingerprint(result[0])
	if err != nil {
		t.Error(err)
	}

	if m == nil {
		t.Fatal("Did not expect nil.")
	}

	if len(m) != 1 {
		t.Errorf("Expected one-dimensional metric.")
	}

	if m["request_type"] != "your_mom" {
		t.Errorf("Expected metric to match.")
	}

	result, err = p.GetFingerprintsForLabelMatchers(metric.LabelMatchers{{
		Type:  metric.Equal,
		Name:  "request_type",
		Value: "your_dad",
	}})

	if err != nil {
		t.Error(err)
	}

	if len(result) != 1 {
		t.Errorf("Expected one element.")
	}

	m, err = p.GetMetricForFingerprint(result[0])

	if m == nil {
		t.Fatal("Did not expect nil.")
	}

	if err != nil {
		t.Error(err)
	}

	if len(m) != 2 {
		t.Errorf("Expected two-dimensional metric.")
	}

	if m["request_type"] != "your_dad" {
		t.Errorf("Expected metric to match.")
	}

	if m["one-off"] != "value" {
		t.Errorf("Expected metric to match.")
	}

	// Verify that mutating a returned metric does not result in the mutated
	// metric to be returned at the next GetMetricForFingerprint() call.
	m["one-off"] = "new value"
	m, err = p.GetMetricForFingerprint(result[0])

	if m == nil {
		t.Fatal("Did not expect nil.")
	}

	if err != nil {
		t.Error(err)
	}

	if len(m) != 2 {
		t.Errorf("Expected two-dimensional metric.")
	}

	if m["request_type"] != "your_dad" {
		t.Errorf("Expected metric to match.")
	}

	if m["one-off"] != "value" {
		t.Errorf("Expected metric to match.")
	}
}
Пример #11
0
func testAppendSamples(p metric.Persistence, s *clientmodel.Sample, t test.Tester) {
	err := p.AppendSamples(clientmodel.Samples{s})
	if err != nil {
		t.Fatal(err)
	}
}