Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(Feat): Upload streamlined BEP file #226

Merged
merged 5 commits into from
Dec 15, 2024
Merged

(Feat): Upload streamlined BEP file #226

merged 5 commits into from
Dec 15, 2024

Conversation

TylerJang27
Copy link
Collaborator

@TylerJang27 TylerJang27 commented Dec 13, 2024

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

Copy link

trunk-io bot commented Dec 13, 2024

😎 Merged successfully - details.

Copy link

trunk-staging-io bot commented Dec 13, 2024

Static BadgeStatic BadgeStatic BadgeStatic Badge

View Full Report ↗︎Docs

@TylerJang27 TylerJang27 marked this pull request as ready for review December 13, 2024 09:32
Comment on lines +89 to +90
bep_events_file.flush()?;
bep_events_file.seek(std::io::SeekFrom::Start(0))?;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seemed to be necessary in order for the tests to work on Mac.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I think it's necessary when you write then immediately read again within the same scope

match parse_event {
Result::Err(ref err) => {
errors.push(format!("Error parsing build event: {}", err));
}
Result::Ok(build_event) => {
if let Some(Payload::TestResult(test_result)) = build_event.payload {
let xml_files = test_result
if let Some(Payload::TestResult(test_result)) = &build_event.payload {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will also be uploading TestSummary events in a follow-up. I considered the started events too, but that can include some env vars and bazel config that we probably shouldn't collect

Copy link
Contributor

@max-trunk max-trunk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, just 1 Q!

tar.append_file("CODEOWNERS", &mut file)?;
total_bytes_in += std::fs::metadata(path)?.len();
}

if let Some(bep_parser) = self.bep_parser.as_ref() {
let mut bep_events_file = tempfile::tempfile()?;
bep_parser.bep_test_events().iter().for_each(|event| {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assumes that bep_parser.parse() was called somewhere upstream (and I do see that it was called in the upload flow before being passed to the BundlerUtil here). Curious if you've considered having the BazelBepParser output a single struct with all of the relevant parsed data that we can pass around rather than the parser itself?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed—might be better to have a struct which represents an already parsed state

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. I'm refactoring to handle that

Comment on lines 6 to 10
use std::path::PathBuf;
use std::{
fs::File,
io::{Seek, Write},
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would be awesome if we could combine these std imports and stick them in their own group above these normal crate imports

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Need a linter for this 🙄

bundle/src/bundler.rs Outdated Show resolved Hide resolved
tar.append_file("CODEOWNERS", &mut file)?;
total_bytes_in += std::fs::metadata(path)?.len();
}

if let Some(bep_parser) = self.bep_parser.as_ref() {
let mut bep_events_file = tempfile::tempfile()?;
bep_parser.bep_test_events().iter().for_each(|event| {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed—might be better to have a struct which represents an already parsed state

bundle/src/bundler.rs Outdated Show resolved Hide resolved
Comment on lines +89 to +90
bep_events_file.flush()?;
bep_events_file.seek(std::io::SeekFrom::Start(0))?;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I think it's necessary when you write then immediately read again within the same scope

Comment on lines 236 to 241
let mut bazel_bep_parser = BazelBepParser::new(
tar_extract_directory
.join("bazel_bep.json")
.to_string_lossy()
.to_string(),
);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we update BazelBepParser you won't have to do all of this Path <-> String conversion:

#[derive(Debug, Clone, Default)]
pub struct BazelBepParser {
    bazel_bep_path: PathBuf,
    test_results: Vec<TestResult>,
    bep_test_events: Vec<BuildEvent>,
    errors: Vec<String>,
}

impl BazelBepParser {
    pub fn new<T: Into<PathBuf>>(bazel_bep_path: T) -> Self {
        Self {
            bazel_bep_path: bazel_bep_path.into(),
            ..Default::default()
        }
    }
    // ... other code ...
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everytime I'm sitting here thinking "there has to be a better way," Dylan's got me

@trunk-io trunk-io bot merged commit 9fbb8d4 into main Dec 15, 2024
13 checks passed
trunk-io bot pushed a commit that referenced this pull request Dec 18, 2024
Follow-up to #215 (incomplete, just timestamps) and #226 (more BEP debugging). Parses bazel [TestSummary](https://github.com/bazelbuild/bazel/blob/master/src/main/java/com/google/devtools/build/lib/buildeventstream/proto/build_event_stream.proto#L781) events in order to override the failure status of a given junit. This allows us to properly return a zero exit code if bazel marks a test as flaky, rather than waiting for a quarantine status to properly return.

This should hopefully also allow us to better inform the rules engine for test runner-identified flakiness from bazel

Notes:
- I have attempted to make this as generic as possible without entangling too much logic with bazel parsing
- Unfortunately this logic does have to (and already does) live in the client, since we need to parse the junits in order to properly arrive at a quarantine result
- I have added unit and integration tests here, and also validated this against the repros identified in [thread](https://trunk-io.slack.com/archives/C044VBASZ0D/p1734028034948189).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

3 participants