mjolnir/test/harness/mjolnirTesting.ts
2021-09-09 17:22:05 +01:00

135 lines
5.0 KiB
TypeScript

/*
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, `# 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\
SYNAPSE_CONFIG_DIR=/data`);
console.log('generating synapse keys');
await compose.run('synapse_release', 'generate', {config: composeConfig, log:true});
console.log(process.env.NODE_ENV)
}
async function configureSynapseData() {
let synapseData = path.join(__dirname, 'synapse-data');
let synapseConfig = path.join(__dirname, 'config/synapse');
await fs.mkdir(synapseData).catch(e => {
if (e.code === 'EEXIST') {
console.debug('synapse-data already exists')
} else {
throw e
}
}
);
await fs.mkdir(path.join(synapseData, 'media_store')).catch (e => {
if (e.code === 'EEXIST') {
console.debug('media_store already exists')
} else {
throw e
}
});
await fs.copyFile(path.join(synapseConfig, 'homeserver.yaml'),
path.join(synapseData, "homeserver.yaml"));
}
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 sleep(5000);
await registerUser('mjolnir', 'mjolnir', 'mjolnir', true);
await registerUser('admin', 'admin', 'admin', true);
}
async function configureMjolnir() {
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');
} else {
throw e;
}
});
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');
await import('../../src/index');
}
async function registerUser(username: string, displayname: string, password: string, admin: boolean) {
let registerUrl = `${config.homeserverUrl}/_synapse/admin/v1/register`
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');
return await axios.post(registerUrl, {
nonce,
username,
displayname,
password,
admin,
mac: mac.toString()
}).catch(e => {
if (e.isAxiosError && e.response.data.errcode === 'M_USER_IN_USE') {
console.log(`${username} already registered, skipping`)
} else {
throw e;
}
});
}
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
//await compose.logs(['mjolnir', 'synapse_release'], {config: composeConfig, follow: true});
} catch (e) {
console.error(e);
throw e;
}
await startMjolnir();
}
export async function downHarness() {
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});
}