summaryrefslogtreecommitdiff
path: root/tests/integration/polling.rs
diff options
context:
space:
mode:
Diffstat (limited to 'tests/integration/polling.rs')
-rw-r--r--tests/integration/polling.rs114
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;
+ }
+}