Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 2
release: publish fbuild 2.5.7 dependency cascade#1244
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
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Uh oh!
There was an error while loading. Please reload this page.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -5,8 +5,45 @@ | ||
| //! with it). | ||
| use fbuild_build::zccache_embedded::FbuildZccacheService; | ||
| use fbuild_core::path::NormalizedPath; | ||
| use zccache::embedded::ShutdownMode; | ||
| fn find_c_compiler() -> NormalizedPath { | ||
| let path_dirs: Vec<_> = | ||
| std::env::split_paths(&std::env::var_os("PATH").expect("PATH should be set")).collect(); | ||
| let on_path = |name: &str| { | ||
| path_dirs | ||
| .iter() | ||
| .map(|dir| dir.join(name)) | ||
| .find(|candidate| candidate.is_file()) | ||
| .map(NormalizedPath::from) | ||
| }; | ||
| if cfg!(windows) { | ||
| if let Some(candidate) = on_path("clang.exe") { | ||
| return candidate; | ||
| } | ||
| if let Some(program_files) = std::env::var_os("ProgramFiles") { | ||
| let candidate = NormalizedPath::new(std::path::Path::new(&program_files)) | ||
| .join("LLVM") | ||
| .join("bin") | ||
| .join("clang.exe"); | ||
| if candidate.is_file() { | ||
| return candidate; | ||
| } | ||
| } | ||
| if let Some(candidate) = on_path("gcc.exe") { | ||
| return candidate; | ||
| } | ||
| panic!("clang.exe or gcc.exe must be installed for this smoke test"); | ||
| } | ||
| for name in ["cc", "clang", "gcc"] { | ||
| if let Some(candidate) = on_path(name) { | ||
| return candidate; | ||
| } | ||
| } | ||
coderabbitai[bot] marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| panic!("cc, clang, or gcc must be installed for this smoke test"); | ||
| } | ||
| /// `FbuildZccacheService::start_in` produces a working service | ||
| /// handle: the cache root exists on disk, the identity carries our | ||
| /// product tag, and a graceful shutdown returns cleanly. | ||
| @@ -42,3 +79,80 @@ async fn embedded_service_starts_and_shuts_down() { | ||
| .await | ||
| .expect("graceful shutdown should succeed"); | ||
| } | ||
| /// A real compile traverses fbuild's embedded zccache boundary twice: the | ||
| /// first invocation populates a fresh cache and the second must materialize | ||
| /// the object from that cache. This is also a link-time guard against loading | ||
| /// two copies of running-process's unmangled `rp_*_public` exports. | ||
| #[tokio::test(flavor = "multi_thread", worker_threads = 2)] | ||
| async fn embedded_compilation_cold_miss_then_warm_hit() { | ||
| let tmp = tempfile::TempDir::new().expect("tempdir"); | ||
| let cache_root = tmp.path().join("zccache"); | ||
| let source = tmp.path().join("smoke.c"); | ||
| let object = tmp.path().join(if cfg!(windows) { | ||
| "smoke.obj" | ||
| } else { | ||
| "smoke.o" | ||
| }); | ||
| std::fs::write(&source, "int smoke(void) { return 42; }\n").expect("write source"); | ||
| let svc = FbuildZccacheService::start_in(cache_root) | ||
| .await | ||
| .expect("embedded service should start"); | ||
| let compiler = find_c_compiler(); | ||
| let args = vec![ | ||
| "-c".to_string(), | ||
| source.to_string_lossy().into_owned(), | ||
| "-o".to_string(), | ||
| object.to_string_lossy().into_owned(), | ||
| ]; | ||
| let mut compile_env = fbuild_core::subprocess::compile_env_for_build(tmp.path()) | ||
| .expect("prepare the same hermetic compile environment used in production"); | ||
| compile_env.push(( | ||
| "ZCCACHE_WORKTREE_ROOT".to_string(), | ||
| tmp.path().to_string_lossy().into_owned(), | ||
| )); | ||
| let cold = svc | ||
| .compile( | ||
| &compiler, | ||
| args.clone(), | ||
| tmp.path().to_path_buf(), | ||
| compile_env.clone(), | ||
| ) | ||
| .await | ||
| .expect("cold embedded compile should succeed"); | ||
| assert_eq!( | ||
| cold.exit_code, | ||
| 0, | ||
| "cold compile stderr: {}", | ||
| String::from_utf8_lossy(&cold.stderr) | ||
| ); | ||
| assert!(!cold.cached, "fresh cache unexpectedly reported a hit"); | ||
| assert!(object.is_file(), "cold compile should create an object"); | ||
| svc.flush() | ||
| .await | ||
| .expect("flush cold compile into the cache"); | ||
| std::fs::remove_file(&object).expect("remove cold object before warm materialization"); | ||
| let warm = svc | ||
| .compile(&compiler, args, tmp.path().to_path_buf(), compile_env) | ||
| .await | ||
| .expect("warm embedded compile should succeed"); | ||
| assert_eq!( | ||
| warm.exit_code, | ||
| 0, | ||
| "warm compile stderr: {}", | ||
| String::from_utf8_lossy(&warm.stderr) | ||
| ); | ||
| assert!( | ||
| warm.cached, | ||
| "second identical compile should be a cache hit" | ||
| ); | ||
| assert!(object.is_file(), "warm hit should materialize the object"); | ||
| svc.shutdown(ShutdownMode::Graceful) | ||
| .await | ||
| .expect("graceful shutdown should succeed"); | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.