Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[casr-cluster] --diff option. Get diff between two directories with reports. #193

Merged
merged 4 commits into from
Jan 22, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 41 additions & 10 deletions casr/src/bin/casr-cluster.rs
Original file line number Diff line number Diff line change
Expand Up @@ -279,22 +279,26 @@
Ok((before, after))
}

/// Merge new reports from input directory into output directory
/// Merge unique reports from `new` directory into `prev` directory.
/// If `diff` directory is set unique (`new` \ `prev`) reports are saved
anfedotoff marked this conversation as resolved.
Show resolved Hide resolved
/// in `diff` directory.
///
/// # Arguments
///
/// * `input` - path to directory with new CASR reports
/// * `new` - path to directory with new CASR reports
///
/// * `output` - path to output directory with CASR reports
/// * `prev` - path to directory with previous CASR reports
///
/// * `diff` - optional: path to save unique (`new` \ `prev`) reports
///
/// # Return value
///
/// Number of merged reports
fn merge_dirs(input: &Path, output: &Path) -> Result<u64> {
anfedotoff marked this conversation as resolved.
Show resolved Hide resolved
let dir = fs::read_dir(output).with_context(|| {
fn merge_or_diff(new: &Path, prev: &Path, diff: Option<&Path>) -> Result<u64> {
let dir = fs::read_dir(prev).with_context(|| {
format!(
"Error occurred while opening directory with CASR reports. Directory: {}",
output.display()
prev.display()

Check warning on line 301 in casr/src/bin/casr-cluster.rs

View check run for this annotation

Codecov / codecov/patch

casr/src/bin/casr-cluster.rs#L301

Added line #L301 was not covered by tests
)
})?;

Expand All @@ -309,19 +313,26 @@
}
}

let dir = fs::read_dir(input).with_context(|| {
let dir = fs::read_dir(new).with_context(|| {
format!(
"Error occurred while opening directory with CASR reports. Directory: {}",
input.display()
new.display()

Check warning on line 319 in casr/src/bin/casr-cluster.rs

View check run for this annotation

Codecov / codecov/patch

casr/src/bin/casr-cluster.rs#L319

Added line #L319 was not covered by tests
)
})?;

let save_dir = if let Some(diff) = diff {
fs::create_dir(diff)?;
diff
} else {
prev
};

let mut new: u64 = 0;
for entry in dir.flatten() {
if entry.path().extension().is_some() && entry.path().extension().unwrap() == "casrep" {
if let Ok(trace) = stacktrace(entry.path().as_path()) {
if mainhash.insert(trace) {
let target = Path::new(&output).join(entry.file_name());
let target = Path::new(&save_dir).join(entry.file_name());
if target.exists() {
eprintln!(
"File with name {} already exists in OUTPUT_DIR.",
Expand Down Expand Up @@ -408,6 +419,18 @@
INPUT_DIR will be added to OUTPUT_DIR.",
),
)
.arg(
Arg::new("diff")
.long("diff")
.action(ArgAction::Set)
.num_args(3)
.value_parser(clap::value_parser!(PathBuf))
.value_names(["NEW_DIR", "PREV_DIR", "DIFF_DIR"])
.help(
"Compute NEW_DIR \\ PREV_DIR. Save new CASR reports from \
NEW_DIR into DIFF_DIR.",
anfedotoff marked this conversation as resolved.
Show resolved Hide resolved
),
)
.arg(
Arg::new("ignore")
.long("ignore")
Expand Down Expand Up @@ -474,12 +497,20 @@
println!("Number of reports after deduplication: {after}");
} else if matches.contains_id("merge") {
let paths: Vec<&PathBuf> = matches.get_many::<PathBuf>("merge").unwrap().collect();
let new = merge_dirs(paths[0], paths[1])?;
let new = merge_or_diff(paths[0], paths[1], None)?;
println!(
"Merged {} new reports into {} directory",
new,
paths[1].display()
);
} else if matches.contains_id("diff") {
let paths: Vec<&PathBuf> = matches.get_many::<PathBuf>("diff").unwrap().collect();
let new = merge_or_diff(paths[0], paths[1], Some(paths[2]))?;
println!(
"Diff of {} new reports is saved into {} directory",
new,
paths[2].display()
);
}

Ok(())
Expand Down
22 changes: 21 additions & 1 deletion casr/tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2603,9 +2603,11 @@ fn test_casr_cluster_d_and_m() {
let paths = [
abs_path("tests/casr_tests/casrep/dedup/in"),
abs_path("tests/tmp_tests_casr/dedup_out"),
abs_path("tests/tmp_tests_casr/dedup_diff"),
];

let _ = fs::remove_dir_all(&paths[1]);
let _ = fs::remove_dir_all(&paths[2]);

let output = Command::new(*EXE_CASR_CLUSTER.read().unwrap())
.args(["-d", &paths[0], &paths[1]])
Expand Down Expand Up @@ -2648,7 +2650,25 @@ fn test_casr_cluster_d_and_m() {
"Something went wrong while merging directories"
);

let _ = std::fs::remove_dir_all(&paths[1]);
// Test --diff option
dirvec = match fs::read_dir(&paths[1]) {
Ok(vec) => vec,
Err(why) => {
panic!("{:?}", why.kind());
}
};
let casrep = dirvec.next().unwrap().unwrap().path();
let _ = std::fs::remove_file(casrep);
let output = Command::new(*EXE_CASR_CLUSTER.read().unwrap())
.args(["--diff", &paths[0], &paths[1], &paths[2]])
.output()
.expect("failed to start casr-cluster");
let out = String::from_utf8_lossy(&output.stdout);
println!("{}", out);
anfedotoff marked this conversation as resolved.
Show resolved Hide resolved
assert!(
out.contains("Diff of 1 new reports") && (fs::read_dir(&paths[2]).unwrap().count() == 1),
"Something went wrong while diffing directories"
);
}

#[test]
Expand Down
24 changes: 13 additions & 11 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,24 +170,24 @@ Run casr-java:

## casr-js

Create CASR reports (.casrep) from JavaScript reports
Create CASR reports (.casrep) from JavaScript crash reports

Usage: casr-js [OPTIONS] <--stdout|--output <REPORT>> [-- <ARGS>...]

Arguments:
[ARGS]... Add "-- <path> <arguments>" to run

Options:
-o, --output <REPORT> Path to save report. Path can be a directory, then report
name is generated
--stdout Print CASR report to stdout
--stdin <FILE> Stdin file for program
-t, --timeout <SECONDS> Timeout (in seconds) for target execution, 0 value means
that timeout is disabled [default: 0]
--ignore <FILE> File with regular expressions for functions and file paths
that should be ignored
-h, --help Print help
-V, --version Print version
-o, --output <REPORT> Path to save report. Path can be a directory, then report name
is generated
--stdout Print CASR report to stdout
--stdin <FILE> Stdin file for program
-t, --timeout <SECONDS> Timeout (in seconds) for target execution, 0 value means that
timeout is disabled [default: 0]
--ignore <FILE> File with regular expressions for functions and file paths that
should be ignored
-h, --help Print help
-V, --version Print version

Run casr-js:

Expand Down Expand Up @@ -261,6 +261,8 @@ Tool for clustering CASR reports
-m, --merge <INPUT_DIR> <OUTPUT_DIR>
Merge INPUT_DIR into OUTPUT_DIR. Only new CASR reports from INPUT_DIR will be
added to OUTPUT_DIR.
--diff <NEW_DIR> <PREV_DIR> <DIFF_DIR>
Compute NEW_DIR \ PREV_DIR. Save new CASR reports from NEW_DIR into DIFF_DIR.
anfedotoff marked this conversation as resolved.
Show resolved Hide resolved
--ignore <FILE>
File with regular expressions for functions and file paths that should be
ignored
Expand Down