@@ -347,3 +347,153 @@ fn check_llvm_and_get_config() -> Result<String> {
347
347
348
348
Ok ( llvm_config)
349
349
}
350
+
351
+ #[ cfg( test) ]
352
+ mod tests {
353
+ use super :: { copy_aflplusplus_submodule, remove_aflplusplus_dir, update_to_stable_or_tag} ;
354
+ use crate :: { common, config:: is_repo} ;
355
+ use anyhow:: Result ;
356
+ use assert_cmd:: cargo:: CommandCargoExt ;
357
+ use std:: { path:: Path , process:: Command } ;
358
+ use tempfile:: tempdir;
359
+
360
+ #[ derive( Clone , Copy , Debug ) ]
361
+ enum State {
362
+ Nonexistent ,
363
+ Submodule ,
364
+ Tag ( & ' static str ) ,
365
+ Stable ,
366
+ }
367
+
368
+ const TESTCASES : & [ ( State , State , & [ & str ] ) ] = & [
369
+ // smoelius: There is currently no way to update to the submodule.
370
+ // (State::Nonexistent, State::Submodule, &[]),
371
+ (
372
+ State :: Nonexistent ,
373
+ State :: Tag ( "v4.33c" ) ,
374
+ & [
375
+ if cfg ! ( target_os = "macos" ) {
376
+ "Previous HEAD position was"
377
+ } else {
378
+ "Note: switching to 'v4.33c'."
379
+ } ,
380
+ "HEAD is now at" ,
381
+ ] ,
382
+ ) ,
383
+ (
384
+ State :: Nonexistent ,
385
+ State :: Stable ,
386
+ & [
387
+ if cfg ! ( target_os = "macos" ) {
388
+ "Previous HEAD position was"
389
+ } else {
390
+ "Note: switching to 'origin/stable'."
391
+ } ,
392
+ "HEAD is now at" ,
393
+ ] ,
394
+ ) ,
395
+ (
396
+ State :: Submodule ,
397
+ State :: Tag ( "v4.33c" ) ,
398
+ & [
399
+ if cfg ! ( target_os = "macos" ) {
400
+ "Previous HEAD position was"
401
+ } else {
402
+ "Note: switching to 'v4.33c'."
403
+ } ,
404
+ "HEAD is now at" ,
405
+ ] ,
406
+ ) ,
407
+ (
408
+ State :: Submodule ,
409
+ State :: Stable ,
410
+ & [
411
+ if cfg ! ( target_os = "macos" ) {
412
+ "Previous HEAD position was"
413
+ } else {
414
+ "Note: switching to 'origin/stable'."
415
+ } ,
416
+ "HEAD is now at" ,
417
+ ] ,
418
+ ) ,
419
+ // smoelius: It should be possible to go from a tag to the stable version.
420
+ (
421
+ State :: Tag ( "v4.33c" ) ,
422
+ State :: Stable ,
423
+ & [ "Previous HEAD position was" , "HEAD is now at" ] ,
424
+ ) ,
425
+ // smoelius: It should be possible to go from the stable version to a tag.
426
+ (
427
+ State :: Stable ,
428
+ State :: Tag ( "v4.33c" ) ,
429
+ & [ "Previous HEAD position was" , "HEAD is now at" ] ,
430
+ ) ,
431
+ ] ;
432
+
433
+ #[ test]
434
+ fn update ( ) {
435
+ let mut base_dir = common:: xdg_base_dir ( ) ;
436
+
437
+ for & ( before, after, line_prefixes) in TESTCASES {
438
+ eprintln ! ( "{before:?} -> {after:?}" ) ;
439
+
440
+ let tempdir = tempdir ( ) . unwrap ( ) ;
441
+
442
+ // smoelius: Based on https://github.com/whitequark/rust-xdg/issues/44, the recommended
443
+ // way of testing with a fake value of `XDG_DATA_HOME` seems to be manually overwriting
444
+ // the `data_home` field in `xdg::BaseDirectories`.
445
+ base_dir. data_home = Some ( tempdir. path ( ) . to_path_buf ( ) ) ;
446
+
447
+ let aflplusplus_dir = common:: aflplusplus_dir_from_base_dir ( & base_dir) . unwrap ( ) ;
448
+
449
+ assert ! ( aflplusplus_dir. starts_with( tempdir. path( ) ) ) ;
450
+
451
+ set_aflplusplus_dir_contents ( before, & aflplusplus_dir) . unwrap ( ) ;
452
+
453
+ let mut command = Command :: cargo_bin ( "cargo-afl" ) . unwrap ( ) ;
454
+ command. args ( [ "afl" , "config" , "--update" ] ) ;
455
+ command. env ( "XDG_DATA_HOME" , tempdir. path ( ) ) ;
456
+ match after {
457
+ State :: Nonexistent | State :: Submodule => unreachable ! ( ) ,
458
+ State :: Tag ( tag) => {
459
+ command. args ( [ "--tag" , tag] ) ;
460
+ }
461
+ State :: Stable => { }
462
+ }
463
+ let output = command. output ( ) . unwrap ( ) ;
464
+ assert ! ( output. status. success( ) ) ;
465
+ let stderr = String :: from_utf8 ( output. stderr ) . unwrap ( ) ;
466
+ contains_expected_line_prefixes ( & stderr, line_prefixes) ;
467
+ }
468
+ }
469
+
470
+ fn set_aflplusplus_dir_contents ( state : State , aflplusplus_dir : & Path ) -> Result < ( ) > {
471
+ let result = match state {
472
+ State :: Nonexistent => remove_aflplusplus_dir ( aflplusplus_dir) ,
473
+ State :: Submodule => copy_aflplusplus_submodule ( aflplusplus_dir) ,
474
+ State :: Tag ( tag) => update_to_stable_or_tag ( aflplusplus_dir, Some ( tag) ) ,
475
+ State :: Stable => update_to_stable_or_tag ( aflplusplus_dir, None ) ,
476
+ } ;
477
+ // smoelius: Sanity.
478
+ assert ! (
479
+ is_repo( aflplusplus_dir)
480
+ . is_ok_and( |value| value == matches!( state, State :: Tag ( _) | State :: Stable ) )
481
+ ) ;
482
+ result
483
+ }
484
+
485
+ fn contains_expected_line_prefixes ( stderr : & str , mut line_prefixes : & [ & str ] ) {
486
+ for line in stderr. lines ( ) {
487
+ if line_prefixes
488
+ . first ( )
489
+ . is_some_and ( |prefix| line. starts_with ( prefix) )
490
+ {
491
+ line_prefixes = & line_prefixes[ 1 ..] ;
492
+ }
493
+ }
494
+ assert ! (
495
+ line_prefixes. is_empty( ) ,
496
+ "Could not find line prefix {line_prefixes:?}:\n ```\n {stderr}```"
497
+ ) ;
498
+ }
499
+ }
0 commit comments