Skip to content

Commit 2b65a6b

Browse files
committed
Add tests
1 parent 7e839a9 commit 2b65a6b

File tree

2 files changed

+148
-0
lines changed

2 files changed

+148
-0
lines changed

cargo-afl/src/config.rs

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,3 +347,141 @@ fn check_llvm_and_get_config() -> Result<String> {
347347

348348
Ok(llvm_config)
349349
}
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+
#[cfg(not(target_os = "macos"))]
376+
"Note: switching to 'v4.33c'.",
377+
"HEAD is now at",
378+
],
379+
),
380+
(
381+
State::Nonexistent,
382+
State::Stable,
383+
&[
384+
#[cfg(not(target_os = "macos"))]
385+
"Note: switching to 'origin/stable'.",
386+
"HEAD is now at",
387+
],
388+
),
389+
(
390+
State::Submodule,
391+
State::Tag("v4.33c"),
392+
&[
393+
#[cfg(not(target_os = "macos"))]
394+
"Note: switching to 'v4.33c'.",
395+
"HEAD is now at",
396+
],
397+
),
398+
(
399+
State::Submodule,
400+
State::Stable,
401+
&[
402+
#[cfg(not(target_os = "macos"))]
403+
"Note: switching to 'origin/stable'.",
404+
"HEAD is now at",
405+
],
406+
),
407+
// smoelius: It should be possible to go from a tag to the stable version.
408+
(
409+
State::Tag("v4.33c"),
410+
State::Stable,
411+
&["Previous HEAD position was", "HEAD is now at"],
412+
),
413+
// smoelius: It should be possible to go from the stable version to a tag.
414+
(
415+
State::Stable,
416+
State::Tag("v4.33c"),
417+
&["Previous HEAD position was", "HEAD is now at"],
418+
),
419+
];
420+
421+
#[test]
422+
fn update() {
423+
let mut base_dir = common::xdg_base_dir();
424+
425+
for &(before, after, line_prefixes) in TESTCASES {
426+
eprintln!("{before:?} -> {after:?}");
427+
428+
let tempdir = tempdir().unwrap();
429+
430+
// smoelius: Based on https://github.com/whitequark/rust-xdg/issues/44, the recommended
431+
// way of testing with a fake value of `XDG_DATA_HOME` seems to be manually overwriting
432+
// the `data_home` field in `xdg::BaseDirectories`.
433+
base_dir.data_home = Some(tempdir.path().to_path_buf());
434+
435+
let aflplusplus_dir = common::aflplusplus_dir_from_base_dir(&base_dir).unwrap();
436+
437+
assert!(aflplusplus_dir.starts_with(tempdir.path()));
438+
439+
set_aflplusplus_dir_contents(before, &aflplusplus_dir).unwrap();
440+
441+
let mut command = Command::cargo_bin("cargo-afl").unwrap();
442+
command.args(["afl", "config", "--update"]);
443+
command.env("XDG_DATA_HOME", tempdir.path());
444+
match after {
445+
State::Nonexistent | State::Submodule => unreachable!(),
446+
State::Tag(tag) => {
447+
command.args(["--tag", tag]);
448+
}
449+
State::Stable => {}
450+
}
451+
let output = command.output().unwrap();
452+
assert!(output.status.success());
453+
let stderr = String::from_utf8(output.stderr).unwrap();
454+
contains_expected_line_prefixes(&stderr, line_prefixes);
455+
}
456+
}
457+
458+
fn set_aflplusplus_dir_contents(state: State, aflplusplus_dir: &Path) -> Result<()> {
459+
let result = match state {
460+
State::Nonexistent => remove_aflplusplus_dir(aflplusplus_dir),
461+
State::Submodule => copy_aflplusplus_submodule(aflplusplus_dir),
462+
State::Tag(tag) => update_to_stable_or_tag(aflplusplus_dir, Some(tag)),
463+
State::Stable => update_to_stable_or_tag(aflplusplus_dir, None),
464+
};
465+
// smoelius: Sanity.
466+
assert!(
467+
is_repo(aflplusplus_dir)
468+
.is_ok_and(|value| value == matches!(state, State::Tag(_) | State::Stable))
469+
);
470+
result
471+
}
472+
473+
fn contains_expected_line_prefixes(stderr: &str, mut line_prefixes: &[&str]) {
474+
for line in stderr.lines() {
475+
if line_prefixes
476+
.first()
477+
.is_some_and(|prefix| line.starts_with(prefix))
478+
{
479+
line_prefixes = &line_prefixes[1..];
480+
}
481+
}
482+
assert!(
483+
line_prefixes.is_empty(),
484+
"Could not find line prefix {line_prefixes:?}:\n```\n{stderr}```"
485+
);
486+
}
487+
}

cargo-afl/src/main.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,16 @@ mod tests {
535535
}
536536
}
537537

538+
#[test]
539+
fn tag_requires_update() {
540+
let output = cargo_afl(&["config", "--tag", "v4.33c"]).output().unwrap();
541+
assert_failure(&output, None);
542+
assert!(String::from_utf8(output.stderr).unwrap().contains(
543+
"error: the following required arguments were not provided:
544+
--update"
545+
));
546+
}
547+
538548
fn cargo_afl<T: AsRef<OsStr>>(args: &[T]) -> Command {
539549
let mut command = command();
540550
command.arg("afl").args(args).env("NO_SUDO", "1");

0 commit comments

Comments
 (0)