Skip to content

Commit

Permalink
Add key for block coverage, tests (microsoft#2715)
Browse files Browse the repository at this point in the history
  • Loading branch information
ranweiler authored Dec 20, 2022
1 parent 1726bed commit f7bd508
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 12 deletions.
7 changes: 4 additions & 3 deletions src/agent/coverage/src/binary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,19 @@
use std::collections::{BTreeMap, BTreeSet};

use anyhow::{bail, Result};
use debuggable_module::{block, path::FilePath, Module, Offset};
use debuggable_module::Module;
pub use debuggable_module::{block, path::FilePath, Offset};
use symbolic::debuginfo::Object;
use symbolic::symcache::{SymCache, SymCacheConverter};

use crate::allowlist::TargetAllowList;

#[derive(Clone, Debug, Default)]
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct BinaryCoverage {
pub modules: BTreeMap<FilePath, ModuleBinaryCoverage>,
}

#[derive(Clone, Debug, Default)]
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct ModuleBinaryCoverage {
pub offsets: BTreeMap<Offset, Count>,
}
Expand Down
25 changes: 16 additions & 9 deletions src/agent/onefuzz-file-format/src/coverage/binary/v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,29 @@ use crate::hex::Hex;
#[derive(Deserialize, Serialize)]
pub struct BinaryCoverageJson {
#[serde(flatten)]
pub modules: BTreeMap<String, BTreeMap<Hex, u32>>,
pub modules: BTreeMap<String, ModuleCoverageJson>,
}

#[derive(Deserialize, Serialize)]
pub struct ModuleCoverageJson {
pub blocks: BTreeMap<Hex, u32>,
}

impl From<BinaryCoverage> for BinaryCoverageJson {
fn from(binary: BinaryCoverage) -> Self {
let mut modules = BTreeMap::new();

for (module, offsets) in &binary.modules {
let mut map: BTreeMap<Hex, u32> = BTreeMap::new();
for (path, offsets) in &binary.modules {
let mut blocks: BTreeMap<Hex, u32> = BTreeMap::new();

for (offset, count) in offsets.as_ref() {
map.insert(Hex(offset.0), count.0);
blocks.insert(Hex(offset.0), count.0);
}

let path = module.as_str().to_owned();
modules.insert(path, map);
let path = path.as_str().to_owned();
let module = ModuleCoverageJson { blocks };

modules.insert(path, module);
}

Self { modules }
Expand All @@ -41,15 +48,15 @@ impl TryFrom<BinaryCoverageJson> for BinaryCoverage {
fn try_from(json: BinaryCoverageJson) -> Result<Self> {
let mut process = BinaryCoverage::default();

for (module, offsets) in json.modules {
for (path, module) in json.modules {
let mut coverage = ModuleBinaryCoverage::default();

for (hex, count) in offsets {
for (hex, count) in module.blocks {
let offset = Offset(hex.0);
coverage.offsets.insert(offset, Count(count));
}

let path = FilePath::new(module)?;
let path = FilePath::new(path)?;
process.modules.insert(path, coverage);
}

Expand Down
32 changes: 32 additions & 0 deletions src/agent/onefuzz-file-format/tests/files/binary-coverage.v0.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
[
{
"module": "/setup/main.exe",
"blocks": [
{
"offset": 1,
"count": 0
},
{
"offset": 300,
"count": 1
},
{
"offset": 5000,
"count": 0
}
]
},
{
"module": "/setup/lib/some.dll",
"blocks": [
{
"offset": 123,
"count": 0
},
{
"offset": 456,
"count": 10
}
]
}
]
15 changes: 15 additions & 0 deletions src/agent/onefuzz-file-format/tests/files/binary-coverage.v1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"/setup/main.exe": {
"blocks": {
"1": 0,
"12c": 1,
"1388": 0
}
},
"/setup/lib/some.dll": {
"blocks": {
"7b": 0,
"1c8": 10
}
}
}
45 changes: 45 additions & 0 deletions src/agent/onefuzz-file-format/tests/integration.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

use pretty_assertions::assert_eq;

use anyhow::Result;
use coverage::binary::{BinaryCoverage, Count, FilePath, ModuleBinaryCoverage, Offset};
use onefuzz_file_format::coverage::binary::{v0, v1};

fn expected_binary_coverage() -> Result<BinaryCoverage> {
let main_exe_path = FilePath::new("/setup/main.exe")?;
let some_dll_path = FilePath::new("/setup/lib/some.dll")?;

let mut main_exe = ModuleBinaryCoverage::default();
main_exe.offsets.insert(Offset(1), Count(0));
main_exe.offsets.insert(Offset(300), Count(1));
main_exe.offsets.insert(Offset(5000), Count(0));

let mut some_dll = ModuleBinaryCoverage::default();
some_dll.offsets.insert(Offset(123), Count(0));
some_dll.offsets.insert(Offset(456), Count(10));

let mut binary = BinaryCoverage::default();
binary.modules.insert(some_dll_path, some_dll);
binary.modules.insert(main_exe_path, main_exe);

Ok(binary)
}

#[test]
fn test_binary_coverage_formats() -> Result<()> {
let expected = expected_binary_coverage()?;

let v0_text = include_str!("files/binary-coverage.v0.json");
let v0_json: v0::BinaryCoverageJson = serde_json::from_str(v0_text)?;
let from_v0 = BinaryCoverage::try_from(v0_json)?;
assert_eq!(from_v0, expected);

let v1_text = include_str!("files/binary-coverage.v1.json");
let v1_json: v1::BinaryCoverageJson = serde_json::from_str(v1_text)?;
let from_v1 = BinaryCoverage::try_from(v1_json)?;
assert_eq!(from_v1, expected);

Ok(())
}

0 comments on commit f7bd508

Please sign in to comment.