(t *testing.T)
| 2897 | } |
| 2898 | |
| 2899 | func TestHistogramAggregator(t *testing.T) { |
| 2900 | req := &tempopb.QueryRangeRequest{ |
| 2901 | Start: uint64(time.Now().Add(-1 * time.Hour).UnixNano()), |
| 2902 | End: uint64(time.Now().UnixNano()), |
| 2903 | Step: uint64(15 * time.Second.Nanoseconds()), |
| 2904 | Exemplars: 100, |
| 2905 | } |
| 2906 | const seriesCount = 6 |
| 2907 | |
| 2908 | cases := []struct { |
| 2909 | name string |
| 2910 | samplesCount int |
| 2911 | exemplarCount int |
| 2912 | }{ |
| 2913 | {"Small", 10, 5}, |
| 2914 | {"Medium", 100, 20}, |
| 2915 | {"Large", 1000, 100}, |
| 2916 | } |
| 2917 | |
| 2918 | for _, tc := range cases { |
| 2919 | t.Run(tc.name, func(t *testing.T) { |
| 2920 | series := generateTestTimeSeries(seriesCount, tc.samplesCount, tc.exemplarCount, req.Start, req.End) |
| 2921 | quantiles := []float64{0.5, 0.9, 0.99} |
| 2922 | |
| 2923 | agg := NewHistogramAggregator(req, quantiles, uint32(tc.exemplarCount)) |
| 2924 | agg.Combine(series) |
| 2925 | results := agg.Results() |
| 2926 | require.NotNil(t, results, "Expected non-nil SeriesSet from HistogramAggregator") |
| 2927 | require.Greater(t, len(results), 0, "Expected non-empty SeriesSet from HistogramAggregator") |
| 2928 | |
| 2929 | // Check that exemplars are distributed across quantile series |
| 2930 | totalExemplars := 0 |
| 2931 | for _, ts := range results { |
| 2932 | totalExemplars += len(ts.Exemplars) |
| 2933 | } |
| 2934 | require.Greater(t, totalExemplars, 0, "Expected at least some exemplars across all quantile series") |
| 2935 | |
| 2936 | for _, ts := range results { |
| 2937 | // With aggregated semantic matching, total exemplars can be higher since |
| 2938 | // we're more efficiently distributing exemplars across quantile series |
| 2939 | require.LessOrEqual(t, len(ts.Exemplars), tc.exemplarCount*5, "Per-series exemplars should be reasonable") |
| 2940 | // Note: With aggregated semantic matching, exemplars are distributed more efficiently |
| 2941 | // across quantile series based on comprehensive quantile thresholds |
| 2942 | |
| 2943 | // t.Logf("Series: %s", ts.Labels) |
| 2944 | // t.Logf("Values: %v", ts.Values) |
| 2945 | // t.Logf("Exemplars: %v", ts.Exemplars) |
| 2946 | |
| 2947 | // check that the values are within the expected histogram buckets |
| 2948 | require.Greater(t, len(ts.Values), 0, "Expected non-empty histogram values") |
| 2949 | for _, value := range ts.Values { |
| 2950 | require.GreaterOrEqual(t, value, 0.0, "Histogram values should be non-negative") |
| 2951 | } |
| 2952 | // check that the exemplars are within the expected histogram Buckets |
| 2953 | for _, ex := range ts.Exemplars { |
| 2954 | require.GreaterOrEqual(t, ex.Value, 0.0, "Exemplar values should be non-negative") |
| 2955 | // Convert nanoseconds to milliseconds for comparison |
| 2956 | startMs := req.Start / uint64(time.Millisecond) |
nothing calls this directly
no test coverage detected