mirror of
https://github.com/microsoft/onefuzz.git
synced 2025-06-20 21:35:42 +00:00
Add key for block coverage, tests (#2715)
This commit is contained in:
@ -4,18 +4,19 @@
|
|||||||
use std::collections::{BTreeMap, BTreeSet};
|
use std::collections::{BTreeMap, BTreeSet};
|
||||||
|
|
||||||
use anyhow::{bail, Result};
|
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::debuginfo::Object;
|
||||||
use symbolic::symcache::{SymCache, SymCacheConverter};
|
use symbolic::symcache::{SymCache, SymCacheConverter};
|
||||||
|
|
||||||
use crate::allowlist::TargetAllowList;
|
use crate::allowlist::TargetAllowList;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default, Eq, PartialEq)]
|
||||||
pub struct BinaryCoverage {
|
pub struct BinaryCoverage {
|
||||||
pub modules: BTreeMap<FilePath, ModuleBinaryCoverage>,
|
pub modules: BTreeMap<FilePath, ModuleBinaryCoverage>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default, Eq, PartialEq)]
|
||||||
pub struct ModuleBinaryCoverage {
|
pub struct ModuleBinaryCoverage {
|
||||||
pub offsets: BTreeMap<Offset, Count>,
|
pub offsets: BTreeMap<Offset, Count>,
|
||||||
}
|
}
|
||||||
|
@ -13,22 +13,29 @@ use crate::hex::Hex;
|
|||||||
#[derive(Deserialize, Serialize)]
|
#[derive(Deserialize, Serialize)]
|
||||||
pub struct BinaryCoverageJson {
|
pub struct BinaryCoverageJson {
|
||||||
#[serde(flatten)]
|
#[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 {
|
impl From<BinaryCoverage> for BinaryCoverageJson {
|
||||||
fn from(binary: BinaryCoverage) -> Self {
|
fn from(binary: BinaryCoverage) -> Self {
|
||||||
let mut modules = BTreeMap::new();
|
let mut modules = BTreeMap::new();
|
||||||
|
|
||||||
for (module, offsets) in &binary.modules {
|
for (path, offsets) in &binary.modules {
|
||||||
let mut map: BTreeMap<Hex, u32> = BTreeMap::new();
|
let mut blocks: BTreeMap<Hex, u32> = BTreeMap::new();
|
||||||
|
|
||||||
for (offset, count) in offsets.as_ref() {
|
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();
|
let path = path.as_str().to_owned();
|
||||||
modules.insert(path, map);
|
let module = ModuleCoverageJson { blocks };
|
||||||
|
|
||||||
|
modules.insert(path, module);
|
||||||
}
|
}
|
||||||
|
|
||||||
Self { modules }
|
Self { modules }
|
||||||
@ -41,15 +48,15 @@ impl TryFrom<BinaryCoverageJson> for BinaryCoverage {
|
|||||||
fn try_from(json: BinaryCoverageJson) -> Result<Self> {
|
fn try_from(json: BinaryCoverageJson) -> Result<Self> {
|
||||||
let mut process = BinaryCoverage::default();
|
let mut process = BinaryCoverage::default();
|
||||||
|
|
||||||
for (module, offsets) in json.modules {
|
for (path, module) in json.modules {
|
||||||
let mut coverage = ModuleBinaryCoverage::default();
|
let mut coverage = ModuleBinaryCoverage::default();
|
||||||
|
|
||||||
for (hex, count) in offsets {
|
for (hex, count) in module.blocks {
|
||||||
let offset = Offset(hex.0);
|
let offset = Offset(hex.0);
|
||||||
coverage.offsets.insert(offset, Count(count));
|
coverage.offsets.insert(offset, Count(count));
|
||||||
}
|
}
|
||||||
|
|
||||||
let path = FilePath::new(module)?;
|
let path = FilePath::new(path)?;
|
||||||
process.modules.insert(path, coverage);
|
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