Line data Source code
1 : use std::collections::HashMap;
2 :
3 : use super::*;
4 : use crate::consumption_metrics::RawMetric;
5 :
6 : #[test]
7 1 : fn startup_collected_timeline_metrics_before_advancing() {
8 1 : let tenant_id = TenantId::generate();
9 1 : let timeline_id = TimelineId::generate();
10 1 :
11 1 : let mut metrics = Vec::new();
12 1 : let cache = HashMap::new();
13 1 :
14 1 : let initdb_lsn = Lsn(0x10000);
15 1 : let pitr_cutoff = Lsn(0x11000);
16 1 : let disk_consistent_lsn = Lsn(initdb_lsn.0 * 2);
17 1 : let logical_size = 0x42000;
18 1 :
19 1 : let snap = TimelineSnapshot {
20 1 : loaded_at: (disk_consistent_lsn, SystemTime::now()),
21 1 : last_record_lsn: disk_consistent_lsn,
22 1 : ancestor_lsn: Lsn(0),
23 1 : current_exact_logical_size: Some(logical_size),
24 1 : pitr_enabled: true,
25 1 : pitr_cutoff: Some(pitr_cutoff),
26 1 : };
27 1 :
28 1 : let now = DateTime::<Utc>::from(SystemTime::now());
29 1 :
30 1 : snap.to_metrics(tenant_id, timeline_id, now, &mut metrics, &cache);
31 1 :
32 1 : assert_eq!(
33 1 : metrics,
34 1 : &[
35 1 : MetricsKey::written_size_delta(tenant_id, timeline_id).from_until(
36 1 : snap.loaded_at.1.into(),
37 1 : now,
38 1 : 0
39 1 : ),
40 1 : MetricsKey::written_size(tenant_id, timeline_id).at(now, disk_consistent_lsn.0),
41 1 : MetricsKey::written_size_since_parent(tenant_id, timeline_id)
42 1 : .at(now, disk_consistent_lsn.0),
43 1 : MetricsKey::pitr_history_size_since_parent(tenant_id, timeline_id)
44 1 : .at(now, disk_consistent_lsn.0 - pitr_cutoff.0),
45 1 : MetricsKey::timeline_logical_size(tenant_id, timeline_id).at(now, logical_size)
46 1 : ]
47 1 : );
48 1 : }
49 :
50 : #[test]
51 1 : fn startup_collected_timeline_metrics_second_round() {
52 1 : let tenant_id = TenantId::generate();
53 1 : let timeline_id = TimelineId::generate();
54 1 :
55 1 : let [now, before, init] = time_backwards();
56 1 :
57 1 : let now = DateTime::<Utc>::from(now);
58 1 : let before = DateTime::<Utc>::from(before);
59 1 :
60 1 : let initdb_lsn = Lsn(0x10000);
61 1 : let pitr_cutoff = Lsn(0x11000);
62 1 : let disk_consistent_lsn = Lsn(initdb_lsn.0 * 2);
63 1 : let logical_size = 0x42000;
64 1 :
65 1 : let mut metrics = Vec::new();
66 1 : let cache = HashMap::from([MetricsKey::written_size(tenant_id, timeline_id)
67 1 : .at(before, disk_consistent_lsn.0)
68 1 : .to_kv_pair()]);
69 1 :
70 1 : let snap = TimelineSnapshot {
71 1 : loaded_at: (disk_consistent_lsn, init),
72 1 : last_record_lsn: disk_consistent_lsn,
73 1 : ancestor_lsn: Lsn(0),
74 1 : current_exact_logical_size: Some(logical_size),
75 1 : pitr_enabled: true,
76 1 : pitr_cutoff: Some(pitr_cutoff),
77 1 : };
78 1 :
79 1 : snap.to_metrics(tenant_id, timeline_id, now, &mut metrics, &cache);
80 1 :
81 1 : assert_eq!(
82 1 : metrics,
83 1 : &[
84 1 : MetricsKey::written_size_delta(tenant_id, timeline_id).from_until(before, now, 0),
85 1 : MetricsKey::written_size(tenant_id, timeline_id).at(now, disk_consistent_lsn.0),
86 1 : MetricsKey::written_size_since_parent(tenant_id, timeline_id)
87 1 : .at(now, disk_consistent_lsn.0),
88 1 : MetricsKey::pitr_history_size_since_parent(tenant_id, timeline_id)
89 1 : .at(now, disk_consistent_lsn.0 - pitr_cutoff.0),
90 1 : MetricsKey::timeline_logical_size(tenant_id, timeline_id).at(now, logical_size)
91 1 : ]
92 1 : );
93 1 : }
94 :
95 : #[test]
96 1 : fn startup_collected_timeline_metrics_nth_round_at_same_lsn() {
97 1 : let tenant_id = TenantId::generate();
98 1 : let timeline_id = TimelineId::generate();
99 1 :
100 1 : let [now, just_before, before, init] = time_backwards();
101 1 :
102 1 : let now = DateTime::<Utc>::from(now);
103 1 : let just_before = DateTime::<Utc>::from(just_before);
104 1 : let before = DateTime::<Utc>::from(before);
105 1 :
106 1 : let initdb_lsn = Lsn(0x10000);
107 1 : let pitr_cutoff = Lsn(0x11000);
108 1 : let disk_consistent_lsn = Lsn(initdb_lsn.0 * 2);
109 1 : let logical_size = 0x42000;
110 1 :
111 1 : let mut metrics = Vec::new();
112 1 : let cache = HashMap::from([
113 1 : // at t=before was the last time the last_record_lsn changed
114 1 : MetricsKey::written_size(tenant_id, timeline_id)
115 1 : .at(before, disk_consistent_lsn.0)
116 1 : .to_kv_pair(),
117 1 : // end time of this event is used for the next ones
118 1 : MetricsKey::written_size_delta(tenant_id, timeline_id)
119 1 : .from_until(before, just_before, 0)
120 1 : .to_kv_pair(),
121 1 : ]);
122 1 :
123 1 : let snap = TimelineSnapshot {
124 1 : loaded_at: (disk_consistent_lsn, init),
125 1 : last_record_lsn: disk_consistent_lsn,
126 1 : ancestor_lsn: Lsn(0),
127 1 : current_exact_logical_size: Some(logical_size),
128 1 : pitr_enabled: true,
129 1 : pitr_cutoff: Some(pitr_cutoff),
130 1 : };
131 1 :
132 1 : snap.to_metrics(tenant_id, timeline_id, now, &mut metrics, &cache);
133 1 :
134 1 : assert_eq!(
135 1 : metrics,
136 1 : &[
137 1 : MetricsKey::written_size_delta(tenant_id, timeline_id).from_until(just_before, now, 0),
138 1 : MetricsKey::written_size(tenant_id, timeline_id).at(now, disk_consistent_lsn.0),
139 1 : MetricsKey::written_size_since_parent(tenant_id, timeline_id)
140 1 : .at(now, disk_consistent_lsn.0),
141 1 : MetricsKey::pitr_history_size_since_parent(tenant_id, timeline_id)
142 1 : .at(now, disk_consistent_lsn.0 - pitr_cutoff.0),
143 1 : MetricsKey::timeline_logical_size(tenant_id, timeline_id).at(now, logical_size)
144 1 : ]
145 1 : );
146 1 : }
147 :
148 : /// Tests that written sizes do not regress across restarts.
149 : #[test]
150 1 : fn post_restart_written_sizes_with_rolled_back_last_record_lsn() {
151 1 : let tenant_id = TenantId::generate();
152 1 : let timeline_id = TimelineId::generate();
153 1 :
154 1 : let [later, now, at_restart] = time_backwards();
155 1 :
156 1 : // FIXME: tests would be so much easier if we did not need to juggle back and forth
157 1 : // SystemTime and DateTime::<Utc> ... Could do the conversion only at upload time?
158 1 : let now = DateTime::<Utc>::from(now);
159 1 : let later = DateTime::<Utc>::from(later);
160 1 : let before_restart = at_restart - std::time::Duration::from_secs(5 * 60);
161 1 : let way_before = before_restart - std::time::Duration::from_secs(10 * 60);
162 1 : let before_restart = DateTime::<Utc>::from(before_restart);
163 1 : let way_before = DateTime::<Utc>::from(way_before);
164 1 :
165 1 : let snap = TimelineSnapshot {
166 1 : loaded_at: (Lsn(50), at_restart),
167 1 : last_record_lsn: Lsn(50),
168 1 : ancestor_lsn: Lsn(0),
169 1 : current_exact_logical_size: None,
170 1 : pitr_enabled: true,
171 1 : pitr_cutoff: Some(Lsn(20)),
172 1 : };
173 1 :
174 1 : let mut cache = HashMap::from([
175 1 : MetricsKey::written_size(tenant_id, timeline_id)
176 1 : .at(before_restart, 100)
177 1 : .to_kv_pair(),
178 1 : MetricsKey::written_size_delta(tenant_id, timeline_id)
179 1 : .from_until(
180 1 : way_before,
181 1 : before_restart,
182 1 : // not taken into account, but the timestamps are important
183 1 : 999_999_999,
184 1 : )
185 1 : .to_kv_pair(),
186 1 : ]);
187 1 :
188 1 : let mut metrics = Vec::new();
189 1 : snap.to_metrics(tenant_id, timeline_id, now, &mut metrics, &cache);
190 1 :
191 1 : assert_eq!(
192 1 : metrics,
193 1 : &[
194 1 : MetricsKey::written_size_delta(tenant_id, timeline_id).from_until(
195 1 : before_restart,
196 1 : now,
197 1 : 0
198 1 : ),
199 1 : MetricsKey::written_size(tenant_id, timeline_id).at(now, 100),
200 1 : MetricsKey::written_size_since_parent(tenant_id, timeline_id).at(now, 100),
201 1 : MetricsKey::pitr_history_size_since_parent(tenant_id, timeline_id).at(now, 80),
202 1 : ]
203 1 : );
204 :
205 : // now if we cache these metrics, and re-run while "still in recovery"
206 4 : cache.extend(metrics.drain(..).map(|x| x.to_kv_pair()));
207 1 :
208 1 : // "still in recovery", because our snapshot did not change
209 1 : snap.to_metrics(tenant_id, timeline_id, later, &mut metrics, &cache);
210 1 :
211 1 : assert_eq!(
212 1 : metrics,
213 1 : &[
214 1 : MetricsKey::written_size_delta(tenant_id, timeline_id).from_until(now, later, 0),
215 1 : MetricsKey::written_size(tenant_id, timeline_id).at(later, 100),
216 1 : MetricsKey::written_size_since_parent(tenant_id, timeline_id).at(later, 100),
217 1 : MetricsKey::pitr_history_size_since_parent(tenant_id, timeline_id).at(later, 80),
218 1 : ]
219 1 : );
220 1 : }
221 :
222 : /// Tests that written sizes do not regress across restarts, even on child branches.
223 : #[test]
224 1 : fn post_restart_written_sizes_with_rolled_back_last_record_lsn_and_ancestor_lsn() {
225 1 : let tenant_id = TenantId::generate();
226 1 : let timeline_id = TimelineId::generate();
227 1 :
228 1 : let [later, now, at_restart] = time_backwards();
229 1 :
230 1 : // FIXME: tests would be so much easier if we did not need to juggle back and forth
231 1 : // SystemTime and DateTime::<Utc> ... Could do the conversion only at upload time?
232 1 : let now = DateTime::<Utc>::from(now);
233 1 : let later = DateTime::<Utc>::from(later);
234 1 : let before_restart = at_restart - std::time::Duration::from_secs(5 * 60);
235 1 : let way_before = before_restart - std::time::Duration::from_secs(10 * 60);
236 1 : let before_restart = DateTime::<Utc>::from(before_restart);
237 1 : let way_before = DateTime::<Utc>::from(way_before);
238 1 :
239 1 : let snap = TimelineSnapshot {
240 1 : loaded_at: (Lsn(50), at_restart),
241 1 : last_record_lsn: Lsn(50),
242 1 : ancestor_lsn: Lsn(40),
243 1 : current_exact_logical_size: None,
244 1 : pitr_enabled: true,
245 1 : pitr_cutoff: Some(Lsn(20)),
246 1 : };
247 1 :
248 1 : let mut cache = HashMap::from([
249 1 : MetricsKey::written_size(tenant_id, timeline_id)
250 1 : .at(before_restart, 100)
251 1 : .to_kv_pair(),
252 1 : MetricsKey::written_size_delta(tenant_id, timeline_id)
253 1 : .from_until(
254 1 : way_before,
255 1 : before_restart,
256 1 : // not taken into account, but the timestamps are important
257 1 : 999_999_999,
258 1 : )
259 1 : .to_kv_pair(),
260 1 : ]);
261 1 :
262 1 : let mut metrics = Vec::new();
263 1 : snap.to_metrics(tenant_id, timeline_id, now, &mut metrics, &cache);
264 1 :
265 1 : assert_eq!(
266 1 : metrics,
267 1 : &[
268 1 : MetricsKey::written_size_delta(tenant_id, timeline_id).from_until(
269 1 : before_restart,
270 1 : now,
271 1 : 0
272 1 : ),
273 1 : MetricsKey::written_size(tenant_id, timeline_id).at(now, 100),
274 1 : MetricsKey::written_size_since_parent(tenant_id, timeline_id).at(now, 60),
275 1 : MetricsKey::pitr_history_size_since_parent(tenant_id, timeline_id).at(now, 60),
276 1 : ]
277 1 : );
278 :
279 : // now if we cache these metrics, and re-run while "still in recovery"
280 4 : cache.extend(metrics.drain(..).map(|x| x.to_kv_pair()));
281 1 :
282 1 : // "still in recovery", because our snapshot did not change
283 1 : snap.to_metrics(tenant_id, timeline_id, later, &mut metrics, &cache);
284 1 :
285 1 : assert_eq!(
286 1 : metrics,
287 1 : &[
288 1 : MetricsKey::written_size_delta(tenant_id, timeline_id).from_until(now, later, 0),
289 1 : MetricsKey::written_size(tenant_id, timeline_id).at(later, 100),
290 1 : MetricsKey::written_size_since_parent(tenant_id, timeline_id).at(later, 60),
291 1 : MetricsKey::pitr_history_size_since_parent(tenant_id, timeline_id).at(later, 60),
292 1 : ]
293 1 : );
294 1 : }
295 :
296 : /// Tests that written sizes do not regress across restarts, even on child branches and
297 : /// with a PITR cutoff after the branch point.
298 : #[test]
299 1 : fn post_restart_written_sizes_with_rolled_back_last_record_lsn_and_ancestor_lsn_and_pitr_cutoff() {
300 1 : let tenant_id = TenantId::generate();
301 1 : let timeline_id = TimelineId::generate();
302 1 :
303 1 : let [later, now, at_restart] = time_backwards();
304 1 :
305 1 : // FIXME: tests would be so much easier if we did not need to juggle back and forth
306 1 : // SystemTime and DateTime::<Utc> ... Could do the conversion only at upload time?
307 1 : let now = DateTime::<Utc>::from(now);
308 1 : let later = DateTime::<Utc>::from(later);
309 1 : let before_restart = at_restart - std::time::Duration::from_secs(5 * 60);
310 1 : let way_before = before_restart - std::time::Duration::from_secs(10 * 60);
311 1 : let before_restart = DateTime::<Utc>::from(before_restart);
312 1 : let way_before = DateTime::<Utc>::from(way_before);
313 1 :
314 1 : let snap = TimelineSnapshot {
315 1 : loaded_at: (Lsn(50), at_restart),
316 1 : last_record_lsn: Lsn(50),
317 1 : ancestor_lsn: Lsn(30),
318 1 : current_exact_logical_size: None,
319 1 : pitr_enabled: true,
320 1 : pitr_cutoff: Some(Lsn(40)),
321 1 : };
322 1 :
323 1 : let mut cache = HashMap::from([
324 1 : MetricsKey::written_size(tenant_id, timeline_id)
325 1 : .at(before_restart, 100)
326 1 : .to_kv_pair(),
327 1 : MetricsKey::written_size_delta(tenant_id, timeline_id)
328 1 : .from_until(
329 1 : way_before,
330 1 : before_restart,
331 1 : // not taken into account, but the timestamps are important
332 1 : 999_999_999,
333 1 : )
334 1 : .to_kv_pair(),
335 1 : ]);
336 1 :
337 1 : let mut metrics = Vec::new();
338 1 : snap.to_metrics(tenant_id, timeline_id, now, &mut metrics, &cache);
339 1 :
340 1 : assert_eq!(
341 1 : metrics,
342 1 : &[
343 1 : MetricsKey::written_size_delta(tenant_id, timeline_id).from_until(
344 1 : before_restart,
345 1 : now,
346 1 : 0
347 1 : ),
348 1 : MetricsKey::written_size(tenant_id, timeline_id).at(now, 100),
349 1 : MetricsKey::written_size_since_parent(tenant_id, timeline_id).at(now, 70),
350 1 : MetricsKey::pitr_history_size_since_parent(tenant_id, timeline_id).at(now, 60),
351 1 : ]
352 1 : );
353 :
354 : // now if we cache these metrics, and re-run while "still in recovery"
355 4 : cache.extend(metrics.drain(..).map(|x| x.to_kv_pair()));
356 1 :
357 1 : // "still in recovery", because our snapshot did not change
358 1 : snap.to_metrics(tenant_id, timeline_id, later, &mut metrics, &cache);
359 1 :
360 1 : assert_eq!(
361 1 : metrics,
362 1 : &[
363 1 : MetricsKey::written_size_delta(tenant_id, timeline_id).from_until(now, later, 0),
364 1 : MetricsKey::written_size(tenant_id, timeline_id).at(later, 100),
365 1 : MetricsKey::written_size_since_parent(tenant_id, timeline_id).at(later, 70),
366 1 : MetricsKey::pitr_history_size_since_parent(tenant_id, timeline_id).at(later, 60),
367 1 : ]
368 1 : );
369 1 : }
370 :
371 : #[test]
372 1 : fn post_restart_current_exact_logical_size_uses_cached() {
373 1 : let tenant_id = TenantId::generate();
374 1 : let timeline_id = TimelineId::generate();
375 1 :
376 1 : let [now, at_restart] = time_backwards();
377 1 :
378 1 : let now = DateTime::<Utc>::from(now);
379 1 : let before_restart = at_restart - std::time::Duration::from_secs(5 * 60);
380 1 : let before_restart = DateTime::<Utc>::from(before_restart);
381 1 :
382 1 : let snap = TimelineSnapshot {
383 1 : loaded_at: (Lsn(50), at_restart),
384 1 : last_record_lsn: Lsn(50),
385 1 : ancestor_lsn: Lsn(0),
386 1 : current_exact_logical_size: None,
387 1 : pitr_enabled: true,
388 1 : pitr_cutoff: None,
389 1 : };
390 1 :
391 1 : let cache = HashMap::from([MetricsKey::timeline_logical_size(tenant_id, timeline_id)
392 1 : .at(before_restart, 100)
393 1 : .to_kv_pair()]);
394 1 :
395 1 : let mut metrics = Vec::new();
396 1 : snap.to_metrics(tenant_id, timeline_id, now, &mut metrics, &cache);
397 1 :
398 4 : metrics.retain(|item| item.key.metric == Name::LogicalSize);
399 1 :
400 1 : assert_eq!(
401 1 : metrics,
402 1 : &[MetricsKey::timeline_logical_size(tenant_id, timeline_id).at(now, 100)]
403 1 : );
404 1 : }
405 :
406 : #[test]
407 1 : fn post_restart_synthetic_size_uses_cached_if_available() {
408 1 : let tenant_id = TenantId::generate();
409 1 :
410 1 : let ts = TenantSnapshot {
411 1 : remote_size: 1000,
412 1 : // not yet calculated
413 1 : synthetic_size: 0,
414 1 : };
415 1 :
416 1 : let now = SystemTime::now();
417 1 : let before_restart = DateTime::<Utc>::from(now - std::time::Duration::from_secs(5 * 60));
418 1 : let now = DateTime::<Utc>::from(now);
419 1 :
420 1 : let cached = HashMap::from([MetricsKey::synthetic_size(tenant_id)
421 1 : .at(before_restart, 1000)
422 1 : .to_kv_pair()]);
423 1 :
424 1 : let mut metrics = Vec::new();
425 1 : ts.to_metrics(tenant_id, now, &cached, &mut metrics);
426 1 :
427 1 : assert_eq!(
428 1 : metrics,
429 1 : &[
430 1 : MetricsKey::remote_storage_size(tenant_id).at(now, 1000),
431 1 : MetricsKey::synthetic_size(tenant_id).at(now, 1000),
432 1 : ]
433 1 : );
434 1 : }
435 :
436 : #[test]
437 1 : fn post_restart_synthetic_size_is_not_sent_when_not_cached() {
438 1 : let tenant_id = TenantId::generate();
439 1 :
440 1 : let ts = TenantSnapshot {
441 1 : remote_size: 1000,
442 1 : // not yet calculated
443 1 : synthetic_size: 0,
444 1 : };
445 1 :
446 1 : let now = SystemTime::now();
447 1 : let now = DateTime::<Utc>::from(now);
448 1 :
449 1 : let cached = HashMap::new();
450 1 :
451 1 : let mut metrics = Vec::new();
452 1 : ts.to_metrics(tenant_id, now, &cached, &mut metrics);
453 1 :
454 1 : assert_eq!(
455 1 : metrics,
456 1 : &[
457 1 : MetricsKey::remote_storage_size(tenant_id).at(now, 1000),
458 1 : // no synthetic size here
459 1 : ]
460 1 : );
461 1 : }
462 :
463 6 : fn time_backwards<const N: usize>() -> [std::time::SystemTime; N] {
464 6 : let mut times = [std::time::SystemTime::UNIX_EPOCH; N];
465 6 : times[0] = std::time::SystemTime::now();
466 18 : for behind in 1..N {
467 12 : times[behind] = times[0] - std::time::Duration::from_secs(behind as u64);
468 12 : }
469 :
470 6 : times
471 6 : }
472 :
473 : /// Tests that disabled PITR history does not yield any history size, even when the PITR cutoff
474 : /// indicates otherwise.
475 : #[test]
476 1 : fn pitr_disabled_yields_no_history_size() {
477 1 : let tenant_id = TenantId::generate();
478 1 : let timeline_id = TimelineId::generate();
479 1 :
480 1 : let mut metrics = Vec::new();
481 1 : let cache = HashMap::new();
482 1 :
483 1 : let initdb_lsn = Lsn(0x10000);
484 1 : let pitr_cutoff = Lsn(0x11000);
485 1 : let disk_consistent_lsn = Lsn(initdb_lsn.0 * 2);
486 1 :
487 1 : let snap = TimelineSnapshot {
488 1 : loaded_at: (disk_consistent_lsn, SystemTime::now()),
489 1 : last_record_lsn: disk_consistent_lsn,
490 1 : ancestor_lsn: Lsn(0),
491 1 : current_exact_logical_size: None,
492 1 : pitr_enabled: false,
493 1 : pitr_cutoff: Some(pitr_cutoff),
494 1 : };
495 1 :
496 1 : let now = DateTime::<Utc>::from(SystemTime::now());
497 1 :
498 1 : snap.to_metrics(tenant_id, timeline_id, now, &mut metrics, &cache);
499 1 :
500 1 : assert_eq!(
501 1 : metrics,
502 1 : &[
503 1 : MetricsKey::written_size_delta(tenant_id, timeline_id).from_until(
504 1 : snap.loaded_at.1.into(),
505 1 : now,
506 1 : 0
507 1 : ),
508 1 : MetricsKey::written_size(tenant_id, timeline_id).at(now, disk_consistent_lsn.0),
509 1 : MetricsKey::written_size_since_parent(tenant_id, timeline_id)
510 1 : .at(now, disk_consistent_lsn.0),
511 1 : MetricsKey::pitr_history_size_since_parent(tenant_id, timeline_id).at(now, 0),
512 1 : ]
513 1 : );
514 1 : }
515 :
516 : /// Tests that uninitialized PITR cutoff does not emit any history size metric at all.
517 : #[test]
518 1 : fn pitr_uninitialized_does_not_emit_history_size() {
519 1 : let tenant_id = TenantId::generate();
520 1 : let timeline_id = TimelineId::generate();
521 1 :
522 1 : let mut metrics = Vec::new();
523 1 : let cache = HashMap::new();
524 1 :
525 1 : let initdb_lsn = Lsn(0x10000);
526 1 : let disk_consistent_lsn = Lsn(initdb_lsn.0 * 2);
527 1 :
528 1 : let snap = TimelineSnapshot {
529 1 : loaded_at: (disk_consistent_lsn, SystemTime::now()),
530 1 : last_record_lsn: disk_consistent_lsn,
531 1 : ancestor_lsn: Lsn(0),
532 1 : current_exact_logical_size: None,
533 1 : pitr_enabled: true,
534 1 : pitr_cutoff: None,
535 1 : };
536 1 :
537 1 : let now = DateTime::<Utc>::from(SystemTime::now());
538 1 :
539 1 : snap.to_metrics(tenant_id, timeline_id, now, &mut metrics, &cache);
540 1 :
541 1 : assert_eq!(
542 1 : metrics,
543 1 : &[
544 1 : MetricsKey::written_size_delta(tenant_id, timeline_id).from_until(
545 1 : snap.loaded_at.1.into(),
546 1 : now,
547 1 : 0
548 1 : ),
549 1 : MetricsKey::written_size(tenant_id, timeline_id).at(now, disk_consistent_lsn.0),
550 1 : MetricsKey::written_size_since_parent(tenant_id, timeline_id)
551 1 : .at(now, disk_consistent_lsn.0),
552 1 : ]
553 1 : );
554 1 : }
555 :
556 1 : pub(crate) const fn metric_examples_old(
557 1 : tenant_id: TenantId,
558 1 : timeline_id: TimelineId,
559 1 : now: DateTime<Utc>,
560 1 : before: DateTime<Utc>,
561 1 : ) -> [RawMetric; 7] {
562 1 : [
563 1 : MetricsKey::written_size(tenant_id, timeline_id).at_old_format(now, 0),
564 1 : MetricsKey::written_size_delta(tenant_id, timeline_id)
565 1 : .from_until_old_format(before, now, 0),
566 1 : MetricsKey::written_size_since_parent(tenant_id, timeline_id).at_old_format(now, 0),
567 1 : MetricsKey::pitr_history_size_since_parent(tenant_id, timeline_id).at_old_format(now, 0),
568 1 : MetricsKey::timeline_logical_size(tenant_id, timeline_id).at_old_format(now, 0),
569 1 : MetricsKey::remote_storage_size(tenant_id).at_old_format(now, 0),
570 1 : MetricsKey::synthetic_size(tenant_id).at_old_format(now, 1),
571 1 : ]
572 1 : }
573 :
574 3 : pub(crate) const fn metric_examples(
575 3 : tenant_id: TenantId,
576 3 : timeline_id: TimelineId,
577 3 : now: DateTime<Utc>,
578 3 : before: DateTime<Utc>,
579 3 : ) -> [NewRawMetric; 7] {
580 3 : [
581 3 : MetricsKey::written_size(tenant_id, timeline_id).at(now, 0),
582 3 : MetricsKey::written_size_delta(tenant_id, timeline_id).from_until(before, now, 0),
583 3 : MetricsKey::written_size_since_parent(tenant_id, timeline_id).at(now, 0),
584 3 : MetricsKey::pitr_history_size_since_parent(tenant_id, timeline_id).at(now, 0),
585 3 : MetricsKey::timeline_logical_size(tenant_id, timeline_id).at(now, 0),
586 3 : MetricsKey::remote_storage_size(tenant_id).at(now, 0),
587 3 : MetricsKey::synthetic_size(tenant_id).at(now, 1),
588 3 : ]
589 3 : }
|