func AppendSampleAsPureSparseAppendTests(p MetricPersistence, t test.Tester) { appendSample := func(x int) (success bool) { v := model.SampleValue(x) ts := time.Unix(int64(x), int64(x)) labelName := model.LabelName(x) labelValue := model.LabelValue(x) l := model.Metric{labelName: labelValue} sample := model.Sample{ Value: v, Timestamp: ts, Metric: l, } err := p.AppendSample(sample) success = err == nil if !success { t.Error(err) } return } if err := quick.Check(appendSample, nil); err != nil { t.Error(err) } }
func AppendSampleAsPureSingleEntityAppendTests(p MetricPersistence, t test.Tester) { appendSample := func(x int) bool { sample := model.Sample{ Value: model.SampleValue(x), Timestamp: time.Unix(int64(x), 0), Metric: model.Metric{model.MetricNameLabel: "my_metric"}, } err := p.AppendSample(sample) return err == nil } if err := quick.Check(appendSample, nil); err != nil { t.Error(err) } }
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) } }
func ReadEmptyTests(p MetricPersistence, t test.Tester) { hasLabelPair := func(x int) (success bool) { name := model.LabelName(string(x)) value := model.LabelValue(string(x)) labelSet := model.LabelSet{ name: value, } fingerprints, err := p.GetFingerprintsForLabelSet(labelSet) 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 := model.LabelName(string(x)) fingerprints, err := p.GetFingerprintsForLabelName(labelName) 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(hasLabelName, nil) if err != nil { t.Error(err) return } }
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) } }
func AppendSampleAsSparseAppendWithReadsTests(p MetricPersistence, t test.Tester) { appendSample := func(x int) (success bool) { v := model.SampleValue(x) ts := time.Unix(int64(x), int64(x)) labelName := model.LabelName(x) labelValue := model.LabelValue(x) l := model.Metric{labelName: labelValue} sample := model.Sample{ Value: v, Timestamp: ts, Metric: l, } err := p.AppendSample(sample) if err != nil { t.Error(err) return } fingerprints, err := p.GetFingerprintsForLabelName(labelName) if err != nil { t.Error(err) return } if len(fingerprints) != 1 { t.Errorf("expected fingerprint count of %d, got %d", 1, len(fingerprints)) return } fingerprints, err = p.GetFingerprintsForLabelSet(model.LabelSet{ labelName: 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) } }
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 } }
func GetFingerprintsForLabelSetTests(p MetricPersistence, t test.Tester) { testAppendSample(p, model.Sample{ Value: 0, Timestamp: time.Time{}, Metric: model.Metric{ model.MetricNameLabel: "my_metric", "request_type": "your_mom", }, }, t) testAppendSample(p, model.Sample{ Value: 0, Timestamp: time.Time{}, Metric: model.Metric{ model.MetricNameLabel: "my_metric", "request_type": "your_dad", }, }, t) result, err := p.GetFingerprintsForLabelSet(model.LabelSet{ model.MetricNameLabel: model.LabelValue("my_metric"), }) if err != nil { t.Error(err) } if len(result) != 2 { t.Errorf("Expected two elements.") } result, err = p.GetFingerprintsForLabelSet(model.LabelSet{ model.LabelName("request_type"): model.LabelValue("your_mom"), }) if err != nil { t.Error(err) } if len(result) != 1 { t.Errorf("Expected one element.") } result, err = p.GetFingerprintsForLabelSet(model.LabelSet{ model.LabelName("request_type"): model.LabelValue("your_dad"), }) if err != nil { t.Error(err) } if len(result) != 1 { t.Errorf("Expected one element.") } }
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.") } }
func testBuilder(t test.Tester) { type atTime struct { fingerprint string time clientmodel.Timestamp } type atInterval struct { fingerprint string from clientmodel.Timestamp through clientmodel.Timestamp interval time.Duration } type atRange struct { fingerprint string from clientmodel.Timestamp through clientmodel.Timestamp } type in struct { atTimes []atTime atIntervals []atInterval atRanges []atRange } type out []struct { fingerprint string operations ops } var scenarios = []struct { in in out out }{ // Ensure that the fingerprint is sorted in proper order. { in: in{ atTimes: []atTime{ { fingerprint: "0000000000000001111-a-4-a", time: clientmodel.TimestampFromUnix(100), }, { fingerprint: "0000000000000000000-a-4-a", time: clientmodel.TimestampFromUnix(100), }, }, }, out: out{ { fingerprint: "00000000000000000000-a-4-a", }, { fingerprint: "00000000000000001111-a-4-a", }, }, }, // // Ensure that the fingerprint-timestamp pairs are sorted in proper order. { in: in{ atTimes: []atTime{ { fingerprint: "1111-a-4-a", time: clientmodel.TimestampFromUnix(100), }, { fingerprint: "1111-a-4-a", time: clientmodel.TimestampFromUnix(200), }, { fingerprint: "0-a-4-a", time: clientmodel.TimestampFromUnix(100), }, { fingerprint: "0-a-4-a", time: clientmodel.TimestampFromUnix(0), }, }, }, out: out{ { fingerprint: "00000000000000000000-a-4-a", }, { fingerprint: "00000000000000000000-a-4-a", }, { fingerprint: "00000000000000001111-a-4-a", }, { fingerprint: "00000000000000001111-a-4-a", }, }, }, // Ensure grouping of operations { in: in{ atTimes: []atTime{ { fingerprint: "1111-a-4-a", time: clientmodel.TimestampFromUnix(100), }, }, atRanges: []atRange{ { fingerprint: "1111-a-4-a", from: clientmodel.TimestampFromUnix(100), through: clientmodel.TimestampFromUnix(1000), }, { fingerprint: "1111-a-4-a", from: clientmodel.TimestampFromUnix(100), through: clientmodel.TimestampFromUnix(9000), }, }, }, out: out{ { fingerprint: "00000000000000001111-a-4-a", }, { fingerprint: "00000000000000001111-a-4-a", }, { fingerprint: "00000000000000001111-a-4-a", }, }, }, } for i, scenario := range scenarios { builder := &viewRequestBuilder{} for _, atTime := range scenario.in.atTimes { fingerprint := &clientmodel.Fingerprint{} fingerprint.LoadFromString(atTime.fingerprint) builder.GetMetricAtTime(fingerprint, atTime.time) } for _, atInterval := range scenario.in.atIntervals { fingerprint := &clientmodel.Fingerprint{} fingerprint.LoadFromString(atInterval.fingerprint) builder.GetMetricAtInterval(fingerprint, atInterval.from, atInterval.through, atInterval.interval) } for _, atRange := range scenario.in.atRanges { fingerprint := &clientmodel.Fingerprint{} fingerprint.LoadFromString(atRange.fingerprint) builder.GetMetricRange(fingerprint, atRange.from, atRange.through) } for j, job := range scenario.out { got := builder.PopOp() if got.Fingerprint().String() != job.fingerprint { t.Errorf("%d.%d. expected fingerprint %s, got %s", i, j, job.fingerprint, got.Fingerprint()) } } if builder.HasOp() { t.Error("Expected builder to have no scan jobs left.") } } }
func GetFingerprintsForLabelNameTests(p MetricPersistence, t test.Tester) { testAppendSample(p, model.Sample{ Value: 0, Timestamp: time.Time{}, Metric: model.Metric{ model.MetricNameLabel: "my_metric", "request_type": "your_mom", "language": "english", }, }, t) testAppendSample(p, model.Sample{ Value: 0, Timestamp: time.Time{}, Metric: model.Metric{ model.MetricNameLabel: "my_metric", "request_type": "your_dad", "sprache": "deutsch", }, }, t) b := model.MetricNameLabel result, err := p.GetFingerprintsForLabelName(b) if err != nil { t.Error(err) } if len(result) != 2 { t.Errorf("Expected two elements.") } b = model.LabelName("request_type") result, err = p.GetFingerprintsForLabelName(b) if err != nil { t.Error(err) } if len(result) != 2 { t.Errorf("Expected two elements.") } b = model.LabelName("language") result, err = p.GetFingerprintsForLabelName(b) if err != nil { t.Error(err) } if len(result) != 1 { t.Errorf("Expected one element.") } b = model.LabelName("sprache") result, err = p.GetFingerprintsForLabelName(b) if err != nil { t.Error(err) } if len(result) != 1 { t.Errorf("Expected one element.") } }
func GetMetricForFingerprintTests(p MetricPersistence, t test.Tester) { testAppendSample(p, model.Sample{ Value: 0, Timestamp: time.Time{}, Metric: model.Metric{ "request_type": "your_mom", }, }, t) testAppendSample(p, model.Sample{ Value: 0, Timestamp: time.Time{}, Metric: model.Metric{ "request_type": "your_dad", "one-off": "value", }, }, t) result, err := p.GetFingerprintsForLabelSet(model.LabelSet{ model.LabelName("request_type"): model.LabelValue("your_mom"), }) if err != nil { t.Error(err) } if len(result) != 1 { t.Errorf("Expected one element.") } v, e := p.GetMetricForFingerprint(result[0]) if e != nil { t.Error(e) } if v == nil { t.Fatal("Did not expect nil.") } metric := *v if len(metric) != 1 { t.Errorf("Expected one-dimensional metric.") } if metric["request_type"] != "your_mom" { t.Errorf("Expected metric to match.") } result, err = p.GetFingerprintsForLabelSet(model.LabelSet{ model.LabelName("request_type"): model.LabelValue("your_dad"), }) if err != nil { t.Error(err) } if len(result) != 1 { t.Errorf("Expected one element.") } v, e = p.GetMetricForFingerprint(result[0]) if v == nil { t.Fatal("Did not expect nil.") } metric = *v if e != nil { t.Error(e) } if len(metric) != 2 { t.Errorf("Expected one-dimensional metric.") } if metric["request_type"] != "your_dad" { t.Errorf("Expected metric to match.") } if metric["one-off"] != "value" { t.Errorf("Expected metric to match.") } }
func StochasticTests(persistenceMaker func() (MetricPersistence, test.Closer), t test.Tester) { stochastic := func(x int) (success bool) { p, closer := persistenceMaker() defer closer.Close() defer p.Close() seed := rand.NewSource(int64(x)) random := rand.New(seed) numberOfMetrics := random.Intn(stochasticMaximumVariance) + 1 numberOfSharedLabels := random.Intn(stochasticMaximumVariance) numberOfUnsharedLabels := random.Intn(stochasticMaximumVariance) numberOfSamples := random.Intn(stochasticMaximumVariance) + 2 numberOfRangeScans := random.Intn(stochasticMaximumVariance) metricTimestamps := map[int]map[int64]bool{} metricEarliestSample := map[int]int64{} metricNewestSample := map[int]int64{} for metricIndex := 0; metricIndex < numberOfMetrics; metricIndex++ { sample := model.Sample{ Metric: model.Metric{}, } v := model.LabelValue(fmt.Sprintf("metric_index_%d", metricIndex)) sample.Metric[model.MetricNameLabel] = v for sharedLabelIndex := 0; sharedLabelIndex < numberOfSharedLabels; sharedLabelIndex++ { l := model.LabelName(fmt.Sprintf("shared_label_%d", sharedLabelIndex)) v := model.LabelValue(fmt.Sprintf("label_%d", sharedLabelIndex)) sample.Metric[l] = v } for unsharedLabelIndex := 0; unsharedLabelIndex < numberOfUnsharedLabels; unsharedLabelIndex++ { l := model.LabelName(fmt.Sprintf("metric_index_%d_private_label_%d", metricIndex, unsharedLabelIndex)) v := model.LabelValue(fmt.Sprintf("private_label_%d", unsharedLabelIndex)) sample.Metric[l] = v } timestamps := map[int64]bool{} metricTimestamps[metricIndex] = timestamps var ( newestSample int64 = math.MinInt64 oldestSample int64 = math.MaxInt64 nextTimestamp func() int64 ) nextTimestamp = func() int64 { var candidate int64 candidate = random.Int63n(math.MaxInt32 - 1) if _, has := timestamps[candidate]; has { // WART candidate = nextTimestamp() } timestamps[candidate] = true if candidate < oldestSample { oldestSample = candidate } if candidate > newestSample { newestSample = candidate } return candidate } for sampleIndex := 0; sampleIndex < numberOfSamples; sampleIndex++ { sample.Timestamp = time.Unix(nextTimestamp(), 0) sample.Value = model.SampleValue(sampleIndex) err := p.AppendSample(sample) if err != nil { t.Error(err) return } } metricEarliestSample[metricIndex] = oldestSample metricNewestSample[metricIndex] = newestSample for sharedLabelIndex := 0; sharedLabelIndex < numberOfSharedLabels; sharedLabelIndex++ { labelPair := model.LabelSet{ model.LabelName(fmt.Sprintf("shared_label_%d", sharedLabelIndex)): model.LabelValue(fmt.Sprintf("label_%d", sharedLabelIndex)), } fingerprints, err := p.GetFingerprintsForLabelSet(labelPair) if err != nil { t.Error(err) return } if len(fingerprints) == 0 { t.Errorf("expected fingerprint count of %d, got %d", 0, len(fingerprints)) return } labelName := model.LabelName(fmt.Sprintf("shared_label_%d", sharedLabelIndex)) fingerprints, err = p.GetFingerprintsForLabelName(labelName) if err != nil { t.Error(err) return } if len(fingerprints) == 0 { t.Errorf("expected fingerprint count of %d, got %d", 0, len(fingerprints)) return } } } for sharedIndex := 0; sharedIndex < numberOfSharedLabels; sharedIndex++ { labelName := model.LabelName(fmt.Sprintf("shared_label_%d", sharedIndex)) fingerprints, err := p.GetFingerprintsForLabelName(labelName) if err != nil { t.Error(err) return } if len(fingerprints) != numberOfMetrics { t.Errorf("expected fingerprint count of %d, got %d", numberOfMetrics, len(fingerprints)) return } } for metricIndex := 0; metricIndex < numberOfMetrics; metricIndex++ { for unsharedLabelIndex := 0; unsharedLabelIndex < numberOfUnsharedLabels; unsharedLabelIndex++ { labelName := model.LabelName(fmt.Sprintf("metric_index_%d_private_label_%d", metricIndex, unsharedLabelIndex)) labelValue := model.LabelValue(fmt.Sprintf("private_label_%d", unsharedLabelIndex)) labelSet := model.LabelSet{ labelName: labelValue, } fingerprints, err := p.GetFingerprintsForLabelSet(labelSet) if err != nil { t.Error(err) return } if len(fingerprints) != 1 { t.Errorf("expected fingerprint count of %d, got %d", 1, len(fingerprints)) return } fingerprints, err = p.GetFingerprintsForLabelName(labelName) if err != nil { t.Error(err) return } if len(fingerprints) != 1 { t.Errorf("expected fingerprint count of %d, got %d", 1, len(fingerprints)) return } } metric := model.Metric{} metric[model.MetricNameLabel] = model.LabelValue(fmt.Sprintf("metric_index_%d", metricIndex)) for i := 0; i < numberOfSharedLabels; i++ { l := model.LabelName(fmt.Sprintf("shared_label_%d", i)) v := model.LabelValue(fmt.Sprintf("label_%d", i)) metric[l] = v } for i := 0; i < numberOfUnsharedLabels; i++ { l := model.LabelName(fmt.Sprintf("metric_index_%d_private_label_%d", metricIndex, i)) v := model.LabelValue(fmt.Sprintf("private_label_%d", i)) metric[l] = v } for i := 0; i < numberOfRangeScans; i++ { timestamps := metricTimestamps[metricIndex] var first int64 = 0 var second int64 = 0 for { firstCandidate := random.Int63n(int64(len(timestamps))) secondCandidate := random.Int63n(int64(len(timestamps))) smallest := int64(-1) largest := int64(-1) if firstCandidate == secondCandidate { continue } else if firstCandidate > secondCandidate { largest = firstCandidate smallest = secondCandidate } else { largest = secondCandidate smallest = firstCandidate } j := int64(0) for i := range timestamps { if j == smallest { first = i } else if j == largest { second = i break } j++ } break } begin := first end := second if second < first { begin, end = second, first } interval := model.Interval{ OldestInclusive: time.Unix(begin, 0), NewestInclusive: time.Unix(end, 0), } samples, err := p.GetRangeValues(model.NewFingerprintFromMetric(metric), interval) if err != nil { t.Error(err) return } if len(samples.Values) < 2 { t.Errorf("expected sample count less than %d, got %d", 2, len(samples.Values)) return } } } return true } if err := quick.Check(stochastic, nil); err != nil { t.Error(err) } }
func StochasticTests(persistenceMaker func() (metric.Persistence, test.Closer), t test.Tester) { stochastic := func(x int) (success bool) { p, closer := persistenceMaker() defer closer.Close() defer p.Close() seed := rand.NewSource(int64(x)) random := rand.New(seed) numberOfMetrics := random.Intn(stochasticMaximumVariance) + 1 numberOfSharedLabels := random.Intn(stochasticMaximumVariance) numberOfUnsharedLabels := random.Intn(stochasticMaximumVariance) numberOfSamples := random.Intn(stochasticMaximumVariance) + 2 numberOfRangeScans := random.Intn(stochasticMaximumVariance) metricTimestamps := map[int]map[int64]bool{} metricEarliestSample := map[int]int64{} metricNewestSample := map[int]int64{} for metricIndex := 0; metricIndex < numberOfMetrics; metricIndex++ { sample := &clientmodel.Sample{ Metric: clientmodel.Metric{}, } v := clientmodel.LabelValue(fmt.Sprintf("metric_index_%d", metricIndex)) sample.Metric[clientmodel.MetricNameLabel] = v for sharedLabelIndex := 0; sharedLabelIndex < numberOfSharedLabels; sharedLabelIndex++ { l := clientmodel.LabelName(fmt.Sprintf("shared_label_%d", sharedLabelIndex)) v := clientmodel.LabelValue(fmt.Sprintf("label_%d", sharedLabelIndex)) sample.Metric[l] = v } for unsharedLabelIndex := 0; unsharedLabelIndex < numberOfUnsharedLabels; unsharedLabelIndex++ { l := clientmodel.LabelName(fmt.Sprintf("metric_index_%d_private_label_%d", metricIndex, unsharedLabelIndex)) v := clientmodel.LabelValue(fmt.Sprintf("private_label_%d", unsharedLabelIndex)) sample.Metric[l] = v } timestamps := map[int64]bool{} metricTimestamps[metricIndex] = timestamps var newestSample int64 = math.MinInt64 var oldestSample int64 = math.MaxInt64 var nextTimestamp func() int64 nextTimestamp = func() int64 { var candidate int64 candidate = random.Int63n(math.MaxInt32 - 1) if _, has := timestamps[candidate]; has { // WART candidate = nextTimestamp() } timestamps[candidate] = true if candidate < oldestSample { oldestSample = candidate } if candidate > newestSample { newestSample = candidate } return candidate } // BUG(matt): Invariant of the in-memory database assumes this. sortedTimestamps := timeslice{} for sampleIndex := 0; sampleIndex < numberOfSamples; sampleIndex++ { sortedTimestamps = append(sortedTimestamps, clientmodel.TimestampFromUnix(nextTimestamp())) } sort.Sort(sortedTimestamps) for sampleIndex := 0; sampleIndex < numberOfSamples; sampleIndex++ { sample.Timestamp = sortedTimestamps[sampleIndex] sample.Value = clientmodel.SampleValue(sampleIndex) err := p.AppendSamples(clientmodel.Samples{sample}) if err != nil { t.Error(err) return } } metricEarliestSample[metricIndex] = oldestSample metricNewestSample[metricIndex] = newestSample for sharedLabelIndex := 0; sharedLabelIndex < numberOfSharedLabels; sharedLabelIndex++ { matchers := metric.LabelMatchers{{ Type: metric.Equal, Name: clientmodel.LabelName(fmt.Sprintf("shared_label_%d", sharedLabelIndex)), Value: clientmodel.LabelValue(fmt.Sprintf("label_%d", sharedLabelIndex)), }} fingerprints, err := p.GetFingerprintsForLabelMatchers(matchers) if err != nil { t.Error(err) return } if len(fingerprints) == 0 { t.Errorf("expected fingerprint count of %d, got %d", 0, len(fingerprints)) return } } } for metricIndex := 0; metricIndex < numberOfMetrics; metricIndex++ { for unsharedLabelIndex := 0; unsharedLabelIndex < numberOfUnsharedLabels; unsharedLabelIndex++ { labelName := clientmodel.LabelName(fmt.Sprintf("metric_index_%d_private_label_%d", metricIndex, unsharedLabelIndex)) labelValue := clientmodel.LabelValue(fmt.Sprintf("private_label_%d", unsharedLabelIndex)) matchers := metric.LabelMatchers{{ Type: metric.Equal, Name: labelName, Value: labelValue, }} fingerprints, err := p.GetFingerprintsForLabelMatchers(matchers) if err != nil { t.Error(err) return } if len(fingerprints) != 1 { t.Errorf("expected fingerprint count of %d, got %d", 1, len(fingerprints)) return } } m := clientmodel.Metric{} m[clientmodel.MetricNameLabel] = clientmodel.LabelValue(fmt.Sprintf("metric_index_%d", metricIndex)) for i := 0; i < numberOfSharedLabels; i++ { l := clientmodel.LabelName(fmt.Sprintf("shared_label_%d", i)) v := clientmodel.LabelValue(fmt.Sprintf("label_%d", i)) m[l] = v } for i := 0; i < numberOfUnsharedLabels; i++ { l := clientmodel.LabelName(fmt.Sprintf("metric_index_%d_private_label_%d", metricIndex, i)) v := clientmodel.LabelValue(fmt.Sprintf("private_label_%d", i)) m[l] = v } for i := 0; i < numberOfRangeScans; i++ { timestamps := metricTimestamps[metricIndex] var first int64 var second int64 for { firstCandidate := random.Int63n(int64(len(timestamps))) secondCandidate := random.Int63n(int64(len(timestamps))) smallest := int64(-1) largest := int64(-1) if firstCandidate == secondCandidate { continue } else if firstCandidate > secondCandidate { largest = firstCandidate smallest = secondCandidate } else { largest = secondCandidate smallest = firstCandidate } j := int64(0) for i := range timestamps { if j == smallest { first = i } else if j == largest { second = i break } j++ } break } begin := first end := second if second < first { begin, end = second, first } interval := metric.Interval{ OldestInclusive: clientmodel.TimestampFromUnix(begin), NewestInclusive: clientmodel.TimestampFromUnix(end), } samples := metric.Values{} fp := &clientmodel.Fingerprint{} fp.LoadFromMetric(m) switch persistence := p.(type) { case metric.View: samples = persistence.GetRangeValues(fp, interval) if len(samples) < 2 { t.Fatalf("expected sample count greater than %d, got %d", 2, len(samples)) } case *LevelDBPersistence: var err error samples, err = levelDBGetRangeValues(persistence, fp, interval) if err != nil { t.Fatal(err) } if len(samples) < 2 { t.Fatalf("expected sample count greater than %d, got %d", 2, len(samples)) } default: t.Error("Unexpected type of metric.Persistence.") } } } return true } if err := quick.Check(stochastic, nil); err != nil { t.Error(err) } }