iotagent-node-lib 4.4.0 → 4.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/README.md +67 -272
  2. package/config.js +2 -1
  3. package/doc/README.md +1 -1
  4. package/doc/admin.md +19 -22
  5. package/doc/api.md +621 -155
  6. package/doc/deprecated.md +4 -0
  7. package/doc/devel/architecture.md +5 -135
  8. package/doc/devel/development.md +224 -12
  9. package/doc/getting-started.md +114 -53
  10. package/doc/requirements.txt +1 -1
  11. package/doc/roadmap.md +5 -5
  12. package/docker/Mosquitto/Dockerfile +2 -2
  13. package/docker/Mosquitto/README.md +14 -11
  14. package/lib/commonConfig.js +7 -1
  15. package/lib/constants.js +3 -0
  16. package/lib/fiware-iotagent-lib.js +12 -15
  17. package/lib/jexlTranformsMap.js +3 -1
  18. package/lib/model/dbConn.js +1 -4
  19. package/lib/services/common/alarmManagement.js +3 -0
  20. package/lib/services/devices/deviceRegistryMemory.js +1 -1
  21. package/lib/services/devices/deviceRegistryMongoDB.js +2 -2
  22. package/lib/services/devices/deviceService.js +4 -3
  23. package/lib/services/devices/devices-NGSI-LD.js +5 -5
  24. package/lib/services/devices/devices-NGSI-mixed.js +3 -3
  25. package/lib/services/devices/devices-NGSI-v2.js +5 -5
  26. package/lib/services/groups/groupService.js +1 -1
  27. package/lib/services/ngsi/entities-NGSI-LD.js +321 -571
  28. package/lib/services/ngsi/entities-NGSI-v2.js +348 -281
  29. package/lib/services/ngsi/ngsiService.js +3 -1
  30. package/lib/services/ngsi/subscription-NGSI-LD.js +2 -2
  31. package/lib/services/ngsi/subscription-NGSI-v2.js +2 -2
  32. package/lib/services/northBound/deviceGroupAdministrationServer.js +42 -6
  33. package/lib/services/northBound/deviceProvisioningServer.js +5 -5
  34. package/lib/services/northBound/northboundServer.js +4 -2
  35. package/lib/services/stats/statsRegistry.js +128 -101
  36. package/lib/templates/createDevice.json +0 -24
  37. package/lib/templates/createDeviceLax.json +0 -23
  38. package/lib/templates/deviceGroup.json +1 -25
  39. package/lib/templates/updateDevice.json +0 -24
  40. package/lib/templates/updateDeviceLax.json +0 -23
  41. package/package.json +2 -2
  42. package/scripts/legacy_expression_tool/README.md +0 -1
  43. package/test/functional/README.md +75 -47
  44. package/test/functional/functional-tests-runner.js +9 -4
  45. package/test/functional/functional-tests.js +4 -4
  46. package/test/functional/testCases.js +1251 -257
  47. package/test/functional/testUtils.js +53 -20
  48. package/test/unit/examples/deviceProvisioningRequests/provisionFullDevice.json +1 -13
  49. package/test/unit/examples/deviceProvisioningRequests/updateProvisionDeviceWithApikey.json +4 -0
  50. package/test/unit/examples/groupProvisioningRequests/multipleConfigGroupsCreation.json +44 -0
  51. package/test/unit/examples/groupProvisioningRequests/provisionDuplicateConfigGroup.json +35 -0
  52. package/test/unit/examples/groupProvisioningRequests/provisionFullConfigGroup.json +36 -0
  53. package/test/unit/examples/groupProvisioningRequests/provisionFullConfigGroupAlternate.json +36 -0
  54. package/test/unit/general/deviceService-test.js +102 -0
  55. package/test/unit/general/statistics-service_test.js +1 -74
  56. package/test/unit/mongodb/mongodb-configGroup-registry-test.js +452 -0
  57. package/test/unit/mongodb/mongodb-connectionoptions-test.js +2 -3
  58. package/test/unit/mongodb/mongodb-group-registry-test.js +34 -33
  59. package/test/unit/mongodb/mongodb-service-registry-test.js +477 -0
  60. package/test/unit/ngsi-ld/examples/contextRequests/updateContextExpressionPlugin1a.json +4 -4
  61. package/test/unit/ngsi-ld/examples/contextRequests/updateContextExpressionPlugin2.json +22 -22
  62. package/test/unit/ngsi-ld/examples/contextRequests/updateContextExpressionPlugin29.json +4 -4
  63. package/test/unit/ngsi-ld/examples/contextRequests/updateContextExpressionPlugin32.json +14 -15
  64. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin1.json +23 -23
  65. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin15.json +0 -5
  66. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin4.json +11 -16
  67. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin5.json +23 -28
  68. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin6.json +8 -13
  69. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin7.json +0 -5
  70. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin8.json +24 -29
  71. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityTimestampPlugin2.json +12 -17
  72. package/test/unit/ngsi-ld/examples/contextRequests/updateContextStaticLinkedAttributes.json +12 -10
  73. package/test/unit/ngsi-ld/expressions/jexlBasedTransformations-test.js +0 -102
  74. package/test/unit/ngsi-ld/plugins/multientity-plugin_test.js +4 -5
  75. package/test/unit/ngsi-ld/provisioning/device-update-registration_test.js +5 -5
  76. package/test/unit/ngsi-ld/provisioning/listProvisionedDevices-test.js +0 -4
  77. package/test/unit/ngsiv2/general/deviceService-test.js +94 -1
  78. package/test/unit/ngsiv2/general/iotam-autoregistration-test.js +195 -0
  79. package/test/unit/ngsiv2/provisioning/device-group-api-test.js +259 -0
  80. package/test/unit/ngsiv2/provisioning/device-provisioning-configGroup-api_test.js +1189 -0
  81. package/test/unit/ngsiv2/provisioning/device-update-registration_test.js +6 -6
  82. package/test/unit/ngsiv2/provisioning/listProvisionedDevices-test.js +0 -4
  83. package/test/unit/ngsiv2/provisioning/updateProvisionedDevices-test.js +35 -0
  84. package/test/unit/statsRegistry/openmetrics-test.js +167 -0
  85. package/lib/templates/queryContext.json +0 -25
  86. package/test/unit/examples/deviceProvisioningRequests/provisionBidirectionalDevice.json +0 -35
  87. package/test/unit/examples/deviceProvisioningRequests/provisionDeviceBidirectionalGroup.json +0 -17
  88. package/test/unit/examples/groupProvisioningRequests/bidirectionalGroup.json +0 -31
  89. package/test/unit/general/statistics-persistence_test.js +0 -121
  90. package/test/unit/ngsi-ld/examples/contextRequests/createBidirectionalDevice.json +0 -17
  91. package/test/unit/ngsi-ld/examples/contextRequests/updateContextProcessTimestamp.json +0 -12
  92. package/test/unit/ngsi-ld/examples/subscriptionRequests/bidirectionalNotification.json +0 -13
  93. package/test/unit/ngsi-ld/examples/subscriptionRequests/bidirectionalNotificationWithDatasetId.json +0 -21
  94. package/test/unit/ngsi-ld/examples/subscriptionRequests/bidirectionalNotificationWithMetadata.json +0 -17
  95. package/test/unit/ngsi-ld/examples/subscriptionRequests/bidirectionalSubscriptionRequest.json +0 -23
  96. package/test/unit/ngsi-ld/plugins/timestamp-processing-plugin_test.js +0 -132
  97. package/test/unit/ngsiv2/examples/contextRequests/createBidirectionalDevice.json +0 -8
  98. package/test/unit/ngsiv2/examples/subscriptionRequests/bidirectionalNotification.json +0 -13
  99. package/test/unit/ngsiv2/examples/subscriptionRequests/bidirectionalNotificationWithMetadata.json +0 -19
  100. package/test/unit/ngsiv2/examples/subscriptionRequests/bidirectionalSubscriptionRequest.json +0 -24
@@ -98,28 +98,61 @@ function sendMeasureIotaLib(measure, provision) {
98
98
  * @param {Object} json
99
99
  * @returns {Array} measures
100
100
  */
101
- function jsonToIotaMeasures(json) {
102
- let measures = [];
103
- for (let key in json) {
104
- /* eslint-disable-next-line no-prototype-builtins */
105
- if (json.hasOwnProperty(key)) {
106
- let measure = {
107
- name: key,
108
- value: json[key]
109
- };
110
- // A bit of Magic. If the key is TimeInstant, we set the type to DateTime.
111
- // When sending the data through iot
112
- if (key === 'TimeInstant') {
113
- measure.type = 'DateTime';
114
- } else {
115
- // Although the type is not meaningfull and we could have picked any string for this,
116
- // we have aligned with DEFAULT_ATTRIBUTE_TYPE constant in IOTA-JSON and IOTA-UL repositories
117
- measure.type = 'Text';
101
+ function jsonToIotaMeasures(originJson) {
102
+ // FIXME: maybe this could be refactored to use less code
103
+ if (originJson && originJson[0]) {
104
+ // multimeasure case
105
+ let finalMeasures = [];
106
+
107
+ for (let json of originJson) {
108
+ let measures = [];
109
+ for (let key in json) {
110
+ /* eslint-disable-next-line no-prototype-builtins */
111
+ if (json.hasOwnProperty(key)) {
112
+ let measure = {
113
+ name: key,
114
+ value: json[key]
115
+ };
116
+ // A bit of Magic. If the key is TimeInstant, we set the type to DateTime.
117
+ // When sending the data through iot
118
+ if (key === 'TimeInstant') {
119
+ measure.type = 'DateTime';
120
+ } else {
121
+ // Although the type is not meaningfull and we could have picked any string for this,
122
+ // we have aligned with DEFAULT_ATTRIBUTE_TYPE constant in IOTA-JSON and IOTA-UL repositories
123
+ measure.type = 'Text';
124
+ }
125
+ measures.push(measure);
126
+ }
127
+ }
128
+ finalMeasures.push(measures);
129
+ }
130
+ return finalMeasures;
131
+ } else {
132
+ let json = originJson;
133
+
134
+ let measures = [];
135
+ for (let key in json) {
136
+ /* eslint-disable-next-line no-prototype-builtins */
137
+ if (json.hasOwnProperty(key)) {
138
+ let measure = {
139
+ name: key,
140
+ value: json[key]
141
+ };
142
+ // A bit of Magic. If the key is TimeInstant, we set the type to DateTime.
143
+ // When sending the data through iot
144
+ if (key === 'TimeInstant') {
145
+ measure.type = 'DateTime';
146
+ } else {
147
+ // Although the type is not meaningfull and we could have picked any string for this,
148
+ // we have aligned with DEFAULT_ATTRIBUTE_TYPE constant in IOTA-JSON and IOTA-UL repositories
149
+ measure.type = 'Text';
150
+ }
151
+ measures.push(measure);
118
152
  }
119
- measures.push(measure);
120
153
  }
154
+ return measures;
121
155
  }
122
- return measures;
123
156
  }
124
157
 
125
158
  /**
@@ -170,7 +203,7 @@ async function testCase(measure, expectation, provision, env, config, type, tran
170
203
  let receivedContext = [];
171
204
  let cbMockRoute = '';
172
205
  // Set the correct route depending if the test is multientity or not
173
- if (type === 'multientity') {
206
+ if (type === 'multientity' || type === 'multimeasure') {
174
207
  cbMockRoute = '/v2/op/update';
175
208
  } else {
176
209
  cbMockRoute = '/v2/entities?options=upsert';
@@ -25,19 +25,7 @@
25
25
  {
26
26
  "name":"location",
27
27
  "type":"geo:point",
28
- "expression": "${latitude}, ${longitude}",
29
- "reverse": [
30
- {
31
- "object_id":"latitude",
32
- "type": "string",
33
- "expression": "${trim(substr(@location, indexOf(@location, \",\") + 1, length(@location)))}"
34
- },
35
- {
36
- "object_id":"longitude",
37
- "type": "string",
38
- "expression": "${trim(substr(@location, 0, indexOf(@location, \",\")))}"
39
- }
40
- ]
28
+ "expression": "${latitude}, ${longitude}"
41
29
  }
42
30
  ],
43
31
  "static_attributes": [],
@@ -0,0 +1,4 @@
1
+ {
2
+ "apikey": "APIKEY2",
3
+ "timezone": "Europe/Madrid"
4
+ }
@@ -0,0 +1,44 @@
1
+ {
2
+ "groups": [
3
+ {
4
+ "resource": "/deviceTest",
5
+ "apikey": "801230BJKL23Y9090DSFL123HJK09H324HV8732",
6
+ "entity_type": "Light",
7
+ "trust": "8970A9078A803H3BL98PINEQRW8342HBAMS",
8
+ "cbHost": "http://unexistentHost:1026",
9
+ "commands": [
10
+ {
11
+ "name": "wheel1",
12
+ "type": "Wheel"
13
+ }
14
+ ],
15
+ "lazy": [
16
+ {
17
+ "name": "luminescence",
18
+ "type": "Lumens"
19
+ }
20
+ ],
21
+ "attributes": [
22
+ {
23
+ "name": "status",
24
+ "type": "Boolean"
25
+ }
26
+ ]
27
+ },
28
+ {
29
+ "resource": "/deviceTest",
30
+ "apikey": "23HJK3Y9090DSFL173209HV8801232",
31
+ "entity_type": "Termometer",
32
+ "trust": "BL9803H3QRW8342HBAMS8A8",
33
+ "cbHost": "http://unexistentHost:1026",
34
+ "commands": [
35
+ {
36
+ "name": "temperature",
37
+ "type": "degrees"
38
+ }
39
+ ],
40
+ "lazy": [],
41
+ "attributes": []
42
+ }
43
+ ]
44
+ }
@@ -0,0 +1,35 @@
1
+ {
2
+ "groups": [
3
+ {
4
+ "resource": "/deviceDuplicateGroup",
5
+ "apikey": "JK09H3L12K09H3L123HJK0732L123HJK38K09H3",
6
+ "entity_type": "CommandMachinery",
7
+ "trust": "8970A9078A803H3BL98PINEQRW8342HBAMS",
8
+ "commands": [
9
+ {
10
+ "name": "wheel1",
11
+ "type": "Wheel"
12
+ }
13
+ ],
14
+ "lazy": [
15
+ {
16
+ "name": "luminescence",
17
+ "type": "Lumens"
18
+ }
19
+ ],
20
+ "attributes": [
21
+ {
22
+ "name": "status",
23
+ "type": "Boolean"
24
+ }
25
+ ],
26
+ "static_attributes": [
27
+ {
28
+ "name": "bootstrapServer",
29
+ "type": "Address",
30
+ "value": "127.0.0.1"
31
+ }
32
+ ]
33
+ }
34
+ ]
35
+ }
@@ -0,0 +1,36 @@
1
+ {
2
+ "groups": [
3
+ {
4
+ "resource": "/deviceTest",
5
+ "apikey": "801230BJKL23Y9090DSFL123HJK09H324HV8732",
6
+ "entity_type": "SensorMachine",
7
+ "trust": "8970A9078A803H3BL98PINEQRW8342HBAMS",
8
+ "cbHost": "http://unexistentHost:1026",
9
+ "commands": [
10
+ {
11
+ "name": "wheel1",
12
+ "type": "Wheel"
13
+ }
14
+ ],
15
+ "lazy": [
16
+ {
17
+ "name": "luminescence",
18
+ "type": "Lumens"
19
+ }
20
+ ],
21
+ "attributes": [
22
+ {
23
+ "name": "status",
24
+ "type": "Boolean"
25
+ }
26
+ ],
27
+ "static_attributes": [
28
+ {
29
+ "name": "bootstrapServer",
30
+ "type": "Address",
31
+ "value": "127.0.0.1"
32
+ }
33
+ ]
34
+ }
35
+ ]
36
+ }
@@ -0,0 +1,36 @@
1
+ {
2
+ "groups": [
3
+ {
4
+ "resource": "/deviceTest",
5
+ "apikey": "754KL23Y9090DSFL123HSFL12380KL23Y2",
6
+ "entity_type": "AnotherMachine",
7
+ "trust": "8970A9078A803H3BL98PINEQRW8342HBAMS",
8
+ "cbHost": "http://unexistentHost:1026",
9
+ "commands": [
10
+ {
11
+ "name": "wheel1",
12
+ "type": "Wheel"
13
+ }
14
+ ],
15
+ "lazy": [
16
+ {
17
+ "name": "luminescence",
18
+ "type": "Lumens"
19
+ }
20
+ ],
21
+ "attributes": [
22
+ {
23
+ "name": "status",
24
+ "type": "Boolean"
25
+ }
26
+ ],
27
+ "static_attributes": [
28
+ {
29
+ "name": "bootstrapServer",
30
+ "type": "Address",
31
+ "value": "127.0.0.1"
32
+ }
33
+ ]
34
+ }
35
+ ]
36
+ }
@@ -153,6 +153,36 @@ const groupCreation = {
153
153
  'fiware-servicepath': '/testingPath'
154
154
  }
155
155
  };
156
+
157
+ const configGroupCreation = {
158
+ url: 'http://localhost:' + iotAgentConfig.server.port + '/iot/groups',
159
+ method: 'POST',
160
+ json: {
161
+ groups: [
162
+ {
163
+ resource: '',
164
+ apikey: '801230BJKL23Y9090DSFL123HJK09H324HV8732',
165
+ entity_type: 'TheLightType',
166
+ trust: '8970A9078A803H3BL98PINEQRW8342HBAMS',
167
+ cbHost: 'http://192.168.1.1:1026',
168
+ commands: [],
169
+ lazy: [],
170
+ attributes: [
171
+ {
172
+ name: 'status',
173
+ type: 'Boolean'
174
+ }
175
+ ],
176
+ static_attributes: []
177
+ }
178
+ ]
179
+ },
180
+ headers: {
181
+ 'fiware-service': 'testservice',
182
+ 'fiware-servicepath': '/testingPath'
183
+ }
184
+ };
185
+
156
186
  const deviceCreation = {
157
187
  url: 'http://localhost:' + iotAgentConfig.server.port + '/iot/devices',
158
188
  method: 'POST',
@@ -180,6 +210,7 @@ describe('NGSI-v2 - Device Service: utils', function () {
180
210
  async.series([iotAgentLib.clearAll, iotAgentLib.deactivate], done);
181
211
  });
182
212
 
213
+ // #FIXME1649: this test will be removed if at the end /iot/services API (now Deprecated) is removed
183
214
  describe('When an existing device tries to be retrieved with retrieveOrCreate()', function () {
184
215
  beforeEach(function (done) {
185
216
  contextBrokerMock = nock('http://192.168.1.1:1026')
@@ -213,6 +244,41 @@ describe('NGSI-v2 - Device Service: utils', function () {
213
244
  });
214
245
  });
215
246
 
247
+ describe('When an existing device tries to be retrieved with retrieveOrCreate()', function () {
248
+ beforeEach(function (done) {
249
+ contextBrokerMock = nock('http://192.168.1.1:1026')
250
+ .matchHeader('fiware-service', 'testservice')
251
+ .matchHeader('fiware-servicepath', '/testingPath')
252
+ .post('/v2/registrations')
253
+ .reply(201, null, { Location: '/v2/registrations/6319a7f5254b05844116584d' });
254
+
255
+ contextBrokerMock
256
+ .matchHeader('fiware-service', 'testservice')
257
+ .matchHeader('fiware-servicepath', '/testingPath')
258
+ .post('/v2/entities?options=upsert')
259
+ .reply(204);
260
+
261
+ async.series(
262
+ [request.bind(request, configGroupCreation), request.bind(request, deviceCreation)],
263
+ function (error, results) {
264
+ done();
265
+ }
266
+ );
267
+ });
268
+
269
+ it('should return the existing device', function (done) {
270
+ iotAgentLib.retrieveDevice('Light1', '801230BJKL23Y9090DSFL123HJK09H324HV8732', function (error, device) {
271
+ should.not.exist(error);
272
+ should.exist(device);
273
+
274
+ device.id.should.equal('Light1');
275
+ done();
276
+ });
277
+ });
278
+ });
279
+
280
+ // #FIXME1649: this test will be removed if at the end /iot/services API (now Deprecated) is removed
281
+
216
282
  describe('When an unexisting device tries to be retrieved for an existing APIKey', function () {
217
283
  beforeEach(function (done) {
218
284
  contextBrokerMock = nock('http://192.168.1.1:1026')
@@ -249,6 +315,42 @@ describe('NGSI-v2 - Device Service: utils', function () {
249
315
  });
250
316
  });
251
317
 
318
+ describe('When an unexisting device tries to be retrieved for an existing APIKey', function () {
319
+ beforeEach(function (done) {
320
+ contextBrokerMock = nock('http://192.168.1.1:1026')
321
+ .matchHeader('fiware-service', 'testservice')
322
+ .matchHeader('fiware-servicepath', '/testingPath')
323
+ .post('/v2/registrations')
324
+ .reply(201, null, { Location: '/v2/registrations/6319a7f5254b05844116584d' });
325
+
326
+ contextBrokerMock
327
+ .matchHeader('fiware-service', 'testservice')
328
+ .matchHeader('fiware-servicepath', '/testingPath')
329
+ .post('/v2/entities?options=upsert')
330
+ .reply(204);
331
+
332
+ async.series([request.bind(request, configGroupCreation)], function (error, results) {
333
+ done();
334
+ });
335
+ });
336
+
337
+ it('should register the device and return it', function (done) {
338
+ iotAgentLib.retrieveDevice(
339
+ 'UNEXISTENT_DEV',
340
+ '801230BJKL23Y9090DSFL123HJK09H324HV8732',
341
+ function (error, device) {
342
+ should.not.exist(error);
343
+ should.exist(device);
344
+
345
+ device.id.should.equal('UNEXISTENT_DEV');
346
+ should.exist(device.protocol);
347
+ device.protocol.should.equal('MQTT_UL');
348
+ done();
349
+ }
350
+ );
351
+ });
352
+ });
353
+
252
354
  describe('When an unexisting device tries to be retrieved for an unexisting APIKey', function () {
253
355
  it('should raise an error', function (done) {
254
356
  iotAgentLib.retrieveDevice(
@@ -35,9 +35,6 @@ const iotAgentConfig = {
35
35
  host: 'localhost',
36
36
  baseRoot: '/'
37
37
  },
38
- stats: {
39
- interval: 100
40
- },
41
38
  types: {},
42
39
  service: 'smartgondor',
43
40
  subservice: 'gardens',
@@ -51,9 +48,7 @@ describe('Statistics service', function () {
51
48
  oldConfig = commonConfig.getConfig();
52
49
  commonConfig.setConfig(iotAgentConfig);
53
50
 
54
- statsService.globalLoad({}, function () {
55
- statsService.clearTimers(done);
56
- });
51
+ statsService.globalLoad({}, done);
57
52
  });
58
53
 
59
54
  afterEach(function (done) {
@@ -74,16 +69,6 @@ describe('Statistics service', function () {
74
69
  );
75
70
  });
76
71
 
77
- it('should appear the modified value in the getCurrent() statistics', function (done) {
78
- statsService.add(statName, statValue, function () {
79
- statsService.getCurrent(statName, function (error, value) {
80
- should.not.exist(error);
81
- should.exist(value);
82
- value.should.equal(statValue);
83
- done();
84
- });
85
- });
86
- });
87
72
  it('should add the value to the global values', function (done) {
88
73
  statsService.add(statName, statValue, function () {
89
74
  statsService.getGlobal(statName, function (error, value) {
@@ -119,62 +104,4 @@ describe('Statistics service', function () {
119
104
  });
120
105
  });
121
106
  });
122
- describe('When the current statistics are reset', function () {
123
- beforeEach(function (done) {
124
- statsService.add('statA', 42, function () {
125
- statsService.add('statB', 52, done);
126
- });
127
- });
128
-
129
- it('should return a value of zero for any of the individual statistics', function (done) {
130
- statsService.resetCurrent(function (error) {
131
- should.not.exist(error);
132
-
133
- statsService.getAllCurrent(function (error, data) {
134
- should.exist(data);
135
- should.exist(data.statA);
136
- should.exist(data.statB);
137
- data.statA.should.equal(0);
138
- data.statB.should.equal(0);
139
- done();
140
- });
141
- });
142
- });
143
- });
144
- describe('When a new periodic stats action is set', function () {
145
- let valueCurrent = 0;
146
- let valueGlobal = 0;
147
- let times = 0;
148
-
149
- beforeEach(function (done) {
150
- statsService.globalLoad(
151
- {
152
- stat1: 10
153
- },
154
- function () {
155
- statsService.add('stat1', 5, done);
156
- }
157
- );
158
- });
159
-
160
- function mockedAction(current, global, callback) {
161
- valueCurrent = current.stat1;
162
- valueGlobal = global.stat1;
163
- times++;
164
- callback();
165
- }
166
-
167
- it('should be triggered with the periodicity stated in the config.stats.interval parameter', function (done) {
168
- statsService.addTimerAction(mockedAction, function () {
169
- setTimeout(function () {
170
- statsService.clearTimers(function () {
171
- valueCurrent.should.equal(5);
172
- valueGlobal.should.equal(15);
173
- times.should.equal(4);
174
- done();
175
- });
176
- }, 480);
177
- });
178
- });
179
- });
180
107
  });