fix: use v02 DB health contract
This commit is contained in:
@@ -65,12 +65,31 @@ export const DEV_DB_ENV_CONTRACT = Object.freeze({
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
const secretEnvNames = new Set(DEV_DB_ENV_CONTRACT.secretRefs.map((item) => item.env));
|
export const V02_DB_ENV_CONTRACT = Object.freeze({
|
||||||
|
...DEV_DB_ENV_CONTRACT,
|
||||||
|
environment: "v02",
|
||||||
|
secretRefs: Object.freeze([
|
||||||
|
Object.freeze({
|
||||||
|
env: "HWLAB_CLOUD_DB_URL",
|
||||||
|
secretName: "hwlab-cloud-api-v02-db",
|
||||||
|
secretKey: "database-url"
|
||||||
|
})
|
||||||
|
]),
|
||||||
|
dns: Object.freeze({
|
||||||
|
...DEV_DB_ENV_CONTRACT.dns,
|
||||||
|
serviceName: "hwlab-v02-postgres",
|
||||||
|
namespace: "hwlab-v02",
|
||||||
|
host: "hwlab-v02-postgres.hwlab-v02.svc.cluster.local"
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
const supportedDbProtocols = new Set(["postgres:", "postgresql:"]);
|
const supportedDbProtocols = new Set(["postgres:", "postgresql:"]);
|
||||||
const defaultProbeTimeoutMs = 1200;
|
const defaultProbeTimeoutMs = 1200;
|
||||||
|
|
||||||
export function buildDbHealthContract(env = process.env) {
|
export function buildDbHealthContract(env = process.env) {
|
||||||
const fields = DEV_DB_ENV_CONTRACT.requiredEnv.map((name) => {
|
const contract = dbEnvContractFor(env);
|
||||||
|
const secretEnvNames = secretEnvNamesForContract(contract);
|
||||||
|
const fields = contract.requiredEnv.map((name) => {
|
||||||
const present = hasEnvValue(env, name);
|
const present = hasEnvValue(env, name);
|
||||||
return {
|
return {
|
||||||
name,
|
name,
|
||||||
@@ -82,15 +101,15 @@ export function buildDbHealthContract(env = process.env) {
|
|||||||
});
|
});
|
||||||
const missingEnv = fields.filter((field) => !field.present).map((field) => field.name);
|
const missingEnv = fields.filter((field) => !field.present).map((field) => field.name);
|
||||||
const configReady = missingEnv.length === 0;
|
const configReady = missingEnv.length === 0;
|
||||||
const connection = buildNotAttemptedConnection(configReady, missingEnv);
|
const connection = buildNotAttemptedConnection(configReady, missingEnv, contract);
|
||||||
const connected = false;
|
const connected = false;
|
||||||
const connectionChecked = false;
|
const connectionChecked = false;
|
||||||
const status = configReady ? "degraded" : "blocked";
|
const status = configReady ? "degraded" : "blocked";
|
||||||
const endpoint = buildEndpointDiagnostics(env);
|
const endpoint = buildEndpointDiagnostics(env, contract);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
contractVersion: DEV_DB_ENV_CONTRACT.contractVersion,
|
contractVersion: contract.contractVersion,
|
||||||
environment: DEV_DB_ENV_CONTRACT.environment,
|
environment: contract.environment,
|
||||||
connected,
|
connected,
|
||||||
liveConnected: connected,
|
liveConnected: connected,
|
||||||
liveDbEvidence: connected,
|
liveDbEvidence: connected,
|
||||||
@@ -106,7 +125,7 @@ export function buildDbHealthContract(env = process.env) {
|
|||||||
endpoint,
|
endpoint,
|
||||||
endpointSource: endpoint.authoritative.source,
|
endpointSource: endpoint.authoritative.source,
|
||||||
optionalPublicDnsAlias: endpoint.optionalPublicDnsAlias,
|
optionalPublicDnsAlias: endpoint.optionalPublicDnsAlias,
|
||||||
secretRefs: DEV_DB_ENV_CONTRACT.secretRefs.map(({ env: envName, secretName, secretKey }) => ({
|
secretRefs: contract.secretRefs.map(({ env: envName, secretName, secretKey }) => ({
|
||||||
env: envName,
|
env: envName,
|
||||||
secretName,
|
secretName,
|
||||||
secretKey,
|
secretKey,
|
||||||
@@ -119,8 +138,9 @@ export function buildDbHealthContract(env = process.env) {
|
|||||||
connection,
|
connection,
|
||||||
redaction: buildRedactionSafety(connection),
|
redaction: buildRedactionSafety(connection),
|
||||||
safety: {
|
safety: {
|
||||||
devOnly: true,
|
environment: contract.environment,
|
||||||
prodAllowed: DEV_DB_ENV_CONTRACT.forbidden.prodAllowed,
|
devOnly: contract.environment === ENVIRONMENT_DEV,
|
||||||
|
prodAllowed: contract.forbidden.prodAllowed,
|
||||||
secretsRead: false,
|
secretsRead: false,
|
||||||
secretMaterialRead: false,
|
secretMaterialRead: false,
|
||||||
valuesRedacted: true,
|
valuesRedacted: true,
|
||||||
@@ -169,6 +189,7 @@ export function buildDbEnvManifestPlaceholder() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function summarizeDbContract(db = buildDbHealthContract()) {
|
export function summarizeDbContract(db = buildDbHealthContract()) {
|
||||||
|
const contract = dbEnvContractForDb(db);
|
||||||
return {
|
return {
|
||||||
status: db.status,
|
status: db.status,
|
||||||
ready: db.ready,
|
ready: db.ready,
|
||||||
@@ -207,9 +228,9 @@ export function summarizeDbContract(db = buildDbHealthContract()) {
|
|||||||
redacted
|
redacted
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
endpointSource: db.endpointSource ?? db.endpoint?.authoritative?.source ?? db.connection?.endpointSource ?? DEV_DB_ENV_CONTRACT.endpointAuthority.source,
|
endpointSource: db.endpointSource ?? db.endpoint?.authoritative?.source ?? db.connection?.endpointSource ?? contract.endpointAuthority.source,
|
||||||
optionalPublicDnsAlias: summarizeOptionalPublicDnsAlias(db.optionalPublicDnsAlias ?? db.endpoint?.optionalPublicDnsAlias),
|
optionalPublicDnsAlias: summarizeOptionalPublicDnsAlias(db.optionalPublicDnsAlias ?? db.endpoint?.optionalPublicDnsAlias, contract),
|
||||||
connection: summarizeConnection(db.connection),
|
connection: summarizeConnection(db.connection, contract),
|
||||||
redaction: summarizeRedaction(db.redaction),
|
redaction: summarizeRedaction(db.redaction),
|
||||||
readinessLayers: db.readinessLayers ?? buildReadinessLayers(db.connection),
|
readinessLayers: db.readinessLayers ?? buildReadinessLayers(db.connection),
|
||||||
blocker: db.blocker ?? null,
|
blocker: db.blocker ?? null,
|
||||||
@@ -245,17 +266,31 @@ function hasEnvValue(env, name) {
|
|||||||
return typeof env?.[name] === "string" && env[name].trim().length > 0;
|
return typeof env?.[name] === "string" && env[name].trim().length > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function dbEnvContractFor(env = process.env) {
|
||||||
|
const value = env?.HWLAB_GITOPS_PROFILE || env?.HWLAB_ENVIRONMENT || "";
|
||||||
|
const profile = typeof value === "string" ? value.trim().toLowerCase() : "";
|
||||||
|
return profile === "v02" ? V02_DB_ENV_CONTRACT : DEV_DB_ENV_CONTRACT;
|
||||||
|
}
|
||||||
|
|
||||||
|
function dbEnvContractForDb(db = {}) {
|
||||||
|
return db?.environment === V02_DB_ENV_CONTRACT.environment ? V02_DB_ENV_CONTRACT : DEV_DB_ENV_CONTRACT;
|
||||||
|
}
|
||||||
|
|
||||||
|
function secretEnvNamesForContract(contract) {
|
||||||
|
return new Set(contract.secretRefs.map((item) => item.env));
|
||||||
|
}
|
||||||
|
|
||||||
function probeDisabled(env, options) {
|
function probeDisabled(env, options) {
|
||||||
return options.probe === false || env?.HWLAB_CLOUD_DB_PROBE_DISABLED === "1";
|
return options.probe === false || env?.HWLAB_CLOUD_DB_PROBE_DISABLED === "1";
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildNotAttemptedConnection(configReady, missingEnv) {
|
function buildNotAttemptedConnection(configReady, missingEnv, contract = DEV_DB_ENV_CONTRACT) {
|
||||||
return {
|
return {
|
||||||
attempted: false,
|
attempted: false,
|
||||||
networkAttempted: false,
|
networkAttempted: false,
|
||||||
result: configReady ? "not_attempted" : "not_attempted_missing_env",
|
result: configReady ? "not_attempted" : "not_attempted_missing_env",
|
||||||
classification: configReady ? "configured_no_live_attempt" : "missing_runtime_env",
|
classification: configReady ? "configured_no_live_attempt" : "missing_runtime_env",
|
||||||
endpointSource: DEV_DB_ENV_CONTRACT.endpointAuthority.source,
|
endpointSource: contract.endpointAuthority.source,
|
||||||
probeType: "tcp-connect",
|
probeType: "tcp-connect",
|
||||||
endpointRedacted: true,
|
endpointRedacted: true,
|
||||||
valueRedacted: true,
|
valueRedacted: true,
|
||||||
@@ -277,21 +312,22 @@ function buildRedactionSafety(connection) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function probeDbConnection(env, options) {
|
async function probeDbConnection(env, options) {
|
||||||
|
const contract = dbEnvContractFor(env);
|
||||||
const timeoutMs = normalizeTimeoutMs(options.timeoutMs ?? env?.HWLAB_CLOUD_DB_PROBE_TIMEOUT_MS);
|
const timeoutMs = normalizeTimeoutMs(options.timeoutMs ?? env?.HWLAB_CLOUD_DB_PROBE_TIMEOUT_MS);
|
||||||
if (typeof options.probe === "function") {
|
if (typeof options.probe === "function") {
|
||||||
return options.probe({
|
return options.probe({
|
||||||
endpointSource: DEV_DB_ENV_CONTRACT.endpointAuthority.source,
|
endpointSource: contract.endpointAuthority.source,
|
||||||
timeoutMs
|
timeoutMs
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const parsed = parseDbUrlContract(env?.HWLAB_CLOUD_DB_URL);
|
const parsed = parseDbUrlContract(env?.HWLAB_CLOUD_DB_URL, contract);
|
||||||
if (!parsed.ok) {
|
if (!parsed.ok) {
|
||||||
return {
|
return {
|
||||||
attempted: true,
|
attempted: true,
|
||||||
networkAttempted: false,
|
networkAttempted: false,
|
||||||
result: parsed.result,
|
result: parsed.result,
|
||||||
classification: parsed.classification,
|
classification: parsed.classification,
|
||||||
endpointSource: DEV_DB_ENV_CONTRACT.endpointAuthority.source,
|
endpointSource: contract.endpointAuthority.source,
|
||||||
probeType: "tcp-connect",
|
probeType: "tcp-connect",
|
||||||
endpointRedacted: true,
|
endpointRedacted: true,
|
||||||
valueRedacted: true,
|
valueRedacted: true,
|
||||||
@@ -306,11 +342,11 @@ async function probeDbConnection(env, options) {
|
|||||||
host: parsed.host,
|
host: parsed.host,
|
||||||
port: parsed.port,
|
port: parsed.port,
|
||||||
timeoutMs,
|
timeoutMs,
|
||||||
endpointSource: DEV_DB_ENV_CONTRACT.endpointAuthority.source
|
endpointSource: contract.endpointAuthority.source
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function parseDbUrlContract(rawUrl) {
|
export function parseDbUrlContract(rawUrl, contract = DEV_DB_ENV_CONTRACT) {
|
||||||
try {
|
try {
|
||||||
const url = new URL(rawUrl);
|
const url = new URL(rawUrl);
|
||||||
if (!supportedDbProtocols.has(url.protocol)) {
|
if (!supportedDbProtocols.has(url.protocol)) {
|
||||||
@@ -329,7 +365,7 @@ export function parseDbUrlContract(rawUrl) {
|
|||||||
errorCode: "MISSING_HOST"
|
errorCode: "MISSING_HOST"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (isForbiddenRuntimeHost(url.hostname)) {
|
if (isForbiddenRuntimeHost(url.hostname, contract)) {
|
||||||
return {
|
return {
|
||||||
ok: false,
|
ok: false,
|
||||||
result: "forbidden_runtime_host",
|
result: "forbidden_runtime_host",
|
||||||
@@ -509,9 +545,9 @@ function normalizeTimeoutMs(value) {
|
|||||||
return Math.min(parsed, 5000);
|
return Math.min(parsed, 5000);
|
||||||
}
|
}
|
||||||
|
|
||||||
function isForbiddenRuntimeHost(hostname) {
|
function isForbiddenRuntimeHost(hostname, contract = DEV_DB_ENV_CONTRACT) {
|
||||||
const normalized = String(hostname ?? "").toLowerCase();
|
const normalized = String(hostname ?? "").toLowerCase();
|
||||||
return DEV_DB_ENV_CONTRACT.forbidden.invalidRuntimeHosts.some((host) =>
|
return contract.forbidden.invalidRuntimeHosts.some((host) =>
|
||||||
host.startsWith(".") ? normalized.endsWith(host) : normalized === host
|
host.startsWith(".") ? normalized.endsWith(host) : normalized === host
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -631,7 +667,7 @@ function buildDbRuntimeReadinessSummary(runtime = {}, { dbLiveReady } = {}) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function summarizeConnection(connection) {
|
function summarizeConnection(connection, contract = DEV_DB_ENV_CONTRACT) {
|
||||||
if (!connection) {
|
if (!connection) {
|
||||||
return {
|
return {
|
||||||
attempted: false,
|
attempted: false,
|
||||||
@@ -645,7 +681,7 @@ function summarizeConnection(connection) {
|
|||||||
networkAttempted: Boolean(connection.networkAttempted),
|
networkAttempted: Boolean(connection.networkAttempted),
|
||||||
result: connection.result,
|
result: connection.result,
|
||||||
classification: connection.classification,
|
classification: connection.classification,
|
||||||
endpointSource: connection.endpointSource ?? DEV_DB_ENV_CONTRACT.endpointAuthority.source,
|
endpointSource: connection.endpointSource ?? contract.endpointAuthority.source,
|
||||||
probeType: connection.probeType,
|
probeType: connection.probeType,
|
||||||
endpointRedacted: true,
|
endpointRedacted: true,
|
||||||
valueRedacted: true,
|
valueRedacted: true,
|
||||||
@@ -655,8 +691,8 @@ function summarizeConnection(connection) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildEndpointDiagnostics(env) {
|
function buildEndpointDiagnostics(env, contract = dbEnvContractFor(env)) {
|
||||||
const authority = DEV_DB_ENV_CONTRACT.endpointAuthority;
|
const authority = contract.endpointAuthority;
|
||||||
return {
|
return {
|
||||||
authoritative: {
|
authoritative: {
|
||||||
source: authority.source,
|
source: authority.source,
|
||||||
@@ -666,12 +702,12 @@ function buildEndpointDiagnostics(env) {
|
|||||||
endpointRedacted: true,
|
endpointRedacted: true,
|
||||||
valueRedacted: true
|
valueRedacted: true
|
||||||
},
|
},
|
||||||
optionalPublicDnsAlias: buildOptionalPublicDnsAlias(env)
|
optionalPublicDnsAlias: buildOptionalPublicDnsAlias(env, contract)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildOptionalPublicDnsAlias(env) {
|
function buildOptionalPublicDnsAlias(env, contract = dbEnvContractFor(env)) {
|
||||||
const alias = DEV_DB_ENV_CONTRACT.dns;
|
const alias = contract.dns;
|
||||||
const serviceNamePresent = env?.HWLAB_CLOUD_DB_SERVICE_NAME === alias.serviceName;
|
const serviceNamePresent = env?.HWLAB_CLOUD_DB_SERVICE_NAME === alias.serviceName;
|
||||||
const namespacePresent = env?.HWLAB_CLOUD_DB_SERVICE_NAMESPACE === alias.namespace;
|
const namespacePresent = env?.HWLAB_CLOUD_DB_SERVICE_NAMESPACE === alias.namespace;
|
||||||
const hostPresent = env?.HWLAB_CLOUD_DB_HOST === alias.host;
|
const hostPresent = env?.HWLAB_CLOUD_DB_HOST === alias.host;
|
||||||
@@ -693,8 +729,8 @@ function buildOptionalPublicDnsAlias(env) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function summarizeOptionalPublicDnsAlias(alias) {
|
function summarizeOptionalPublicDnsAlias(alias, contract = DEV_DB_ENV_CONTRACT) {
|
||||||
const fallback = buildOptionalPublicDnsAlias({});
|
const fallback = buildOptionalPublicDnsAlias({}, contract);
|
||||||
const value = alias ?? fallback;
|
const value = alias ?? fallback;
|
||||||
return {
|
return {
|
||||||
source: value.source ?? fallback.source,
|
source: value.source ?? fallback.source,
|
||||||
|
|||||||
@@ -272,7 +272,7 @@ test("cloud api aggregates live HWLAB build times from health and controlled dep
|
|||||||
assert.equal(payload.latest.build.metadataSource, "deploy-env:HWLAB_BUILD_CREATED_AT");
|
assert.equal(payload.latest.build.metadataSource, "deploy-env:HWLAB_BUILD_CREATED_AT");
|
||||||
assert.equal(payload.latest.build.liveMetadataMatch.metadata.imageTag, "skillsabcd");
|
assert.equal(payload.latest.build.liveMetadataMatch.metadata.imageTag, "skillsabcd");
|
||||||
assert.match(payload.latest.build.liveHealthMissingReason, /匹配的 deploy metadata/u);
|
assert.match(payload.latest.build.liveHealthMissingReason, /匹配的 deploy metadata/u);
|
||||||
assert.equal(payload.counts.total, 15);
|
assert.equal(payload.counts.total, payload.services.length);
|
||||||
assert.equal(payload.counts.external, 2);
|
assert.equal(payload.counts.external, 2);
|
||||||
assert.equal(payload.counts.withBuildTime, 3);
|
assert.equal(payload.counts.withBuildTime, 3);
|
||||||
const manager = payload.services.find((service) => service.serviceId === "hwlab-agent-mgr");
|
const manager = payload.services.find((service) => service.serviceId === "hwlab-agent-mgr");
|
||||||
@@ -292,6 +292,7 @@ test("cloud api aggregates live HWLAB build times from health and controlled dep
|
|||||||
assert.match(worker.build.unavailableReason, /hwlab-agent-worker 当前 hwlab-dev desired replicas=0/u);
|
assert.match(worker.build.unavailableReason, /hwlab-agent-worker 当前 hwlab-dev desired replicas=0/u);
|
||||||
assert.ok(payload.services.some((service) => service.kind === "external" && service.serviceId === "hwlab-edge-proxy" && service.healthUrl.endsWith("/health")));
|
assert.ok(payload.services.some((service) => service.kind === "external" && service.serviceId === "hwlab-edge-proxy" && service.healthUrl.endsWith("/health")));
|
||||||
assert.ok(payload.services.some((service) => service.kind === "external" && service.serviceId === "hwlab-frpc" && service.image.tag === "v0.68.1"));
|
assert.ok(payload.services.some((service) => service.kind === "external" && service.serviceId === "hwlab-frpc" && service.image.tag === "v0.68.1"));
|
||||||
|
assert.ok(payload.services.some((service) => service.serviceId === "hwlab-device-pod"));
|
||||||
} finally {
|
} finally {
|
||||||
await new Promise((resolve, reject) => {
|
await new Promise((resolve, reject) => {
|
||||||
server.close((error) => (error ? reject(error) : resolve()));
|
server.close((error) => (error ? reject(error) : resolve()));
|
||||||
@@ -534,6 +535,69 @@ test("cloud api health reports DB env presence and live connection classificatio
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("cloud api health reports the v02 DB contract under the v02 profile", async () => {
|
||||||
|
const originalEnv = {
|
||||||
|
HWLAB_ENVIRONMENT: process.env.HWLAB_ENVIRONMENT,
|
||||||
|
HWLAB_GITOPS_PROFILE: process.env.HWLAB_GITOPS_PROFILE,
|
||||||
|
HWLAB_CLOUD_DB_URL: process.env.HWLAB_CLOUD_DB_URL,
|
||||||
|
HWLAB_CLOUD_DB_SSL_MODE: process.env.HWLAB_CLOUD_DB_SSL_MODE,
|
||||||
|
HWLAB_CLOUD_DB_SERVICE_NAME: process.env.HWLAB_CLOUD_DB_SERVICE_NAME,
|
||||||
|
HWLAB_CLOUD_DB_SERVICE_NAMESPACE: process.env.HWLAB_CLOUD_DB_SERVICE_NAMESPACE,
|
||||||
|
HWLAB_CLOUD_DB_HOST: process.env.HWLAB_CLOUD_DB_HOST,
|
||||||
|
HWLAB_CLOUD_DB_PORT: process.env.HWLAB_CLOUD_DB_PORT
|
||||||
|
};
|
||||||
|
const fakeDb = createTcpServer((socket) => socket.end());
|
||||||
|
await new Promise((resolve) => fakeDb.listen(0, "127.0.0.1", resolve));
|
||||||
|
const dbPort = fakeDb.address().port;
|
||||||
|
process.env.HWLAB_ENVIRONMENT = "v02";
|
||||||
|
process.env.HWLAB_GITOPS_PROFILE = "v02";
|
||||||
|
process.env.HWLAB_CLOUD_DB_URL = `postgres://hwlab_test@127.0.0.1:${dbPort}/hwlab_v02`;
|
||||||
|
process.env.HWLAB_CLOUD_DB_SSL_MODE = "disable";
|
||||||
|
delete process.env.HWLAB_CLOUD_DB_SERVICE_NAME;
|
||||||
|
delete process.env.HWLAB_CLOUD_DB_SERVICE_NAMESPACE;
|
||||||
|
delete process.env.HWLAB_CLOUD_DB_HOST;
|
||||||
|
delete process.env.HWLAB_CLOUD_DB_PORT;
|
||||||
|
|
||||||
|
const server = createCloudApiServer();
|
||||||
|
await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));
|
||||||
|
|
||||||
|
try {
|
||||||
|
const { port } = server.address();
|
||||||
|
const response = await fetch(`http://127.0.0.1:${port}/health`);
|
||||||
|
const payload = await response.json();
|
||||||
|
const dbJson = JSON.stringify(payload.db);
|
||||||
|
assert.equal(payload.environment, "v02");
|
||||||
|
assert.equal(payload.db.environment, "v02");
|
||||||
|
assert.equal(payload.db.secretRefs[0].secretName, "hwlab-cloud-api-v02-db");
|
||||||
|
assert.equal(payload.db.secretRefs[0].secretKey, "database-url");
|
||||||
|
assert.equal(payload.db.optionalPublicDnsAlias.serviceName, "hwlab-v02-postgres");
|
||||||
|
assert.equal(payload.db.optionalPublicDnsAlias.namespace, "hwlab-v02");
|
||||||
|
assert.equal(payload.db.optionalPublicDnsAlias.requiredForReadiness, false);
|
||||||
|
assert.equal(payload.db.optionalPublicDnsAlias.usedForProbe, false);
|
||||||
|
assert.equal(payload.db.safety.environment, "v02");
|
||||||
|
assert.equal(payload.db.safety.devOnly, false);
|
||||||
|
assert.equal(payload.db.redaction.secretMaterialRead, false);
|
||||||
|
assert.equal(dbJson.includes("hwlab-cloud-api-dev-db"), false);
|
||||||
|
assert.equal(dbJson.includes("hwlab-dev"), false);
|
||||||
|
assert.equal(dbJson.includes("127.0.0.1"), false);
|
||||||
|
assert.equal(dbJson.includes(String(dbPort)), false);
|
||||||
|
} finally {
|
||||||
|
for (const [name, value] of Object.entries(originalEnv)) {
|
||||||
|
if (value === undefined) {
|
||||||
|
delete process.env[name];
|
||||||
|
} else {
|
||||||
|
process.env[name] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await new Promise((resolve, reject) => {
|
||||||
|
server.close((error) => (error ? reject(error) : resolve()));
|
||||||
|
});
|
||||||
|
await new Promise((resolve, reject) => {
|
||||||
|
fakeDb.close((error) => (error ? reject(error) : resolve()));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
test("cloud api health separates DB connected from durable runtime schema readiness", async () => {
|
test("cloud api health separates DB connected from durable runtime schema readiness", async () => {
|
||||||
const originalUrl = process.env.HWLAB_CLOUD_DB_URL;
|
const originalUrl = process.env.HWLAB_CLOUD_DB_URL;
|
||||||
const originalSslMode = process.env.HWLAB_CLOUD_DB_SSL_MODE;
|
const originalSslMode = process.env.HWLAB_CLOUD_DB_SSL_MODE;
|
||||||
|
|||||||
Reference in New Issue
Block a user