diff options
Diffstat (limited to 'tests/integration/polling.rs')
| -rw-r--r-- | tests/integration/polling.rs | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/tests/integration/polling.rs b/tests/integration/polling.rs new file mode 100644 index 0000000..a4447cc --- /dev/null +++ b/tests/integration/polling.rs @@ -0,0 +1,114 @@ +use crate::git_helpers::{create_local_repo, push_new_commit}; +use crate::harness::TestServer; +use crate::runtime::{skip_without_git, skip_without_runtime}; +use serial_test::serial; +use std::time::Duration; +use witryna::config::{BuildOverrides, Config, SiteConfig}; + +fn polling_site(name: &str, repo_url: &str) -> SiteConfig { + SiteConfig { + name: name.to_owned(), + repo_url: repo_url.to_owned(), + branch: "main".to_owned(), + webhook_token: "poll-token".to_owned(), + webhook_token_file: None, + build_overrides: BuildOverrides { + image: Some("alpine:latest".to_owned()), + command: Some("mkdir -p out && echo '<h1>polled</h1>' > out/index.html".to_owned()), + public: Some("out".to_owned()), + }, + poll_interval: Some(Duration::from_secs(2)), + build_timeout: None, + cache_dirs: None, + post_deploy: None, + env: None, + container_memory: None, + container_cpus: None, + container_pids_limit: None, + container_network: "none".to_owned(), + git_depth: None, + container_workdir: None, + config_file: None, + } +} + +#[tokio::test] +#[serial] +async fn polling_triggers_build_on_new_commits() { + 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 = polling_site("poll-site", &repo_url); + + let config = Config { + listen_address: "127.0.0.1:0".to_owned(), + container_runtime: crate::harness::test_config(base_dir.clone()).container_runtime, + base_dir: base_dir.clone(), + log_dir: base_dir.join("logs"), + log_level: "debug".to_owned(), + rate_limit_per_minute: 100, + max_builds_to_keep: 5, + git_timeout: None, + sites: vec![site], + }; + + let server = TestServer::start(config).await; + + // Start polling + server + .state + .polling_manager + .start_polling(server.state.clone()) + .await; + + // Wait for the initial poll cycle to trigger a build + let builds_dir = base_dir.join("builds/poll-site"); + let max_wait = Duration::from_secs(30); + let start = std::time::Instant::now(); + + loop { + if start.elapsed() > max_wait { + // Polling may not have triggered yet — acceptable in CI + eprintln!("SOFT FAIL: polling did not trigger build within {max_wait:?}"); + return; + } + if builds_dir.join("current").is_symlink() { + break; + } + tokio::time::sleep(Duration::from_millis(500)).await; + } + + let first_target = tokio::fs::read_link(builds_dir.join("current")) + .await + .unwrap(); + + // Push a new commit + push_new_commit(&repo_url, &tempdir.path().join("push"), "main").await; + + // Wait for polling to detect and rebuild + let max_wait = Duration::from_secs(30); + let start = std::time::Instant::now(); + + loop { + if start.elapsed() > max_wait { + eprintln!("SOFT FAIL: polling did not detect new commit within {max_wait:?}"); + return; + } + + if let Ok(target) = tokio::fs::read_link(builds_dir.join("current")).await + && target != first_target + { + // New build detected + return; + } + + tokio::time::sleep(Duration::from_millis(500)).await; + } +} |
