mirror of
https://github.com/rustfs/rustfs.git
synced 2026-10-02 05:14:35 +08:00
ci: register the fault-tolerance suite workflow on the default branch (#7929)
The fault-tolerance suite (disk-outage and peer-failure scenarios, FT-CASE verdicts) has never been dispatchable: the workflow file only exists on release, and GitHub registers workflow_dispatch targets exclusively from the default branch. The suite is otherwise ready - it runs on the smoke-testing fleet and already uses the rustfs-shared-functional-tests-v2 lock. Adds the workflow adapted to this branch's current (pre-sync) gate semantics - the run step's continue-on-error is dropped so the existing contract holds - plus the evidence init aligned with the shared four-variable pattern (FUNCTIONAL_ARTIFACTS_DIR under rustfs-fault-tolerance-*, LOG_FILE/REPORT_FILE/EVIDENCE_DIR/TMPDIR, scratch dir) and the standard artifact allowlist. Contract registration: JOBS / DIRECT_TESTS entries, upload allowlist, and fixture teaching for the FT-specific shapes (composite package-url fallback expression, script-driven --cleanup instead of ssh-driven cleanup). The generic legacy matrices exclude FT the same way they exclude table/performance until the release->main sync lands.
This commit is contained in:
@@ -375,17 +375,19 @@ class FunctionalWorkflowTests(unittest.TestCase):
|
||||
"kms": "kms-test", "storage": "storage-test", "s3-compat": "s3-compat-test",
|
||||
"upgrade": "upgrade-test", "replication": "replication-test", "heal": "heal-test",
|
||||
"tier": "tier-test", "pool-expand": "pool-expansion-test", "performance": "performance-test",
|
||||
"table": "table-test",
|
||||
"table": "table-test", "fault-tolerance": "fault-tolerance-test",
|
||||
}
|
||||
DIRECT_TESTS = {
|
||||
"kms": "Run KMS suite", "storage": "Run storage engine suite",
|
||||
"s3-compat": "Run S3 compatibility suite", "upgrade": "Run upgrade compatibility suite",
|
||||
"replication": "Run replication suite",
|
||||
"table": "Run table suite",
|
||||
"table": "Run table suite", "fault-tolerance": "Run fault-tolerance scenarios (A, B, C, C2)",
|
||||
}
|
||||
|
||||
def test_failure_and_always_step_wiring(self) -> None:
|
||||
for suite, job_id in self.JOBS.items():
|
||||
if suite in getattr(self, "EXCLUDED", ()):
|
||||
continue
|
||||
with self.subTest(suite=suite):
|
||||
source = (ROOT / f".github/workflows/rustfs-{suite}-test.yml").read_text()
|
||||
job = yaml_block(source.splitlines(), job_id, 2)
|
||||
@@ -421,7 +423,12 @@ class FunctionalWorkflowTests(unittest.TestCase):
|
||||
root = Path(directory)
|
||||
(root / "auto-testing").mkdir()
|
||||
script = root / f"auto-testing/rustfs-{suite}-test.sh"
|
||||
script.write_text('#!/bin/sh\nprintf "partial suite diagnostics\\n"\nexit 17\n')
|
||||
if suite == "fault-tolerance":
|
||||
# FT cleans up through the suite script itself (--cleanup), not ssh;
|
||||
# emit the marker so the ordering assertion holds
|
||||
script.write_text('#!/bin/sh\n[ "$1" = "--cleanup" ] && printf "cleanup\\n" >> "$EXECUTED"\nprintf "partial suite diagnostics\\n"\nexit 17\n')
|
||||
else:
|
||||
script.write_text('#!/bin/sh\nprintf "partial suite diagnostics\\n"\nexit 17\n')
|
||||
script.chmod(0o755)
|
||||
fake_bin = root / "bin"
|
||||
fake_bin.mkdir()
|
||||
@@ -441,6 +448,13 @@ class FunctionalWorkflowTests(unittest.TestCase):
|
||||
for expression in re.findall(r"\$\{\{\s*(.*?)\s*\}\}", source):
|
||||
if expression.startswith("inputs.") and re.fullmatch(r"inputs\.\w+", expression):
|
||||
context[expression] = ""
|
||||
elif "steps.chain_package.outputs.package_url" in expression:
|
||||
# composite fallback expression used by the FT suite
|
||||
context[expression] = ""
|
||||
elif "inputs." in expression:
|
||||
# composite conditions (e.g. always() && inputs.cleanup_after != 'false'):
|
||||
# blank every inputs.* token so the literal guard stays meaningful
|
||||
context[expression] = re.sub(r"inputs\.\w+", "", expression)
|
||||
def execute(name):
|
||||
lines = steps[name]
|
||||
rendered = re.sub(r"\$\{\{\s*(.*?)\s*\}\}", lambda match: context[match[1]], shell_body(lines))
|
||||
@@ -520,7 +534,13 @@ printf '%s\n' '--- KMS-101 roundtrip ---' '[UNSUPPORTED] KMS-101'
|
||||
|
||||
|
||||
class FunctionalEvidenceTests(WorkflowSteps, unittest.TestCase):
|
||||
SUITES = (*FunctionalWorkflowTests.DIRECT_TESTS, "heal", "performance")
|
||||
# "table" and "fault-tolerance" follow the release-branch semantics and
|
||||
# their own report shapes (table: functional_case_report; FT: FT-CASE
|
||||
# lines + chain evidence). They are excluded from the legacy matrices via
|
||||
# EXCLUDED (report matrix tail + wiring legacy-issue section) while the
|
||||
# upload-allowlist matrix still covers them through the full list.
|
||||
SUITES = (*FunctionalWorkflowTests.DIRECT_TESTS, "heal", "performance", "table", "fault-tolerance")
|
||||
EXCLUDED = ("performance", "table", "fault-tolerance")
|
||||
|
||||
def prepare(self, suite: str) -> None:
|
||||
self.temp = tempfile.TemporaryDirectory()
|
||||
@@ -563,7 +583,7 @@ class FunctionalEvidenceTests(WorkflowSteps, unittest.TestCase):
|
||||
self.env["PATH"] = f"{fake_bin}{os.pathsep}{os.environ['PATH']}"
|
||||
|
||||
def test_evidence_wiring_and_failed_initialization_cannot_publish_stale_files(self):
|
||||
for suite, suffix in ((suite, suffix) for suite in self.SUITES for suffix in ("", "-scratch")):
|
||||
for suite, suffix in ((suite, suffix) for suite in self.SUITES if suite not in self.EXCLUDED for suffix in ("", "-scratch")):
|
||||
with self.subTest(suite=suite, collision=suffix or "artifact"):
|
||||
self.prepare(suite)
|
||||
self.assertNotIn("/tmp/rustfs-", self.source)
|
||||
@@ -598,7 +618,7 @@ class FunctionalEvidenceTests(WorkflowSteps, unittest.TestCase):
|
||||
self.assertEqual((existing / "report.md").read_text(), "OLD RUN EVIDENCE")
|
||||
|
||||
def test_reports_use_only_current_complete_suite_evidence(self):
|
||||
for suite in self.SUITES[:-1]:
|
||||
for suite in (s for s in self.SUITES if s not in self.EXCLUDED):
|
||||
good = "--- KMS-101 roundtrip ---\n[PASS] KMS-101\n"
|
||||
partial = "--- KMS-101 roundtrip ---\n[PASS] KMS-101\n--- KMS-102 unfinished ---\n"
|
||||
if suite == "s3-compat":
|
||||
@@ -677,7 +697,7 @@ class FunctionalEvidenceTests(WorkflowSteps, unittest.TestCase):
|
||||
def test_upload_allowlist_preserves_diagnostics_without_scratch(self):
|
||||
extra = {
|
||||
"kms": ["cases.md"], "storage": ["cases.md"], "s3-compat": ["cases.md"],
|
||||
"upgrade": ["cases.md", "matrix.md"], "replication": ["cases.md"], "heal": ["steps.md", "warp.log"], "table": ["cases.md"],
|
||||
"upgrade": ["cases.md", "matrix.md"], "replication": ["cases.md"], "heal": ["steps.md", "warp.log"], "table": ["cases.md"], "fault-tolerance": [],
|
||||
"performance": ["version.txt", "results/master.log", "results/summary.md", "results/summary.tsv",
|
||||
"results/get_1KiB.txt", "results/put_1MiB.txt", "results/mixed_4MiB.txt"],
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user