OXYGENHUB

Tests wait for the push hook instead of guessing how long it takes 92cea629fdf6

Three tests slept a fixed 300 ms after a push and then expected the
push hook, which runs after the push answers, to have linked an
identity, closed an issue or recorded a reference; under load it had
not (a_rotated_identity_links_itself failed once, 2026-10-10). They
poll for the effect, up to ten seconds. The one that checks no run
starts keeps its wait: a late run would make it pass, not fail.

closes #121
Author
Andy McCall @andymccall <[email protected]>
When
· 2026-10-10 21:57 UTC
Signature
✔ signed by Andy McCall
Hash
92cea629fdf6614fe819c850b117a530402d079bc5dfc690ddacb0fe044fd336
Depends on
145306044896 18e381ea88c2 78001759604c 8933faff2043
Depended on by
nothing yet
In bookmarks
api-unknown-fields cancel-landed-runs clear-waiting close-proposal-140 diffusion-pin-bookmark draft-ready image-check job-waits main oh-comment-body-file proposal-list-fast run-one-job wiki-says-so
In tags
v0.4.2 v0.5.0 v0.5.1 v0.5.2 v0.6.0 v0.6.1 v0.7.0 v0.8.0 v0.9.0 v0.9.1 v0.9.11 v0.9.15 v0.9.16 v0.9.19 v0.9.2 v0.9.20 v0.9.21 v0.9.22 v0.9.23 v0.9.24 v0.9.3 v0.9.4 v0.9.5 v0.9.6 v0.9.7 v0.9.8 v0.9.9
Edits
5 atoms, 0 tree operations, 2 files

Browse the tree at this change

modified crates/hub/tests/edits.rs +10 −3
…
538 unchanged lines
539 539
    let by_agent = as_agent.commit("third, by the agent", &[]).unwrap();
540 540
    // Andy pushes both.
541 541
    assert!(client.push("origin", false).unwrap().iter().all(|r| r.ok));
542 -
    tokio::time::sleep(std::time::Duration::from_millis(300)).await;
543 542
544 -
    // The successor is linked to Andy's account by the push.
545 -
    let linked = db::accounts::identity_by_key(&app.db, &key2.to_hex()).await.unwrap();
543 +
    // The successor is linked to Andy's account by the push hook, which runs
544 +
    // after the push answers: wait for it, up to ten seconds (#121).
545 +
    let mut linked = None;
546 +
    for _ in 0..200 {
547 +
        linked = db::accounts::identity_by_key(&app.db, &key2.to_hex()).await.unwrap();
548 +
        if linked.is_some() {
549 +
            break;
550 +
        }
551 +
        tokio::time::sleep(std::time::Duration::from_millis(50)).await;
552 +
    }
546 553
    assert_eq!(linked.map(|l| l.account_id), Some(andy_id), "the rotated identity links itself");
547 554
    assert!(db::accounts::identity_by_key(&app.db, &agent_key.to_hex()).await.unwrap().is_none(), "an agent's key is nobody's account");
548 555
…
24 unchanged lines
modified crates/hub/tests/issues.rs +20 −4
…
225 unchanged lines
226 226
    client.snapshot("t").unwrap();
227 227
    client.commit("Fix the typo\n\nCloses #2", &[]).unwrap();
228 228
    assert!(client.push("origin", false).unwrap().iter().all(|r| r.ok));
229 -
    tokio::time::sleep(std::time::Duration::from_millis(300)).await;
230 -
    let issue2 = db::issues::get(&app.db, db::repos::get(&app.db, "andy", "demo").await.unwrap().unwrap().id, 2).await.unwrap().unwrap();
229 +
    // The push hook closes it after the push answers: wait, up to ten seconds (#121).
230 +
    let repo_id = db::repos::get(&app.db, "andy", "demo").await.unwrap().unwrap().id;
231 +
    let mut issue2 = db::issues::get(&app.db, repo_id, 2).await.unwrap().unwrap();
232 +
    for _ in 0..200 {
233 +
        if issue2.state == "closed" {
234 +
            break;
235 +
        }
236 +
        tokio::time::sleep(std::time::Duration::from_millis(50)).await;
237 +
        issue2 = db::issues::get(&app.db, repo_id, 2).await.unwrap().unwrap();
238 +
    }
231 239
    assert_eq!(issue2.state, "closed", "closed by the landed change");
232 240
    assert!(get(app, "/andy/demo/issue/2", None).await.body.contains("closed by change"));
233 241
…
17 unchanged lines
251 259
    client.snapshot("t").unwrap();
252 260
    let r = client.commit("Tidy up (refs #1, see #3)", &[]).unwrap();
253 261
    assert!(client.push("origin", false).unwrap().iter().all(|r| r.ok));
254 -
    tokio::time::sleep(std::time::Duration::from_millis(300)).await;
255 262
    let short = &r.to_hex()[..12];
256 -
    let one = get(app, "/andy/demo/issue/1", None).await.body;
263 +
    // The push hook records the references after the push answers: wait, up
264 +
    // to ten seconds (#121).
265 +
    let mut one = get(app, "/andy/demo/issue/1", None).await.body;
266 +
    for _ in 0..200 {
267 +
        if one.contains("referenced by change") {
268 +
            break;
269 +
        }
270 +
        tokio::time::sleep(std::time::Duration::from_millis(50)).await;
271 +
        one = get(app, "/andy/demo/issue/1", None).await.body;
272 +
    }
257 273
    assert!(
258 274
        one.contains("referenced by change") && one.contains(&format!("href=\"/andy/demo/change/{short}\"")) && one.contains(" on main"),
259 275
        "{one}"
…
584 unchanged lines