Generate source-line coverage in task (#1535)

This commit is contained in:
Joe Ranweiler
2022-01-07 14:58:37 -08:00
committed by GitHub
parent f505ece25f
commit c3ab5089e8

View File

@ -12,6 +12,7 @@ use async_trait::async_trait;
use coverage::block::CommandBlockCov; use coverage::block::CommandBlockCov;
use coverage::cache::ModuleCache; use coverage::cache::ModuleCache;
use coverage::code::{CmdFilter, CmdFilterDef}; use coverage::code::{CmdFilter, CmdFilterDef};
use coverage::debuginfo::DebugInfo;
use onefuzz::expand::{Expand, PlaceHolder}; use onefuzz::expand::{Expand, PlaceHolder};
use onefuzz::syncdir::SyncedDir; use onefuzz::syncdir::SyncedDir;
use onefuzz_telemetry::{warn, Event::coverage_data, EventData}; use onefuzz_telemetry::{warn, Event::coverage_data, EventData};
@ -28,6 +29,7 @@ use crate::tasks::heartbeat::{HeartbeatSender, TaskHeartbeatClient};
const MAX_COVERAGE_RECORDING_ATTEMPTS: usize = 2; const MAX_COVERAGE_RECORDING_ATTEMPTS: usize = 2;
const COVERAGE_FILE: &str = "coverage.json"; const COVERAGE_FILE: &str = "coverage.json";
const SOURCE_COVERAGE_FILE: &str = "source-coverage.json";
const MODULE_CACHE_FILE: &str = "module-cache.json"; const MODULE_CACHE_FILE: &str = "module-cache.json";
const DEFAULT_TARGET_TIMEOUT: Duration = Duration::from_secs(5); const DEFAULT_TARGET_TIMEOUT: Duration = Duration::from_secs(5);
@ -168,6 +170,7 @@ struct TaskContext<'a> {
cache: Arc<Mutex<ModuleCache>>, cache: Arc<Mutex<ModuleCache>>,
config: &'a Config, config: &'a Config,
coverage: CommandBlockCov, coverage: CommandBlockCov,
debuginfo: Mutex<DebugInfo>,
filter: CmdFilter, filter: CmdFilter,
heartbeat: Option<TaskHeartbeatClient>, heartbeat: Option<TaskHeartbeatClient>,
} }
@ -181,11 +184,13 @@ impl<'a> TaskContext<'a> {
heartbeat: Option<TaskHeartbeatClient>, heartbeat: Option<TaskHeartbeatClient>,
) -> Self { ) -> Self {
let cache = Arc::new(Mutex::new(cache)); let cache = Arc::new(Mutex::new(cache));
let debuginfo = Mutex::new(DebugInfo::default());
Self { Self {
cache, cache,
config, config,
coverage, coverage,
debuginfo,
filter, filter,
heartbeat, heartbeat,
} }
@ -339,11 +344,24 @@ impl<'a> TaskContext<'a> {
pub async fn save_and_sync_coverage(&self) -> Result<()> { pub async fn save_and_sync_coverage(&self) -> Result<()> {
let path = self.config.coverage.local_path.join(COVERAGE_FILE); let path = self.config.coverage.local_path.join(COVERAGE_FILE);
let text = serde_json::to_string(&self.coverage).context("serializing coverage to JSON")?; let text = serde_json::to_string(&self.coverage).context("serializing block coverage")?;
fs::write(&path, &text) fs::write(&path, &text)
.await .await
.with_context(|| format!("writing coverage to {}", path.display()))?; .with_context(|| format!("writing coverage to {}", path.display()))?;
let path = self.config.coverage.local_path.join(SOURCE_COVERAGE_FILE);
let src_coverage = {
let mut debuginfo = self
.debuginfo
.lock()
.map_err(|e| anyhow::format_err!("{}", e))?;
self.coverage.source_coverage(&mut *debuginfo)?
};
let text = serde_json::to_string(&src_coverage).context("serializing source coverage")?;
fs::write(&path, &text)
.await
.with_context(|| format!("writing source coverage to {}", path.display()))?;
self.config.coverage.sync_push().await?; self.config.coverage.sync_push().await?;
Ok(()) Ok(())