Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/crates/cache/src/config/tests.rs
1693 views
1
use super::CacheConfig;
2
use std::fs;
3
use std::path::PathBuf;
4
use std::time::Duration;
5
use tempfile::TempDir;
6
7
// note: config loading during validation creates cache directory to canonicalize its path,
8
// that's why these function and macro always use custom cache directory
9
// note: tempdir removes directory when being dropped, so we need to return it to the caller,
10
// so the paths are valid
11
pub fn test_prolog() -> (TempDir, PathBuf, PathBuf) {
12
let _ = env_logger::try_init();
13
let temp_dir = tempfile::tempdir().expect("Can't create temporary directory");
14
let cache_dir = temp_dir.path().join("cache-dir");
15
let config_path = temp_dir.path().join("cache-config.toml");
16
(temp_dir, cache_dir, config_path)
17
}
18
19
macro_rules! load_config {
20
($config_path:ident, $content_fmt:expr, $cache_dir:ident) => {{
21
let config_path = &$config_path;
22
let content = format!($content_fmt, cache_dir = $cache_dir.display());
23
fs::write(config_path, content).expect("Failed to write test config file");
24
CacheConfig::from_file(Some(config_path)).unwrap()
25
}};
26
}
27
28
macro_rules! bad_config {
29
($config_path:ident, $content_fmt:expr, $cache_dir:ident) => {{
30
let config_path = &$config_path;
31
let content = format!($content_fmt, cache_dir = $cache_dir.display());
32
fs::write(config_path, content).expect("Failed to write test config file");
33
assert!(CacheConfig::from_file(Some(config_path)).is_err());
34
}};
35
}
36
37
#[test]
38
fn test_unrecognized_settings() {
39
let (_td, cd, cp) = test_prolog();
40
bad_config!(
41
cp,
42
"unrecognized-setting = 42\n\
43
[cache]\n\
44
directory = '{cache_dir}'",
45
cd
46
);
47
48
bad_config!(
49
cp,
50
"[cache]\n\
51
directory = '{cache_dir}'\n\
52
unrecognized-setting = 42",
53
cd
54
);
55
}
56
57
#[test]
58
fn test_all_settings() {
59
let (_td, cd, cp) = test_prolog();
60
let conf = load_config!(
61
cp,
62
"[cache]\n\
63
directory = '{cache_dir}'\n\
64
worker-event-queue-size = '16'\n\
65
baseline-compression-level = 3\n\
66
optimized-compression-level = 20\n\
67
optimized-compression-usage-counter-threshold = '256'\n\
68
cleanup-interval = '1h'\n\
69
optimizing-compression-task-timeout = '30m'\n\
70
allowed-clock-drift-for-files-from-future = '1d'\n\
71
file-count-soft-limit = '65536'\n\
72
files-total-size-soft-limit = '512Mi'\n\
73
file-count-limit-percent-if-deleting = '70%'\n\
74
files-total-size-limit-percent-if-deleting = '70%'",
75
cd
76
);
77
check_conf(&conf, &cd);
78
79
let conf = load_config!(
80
cp,
81
// added some white spaces
82
"[cache]\n\
83
directory = '{cache_dir}'\n\
84
worker-event-queue-size = ' 16\t'\n\
85
baseline-compression-level = 3\n\
86
optimized-compression-level =\t 20\n\
87
optimized-compression-usage-counter-threshold = '256'\n\
88
cleanup-interval = ' 1h'\n\
89
optimizing-compression-task-timeout = '30 m'\n\
90
allowed-clock-drift-for-files-from-future = '1\td'\n\
91
file-count-soft-limit = '\t \t65536\t'\n\
92
files-total-size-soft-limit = '512\t\t Mi '\n\
93
file-count-limit-percent-if-deleting = '70\t%'\n\
94
files-total-size-limit-percent-if-deleting = ' 70 %'",
95
cd
96
);
97
check_conf(&conf, &cd);
98
99
fn check_conf(conf: &CacheConfig, cd: &PathBuf) {
100
assert_eq!(
101
conf.directory(),
102
Some(&fs::canonicalize(cd).expect("canonicalize failed"))
103
);
104
assert_eq!(conf.worker_event_queue_size(), 0x10);
105
assert_eq!(conf.baseline_compression_level(), 3);
106
assert_eq!(conf.optimized_compression_level(), 20);
107
assert_eq!(conf.optimized_compression_usage_counter_threshold(), 0x100);
108
assert_eq!(conf.cleanup_interval(), Duration::from_secs(60 * 60));
109
assert_eq!(
110
conf.optimizing_compression_task_timeout(),
111
Duration::from_secs(30 * 60)
112
);
113
assert_eq!(
114
conf.allowed_clock_drift_for_files_from_future(),
115
Duration::from_secs(60 * 60 * 24)
116
);
117
assert_eq!(conf.file_count_soft_limit(), 0x10_000);
118
assert_eq!(conf.files_total_size_soft_limit(), 512 * (1u64 << 20));
119
assert_eq!(conf.file_count_limit_percent_if_deleting(), 70);
120
assert_eq!(conf.files_total_size_limit_percent_if_deleting(), 70);
121
}
122
}
123
124
#[test]
125
fn test_compression_level_settings() {
126
let (_td, cd, cp) = test_prolog();
127
let conf = load_config!(
128
cp,
129
"[cache]\n\
130
directory = '{cache_dir}'\n\
131
baseline-compression-level = 1\n\
132
optimized-compression-level = 21",
133
cd
134
);
135
assert_eq!(conf.baseline_compression_level(), 1);
136
assert_eq!(conf.optimized_compression_level(), 21);
137
138
bad_config!(
139
cp,
140
"[cache]\n\
141
directory = '{cache_dir}'\n\
142
baseline-compression-level = -1\n\
143
optimized-compression-level = 21",
144
cd
145
);
146
147
bad_config!(
148
cp,
149
"[cache]\n\
150
directory = '{cache_dir}'\n\
151
baseline-compression-level = 15\n\
152
optimized-compression-level = 10",
153
cd
154
);
155
}
156
157
#[test]
158
fn test_si_prefix_settings() {
159
let (_td, cd, cp) = test_prolog();
160
let conf = load_config!(
161
cp,
162
"[cache]\n\
163
directory = '{cache_dir}'\n\
164
worker-event-queue-size = '42'\n\
165
optimized-compression-usage-counter-threshold = '4K'\n\
166
file-count-soft-limit = '3M'",
167
cd
168
);
169
assert_eq!(conf.worker_event_queue_size(), 42);
170
assert_eq!(conf.optimized_compression_usage_counter_threshold(), 4_000);
171
assert_eq!(conf.file_count_soft_limit(), 3_000_000);
172
173
let conf = load_config!(
174
cp,
175
"[cache]\n\
176
directory = '{cache_dir}'\n\
177
worker-event-queue-size = '2K'\n\
178
optimized-compression-usage-counter-threshold = '4444T'\n\
179
file-count-soft-limit = '1P'",
180
cd
181
);
182
assert_eq!(conf.worker_event_queue_size(), 2_000);
183
assert_eq!(
184
conf.optimized_compression_usage_counter_threshold(),
185
4_444_000_000_000_000
186
);
187
assert_eq!(conf.file_count_soft_limit(), 1_000_000_000_000_000);
188
189
// different errors
190
bad_config!(
191
cp,
192
"[cache]\n\
193
directory = '{cache_dir}'\n\
194
worker-event-queue-size = '2g'",
195
cd
196
);
197
198
bad_config!(
199
cp,
200
"[cache]\n\
201
directory = '{cache_dir}'\n\
202
file-count-soft-limit = 1",
203
cd
204
);
205
206
bad_config!(
207
cp,
208
"[cache]\n\
209
directory = '{cache_dir}'\n\
210
file-count-soft-limit = '-31337'",
211
cd
212
);
213
214
bad_config!(
215
cp,
216
"[cache]\n\
217
directory = '{cache_dir}'\n\
218
file-count-soft-limit = '3.14M'",
219
cd
220
);
221
}
222
223
#[test]
224
fn test_disk_space_settings() {
225
let (_td, cd, cp) = test_prolog();
226
let conf = load_config!(
227
cp,
228
"[cache]\n\
229
directory = '{cache_dir}'\n\
230
files-total-size-soft-limit = '76'",
231
cd
232
);
233
assert_eq!(conf.files_total_size_soft_limit(), 76);
234
235
let conf = load_config!(
236
cp,
237
"[cache]\n\
238
directory = '{cache_dir}'\n\
239
files-total-size-soft-limit = '42 Mi'",
240
cd
241
);
242
assert_eq!(conf.files_total_size_soft_limit(), 42 * (1u64 << 20));
243
244
let conf = load_config!(
245
cp,
246
"[cache]\n\
247
directory = '{cache_dir}'\n\
248
files-total-size-soft-limit = '2 Gi'",
249
cd
250
);
251
assert_eq!(conf.files_total_size_soft_limit(), 2 * (1u64 << 30));
252
253
let conf = load_config!(
254
cp,
255
"[cache]\n\
256
directory = '{cache_dir}'\n\
257
files-total-size-soft-limit = '31337 Ti'",
258
cd
259
);
260
assert_eq!(conf.files_total_size_soft_limit(), 31337 * (1u64 << 40));
261
262
let conf = load_config!(
263
cp,
264
"[cache]\n\
265
directory = '{cache_dir}'\n\
266
files-total-size-soft-limit = '7 Pi'",
267
cd
268
);
269
assert_eq!(conf.files_total_size_soft_limit(), 7 * (1u64 << 50));
270
271
let conf = load_config!(
272
cp,
273
"[cache]\n\
274
directory = '{cache_dir}'\n\
275
files-total-size-soft-limit = '7M'",
276
cd
277
);
278
assert_eq!(conf.files_total_size_soft_limit(), 7_000_000);
279
280
// different errors
281
bad_config!(
282
cp,
283
"[cache]\n\
284
directory = '{cache_dir}'\n\
285
files-total-size-soft-limit = '7 mi'",
286
cd
287
);
288
289
bad_config!(
290
cp,
291
"[cache]\n\
292
directory = '{cache_dir}'\n\
293
files-total-size-soft-limit = 1",
294
cd
295
);
296
297
bad_config!(
298
cp,
299
"[cache]\n\
300
directory = '{cache_dir}'\n\
301
files-total-size-soft-limit = '-31337'",
302
cd
303
);
304
305
bad_config!(
306
cp,
307
"[cache]\n\
308
directory = '{cache_dir}'\n\
309
files-total-size-soft-limit = '3.14Ki'",
310
cd
311
);
312
}
313
314
#[test]
315
fn test_duration_settings() {
316
let (_td, cd, cp) = test_prolog();
317
let conf = load_config!(
318
cp,
319
"[cache]\n\
320
directory = '{cache_dir}'\n\
321
cleanup-interval = '100s'\n\
322
optimizing-compression-task-timeout = '3m'\n\
323
allowed-clock-drift-for-files-from-future = '4h'",
324
cd
325
);
326
assert_eq!(conf.cleanup_interval(), Duration::from_secs(100));
327
assert_eq!(
328
conf.optimizing_compression_task_timeout(),
329
Duration::from_secs(3 * 60)
330
);
331
assert_eq!(
332
conf.allowed_clock_drift_for_files_from_future(),
333
Duration::from_secs(4 * 60 * 60)
334
);
335
336
let conf = load_config!(
337
cp,
338
"[cache]\n\
339
directory = '{cache_dir}'\n\
340
cleanup-interval = '2d'\n\
341
optimizing-compression-task-timeout = '333 m'",
342
cd
343
);
344
assert_eq!(
345
conf.cleanup_interval(),
346
Duration::from_secs(2 * 24 * 60 * 60)
347
);
348
assert_eq!(
349
conf.optimizing_compression_task_timeout(),
350
Duration::from_secs(333 * 60)
351
);
352
353
// different errors
354
bad_config!(
355
cp,
356
"[cache]\n\
357
directory = '{cache_dir}'\n\
358
optimizing-compression-task-timeout = '333'",
359
cd
360
);
361
362
bad_config!(
363
cp,
364
"[cache]\n\
365
directory = '{cache_dir}'\n\
366
optimizing-compression-task-timeout = 333",
367
cd
368
);
369
370
bad_config!(
371
cp,
372
"[cache]\n\
373
directory = '{cache_dir}'\n\
374
optimizing-compression-task-timeout = '10 M'",
375
cd
376
);
377
378
bad_config!(
379
cp,
380
"[cache]\n\
381
directory = '{cache_dir}'\n\
382
optimizing-compression-task-timeout = '10 min'",
383
cd
384
);
385
386
bad_config!(
387
cp,
388
"[cache]\n\
389
directory = '{cache_dir}'\n\
390
optimizing-compression-task-timeout = '-10s'",
391
cd
392
);
393
394
bad_config!(
395
cp,
396
"[cache]\n\
397
directory = '{cache_dir}'\n\
398
optimizing-compression-task-timeout = '1.5m'",
399
cd
400
);
401
}
402
403
#[test]
404
fn test_percent_settings() {
405
let (_td, cd, cp) = test_prolog();
406
let conf = load_config!(
407
cp,
408
"[cache]\n\
409
directory = '{cache_dir}'\n\
410
file-count-limit-percent-if-deleting = '62%'\n\
411
files-total-size-limit-percent-if-deleting = '23 %'",
412
cd
413
);
414
assert_eq!(conf.file_count_limit_percent_if_deleting(), 62);
415
assert_eq!(conf.files_total_size_limit_percent_if_deleting(), 23);
416
417
// different errors
418
bad_config!(
419
cp,
420
"[cache]\n\
421
directory = '{cache_dir}'\n\
422
files-total-size-limit-percent-if-deleting = '23'",
423
cd
424
);
425
426
bad_config!(
427
cp,
428
"[cache]\n\
429
directory = '{cache_dir}'\n\
430
files-total-size-limit-percent-if-deleting = '22.5%'",
431
cd
432
);
433
434
bad_config!(
435
cp,
436
"[cache]\n\
437
directory = '{cache_dir}'\n\
438
files-total-size-limit-percent-if-deleting = '0.5'",
439
cd
440
);
441
442
bad_config!(
443
cp,
444
"[cache]\n\
445
directory = '{cache_dir}'\n\
446
files-total-size-limit-percent-if-deleting = '-1%'",
447
cd
448
);
449
450
bad_config!(
451
cp,
452
"[cache]\n\
453
directory = '{cache_dir}'\n\
454
files-total-size-limit-percent-if-deleting = '101%'",
455
cd
456
);
457
}
458
459
/// Default builder produces a disabled cache configuration with the same defaults.
460
#[test]
461
fn test_builder_default() {
462
let (_td, _cd, cp) = test_prolog();
463
let config_content = "[cache]\n";
464
fs::write(&cp, config_content).expect("Failed to write test config file");
465
let expected_config = CacheConfig::from_file(Some(&cp)).unwrap();
466
467
let mut config = CacheConfig::new();
468
config
469
.validate()
470
.expect("Failed to validate default config");
471
472
assert_eq!(config.directory, expected_config.directory);
473
assert_eq!(
474
config.worker_event_queue_size,
475
expected_config.worker_event_queue_size
476
);
477
assert_eq!(
478
config.baseline_compression_level,
479
expected_config.baseline_compression_level
480
);
481
assert_eq!(
482
config.optimized_compression_level,
483
expected_config.optimized_compression_level
484
);
485
assert_eq!(
486
config.optimized_compression_usage_counter_threshold,
487
expected_config.optimized_compression_usage_counter_threshold
488
);
489
assert_eq!(config.cleanup_interval, expected_config.cleanup_interval);
490
assert_eq!(
491
config.optimizing_compression_task_timeout,
492
expected_config.optimizing_compression_task_timeout
493
);
494
assert_eq!(
495
config.allowed_clock_drift_for_files_from_future,
496
expected_config.allowed_clock_drift_for_files_from_future
497
);
498
assert_eq!(
499
config.file_count_soft_limit,
500
expected_config.file_count_soft_limit
501
);
502
assert_eq!(
503
config.files_total_size_soft_limit,
504
expected_config.files_total_size_soft_limit
505
);
506
assert_eq!(
507
config.file_count_limit_percent_if_deleting,
508
expected_config.file_count_limit_percent_if_deleting
509
);
510
assert_eq!(
511
config.files_total_size_limit_percent_if_deleting,
512
expected_config.files_total_size_limit_percent_if_deleting
513
);
514
}
515
516
#[test]
517
fn test_builder_all_settings() {
518
let (_td, cd, _cp) = test_prolog();
519
520
let mut conf = CacheConfig::new();
521
conf.with_directory(&cd)
522
.with_worker_event_queue_size(0x10)
523
.with_baseline_compression_level(3)
524
.with_optimized_compression_level(20)
525
.with_optimized_compression_usage_counter_threshold(0x100)
526
.with_cleanup_interval(Duration::from_secs(60 * 60))
527
.with_optimizing_compression_task_timeout(Duration::from_secs(30 * 60))
528
.with_allowed_clock_drift_for_files_from_future(Duration::from_secs(60 * 60 * 24))
529
.with_file_count_soft_limit(0x10_000)
530
.with_files_total_size_soft_limit(512 * (1u64 << 20))
531
.with_file_count_limit_percent_if_deleting(70)
532
.with_files_total_size_limit_percent_if_deleting(70);
533
conf.validate().expect("validation failed");
534
check_conf(&conf, &cd);
535
536
fn check_conf(conf: &CacheConfig, cd: &PathBuf) {
537
assert_eq!(
538
conf.directory(),
539
Some(&fs::canonicalize(cd).expect("canonicalize failed"))
540
);
541
assert_eq!(conf.worker_event_queue_size(), 0x10);
542
assert_eq!(conf.baseline_compression_level(), 3);
543
assert_eq!(conf.optimized_compression_level(), 20);
544
assert_eq!(conf.optimized_compression_usage_counter_threshold(), 0x100);
545
assert_eq!(conf.cleanup_interval(), Duration::from_secs(60 * 60));
546
assert_eq!(
547
conf.optimizing_compression_task_timeout(),
548
Duration::from_secs(30 * 60)
549
);
550
assert_eq!(
551
conf.allowed_clock_drift_for_files_from_future(),
552
Duration::from_secs(60 * 60 * 24)
553
);
554
assert_eq!(conf.file_count_soft_limit(), 0x10_000);
555
assert_eq!(conf.files_total_size_soft_limit(), 512 * (1u64 << 20));
556
assert_eq!(conf.file_count_limit_percent_if_deleting(), 70);
557
assert_eq!(conf.files_total_size_limit_percent_if_deleting(), 70);
558
}
559
}
560
561