blob: 6184f589091538e0c08a4b23e87e5eac53c76cbc [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
43 describe('Workflow kickstart test', function() {
44
45 before(function() {
46 // Start our server
47 server.start(port);
48 });
49
50 after(function() {
51 server.stop();
52 });
53
54 beforeEach(function(done) {
55 async.series([
56 (callback) => {
57 // connect a probe to the server
58 // to send events for test
59 probeClient = io.connect(`http://localhost:${port}`, {
60 query: 'id=probe_id&type=probe' +
61 '&name=probe@xos.org'
62 });
63
64 probeClient.on('connect', () => {
65 callback(null, true);
66 });
67 return;
68 },
69 (callback) => {
70 // connect first workflow manager to the server
71 // this manager will kickstart a workflow
72 let workflowManagerClient = io.connect(`http://localhost:${port}`, {
73 query: 'id=workflow_manager_id1&type=workflow_manager' +
74 '&name=manager1@xos.org'
75 });
76
77 workflowManagerClient.on(eventrouter.serviceEvents.WORKFLOW_KICKSTART, (message) => {
78 // save it for check
79 receivedKickstartMessages[0].push(message);
80
81 // save workflow_id and workflow_run_id
82 workflowRunInfos.push({
83 workflowId: message.workflow_id,
84 workflowRunId: message.workflow_run_id
85 });
86
87 setTimeout(() => {
88 // call-back
89 workflowManagerClient.emit(eventrouter.serviceEvents.WORKFLOW_KICKSTART, {
90 workflow_id: message.workflow_id,
91 workflow_run_id: message.workflow_run_id
92 })
93 }, 2000);
94 });
95
96 workflowManagerClient.on('connect', () => {
97 callback(null, true);
98 });
99
100 workflowManagerClients.push(workflowManagerClient);
101 return;
102 },
103 (callback) => {
104 // connect second workflow manager to the server
105 // this manager will not kickstart a workflow
106 let workflowManagerClient = io.connect(`http://localhost:${port}`, {
107 query: 'id=workflow_manager_id2&type=workflow_manager' +
108 '&name=manager2@xos.org'
109 });
110
111 workflowManagerClient.on(eventrouter.serviceEvents.WORKFLOW_KICKSTART, (message) => {
112 receivedKickstartMessages[1].push(message);
113 });
114
115 workflowManagerClient.on('connect', () => {
116 callback(null, true);
117 });
118
119 workflowManagerClients.push(workflowManagerClient);
120 return;
121 },
122 (callback) => {
123 let essence = essenceLoader.loadEssence(essenceFileName, true);
124
125 // register the workflow
126 workflowManagerClients[0].emit(eventrouter.serviceEvents.WORKFLOW_REG_ESSENCE, essence);
127
128 _.forOwn(essence, (_value, workflowId) => {
129 // save
130 workflowIds.push(workflowId);
131 });
132
133 // handle return
134 workflowManagerClients[0].on(
135 eventrouter.serviceEvents.WORKFLOW_REG_ESSENCE,
136 (workflowRegResult) => {
137 callback(null, workflowRegResult);
138 }
139 );
140 return;
141 }
142 ],
143 function(err, results) {
144 // we do not actually check results;
145 if(results.includes(false)) {
146 done.fail(err);
147 }
148 else {
149 done();
150 }
151 });
152 return;
153 });
154
155 afterEach(function() {
156 // remove workflow runs
157 _.forOwn(workflowRunInfos, (workflowRunInfo) => {
158 workflowManagerClients[0].emit(server.serviceEvents.WORKFLOW_RUN_REMOVE, {
159 workflow_id: workflowRunInfo.workflowId,
160 workflow_run_id: workflowRunInfo.workflowRunId
161 });
162 });
163 workflowRunInfos.length = 0;
164
165 // remove workflows
166 _.forOwn(workflowIds, (workflowId) => {
167 workflowManagerClients[0].emit(server.serviceEvents.WORKFLOW_REMOVE, workflowId);
168 });
169 workflowIds.length = 0;
170
171 // remove message store
172 receivedKickstartMessages.forEach((receivedKickstartMessageStore) => {
173 receivedKickstartMessageStore.length = 0;
174 });
175
176 // disconnect clients
177 workflowManagerClients.forEach((workflowManagerClient) => {
178 if(workflowManagerClient.connected) {
179 workflowManagerClient.disconnect();
180 }
181 });
182 workflowManagerClients.length = 0;
183
184 workflowRunClients.forEach((workflowRunClient) => {
185 if(workflowRunClient.connected) {
186 workflowRunClient.disconnect();
187 }
188 });
189 workflowRunClients.length = 0;
190
191 if(probeClient.connected) {
192 probeClient.disconnect();
193 }
194 probeClient = null;
195 });
196
197 it('should have two workflows', function(done) {
198 workflowManagerClients[0].on(eventrouter.serviceEvents.WORKFLOW_LIST, (result) => {
199 let workflowsList = result.result;
200 expect(workflowsList.length).to.equal(2);
201 workflowsList.forEach((workflowIdInList) => {
202 expect(workflowIds).to.includes(workflowIdInList);
203 });
204 done();
205 });
206
207 workflowManagerClients[0].emit(eventrouter.serviceEvents.WORKFLOW_LIST, {});
208 });
209
210 it('all managers should receive kickstart messages', function(done) {
211 // kickstart the workflow
212 probeClient.emit('onu.events', {serialNumber: 'testSerialXXX', other: 'test_other_field'});
213 setTimeout(() => {
214 expect(receivedKickstartMessages.length, 'num of message stores').to.equal(2);
215 receivedKickstartMessages.forEach((receivedKickstartMessageStore) => {
216 expect(receivedKickstartMessageStore.length, 'num of messages in a store').to.equal(1);
217 });
218 done();
219 }, 500);
220 });
221
222 it('should have only one workflow run', function(done) {
223 this.timeout(5000);
224
225 // kickstart the workflow
226 probeClient.emit('onu.events', {serialNumber: 'testSerialXXX', other: 'test_other_field'});
227 setTimeout(() => {
228 // kickstart will take 2 seconds roughly
229 expect(workflowRunInfos.length, 'num of workflow runs').to.equal(1);
230 // the workflow must be 'should_be_called'
231 expect(workflowRunInfos[0].workflowId, 'workflow id').to.equal('should_be_called');
232 done();
233 }, 3000);
234 });
235
236 it('should be able to read an event that is used for workflow kickstart', function(done) {
237 this.timeout(5000);
238
239 // kickstart the workflow
240 probeClient.emit('onu.events', {serialNumber: 'testSerialXXX', other: 'test_other_field'});
241 setTimeout(() => {
242 // kickstart will take 2 seconds roughly
243 expect(workflowRunInfos.length, 'num of workflow runs').to.equal(1);
244 // the workflow must be 'should_be_called'
245 expect(workflowRunInfos[0].workflowId, 'workflow id').to.equal('should_be_called');
246
247 // connect a workflow run client to the server
248 let workflowRunClient = io.connect(`http://localhost:${port}`, {
249 query: 'id=workflow_run_id1&type=workflow_run' +
250 `&workflow_id=${workflowRunInfos[0].workflowId}` +
251 `&workflow_run_id=${workflowRunInfos[0].workflowRunId}` +
252 '&name=run1@xos.org'
253 });
254 workflowRunClients.push(workflowRunClient);
255
256 workflowRunClient.on('connect', () => {
257 workflowRunClient.emit(eventrouter.serviceEvents.WORKFLOW_RUN_FETCH_EVENT, {
258 workflow_id: workflowRunInfos[0].workflowId,
259 workflow_run_id: workflowRunInfos[0].workflowRunId,
260 task_id: 'onu_event_handler',
261 topic: 'onu.events'
262 });
263 });
264
265 workflowRunClient.on(eventrouter.serviceEvents.WORKFLOW_RUN_FETCH_EVENT, (result) => {
266 let event = result.result;
267 expect(event.topic).to.equal('onu.events');
268 expect(event.message.serialNumber).to.equal('testSerialXXX');
269 done();
270 });
271 }, 3000);
272 });
273
274 /*
275 it('should store user details for a new connection', () => {
276 const eventrouter = require('../src/controllers/eventrouter.js');
277
278 const probe = eventrouter.getClients()['probe_id'];
279 expect(probe.getParams().name).to.equal('probe@xos.org');
280
281 const manager = eventrouter.getClients()['workflow_manager_id'];
282 expect(manager.getParams().name).to.equal('manager@xos.org');
283
284 const run = eventrouter.getClients()['workflow_run_id'];
285 expect(run.getParams().name).to.equal('run@xos.org');
286 });
287
288 it('should not store the same user twice', (done) => {
289 // This test case makes cleaning up process taking long time because it leaves
290 // a client socket. It seems there's no way to release it from server-side.
291
292 // connect a client to the server
293 const client2 = io.connect(`http://localhost:${port}`, {
294 query: 'id=probe_id&type=probe' +
295 '&name=probe@xos.org&value=different_value'
296 });
297
298 // when is connected start testing
299 client2.on('connect', () => {
300 setTimeout(() => {
301 const eventrouter = require('../src/controllers/eventrouter.js');
302 expect(
303 Object.keys(eventrouter.getWorkflowRunClients()).length,
304 'num of workflow run clients'
305 ).to.equal(1);
306 expect(
307 Object.keys(eventrouter.getWorkflowManagerClients()).length,
308 'num of workflow manager clients'
309 ).to.equal(1);
310 expect(
311 Object.keys(eventrouter.getProbeClients()).length,
312 'num of probe clients'
313 ).to.equal(1);
314 expect(
315 Object.keys(eventrouter.getClients()).length,
316 'total num of clients'
317 ).to.equal(3);
318
319 done();
320 }, 100);
321 });
322 });
323
324 it('should remove a user on disconnect', (done) => {
325 workflowManagerClient.disconnect();
326 workflowRunClient.disconnect();
327 probeClient.disconnect();
328
329 // we need to wait for the event to be dispatched
330 setTimeout(() => {
331 const eventrouter = require('../src/controllers/eventrouter.js');
332 expect(
333 Object.keys(eventrouter.getWorkflowRunClients()).length,
334 'num of workflow run clients'
335 ).to.equal(0);
336 expect(
337 Object.keys(eventrouter.getWorkflowManagerClients()).length,
338 'num of workflow manager clients'
339 ).to.equal(0);
340 expect(
341 Object.keys(eventrouter.getProbeClients()).length,
342 'num of probe clients'
343 ).to.equal(0);
344 expect(
345 Object.keys(eventrouter.getClients()).length,
346 'total num of clients'
347 ).to.equal(0);
348 done();
349 }, 100);
350 });
351 */
352 });
353})();