mirror of
https://github.com/rustfs/rustfs.git
synced 2026-09-09 21:56:03 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 212950fe59 |
@@ -1,2 +1,2 @@
|
||||
sha256-darwin=874c881d7b45f12378a5817c7f42c95c4981960a2ec9ce12dcf4af239ae1f9d5
|
||||
sha256-linux=9351e25b45bf7dfce18b951a5e3740225f457cacc53b8bf9f500f6947763ec0e
|
||||
sha256-linux=9515861be899ceb10e2e0ef93c34208bb7a7a8a7f8067a02db4cfba23270ebd6
|
||||
|
||||
@@ -17540,6 +17540,66 @@ mod tests {
|
||||
assert!(current.tiers.contains_key("COLD-B"));
|
||||
}
|
||||
|
||||
async fn wait_for_reference_proof_barrier(
|
||||
barrier: &TierDriverBuildBarrier,
|
||||
update: &mut tokio::task::JoinHandle<std::result::Result<(), TierConfigUpdateError>>,
|
||||
) -> std::result::Result<(), String> {
|
||||
tokio::select! {
|
||||
biased;
|
||||
result = &mut *update => Err(format!("tier update exited before the reference proof barrier: {result:?}")),
|
||||
() = barrier.arrived.notified() => Ok(()),
|
||||
() = tokio::time::sleep(Duration::from_secs(30)) => {
|
||||
// Aborting the caller does not stop its owned mutation task.
|
||||
// Let a late arrival pass the test-only barrier.
|
||||
barrier.release.add_permits(1);
|
||||
update.abort();
|
||||
Err("timed out waiting for the reference proof barrier".to_string())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[serial_test::serial]
|
||||
async fn reference_proof_barrier_reports_update_failure_before_arrival() {
|
||||
let manager = TierConfigMgr::new();
|
||||
let store = Arc::new(CasConfigStore::default());
|
||||
let mut persisted = empty_mgr();
|
||||
persisted.tiers.insert("COLD-A".to_string(), build_rustfs_tier("COLD-A"));
|
||||
persisted
|
||||
.save_tiering_config_if_current(store.clone(), None)
|
||||
.await
|
||||
.expect("early update failure fixture should persist");
|
||||
let barrier = tier_reference_proof_test_barrier();
|
||||
let scoped_barrier = barrier.clone();
|
||||
let factory: TierDriverTestFactory =
|
||||
Arc::new(|_| Err(AdminError::msg("injected driver initialization failure before reference proof")));
|
||||
let mut update = tokio::spawn(async move {
|
||||
TIER_REFERENCE_PROOF_TEST_BARRIER
|
||||
.scope(
|
||||
scoped_barrier,
|
||||
TIER_DRIVER_TEST_FACTORY.scope(
|
||||
factory,
|
||||
TIER_MUTATION_TEST_PEERS.scope(
|
||||
Vec::new(),
|
||||
TierConfigMgr::update_candidate_with_config_lock(
|
||||
&manager,
|
||||
store,
|
||||
TierCandidateMutation::Remove("COLD-A".to_string(), true),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
.await
|
||||
});
|
||||
|
||||
let err = tokio::time::timeout(Duration::from_secs(5), wait_for_reference_proof_barrier(&barrier, &mut update))
|
||||
.await
|
||||
.expect("an early update failure should be observed without waiting for the barrier deadline")
|
||||
.expect_err("a failed update cannot reach the reference proof barrier");
|
||||
assert!(err.contains("Mutation"), "{err}");
|
||||
assert!(err.contains("injected driver initialization failure before reference proof"), "{err}");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[serial_test::serial]
|
||||
async fn reference_proof_rejects_a_changed_prepared_fence_revision_before_publish() {
|
||||
@@ -17560,7 +17620,7 @@ mod tests {
|
||||
let scoped_barrier = barrier.clone();
|
||||
let update_manager = manager.clone();
|
||||
let update_store = store.clone();
|
||||
let update = tokio::spawn(async move {
|
||||
let mut update = tokio::spawn(async move {
|
||||
TIER_REFERENCE_PROOF_TEST_BARRIER
|
||||
.scope(
|
||||
scoped_barrier,
|
||||
@@ -17575,7 +17635,9 @@ mod tests {
|
||||
)
|
||||
.await
|
||||
});
|
||||
barrier.arrived.notified().await;
|
||||
wait_for_reference_proof_barrier(&barrier, &mut update)
|
||||
.await
|
||||
.expect("tier update should reach the reference proof barrier");
|
||||
|
||||
let unrelated = prepared_remove_intent("COLD-B", uuid::Uuid::from_u128(0x2237));
|
||||
TierConfigMgr::apply_prepared_mutation_intent_block(&manager, &unrelated)
|
||||
@@ -17583,8 +17645,9 @@ mod tests {
|
||||
.expect("an unrelated prepared fence should advance the runtime revision");
|
||||
barrier.release.add_permits(1);
|
||||
|
||||
let err = update
|
||||
let err = tokio::time::timeout(Duration::from_secs(30), update)
|
||||
.await
|
||||
.expect("tier update should finish after the reference proof barrier releases")
|
||||
.expect("tier update task should join")
|
||||
.expect_err("a reference proof cannot authorize publication across a fence revision change");
|
||||
let TierConfigUpdateError::Publish(err) = err else {
|
||||
|
||||
+1
-22
@@ -59,7 +59,7 @@ def expected_results(mode: str, event: str, ref: str) -> dict[str, str]:
|
||||
expected.update({job: "success" if mode == "full" else "skipped" for job in CODE_JOBS})
|
||||
rio = mode == "full" and event in ("schedule", "workflow_dispatch")
|
||||
expected.update({job: "success" if rio else "skipped" for job in OPTIONAL_JOBS[:2]})
|
||||
full = mode == "full" and (event in ("merge_group", "workflow_dispatch") or (event == "push" and ref in ("refs/heads/main", "refs/heads/release")))
|
||||
full = mode == "full" and (event in ("merge_group", "workflow_dispatch") or (event == "push" and ref == "refs/heads/main"))
|
||||
expected["e2e-full"] = "success" if full else "skipped"
|
||||
return expected
|
||||
|
||||
@@ -219,27 +219,6 @@ class SelfTests(unittest.TestCase):
|
||||
bad = {**good, "classify-changes": {"result": "success", "outputs": selection}}
|
||||
self.assertTrue(verify_results(bad, event, "refs/heads/main"))
|
||||
|
||||
def test_full_e2e_gate_preserves_workflow_branch_and_event_scope(self):
|
||||
for event, ref, required in (
|
||||
("push", "refs/heads/main", "success"),
|
||||
("push", "refs/heads/release", "success"),
|
||||
("push", "refs/heads/feature", "skipped"),
|
||||
("push", "refs/heads/release-candidate", "skipped"),
|
||||
("push", "refs/tags/release", "skipped"),
|
||||
("pull_request", "refs/pull/1/merge", "skipped"),
|
||||
("schedule", "refs/heads/release", "skipped"),
|
||||
("workflow_dispatch", "refs/heads/feature", "success"),
|
||||
("merge_group", "refs/heads/gh-readonly-queue/release/pr-1", "success"),
|
||||
):
|
||||
with self.subTest(event=event, ref=ref):
|
||||
expected = expected_results("full", event, ref)
|
||||
self.assertEqual(expected["e2e-full"], required)
|
||||
needs = {job: {"result": result} for job, result in expected.items()}
|
||||
needs["classify-changes"]["outputs"] = {"mode": "full"}
|
||||
for result in ("success", "skipped", "failure", "cancelled"):
|
||||
needs["e2e-full"]["result"] = result
|
||||
self.assertEqual(verify_results(needs, event, ref) == [], result == required)
|
||||
|
||||
def test_repository_wiring_and_missing_dependency_regression(self):
|
||||
self.assertEqual(check_workflow(ROOT), [])
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
|
||||
Reference in New Issue
Block a user