summaryrefslogtreecommitdiff
path: root/tests/integration/cache.rs
diff options
context:
space:
mode:
Diffstat (limited to 'tests/integration/cache.rs')
-rw-r--r--tests/integration/cache.rs125
1 files changed, 125 insertions, 0 deletions
diff --git a/tests/integration/cache.rs b/tests/integration/cache.rs
new file mode 100644
index 0000000..42d2a15
--- /dev/null
+++ b/tests/integration/cache.rs
@@ -0,0 +1,125 @@
+use crate::git_helpers::create_local_repo;
+use crate::harness::{SiteBuilder, TestServer, test_config_with_site};
+use crate::runtime::{skip_without_git, skip_without_runtime};
+use std::time::Duration;
+use witryna::config::sanitize_cache_dir_name;
+
+#[tokio::test]
+async fn cache_dir_persists_across_builds() {
+ skip_without_git!();
+ skip_without_runtime!();
+
+ let tempdir = tempfile::tempdir().unwrap();
+ let base_dir = tempdir.path().to_path_buf();
+
+ let repo_dir = tempdir.path().join("repos");
+ tokio::fs::create_dir_all(&repo_dir).await.unwrap();
+ let repo_url = create_local_repo(&repo_dir, "main").await;
+
+ let site = SiteBuilder::new("cache-site", &repo_url, "cache-token")
+ .overrides(
+ "alpine:latest",
+ "mkdir -p /tmp/test-cache && echo 'cached' > /tmp/test-cache/marker && mkdir -p out && cp /tmp/test-cache/marker out/marker",
+ "out",
+ )
+ .cache_dirs(vec!["/tmp/test-cache".to_owned()])
+ .build();
+
+ let server = TestServer::start(test_config_with_site(base_dir.clone(), site)).await;
+
+ // --- Build 1: create marker in cache ---
+ let resp = TestServer::client()
+ .post(server.url("/cache-site"))
+ .header("Authorization", "Bearer cache-token")
+ .send()
+ .await
+ .unwrap();
+ assert_eq!(resp.status().as_u16(), 202);
+
+ // Wait for build to complete
+ let builds_dir = base_dir.join("builds/cache-site");
+ let max_wait = Duration::from_secs(120);
+ let start = std::time::Instant::now();
+
+ loop {
+ assert!(
+ start.elapsed() <= max_wait,
+ "build 1 timed out after {max_wait:?}"
+ );
+ if builds_dir.join("current").is_symlink() {
+ break;
+ }
+ tokio::time::sleep(Duration::from_millis(500)).await;
+ }
+
+ // Verify built output
+ let target = tokio::fs::read_link(builds_dir.join("current"))
+ .await
+ .unwrap();
+ assert!(
+ target.join("marker").exists(),
+ "marker should exist in build output"
+ );
+
+ // Host-side verification: cache directory should exist with marker
+ let sanitized = sanitize_cache_dir_name("/tmp/test-cache");
+ let host_cache_dir = base_dir.join("cache/cache-site").join(&sanitized);
+ assert!(
+ host_cache_dir.join("marker").exists(),
+ "marker should exist in host cache dir: {}",
+ host_cache_dir.display()
+ );
+
+ // --- Build 2: verify marker was already there (cache persisted) ---
+ // Wait for build lock to release
+ let start = std::time::Instant::now();
+ loop {
+ if start.elapsed() > Duration::from_secs(10) {
+ break;
+ }
+ if !server
+ .state
+ .build_scheduler
+ .in_progress
+ .contains("cache-site")
+ {
+ break;
+ }
+ tokio::time::sleep(Duration::from_millis(200)).await;
+ }
+
+ let resp = TestServer::client()
+ .post(server.url("/cache-site"))
+ .header("Authorization", "Bearer cache-token")
+ .send()
+ .await
+ .unwrap();
+ assert_eq!(resp.status().as_u16(), 202);
+
+ // Wait for second build to complete (symlink target changes)
+ let first_target = target;
+ let start = std::time::Instant::now();
+ loop {
+ assert!(
+ start.elapsed() <= max_wait,
+ "build 2 timed out after {max_wait:?}"
+ );
+ if let Ok(new_target) = tokio::fs::read_link(builds_dir.join("current")).await
+ && new_target != first_target
+ {
+ // Verify marker still in output
+ assert!(
+ new_target.join("marker").exists(),
+ "marker should exist in second build output (cache persisted)"
+ );
+ break;
+ }
+ tokio::time::sleep(Duration::from_millis(500)).await;
+ }
+
+ // Host-side: cache dir still has marker
+ assert!(
+ host_cache_dir.join("marker").exists(),
+ "marker should still exist in host cache dir after build 2"
+ );
+}