From 57ef8ab7feb43601b12df33c9225d7d276fbbd0b Mon Sep 17 00:00:00 2001 From: gnuxie Date: Wed, 8 Sep 2021 16:44:06 +0100 Subject: [PATCH] Tidy up test harness. --- docker/README.md | 10 --- src/index.ts | 14 ---- .../docker/Dockerfile.synapse.registration | 6 -- test/harness/launchScript.ts | 2 - test/harness/mjolnirSetup.ts | 31 ++++++++ test/harness/mjolnirTesting.ts | 73 +++++++++++-------- 6 files changed, 72 insertions(+), 64 deletions(-) delete mode 100644 docker/README.md delete mode 100644 test/harness/config/docker/Dockerfile.synapse.registration create mode 100644 test/harness/mjolnirSetup.ts diff --git a/docker/README.md b/docker/README.md deleted file mode 100644 index 90d25272..00000000 --- a/docker/README.md +++ /dev/null @@ -1,10 +0,0 @@ -## Testing mjolnir with docker - -At the moment a test environment for mjolnir can be setup by running -`./mjolnir_testing.sh` from the parent directory. This script will use -the `docker-compose.yaml` in the parent directory. - -This sets up synapse container with a user for mjolnir to use. -The container for mjolnir, creates and joins the moderation room -which has to be specified with an alias in the config under `managementRoom`. -Eventually this setup should be moved to a testing module. diff --git a/src/index.ts b/src/index.ts index fdd70d9f..f9293e26 100644 --- a/src/index.ts +++ b/src/index.ts @@ -44,11 +44,6 @@ if (config.health.healthz.enabled) { Healthz.listen(); } -async function createManagementRoom(client: MatrixClient, alias: string) { - let roomId = await client.createRoom(); - await client.createRoomAlias(alias, roomId); -} - (async function () { const storage = new SimpleFsStorageProvider(path.join(config.dataPath, "bot.json")); @@ -61,13 +56,6 @@ async function createManagementRoom(client: MatrixClient, alias: string) { } config.RUNTIME.client = client; - // probably better to change to a config value - if (process.env.NODE_ENV === "development") { - // expects the config value to be an alias - // don't know what to do about that for now - // probably should validate it so someone doesn't have a huge headache - await createManagementRoom(client, config.managementRoom); - } client.on("room.invite", async (roomId: string, inviteEvent: any) => { const membershipEvent = new MembershipEvent(inviteEvent); @@ -100,9 +88,7 @@ async function createManagementRoom(client: MatrixClient, alias: string) { const banLists: BanList[] = []; const protectedRooms: { [roomId: string]: string } = {}; - const joinedRooms = await client.getJoinedRooms(); - // Ensure we're also joined to the rooms we're protecting LogService.info("index", "Resolving protected rooms..."); for (const roomRef of config.protectedRooms) { diff --git a/test/harness/config/docker/Dockerfile.synapse.registration b/test/harness/config/docker/Dockerfile.synapse.registration deleted file mode 100644 index 0b2bb438..00000000 --- a/test/harness/config/docker/Dockerfile.synapse.registration +++ /dev/null @@ -1,6 +0,0 @@ -# Only exists to register a user, temporary solution - -FROM matrixdotorg/synapse:latest -VOLUME ["/data"] -CMD ["-c", "/data/homeserver.yaml", "-u", "mjolnir", "-p", "mjolnir", "--admin", "http://synapse_release:9999"] -ENTRYPOINT ["register_new_matrix_user"] diff --git a/test/harness/launchScript.ts b/test/harness/launchScript.ts index 609aa6a3..0ede175f 100644 --- a/test/harness/launchScript.ts +++ b/test/harness/launchScript.ts @@ -1,9 +1,7 @@ import * as mjolnirTesting from './mjolnirTesting'; -console.log('wat') switch (process.argv[2]) { case 'up': - console.info('hmm') mjolnirTesting.upHarness(); break; case 'down': diff --git a/test/harness/mjolnirSetup.ts b/test/harness/mjolnirSetup.ts new file mode 100644 index 00000000..c697c33c --- /dev/null +++ b/test/harness/mjolnirSetup.ts @@ -0,0 +1,31 @@ +import { + MatrixClient, + Permalinks, +} from "matrix-bot-sdk"; +import config from "../../src/config"; + +export async function createManagementRoom(client: MatrixClient) { + let roomId = await client.createRoom(); + return await client.createRoomAlias(config.managementRoom, roomId); +} + +export async function ensureManagementRoomExists(client: MatrixClient): Promise { + return await client.resolveRoom(config.managementRoom).catch(async e => { + if (e?.body?.errcode === 'M_NOT_FOUND') { + console.info("moderation room hasn't been created yet, so we're making it now.") + return await createManagementRoom(client); + } + throw e; + }); +} + +export async function ensureLobbyRoomExists(client: MatrixClient): Promise { + const alias = Permalinks.parseUrl(config.protectedRooms[0]).roomIdOrAlias; + return await client.resolveRoom(alias).catch(async e => { + if (e?.body?.errcode === 'M_NOT_FOUND') { + console.info(`${alias} hasn't been created yet, so we're making it now.`) + return await client.createRoomAlias(alias, await client.createRoom()); + } + throw e; + }); +} \ No newline at end of file diff --git a/test/harness/mjolnirTesting.ts b/test/harness/mjolnirTesting.ts index 5a5fc6cb..aafe5f38 100644 --- a/test/harness/mjolnirTesting.ts +++ b/test/harness/mjolnirTesting.ts @@ -1,14 +1,35 @@ +/* +Copyright 2021 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ import * as compose from 'docker-compose'; import * as path from 'path'; import * as fs from 'fs/promises'; import * as HmacSHA1 from 'crypto-js/hmac-sha1'; import axios from 'axios'; import config from "../../src/config"; +import * as mjolnirSetup from './mjolnirSetup'; +import { + PantalaimonClient, + MemoryStorageProvider +} from "matrix-bot-sdk"; const composeConfig = path.join(__dirname, '../../docker-compose.test.yaml'); async function synapseGenerate() { let synapseEnv = path.join(__dirname, 'config/synapse/synapse.env'); - await fs.writeFile(synapseEnv, `UID=${process.getuid()}\n\ + await fs.writeFile(synapseEnv, `# NOTE: This file is generated by the test harness. +UID=${process.getuid()}\n\ GID=${process.getuid()}\n\ SYNAPSE_SERVER_NAME=localhost:9999 SYNAPSE_REPORT_STATS=no\n\ @@ -18,8 +39,6 @@ SYNAPSE_CONFIG_DIR=/data`); console.log(process.env.NODE_ENV) } -// create synapase-data directory -// copy config to it async function configureSynapseData() { let synapseData = path.join(__dirname, 'synapse-data'); let synapseConfig = path.join(__dirname, 'config/synapse'); @@ -43,46 +62,39 @@ async function configureSynapseData() { } async function startSynpase() { + const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)) await synapseGenerate(); console.info('starting synapse.') await compose.upOne('synapse_release', {config: composeConfig, log: true}) - await registerTestUser(); + await sleep(5000); + await registerUser('mjolnir', 'mjolnir', 'mjolnir', true); + await registerUser('admin', 'admin', 'admin', true); } async function configureMjolnir() { - // do we want to clean mjolnir everytime? - //await fs.rm('synapse-data', {recursive: true, force: true}); + await fs.copyFile(path.join(__dirname, 'config', 'mjolnir', 'harness.yaml'), path.join(__dirname, '../../config/harness.yaml')); + await fs.rm(path.join(__dirname, 'mjolnir-data'), {recursive: true, force: true}); await fs.mkdir(path.join(__dirname, 'mjolnir-data')).catch (e => { if (e.code === 'EEXIST') { - console.debug('mjolnir-data already exists') + console.debug('mjolnir-data already exists'); } else { - throw e + throw e; } }); - - // now we need to setup the management room alias that it should join. - // just make bot sdk and make it here or something - // or we should probably have a generic setup module. - + const pantalaimon = new PantalaimonClient(config.homeserverUrl, new MemoryStorageProvider()); + const client = await pantalaimon.createClientWithCredentials(config.pantalaimon.username, config.pantalaimon.password); + await mjolnirSetup.ensureManagementRoomExists(client); + return await mjolnirSetup.ensureLobbyRoomExists(client); } async function startMjolnir() { await configureMjolnir(); console.info('starting mjolnir'); - // will not work without some additonal config, but also it isn't useful to debug like this. - // it would be nice if there was a way to run tests and mjolnir in the same process - // to assist with debugging - //await compose.upOne('mjolnir', {config: composeConfig, log: true}) await import('../../src/index'); } -async function cleanUpSynpase() { - await fs.rm('synapse-data', {recursive: true, force: true}); -} - async function registerUser(username: string, displayname: string, password: string, admin: boolean) { let registerUrl = `${config.homeserverUrl}/_synapse/admin/v1/register` - console.log(registerUrl); let { data } = await axios.get(registerUrl); let nonce = data.nonce!; let mac = HmacSHA1(`${nonce}\0${username}\0${password}\0${admin ? 'admin' : 'notadmin'}`, 'REGISTRATION_SHARED_SECRET'); @@ -95,23 +107,19 @@ async function registerUser(username: string, displayname: string, password: str mac: mac.toString() }).catch(e => { if (e.isAxiosError && e.response.data.errcode === 'M_USER_IN_USE') { - console.log('user already registered, skipping') + console.log(`${username} already registered, skipping`) } else { throw e; } }); } -async function registerTestUser() { - return await registerUser('mjolnir', 'mjolnir', 'mjolnir', true); -} - export async function upHarness() { try { await configureSynapseData(); await startSynpase(); - // this doesn't actually seem to be implented by the library authors (at least it doesn't do what you'd expect)? - // see their github issue https://github.com/PDMLab/docker-compose/issues/127 + // This doesn't actually seem to be implented by the library authors (at least it doesn't do what you'd expect)? + // See their github issue https://github.com/PDMLab/docker-compose/issues/127 //await compose.logs(['mjolnir', 'synapse_release'], {config: composeConfig, follow: true}); } catch (e) { console.error(e); @@ -121,6 +129,7 @@ export async function upHarness() { } export async function downHarness() { - await cleanUpSynpase(); -} - + compose.down({config: composeConfig, log: true}); + await fs.rm(path.join(__dirname, 'synapse-data'), {recursive: true, force: true}); + await fs.rm(path.join(__dirname, 'mjolnir-data'), {recursive: true, force: true}); +} \ No newline at end of file