blob: 0b2a2172731c94774cd4985d18cae93368511c79 [file] [log] [blame]
Illyoung Choi59820ed2019-06-24 17:01:00 -07001/*
2 * Copyright 2019-present Open Networking Foundation
3
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7
8 * http://www.apache.org/licenses/LICENSE-2.0
9
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17
18(function () {
19 'use strict';
20
21 const path = require('path');
22 const chai = require('chai');
23 const expect = chai.expect;
24 const sinonChai = require('sinon-chai');
25 chai.use(sinonChai);
26 const io = require('socket.io-client');
27 const async = require('async');
28 const _ = require('lodash');
29 const server = require('../src/server.js');
30 const port = 4000;
31 const eventrouter = require('../src/controllers/eventrouter.js');
32 const essenceLoader = require('../src/workflows/loader.js');
33 const essenceFileName = path.join(__dirname, 'test_multi_workflow_essence.json');
34
35 var probeClient;
36 var workflowManagerClients = [];
37 var workflowRunClients = [];
38 var workflowIds = [];
39 var workflowRunInfos = [];
40
41 var receivedKickstartMessages = [[],[]];
42
Illyoung Choic707c052019-07-18 13:50:49 -070043 describe('Event Router test', function() {
Illyoung Choie3ce4cf2019-06-28 11:07:47 -070044 this.slow(5000);
Illyoung Choi59820ed2019-06-24 17:01:00 -070045
46 before(function() {
47 // Start our server
48 server.start(port);
49 });
50
51 after(function() {
52 server.stop();
53 });
54
55 beforeEach(function(done) {
56 async.series([
57 (callback) => {
58 // connect a probe to the server
59 // to send events for test
60 probeClient = io.connect(`http://localhost:${port}`, {
61 query: 'id=probe_id&type=probe' +
62 '&name=probe@xos.org'
63 });
64
65 probeClient.on('connect', () => {
66 callback(null, true);
67 });
68 return;
69 },
70 (callback) => {
71 // connect first workflow manager to the server
72 // this manager will kickstart a workflow
Illyoung Choic707c052019-07-18 13:50:49 -070073 let workflowManagerClient1 = io.connect(`http://localhost:${port}`, {
Illyoung Choi59820ed2019-06-24 17:01:00 -070074 query: 'id=workflow_manager_id1&type=workflow_manager' +
75 '&name=manager1@xos.org'
76 });
77
Illyoung Choic707c052019-07-18 13:50:49 -070078 workflowManagerClient1.on(eventrouter.serviceEvents.WORKFLOW_KICKSTART, (message) => {
Illyoung Choi59820ed2019-06-24 17:01:00 -070079 // save it for check
80 receivedKickstartMessages[0].push(message);
81
82 // save workflow_id and workflow_run_id
83 workflowRunInfos.push({
84 workflowId: message.workflow_id,
85 workflowRunId: message.workflow_run_id
86 });
87
88 setTimeout(() => {
89 // call-back
Illyoung Choic707c052019-07-18 13:50:49 -070090 workflowManagerClient1.emit(eventrouter.serviceEvents.WORKFLOW_REPORT_NEW_RUN, {
Illyoung Choi59820ed2019-06-24 17:01:00 -070091 workflow_id: message.workflow_id,
92 workflow_run_id: message.workflow_run_id
93 })
Illyoung Choie3ce4cf2019-06-28 11:07:47 -070094 }, 1000);
Illyoung Choi59820ed2019-06-24 17:01:00 -070095 });
96
Illyoung Choic707c052019-07-18 13:50:49 -070097 workflowManagerClient1.on('connect', () => {
Illyoung Choi59820ed2019-06-24 17:01:00 -070098 callback(null, true);
99 });
100
Illyoung Choic707c052019-07-18 13:50:49 -0700101 workflowManagerClients.push(workflowManagerClient1);
Illyoung Choi59820ed2019-06-24 17:01:00 -0700102 return;
103 },
104 (callback) => {
105 // connect second workflow manager to the server
106 // this manager will not kickstart a workflow
Illyoung Choic707c052019-07-18 13:50:49 -0700107 let workflowManagerClient2 = io.connect(`http://localhost:${port}`, {
Illyoung Choi59820ed2019-06-24 17:01:00 -0700108 query: 'id=workflow_manager_id2&type=workflow_manager' +
109 '&name=manager2@xos.org'
110 });
111
Illyoung Choic707c052019-07-18 13:50:49 -0700112 workflowManagerClient2.on(eventrouter.serviceEvents.WORKFLOW_KICKSTART, (message) => {
Illyoung Choi59820ed2019-06-24 17:01:00 -0700113 receivedKickstartMessages[1].push(message);
Illyoung Choib4fc0d82019-07-16 10:29:39 -0700114
115 setTimeout(() => {
116 // call-back
Illyoung Choic707c052019-07-18 13:50:49 -0700117 workflowManagerClient2.emit(eventrouter.serviceEvents.WORKFLOW_REPORT_NEW_RUN, {
Illyoung Choib4fc0d82019-07-16 10:29:39 -0700118 workflow_id: message.workflow_id,
119 workflow_run_id: message.workflow_run_id
120 })
121 }, 1000);
Illyoung Choi59820ed2019-06-24 17:01:00 -0700122 });
123
Illyoung Choic707c052019-07-18 13:50:49 -0700124 workflowManagerClient2.on('connect', () => {
Illyoung Choi59820ed2019-06-24 17:01:00 -0700125 callback(null, true);
126 });
127
Illyoung Choic707c052019-07-18 13:50:49 -0700128 workflowManagerClients.push(workflowManagerClient2);
Illyoung Choi59820ed2019-06-24 17:01:00 -0700129 return;
130 },
131 (callback) => {
132 let essence = essenceLoader.loadEssence(essenceFileName, true);
133
134 // register the workflow
Illyoung Choib4fc0d82019-07-16 10:29:39 -0700135 workflowManagerClients[0].emit(eventrouter.serviceEvents.WORKFLOW_REGISTER_ESSENCE, {
Illyoung Choie3ce4cf2019-06-28 11:07:47 -0700136 essence: essence
137 });
Illyoung Choi59820ed2019-06-24 17:01:00 -0700138
139 _.forOwn(essence, (_value, workflowId) => {
140 // save
141 workflowIds.push(workflowId);
142 });
143
144 // handle return
145 workflowManagerClients[0].on(
Illyoung Choib4fc0d82019-07-16 10:29:39 -0700146 eventrouter.serviceEvents.WORKFLOW_REGISTER_ESSENCE,
Illyoung Choi59820ed2019-06-24 17:01:00 -0700147 (workflowRegResult) => {
148 callback(null, workflowRegResult);
149 }
150 );
151 return;
152 }
153 ],
154 function(err, results) {
155 // we do not actually check results;
156 if(results.includes(false)) {
157 done.fail(err);
158 }
159 else {
160 done();
161 }
162 });
163 return;
164 });
165
Illyoung Choic707c052019-07-18 13:50:49 -0700166 afterEach(function(done) {
167 this.timeout(5000);
168
Illyoung Choi59820ed2019-06-24 17:01:00 -0700169 // remove workflow runs
170 _.forOwn(workflowRunInfos, (workflowRunInfo) => {
Illyoung Choib4fc0d82019-07-16 10:29:39 -0700171 workflowManagerClients[0].emit(server.serviceEvents.WORKFLOW_REMOVE_RUN, {
Illyoung Choi59820ed2019-06-24 17:01:00 -0700172 workflow_id: workflowRunInfo.workflowId,
173 workflow_run_id: workflowRunInfo.workflowRunId
174 });
175 });
176 workflowRunInfos.length = 0;
177
178 // remove workflows
179 _.forOwn(workflowIds, (workflowId) => {
Illyoung Choie3ce4cf2019-06-28 11:07:47 -0700180 workflowManagerClients[0].emit(server.serviceEvents.WORKFLOW_REMOVE, {
181 workflow_id: workflowId
182 });
Illyoung Choi59820ed2019-06-24 17:01:00 -0700183 });
184 workflowIds.length = 0;
185
186 // remove message store
187 receivedKickstartMessages.forEach((receivedKickstartMessageStore) => {
188 receivedKickstartMessageStore.length = 0;
189 });
190
191 // disconnect clients
192 workflowManagerClients.forEach((workflowManagerClient) => {
193 if(workflowManagerClient.connected) {
194 workflowManagerClient.disconnect();
195 }
196 });
197 workflowManagerClients.length = 0;
198
199 workflowRunClients.forEach((workflowRunClient) => {
200 if(workflowRunClient.connected) {
201 workflowRunClient.disconnect();
202 }
203 });
204 workflowRunClients.length = 0;
205
206 if(probeClient.connected) {
207 probeClient.disconnect();
208 }
209 probeClient = null;
Illyoung Choic707c052019-07-18 13:50:49 -0700210
211 setTimeout(() => {
212 // this gives enough time to complete disconnection for clients
213 done();
214 }, 2000);
Illyoung Choi59820ed2019-06-24 17:01:00 -0700215 });
216
217 it('should have two workflows', function(done) {
218 workflowManagerClients[0].on(eventrouter.serviceEvents.WORKFLOW_LIST, (result) => {
219 let workflowsList = result.result;
220 expect(workflowsList.length).to.equal(2);
221 workflowsList.forEach((workflowIdInList) => {
222 expect(workflowIds).to.includes(workflowIdInList);
223 });
224 done();
225 });
226
227 workflowManagerClients[0].emit(eventrouter.serviceEvents.WORKFLOW_LIST, {});
228 });
229
230 it('all managers should receive kickstart messages', function(done) {
Illyoung Choib4fc0d82019-07-16 10:29:39 -0700231 this.timeout(5000);
232
Illyoung Choi59820ed2019-06-24 17:01:00 -0700233 // kickstart the workflow
234 probeClient.emit('onu.events', {serialNumber: 'testSerialXXX', other: 'test_other_field'});
235 setTimeout(() => {
236 expect(receivedKickstartMessages.length, 'num of message stores').to.equal(2);
237 receivedKickstartMessages.forEach((receivedKickstartMessageStore) => {
238 expect(receivedKickstartMessageStore.length, 'num of messages in a store').to.equal(1);
239 });
240 done();
Illyoung Choib4fc0d82019-07-16 10:29:39 -0700241 }, 2000);
Illyoung Choi59820ed2019-06-24 17:01:00 -0700242 });
243
244 it('should have only one workflow run', function(done) {
245 this.timeout(5000);
246
247 // kickstart the workflow
248 probeClient.emit('onu.events', {serialNumber: 'testSerialXXX', other: 'test_other_field'});
249 setTimeout(() => {
250 // kickstart will take 2 seconds roughly
251 expect(workflowRunInfos.length, 'num of workflow runs').to.equal(1);
252 // the workflow must be 'should_be_called'
253 expect(workflowRunInfos[0].workflowId, 'workflow id').to.equal('should_be_called');
254 done();
Illyoung Choie3ce4cf2019-06-28 11:07:47 -0700255 }, 2000);
Illyoung Choi59820ed2019-06-24 17:01:00 -0700256 });
257
Illyoung Choie3ce4cf2019-06-28 11:07:47 -0700258 it('should read an event that is used for workflow kickstart', function(done) {
Illyoung Choi59820ed2019-06-24 17:01:00 -0700259 this.timeout(5000);
260
261 // kickstart the workflow
262 probeClient.emit('onu.events', {serialNumber: 'testSerialXXX', other: 'test_other_field'});
263 setTimeout(() => {
264 // kickstart will take 2 seconds roughly
265 expect(workflowRunInfos.length, 'num of workflow runs').to.equal(1);
266 // the workflow must be 'should_be_called'
267 expect(workflowRunInfos[0].workflowId, 'workflow id').to.equal('should_be_called');
268
269 // connect a workflow run client to the server
270 let workflowRunClient = io.connect(`http://localhost:${port}`, {
271 query: 'id=workflow_run_id1&type=workflow_run' +
272 `&workflow_id=${workflowRunInfos[0].workflowId}` +
273 `&workflow_run_id=${workflowRunInfos[0].workflowRunId}` +
274 '&name=run1@xos.org'
275 });
276 workflowRunClients.push(workflowRunClient);
277
278 workflowRunClient.on('connect', () => {
279 workflowRunClient.emit(eventrouter.serviceEvents.WORKFLOW_RUN_FETCH_EVENT, {
280 workflow_id: workflowRunInfos[0].workflowId,
281 workflow_run_id: workflowRunInfos[0].workflowRunId,
282 task_id: 'onu_event_handler',
283 topic: 'onu.events'
284 });
285 });
286
287 workflowRunClient.on(eventrouter.serviceEvents.WORKFLOW_RUN_FETCH_EVENT, (result) => {
288 let event = result.result;
289 expect(event.topic).to.equal('onu.events');
290 expect(event.message.serialNumber).to.equal('testSerialXXX');
291 done();
292 });
Illyoung Choie3ce4cf2019-06-28 11:07:47 -0700293 }, 2000);
Illyoung Choi59820ed2019-06-24 17:01:00 -0700294 });
295
Illyoung Choie3ce4cf2019-06-28 11:07:47 -0700296 it('should map a workflow run using key-field', function(done) {
297 this.timeout(5000);
Illyoung Choi59820ed2019-06-24 17:01:00 -0700298
Illyoung Choie3ce4cf2019-06-28 11:07:47 -0700299 // kickstart the workflow
300 probeClient.emit(
301 'onu.events',
302 {serialNumber: 'testSerialXXX', other: 'test_other_field'}
303 );
304 probeClient.emit(
305 'datamodel.AttWorkflowDriverServiceInstance',
306 {operation: 'update', serialNumber: 'testSerialXXX', other: 'updated_test_other_field'}
307 );
Illyoung Choi59820ed2019-06-24 17:01:00 -0700308 setTimeout(() => {
Illyoung Choie3ce4cf2019-06-28 11:07:47 -0700309 // kickstart will take 2 seconds roughly
310 expect(workflowRunInfos.length, 'num of workflow runs').to.equal(1);
311 // the workflow must be 'should_be_called'
312 expect(workflowRunInfos[0].workflowId, 'workflow id').to.equal('should_be_called');
313
314 // connect a workflow run client to the server
315 let workflowRunClient = io.connect(`http://localhost:${port}`, {
316 query: 'id=workflow_run_id1&type=workflow_run' +
317 `&workflow_id=${workflowRunInfos[0].workflowId}` +
318 `&workflow_run_id=${workflowRunInfos[0].workflowRunId}` +
319 '&name=run1@xos.org'
320 });
321 workflowRunClients.push(workflowRunClient);
322
323 workflowRunClient.on('connect', () => {
324 // check message counts
325 workflowRunClient.emit(eventrouter.serviceEvents.WORKFLOW_RUN_COUNT_EVENTS, {
326 workflow_id: workflowRunInfos[0].workflowId,
327 workflow_run_id: workflowRunInfos[0].workflowRunId
328 });
329 });
330
331 let eventRaised = 0;
332 workflowRunClient.on(eventrouter.serviceEvents.WORKFLOW_RUN_COUNT_EVENTS, (result) => {
333 let count = result.result;
334 expect(count, 'number of events queued').to.equal(2);
335
336 // fetch two events
337 workflowRunClient.emit(eventrouter.serviceEvents.WORKFLOW_RUN_FETCH_EVENT, {
338 workflow_id: workflowRunInfos[0].workflowId,
339 workflow_run_id: workflowRunInfos[0].workflowRunId,
340 task_id: 'onu_event_handler',
341 topic: 'onu.events'
342 });
343 eventRaised++;
344
345 workflowRunClient.emit(eventrouter.serviceEvents.WORKFLOW_RUN_FETCH_EVENT, {
346 workflow_id: workflowRunInfos[0].workflowId,
347 workflow_run_id: workflowRunInfos[0].workflowRunId,
348 task_id: 'onu_model_event_handler',
349 topic: 'datamodel.AttWorkflowDriverServiceInstance'
350 });
351 eventRaised++;
352 });
353
354 workflowRunClient.on(eventrouter.serviceEvents.WORKFLOW_RUN_FETCH_EVENT, (result) => {
355 let event = result.result;
356 if(eventRaised === 2) {
357 expect(event.topic).to.equal('onu.events');
358 expect(event.message.serialNumber).to.equal('testSerialXXX');
359 }
360 else if(eventRaised === 1) {
361 expect(event.topic).to.equal('datamodel.AttWorkflowDriverServiceInstance');
362 expect(event.message.serialNumber).to.equal('testSerialXXX');
363 }
364 eventRaised--;
365
366 if(eventRaised === 0) {
367 done();
368 }
369 });
370 }, 2000);
Illyoung Choi59820ed2019-06-24 17:01:00 -0700371 });
Illyoung Choi59820ed2019-06-24 17:01:00 -0700372 });
Illyoung Choib4fc0d82019-07-16 10:29:39 -0700373})();