| 192 | } |
| 193 | |
| 194 | func TestExemplarsForBlock(t *testing.T) { |
| 195 | s := &queryRangeSharder{} |
| 196 | |
| 197 | createBlockMeta := func(durationSeconds int) *backend.BlockMeta { |
| 198 | now := time.Now() |
| 199 | return &backend.BlockMeta{ |
| 200 | BlockID: backend.MustParse(uuid.NewString()), |
| 201 | StartTime: now.Add(-time.Duration(durationSeconds) * time.Second), |
| 202 | EndTime: now, |
| 203 | } |
| 204 | } |
| 205 | |
| 206 | testCases := []struct { |
| 207 | name string |
| 208 | block *backend.BlockMeta |
| 209 | totalExemplars uint32 |
| 210 | totalDurationNanos int64 |
| 211 | expectedResult uint32 |
| 212 | }{ |
| 213 | { |
| 214 | name: "limit is zero", |
| 215 | block: createBlockMeta(60), |
| 216 | totalExemplars: 0, |
| 217 | totalDurationNanos: 60 * 1e9, |
| 218 | expectedResult: 0, |
| 219 | }, |
| 220 | { |
| 221 | name: "total duration is zero", |
| 222 | block: createBlockMeta(60), |
| 223 | totalExemplars: 100, |
| 224 | totalDurationNanos: 0, |
| 225 | expectedResult: 0, |
| 226 | }, |
| 227 | { |
| 228 | name: "single block gets all exemplars with overhead", |
| 229 | block: createBlockMeta(60), |
| 230 | totalExemplars: 100, |
| 231 | totalDurationNanos: 60 * 1e9, |
| 232 | expectedResult: 120, // 100 * 1.2 |
| 233 | }, |
| 234 | { |
| 235 | name: "block gets proportional share - 90% of time", |
| 236 | block: createBlockMeta(90), |
| 237 | totalExemplars: 100, |
| 238 | totalDurationNanos: 100 * 1e9, |
| 239 | expectedResult: 108, // 90/100 * 100 * 1.2 = 108 |
| 240 | }, |
| 241 | { |
| 242 | name: "block gets proportional share - 10% of time", |
| 243 | block: createBlockMeta(10), |
| 244 | totalExemplars: 100, |
| 245 | totalDurationNanos: 100 * 1e9, |
| 246 | expectedResult: 12, // 10/100 * 100 * 1.2 = 12 |
| 247 | }, |
| 248 | { |
| 249 | name: "at least one exemplar for very small block", |
| 250 | block: createBlockMeta(1), |
| 251 | totalExemplars: 10, |