/** * Smoke: the shortest path that proves the harness can reach every plane it * needs, and that the deployment is fundamentally alive. * * If this fails, nothing else in the suite is worth reading. It covers: * - the cluster plane (kubectl can list the StatefulSet pods) * - public DNS + TLS (the hostname resolves and the ingress serves health) * - the credential path (the sourced bearer is accepted) * - the write path (a quorum-acked write really commits) */ import { resolve4 } from 'node:dns/promises'; import { expect, test } from '@playwright/test'; import { kubectl } from './support/cluster'; import { observed, recordJson } from './support/evidence'; import { EXPECTED_NODE_IPS, NAMESPACE, POD_NAMES, PUBLIC_BASE_URL, PUBLIC_HOST, apiKey, } from './support/env'; test.describe('smoke', () => { test('all three cluster pods are Ready', async ({}, testInfo) => { const result = await observed(testInfo, 'get pods', () => kubectl([ '-n', NAMESPACE, 'get', 'pods', '-l', 'app.kubernetes.io/name=tidaldb', '-o', 'jsonpath={range .items[*]}{.metadata.name}{" "}{.status.containerStatuses[0].ready}{"\\n"}{end}', ]), ); expect(result.code, `kubectl failed: ${result.stderr}`).toBe(0); const readyByPod: Record = {}; for (const line of result.stdout.trim().split('\n')) { if (line.trim() === '') continue; const [name, ready] = line.trim().split(/\s+/); readyByPod[name] = ready === 'true'; } await recordJson(testInfo, 'pod-readiness', readyByPod); for (const pod of POD_NAMES) { expect(readyByPod[pod], `${pod} should be Ready`).toBe(true); } expect( Object.keys(readyByPod).sort(), 'expected exactly the known pod set', ).toEqual([...POD_NAMES].sort()); }); test('public hostname resolves to every node and serves health over valid TLS', async ({ playwright, }, testInfo) => { // Real public resolution is part of the claim, so resolve it for real // rather than pinning an IP. A pinned IP would still pass if DNS were // broken — which is precisely the failure that retired the old hostname. const addresses = await resolve4(PUBLIC_HOST); await recordJson(testInfo, 'dns-resolution', { host: PUBLIC_HOST, addresses }); expect( [...addresses].sort(), 'every node IP should answer for the public hostname', ).toEqual([...EXPECTED_NODE_IPS].sort()); // ignoreHTTPSErrors stays false: an invalid or expired certificate must // fail this test, not be tolerated. const context = await playwright.request.newContext({ ignoreHTTPSErrors: false }); try { const response = await context.get(`${PUBLIC_BASE_URL}/health`); await recordJson(testInfo, 'health-response', { status: response.status(), body: (await response.text()).slice(0, 500), }); expect(response.status(), 'health must be publicly reachable').toBe(200); } finally { await context.dispose(); } }); test('sourced bearer is accepted and a quorum write commits', async ({ playwright, }, testInfo) => { const context = await playwright.request.newContext({ baseURL: PUBLIC_BASE_URL, extraHTTPHeaders: { authorization: `Bearer ${apiKey()}` }, }); try { const read = await context.get('/search', { params: { query: 'smoke', limit: 1 } }); expect(read.status(), 'authenticated read must succeed').toBe(200); const write = await context.post('/items', { headers: { 'content-type': 'application/json', 'x-tidal-ack': 'quorum' }, data: { entity_id: 999_000_001, metadata: { title: 'harness smoke', category: 'verification' }, }, }); await recordJson(testInfo, 'quorum-write', { status: write.status(), body: (await write.text()).slice(0, 500), }); // 201 means the write was acknowledged by a quorum, not merely accepted // by one node. This is the single strongest signal in the suite. expect(write.status(), 'quorum-acked write must commit').toBe(201); } finally { await context.dispose(); } }); });