Skip to content

Commit a3ab6e8

Browse files
committed
more robust deployment verification
1 parent c1dcab3 commit a3ab6e8

1 file changed

Lines changed: 78 additions & 32 deletions

File tree

workspaces/orchestrator/e2e-tests/tests/specs/test-helpers.ts

Lines changed: 78 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ const MANIFEST_DIRS = [
4545

4646
const WORKFLOWS = ["greeting", "failswitch"];
4747

48+
/** Default SonataFlow operator Postgres secret; e2e uses `backstage-psql-secret` instead. */
49+
const UPSTREAM_WORKFLOW_PG_SECRET = "sonataflow-psql-postgresql";
50+
const E2E_WORKFLOW_PG_SECRET = "backstage-psql-secret";
51+
4852
// ---------------------------------------------------------------------------
4953
// RBAC helpers
5054
// ---------------------------------------------------------------------------
@@ -399,8 +403,18 @@ export async function deploySonataflow(namespace: string): Promise<void> {
399403
patchWorkflowPostgres(namespace, workflow);
400404
}
401405

406+
const postgresAlignTimeoutMs = 120_000;
402407
for (const workflow of WORKFLOWS) {
403-
await waitForReconciliation(namespace, workflow, 60);
408+
await waitForWorkflowPostgresDeploymentAligned(
409+
namespace,
410+
workflow,
411+
postgresAlignTimeoutMs,
412+
);
413+
runOc(
414+
["rollout", "restart", `deployment/${workflow}`, "-n", namespace],
415+
60_000,
416+
);
417+
await sleep(2_000);
404418
runOc(
405419
[
406420
"rollout",
@@ -447,57 +461,89 @@ function patchWorkflowPostgres(namespace: string, workflow: string): string {
447461
]);
448462
}
449463

450-
async function waitForCRs(namespace: string): Promise<void> {
451-
const deadline = Date.now() + 60_000;
464+
function parseOcJson<T = unknown>(
465+
args: string[],
466+
timeoutMs: number,
467+
): T | undefined {
468+
try {
469+
return JSON.parse(runOc(args, timeoutMs)) as T;
470+
} catch {
471+
return undefined;
472+
}
473+
}
474+
475+
function sonataFlowUsesE2ePostgresSecret(cr: Record<string, unknown>): boolean {
476+
const spec = cr.spec as Record<string, unknown> | undefined;
477+
const persistence = spec?.persistence as Record<string, unknown> | undefined;
478+
const pg = persistence?.postgresql as Record<string, unknown> | undefined;
479+
const secretRef = pg?.secretRef as Record<string, unknown> | undefined;
480+
return secretRef?.name === E2E_WORKFLOW_PG_SECRET;
481+
}
482+
483+
/** True if the live Deployment pod template still references the operator default secret. */
484+
function deploymentPodTemplateReferencesUpstreamPgSecret(
485+
deployment: Record<string, unknown>,
486+
): boolean {
487+
const spec = deployment.spec as Record<string, unknown> | undefined;
488+
const template = spec?.template as Record<string, unknown> | undefined;
489+
if (!template) return false;
490+
return JSON.stringify(template).includes(UPSTREAM_WORKFLOW_PG_SECRET);
491+
}
492+
493+
/**
494+
* Wait until the SonataFlow CR and workflow Deployment both reflect the e2e Postgres
495+
* wiring, re-applying the merge patch when the operator lags. Does not restart the rollout.
496+
*/
497+
async function waitForWorkflowPostgresDeploymentAligned(
498+
namespace: string,
499+
workflow: string,
500+
timeoutMs: number,
501+
): Promise<void> {
502+
const deadline = Date.now() + timeoutMs;
452503
let attempt = 0;
453504
while (Date.now() < deadline) {
454505
attempt++;
455-
try {
456-
const out = runOc(["get", "sonataflow", "-n", namespace, "--no-headers"]);
457-
const found = out.split("\n").filter(Boolean).length;
458-
if (found >= WORKFLOWS.length) {
459-
return;
460-
}
461-
} catch {
462-
// not available yet
506+
const cr = parseOcJson<Record<string, unknown>>(
507+
["get", "sonataflow", workflow, "-n", namespace, "-o", "json"],
508+
15_000,
509+
);
510+
const deployment = parseOcJson<Record<string, unknown>>(
511+
["get", "deployment", workflow, "-n", namespace, "-o", "json"],
512+
15_000,
513+
);
514+
const crOk = cr && sonataFlowUsesE2ePostgresSecret(cr);
515+
const depOk =
516+
deployment &&
517+
!deploymentPodTemplateReferencesUpstreamPgSecret(deployment);
518+
if (crOk && depOk) {
519+
return;
463520
}
464-
await sleep(5_000);
521+
patchWorkflowPostgres(namespace, workflow);
522+
await sleep(2_000);
465523
}
466524
console.warn(
467-
`[deploy-sonataflow] TIMEOUT: Only found fewer than ${WORKFLOWS.length} SonataFlow CRs after ${attempt} attempts`,
525+
`[deploy-sonataflow] TIMEOUT (${timeoutMs}ms): workflow "${workflow}" not aligned on ${E2E_WORKFLOW_PG_SECRET} (SonataFlow CR + Deployment template; attempts=${attempt})`,
468526
);
469527
}
470528

471-
async function waitForReconciliation(
472-
namespace: string,
473-
workflow: string,
474-
timeoutSecs: number,
475-
): Promise<void> {
476-
const deadline = Date.now() + timeoutSecs * 1_000;
529+
async function waitForCRs(namespace: string): Promise<void> {
530+
const deadline = Date.now() + 60_000;
477531
let attempt = 0;
478532
while (Date.now() < deadline) {
479533
attempt++;
480534
try {
481-
const status = runOc([
482-
"get",
483-
"deployment",
484-
workflow,
485-
"-n",
486-
namespace,
487-
"-o",
488-
'jsonpath={.status.conditions[?(@.type=="Progressing")].status}',
489-
]);
490-
const cleaned = status.replaceAll("'", "");
491-
if (cleaned === "True") {
535+
const out = runOc(["get", "sonataflow", "-n", namespace, "--no-headers"]);
536+
const found = out.split("\n").filter(Boolean).length;
537+
if (found >= WORKFLOWS.length) {
492538
return;
493539
}
494540
} catch {
495541
// not available yet
496542
}
497-
await sleep(2_000);
543+
await sleep(5_000);
498544
}
499545
console.warn(
500-
`[deploy-sonataflow] TIMEOUT waiting for reconciliation of ${workflow} after ${timeoutSecs}s (${attempt} attempts)`,
546+
`[deploy-sonataflow] TIMEOUT: Only found fewer than ${WORKFLOWS.length} SonataFlow CRs after ${attempt} attempts`,
501547
);
502548
}
503549

0 commit comments

Comments
 (0)