chore(tests): проверить backend на PostgreSQL и убрать ожидание idle пула
This commit is contained in:
1 parent
fdddc52019
commit
7ad66f178b
15 files changed
+1249
-17
No files matched your search
@@ -8,7 +8,7 @@
|
||||
"dev": "tsx watch src/index.ts",
|
||||
"build": "npm run build -w @mmapp/contracts && tsc",
|
||||
"test:alerts-telegram": "tsx src/services/alerts-outbox-retry.test.ts && tsx src/services/alerts-outbox-overview.test.ts && tsx src/services/alert-engine/outbox-execution.test.ts && tsx src/services/alerts-telegram-delivery.test.ts && tsx src/services/alerts-revision.test.ts && tsx src/services/alerts-overview.test.ts && tsx ../packages/contracts/src/alerts-normalization.test.ts && tsx src/services/alerts-config-execution.test.ts && tsx src/services/alerts-telegram-settings.test.ts && tsx src/services/alerts-telegram-send.test.ts && tsx src/routes/alerts.test.ts && tsx src/plugins/auth.alerts.test.ts",
|
||||
"test:alert-engine": "tsx src/services/alert-engine/groups.test.ts && tsx src/services/alert-engine/evaluate-rule.test.ts && tsx src/services/gre-bgp-snapshot-collector.test.ts && tsx src/services/gre-bgp-snapshot-history.test.ts && tsx src/services/alert-engine/confirm-stability.test.ts",
|
||||
"test:alert-engine": "tsx src/services/alert-engine/groups.test.ts && tsx src/services/alert-engine/evaluate-rule.test.ts && tsx src/services/gre-bgp-snapshot-collector.test.ts && tsx src/services/gre-bgp-snapshot-history.test.ts && tsx src/services/gre-bgp-snapshot-sql.test.ts && tsx src/services/alert-engine/confirm-stability.test.ts",
|
||||
"start": "node dist/index.js",
|
||||
"db:generate": "drizzle-kit generate",
|
||||
"db:migrate": "drizzle-kit migrate",
|
||||
@@ -22,7 +22,7 @@
|
||||
"test:traffic-rate": "tsx src/services/traffic-rate.test.ts",
|
||||
"test:traffic-flow": "tsx src/routes/traffic-flow-query.test.ts && tsx src/services/traffic-flow-month.test.ts && tsx src/services/traffic-flow-parse.test.ts && tsx src/services/traffic-flow-ipv6-pipeline.test.ts && tsx src/services/traffic-flow-map-exporter.test.ts && tsx src/services/traffic-flow-ifaces.test.ts && tsx src/services/traffic-flow-ifindex.test.ts && tsx src/services/traffic-flow-dedup.test.ts && tsx src/services/traffic-flow-planes.test.ts && tsx src/services/traffic-flow-ip.test.ts && tsx src/services/traffic-flow-dest.test.ts && tsx src/services/traffic-flow-classify.test.ts && tsx src/services/traffic-flow-ripe.test.ts && tsx src/services/traffic-flow-brands.test.ts && tsx src/services/traffic-flow-ingest.test.ts && tsx src/services/traffic-flow-analytics.test.ts && tsx src/services/traffic-flow-map-hops.test.ts && tsx src/services/traffic-flow-purge.test.ts && tsx src/services/traffic-flow-geoip.test.ts && tsx src/services/traffic-flow-facts.test.ts && tsx src/services/traffic-flow-facts-filter.test.ts && tsx src/services/traffic-flow-facts-rebuild.test.ts && tsx src/services/statistics-aggregate.test.ts",
|
||||
"test:users": "tsx src/modules/users/iface-type.test.ts && tsx src/modules/users/bindings.test.ts && tsx src/modules/users/interface-inventory.test.ts && tsx src/routes/users-catalog.test.ts",
|
||||
"test:pg": "tsx src/db/sql-bind.test.ts && tsx src/db/sqlite-json.test.ts && tsx src/db/traffic-flags.test.ts && tsx src/db/pg-schema.test.ts && tsx src/services/config-revisions.test.ts",
|
||||
"test:pg": "tsx src/db/pg-pool.test.ts && tsx src/db/sql-bind.test.ts && tsx src/db/sqlite-json.test.ts && tsx src/db/traffic-flags.test.ts && tsx src/db/pg-schema.test.ts && tsx src/services/config-revisions.test.ts",
|
||||
"test:recursive-routes": "tsx src/routes/recursive-routes.test.ts && tsx src/services/recursive-route-catalog.test.ts && tsx src/services/recursive-apply.test.ts",
|
||||
"test:config-sync": "tsx src/utils/server-id.test.ts && tsx src/services/config-apply-plan.test.ts && tsx src/services/entity-snapshots.test.ts && tsx src/services/gre-ipv6.test.ts && tsx src/routes/gre-ipv6-validation.test.ts && tsx src/services/network-disabled-server.test.ts",
|
||||
"test:ros-file": "tsx src/services/ros-file-contents.test.ts && tsx src/services/mikrotik-response.test.ts",
|
||||
@@ -30,7 +30,7 @@
|
||||
"test:backups": "tsx src/services/backup-scheduler-run.test.ts && tsx src/services/backup-restore.test.ts && tsx src/services/backup-deletion.test.ts && tsx src/services/backup-dto.test.ts && tsx src/services/backup-storage-update.test.ts && tsx src/services/backup-job-execution.test.ts && tsx src/routes/backups-operations.test.ts && tsx src/services/s3-backup-client.test.ts",
|
||||
"test:ipsec": "tsx src/services/ipsec-config.test.ts && tsx src/services/ipsec-state.test.ts && tsx src/routes/ipsec-history.test.ts && tsx src/services/ipsec-restore.test.ts && tsx src/services/ipsec-operation.test.ts && tsx src/routes/ipsec-mutation.test.ts && tsx src/routes/ipsec-nat.test.ts && tsx src/routes/ipsec-group.test.ts",
|
||||
"test:live-maps": "tsx src/services/ospf-route-parse.test.ts && tsx src/services/vxlan-live.test.ts && tsx src/routes/vxlan.test.ts && tsx src/services/containers-live.test.ts && tsx src/services/firewall-poll.test.ts && tsx src/services/gre-catalog-poll.test.ts && tsx src/routes/filters-gre-catalog.test.ts && tsx src/routes/bgp-catalog.test.ts && tsx src/services/bgp-catalog-parse.test.ts && tsx src/routes/ospf-catalog.test.ts && tsx src/services/ospf-observed-values.test.ts",
|
||||
"test": "npm run test:probes && npm run test:exec && npm run test:alert-engine && npm run test:alerts-telegram && npm run test:auth && npm run test:wireguard && npm run test:ipsec && npm run test:traffic-rate && npm run test:traffic-flow && npm run test:users && npm run test:pg && npm run test:backups && npm run test:scheduler && npm run test:live-maps && npm run test:ospf-optimizer && npm run test:recursive-routes && npm run test:config-sync && npm run test:ros-file && npm run test:containers && npm run test:certificates && npm run test:netflow-settings && npm run test:netflow-purge && npm run test:evolution && npm run test:system-database",
|
||||
"test": "node scripts/test.mjs",
|
||||
"test:evolution": "tsx src/services/evobgp-catalog.test.ts && tsx src/routes/evobgp-catalog.test.ts && tsx src/routes/evobgp-settings.test.ts && tsx src/plugins/auth.evolution-settings.test.ts",
|
||||
"test:netflow-purge": "tsx src/db/operation-lock.test.ts && tsx src/services/traffic-flow-purge-execution.test.ts && tsx src/routes/traffic-flow-purge.test.ts",
|
||||
"test:netflow-settings": "tsx src/services/traffic-flow-host-file-builders.test.ts && tsx src/services/traffic-flow-key-execution.test.ts && tsx src/routes/traffic-flow-settings.test.ts && tsx src/plugins/auth.netflow-settings.test.ts",
|
||||
@@ -38,7 +38,8 @@
|
||||
"test:ospf-optimizer": "tsx src/services/ospf-optimizer-identity.test.ts && tsx src/services/ospf-optimizer-metrics.test.ts && tsx src/services/ospf-optimizer-plan.test.ts && tsx src/services/ospf-effective-disabled.test.ts && tsx src/routes/ospf-optimizer.test.ts",
|
||||
"test:containers": "tsx src/services/containers-state.test.ts && tsx src/routes/containers-state.test.ts",
|
||||
"test:certificates": "tsx src/services/certificate-issue-execution.test.ts && tsx src/services/certificate-issue-request.test.ts && tsx src/routes/certificates-issue.test.ts && tsx src/services/certificate-issue-dto.test.ts && tsx src/services/certificate-parse.test.ts && tsx src/services/certificates-state.test.ts && tsx src/routes/certificates-state.test.ts",
|
||||
"test:system-database": "tsx src/services/system-database-partition-restore.test.ts && tsx src/services/system-database-cache.test.ts && tsx src/services/database-background-work.test.ts && tsx src/services/database-request-gate.test.ts && tsx src/services/traffic-flow-worker-shutdown.test.ts && tsx src/services/system-database-restore-execution.test.ts && tsx src/services/system-database-operation.test.ts && tsx src/routes/system-database.test.ts && tsx src/plugins/auth.system-database.test.ts"
|
||||
"test:system-database": "tsx src/services/system-database-partition-restore.test.ts && tsx src/services/system-database-cache.test.ts && tsx src/services/database-background-work.test.ts && tsx src/services/database-request-gate.test.ts && tsx src/services/traffic-flow-worker-shutdown.test.ts && tsx src/services/system-database-restore-execution.test.ts && tsx src/services/system-database-operation.test.ts && tsx src/routes/system-database.test.ts && tsx src/plugins/auth.system-database.test.ts",
|
||||
"test:all": "npm run test:probes && npm run test:exec && npm run test:alert-engine && npm run test:alerts-telegram && npm run test:auth && npm run test:wireguard && npm run test:ipsec && npm run test:traffic-rate && npm run test:traffic-flow && npm run test:users && npm run test:pg && npm run test:backups && npm run test:scheduler && npm run test:live-maps && npm run test:ospf-optimizer && npm run test:recursive-routes && npm run test:config-sync && npm run test:ros-file && npm run test:containers && npm run test:certificates && npm run test:netflow-settings && npm run test:netflow-purge && npm run test:evolution && npm run test:system-database"
|
||||
},
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-s3": "^3.888.0",
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import { readFileSync } from "node:fs"
|
||||
import { spawnSync } from "node:child_process"
|
||||
const pkg = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8"))
|
||||
const npmCli = process.env.npm_execpath
|
||||
if (!npmCli) throw new Error("Запускайте тесты через npm --prefix backend test")
|
||||
for (const command of pkg.scripts["test:all"].split(/\s*&&\s*/)) {
|
||||
const match = /^npm run (test:[\w-]+)$/.exec(command)
|
||||
if (!match) throw new Error("Неизвестный формат профиля backend tests")
|
||||
const result = spawnSync(process.execPath, [npmCli, "run", match[1]], {
|
||||
cwd: new URL("../", import.meta.url),
|
||||
env: { ...process.env, NODE_ENV: "test" },
|
||||
stdio: "inherit",
|
||||
})
|
||||
if (result.error) throw result.error
|
||||
if (result.status !== 0) process.exit(result.status ?? 1)
|
||||
}
|
||||
@@ -19,6 +19,7 @@ export function createPool(max = 16): pg.Pool {
|
||||
connectionString: env.DATABASE_URL,
|
||||
max,
|
||||
idleTimeoutMillis: 30_000,
|
||||
allowExitOnIdle: process.env.NODE_ENV === "test",
|
||||
connectionTimeoutMillis: 8_000,
|
||||
statement_timeout: 120_000,
|
||||
})
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import assert from "node:assert/strict"
|
||||
import { createPool } from "./index.js"
|
||||
const original = process.env.NODE_ENV
|
||||
try {
|
||||
for (const mode of ["production", "development", "test"]) {
|
||||
process.env.NODE_ENV = mode
|
||||
const pool = createPool(1)
|
||||
assert.equal(pool.options.allowExitOnIdle, mode === "test")
|
||||
assert.equal(pool.options.idleTimeoutMillis, 30_000)
|
||||
assert.equal(pool.options.max, 1)
|
||||
await pool.end()
|
||||
}
|
||||
} finally {
|
||||
if (original === undefined) delete process.env.NODE_ENV
|
||||
else process.env.NODE_ENV = original
|
||||
}
|
||||
console.log("PG pool: tests may exit on idle; production/development retain normal pool lifecycle, no SQL connection")
|
||||
@@ -0,0 +1,47 @@
|
||||
import assert from "node:assert/strict"
|
||||
import { pool, closePool } from "../db/index.js"
|
||||
import { initDatabase } from "../db/bootstrap.js"
|
||||
import { readGreBgpRunSnapshots } from "./gre-bgp-snapshot-history.js"
|
||||
import { buildSignalSnapshotFromCollectors } from "./alert-engine/signals-from-collectors.js"
|
||||
import { SCHEDULER_RUN_SNAPSHOT_VERSION } from "../types/scheduler-run-snapshot.js"
|
||||
|
||||
const name = process.env.MMAPP_OWN_SQL_DB
|
||||
if (!name) console.log("GRE/BGP SQL: skipped; explicit owned database required")
|
||||
else {
|
||||
assert(/^mm_accept_166_\d+$/.test(name))
|
||||
assert.equal(decodeURIComponent(new URL(process.env.DATABASE_URL!).pathname.slice(1)), name)
|
||||
assert.equal((await pool.query("SELECT current_database() AS name")).rows[0].name, name)
|
||||
const prefix = "own-history166-" + Date.now() + "-"
|
||||
let sequence = 0
|
||||
const start = Date.now() - 60_000
|
||||
const old = { v: SCHEDULER_RUN_SNAPSHOT_VERSION, job: "gre_bgp", sampledAt: new Date(start).toISOString(), greWritten: 1, bgpWritten: 1, greTunnels: [{ targetLabel: "old-gre", status: "down" }], bgpPeers: [{ key: "old-peer", state: "Idle" }] }
|
||||
async function insert(status: "ok" | "error", payload: unknown) {
|
||||
const id = prefix + sequence++, time = new Date(start + sequence * 1000).toISOString()
|
||||
await pool.query("INSERT INTO scheduler_runs(id,job_key,started_at,finished_at,status,error,result_json) VALUES($1,'gre_bgp',$2,$2,$3,$4,$5::jsonb)", [id, time, status, status === "error" ? "owned failure" : null, payload === null ? null : JSON.stringify(payload)])
|
||||
}
|
||||
try {
|
||||
await initDatabase()
|
||||
await insert("ok", old)
|
||||
await insert("error", { ...old, greWritten: 0, greTunnels: [], bgpPeers: [{ key: "current-peer", state: "Established" }], errors: ["GRE: owned refusal"] })
|
||||
assert.deepEqual((await readGreBgpRunSnapshots())[0].bgpPeers, [{ key: "current-peer", state: "Established" }])
|
||||
let signals = await buildSignalSnapshotFromCollectors()
|
||||
assert.deepEqual(signals.bgpSessions, [{ key: "current-peer", state: "Established", prevState: null }]); assert.deepEqual(signals.greTunnels, [])
|
||||
for (const payload of [null, "{bad"]) {
|
||||
await insert("error", payload)
|
||||
assert((await readGreBgpRunSnapshots())[0].fatalError)
|
||||
signals = await buildSignalSnapshotFromCollectors()
|
||||
assert.deepEqual(signals.bgpSessions, []); assert.deepEqual(signals.greTunnels, [])
|
||||
}
|
||||
await insert("ok", { ...old, greTunnels: [], bgpPeers: [] })
|
||||
signals = await buildSignalSnapshotFromCollectors()
|
||||
assert.deepEqual(signals.bgpSessions, []); assert.deepEqual(signals.greTunnels, [])
|
||||
await insert("ok", { ...old, greTunnels: [{ targetLabel: "duplicate", status: "up" }, { targetLabel: "duplicate", status: "down" }], bgpPeers: [{ key: "duplicate", state: "Established" }, { key: "duplicate", state: "Idle" }] })
|
||||
signals = await buildSignalSnapshotFromCollectors()
|
||||
assert.deepEqual(signals.bgpSessions, [{ key: "duplicate", state: "Unknown", prevState: null }]); assert.deepEqual(signals.greTunnels, [])
|
||||
console.log("GRE/BGP owned SQL: 6 real rows; newest error/partial, NULL/malformed barrier, empty/deleted and duplicate guards passed")
|
||||
} finally {
|
||||
await pool.query("DELETE FROM scheduler_runs WHERE id LIKE $1", [prefix + "%"])
|
||||
assert.equal((await pool.query("SELECT count(*)::int AS n FROM scheduler_runs WHERE id LIKE $1", [prefix + "%"])).rows[0].n, 0)
|
||||
await closePool()
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user