From dd879f6e788876267de94784711d79e51a403483 Mon Sep 17 00:00:00 2001 From: Cheick Keita Date: Thu, 10 Aug 2023 16:57:28 -0700 Subject: [PATCH] deserialize the coverage files directly into the output files --- src/agent/cobertura/src/lib.rs | 71 ++++++++++--------- .../src/tasks/coverage/generic.rs | 27 ++++--- 2 files changed, 56 insertions(+), 42 deletions(-) diff --git a/src/agent/cobertura/src/lib.rs b/src/agent/cobertura/src/lib.rs index 9becf4a1130..73e6f6f6e7d 100644 --- a/src/agent/cobertura/src/lib.rs +++ b/src/agent/cobertura/src/lib.rs @@ -12,15 +12,20 @@ impl CoberturaCoverage { let mut writer = Writer::new_with_indent(cursor, b' ', 2); - self.write_xml(&mut writer)?; + self.write_xml_(&mut writer)?; let text = String::from_utf8(data)?; Ok(text) } } -trait WriteXml { - fn write_xml(&self, writer: &mut Writer) -> Result<()>; +pub trait WriteXml { + fn write_xml_(&self, writer: &mut Writer) -> Result<()>; + + fn write_xml(&self, writer: W) -> Result<()> { + let mut writer = Writer::new(writer); + self.write_xml_(&mut writer) + } } // Only write optional fields if present. @@ -28,9 +33,9 @@ impl WriteXml for Option where T: WriteXml, { - fn write_xml(&self, writer: &mut Writer) -> Result<()> { + fn write_xml_(&self, writer: &mut Writer) -> Result<()> { if let Some(value) = self { - value.write_xml(writer)?; + value.write_xml_(writer)?; } Ok(()) @@ -41,9 +46,9 @@ impl WriteXml for Vec where T: WriteXml, { - fn write_xml(&self, writer: &mut Writer) -> Result<()> { + fn write_xml_(&self, writer: &mut Writer) -> Result<()> { for value in self { - value.write_xml(writer)?; + value.write_xml_(writer)?; } Ok(()) @@ -101,7 +106,7 @@ pub struct CoberturaCoverage { } impl WriteXml for CoberturaCoverage { - fn write_xml(&self, writer: &mut Writer) -> Result<()> { + fn write_xml_(&self, writer: &mut Writer) -> Result<()> { writer .create_element("coverage") .with_attributes([ @@ -116,8 +121,8 @@ impl WriteXml for CoberturaCoverage { ("timestamp", uint!(self.timestamp)), ]) .write_inner_content(|w| { - self.sources.write_xml(w)?; - self.packages.write_xml(w)?; + self.sources.write_xml_(w)?; + self.packages.write_xml_(w)?; Ok(()) })?; @@ -133,10 +138,10 @@ pub struct Sources { } impl WriteXml for Sources { - fn write_xml(&self, writer: &mut Writer) -> Result<()> { + fn write_xml_(&self, writer: &mut Writer) -> Result<()> { writer .create_element("sources") - .write_inner_content(|w| self.sources.write_xml(w))?; + .write_inner_content(|w| self.sources.write_xml_(w))?; Ok(()) } @@ -149,7 +154,7 @@ pub struct Source { } impl WriteXml for Source { - fn write_xml(&self, writer: &mut Writer) -> Result<()> { + fn write_xml_(&self, writer: &mut Writer) -> Result<()> { writer .create_element("source") .with_attributes([("path", string!(self.path))]) @@ -166,10 +171,10 @@ pub struct Packages { } impl WriteXml for Packages { - fn write_xml(&self, writer: &mut Writer) -> Result<()> { + fn write_xml_(&self, writer: &mut Writer) -> Result<()> { writer .create_element("packages") - .write_inner_content(|w| self.packages.write_xml(w))?; + .write_inner_content(|w| self.packages.write_xml_(w))?; Ok(()) } @@ -191,7 +196,7 @@ pub struct Package { } impl WriteXml for Package { - fn write_xml(&self, writer: &mut Writer) -> Result<()> { + fn write_xml_(&self, writer: &mut Writer) -> Result<()> { writer .create_element("package") .with_attributes([ @@ -200,7 +205,7 @@ impl WriteXml for Package { ("branch-rate", float!(self.branch_rate)), ("complexity", uint!(self.complexity)), ]) - .write_inner_content(|w| self.classes.write_xml(w))?; + .write_inner_content(|w| self.classes.write_xml_(w))?; Ok(()) } @@ -213,10 +218,10 @@ pub struct Classes { } impl WriteXml for Classes { - fn write_xml(&self, writer: &mut Writer) -> Result<()> { + fn write_xml_(&self, writer: &mut Writer) -> Result<()> { writer .create_element("classes") - .write_inner_content(|w| self.classes.write_xml(w))?; + .write_inner_content(|w| self.classes.write_xml_(w))?; Ok(()) } @@ -241,7 +246,7 @@ pub struct Class { } impl WriteXml for Class { - fn write_xml(&self, writer: &mut Writer) -> Result<()> { + fn write_xml_(&self, writer: &mut Writer) -> Result<()> { writer .create_element("class") .with_attributes([ @@ -252,8 +257,8 @@ impl WriteXml for Class { ("complexity", uint!(self.complexity)), ]) .write_inner_content(|w| { - self.methods.write_xml(w)?; - self.lines.write_xml(w)?; + self.methods.write_xml_(w)?; + self.lines.write_xml_(w)?; Ok(()) })?; @@ -268,10 +273,10 @@ pub struct Methods { } impl WriteXml for Methods { - fn write_xml(&self, writer: &mut Writer) -> Result<()> { + fn write_xml_(&self, writer: &mut Writer) -> Result<()> { writer .create_element("methods") - .write_inner_content(|w| self.methods.write_xml(w))?; + .write_inner_content(|w| self.methods.write_xml_(w))?; Ok(()) } @@ -293,7 +298,7 @@ pub struct Method { } impl WriteXml for Method { - fn write_xml(&self, writer: &mut Writer) -> Result<()> { + fn write_xml_(&self, writer: &mut Writer) -> Result<()> { writer .create_element("method") .with_attributes([ @@ -302,7 +307,7 @@ impl WriteXml for Method { ("line-rate", float!(self.line_rate)), ("branch-rate", float!(self.branch_rate)), ]) - .write_inner_content(|w| self.lines.write_xml(w))?; + .write_inner_content(|w| self.lines.write_xml_(w))?; Ok(()) } @@ -315,10 +320,10 @@ pub struct Lines { } impl WriteXml for Lines { - fn write_xml(&self, writer: &mut Writer) -> Result<()> { + fn write_xml_(&self, writer: &mut Writer) -> Result<()> { writer .create_element("lines") - .write_inner_content(|w| self.lines.write_xml(w))?; + .write_inner_content(|w| self.lines.write_xml_(w))?; Ok(()) } @@ -340,7 +345,7 @@ pub struct Line { } impl WriteXml for Line { - fn write_xml(&self, writer: &mut Writer) -> Result<()> { + fn write_xml_(&self, writer: &mut Writer) -> Result<()> { let condition_coverage = if let Some(s) = &self.condition_coverage { s.as_str() } else { @@ -355,7 +360,7 @@ impl WriteXml for Line { ("branch", boolean!(self.branch.unwrap_or_default())), ("condition-coverage", condition_coverage), ]) - .write_inner_content(|w| self.conditions.write_xml(w))?; + .write_inner_content(|w| self.conditions.write_xml_(w))?; Ok(()) } @@ -368,10 +373,10 @@ pub struct Conditions { } impl WriteXml for Conditions { - fn write_xml(&self, writer: &mut Writer) -> Result<()> { + fn write_xml_(&self, writer: &mut Writer) -> Result<()> { writer .create_element("conditions") - .write_inner_content(|w| self.conditions.write_xml(w))?; + .write_inner_content(|w| self.conditions.write_xml_(w))?; Ok(()) } @@ -389,7 +394,7 @@ pub struct Condition { } impl WriteXml for Condition { - fn write_xml(&self, writer: &mut Writer) -> Result<()> { + fn write_xml_(&self, writer: &mut Writer) -> Result<()> { writer .create_element("condition") .with_attributes([ diff --git a/src/agent/onefuzz-task/src/tasks/coverage/generic.rs b/src/agent/onefuzz-task/src/tasks/coverage/generic.rs index 17ece8c017d..0533980aa29 100644 --- a/src/agent/onefuzz-task/src/tasks/coverage/generic.rs +++ b/src/agent/onefuzz-task/src/tasks/coverage/generic.rs @@ -10,7 +10,7 @@ use std::time::Duration; use anyhow::{bail, Context, Result}; use async_trait::async_trait; -use cobertura::CoberturaCoverage; +use cobertura::{CoberturaCoverage, WriteXml}; use coverage::allowlist::AllowList; use coverage::binary::{BinaryCoverage, DebugInfoCache}; use coverage::record::CoverageRecorder; @@ -461,20 +461,22 @@ impl<'a> TaskContext<'a> { // JSON binary coverage. let binary = self.coverage.clone(); let json = BinaryCoverageJson::V1(BinaryCoverageJsonV1::from(binary)); - let text = serde_json::to_string(&json).context("serializing binary coverage")?; let path = self.config.coverage.local_path.join(COVERAGE_FILE); - fs::write(&path, &text) - .await - .with_context(|| format!("writing coverage to {}", path.display()))?; + let coverage_file = std::fs::File::create(&path) + .with_context(|| format!("creating coverage file {}", path.display()))?; + let coverage_file_writer = std::io::BufWriter::new(coverage_file); + serde_json::to_writer_pretty(coverage_file_writer, &json) + .with_context(|| format!("serializing binary coverage to {}", path.display()))?; // JSON source coverage. let source = self.source_coverage().await?; let json = SourceCoverageJson::V1(SourceCoverageJsonV1::from(source.clone())); - let text = serde_json::to_string(&json).context("serializing source coverage")?; let path = self.config.coverage.local_path.join(SOURCE_COVERAGE_FILE); - fs::write(&path, &text) - .await - .with_context(|| format!("writing source coverage to {}", path.display()))?; + let source_coverage_file = std::fs::File::create(&path) + .with_context(|| format!("creating source coverage file {}", path.display()))?; + let source_coverage_file_writer = std::io::BufWriter::new(source_coverage_file); + serde_json::to_writer_pretty(source_coverage_file_writer, &json) + .with_context(|| format!("serializing source coverage to {}", path.display()))?; // Cobertura XML source coverage. let cobertura = CoberturaCoverage::from(source.clone()); @@ -484,6 +486,13 @@ impl<'a> TaskContext<'a> { .coverage .local_path .join(COBERTURA_COVERAGE_FILE); + let cobertura_coverage_file = std::fs::File::create(&path) + .with_context(|| format!("creating cobertura coverage file {}", path.display()))?; + let cobertura_coverage_file_writer = std::io::BufWriter::new(cobertura_coverage_file); + cobertura + .write_xml(cobertura_coverage_file_writer) + .with_context(|| format!("serializing cobertura coverage to {}", path.display()))?; + fs::write(&path, &text) .await .with_context(|| format!("writing cobertura source coverage to {}", path.display()))?;