@alwaysai/device-agent 1.5.0 → 2.0.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 (273) hide show
  1. package/lib/application-control/config.d.ts.map +1 -1
  2. package/lib/application-control/config.js +8 -3
  3. package/lib/application-control/config.js.map +1 -1
  4. package/lib/application-control/environment-variables.d.ts +1 -5
  5. package/lib/application-control/environment-variables.d.ts.map +1 -1
  6. package/lib/application-control/environment-variables.js +9 -26
  7. package/lib/application-control/environment-variables.js.map +1 -1
  8. package/lib/application-control/environment-variables.test.js +27 -7
  9. package/lib/application-control/environment-variables.test.js.map +1 -1
  10. package/lib/application-control/index.d.ts +4 -4
  11. package/lib/application-control/index.d.ts.map +1 -1
  12. package/lib/application-control/index.js +1 -4
  13. package/lib/application-control/index.js.map +1 -1
  14. package/lib/application-control/install.d.ts.map +1 -1
  15. package/lib/application-control/install.js +8 -7
  16. package/lib/application-control/install.js.map +1 -1
  17. package/lib/application-control/models.d.ts +0 -11
  18. package/lib/application-control/models.d.ts.map +1 -1
  19. package/lib/application-control/models.js +5 -54
  20. package/lib/application-control/models.js.map +1 -1
  21. package/lib/application-control/utils.d.ts +0 -4
  22. package/lib/application-control/utils.d.ts.map +1 -1
  23. package/lib/application-control/utils.js +1 -24
  24. package/lib/application-control/utils.js.map +1 -1
  25. package/lib/cloud-connection/bootstrap-provision.js +3 -2
  26. package/lib/cloud-connection/bootstrap-provision.js.map +1 -1
  27. package/lib/cloud-connection/device-agent-cloud-connection.d.ts +10 -15
  28. package/lib/cloud-connection/device-agent-cloud-connection.d.ts.map +1 -1
  29. package/lib/cloud-connection/device-agent-cloud-connection.js +279 -250
  30. package/lib/cloud-connection/device-agent-cloud-connection.js.map +1 -1
  31. package/lib/cloud-connection/device-agent.d.ts.map +1 -1
  32. package/lib/cloud-connection/device-agent.js +11 -9
  33. package/lib/cloud-connection/device-agent.js.map +1 -1
  34. package/lib/cloud-connection/live-updates-handler.d.ts +18 -28
  35. package/lib/cloud-connection/live-updates-handler.d.ts.map +1 -1
  36. package/lib/cloud-connection/live-updates-handler.js +54 -169
  37. package/lib/cloud-connection/live-updates-handler.js.map +1 -1
  38. package/lib/cloud-connection/live-updates-handler.test.js +71 -165
  39. package/lib/cloud-connection/live-updates-handler.test.js.map +1 -1
  40. package/lib/cloud-connection/passthrough-handler.d.ts +4 -1
  41. package/lib/cloud-connection/passthrough-handler.d.ts.map +1 -1
  42. package/lib/cloud-connection/passthrough-handler.js +30 -11
  43. package/lib/cloud-connection/passthrough-handler.js.map +1 -1
  44. package/lib/cloud-connection/shadow-handler.d.ts +5 -3
  45. package/lib/cloud-connection/shadow-handler.d.ts.map +1 -1
  46. package/lib/cloud-connection/shadow-handler.js +59 -27
  47. package/lib/cloud-connection/shadow-handler.js.map +1 -1
  48. package/lib/cloud-connection/shadow-handler.test.js +45 -57
  49. package/lib/cloud-connection/shadow-handler.test.js.map +1 -1
  50. package/lib/cloud-connection/shadow.d.ts.map +1 -1
  51. package/lib/cloud-connection/shadow.js +2 -1
  52. package/lib/cloud-connection/shadow.js.map +1 -1
  53. package/lib/cloud-connection/transaction-manager.d.ts +4 -2
  54. package/lib/cloud-connection/transaction-manager.d.ts.map +1 -1
  55. package/lib/cloud-connection/transaction-manager.js +18 -29
  56. package/lib/cloud-connection/transaction-manager.js.map +1 -1
  57. package/lib/cloud-connection/transaction-manager.test.js +3 -3
  58. package/lib/cloud-connection/transaction-manager.test.js.map +1 -1
  59. package/lib/device-control/device-control.d.ts +8 -8
  60. package/lib/device-control/device-control.d.ts.map +1 -1
  61. package/lib/device-control/device-control.js +95 -71
  62. package/lib/device-control/device-control.js.map +1 -1
  63. package/lib/docker/docker-compose.d.ts.map +1 -1
  64. package/lib/docker/docker-compose.js +2 -1
  65. package/lib/docker/docker-compose.js.map +1 -1
  66. package/lib/infrastructure/agent-config.d.ts +2 -1
  67. package/lib/infrastructure/agent-config.d.ts.map +1 -1
  68. package/lib/infrastructure/agent-config.js +7 -7
  69. package/lib/infrastructure/agent-config.js.map +1 -1
  70. package/lib/infrastructure/agent-config.test.js +3 -1
  71. package/lib/infrastructure/agent-config.test.js.map +1 -1
  72. package/lib/infrastructure/config-check-utility.d.ts +6 -0
  73. package/lib/infrastructure/config-check-utility.d.ts.map +1 -0
  74. package/lib/infrastructure/config-check-utility.js +67 -0
  75. package/lib/infrastructure/config-check-utility.js.map +1 -0
  76. package/lib/infrastructure/config-check-utility.test.d.ts +2 -0
  77. package/lib/infrastructure/config-check-utility.test.d.ts.map +1 -0
  78. package/lib/infrastructure/config-check-utility.test.js +109 -0
  79. package/lib/infrastructure/config-check-utility.test.js.map +1 -0
  80. package/lib/infrastructure/device-certificate.d.ts +10 -0
  81. package/lib/infrastructure/device-certificate.d.ts.map +1 -0
  82. package/lib/infrastructure/device-certificate.js +47 -0
  83. package/lib/infrastructure/device-certificate.js.map +1 -0
  84. package/lib/infrastructure/device-certificate.test.d.ts +2 -0
  85. package/lib/infrastructure/device-certificate.test.d.ts.map +1 -0
  86. package/lib/infrastructure/device-certificate.test.js +24 -0
  87. package/lib/infrastructure/device-certificate.test.js.map +1 -0
  88. package/lib/infrastructure/legacy-migration/legacy-file.test.d.ts +2 -0
  89. package/lib/infrastructure/legacy-migration/legacy-file.test.d.ts.map +1 -0
  90. package/lib/infrastructure/legacy-migration/legacy-file.test.js +61 -0
  91. package/lib/infrastructure/legacy-migration/legacy-file.test.js.map +1 -0
  92. package/lib/infrastructure/legacy-migration/legacy-files.d.ts +75 -0
  93. package/lib/infrastructure/legacy-migration/legacy-files.d.ts.map +1 -0
  94. package/lib/infrastructure/legacy-migration/legacy-files.js +75 -0
  95. package/lib/infrastructure/legacy-migration/legacy-files.js.map +1 -0
  96. package/lib/infrastructure/legacy-migration/legacy-migration.d.ts +6 -0
  97. package/lib/infrastructure/legacy-migration/legacy-migration.d.ts.map +1 -0
  98. package/lib/infrastructure/legacy-migration/legacy-migration.js +149 -0
  99. package/lib/infrastructure/legacy-migration/legacy-migration.js.map +1 -0
  100. package/lib/infrastructure/legacy-migration/legacy-migration.test.d.ts +2 -0
  101. package/lib/infrastructure/legacy-migration/legacy-migration.test.d.ts.map +1 -0
  102. package/lib/infrastructure/legacy-migration/legacy-migration.test.js +226 -0
  103. package/lib/infrastructure/legacy-migration/legacy-migration.test.js.map +1 -0
  104. package/lib/infrastructure/require-files-present-ready.test.d.ts +2 -0
  105. package/lib/infrastructure/require-files-present-ready.test.d.ts.map +1 -0
  106. package/lib/infrastructure/require-files-present-ready.test.js +44 -0
  107. package/lib/infrastructure/require-files-present-ready.test.js.map +1 -0
  108. package/lib/infrastructure/required-config-checks.d.ts +2 -0
  109. package/lib/infrastructure/required-config-checks.d.ts.map +1 -0
  110. package/lib/infrastructure/required-config-checks.js +30 -0
  111. package/lib/infrastructure/required-config-checks.js.map +1 -0
  112. package/lib/infrastructure/tokens-and-device-cfg.d.ts.map +1 -1
  113. package/lib/infrastructure/tokens-and-device-cfg.js +11 -8
  114. package/lib/infrastructure/tokens-and-device-cfg.js.map +1 -1
  115. package/lib/local-connection/rabbitmq-connection.d.ts.map +1 -1
  116. package/lib/local-connection/rabbitmq-connection.js +14 -14
  117. package/lib/local-connection/rabbitmq-connection.js.map +1 -1
  118. package/lib/secure-tunneling/secure-tunneling.d.ts +9 -9
  119. package/lib/secure-tunneling/secure-tunneling.d.ts.map +1 -1
  120. package/lib/secure-tunneling/secure-tunneling.js +21 -16
  121. package/lib/secure-tunneling/secure-tunneling.js.map +1 -1
  122. package/lib/secure-tunneling/secure-tunneling.test.js +11 -13
  123. package/lib/secure-tunneling/secure-tunneling.test.js.map +1 -1
  124. package/lib/subcommands/app/analytics.d.ts.map +1 -1
  125. package/lib/subcommands/app/analytics.js +1 -2
  126. package/lib/subcommands/app/analytics.js.map +1 -1
  127. package/lib/subcommands/app/env-vars.d.ts +4 -0
  128. package/lib/subcommands/app/env-vars.d.ts.map +1 -1
  129. package/lib/subcommands/app/env-vars.js +52 -6
  130. package/lib/subcommands/app/env-vars.js.map +1 -1
  131. package/lib/subcommands/app/index.d.ts.map +1 -1
  132. package/lib/subcommands/app/index.js +1 -3
  133. package/lib/subcommands/app/index.js.map +1 -1
  134. package/lib/subcommands/app/models.d.ts +0 -11
  135. package/lib/subcommands/app/models.d.ts.map +1 -1
  136. package/lib/subcommands/app/models.js +2 -58
  137. package/lib/subcommands/app/models.js.map +1 -1
  138. package/lib/subcommands/app/shadow.d.ts.map +1 -1
  139. package/lib/subcommands/app/shadow.js +6 -5
  140. package/lib/subcommands/app/shadow.js.map +1 -1
  141. package/lib/subcommands/app/version.d.ts.map +1 -1
  142. package/lib/subcommands/app/version.js +2 -4
  143. package/lib/subcommands/app/version.js.map +1 -1
  144. package/lib/subcommands/config.d.ts +2 -0
  145. package/lib/subcommands/config.d.ts.map +1 -0
  146. package/lib/subcommands/config.js +39 -0
  147. package/lib/subcommands/config.js.map +1 -0
  148. package/lib/subcommands/device/clean.d.ts +1 -1
  149. package/lib/subcommands/device/clean.d.ts.map +1 -1
  150. package/lib/subcommands/device/clean.js +23 -13
  151. package/lib/subcommands/device/clean.js.map +1 -1
  152. package/lib/subcommands/device/index.d.ts.map +1 -1
  153. package/lib/subcommands/device/index.js +3 -1
  154. package/lib/subcommands/device/index.js.map +1 -1
  155. package/lib/subcommands/device/init.js +8 -8
  156. package/lib/subcommands/device/init.js.map +1 -1
  157. package/lib/subcommands/device/migrate.d.ts +2 -0
  158. package/lib/subcommands/device/migrate.d.ts.map +1 -0
  159. package/lib/subcommands/device/migrate.js +24 -0
  160. package/lib/subcommands/device/migrate.js.map +1 -0
  161. package/lib/subcommands/device/refresh.d.ts.map +1 -1
  162. package/lib/subcommands/device/refresh.js +1 -0
  163. package/lib/subcommands/device/refresh.js.map +1 -1
  164. package/lib/subcommands/index.d.ts +1 -1
  165. package/lib/subcommands/index.d.ts.map +1 -1
  166. package/lib/subcommands/index.js +3 -1
  167. package/lib/subcommands/index.js.map +1 -1
  168. package/lib/subcommands/rabbitmq-connection.d.ts +1 -1
  169. package/lib/subcommands/rabbitmq-connection.d.ts.map +1 -1
  170. package/lib/util/aai-error.d.ts +12 -0
  171. package/lib/util/aai-error.d.ts.map +1 -0
  172. package/lib/util/aai-error.js +11 -0
  173. package/lib/util/aai-error.js.map +1 -0
  174. package/lib/util/aws-regions.d.ts +2 -0
  175. package/lib/util/aws-regions.d.ts.map +1 -0
  176. package/lib/util/{cloud-mode-ready.js → aws-regions.js} +2 -20
  177. package/lib/util/aws-regions.js.map +1 -0
  178. package/lib/util/check-for-updates.d.ts.map +1 -1
  179. package/lib/util/check-for-updates.js +5 -28
  180. package/lib/util/check-for-updates.js.map +1 -1
  181. package/lib/util/clean-certs.d.ts.map +1 -1
  182. package/lib/util/clean-certs.js +5 -4
  183. package/lib/util/clean-certs.js.map +1 -1
  184. package/lib/util/directories.d.ts +4 -18
  185. package/lib/util/directories.d.ts.map +1 -1
  186. package/lib/util/directories.js +18 -32
  187. package/lib/util/directories.js.map +1 -1
  188. package/lib/util/file.d.ts +4 -0
  189. package/lib/util/file.d.ts.map +1 -1
  190. package/lib/util/file.js +65 -4
  191. package/lib/util/file.js.map +1 -1
  192. package/lib/util/get-device-id.d.ts.map +1 -1
  193. package/lib/util/get-device-id.js +7 -1
  194. package/lib/util/get-device-id.js.map +1 -1
  195. package/lib/util/http-client.js +3 -3
  196. package/lib/util/http-client.js.map +1 -1
  197. package/package.json +19 -17
  198. package/readme.md +12 -32
  199. package/src/application-control/config.ts +9 -12
  200. package/src/application-control/environment-variables.test.ts +28 -7
  201. package/src/application-control/environment-variables.ts +13 -40
  202. package/src/application-control/index.ts +3 -16
  203. package/src/application-control/install.ts +15 -10
  204. package/src/application-control/models.ts +6 -87
  205. package/src/application-control/utils.ts +0 -28
  206. package/src/cloud-connection/bootstrap-provision.ts +7 -7
  207. package/src/cloud-connection/device-agent-cloud-connection.ts +639 -525
  208. package/src/cloud-connection/device-agent.ts +16 -7
  209. package/src/cloud-connection/live-updates-handler.test.ts +121 -189
  210. package/src/cloud-connection/live-updates-handler.ts +99 -234
  211. package/src/cloud-connection/passthrough-handler.ts +55 -18
  212. package/src/cloud-connection/shadow-handler.test.ts +45 -57
  213. package/src/cloud-connection/shadow-handler.ts +103 -57
  214. package/src/cloud-connection/shadow.ts +4 -1
  215. package/src/cloud-connection/transaction-manager.test.ts +3 -3
  216. package/src/cloud-connection/transaction-manager.ts +53 -39
  217. package/src/device-control/device-control.ts +102 -70
  218. package/src/docker/docker-compose.ts +3 -2
  219. package/src/infrastructure/agent-config.test.ts +6 -2
  220. package/src/infrastructure/agent-config.ts +8 -7
  221. package/src/infrastructure/config-check-utility.test.ts +154 -0
  222. package/src/infrastructure/config-check-utility.ts +77 -0
  223. package/src/infrastructure/device-certificate.test.ts +40 -0
  224. package/src/infrastructure/device-certificate.ts +58 -0
  225. package/src/infrastructure/legacy-migration/legacy-file.test.ts +88 -0
  226. package/src/infrastructure/legacy-migration/legacy-files.ts +101 -0
  227. package/src/infrastructure/legacy-migration/legacy-migration.test.ts +396 -0
  228. package/src/infrastructure/legacy-migration/legacy-migration.ts +229 -0
  229. package/src/infrastructure/require-files-present-ready.test.ts +53 -0
  230. package/src/infrastructure/required-config-checks.ts +33 -0
  231. package/src/infrastructure/tokens-and-device-cfg.ts +12 -10
  232. package/src/local-connection/rabbitmq-connection.ts +22 -17
  233. package/src/secure-tunneling/secure-tunneling.test.ts +20 -22
  234. package/src/secure-tunneling/secure-tunneling.ts +41 -29
  235. package/src/subcommands/app/analytics.ts +2 -4
  236. package/src/subcommands/app/env-vars.ts +72 -9
  237. package/src/subcommands/app/index.ts +3 -11
  238. package/src/subcommands/app/models.ts +5 -81
  239. package/src/subcommands/app/shadow.ts +6 -5
  240. package/src/subcommands/app/version.ts +3 -4
  241. package/src/subcommands/config.ts +42 -0
  242. package/src/subcommands/device/clean.ts +31 -17
  243. package/src/subcommands/device/index.ts +3 -1
  244. package/src/subcommands/device/init.ts +11 -11
  245. package/src/subcommands/device/migrate.ts +20 -0
  246. package/src/subcommands/device/refresh.ts +1 -0
  247. package/src/subcommands/index.ts +3 -1
  248. package/src/util/aai-error.ts +20 -0
  249. package/src/util/{cloud-mode-ready.ts → aws-regions.ts} +0 -24
  250. package/src/util/check-for-updates.ts +14 -30
  251. package/src/util/clean-certs.ts +8 -4
  252. package/src/util/directories.ts +23 -67
  253. package/src/util/file.ts +83 -3
  254. package/src/util/get-device-id.ts +7 -7
  255. package/src/util/http-client.ts +2 -2
  256. package/lib/util/cloud-mode-ready.d.ts +0 -3
  257. package/lib/util/cloud-mode-ready.d.ts.map +0 -1
  258. package/lib/util/cloud-mode-ready.js.map +0 -1
  259. package/lib/util/download-file.d.ts +0 -6
  260. package/lib/util/download-file.d.ts.map +0 -1
  261. package/lib/util/download-file.js +0 -25
  262. package/lib/util/download-file.js.map +0 -1
  263. package/lib/util/fetch-with-timeout.d.ts +0 -4
  264. package/lib/util/fetch-with-timeout.d.ts.map +0 -1
  265. package/lib/util/fetch-with-timeout.js +0 -30
  266. package/lib/util/fetch-with-timeout.js.map +0 -1
  267. package/lib/util/parsing.d.ts +0 -2
  268. package/lib/util/parsing.d.ts.map +0 -1
  269. package/lib/util/parsing.js +0 -17
  270. package/lib/util/parsing.js.map +0 -1
  271. package/src/util/download-file.ts +0 -25
  272. package/src/util/fetch-with-timeout.ts +0 -35
  273. package/src/util/parsing.ts +0 -11
@@ -1,16 +1,20 @@
1
1
  // eslint-disable-next-line
2
2
  const awsIot = require('aws-iot-device-sdk');
3
+ import { getTargetHardwareUuid } from 'alwaysai/lib/core/app';
3
4
  import {
5
+ DEVICE_CERTIFICATE_FILE_NAME,
6
+ DEVICE_CERTIFICATE_ID_FILE_NAME,
4
7
  DEVICE_PRIVATE_KEY_FILE_NAME,
8
+ LOCAL_CERT_AND_KEY_DIR
9
+ } from 'alwaysai/lib/infrastructure';
10
+ import { JsSpawner } from 'alwaysai/lib/util';
11
+ import {
5
12
  CERTIFICATE_OWNERSHIP_TOKEN_FILE_NAME,
6
- DEVICE_ID_FILE_NAME,
7
- DEVICE_CERTIFICATE_FILE_NAME
8
- } from '../util/directories';
13
+ getBootstrapCertificateDirectoryPath
14
+ } from '../infrastructure/device-certificate';
9
15
  import { getDeviceUuid } from '../util/get-device-id';
10
- import { JsSpawner } from 'alwaysai/lib/util';
11
16
  import { logger } from '../util/logger';
12
- import { getTargetHardwareUuid } from 'alwaysai/lib/core/app';
13
- import { LOCAL_CERT_AND_KEY_DIR } from 'alwaysai/lib/paths';
17
+
14
18
  // eslint-disable-next-line
15
19
  const process = require('process');
16
20
 
@@ -85,7 +89,10 @@ export class BootstrapAgent extends DeviceAgent {
85
89
 
86
90
  await certSpawner.writeFile(DEVICE_PRIVATE_KEY_FILE_NAME, privateKey);
87
91
 
88
- await certSpawner.writeFile(DEVICE_ID_FILE_NAME, certificateId);
92
+ await certSpawner.writeFile(
93
+ DEVICE_CERTIFICATE_ID_FILE_NAME,
94
+ certificateId
95
+ );
89
96
 
90
97
  await certSpawner.writeFile(
91
98
  CERTIFICATE_OWNERSHIP_TOKEN_FILE_NAME,
@@ -111,6 +118,8 @@ export class BootstrapAgent extends DeviceAgent {
111
118
  }
112
119
  case '$aws/provisioning-templates/FleetProvisionTemplate/provision/json/accepted': {
113
120
  logger.info('Device agent provisioning: success');
121
+ const spawner = JsSpawner();
122
+ await spawner.rimraf(getBootstrapCertificateDirectoryPath());
114
123
  process.exit();
115
124
  }
116
125
  }
@@ -1,230 +1,162 @@
1
- import { LiveUpdatesHandler } from './live-updates-handler';
2
- import { Publisher } from './publisher';
3
- import sleep from '../util/sleep';
4
- import { getDeviceStatsPayload } from './messages';
1
+ import {
2
+ DEFAULT_INTERVALS_MS,
3
+ LiveUpdatesHandler
4
+ } from './live-updates-handler';
5
+ import { keyMirrors } from '@alwaysai/device-agent-schemas';
6
+ import { randomUUID } from 'crypto';
7
+ import { PassThrough } from 'stream';
5
8
 
6
9
  jest.mock('../util/sleep');
7
10
  jest.mock('./messages');
8
-
9
- jest.mocked(getDeviceStatsPayload).mockResolvedValue({});
10
-
11
- global.setTimeout = jest.fn() as unknown as typeof setTimeout;
11
+ jest.useFakeTimers();
12
12
 
13
13
  // https://github.com/facebook/react-native/issues/35701
14
14
  Object.defineProperty(global, 'performance', {
15
15
  writable: true
16
16
  });
17
17
 
18
- const testTrueToggles = {
19
- deviceStats: true,
20
- appState: true
21
- };
22
-
23
- const testFalseToggles = {
24
- deviceStats: false,
25
- appState: false
26
- };
27
-
28
- const mockClient = {
29
- publish: jest.fn()
30
- };
31
- const clientId = 'test-client';
32
- const emptyTxId = '';
18
+ const mockTransactionId = '9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d';
19
+ const mockProjectId = '12345678-abcd-abcd-abcd-0123456789ab';
33
20
 
34
21
  describe('Test Live Updates Handler', () => {
35
22
  let liveUpdatesHandler: LiveUpdatesHandler;
36
- let publisher: Publisher;
37
23
 
38
24
  beforeEach(() => {
39
- mockClient.publish = jest.fn();
40
- jest.mocked(sleep).mockImplementation(async () => {
41
- return;
42
- });
43
- publisher = new Publisher(mockClient, clientId);
44
- liveUpdatesHandler = new LiveUpdatesHandler(publisher, clientId);
25
+ liveUpdatesHandler = new LiveUpdatesHandler();
45
26
  jest.clearAllMocks();
46
27
  });
47
28
 
48
- test('enable device stats', async () => {
49
- mockClient.publish = jest.fn().mockImplementation(async () => {
50
- liveUpdatesHandler.disableDeviceStatsLiveUpdates();
51
- });
52
-
53
- const enable = { deviceStats: true };
54
- const promises = await liveUpdatesHandler.handleToggles(enable, emptyTxId);
55
- await Promise.all(promises);
29
+ test('enable interval', async () => {
30
+ const mockPublishingFn = jest.fn();
31
+ const mockClearInterval = jest.spyOn(global, 'clearInterval');
32
+ const mockSetInterval = jest.spyOn(global, 'setInterval');
56
33
 
57
- expect(jest.mocked(setTimeout)).toBeCalledTimes(1);
58
- expect(mockClient.publish).toBeCalledTimes(1);
59
- expect(jest.mocked(sleep)).toBeCalledTimes(1);
60
- });
34
+ await liveUpdatesHandler.enable(
35
+ keyMirrors.toClientMessageType.device_stats,
36
+ mockPublishingFn
37
+ );
61
38
 
62
- test('enable app state', async () => {
63
- mockClient.publish = jest.fn().mockImplementation(async () => {
64
- liveUpdatesHandler.disableAppStateLiveUpdates();
65
- });
39
+ jest.advanceTimersByTime(DEFAULT_INTERVALS_MS);
66
40
 
67
- const enable = { appState: true };
68
- const promises = await liveUpdatesHandler.handleToggles(enable, emptyTxId);
69
- await Promise.all(promises);
70
-
71
- expect(jest.mocked(setTimeout)).toBeCalledTimes(1);
72
- expect(mockClient.publish).toBeCalledTimes(1);
73
- expect(jest.mocked(sleep)).toBeCalledTimes(1);
41
+ expect(mockPublishingFn).toBeCalledTimes(2);
42
+ expect(mockClearInterval).toBeCalledWith(undefined);
43
+ expect(mockSetInterval).toBeCalledTimes(1);
74
44
  });
75
45
 
76
- test('ignore subsequent enables', async () => {
77
- // Block on the first sleep call
78
- let doneWaiting;
79
- const waitPromise = new Promise(function (resolve) {
80
- doneWaiting = resolve;
81
- });
82
-
83
- let startSleeping;
84
- const sleepPromise = new Promise(function (resolve) {
85
- startSleeping = resolve;
86
- });
87
- jest.mocked(sleep).mockImplementation(async () => {
88
- startSleeping();
89
- await waitPromise;
90
- });
91
-
92
- const enable = { deviceStats: true };
93
- await liveUpdatesHandler.handleToggles(enable, emptyTxId);
94
- await sleepPromise;
95
-
96
- expect(jest.mocked(setTimeout)).toBeCalledTimes(1);
97
- expect(mockClient.publish).toBeCalledTimes(1);
98
- expect(jest.mocked(sleep)).toBeCalledTimes(1);
99
-
100
- // Second call
101
- jest.clearAllMocks();
102
-
103
- await liveUpdatesHandler.handleToggles(enable, emptyTxId);
104
-
105
- expect(jest.mocked(setTimeout)).toHaveBeenCalledTimes(1);
106
- expect(mockClient.publish).toBeCalledTimes(0);
107
- expect(jest.mocked(sleep)).toBeCalledTimes(0);
108
-
109
- // Disable and clean up
110
- liveUpdatesHandler.disableDeviceStatsLiveUpdates();
111
- doneWaiting();
46
+ test('subsequent enable resets interval with no duplicates', async () => {
47
+ const mockPublishingFn = jest.fn();
48
+ const mockSetInterval = jest.spyOn(global, 'setInterval');
49
+ const mockClearInterval = jest.spyOn(global, 'clearInterval');
50
+
51
+ await liveUpdatesHandler.enable(
52
+ keyMirrors.toClientMessageType.device_stats,
53
+ mockPublishingFn,
54
+ mockTransactionId
55
+ );
56
+ await liveUpdatesHandler.enable(
57
+ keyMirrors.toClientMessageType.device_stats,
58
+ mockPublishingFn,
59
+ mockTransactionId
60
+ );
61
+
62
+ jest.advanceTimersByTime(DEFAULT_INTERVALS_MS);
63
+
64
+ expect(mockClearInterval.mock.calls[0][0]).toEqual(undefined);
65
+ expect(mockClearInterval.mock.calls[1][0]).toEqual(
66
+ mockSetInterval.mock.results[0].value
67
+ );
68
+ expect(mockSetInterval).toBeCalledTimes(2);
69
+ expect(mockPublishingFn).toBeCalledTimes(3);
112
70
  });
113
71
 
114
72
  test('test disable live updates', async () => {
115
- let doneWaiting;
116
- const waitPromise = new Promise(function (resolve) {
117
- doneWaiting = resolve;
118
- });
119
-
120
- let startSleeping;
121
- const sleepPromise = new Promise(function (resolve) {
122
- startSleeping = resolve;
123
- });
124
-
125
- // Wait for two sleep calls, one for Device Stats and one for App State
126
- jest
127
- .mocked(sleep)
128
- .mockImplementationOnce(async () => {
129
- await waitPromise;
130
- })
131
- .mockImplementationOnce(async () => {
132
- startSleeping();
133
- await waitPromise;
134
- });
135
-
136
- // Test calling handleToggles one time, enabling it
137
- await liveUpdatesHandler.handleToggles(testTrueToggles, emptyTxId);
138
- await sleepPromise;
139
-
140
- expect(jest.mocked(setTimeout)).toHaveBeenCalledTimes(1);
141
- expect(jest.mocked(sleep)).toBeCalledTimes(2);
142
- expect(liveUpdatesHandler.getDeviceStatsLiveUpdates()).toBe(true);
143
- expect(liveUpdatesHandler.getAppStateLiveUpdates()).toBe(true);
144
- expect(liveUpdatesHandler.getAppLogsLiveUpdates()).toBe(false);
145
-
146
- // Check to see that attributes are properly set to false when disabled
147
- jest.clearAllMocks();
148
- await liveUpdatesHandler.handleToggles(testFalseToggles, emptyTxId);
73
+ const mockSetInterval = jest.spyOn(global, 'setInterval');
74
+ const mockClearInterval = jest.spyOn(global, 'clearInterval');
75
+
76
+ await liveUpdatesHandler.enable(
77
+ keyMirrors.toClientMessageType.device_stats,
78
+ async () => undefined,
79
+ mockTransactionId
80
+ );
81
+ liveUpdatesHandler.disable(
82
+ keyMirrors.toClientMessageType.device_stats,
83
+ mockTransactionId
84
+ );
85
+
86
+ expect(mockClearInterval).toHaveBeenLastCalledWith(
87
+ mockSetInterval.mock.results[0].value
88
+ );
89
+ });
149
90
 
150
- expect(jest.mocked(setTimeout)).toHaveBeenCalledTimes(1);
151
- expect(jest.mocked(sleep)).toBeCalledTimes(0);
152
- expect(liveUpdatesHandler.getDeviceStatsLiveUpdates()).toBe(false);
153
- expect(liveUpdatesHandler.getAppStateLiveUpdates()).toBe(false);
154
- expect(liveUpdatesHandler.getAppLogsLiveUpdates()).toBe(false);
91
+ test('kill all timeout turns off all live updates', async () => {
92
+ const mockPublishingFn = jest.fn();
93
+ const mockSetInterval = jest.spyOn(global, 'setInterval');
94
+ const mockClearInterval = jest.spyOn(global, 'clearInterval');
95
+ jest.spyOn(global, 'setTimeout');
96
+
97
+ const numLivingIntervals = 5;
98
+ for (let i = 0; i < numLivingIntervals; i++) {
99
+ await liveUpdatesHandler.enable(
100
+ keyMirrors.toClientMessageType.status_response,
101
+ mockPublishingFn,
102
+ randomUUID()
103
+ );
104
+ }
105
+
106
+ mockSetInterval.mock.results.forEach((result) =>
107
+ clearInterval(result.value)
108
+ );
109
+ jest.runAllTimers();
155
110
 
156
- doneWaiting();
111
+ expect(mockPublishingFn).toBeCalledTimes(numLivingIntervals);
112
+ expect(mockSetInterval).toBeCalledTimes(numLivingIntervals);
113
+ for (let i = 0; i < numLivingIntervals; i++) {
114
+ expect(mockClearInterval).toHaveBeenCalledWith(
115
+ mockSetInterval.mock.results[i].value
116
+ );
117
+ }
157
118
  });
158
119
 
159
- test('timeout turns off live updates', async () => {
160
- jest.useFakeTimers({ legacyFakeTimers: true });
161
- let doneWaiting;
162
- const waitPromise = new Promise(function (resolve) {
163
- doneWaiting = resolve;
164
- });
165
-
166
- let startSleeping;
167
- const sleepPromise = new Promise(function (resolve) {
168
- startSleeping = resolve;
169
- });
170
-
171
- // Wait for two sleep calls, one for Device Stats and one for App State
172
- jest
173
- .mocked(sleep)
174
- .mockImplementationOnce(async () => {
175
- await waitPromise;
176
- })
177
- .mockImplementationOnce(async () => {
178
- startSleeping();
179
- await waitPromise;
180
- });
120
+ test('startStream streams data to publish', async () => {
121
+ const mockStream = new PassThrough();
122
+ const mockPublishingFn = jest
123
+ .fn()
124
+ .mockImplementation((logChunk: string) => undefined);
181
125
 
182
- await liveUpdatesHandler.handleToggles(testTrueToggles, emptyTxId);
183
- await sleepPromise;
126
+ await liveUpdatesHandler.startStream(
127
+ mockProjectId,
128
+ async () => mockStream,
129
+ mockPublishingFn
130
+ );
184
131
 
185
- expect(liveUpdatesHandler.getDeviceStatsLiveUpdates()).toBe(true);
186
- expect(liveUpdatesHandler.getAppStateLiveUpdates()).toBe(true);
187
- expect(liveUpdatesHandler.getAppLogsLiveUpdates()).toBe(false);
188
-
189
- jest.runAllTimers();
132
+ const data = 'Data for stream';
133
+ mockStream.emit('data', data);
190
134
 
191
- expect(liveUpdatesHandler.getDeviceStatsLiveUpdates()).toBe(false);
192
- expect(liveUpdatesHandler.getAppStateLiveUpdates()).toBe(false);
193
- expect(liveUpdatesHandler.getAppLogsLiveUpdates()).toBe(false);
135
+ expect(mockPublishingFn).toBeCalledWith(data);
194
136
 
195
- doneWaiting();
137
+ mockStream.end();
138
+ mockStream.destroy();
196
139
  });
197
140
 
198
- test("failure doesn't kill publish loop", async () => {
199
- // Block on the first sleep call
200
- let doneWaiting;
201
- const waitPromise = new Promise(function (resolve) {
202
- doneWaiting = resolve;
203
- });
204
-
205
- let startSleeping;
206
- const sleepPromise = new Promise(function (resolve) {
207
- startSleeping = resolve;
208
- });
209
- jest
210
- .mocked(sleep)
211
- .mockImplementationOnce(async () => {
212
- throw new Error('Test error!');
213
- })
214
- .mockImplementationOnce(async () => {
215
- startSleeping();
216
- await waitPromise;
141
+ test('failure does not disable interval', async () => {
142
+ const mockPublishingFn = jest
143
+ .fn()
144
+ .mockImplementationOnce(() => undefined)
145
+ .mockImplementation(() => {
146
+ throw new Error('Manual throw for unit test');
217
147
  });
148
+ jest.spyOn(global, 'setInterval');
149
+ const mockClearInterval = jest.spyOn(global, 'clearInterval');
218
150
 
219
- const enable = { deviceStats: true };
220
- await liveUpdatesHandler.handleToggles(enable, emptyTxId);
221
- await sleepPromise;
151
+ await liveUpdatesHandler.enable(
152
+ keyMirrors.toClientMessageType.device_stats,
153
+ mockPublishingFn,
154
+ mockTransactionId
155
+ );
222
156
 
223
- expect(jest.mocked(setTimeout)).toBeCalledTimes(1);
224
- expect(mockClient.publish).toBeCalledTimes(2);
225
- expect(jest.mocked(sleep)).toBeCalledTimes(2);
157
+ jest.advanceTimersByTime(DEFAULT_INTERVALS_MS);
226
158
 
227
- liveUpdatesHandler.disableDeviceStatsLiveUpdates();
228
- doneWaiting();
159
+ expect(mockClearInterval).toBeCalledTimes(1);
160
+ expect(mockPublishingFn).toBeCalledTimes(2);
229
161
  });
230
162
  });