From ffaf01349e3c9ad8f621d015f3e88faaf69fa597 Mon Sep 17 00:00:00 2001 From: Joe Ranweiler Date: Wed, 21 Dec 2022 09:15:50 -0800 Subject: [PATCH 1/4] Rename binary coverage integration test --- src/agent/onefuzz-file-format/tests/{integration.rs => binary.rs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/agent/onefuzz-file-format/tests/{integration.rs => binary.rs} (100%) diff --git a/src/agent/onefuzz-file-format/tests/integration.rs b/src/agent/onefuzz-file-format/tests/binary.rs similarity index 100% rename from src/agent/onefuzz-file-format/tests/integration.rs rename to src/agent/onefuzz-file-format/tests/binary.rs From 92832a5477a68ddd3816cfd20cffab95eff0b6a0 Mon Sep 17 00:00:00 2001 From: Joe Ranweiler Date: Wed, 21 Dec 2022 10:35:34 -0800 Subject: [PATCH 2/4] Add `lines` subkey to v1 source coverage JSON --- .../src/coverage/source/v1.rs | 38 +++++++++++++--- .../tests/files/source-coverage.v0.json | 18 ++++++++ .../tests/files/source-coverage.v1.json | 15 +++++++ src/agent/onefuzz-file-format/tests/source.rs | 44 +++++++++++++++++++ 4 files changed, 110 insertions(+), 5 deletions(-) create mode 100644 src/agent/onefuzz-file-format/tests/files/source-coverage.v0.json create mode 100644 src/agent/onefuzz-file-format/tests/files/source-coverage.v1.json create mode 100644 src/agent/onefuzz-file-format/tests/source.rs diff --git a/src/agent/onefuzz-file-format/src/coverage/source/v1.rs b/src/agent/onefuzz-file-format/src/coverage/source/v1.rs index 4a110795c0..85e7370124 100644 --- a/src/agent/onefuzz-file-format/src/coverage/source/v1.rs +++ b/src/agent/onefuzz-file-format/src/coverage/source/v1.rs @@ -9,13 +9,18 @@ use debuggable_module::path::FilePath; use serde::{Deserialize, Serialize}; pub type SourceFile = String; -pub type LineNumber = u32; pub type HitCount = u32; +pub use line_number::LineNumber; #[derive(Deserialize, Serialize)] pub struct SourceCoverageJson { #[serde(flatten)] - pub modules: BTreeMap>, + pub files: BTreeMap, +} + +#[derive(Deserialize, Serialize)] +pub struct FileCoverageJson { + pub lines: BTreeMap, } impl TryFrom for SourceCoverage { @@ -24,13 +29,13 @@ impl TryFrom for SourceCoverage { fn try_from(json: SourceCoverageJson) -> Result { let mut source = SourceCoverage::default(); - for (file_path, lines) in json.modules { + for (file_path, file_json) in json.files { let file_path = FilePath::new(file_path)?; let mut file = FileCoverage::default(); - for (line, count) in lines { - let line = Line::new(line)?; + for (line_number, count) in file_json.lines { + let line = Line::new(line_number.0)?; let count = Count(count); file.lines.insert(line, count); } @@ -41,3 +46,26 @@ impl TryFrom for SourceCoverage { Ok(source) } } + +mod line_number { + use serde::{Deserialize, Deserializer, Serialize, Serializer}; + + #[derive(Clone, Copy, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)] + pub struct LineNumber(#[serde(with = "self")] pub u32); + + pub fn serialize(val: &u32, serializer: S) -> Result + where + S: Serializer, + { + let s = format!("{}", val); + serializer.serialize_str(&s) + } + + pub fn deserialize<'de, D>(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let s = String::deserialize(deserializer)?; + u32::from_str_radix(&s, 10).map_err(serde::de::Error::custom) + } +} diff --git a/src/agent/onefuzz-file-format/tests/files/source-coverage.v0.json b/src/agent/onefuzz-file-format/tests/files/source-coverage.v0.json new file mode 100644 index 0000000000..8e156e0859 --- /dev/null +++ b/src/agent/onefuzz-file-format/tests/files/source-coverage.v0.json @@ -0,0 +1,18 @@ +[ + { + "file": "src/bin/main.c", + "locations": [ + { "line": 4, "column": 1, "count": 1 }, + { "line": 9, "column": 2, "count": 0 }, + { "line": 12, "column": 3, "count": 5 } + ] + }, + { + "file": "src/lib/common.c", + "locations": [ + { "line": 5, "column": null, "count": 0 }, + { "line": 5, "column": null, "count": 1 }, + { "line": 8, "column": null, "count": 0 } + ] + } +] diff --git a/src/agent/onefuzz-file-format/tests/files/source-coverage.v1.json b/src/agent/onefuzz-file-format/tests/files/source-coverage.v1.json new file mode 100644 index 0000000000..c489fbd8d8 --- /dev/null +++ b/src/agent/onefuzz-file-format/tests/files/source-coverage.v1.json @@ -0,0 +1,15 @@ +{ + "src/bin/main.c": { + "lines": { + "4": 1, + "9": 0, + "12": 5 + } + }, + "src/lib/common.c": { + "lines": { + "5": 1, + "8": 0 + } + } +} diff --git a/src/agent/onefuzz-file-format/tests/source.rs b/src/agent/onefuzz-file-format/tests/source.rs new file mode 100644 index 0000000000..11bf08f536 --- /dev/null +++ b/src/agent/onefuzz-file-format/tests/source.rs @@ -0,0 +1,44 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +use pretty_assertions::assert_eq; + +use anyhow::Result; +use coverage::source::{Count, Line, SourceCoverage}; +use debuggable_module::path::FilePath; +use onefuzz_file_format::coverage::source::{v0, v1}; + +fn expected_source_coverage() -> Result { + let main_path = FilePath::new("src/bin/main.c")?; + let common_path = FilePath::new("src/lib/common.c")?; + + let mut source = SourceCoverage::default(); + + let main = source.files.entry(main_path).or_default(); + main.lines.insert(Line::new(4)?, Count(1)); + main.lines.insert(Line::new(9)?, Count(0)); + main.lines.insert(Line::new(12)?, Count(5)); + + let common = source.files.entry(common_path).or_default(); + common.lines.insert(Line::new(5)?, Count(1)); + common.lines.insert(Line::new(8)?, Count(0)); + + Ok(source) +} + +#[test] +fn test_source_coverage_formats() -> Result<()> { + let expected = expected_source_coverage()?; + + let v0_text = include_str!("files/source-coverage.v0.json"); + let v0_json: v0::SourceCoverageJson = serde_json::from_str(v0_text)?; + let from_v0 = SourceCoverage::try_from(v0_json)?; + assert_eq!(from_v0, expected); + + let v1_text = include_str!("files/source-coverage.v1.json"); + let v1_json: v1::SourceCoverageJson = serde_json::from_str(v1_text)?; + let from_v1 = SourceCoverage::try_from(v1_json)?; + assert_eq!(from_v1, expected); + + Ok(()) +} From dee86b1b156a42e324489cf5f14b569c23c0f230 Mon Sep 17 00:00:00 2001 From: Joe Ranweiler Date: Wed, 21 Dec 2022 10:45:58 -0800 Subject: [PATCH 3/4] Lint --- src/agent/onefuzz-file-format/src/coverage/source/v1.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/agent/onefuzz-file-format/src/coverage/source/v1.rs b/src/agent/onefuzz-file-format/src/coverage/source/v1.rs index 85e7370124..c1eb87d109 100644 --- a/src/agent/onefuzz-file-format/src/coverage/source/v1.rs +++ b/src/agent/onefuzz-file-format/src/coverage/source/v1.rs @@ -66,6 +66,6 @@ mod line_number { D: Deserializer<'de>, { let s = String::deserialize(deserializer)?; - u32::from_str_radix(&s, 10).map_err(serde::de::Error::custom) + s.parse().map_err(serde::de::Error::custom) } } From 36bb1f7c5fdf781d5f4ea638ece682bf7890c9fc Mon Sep 17 00:00:00 2001 From: Joe Ranweiler Date: Wed, 21 Dec 2022 10:57:23 -0800 Subject: [PATCH 4/4] Derive `Eq` --- src/agent/coverage/src/source.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/agent/coverage/src/source.rs b/src/agent/coverage/src/source.rs index 33067e6cc6..10c6cb2342 100644 --- a/src/agent/coverage/src/source.rs +++ b/src/agent/coverage/src/source.rs @@ -15,12 +15,12 @@ use crate::binary::BinaryCoverage; pub use crate::binary::Count; -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug, Default, Eq, PartialEq)] pub struct SourceCoverage { pub files: BTreeMap, } -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug, Default, Eq, PartialEq)] pub struct FileCoverage { pub lines: BTreeMap, }