Add key for block coverage, tests (#2715)

This commit is contained in:
Joe Ranweiler
2022-12-20 15:01:25 -08:00
committed by GitHub
parent 1726beda87
commit f7bd50853f
5 changed files with 112 additions and 12 deletions

View File

@ -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>,
}

View File

@ -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 }
@ -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);
}

View File

@ -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
}
]
}
]

View File

@ -0,0 +1,15 @@
{
"/setup/main.exe": {
"blocks": {
"1": 0,
"12c": 1,
"1388": 0
}
},
"/setup/lib/some.dll": {
"blocks": {
"7b": 0,
"1c8": 10
}
}
}

View File

@ -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(())
}