diff --git a/src/agent/onefuzz-task/src/tasks/coverage/generic.rs b/src/agent/onefuzz-task/src/tasks/coverage/generic.rs index 8043deee94..3bab90a6a8 100644 --- a/src/agent/onefuzz-task/src/tasks/coverage/generic.rs +++ b/src/agent/onefuzz-task/src/tasks/coverage/generic.rs @@ -28,7 +28,9 @@ use onefuzz_file_format::coverage::{ }; use onefuzz_result::job_result::JobResultData; use onefuzz_result::job_result::{JobResultSender, TaskJobResultClient}; -use onefuzz_telemetry::{event, warn, Event::coverage_data, Event::coverage_failed, EventData}; +use onefuzz_telemetry::{ + event, warn, Event::coverage_data, Event::coverage_empty, Event::coverage_failed, EventData, +}; use storage_queue::{Message, QueueClient}; use tokio::fs; use tokio::sync::RwLock; @@ -148,7 +150,6 @@ impl CoverageTask { info!("report initial coverage"); context.report_coverage_stats().await; - context.heartbeat.alive(); for dir in &self.config.readonly_inputs { @@ -174,7 +175,6 @@ impl CoverageTask { context.save_and_sync_coverage().await?; } - info!("report coverage"); context.report_coverage_stats().await; context.heartbeat.alive(); @@ -308,6 +308,11 @@ impl<'a> TaskContext<'a> { async fn try_record_input(&mut self, input: &Path) -> Result<()> { let coverage = self.record_impl(input).await?; + let coverage_stats = CoverageStats::new(&coverage); + if coverage_stats.covered == 0 { + event!(coverage_empty; EventData::Path = input.display().to_string()); + metric!(coverage_empty; 1.0; EventData::Path = input.display().to_string()); + } let mut self_coverage = RwLock::write(&self.coverage).await; self_coverage.merge(&coverage); Ok(()) diff --git a/src/agent/onefuzz-telemetry/src/lib.rs b/src/agent/onefuzz-telemetry/src/lib.rs index 21e427f06f..637ae32095 100644 --- a/src/agent/onefuzz-telemetry/src/lib.rs +++ b/src/agent/onefuzz-telemetry/src/lib.rs @@ -76,6 +76,7 @@ pub enum Event { task_start, coverage_data, coverage_failed, + coverage_empty, new_result, new_crashdump, new_coverage, @@ -94,6 +95,7 @@ impl Event { Self::task_start => "task_start", Self::coverage_data => "coverage_data", Self::coverage_failed => "coverage_failed", + Self::coverage_empty => "coverage_empty", Self::new_coverage => "new_coverage", Self::new_crashdump => "new_crashdump", Self::new_result => "new_result",