Skip to content
Merged
Show file tree
Hide file tree
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
1 change: 0 additions & 1 deletion bundle/src/bundler.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use std::{
collections::HashMap,
fs::File,
io::{Seek, Write},
path::PathBuf,
Expand Down
1 change: 1 addition & 0 deletions cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ exitcode = "1.1.1"
gix = { version = "0.74.0", default-features = false, features = [
], optional = true }
http = "1.1.0"
prost-wkt-types = { version = "0.5.1", features = ["vendored-protox"] }
tokio = { version = "*", default-features = false, features = [
"rt-multi-thread",
"macros",
Expand Down
26 changes: 23 additions & 3 deletions cli/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ use context::{
};
use github_actions::extract_github_external_id;
use lazy_static::lazy_static;
use prost::Message;
use proto::test_context::test_run::test_case_run::TestRunnerInformation;
use proto::test_context::test_run::{
BazelAttemptNumber, BazelBuildInformation, TestBuildResult, TestReport, TestResult,
UploaderMetadata,
BazelAttemptNumber, BazelBuildInformation, BazelRunInformation, TestBuildResult, TestReport,
TestResult, UploaderMetadata,
};
use regex::Regex;
use tempfile::TempDir;
Expand Down Expand Up @@ -407,6 +407,26 @@ pub fn generate_internal_file_from_bep(
quarantined_test_ids,
variant.as_deref().unwrap_or(""),
);
xml_test_case_runs.iter_mut().for_each(|test_case_run| {
test_case_run.test_runner_information = Some(
TestRunnerInformation::BazelRunInformation(BazelRunInformation {
label: label.clone(),
attempt_number: xml_file.attempt,
started_at: xml_file.start_time.map(|time| {
prost_wkt_types::Timestamp {
seconds: time.timestamp(),
nanos: time.timestamp_subsec_nanos() as i32,
}
}),
finished_at: xml_file.end_time.map(|time| {
prost_wkt_types::Timestamp {
seconds: time.timestamp(),
nanos: time.timestamp_subsec_nanos() as i32,
}
}),
}),
);
});
test_case_runs.extend(xml_test_case_runs);
}
}
Expand Down
68 changes: 56 additions & 12 deletions context-js/tests/parse_and_validate.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -442,13 +442,12 @@ describe("context-js", () => {
expect(testSuite).toBeDefined();
expect(testSuite?.test_cases).toHaveLength(1);

expect(testSuite?.test_cases.at(0).status.status).toBe(
BindingsTestCaseStatusStatus.Success,
);
expect(
testSuite?.test_cases.at(0)?.js_extra().attempt_number,
).toBeUndefined();
expect(testSuite?.test_cases.at(0)?.js_extra().line).toBe("9");
const testCase = testSuite?.test_cases.at(0);

expect(testCase?.status.status).toBe(BindingsTestCaseStatusStatus.Success);
expect(testCase?.js_extra().attempt_number).toBeUndefined();
expect(testCase?.js_extra().line).toBe("9");
expect(testCase?.bazel_run_information).toBeUndefined();
});

it("parses test_internal_bep_v2.bin", () => {
Expand All @@ -474,12 +473,57 @@ describe("context-js", () => {

expect(testSuite).toBeDefined();
expect(testSuite?.test_cases).toHaveLength(1);
expect(testSuite?.test_cases.at(0).status.status).toBe(
BindingsTestCaseStatusStatus.Success,

const testCase = testSuite?.test_cases.at(0);

expect(testCase?.status.status).toBe(BindingsTestCaseStatusStatus.Success);
expect(testCase?.js_extra().attempt_number).toBeUndefined();
expect(testCase?.js_extra().line).toBe("9");
expect(testCase?.bazel_run_information).toBeUndefined();
});

it("parses test_internal_bep_v3.bin", () => {
expect.hasAssertions();

const file_path = path.resolve(__dirname, "./test_internal_bep_v3.bin");
const file = fs.readFileSync(file_path);
const bindingsReports = bin_parse(file);

expect(bindingsReports).toHaveLength(1);

const result = bindingsReports.at(0);

expect(result?.bazel_build_information?.label).toBe(
"//trunk/hello_world/cc:hello_test",
);
// Newer format of BEP file has attempt number in bazel build information
expect(result?.bazel_build_information?.max_attempt_number).toBe(0);
expect(result?.tests).toBe(1);
expect(result?.test_suites).toHaveLength(1);

const testSuite = result?.test_suites.at(0);

expect(testSuite).toBeDefined();
expect(testSuite?.test_cases).toHaveLength(1);

const testCase = testSuite?.test_cases.at(0);

expect(testCase?.status.status).toBe(BindingsTestCaseStatusStatus.Success);
expect(testCase?.js_extra().attempt_number).toBeUndefined();
expect(testCase?.js_extra().line).toBe("9");
expect(testCase?.bazel_run_information).toBeDefined();
expect(testCase?.bazel_run_information?.label).toBe(
"//trunk/hello_world/cc:hello_test",
);
expect(
new Date(
Number(testCase?.bazel_run_information?.started_at) * 1000,
).toISOString(),
).toBe("2026-01-22T06:07:16.000Z");
expect(
testSuite?.test_cases.at(0)?.js_extra().attempt_number,
).toBeUndefined();
expect(testSuite?.test_cases.at(0)?.js_extra().line).toBe("9");
new Date(
Number(testCase?.bazel_run_information?.finished_at) * 1000,
).toISOString(),
).toBe("2026-01-22T06:07:16.000Z");
});
});
Binary file added context-js/tests/test_internal_bep_v3.bin
Binary file not shown.
19 changes: 19 additions & 0 deletions context/src/bazel_bep/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ pub enum BepTestStatus {
pub struct BepXMLFile {
pub file: String,
pub attempt: i32,
pub label: String,
pub start_time: Option<chrono::DateTime<chrono::Utc>>,
pub end_time: Option<chrono::DateTime<chrono::Utc>>,
}

#[derive(Debug, Clone, Default)]
Expand Down Expand Up @@ -128,6 +131,19 @@ impl BepParseResult {
acc.bep_test_events.push(build_event);
}
(Some(Payload::TestResult(test_result)), Some(Id::TestResult(id))) => {
let start_time =
test_result.test_attempt_start.clone().and_then(|ts| {
DateTime::from_timestamp(ts.seconds, ts.nanos as u32)
});
let end_time = start_time.and_then(|start| {
test_result.test_attempt_duration.clone().map(|duration| {
let duration_secs = duration.seconds;
let duration_nanos = duration.nanos as i64;
start
+ chrono::Duration::seconds(duration_secs)
+ chrono::Duration::nanoseconds(duration_nanos)
})
});
let xml_files = test_result
.test_action_output
.iter()
Expand All @@ -142,6 +158,9 @@ impl BepParseResult {
.to_string(),
// bazel attempt number is 1-indexed, our representation is 0-indexed
attempt: id.attempt - 1,
label: id.label.clone(),
start_time,
end_time,
})
} else {
None
Expand Down
110 changes: 94 additions & 16 deletions context/src/bazel_bep/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,45 @@ mod tests {
&BepTestStatus::Passed
);

// Test that attempt numbers are captured correctly
let attempt_numbers: Vec<i32> = test_result.xml_files.iter().map(|f| f.attempt).collect();
assert_eq!(attempt_numbers.len(), 2, "Should have 2 attempt numbers");
assert!(attempt_numbers.contains(&0), "Should have attempt 0");
assert!(attempt_numbers.contains(&1), "Should have attempt 1");
// Test that xml files include correct testResult information
let xml_files = &test_result.xml_files;
assert_eq!(xml_files.len(), 2);
assert_eq!(xml_files[0].label, "//trunk/hello_world/cc:hello_test");
assert_eq!(xml_files[0].attempt, 0);
assert_eq!(
xml_files[0].start_time,
Some(
DateTime::parse_from_rfc3339("2024-12-10T06:17:23.963Z")
.unwrap()
.into()
)
);
assert_eq!(
xml_files[0].end_time,
Some(
DateTime::parse_from_rfc3339("2024-12-10T06:17:24.006Z")
.unwrap()
.into()
)
);
assert_eq!(xml_files[1].label, "//trunk/hello_world/cc:hello_test");
assert_eq!(xml_files[1].attempt, 1);
assert_eq!(
xml_files[1].start_time,
Some(
DateTime::parse_from_rfc3339("2024-12-10T06:17:24.011Z")
.unwrap()
.into()
)
);
assert_eq!(
xml_files[1].end_time,
Some(
DateTime::parse_from_rfc3339("2024-12-10T06:17:24.055Z")
.unwrap()
.into()
)
);

assert_eq!(
parse_result.errors.len(),
Expand Down Expand Up @@ -259,19 +293,63 @@ mod tests {
.iter()
.find(|r| r.label == "//trunk/hello_world/cc:hello_test")
.expect("Should find hello_test result");
let attempt_numbers: Vec<i32> = hello_test_result
.xml_files
.iter()
.map(|f| f.attempt)
.collect();

let xml_files = &hello_test_result.xml_files;
assert_eq!(xml_files.len(), 3);
assert_eq!(xml_files[0].label, "//trunk/hello_world/cc:hello_test");
assert_eq!(xml_files[0].attempt, 0);
assert_eq!(
attempt_numbers.len(),
3,
"Should have 3 attempt numbers for flaky test"
xml_files[0].start_time,
Some(
DateTime::parse_from_rfc3339("2024-12-17T04:10:55.311Z")
.unwrap()
.into()
)
);
assert_eq!(
xml_files[0].end_time,
Some(
DateTime::parse_from_rfc3339("2024-12-17T04:10:55.357Z")
.unwrap()
.into()
)
);
assert_eq!(xml_files[1].label, "//trunk/hello_world/cc:hello_test");
assert_eq!(xml_files[1].attempt, 1);
assert_eq!(
xml_files[1].start_time,
Some(
DateTime::parse_from_rfc3339("2024-12-17T04:10:55.377Z")
.unwrap()
.into()
)
);
assert_eq!(
xml_files[1].end_time,
Some(
DateTime::parse_from_rfc3339("2024-12-17T04:10:55.421Z")
.unwrap()
.into()
)
);
assert_eq!(xml_files[2].label, "//trunk/hello_world/cc:hello_test");
assert_eq!(xml_files[2].attempt, 2);
assert_eq!(
xml_files[2].start_time,
Some(
DateTime::parse_from_rfc3339("2024-12-17T04:10:55.425Z")
.unwrap()
.into()
)
);
assert_eq!(
xml_files[2].end_time,
Some(
DateTime::parse_from_rfc3339("2024-12-17T04:10:55.466Z")
.unwrap()
.into()
)
);
assert!(attempt_numbers.contains(&0), "Should have attempt 0");
assert!(attempt_numbers.contains(&1), "Should have attempt 1");
assert!(attempt_numbers.contains(&2), "Should have attempt 2");
}

#[test]
Expand Down
Loading