Skip to content

Commit 32b00ea

Browse files
committed
Add tests
1 parent 9f404a7 commit 32b00ea

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
@@ -330,3 +330,141 @@ fn check_llvm_and_get_config() -> Result<String> {
330330

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

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)