| use anyhow::Result; | |
| use assert_cmd::prelude::*; | |
| use std::fs::File; | |
| use std::io::{Seek, SeekFrom, Write}; | |
| use std::path::{Path, PathBuf}; | |
| use std::process::Command; | |
| use std::time::Duration; | |
| #[cfg(target_os = "windows")] | |
| #[test] | |
| fn test_logs_uploaded_to_buildkite() -> Result<()> { | |
| let mut cmd = Command::cargo_bin("bazelci-agent")?; | |
| cmd.args([ | |
| "artifact", | |
| "upload", | |
| "--dry", | |
| "--mode=buildkite", | |
| "--build_event_json_file=tests\\data\\test_bep_win.json", | |
| ]); | |
| cmd.assert() | |
| .success() | |
| .stdout(predicates::ord::eq("buildkite-agent artifact upload --content-type text/plain;charset=utf-8 src\\test\\shell\\bazel\\resource_compiler_toolchain_test\\test.log\n")); | |
| Ok(()) | |
| } | |
| #[cfg(not(target_os = "windows"))] | |
| #[test] | |
| fn test_logs_uploaded_to_buildkite() -> Result<()> { | |
| let mut cmd = Command::cargo_bin("bazelci-agent")?; | |
| cmd.args([ | |
| "artifact", | |
| "upload", | |
| "--dry", | |
| "--mode=buildkite", | |
| "--build_event_json_file=tests/data/test_bep.json", | |
| ]); | |
| cmd.assert() | |
| .success() | |
| .stdout(predicates::ord::eq("buildkite-agent artifact upload --content-type text/plain;charset=utf-8 src/test/shell/bazel/starlark_repository_test/shard_4_of_6/test_attempts/attempt_1.log\n")); | |
| Ok(()) | |
| } | |
| #[cfg(not(target_os = "windows"))] | |
| #[test] | |
| fn test_undeclared_output_uploaded_to_buildkite() -> Result<()> { | |
| let mut cmd = Command::cargo_bin("bazelci-agent")?; | |
| cmd.args([ | |
| "artifact", | |
| "upload", | |
| "--dry", | |
| "--mode=buildkite", | |
| "--build_event_json_file=tests/data/test_bep_undeclared_output.json", | |
| ]); | |
| cmd.assert() | |
| .success() | |
| .stdout(predicates::str::contains("buildkite-agent artifact upload src/test/shell/bazel/tags_propagation_native_test/test_attempts/attempt_1.outputs/test_cc_library_tags_not_propagated_when_incompatible_flag_off/741B943E-B846-4453-A3AF-0D9010431815/output1\n")); | |
| Ok(()) | |
| } | |
| fn with_tmpfile<F>(f: F) -> Result<()> | |
| where | |
| F: Fn(File, &Path) -> Result<()>, | |
| { | |
| let file = tempfile::NamedTempFile::new()?; | |
| let path = PathBuf::from(file.path()); | |
| let file = file.persist(&path)?; | |
| // Keep the tmp file if callback failed | |
| f(file, &path)?; | |
| std::fs::remove_file(path)?; | |
| Ok(()) | |
| } | |
| /// Test that if the BEP json file is truncated and the file size is less | |
| /// than current read cursor, the parser can detect that and reread from the start. | |
| #[test] | |
| fn truncate_build_event_json_file_restart() -> Result<()> { | |
| with_tmpfile(|mut file, path| { | |
| writeln!( | |
| file, | |
| "{}", | |
| r#"{"id":{"workspace":{}},"workspaceInfo":{"localExecRoot":"/private/var/tmp/_bazel_buildkite/78a0792bf9bb0133b1a4a7d083181fcb/execroot/io_bazel"}}"# | |
| )?; | |
| std::thread::spawn(move || { | |
| std::thread::sleep(Duration::from_secs(1)); | |
| file.set_len(0).unwrap(); | |
| file.seek(SeekFrom::Start(0)).unwrap(); | |
| writeln!( | |
| file, | |
| "{}", | |
| r#"{"id":{"progress":{}},"progress":{},"lastMessage":true}"#, | |
| ) | |
| .unwrap(); | |
| }); | |
| let mut cmd = Command::cargo_bin("bazelci-agent")?; | |
| cmd.args([ | |
| "artifact", | |
| "upload", | |
| "--dry", | |
| "--mode=buildkite", | |
| format!("--build_event_json_file={}", path.display()).as_str(), | |
| ]); | |
| cmd.assert().success(); | |
| Ok(()) | |
| }) | |
| } | |
| /// Test that if the BEP json file is truncated and the current read cursor | |
| /// is in the middle of a line (instead of beginning), the parser can detect | |
| /// that and reread from the start. | |
| #[test] | |
| fn truncate_build_event_json_file_recover_from_middle() -> Result<()> { | |
| with_tmpfile(|mut file, path| { | |
| writeln!(file, "{}", r#"{}"#)?; | |
| std::thread::spawn(move || { | |
| std::thread::sleep(Duration::from_secs(1)); | |
| file.set_len(0).unwrap(); | |
| file.seek(SeekFrom::Start(0)).unwrap(); | |
| writeln!( | |
| file, | |
| "{}", | |
| r#"{"id":{"progress":{}},"progress":{},"lastMessage":true}"#, | |
| ) | |
| .unwrap(); | |
| }); | |
| let mut cmd = Command::cargo_bin("bazelci-agent")?; | |
| cmd.args([ | |
| "artifact", | |
| "upload", | |
| "--dry", | |
| "--mode=buildkite", | |
| format!("--build_event_json_file={}", path.display()).as_str(), | |
| ]); | |
| cmd.assert().success(); | |
| Ok(()) | |
| }) | |
| } | |
| #[cfg(not(target_os = "windows"))] | |
| #[test] | |
| fn test_logs_deduplicated() -> Result<()> { | |
| let mut cmd = Command::cargo_bin("bazelci-agent")?; | |
| cmd.args([ | |
| "artifact", | |
| "upload", | |
| "--dry", | |
| "--mode=buildkite", | |
| "--build_event_json_file=tests/data/test_bep_duplicated.json", | |
| ]); | |
| cmd.assert() | |
| .success() | |
| .stdout(predicates::str::contains("buildkite-agent artifact upload --content-type text/plain;charset=utf-8 src/test/shell/bazel/starlark_repository_test/shard_4_of_6/test_attempts/attempt_1.log").count(1)); | |
| Ok(()) | |
| } | |
| #[cfg(not(target_os = "windows"))] | |
| #[test] | |
| fn test_running_json_file() -> Result<()> { | |
| with_tmpfile(|mut file, path| { | |
| std::thread::spawn(move || { | |
| std::thread::sleep(Duration::from_secs(1)); | |
| writeln!(file, "{}", r#"{"id":{"workspace":{}},"workspaceInfo":{"localExecRoot":"/private/var/tmp/_bazel_buildkite/78a0792bf9bb0133b1a4a7d083181fcb/execroot/io_bazel"}}"#).unwrap(); | |
| std::thread::sleep(Duration::from_secs(1)); | |
| writeln!(file, "{}", r#"{"id":{"testSummary":{"label":"//src/test/shell/bazel:starlark_repository_test","configuration":{"id":"7479eaa1eeb472e5c3fdd9f0b604289ffbe45a36edb8a7f474df0c95501b4d00"}}},"testSummary":{"totalRunCount":7,"failed":[{"uri":"file:///private/var/tmp/_bazel_buildkite/78a0792bf9bb0133b1a4a7d083181fcb/execroot/io_bazel/bazel-out/darwin-fastbuild/testlogs/src/test/shell/bazel/starlark_repository_test/shard_4_of_6/test_attempts/attempt_1.log"}],"overallStatus":"FLAKY","firstStartTimeMillis":"1630444947193","lastStopTimeMillis":"1630445154997","totalRunDurationMillis":"338280","runCount":1,"shardCount":6}}"#).unwrap(); | |
| std::thread::sleep(Duration::from_secs(1)); | |
| writeln!(file, "{}", r#"{"id":{"testResult":{}},"testResult":{"testActionOutput":[{"name":"test.log","uri":"file:///private/var/tmp/_bazel_buildkite/78a0792bf9bb0133b1a4a7d083181fcb/execroot/io_bazel/bazel-out/darwin-fastbuild/testlogs/src/test/shell/bazel/starlark_repository_test/shard_4_of_6/test_attempts/attempt_1.log"}],"status":"FAILED"}}"#).unwrap(); | |
| std::thread::sleep(Duration::from_secs(1)); | |
| writeln!( | |
| file, | |
| "{}", | |
| r#"{"id":{"progress":{}},"progress":{},"lastMessage":true}"# | |
| ) | |
| .unwrap(); | |
| }); | |
| let mut cmd = Command::cargo_bin("bazelci-agent")?; | |
| cmd.args([ | |
| "artifact", | |
| "upload", | |
| "--dry", | |
| "--mode=buildkite", | |
| format!("--build_event_json_file={}", path.display()).as_str(), | |
| ]); | |
| cmd.assert() | |
| .success() | |
| .stdout(predicates::str::contains("buildkite-agent artifact upload --content-type text/plain;charset=utf-8 src/test/shell/bazel/starlark_repository_test/shard_4_of_6/test_attempts/attempt_1.log")); | |
| Ok(()) | |
| }) | |
| } |