Skip to content
This repository has been archived by the owner on Nov 1, 2023. It is now read-only.

Retry coverage recording #978

Merged
merged 3 commits into from
Jun 10, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 36 additions & 1 deletion src/agent/onefuzz-agent/src/tasks/coverage/generic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use coverage::cache::ModuleCache;
use coverage::code::{CmdFilter, CmdFilterDef};
use onefuzz::expand::Expand;
use onefuzz::syncdir::SyncedDir;
use onefuzz_telemetry::{Event::coverage_data, EventData};
use onefuzz_telemetry::{warn, Event::coverage_data, EventData};
use serde::de::DeserializeOwned;
use storage_queue::{Message, QueueClient};
use tokio::fs;
Expand All @@ -25,6 +25,7 @@ use crate::tasks::config::CommonConfig;
use crate::tasks::generic::input_poller::{CallbackImpl, InputPoller, Processor};
use crate::tasks::heartbeat::{HeartbeatSender, TaskHeartbeatClient};

const MAX_COVERAGE_RECORDING_ATTEMPTS: usize = 2;
const COVERAGE_FILE: &str = "coverage.json";
const MODULE_CACHE_FILE: &str = "module-cache.json";

Expand Down Expand Up @@ -188,6 +189,40 @@ impl<'a> TaskContext<'a> {
}

pub async fn record_input(&mut self, input: &Path) -> Result<()> {
let attempts = MAX_COVERAGE_RECORDING_ATTEMPTS;

for attempt in 1..=attempts {
let result = self.try_record_input(input).await;

if let Err(err) = &result {
// Recording failed, check if we can retry.
if attempt < attempts {
// We will retry, but warn to capture the error if we succeed.
warn!(
"error recording coverage for input = {}: {:?}",
input.display(),
err
);
} else {
// Final attempt, do not retry.
return result.with_context(|| {
format_err!(
"failed to record coverage for input = {} after {} attempts",
input.display(),
attempts
)
});
}
} else {
// We successfully recorded the coverage for `input`, so stop.
break;
}
}

Ok(())
}

async fn try_record_input(&mut self, input: &Path) -> Result<()> {
let coverage = self.record_impl(input).await?;
self.coverage.merge_max(&coverage);

Expand Down