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): Support passing a bazel BuildEventProtocol path #197

Conversation

TylerJang27
Copy link
Collaborator

@TylerJang27 TylerJang27 commented Dec 5, 2024

Support testing, validating, and uploading from a bazel BuildEventProtocol JSON file

Screenshot 2024-12-05 at 1 32 08 PM

I've added unit and integration tests, and also validated this manually with a local bazel run and a successful upload.

As a follow-up I'll be vendoring the proto crate in this repo

Comment on lines +45 to +46
required_unless_present = "bazel_bep_path",
conflicts_with = "bazel_bep_path",
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 allows it to be mutually exclusive with the --junit-paths as well as --xc-result-path when applicable

required_unless_present = "junit_paths",
help = "Path to bazel build event protocol JSON file."
)]
bazel_bep_path: Option<String>,
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

If we decide we want to support the binary format too at some point, we can just name that bazel_bep_binary_path. JSON seems the sanest default here

cli/src/main.rs Outdated

log::info!("running command: {:?}", command);
let run_result = run_test_command(
&repo,
&org_url_slug,
command.first().unwrap(),
command.iter().skip(1).collect(),
junit_paths,
&junit_spec,
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We can't early parse here like we do in other cases, since we haven't run the test yet 🙃

cli/src/main.rs Outdated
Comment on lines 223 to 231
let mut parser = BazelBepParser::new(bazel_bep_path.clone());
parser.parse()?;
parser.xml_files()
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Not sure if there's a more idiomatic way to do this in rust. Maybe chaining?

Copy link
Member

Choose a reason for hiding this comment

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

Nah, this is pretty good. It gets annoying when having to do mapping with Results

@@ -258,6 +273,7 @@ pub async fn run_upload(

log::info!("Total files pack and upload: {}", file_counter.get_count());
if file_counter.get_count() == 0 {
// DONOTLAND FIX LOG MESSAGE HERE
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Will be auditing this to make sure the message still makes sense/works

let xml_files = test_result.test_action_output.into_iter().fold(
Vec::new(),
|mut xml_files, action_output| {
if action_output.name.ends_with(".xml") {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

test.xml by default afaik, but my understanding is that this may vary for different runners

Copy link
Contributor

@pv72895 pv72895 left a comment

Choose a reason for hiding this comment

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

My pre-review - all looks good to me at a first passthroug. Since we're ok with this feature being hacky, I'm ok with believing the external types you're using to be correct / up-to-date enough

cli/src/main.rs Outdated Show resolved Hide resolved
Comment on lines +6 to +9
pub struct TestResult {
pub cached: bool,
pub xml_files: Vec<String>,
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I was under the impression that one test result = one file - is that not the case? Or just being proactive here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

From what I've seen it's just one xml file. But there are multiple files (test.log), and conceivably if you were using bazel to wrap some other invocation, you could get multiple junits, so being proactive

log::info!(
"Parsed {} ({} cached) test results from BEP file",
self.test_results.len(),
self.test_results.iter().filter(|r| r.cached).count()
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Open to input on precomputing this, storing other info, etc. I wanted to strike a balance of only storing info that we found valuable here, while also reporting useful information for debug purposes...

Copy link
Collaborator Author

@TylerJang27 TylerJang27 Dec 6, 2024

Choose a reason for hiding this comment

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

These are sanitized BEP files from our repro of the original issue. I have:

  • Stripped env vars
  • Simplified paths
  • Removed extra log output
  • Cleaned up CLI options

and tried a few different situations to simulate truncation, invalid files, etc.

@TylerJang27 TylerJang27 force-pushed the tyler/trunk-13743-handle-being-provided-a-path-to-bep-file-in-cli branch from f6f2969 to 32bc6ef Compare December 6, 2024 10:43
@TylerJang27 TylerJang27 marked this pull request as ready for review December 6, 2024 10:44
@TylerJang27 TylerJang27 force-pushed the tyler/trunk-13743-handle-being-provided-a-path-to-bep-file-in-cli branch from 32bc6ef to f72c26a Compare December 6, 2024 18:42
Comment on lines +10 to +11
# Fork from 0.2.2 that adds serde serialize/deserialize via pbjson
bazel-bep = { git = "https://github.com/TylerJang27/bazel-bep.git", rev = "e51c546960067b9fe98ae35ae00bc53302973a9e" }
Copy link
Member

Choose a reason for hiding this comment

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

I'd recommend for us to just vendor the crate in the workspace. There's only ~100 lines of code there

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, will do as a follow-up

cli/src/main.rs Outdated
Comment on lines 223 to 231
let mut parser = BazelBepParser::new(bazel_bep_path.clone());
parser.parse()?;
parser.xml_files()
Copy link
Member

Choose a reason for hiding this comment

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

Nah, this is pretty good. It gets annoying when having to do mapping with Results

cli/src/main.rs Outdated Show resolved Hide resolved
cli/src/main.rs Outdated Show resolved Hide resolved
cli/src/runner.rs Outdated Show resolved Hide resolved
context/src/bazel_bep/parser.rs Outdated Show resolved Hide resolved
context/src/bazel_bep/parser.rs Outdated Show resolved Hide resolved
context/src/bazel_bep/parser.rs Outdated Show resolved Hide resolved
context/src/bazel_bep/parser.rs Outdated Show resolved Hide resolved
context/src/bazel_bep/parser.rs Outdated Show resolved Hide resolved
@TylerJang27 TylerJang27 force-pushed the tyler/trunk-13743-handle-being-provided-a-path-to-bep-file-in-cli branch from f72c26a to 08eed55 Compare December 6, 2024 21:57
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

These changes didn't end up helping with CI like I'd hoped, but it may prove helpful locally. If need be we can remove later

Comment on lines +64 to +71
if [ "$(uname -m)" == "aarch64" ]; then
curl -L https://github.com/protocolbuffers/protobuf/releases/download/v29.1/protoc-29.1-linux-aarch_64.zip -o protoc.zip
unzip protoc.zip
export PROTOC=$(pwd)/bin/protoc
else
curl -L https://github.com/protocolbuffers/protobuf/releases/download/v29.1/protoc-29.1-linux-x86_64.zip -o protoc.zip
unzip protoc.zip
export PROTOC=$(pwd)/bin/protoc
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The package registries were giving me issues. This ended up being a more reliable way to install and pin within the VMs

Comment on lines +12 to +21
- name: Install protoc
shell: bash
run: |
if [ -f /opt/homebrew/bin/brew ]; then
/opt/homebrew/bin/brew install protobuf
elif [ -f /usr/bin/apt ]; then
sudo /usr/bin/apt update
sudo /usr/bin/apt install -y protobuf-compiler
fi

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The arduino setup action was relentless with rate limiting (not sure why they don't allow bypassing the API call), and I didn't want to pass our whole GH token rn https://github.com/marketplace/actions/setup-protoc

let output_paths = match junit_spec {
JunitSpec::Paths(paths) => paths,
JunitSpec::BazelBep(bep_path) => {
let mut parser = BazelBepParser::new(bep_path.clone());
Copy link
Member

Choose a reason for hiding this comment

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

Now that junit_spec is passed by value, we don't need to clone here

Comment on lines +48 to +68
pub fn print_parsed_results(&self) {
if !self.errors.is_empty() {
log::warn!("Errors parsing BEP file: {:?}", &self.errors);
}

let (test_count, cached_count) = self.test_results.iter().fold(
(0, 0),
|(mut test_count, mut cached_count), test_result| {
test_count += test_result.xml_files.len();
if test_result.cached {
cached_count += test_result.xml_files.len();
}
(test_count, cached_count)
},
);
log::info!(
"Parsed {} ({} cached) test results from BEP file",
test_count,
cached_count
);
}
Copy link
Member

@dfrankland dfrankland Dec 7, 2024

Choose a reason for hiding this comment

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

Optional: I would leave the log::info for the CLI crate. This method could just return the number of tests and number of cached tests to be used however the caller pleases

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Ah, fair point. Will handle in follow-up

@TylerJang27 TylerJang27 merged commit 104f48c into main Dec 7, 2024
13 checks passed
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