Files
sk-react-toolkit/server/tfvarsStore.test.ts
T

130 lines
7.0 KiB
TypeScript

import assert from 'node:assert/strict'
import { after, before, test } from 'node:test'
import pg from 'pg'
import { HttpError } from './http.ts'
import { createTfvarsStore, tfvarsText, type TfvarsStore } from './tfvarsStore.ts'
// The tests create a scratch database on the server the PG* variables name, connected to through the database
// postgres, and drop it at the end.
const database = `tfvars_store_test_${process.pid}`
const admin = new pg.Client({ database: 'postgres' })
let pool: pg.Pool
let store: TfvarsStore
before(async () => {
await admin.connect()
await admin.query(`CREATE DATABASE ${database}`)
pool = new pg.Pool({ database })
store = createTfvarsStore(pool)
})
after(async () => {
await pool?.end()
await admin.query(`DROP DATABASE IF EXISTS ${database}`)
await admin.end()
})
const status = async (promise: Promise<unknown>) => {
try {
await promise
} catch (error) {
assert.ok(error instanceof HttpError, String(error))
return error.statusCode
}
return 0
}
test('modules are created, changed, listed and deleted', async () => {
await store.modules.put({ name: 'router', root: 'router/terraform', description: 'VPN router', configuratorUrl: null })
await store.modules.put({ name: 'router', root: 'router/terraform', description: 'VPN router', configuratorUrl: 'http://localhost:7083/' })
await store.modules.put({ name: 'app', root: 'app', description: '', configuratorUrl: null })
assert.deepEqual(await store.modules.list(), [
{ name: 'app', root: 'app', description: '', configuratorUrl: null },
{ name: 'router', root: 'router/terraform', description: 'VPN router', configuratorUrl: 'http://localhost:7083/' },
])
await store.modules.delete('app')
assert.deepEqual((await store.modules.list()).map((module) => module.name), ['router'])
assert.equal(await status(store.modules.put({ name: 'Bad', root: 'x', description: '', configuratorUrl: null })), 400)
})
test('instances are created and refused for a missing module or a name in use', async () => {
await store.instances.create('router', 'platform', 'terraform_remote_state')
await store.instances.create('router', 'test', 'tf_router_test')
assert.deepEqual((await store.instances.list('router')).map((instance) => [instance.name, instance.stateSchema]), [
['platform', 'terraform_remote_state'],
['test', 'tf_router_test'],
])
assert.equal(await status(store.instances.create('missing', 'x', 'tf_missing_x')), 404)
assert.equal(await status(store.instances.create('router', 'test', 'tf_other')), 409)
assert.equal(await status(store.instances.create('router', 'other', 'tf_router_test')), 409)
assert.equal(await status(store.modules.delete('router')), 409)
})
const META = { schema: 1, producer: 'Test Configurator 1.0.0' }
test('variable files are written with their version and refused against another version', async () => {
const variables = store.variables('router', 'test')
const empty = await variables.read()
assert.deepEqual(empty.files, [])
assert.equal(empty.version, '')
assert.equal(empty.revision, null)
assert.equal(await variables.write(empty.version, { 'platform.tfvars.json': tfvarsText({ a: 1 }), 'secrets.tfvars.json': tfvarsText({ s: 'x' }) }, META), true)
const written = await variables.read()
assert.deepEqual(written.files.map((file) => [file.name, file.content.toString('utf8')]), [
['platform.tfvars.json', tfvarsText({ a: 1 })],
['secrets.tfvars.json', tfvarsText({ s: 'x' })],
])
assert.deepEqual(written.status.map((file) => file.previous), [false, false])
assert.equal(await variables.write(empty.version, { 'platform.tfvars.json': tfvarsText({ a: 2 }) }, META), false)
assert.equal(await variables.write(written.version, { 'platform.tfvars.json': tfvarsText({ a: 2 }) }, META), true)
const changed = await variables.read()
assert.deepEqual(changed.status.map((file) => file.previous), [true, false])
assert.notEqual(changed.version, written.version)
assert.equal(await variables.remove(written.version, 'secrets.tfvars.json', META), false)
assert.equal(await variables.remove(changed.version, 'secrets.tfvars.json', META), true)
assert.deepEqual((await variables.read()).files.map((file) => file.name), ['platform.tfvars.json'])
assert.deepEqual((await store.variables('router', 'platform').read()).files, [])
assert.equal(await status(variables.write((await variables.read()).version, { 'notes.json': tfvarsText({}) }, META)), 400)
assert.equal(await status(store.variables('router', 'missing').write('', { 'a.tfvars.json': tfvarsText({}) }, META)), 404)
})
test('every write is a revision with its files, schema and producer', async () => {
const variables = store.variables('router', 'test')
assert.deepEqual((await variables.revisions()).map((revision) => [revision.revision, revision.schema, revision.producer, revision.names]), [
[3, 1, META.producer, ['platform.tfvars.json']],
[2, 1, META.producer, ['platform.tfvars.json', 'secrets.tfvars.json']],
[1, 1, META.producer, ['platform.tfvars.json', 'secrets.tfvars.json']],
])
const current = await variables.read()
assert.equal(await variables.write(current.version, {}, META), true)
assert.equal(await variables.write(current.version, { 'platform.tfvars.json': tfvarsText({ a: 3 }) }, { schema: null, producer: 'manage.mjs import' }), true)
const newest = (await variables.read()).revision
assert.deepEqual(newest && [newest.revision, newest.schema, newest.producer], [4, null, 'manage.mjs import'])
const first = await variables.revision(1)
assert.deepEqual(first?.files.map((file) => [file.name, file.content.toString('utf8')]), [
['platform.tfvars.json', tfvarsText({ a: 1 })],
['secrets.tfvars.json', tfvarsText({ s: 'x' })],
])
assert.equal(await variables.revision(9), null)
assert.deepEqual(await store.variables('router', 'platform').revisions(), [])
})
test('the files of an instance without revisions become its revision 1 of an unknown producer', async () => {
await pool.query(`INSERT INTO tf_variable_files (module, instance, name, content) VALUES ('router', 'platform', 'a.tfvars.json', '{"b": 1}')`)
await pool.query('DELETE FROM tf_variable_revisions')
const again = createTfvarsStore(pool)
const revisions = await again.variables('router', 'platform').revisions()
assert.deepEqual(revisions.map((revision) => [revision.revision, revision.schema, revision.producer, revision.names]), [[1, null, 'unknown', ['a.tfvars.json']]])
assert.deepEqual((await again.variables('router', 'test').revisions()).map((revision) => revision.revision), [1])
})
test('an instance is deleted with its variable files, then its module', async () => {
await store.instances.delete('router', 'test')
await store.instances.delete('router', 'platform')
assert.deepEqual(await store.instances.list('router'), [])
assert.equal((await pool.query('SELECT count(*)::int AS n FROM tf_variable_files')).rows[0].n, 0)
assert.equal((await pool.query('SELECT count(*)::int AS n FROM tf_variable_revisions')).rows[0].n, 0)
await store.modules.delete('router')
assert.deepEqual(await store.modules.list(), [])
})