Skip to content

Commit

Permalink
m-ld/m-ld-gateway#15: Factored compliance tests into dedicated packag…
Browse files Browse the repository at this point in the history
…e m-ld-test
  • Loading branch information
gsvarovsky committed Aug 2, 2023
1 parent b531bc9 commit db09422
Show file tree
Hide file tree
Showing 9 changed files with 147 additions and 533 deletions.
4 changes: 2 additions & 2 deletions compliance/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ If `LOG_LEVEL=trace`, per-clone performance timings will also be output to `./lo
Specific compliance specs by glob (see [m-ld-spec/compliance](https://github.com/m-ld/m-ld-spec/tree/master/compliance)):
- `npm run compliance -- "2-*/2-*"` or just `npm run compliance -- "2/2"`

For IDE integration, `compliance/test.js` can also be run with the Jasmine
For IDE integration, `compliance/runner.js` can also be run with the Jasmine
command line options `reporter` and `filter` e.g.
```
node compliance/test.js 2/2 "--filter=at least one" "--reporter=jasmine-ts-console-reporter"
node compliance/runner.js 2/2 "--filter=at least one" "--reporter=jasmine-ts-console-reporter"
```

Experimental features in this engine may have tests in the `./test` folder. Run these using `.` as the root path, i.e.
Expand Down
88 changes: 17 additions & 71 deletions compliance/clone.js
Original file line number Diff line number Diff line change
@@ -1,74 +1,38 @@
const { ClassicLevel } = require('classic-level');
const { clone, isRead } = require('@m-ld/m-ld');
const { clone } = require('@m-ld/m-ld');
const { MqttRemotes } = require('@m-ld/m-ld/ext/mqtt');
const { createSign } = require('crypto');
const LOG = require('loglevel');
const { EventEmitter } = require('events');
const { createWriteStream, mkdirSync, existsSync } = require('fs');
const { join } = require('path');
const { CloneProcess } = require('@m-ld/m-ld-test/lib');
const { Observable } = require('rxjs');

Error.stackTraceLimit = Infinity;

process.send({ '@type': 'active' });

process.on('message', startMsg => {
if (startMsg['@type'] !== 'start')
return;

const { config, tmpDirName, requestId } = startMsg;
LOG.setLevel(config.logLevel);
LOG.debug(logTs(), config['@id'], 'config is', JSON.stringify(config));
clone(new ClassicLevel(tmpDirName), MqttRemotes, config, createApp(config)).then(meld => {
send(requestId, 'started', { cloneId: config['@id'] });

const handler = message => {
function settle(work, resMsgType, terminal) {
work.then(() => send(message.id, resMsgType))
.catch(errorHandler(message))
.then(() => !terminal || process.off('message', handler));
}
switch (message['@type']) {
case 'transact':
if (isRead(message.request))
meld.read(message.request).subscribe({
next: subject => send(message.id, 'next', { body: subject }),
complete: () => send(message.id, 'complete'),
error: errorHandler(message)
});
else
settle(meld.write(message.request), 'complete');
break;
case 'stop':
settle(meld.close(), 'stopped', true);
break;
case 'destroy':
settle(meld.close(), 'destroyed', true);
break;
default:
sendError(message.id, `No handler for ${message['@type']}`);
}
};
process.on('message', handler);

meld.follow(update => send(requestId, 'updated', { body: update }));

meld.status.subscribe({
next: status => send(requestId, 'status', { body: status }),
complete: () => send(requestId, 'closed'),
error: err => sendError(requestId, err)
});
}).catch(err => {
LOG.error(logTs(), config['@id'], err);
send(requestId, 'unstarted', { err: `${err}` });
});
new CloneProcess(process, async (config, tmpDirName) => {
const meld = await clone(new ClassicLevel(tmpDirName), MqttRemotes, config, createApp(config));
// A m-ld-js clone does not quite conform to a spec MeldClone
return /**@type {import('@m-ld/m-ld-spec').MeldClone}*/{
read: meld.read.bind(meld),
write: meld.write.bind(meld),
follow: () =>
new Observable(subs =>
meld.follow(update => subs.next(update))),
status: meld.status,
close: meld.close.bind(meld)
}
});

/** @returns {InitialApp} */
function createApp(config) {
const app = {};
const { principal, transportSecurity } = config;
// 1. Create an app principal
if (principal) {
delete config.principal;
// noinspection JSUnusedGlobalSymbols
app.principal = {
'@id': principal['@id'],
// Assuming privateKeyEncoding: { type: 'pkcs1', format: 'pem' }
Expand Down Expand Up @@ -97,22 +61,4 @@ function createApp(config) {
app.backendEvents.on('error', err => LOG.warn('Backend error', err));
}
return app;
}

function send(requestId, type, params) {
process.send({ requestId, '@type': type, ...params },
err => err && LOG.warn(logTs(), 'Clone orphaned from orchestrator', err));
}

function errorHandler(message) {
return err => sendError(message.id, err);
}

function sendError(requestId, err) {
LOG.error(logTs(), err);
return send(requestId, 'error', { err: `${err}` });
}

function logTs() {
return new Date().toISOString();
}
Loading

0 comments on commit db09422

Please sign in to comment.