Skip to content

Commit

Permalink
Merge files with same absolute path and different relative paths in t…
Browse files Browse the repository at this point in the history
…he same bucket (#103)
  • Loading branch information
calixteman authored and marco-c committed May 15, 2018
1 parent 7616970 commit 79bec5f
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 45 deletions.
50 changes: 46 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,20 @@ fn merge_results(result: &mut CovResult, result2: &mut CovResult) {
}
}

fn add_results(mut results: Vec<(String,CovResult)>, result_map: &SyncCovResultMap) {
fn add_results(mut results: Vec<(String,CovResult)>, result_map: &SyncCovResultMap, source_dir: &Option<PathBuf>) {
let mut map = result_map.lock().unwrap();
for mut result in results.drain(..) {
match map.entry(result.0) {
let path = match source_dir {
Some(source_dir) => {
// the goal here is to be able to merge results for paths like foo/./bar and foo/bar
match fs::canonicalize(source_dir.join(&result.0)) {
Ok(p) => String::from(p.to_str().unwrap()),
Err(_) => result.0,
}
},
None => result.0
};
match map.entry(path) {
hash_map::Entry::Occupied(obj) => {
merge_results(obj.into_mut(), &mut result.1);
},
Expand Down Expand Up @@ -107,7 +117,7 @@ macro_rules! try_parse {
});
}

pub fn consumer(working_dir: &PathBuf, result_map: &SyncCovResultMap, queue: &WorkQueue, is_llvm: bool, branch_enabled: bool) {
pub fn consumer(working_dir: &PathBuf, source_dir: &Option<PathBuf>, result_map: &SyncCovResultMap, queue: &WorkQueue, is_llvm: bool, branch_enabled: bool) {
let mut gcov_type = GcovType::Unknown;

while let Some(work_item) = queue.pop() {
Expand Down Expand Up @@ -164,14 +174,15 @@ pub fn consumer(working_dir: &PathBuf, result_map: &SyncCovResultMap, queue: &Wo
}
};

add_results(new_results, result_map);
add_results(new_results, result_map, source_dir);
}
}

#[cfg(test)]
mod tests {
use super::*;
use std::collections::HashMap;
use std::sync::{Arc, Mutex};

#[test]
fn test_merge_results() {
Expand Down Expand Up @@ -216,4 +227,35 @@ mod tests {
assert_eq!(func.start, 2);
assert_eq!(func.executed, true);
}

#[test]
fn test_merge_relative_path() {
let f = File::open("./test/relative_path/relative_path.info").expect("Failed to open lcov file");
let file = BufReader::new(&f);
let results = parse_lcov(file, false).unwrap();
let result_map: Arc<SyncCovResultMap> = Arc::new(Mutex::new(HashMap::with_capacity(1)));
add_results(results, &result_map, &Some(PathBuf::from("./test/relative_path")));
let result_map = Arc::try_unwrap(result_map).unwrap().into_inner().unwrap();

assert!(result_map.len() == 1);

let cpp_file = fs::canonicalize(PathBuf::from("./test/relative_path/foo/bar/oof.cpp")).unwrap();
let cpp_file = cpp_file.to_str().unwrap();
let cov_result = result_map.get(cpp_file).unwrap();

assert_eq!(cov_result.lines, [(1,63), (2,63), (3,84), (4,42)].iter().cloned().collect());
assert!(cov_result.functions.contains_key("myfun"));
}

#[test]
fn test_ignore_relative_path() {
let f = File::open("./test/relative_path/relative_path.info").expect("Failed to open lcov file");
let file = BufReader::new(&f);
let results = parse_lcov(file, false).unwrap();
let result_map: Arc<SyncCovResultMap> = Arc::new(Mutex::new(HashMap::with_capacity(3)));
add_results(results, &result_map, &None);
let result_map = Arc::try_unwrap(result_map).unwrap().into_inner().unwrap();

assert!(result_map.len() == 3);
}
}
11 changes: 9 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,12 @@ fn main() {
prefix_dir = source_dir;
}

let source_root = if source_dir != "" {
Some(fs::canonicalize(&source_dir).expect("Source directory does not exist."))
} else {
None
};

let tmp_dir = TempDir::new("grcov").expect("Failed to create temporary directory");
let tmp_path = tmp_dir.path().to_owned();

Expand Down Expand Up @@ -258,10 +264,11 @@ fn main() {
let queue = Arc::clone(&queue);
let result_map = Arc::clone(&result_map);
let working_dir = tmp_path.join(format!("{}", i));
let source_root = source_root.clone();

let t = thread::spawn(move || {
fs::create_dir(&working_dir).expect("Failed to create working directory");
consumer(&working_dir, &result_map, &queue, is_llvm, branch_enabled);
consumer(&working_dir, &source_root, &result_map, &queue, is_llvm, branch_enabled);
});

parsers.push(t);
Expand All @@ -284,7 +291,7 @@ fn main() {
let path_mapping_mutex = Arc::try_unwrap(path_mapping).unwrap();
let path_mapping = path_mapping_mutex.into_inner().unwrap();

let iterator = rewrite_paths(result_map, path_mapping, source_dir, prefix_dir, ignore_global, ignore_not_existing, to_ignore_dirs, filter_option);
let iterator = rewrite_paths(result_map, path_mapping, source_root, prefix_dir, ignore_global, ignore_not_existing, to_ignore_dirs, filter_option);

if output_type == "ade" {
output_activedata_etl(iterator);
Expand Down
Loading

0 comments on commit 79bec5f

Please sign in to comment.