mirror of
https://github.com/microsoft/onefuzz.git
synced 2025-06-20 13:33:46 +00:00
Add key for block coverage, tests (#2715)
This commit is contained in:
@ -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>,
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
@ -0,0 +1,15 @@
|
||||
{
|
||||
"/setup/main.exe": {
|
||||
"blocks": {
|
||||
"1": 0,
|
||||
"12c": 1,
|
||||
"1388": 0
|
||||
}
|
||||
},
|
||||
"/setup/lib/some.dll": {
|
||||
"blocks": {
|
||||
"7b": 0,
|
||||
"1c8": 10
|
||||
}
|
||||
}
|
||||
}
|
45
src/agent/onefuzz-file-format/tests/integration.rs
Normal file
45
src/agent/onefuzz-file-format/tests/integration.rs
Normal 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(())
|
||||
}
|
Reference in New Issue
Block a user