blob: 82261f73f5420afde3b0bf54acdb8b2cf9251b96 [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 Choi16c6d4f2019-07-24 18:09:26 -0700171 workflowManagerClients[0].emit(eventrouter.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 Choi16c6d4f2019-07-24 18:09:26 -0700180 workflowManagerClients[0].emit(eventrouter.serviceEvents.WORKFLOW_REMOVE, {
Illyoung Choie3ce4cf2019-06-28 11:07:47 -0700181 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
Illyoung Choi16c6d4f2019-07-24 18:09:26 -0700234 probeClient.emit(eventrouter.serviceEvents.EVENT_EMIT, {
235 topic: 'onu.events',
236 message: {serialNumber: 'testSerialXXX', other: 'test_other_field'}
237 });
Illyoung Choi59820ed2019-06-24 17:01:00 -0700238 setTimeout(() => {
239 expect(receivedKickstartMessages.length, 'num of message stores').to.equal(2);
240 receivedKickstartMessages.forEach((receivedKickstartMessageStore) => {
241 expect(receivedKickstartMessageStore.length, 'num of messages in a store').to.equal(1);
242 });
243 done();
Illyoung Choib4fc0d82019-07-16 10:29:39 -0700244 }, 2000);
Illyoung Choi59820ed2019-06-24 17:01:00 -0700245 });
246
247 it('should have only one workflow run', function(done) {
248 this.timeout(5000);
249
250 // kickstart the workflow
Illyoung Choi16c6d4f2019-07-24 18:09:26 -0700251 probeClient.emit(eventrouter.serviceEvents.EVENT_EMIT, {
252 topic: 'onu.events',
253 message: {serialNumber: 'testSerialXXX', other: 'test_other_field'}
254 });
Illyoung Choi59820ed2019-06-24 17:01:00 -0700255 setTimeout(() => {
256 // kickstart will take 2 seconds roughly
257 expect(workflowRunInfos.length, 'num of workflow runs').to.equal(1);
258 // the workflow must be 'should_be_called'
259 expect(workflowRunInfos[0].workflowId, 'workflow id').to.equal('should_be_called');
260 done();
Illyoung Choie3ce4cf2019-06-28 11:07:47 -0700261 }, 2000);
Illyoung Choi59820ed2019-06-24 17:01:00 -0700262 });
263
Illyoung Choie3ce4cf2019-06-28 11:07:47 -0700264 it('should read an event that is used for workflow kickstart', function(done) {
Illyoung Choi59820ed2019-06-24 17:01:00 -0700265 this.timeout(5000);
266
267 // kickstart the workflow
Illyoung Choi16c6d4f2019-07-24 18:09:26 -0700268 probeClient.emit(eventrouter.serviceEvents.EVENT_EMIT, {
269 topic: 'onu.events',
270 message: {serialNumber: 'testSerialXXX', other: 'test_other_field'}
271 });
Illyoung Choi59820ed2019-06-24 17:01:00 -0700272 setTimeout(() => {
273 // kickstart will take 2 seconds roughly
274 expect(workflowRunInfos.length, 'num of workflow runs').to.equal(1);
275 // the workflow must be 'should_be_called'
276 expect(workflowRunInfos[0].workflowId, 'workflow id').to.equal('should_be_called');
277
278 // connect a workflow run client to the server
279 let workflowRunClient = io.connect(`http://localhost:${port}`, {
280 query: 'id=workflow_run_id1&type=workflow_run' +
281 `&workflow_id=${workflowRunInfos[0].workflowId}` +
282 `&workflow_run_id=${workflowRunInfos[0].workflowRunId}` +
283 '&name=run1@xos.org'
284 });
285 workflowRunClients.push(workflowRunClient);
286
287 workflowRunClient.on('connect', () => {
288 workflowRunClient.emit(eventrouter.serviceEvents.WORKFLOW_RUN_FETCH_EVENT, {
289 workflow_id: workflowRunInfos[0].workflowId,
290 workflow_run_id: workflowRunInfos[0].workflowRunId,
291 task_id: 'onu_event_handler',
292 topic: 'onu.events'
293 });
294 });
295
296 workflowRunClient.on(eventrouter.serviceEvents.WORKFLOW_RUN_FETCH_EVENT, (result) => {
297 let event = result.result;
298 expect(event.topic).to.equal('onu.events');
299 expect(event.message.serialNumber).to.equal('testSerialXXX');
300 done();
301 });
Illyoung Choie3ce4cf2019-06-28 11:07:47 -0700302 }, 2000);
Illyoung Choi59820ed2019-06-24 17:01:00 -0700303 });
304
Illyoung Choie3ce4cf2019-06-28 11:07:47 -0700305 it('should map a workflow run using key-field', function(done) {
306 this.timeout(5000);
Illyoung Choi59820ed2019-06-24 17:01:00 -0700307
Illyoung Choie3ce4cf2019-06-28 11:07:47 -0700308 // kickstart the workflow
Illyoung Choi16c6d4f2019-07-24 18:09:26 -0700309 probeClient.emit(eventrouter.serviceEvents.EVENT_EMIT, {
310 topic: 'onu.events',
311 message: {serialNumber: 'testSerialXXX', other: 'test_other_field'}
312 });
313 probeClient.emit(eventrouter.serviceEvents.EVENT_EMIT, {
314 topic: 'datamodel.AttWorkflowDriverServiceInstance',
315 message: {operation: 'update', serialNumber: 'testSerialXXX', other: 'updated_test_other_field'}
316 });
Illyoung Choi59820ed2019-06-24 17:01:00 -0700317 setTimeout(() => {
Illyoung Choie3ce4cf2019-06-28 11:07:47 -0700318 // kickstart will take 2 seconds roughly
319 expect(workflowRunInfos.length, 'num of workflow runs').to.equal(1);
320 // the workflow must be 'should_be_called'
321 expect(workflowRunInfos[0].workflowId, 'workflow id').to.equal('should_be_called');
322
323 // connect a workflow run client to the server
324 let workflowRunClient = io.connect(`http://localhost:${port}`, {
325 query: 'id=workflow_run_id1&type=workflow_run' +
326 `&workflow_id=${workflowRunInfos[0].workflowId}` +
327 `&workflow_run_id=${workflowRunInfos[0].workflowRunId}` +
328 '&name=run1@xos.org'
329 });
330 workflowRunClients.push(workflowRunClient);
331
332 workflowRunClient.on('connect', () => {
333 // check message counts
334 workflowRunClient.emit(eventrouter.serviceEvents.WORKFLOW_RUN_COUNT_EVENTS, {
335 workflow_id: workflowRunInfos[0].workflowId,
336 workflow_run_id: workflowRunInfos[0].workflowRunId
337 });
338 });
339
340 let eventRaised = 0;
341 workflowRunClient.on(eventrouter.serviceEvents.WORKFLOW_RUN_COUNT_EVENTS, (result) => {
342 let count = result.result;
343 expect(count, 'number of events queued').to.equal(2);
344
345 // fetch two events
346 workflowRunClient.emit(eventrouter.serviceEvents.WORKFLOW_RUN_FETCH_EVENT, {
347 workflow_id: workflowRunInfos[0].workflowId,
348 workflow_run_id: workflowRunInfos[0].workflowRunId,
349 task_id: 'onu_event_handler',
350 topic: 'onu.events'
351 });
352 eventRaised++;
353
354 workflowRunClient.emit(eventrouter.serviceEvents.WORKFLOW_RUN_FETCH_EVENT, {
355 workflow_id: workflowRunInfos[0].workflowId,
356 workflow_run_id: workflowRunInfos[0].workflowRunId,
357 task_id: 'onu_model_event_handler',
358 topic: 'datamodel.AttWorkflowDriverServiceInstance'
359 });
360 eventRaised++;
361 });
362
363 workflowRunClient.on(eventrouter.serviceEvents.WORKFLOW_RUN_FETCH_EVENT, (result) => {
364 let event = result.result;
365 if(eventRaised === 2) {
366 expect(event.topic).to.equal('onu.events');
367 expect(event.message.serialNumber).to.equal('testSerialXXX');
368 }
369 else if(eventRaised === 1) {
370 expect(event.topic).to.equal('datamodel.AttWorkflowDriverServiceInstance');
371 expect(event.message.serialNumber).to.equal('testSerialXXX');
372 }
373 eventRaised--;
374
375 if(eventRaised === 0) {
376 done();
377 }
378 });
379 }, 2000);
Illyoung Choi59820ed2019-06-24 17:01:00 -0700380 });
Illyoung Choi59820ed2019-06-24 17:01:00 -0700381 });
Illyoung Choib4fc0d82019-07-16 10:29:39 -0700382})();