Skip to content

Commit 9fbb8d4

Browse files
authored
(Feat): Upload streamlined BEP file (#226)
Include a subset of the BEP file in the bundle tar. This strips it to just `testResult` events, which removes sensitive information that may be in other events This is mainly for our debugging purposes and for evaluating the success of this feature
1 parent 15c59f5 commit 9fbb8d4

File tree

7 files changed

+124
-74
lines changed

7 files changed

+124
-74
lines changed

bundle/src/bundler.rs

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
use async_compression::futures::bufread::ZstdDecoder;
22
use async_std::{io::ReadExt, stream::StreamExt};
33
use async_tar_wasm::Archive;
4+
use context::bazel_bep::parser::BepParseResult;
45
use futures_io::AsyncBufRead;
5-
use std::io::{Seek, Write};
6-
use std::path::PathBuf;
6+
use std::{
7+
fs::File,
8+
io::{Seek, Write},
9+
path::PathBuf,
10+
};
711
#[cfg(feature = "wasm")]
812
use tsify_next::Tsify;
913
#[cfg(feature = "wasm")]
@@ -17,24 +21,25 @@ use crate::bundle_meta::{BundleMeta, VersionedBundle};
1721
///
1822
#[cfg_attr(feature = "wasm", derive(Tsify))]
1923
pub struct BundlerUtil {
20-
pub meta: BundleMeta,
24+
meta: BundleMeta,
25+
bep_result: Option<BepParseResult>,
2126
}
2227

2328
const META_FILENAME: &'static str = "meta.json";
2429

2530
impl BundlerUtil {
2631
const ZSTD_COMPRESSION_LEVEL: i32 = 15; // This gives roughly 10x compression for text, 22 gives 11x.
2732

28-
pub fn new(meta: BundleMeta) -> Self {
29-
Self { meta }
33+
pub fn new(meta: BundleMeta, bep_result: Option<BepParseResult>) -> Self {
34+
Self { meta, bep_result }
3035
}
3136

3237
/// Writes compressed tarball to disk.
3338
///
3439
pub fn make_tarball(&self, bundle_path: &PathBuf) -> anyhow::Result<()> {
3540
let mut total_bytes_in: u64 = 0;
3641

37-
let tar_file = std::fs::File::create(bundle_path)?;
42+
let tar_file = File::create(bundle_path)?;
3843
let zstd_encoder = zstd::Encoder::new(tar_file, Self::ZSTD_COMPRESSION_LEVEL)?;
3944
let mut tar = tar::Builder::new(zstd_encoder);
4045

@@ -56,7 +61,7 @@ impl BundlerUtil {
5661
.try_for_each(|file_set| {
5762
file_set.files.iter().try_for_each(|bundled_file| {
5863
let path = std::path::Path::new(&bundled_file.original_path);
59-
let mut file = std::fs::File::open(path)?;
64+
let mut file = File::open(path)?;
6065
tar.append_file(&bundled_file.path, &mut file)?;
6166
total_bytes_in += std::fs::metadata(path)?.len();
6267
Ok::<(), anyhow::Error>(())
@@ -65,11 +70,28 @@ impl BundlerUtil {
6570
})?;
6671

6772
if let Some(CodeOwners { ref path, .. }) = self.meta.base_props.codeowners {
68-
let mut file = std::fs::File::open(path)?;
73+
let mut file = File::open(path)?;
6974
tar.append_file("CODEOWNERS", &mut file)?;
7075
total_bytes_in += std::fs::metadata(path)?.len();
7176
}
7277

78+
if let Some(bep_result) = self.bep_result.as_ref() {
79+
let mut bep_events_file =
80+
bep_result
81+
.bep_test_events
82+
.iter()
83+
.fold(tempfile::tempfile()?, |f, event| {
84+
if let Err(e) = serde_json::to_writer(&f, event) {
85+
log::error!("Failed to write BEP event: {}", e);
86+
}
87+
f
88+
});
89+
bep_events_file.flush()?;
90+
bep_events_file.seek(std::io::SeekFrom::Start(0))?;
91+
tar.append_file("bazel_bep.json", &mut bep_events_file)?;
92+
total_bytes_in += bep_events_file.seek(std::io::SeekFrom::End(0))?;
93+
}
94+
7395
// Flush to disk.
7496
tar.into_inner()?.finish()?;
7597

cli-tests/src/upload.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ use assert_cmd::Command;
99
use assert_matches::assert_matches;
1010
use bundle::{BundleMeta, FileSetType};
1111
use codeowners::CodeOwners;
12-
use context::{junit::parser::JunitParser, repo::RepoUrlParts as Repo};
12+
use context::{
13+
bazel_bep::parser::BazelBepParser, junit::parser::JunitParser, repo::RepoUrlParts as Repo,
14+
};
1315
use predicates::prelude::*;
1416
use tempfile::tempdir;
1517
use test_utils::{
@@ -228,14 +230,19 @@ async fn upload_bundle_using_bep() {
228230

229231
let tar_extract_directory = assert_matches!(&requests[3], RequestPayload::S3Upload(d) => d);
230232

231-
let file = fs::File::open(tar_extract_directory.join("junit/0")).unwrap();
232-
let reader = BufReader::new(file);
233+
let junit_file = fs::File::open(tar_extract_directory.join("junit/0")).unwrap();
234+
let junit_reader = BufReader::new(junit_file);
233235

234236
// Uploaded file is a junit, even when using BEP
235237
let mut junit_parser = JunitParser::new();
236-
assert!(junit_parser.parse(reader).is_ok());
238+
assert!(junit_parser.parse(junit_reader).is_ok());
237239
assert!(junit_parser.errors().is_empty());
238240

241+
let mut bazel_bep_parser = BazelBepParser::new(tar_extract_directory.join("bazel_bep.json"));
242+
let parse_result = bazel_bep_parser.parse().ok().unwrap();
243+
assert!(parse_result.errors.is_empty());
244+
assert_eq!(parse_result.xml_file_counts(), (1, 0));
245+
239246
// HINT: View CLI output with `cargo test -- --nocapture`
240247
println!("{assert}");
241248
}

cli/src/main.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -231,9 +231,9 @@ async fn run(cli: Cli) -> anyhow::Result<i32> {
231231
let junit_file_paths = match bazel_bep_path {
232232
Some(bazel_bep_path) => {
233233
let mut parser = BazelBepParser::new(bazel_bep_path);
234-
parser.parse()?;
235-
print_bep_results(&parser);
236-
parser.uncached_xml_files()
234+
let bep_result = parser.parse()?;
235+
print_bep_results(&bep_result);
236+
bep_result.uncached_xml_files()
237237
}
238238
None => junit_paths,
239239
};

cli/src/print.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
use context::bazel_bep::parser::BazelBepParser;
1+
use context::bazel_bep::parser::BepParseResult;
22

3-
pub fn print_bep_results(parser: &BazelBepParser) {
4-
if !parser.errors().is_empty() {
5-
log::warn!("Errors parsing BEP file: {:?}", &parser.errors());
3+
pub fn print_bep_results(bep_result: &BepParseResult) {
4+
if !bep_result.errors.is_empty() {
5+
log::warn!("Errors parsing BEP file: {:?}", &bep_result.errors);
66
}
77

8-
let (test_count, cached_count) = parser.test_counts();
8+
let (xml_count, cached_xml_count) = bep_result.xml_file_counts();
99
log::info!(
1010
"Parsed {} ({} cached) test results from BEP file",
11-
test_count,
12-
cached_count
11+
xml_count,
12+
cached_xml_count
1313
);
1414
}

cli/src/runner.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ pub async fn run_test_command(
3535
JunitSpec::Paths(paths) => paths,
3636
JunitSpec::BazelBep(bep_path) => {
3737
let mut parser = BazelBepParser::new(bep_path);
38-
parser.parse()?;
39-
print_bep_results(&parser);
40-
parser.uncached_xml_files()
38+
let bep_result = parser.parse()?;
39+
print_bep_results(&bep_result);
40+
bep_result.uncached_xml_files()
4141
}
4242
};
4343

cli/src/upload.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ use codeowners::CodeOwners;
1818
use constants::{EXIT_FAILURE, EXIT_SUCCESS};
1919
#[cfg(target_os = "macos")]
2020
use context::repo::RepoUrlParts;
21-
use context::{bazel_bep::parser::BazelBepParser, junit::parser::JunitParser, repo::BundleRepo};
21+
use context::{
22+
bazel_bep::parser::{BazelBepParser, BepParseResult},
23+
junit::parser::JunitParser,
24+
repo::BundleRepo,
25+
};
2226

2327
use crate::{
2428
api_client::ApiClient,
@@ -154,11 +158,13 @@ pub async fn run_upload(
154158
let codeowners =
155159
codeowners.or_else(|| CodeOwners::find_file(&repo.repo_root, &codeowners_path));
156160

161+
let mut bep_result: Option<BepParseResult> = None;
157162
if let Some(bazel_bep_path) = bazel_bep_path {
158163
let mut parser = BazelBepParser::new(bazel_bep_path);
159-
parser.parse()?;
160-
print_bep_results(&parser);
161-
junit_paths = parser.uncached_xml_files();
164+
let bep_parse_result = parser.parse()?;
165+
print_bep_results(&bep_parse_result);
166+
junit_paths = bep_parse_result.uncached_xml_files();
167+
bep_result = Some(bep_parse_result);
162168
}
163169

164170
let tags = parse_custom_tags(&tags)?;
@@ -308,7 +314,7 @@ pub async fn run_upload(
308314

309315
let bundle_temp_dir = tempfile::tempdir()?;
310316
let bundle_time_file = bundle_temp_dir.path().join("bundle.tar.zstd");
311-
let bundle = BundlerUtil::new(meta);
317+
let bundle = BundlerUtil::new(meta, bep_result);
312318
bundle.make_tarball(&bundle_time_file)?;
313319
log::info!("Flushed temporary tarball to {:?}", bundle_time_file);
314320

0 commit comments

Comments
 (0)