summaryrefslogtreecommitdiff
path: root/tests/integration/concurrent.rs
blob: da09ac9ac3f84b7e98ad7eb4a76e50cdcdc84870 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
use crate::harness::{SiteBuilder, TestServer, test_config_with_site};

#[tokio::test]
async fn concurrent_build_gets_queued() {
    let dir = tempfile::tempdir().unwrap().keep();
    let site = SiteBuilder::new("my-site", "https://example.com/repo.git", "secret-token").build();
    let server = TestServer::start(test_config_with_site(dir, site)).await;

    // Pre-inject a build in progress via AppState
    server
        .state
        .build_scheduler
        .in_progress
        .lock()
        .unwrap()
        .insert("my-site".to_owned());

    let resp = TestServer::client()
        .post(server.url("/my-site"))
        .header("Authorization", "Bearer secret-token")
        .send()
        .await
        .unwrap();

    assert_eq!(resp.status().as_u16(), 202);
    let body = resp.text().await.unwrap();
    let json: serde_json::Value = serde_json::from_str(&body).unwrap();
    assert_eq!(json["status"], "queued");
}

#[tokio::test]
async fn concurrent_build_queue_collapse() {
    let dir = tempfile::tempdir().unwrap().keep();
    let site = SiteBuilder::new("my-site", "https://example.com/repo.git", "secret-token").build();
    let server = TestServer::start(test_config_with_site(dir, site)).await;

    // Pre-inject a build in progress and a queued rebuild
    server
        .state
        .build_scheduler
        .in_progress
        .lock()
        .unwrap()
        .insert("my-site".to_owned());
    server
        .state
        .build_scheduler
        .queued
        .lock()
        .unwrap()
        .insert("my-site".to_owned());

    // Third request should collapse (202, no body)
    let resp = TestServer::client()
        .post(server.url("/my-site"))
        .header("Authorization", "Bearer secret-token")
        .send()
        .await
        .unwrap();

    assert_eq!(resp.status().as_u16(), 202);
    let body = resp.text().await.unwrap();
    assert!(body.is_empty());
}

#[tokio::test]
async fn concurrent_different_sites_both_accepted() {
    let dir = tempfile::tempdir().unwrap().keep();
    let sites = vec![
        SiteBuilder::new("site-one", "https://example.com/one.git", "token-one").build(),
        SiteBuilder::new("site-two", "https://example.com/two.git", "token-two").build(),
    ];
    let config = crate::harness::test_config_with_sites(dir, sites);
    let server = TestServer::start(config).await;

    // First site — accepted
    let resp1 = TestServer::client()
        .post(server.url("/site-one"))
        .header("Authorization", "Bearer token-one")
        .send()
        .await
        .unwrap();
    assert_eq!(resp1.status().as_u16(), 202);

    // Second site — also accepted (different build lock)
    let resp2 = TestServer::client()
        .post(server.url("/site-two"))
        .header("Authorization", "Bearer token-two")
        .send()
        .await
        .unwrap();
    assert_eq!(resp2.status().as_u16(), 202);
}

#[tokio::test]
async fn build_in_progress_checked_after_auth() {
    let dir = tempfile::tempdir().unwrap().keep();
    let site = SiteBuilder::new("my-site", "https://example.com/repo.git", "secret-token").build();
    let server = TestServer::start(test_config_with_site(dir, site)).await;

    // Pre-mark site as building
    server
        .state
        .build_scheduler
        .in_progress
        .lock()
        .unwrap()
        .insert("my-site".to_owned());

    // Request with wrong token should return 401 (auth checked before build status)
    let resp = TestServer::client()
        .post(server.url("/my-site"))
        .header("Authorization", "Bearer wrong-token")
        .send()
        .await
        .unwrap();

    assert_eq!(resp.status().as_u16(), 401);
}