ddl-manager
Version:
store postgres procedures and triggers in files
173 lines (142 loc) • 5 kB
text/typescript
import { Pool } from "pg";
import fs from "fs";
import {prepare, buildDDL} from "./fixture";
import { CacheAuditor, CacheScanner } from "../../../../lib/Auditor";
import { FileReader } from "../../../../lib/fs/FileReader";
import { Database } from "../../../../lib/database/schema/Database";
import { PostgresDriver } from "../../../../lib/database/PostgresDriver";
import { CacheColumnGraph } from "../../../../lib/Comparator/graph/CacheColumnGraph";
import { deepEqualRow, shouldBeBetween } from "./utils";
import { strict } from "assert";
const ROOT_TMP_PATH = __dirname + "/tmp";
describe("CacheAuditor: fix data and save report", () => {
let db: Pool;
beforeEach(async () => {
db = await prepare();
});
it("no reports if all ok", async() => {
fs.writeFileSync(ROOT_TMP_PATH + "/cache.sql", `
cache totals for companies (
select
1 as some_column
)
`);
await build();
await audit();
const lastReport = await loadLastReport();
strict.equal(lastReport, undefined);
});
describe("audit simple broken cache", () => {
beforeEach(async() => {
fs.writeFileSync(ROOT_TMP_PATH + "/cache.sql", `
cache totals for companies (
select
1 as some_column
)
`);
await build();
await db.query(`
update companies set
some_column = 0
`);
});
it("should fix data", async () => {
await audit();
const result = await db.query(`
select id, some_column
from companies
order by id
`);
strict.deepEqual(result.rows, [
{id: 1, some_column: 1},
{id: 2, some_column: 1}
]);
});
it("need recreate report columns", async() => {
await db.query(`
create table ddl_manager_audit_report (
id bigserial primary key
);
update companies set
some_column = 0;
`);
await audit();
await expectedReport("cache_column", "public.companies.some_column");
});
describe("should save report", async () => {
it("save schema, table, column", async() => {
await audit();
await expectedReport("cache_column", "public.companies.some_column");
});
it("save expected, actual cache value", async() => {
await audit();
await expectedReport("expected_value", 1);
await expectedReport("actual_value", 0);
});
it("save scan date", async() => {
const dateStart = new Date();
await audit();
const dateEnd = new Date();
const lastReport = await loadLastReport();
shouldBeBetween(lastReport.scan_date, dateStart, dateEnd);
});
it("save cache row", async() => {
await audit();
const lastReport = await loadLastReport();
deepEqualRow(lastReport.cache_row, {
id: 1,
name: "client",
some_column: 0
});
});
});
});
async function build() {
await buildDDL(db);
}
async function audit() {
const fsState = FileReader.read([ROOT_TMP_PATH]);
const dbState = new Database();
const graph = CacheColumnGraph.build(
new Database().aggregators,
fsState.allCache()
);
const postgres = new PostgresDriver(db);
const scanner = new CacheScanner(
postgres,
dbState,
graph
);
const auditor = new CacheAuditor(
postgres,
dbState,
fsState,
graph,
scanner,
);
await auditor.audit();
}
async function expectedReport(column: string, expected: any) {
const lastReport = await loadLastReport();
strict.ok(lastReport, "report should be saved");
strict.deepEqual({
[]: lastReport[column]
}, {
[]: expected
});
}
async function loadLastReport() {
const {rows} = await db.query(`
select
*,
to_char(
ddl_manager_audit_report.scan_date at time zone 'UTC',
'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"'
) as scan_date
from ddl_manager_audit_report
order by ddl_manager_audit_report.id desc
limit 1
`);
return rows[0];
}
})