Skip to content

Commit 1ad2742

Browse files
committed
fix(EnqueuerAsNodeChildRunner): Add new messages to exchange with node parent process
1 parent 9cd6196 commit 1ad2742

19 files changed

+2805
-1933
lines changed

output/examples.json

+1,279-943
Large diffs are not rendered by default.

output/examples.yml

+1,212-941
Large diffs are not rendered by default.

src/enqueuer-as-node-child-runner.test.ts

+78-26
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,38 @@
1-
import {RequisitionRunner} from './requisition-runners/requisition-runner';
21
import {NotificationEmitter} from './notifications/notification-emitter';
3-
import {EnqueuerAsNodeChildRunner} from "./enqueuer-as-node-child-runner";
4-
import {Notifications} from "./notifications/notifications";
2+
import {EnqueuerAsNodeChildRunner} from './enqueuer-as-node-child-runner';
3+
import {Notifications} from './notifications/notifications';
4+
import {ChildRequisitionRunner} from './run-as-child/child-requisition-runner';
5+
import {AssertDescriber} from './run-as-child/assert-describer';
6+
import {ModuleAdder} from './run-as-child/module-adder';
7+
import {ProtocolDescriber} from './run-as-child/protocol-describer';
8+
import {StoreCleaner} from './run-as-child/store-cleaner';
59

610

7-
jest.mock('./requisition-runners/requisition-runner');
811
jest.mock('./notifications/notification-emitter');
12+
jest.mock('./run-as-child/child-requisition-runner');
13+
jest.mock('./run-as-child/assert-describer');
14+
jest.mock('./run-as-child/module-adder');
15+
jest.mock('./run-as-child/protocol-describer');
16+
jest.mock('./run-as-child/store-cleaner');
917

1018
const processOnMock = jest.fn();
1119
process.on = processOnMock;
1220

1321
const processSendMock = jest.fn();
1422
process.send = processSendMock;
1523

16-
const runMock = jest.fn();
17-
const requisitionRunnerConstructorMock = jest.fn(() => ({run: runMock}));
24+
const replierProcessMock = jest.fn();
25+
const replierConstructorMock = jest.fn(() => ({process: replierProcessMock}));
1826
// @ts-ignore
19-
RequisitionRunner.mockImplementation(requisitionRunnerConstructorMock);
27+
ChildRequisitionRunner.mockImplementation(replierConstructorMock);
28+
// @ts-ignore
29+
AssertDescriber.mockImplementation(replierConstructorMock);
30+
// @ts-ignore
31+
ModuleAdder.mockImplementation(replierConstructorMock);
32+
// @ts-ignore
33+
ProtocolDescriber.mockImplementation(replierConstructorMock);
34+
// @ts-ignore
35+
StoreCleaner.mockImplementation(replierConstructorMock);
2036

2137
let notificationEmitterOnMock = jest.fn();
2238
// @ts-ignore
@@ -26,21 +42,22 @@ describe('EnqueuerAsNodeChildRunner', () => {
2642
beforeEach(() => {
2743
processOnMock.mockClear();
2844
processSendMock.mockClear();
29-
requisitionRunnerConstructorMock.mockClear();
30-
runMock.mockClear();
45+
replierConstructorMock.mockClear();
46+
replierProcessMock.mockClear();
3147
notificationEmitterOnMock.mockClear();
3248
});
3349

3450
it('should listen to message', async () => {
35-
const statusCode = await new EnqueuerAsNodeChildRunner().execute(true);
51+
const enqueuerAsNodeChildRunner = new EnqueuerAsNodeChildRunner();
52+
const statusCode = await enqueuerAsNodeChildRunner.execute();
3653

3754
expect(statusCode).toBe(0);
3855
expect(processOnMock.mock.calls[0][0]).toBe('message');
3956
});
4057

4158
it('should send exit message', async () => {
4259
const statusCode = 0;
43-
await new EnqueuerAsNodeChildRunner().execute(true);
60+
await new EnqueuerAsNodeChildRunner().execute();
4461

4562
expect(processOnMock.mock.calls[1][0]).toBe('exit');
4663

@@ -53,38 +70,73 @@ describe('EnqueuerAsNodeChildRunner', () => {
5370
});
5471
});
5572

56-
it('should run enqueuer runner when a message arrives', async () => {
57-
const requisition = 'value';
58-
await new EnqueuerAsNodeChildRunner().execute(true);
73+
it('should do nothing when message is unknown', async () => {
74+
const message = {event: 'UNKNOWN'};
75+
76+
await new EnqueuerAsNodeChildRunner().execute();
5977

6078
const onMessageCallback = processOnMock.mock.calls[0][1];
61-
onMessageCallback({event: 'runRequisition', value: requisition});
62-
expect(requisitionRunnerConstructorMock).toHaveBeenCalledWith(requisition);
63-
expect(runMock).toHaveBeenCalled();
79+
onMessageCallback(message);
80+
expect(replierProcessMock).not.toHaveBeenCalled();
6481
});
6582

66-
it('should not run enqueuer when a message arrives but is not a requisitions', async () => {
67-
await new EnqueuerAsNodeChildRunner().execute(true);
83+
it('should add modules list when requested', async () => {
84+
const message = {event: 'ADD_MODULE', value: 'value'};
85+
86+
await new EnqueuerAsNodeChildRunner().execute();
87+
88+
const onMessageCallback = processOnMock.mock.calls[0][1];
89+
onMessageCallback(message);
90+
expect(replierConstructorMock).toHaveBeenCalled();
91+
expect(replierProcessMock).toHaveBeenCalledWith(message);
92+
});
93+
94+
it('should get protocols list when requested', async () => {
95+
const message = {event: 'GET_PROTOCOLS', value: 'value'};
96+
97+
await new EnqueuerAsNodeChildRunner().execute();
98+
99+
const onMessageCallback = processOnMock.mock.calls[0][1];
100+
onMessageCallback(message);
101+
expect(replierConstructorMock).toHaveBeenCalled();
102+
expect(replierProcessMock).toHaveBeenCalledWith(message);
103+
});
104+
105+
it('should get asserters list when requested', async () => {
106+
const message = {event: 'GET_ASSERTERS', value: 'value'};
107+
108+
await new EnqueuerAsNodeChildRunner().execute();
109+
110+
const onMessageCallback = processOnMock.mock.calls[0][1];
111+
onMessageCallback(message);
112+
expect(replierConstructorMock).toHaveBeenCalled();
113+
expect(replierProcessMock).toHaveBeenCalledWith(message);
114+
});
115+
116+
it('should run enqueuer runner when a message arrives', async () => {
117+
const message = {event: 'RUN_REQUISITION', value: 'value'};
118+
119+
await new EnqueuerAsNodeChildRunner().execute();
68120

69121
const onMessageCallback = processOnMock.mock.calls[0][1];
70-
onMessageCallback({event: 'NOT_A REQUISITION'});
71-
expect(requisitionRunnerConstructorMock).not.toHaveBeenCalled();
72-
expect(runMock).not.toHaveBeenCalled();
122+
onMessageCallback(message);
123+
expect(replierConstructorMock).toHaveBeenCalled();
124+
expect(replierProcessMock).toHaveBeenCalledWith(message);
73125
});
74126

75127
it('should register senders to every notification', async () => {
76-
await new EnqueuerAsNodeChildRunner().execute(true);
128+
await new EnqueuerAsNodeChildRunner().execute();
77129

78130
const everyNotificationKey = Object.keys(Notifications)
79131
.map((key: any) => Notifications[key])
80-
.filter((key: any) => typeof key === 'number')
132+
.filter((key: any) => typeof key === 'number');
81133

82134
expect(notificationEmitterOnMock.mock.calls.map((call: any) => call[0]))
83135
.toEqual(everyNotificationKey);
84136
});
85137

86-
it('should send when notification is emitted', async () => {
87-
await new EnqueuerAsNodeChildRunner().execute(true);
138+
it('should proxy message when notification is emitted', async () => {
139+
await new EnqueuerAsNodeChildRunner().execute();
88140

89141
const report = {cycle: {}};
90142
report.cycle = report;

src/enqueuer-as-node-child-runner.ts

+41-21
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,42 @@
1-
import {RequisitionRunner} from './requisition-runners/requisition-runner';
21
import {NotificationEmitter} from './notifications/notification-emitter';
32
import {ObjectDecycler} from './object-parser/object-decycler';
43
import {Notifications} from './notifications/notifications';
4+
import {ParentReplier} from './run-as-child/parent-replier';
5+
import {ChildReceivingEvents} from './run-as-child/child-receiving-events';
6+
import {ChildRequisitionRunner} from './run-as-child/child-requisition-runner';
7+
import {ModuleAdder} from './run-as-child/module-adder';
8+
import {ProtocolDescriber} from './run-as-child/protocol-describer';
9+
import {AssertDescriber} from './run-as-child/assert-describer';
10+
import {StoreCleaner} from './run-as-child/store-cleaner';
11+
import {ChildSendingEvents} from './run-as-child/child-sending-events';
512

613
export class EnqueuerAsNodeChildRunner {
14+
private readonly processors: {
15+
[key: string]: ParentReplier
16+
};
717

8-
public execute(shouldEnd: boolean = false): Promise<number> {
9-
console.log('Rocking and rolling');
10-
this.registerSenders();
18+
public constructor() {
19+
this.processors = {
20+
[ChildReceivingEvents.ADD_MODULE]: new ModuleAdder(),
21+
[ChildReceivingEvents.CLEAN_STORE]: new StoreCleaner(),
22+
[ChildReceivingEvents.GET_ASSERTERS]: new AssertDescriber(),
23+
[ChildReceivingEvents.GET_PROTOCOLS]: new ProtocolDescriber(),
24+
[ChildReceivingEvents.RUN_REQUISITION]: new ChildRequisitionRunner(),
25+
};
26+
}
27+
28+
public execute(): Promise<number> {
29+
console.log('Child is rocking and rolling');
30+
this.registerInternProxies();
1131
this.registerListeners();
1232
return new Promise<number>(resolve => {
13-
if (shouldEnd) {
33+
if (process.env.NODE_ENV && process.env.NODE_ENV.toUpperCase() === 'TEST') {
1434
resolve(0);
1535
}
1636
});
1737
}
1838

19-
private registerListeners() {
20-
process.on('message', async message => {
21-
if (message.event === 'runRequisition') {
22-
await new RequisitionRunner(message.value).run();
23-
}
24-
});
25-
process.on('exit', (code) => {
26-
process.send!({
27-
event: 'PROCESS_EXIT',
28-
value: code
29-
});
30-
});
31-
}
32-
33-
private registerSenders() {
34-
39+
private registerInternProxies() {
3540
Object.keys(Notifications)
3641
.map((key: any) => Notifications[key])
3742
.filter((key: any) => typeof key === 'number')
@@ -49,4 +54,19 @@ export class EnqueuerAsNodeChildRunner {
4954
});
5055
}
5156

57+
public registerListeners(): void {
58+
process.on('message', async message => {
59+
const processor = this.processors[message.event];
60+
if (processor) {
61+
await processor.process(message);
62+
}
63+
});
64+
process.on('exit', (code) => {
65+
process.send!({
66+
event: ChildSendingEvents.PROCESS_EXIT,
67+
value: code
68+
});
69+
});
70+
}
71+
5272
}

src/enqueuer-runner.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {SummaryTestOutput} from './outputs/summary-test-output';
66
import {NotificationEmitter} from './notifications/notification-emitter';
77
import {Logger} from './loggers/logger';
88
import {LogLevel} from './loggers/log-level';
9-
import {Notifications} from "./notifications/notifications";
9+
import {Notifications} from './notifications/notifications';
1010

1111
jest.mock('./outputs/summary-test-output');
1212
jest.mock('./configurations/configuration');

src/reporters/subscription/subscription-reporter.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ export class SubscriptionReporter {
9999
public async receiveMessage(): Promise<any> {
100100
if (!this.subscription.ignore) {
101101
try {
102-
const messageReceived = await this.processMessage(await this.subscription.receiveMessage());
102+
const messageReceived = this.processMessage(await this.subscription.receiveMessage());
103103
this.subscription.messageReceived = messageReceived;
104104
Logger.debug(`${this.subscription.name} received its message`);
105105
this.handleMessageArrival();
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import {DynamicModulesManager} from '../plugins/dynamic-modules-manager';
2+
import {AssertDescriber} from './assert-describer';
3+
4+
jest.mock('../plugins/dynamic-modules-manager');
5+
6+
const processSendMock = jest.fn();
7+
process.send = processSendMock;
8+
9+
// @ts-ignore
10+
DynamicModulesManager.getInstance.mockImplementation(() => {
11+
return {
12+
getAsserterManager: () => ({getMatchingAsserters: () => 'mockedAsserter'})
13+
};
14+
});
15+
16+
describe('AssertDescriber', () => {
17+
18+
it('should describe asserters when a message arrives', async () => {
19+
const message = {value: 'value'};
20+
await new AssertDescriber().process(message);
21+
22+
expect(processSendMock).toHaveBeenCalledWith({event: 'ASSERTERS_LIST', value: 'mockedAsserter'});
23+
});
24+
25+
26+
});

src/run-as-child/assert-describer.ts

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import {DynamicModulesManager} from '../plugins/dynamic-modules-manager';
2+
import {ChildSendingEvents} from './child-sending-events';
3+
import {ParentReplier} from './parent-replier';
4+
5+
export class AssertDescriber implements ParentReplier {
6+
public async process(message: any): Promise<boolean> {
7+
const asserters = DynamicModulesManager.getInstance().getAsserterManager().getMatchingAsserters('');
8+
process.send!(
9+
{
10+
event: ChildSendingEvents.ASSERTERS_LIST,
11+
value: asserters
12+
});
13+
return true;
14+
}
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export enum ChildReceivingEvents {
2+
RUN_REQUISITION = 'RUN_REQUISITION',
3+
ADD_MODULE = 'ADD_MODULE',
4+
GET_PROTOCOLS = 'GET_PROTOCOLS',
5+
GET_ASSERTERS = 'GET_ASSERTERS',
6+
CLEAN_STORE = 'CLEAN_STORE',
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import {ChildRequisitionRunner} from './child-requisition-runner';
2+
import {RequisitionRunner} from '../requisition-runners/requisition-runner';
3+
4+
jest.mock('../requisition-runners/requisition-runner');
5+
6+
const processSendMock = jest.fn();
7+
process.send = processSendMock;
8+
9+
const runMock = jest.fn();
10+
const requisitionRunnerConstructorMock = jest.fn(() => ({run: runMock}));
11+
// @ts-ignore
12+
RequisitionRunner.mockImplementation(requisitionRunnerConstructorMock);
13+
14+
describe('ChildRequisitionRunner', () => {
15+
beforeEach(() => {
16+
processSendMock.mockClear();
17+
requisitionRunnerConstructorMock.mockClear();
18+
runMock.mockClear();
19+
});
20+
21+
it('should run enqueuer runner when a message arrives', async () => {
22+
const requisition = 'value';
23+
const message = {value: 'value'};
24+
await new ChildRequisitionRunner().process(message);
25+
26+
expect(requisitionRunnerConstructorMock).toHaveBeenCalledWith('value');
27+
expect(runMock).toHaveBeenCalled();
28+
});
29+
30+
31+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import {RequisitionRunner} from '../requisition-runners/requisition-runner';
2+
import {ParentReplier} from './parent-replier';
3+
4+
export class ChildRequisitionRunner implements ParentReplier {
5+
public async process(message: any): Promise<boolean> {
6+
await new RequisitionRunner(message.value).run();
7+
return true;
8+
}
9+
}
+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export enum ChildSendingEvents {
2+
PROTOCOLS_LIST = 'PROTOCOLS_LIST',
3+
ASSERTERS_LIST = 'ASSERTERS_LIST',
4+
PROCESS_EXIT = 'PROCESS_EXIT'
5+
}

src/run-as-child/module-adder.test.ts

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import {Configuration} from '../configurations/configuration';
2+
import {ModuleAdder} from './module-adder';
3+
4+
jest.mock('../configurations/configuration');
5+
6+
const addPluginMock = jest.fn();
7+
// @ts-ignore
8+
Configuration.getInstance.mockImplementation(() => {
9+
return {
10+
addPlugin: addPluginMock
11+
};
12+
});
13+
describe('ModuleAdder', () => {
14+
15+
it('should add module when a message arrives', async () => {
16+
const message = {value: 'value'};
17+
await new ModuleAdder().process(message);
18+
19+
expect(addPluginMock).toHaveBeenCalledWith('value');
20+
});
21+
22+
23+
});

src/run-as-child/module-adder.ts

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import {Configuration} from '../configurations/configuration';
2+
import {ParentReplier} from './parent-replier';
3+
4+
export class ModuleAdder implements ParentReplier {
5+
public async process(message: any): Promise<boolean> {
6+
Configuration.getInstance().addPlugin(message.value);
7+
return true;
8+
}
9+
10+
}

0 commit comments

Comments
 (0)