#![cfg(all(feature = "dist-client", feature = "dist-server"))] extern crate assert_cmd; #[macro_use] extern crate log; extern crate sccache; extern crate serde_json; use crate::harness::{ get_stats, sccache_command, start_local_daemon, stop_local_daemon, write_json_cfg, write_source, }; use assert_cmd::prelude::*; use sccache::config::HTTPUrl; use sccache::dist::{ AssignJobResult, CompileCommand, InputsReader, JobId, JobState, RunJobResult, ServerIncoming, ServerOutgoing, SubmitToolchainResult, Toolchain, ToolchainReader, }; use std::ffi::OsStr; use std::path::Path; use sccache::errors::*; mod harness; fn basic_compile(tmpdir: &Path, sccache_cfg_path: &Path, sccache_cached_cfg_path: &Path) { let envs: Vec<(_, &OsStr)> = vec![ ("RUST_BACKTRACE", "1".as_ref()), ("SCCACHE_LOG", "debug".as_ref()), ("SCCACHE_CONF", sccache_cfg_path.as_ref()), ("SCCACHE_CACHED_CONF", sccache_cached_cfg_path.as_ref()), ]; let source_file = "x.c"; let obj_file = "x.o"; write_source(tmpdir, source_file, "#if !defined(SCCACHE_TEST_DEFINE)\n#error SCCACHE_TEST_DEFINE is not defined\n#endif\nint x() { return 5; }"); sccache_command() .args([ std::env::var("CC") .unwrap_or_else(|_| "gcc".to_string()) .as_str(), "-c", "-DSCCACHE_TEST_DEFINE", ]) .arg(tmpdir.join(source_file)) .arg("-o") .arg(tmpdir.join(obj_file)) .envs(envs) .assert() .success(); } pub fn dist_test_sccache_client_cfg( tmpdir: &Path, scheduler_url: HTTPUrl, ) -> sccache::config::FileConfig { let mut sccache_cfg = harness::sccache_client_cfg(tmpdir, false); sccache_cfg.cache.disk.as_mut().unwrap().size = 0; sccache_cfg.dist.scheduler_url = Some(scheduler_url); sccache_cfg } #[test] #[cfg_attr(not(feature = "dist-tests"), ignore)] fn test_dist_basic() { let tmpdir = tempfile::Builder::new() .prefix("sccache_dist_test") .tempdir() .unwrap(); let tmpdir = tmpdir.path(); let sccache_dist = harness::sccache_dist_path(); let mut system = harness::DistSystem::new(&sccache_dist, tmpdir); system.add_scheduler(); system.add_server(); let sccache_cfg = dist_test_sccache_client_cfg(tmpdir, system.scheduler_url()); let sccache_cfg_path = tmpdir.join("sccache-cfg.json"); write_json_cfg(tmpdir, "sccache-cfg.json", &sccache_cfg); let sccache_cached_cfg_path = tmpdir.join("sccache-cached-cfg"); stop_local_daemon(); start_local_daemon(&sccache_cfg_path, &sccache_cached_cfg_path); basic_compile(tmpdir, &sccache_cfg_path, &sccache_cached_cfg_path); get_stats(|info| { assert_eq!(1, info.stats.dist_compiles.values().sum::()); assert_eq!(0, info.stats.dist_errors); assert_eq!(1, info.stats.compile_requests); assert_eq!(1, info.stats.requests_executed); assert_eq!(0, info.stats.cache_hits.all()); assert_eq!(1, info.stats.cache_misses.all()); }); } #[test] #[cfg_attr(not(feature = "dist-tests"), ignore)] fn test_dist_restartedserver() { let tmpdir = tempfile::Builder::new() .prefix("sccache_dist_test") .tempdir() .unwrap(); let tmpdir = tmpdir.path(); let sccache_dist = harness::sccache_dist_path(); let mut system = harness::DistSystem::new(&sccache_dist, tmpdir); system.add_scheduler(); let server_handle = system.add_server(); let sccache_cfg = dist_test_sccache_client_cfg(tmpdir, system.scheduler_url()); let sccache_cfg_path = tmpdir.join("sccache-cfg.json"); write_json_cfg(tmpdir, "sccache-cfg.json", &sccache_cfg); let sccache_cached_cfg_path = tmpdir.join("sccache-cached-cfg"); stop_local_daemon(); start_local_daemon(&sccache_cfg_path, &sccache_cached_cfg_path); basic_compile(tmpdir, &sccache_cfg_path, &sccache_cached_cfg_path); system.restart_server(&server_handle); basic_compile(tmpdir, &sccache_cfg_path, &sccache_cached_cfg_path); get_stats(|info| { assert_eq!(2, info.stats.dist_compiles.values().sum::()); assert_eq!(0, info.stats.dist_errors); assert_eq!(2, info.stats.compile_requests); assert_eq!(2, info.stats.requests_executed); assert_eq!(0, info.stats.cache_hits.all()); assert_eq!(2, info.stats.cache_misses.all()); }); } #[test] #[cfg_attr(not(feature = "dist-tests"), ignore)] fn test_dist_nobuilder() { let tmpdir = tempfile::Builder::new() .prefix("sccache_dist_test") .tempdir() .unwrap(); let tmpdir = tmpdir.path(); let sccache_dist = harness::sccache_dist_path(); let mut system = harness::DistSystem::new(&sccache_dist, tmpdir); system.add_scheduler(); let sccache_cfg = dist_test_sccache_client_cfg(tmpdir, system.scheduler_url()); let sccache_cfg_path = tmpdir.join("sccache-cfg.json"); write_json_cfg(tmpdir, "sccache-cfg.json", &sccache_cfg); let sccache_cached_cfg_path = tmpdir.join("sccache-cached-cfg"); stop_local_daemon(); start_local_daemon(&sccache_cfg_path, &sccache_cached_cfg_path); basic_compile(tmpdir, &sccache_cfg_path, &sccache_cached_cfg_path); get_stats(|info| { assert_eq!(0, info.stats.dist_compiles.values().sum::()); assert_eq!(1, info.stats.dist_errors); assert_eq!(1, info.stats.compile_requests); assert_eq!(1, info.stats.requests_executed); assert_eq!(0, info.stats.cache_hits.all()); assert_eq!(1, info.stats.cache_misses.all()); }); } struct FailingServer; impl ServerIncoming for FailingServer { fn handle_assign_job(&self, _job_id: JobId, _tc: Toolchain) -> Result { let need_toolchain = false; let state = JobState::Ready; Ok(AssignJobResult { need_toolchain, state, }) } fn handle_submit_toolchain( &self, _requester: &dyn ServerOutgoing, _job_id: JobId, _tc_rdr: ToolchainReader, ) -> Result { panic!("should not have submitted toolchain") } fn handle_run_job( &self, requester: &dyn ServerOutgoing, job_id: JobId, _command: CompileCommand, _outputs: Vec, _inputs_rdr: InputsReader, ) -> Result { requester .do_update_job_state(job_id, JobState::Started) .context("Updating job state failed")?; bail!("internal build failure") } } #[test] #[cfg_attr(not(feature = "dist-tests"), ignore)] fn test_dist_failingserver() { let tmpdir = tempfile::Builder::new() .prefix("sccache_dist_test") .tempdir() .unwrap(); let tmpdir = tmpdir.path(); let sccache_dist = harness::sccache_dist_path(); let mut system = harness::DistSystem::new(&sccache_dist, tmpdir); system.add_scheduler(); system.add_custom_server(FailingServer); let sccache_cfg = dist_test_sccache_client_cfg(tmpdir, system.scheduler_url()); let sccache_cfg_path = tmpdir.join("sccache-cfg.json"); write_json_cfg(tmpdir, "sccache-cfg.json", &sccache_cfg); let sccache_cached_cfg_path = tmpdir.join("sccache-cached-cfg"); stop_local_daemon(); start_local_daemon(&sccache_cfg_path, &sccache_cached_cfg_path); basic_compile(tmpdir, &sccache_cfg_path, &sccache_cached_cfg_path); get_stats(|info| { assert_eq!(0, info.stats.dist_compiles.values().sum::()); assert_eq!(1, info.stats.dist_errors); assert_eq!(1, info.stats.compile_requests); assert_eq!(1, info.stats.requests_executed); assert_eq!(0, info.stats.cache_hits.all()); assert_eq!(1, info.stats.cache_misses.all()); }); }