@fluidframework/container-loader 2.0.0-rc.2.0.1 → 2.0.0-rc.3.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 (246) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/api-report/container-loader.api.md +13 -13
  3. package/dist/attachment.d.ts +6 -9
  4. package/dist/attachment.d.ts.map +1 -1
  5. package/dist/attachment.js +5 -5
  6. package/dist/attachment.js.map +1 -1
  7. package/dist/audience.d.ts +1 -1
  8. package/dist/audience.d.ts.map +1 -1
  9. package/dist/audience.js +4 -4
  10. package/dist/audience.js.map +1 -1
  11. package/dist/catchUpMonitor.d.ts +1 -1
  12. package/dist/catchUpMonitor.d.ts.map +1 -1
  13. package/dist/catchUpMonitor.js +2 -2
  14. package/dist/catchUpMonitor.js.map +1 -1
  15. package/dist/connectionManager.d.ts +4 -4
  16. package/dist/connectionManager.d.ts.map +1 -1
  17. package/dist/connectionManager.js +48 -43
  18. package/dist/connectionManager.js.map +1 -1
  19. package/dist/connectionStateHandler.d.ts +3 -3
  20. package/dist/connectionStateHandler.d.ts.map +1 -1
  21. package/dist/connectionStateHandler.js +27 -27
  22. package/dist/connectionStateHandler.js.map +1 -1
  23. package/dist/container.d.ts +9 -46
  24. package/dist/container.d.ts.map +1 -1
  25. package/dist/container.js +105 -116
  26. package/dist/container.js.map +1 -1
  27. package/dist/containerContext.d.ts +19 -7
  28. package/dist/containerContext.d.ts.map +1 -1
  29. package/dist/containerContext.js +7 -2
  30. package/dist/containerContext.js.map +1 -1
  31. package/dist/containerStorageAdapter.d.ts +3 -3
  32. package/dist/containerStorageAdapter.d.ts.map +1 -1
  33. package/dist/containerStorageAdapter.js +6 -6
  34. package/dist/containerStorageAdapter.js.map +1 -1
  35. package/dist/contracts.d.ts +4 -3
  36. package/dist/contracts.d.ts.map +1 -1
  37. package/dist/contracts.js +2 -2
  38. package/dist/contracts.js.map +1 -1
  39. package/dist/debugLogger.d.ts +2 -1
  40. package/dist/debugLogger.d.ts.map +1 -1
  41. package/dist/debugLogger.js +4 -4
  42. package/dist/debugLogger.js.map +1 -1
  43. package/dist/deltaManager.d.ts +11 -7
  44. package/dist/deltaManager.d.ts.map +1 -1
  45. package/dist/deltaManager.js +53 -50
  46. package/dist/deltaManager.js.map +1 -1
  47. package/dist/deltaQueue.d.ts +1 -1
  48. package/dist/deltaQueue.d.ts.map +1 -1
  49. package/dist/deltaQueue.js +5 -5
  50. package/dist/deltaQueue.js.map +1 -1
  51. package/dist/error.d.ts +3 -2
  52. package/dist/error.d.ts.map +1 -1
  53. package/dist/error.js +5 -5
  54. package/dist/error.js.map +1 -1
  55. package/dist/legacy.d.ts +29 -0
  56. package/dist/loader.d.ts +4 -4
  57. package/dist/loader.d.ts.map +1 -1
  58. package/dist/loader.js +23 -23
  59. package/dist/loader.js.map +1 -1
  60. package/dist/location-redirection-utilities/resolveWithLocationRedirection.d.ts +2 -2
  61. package/dist/location-redirection-utilities/resolveWithLocationRedirection.d.ts.map +1 -1
  62. package/dist/location-redirection-utilities/resolveWithLocationRedirection.js +2 -2
  63. package/dist/location-redirection-utilities/resolveWithLocationRedirection.js.map +1 -1
  64. package/dist/noopHeuristic.d.ts +1 -1
  65. package/dist/noopHeuristic.d.ts.map +1 -1
  66. package/dist/noopHeuristic.js +6 -6
  67. package/dist/noopHeuristic.js.map +1 -1
  68. package/dist/packageVersion.d.ts +1 -1
  69. package/dist/packageVersion.js +1 -1
  70. package/dist/packageVersion.js.map +1 -1
  71. package/dist/protocol.d.ts +1 -1
  72. package/dist/protocol.d.ts.map +1 -1
  73. package/dist/protocol.js +2 -2
  74. package/dist/protocol.js.map +1 -1
  75. package/dist/protocolTreeDocumentStorageService.d.ts +4 -4
  76. package/dist/protocolTreeDocumentStorageService.d.ts.map +1 -1
  77. package/dist/protocolTreeDocumentStorageService.js.map +1 -1
  78. package/dist/public.d.ts +14 -0
  79. package/dist/quorum.d.ts +1 -1
  80. package/dist/quorum.d.ts.map +1 -1
  81. package/dist/quorum.js +4 -0
  82. package/dist/quorum.js.map +1 -1
  83. package/dist/retriableDocumentStorageService.d.ts +2 -2
  84. package/dist/retriableDocumentStorageService.d.ts.map +1 -1
  85. package/dist/retriableDocumentStorageService.js +7 -7
  86. package/dist/retriableDocumentStorageService.js.map +1 -1
  87. package/dist/serializedStateManager.d.ts +86 -16
  88. package/dist/serializedStateManager.d.ts.map +1 -1
  89. package/dist/serializedStateManager.js +182 -82
  90. package/dist/serializedStateManager.js.map +1 -1
  91. package/dist/utils.d.ts +24 -9
  92. package/dist/utils.d.ts.map +1 -1
  93. package/dist/utils.js +82 -25
  94. package/dist/utils.js.map +1 -1
  95. package/internal.d.ts +11 -0
  96. package/legacy.d.ts +11 -0
  97. package/lib/attachment.d.ts +6 -9
  98. package/lib/attachment.d.ts.map +1 -1
  99. package/lib/attachment.js +1 -1
  100. package/lib/attachment.js.map +1 -1
  101. package/lib/audience.d.ts +1 -1
  102. package/lib/audience.d.ts.map +1 -1
  103. package/lib/audience.js +1 -1
  104. package/lib/audience.js.map +1 -1
  105. package/lib/catchUpMonitor.d.ts +1 -1
  106. package/lib/catchUpMonitor.d.ts.map +1 -1
  107. package/lib/catchUpMonitor.js +1 -1
  108. package/lib/catchUpMonitor.js.map +1 -1
  109. package/lib/connectionManager.d.ts +4 -4
  110. package/lib/connectionManager.d.ts.map +1 -1
  111. package/lib/connectionManager.js +11 -6
  112. package/lib/connectionManager.js.map +1 -1
  113. package/lib/connectionStateHandler.d.ts +3 -3
  114. package/lib/connectionStateHandler.d.ts.map +1 -1
  115. package/lib/connectionStateHandler.js +2 -2
  116. package/lib/connectionStateHandler.js.map +1 -1
  117. package/lib/container.d.ts +9 -46
  118. package/lib/container.d.ts.map +1 -1
  119. package/lib/container.js +37 -48
  120. package/lib/container.js.map +1 -1
  121. package/lib/containerContext.d.ts +19 -7
  122. package/lib/containerContext.d.ts.map +1 -1
  123. package/lib/containerContext.js +7 -2
  124. package/lib/containerContext.js.map +1 -1
  125. package/lib/containerStorageAdapter.d.ts +3 -3
  126. package/lib/containerStorageAdapter.d.ts.map +1 -1
  127. package/lib/containerStorageAdapter.js +2 -2
  128. package/lib/containerStorageAdapter.js.map +1 -1
  129. package/lib/contracts.d.ts +4 -3
  130. package/lib/contracts.d.ts.map +1 -1
  131. package/lib/contracts.js +1 -1
  132. package/lib/contracts.js.map +1 -1
  133. package/lib/debugLogger.d.ts +2 -1
  134. package/lib/debugLogger.d.ts.map +1 -1
  135. package/lib/debugLogger.js +1 -1
  136. package/lib/debugLogger.js.map +1 -1
  137. package/lib/deltaManager.d.ts +11 -7
  138. package/lib/deltaManager.d.ts.map +1 -1
  139. package/lib/deltaManager.js +13 -10
  140. package/lib/deltaManager.js.map +1 -1
  141. package/lib/deltaQueue.d.ts +1 -1
  142. package/lib/deltaQueue.d.ts.map +1 -1
  143. package/lib/deltaQueue.js +2 -2
  144. package/lib/deltaQueue.js.map +1 -1
  145. package/lib/error.d.ts +3 -2
  146. package/lib/error.d.ts.map +1 -1
  147. package/lib/error.js +2 -2
  148. package/lib/error.js.map +1 -1
  149. package/lib/legacy.d.ts +29 -0
  150. package/lib/loader.d.ts +4 -4
  151. package/lib/loader.d.ts.map +1 -1
  152. package/lib/loader.js +4 -4
  153. package/lib/loader.js.map +1 -1
  154. package/lib/location-redirection-utilities/resolveWithLocationRedirection.d.ts +2 -2
  155. package/lib/location-redirection-utilities/resolveWithLocationRedirection.d.ts.map +1 -1
  156. package/lib/location-redirection-utilities/resolveWithLocationRedirection.js +2 -2
  157. package/lib/location-redirection-utilities/resolveWithLocationRedirection.js.map +1 -1
  158. package/lib/noopHeuristic.d.ts +1 -1
  159. package/lib/noopHeuristic.d.ts.map +1 -1
  160. package/lib/noopHeuristic.js +2 -2
  161. package/lib/noopHeuristic.js.map +1 -1
  162. package/lib/packageVersion.d.ts +1 -1
  163. package/lib/packageVersion.js +1 -1
  164. package/lib/packageVersion.js.map +1 -1
  165. package/lib/protocol.d.ts +1 -1
  166. package/lib/protocol.d.ts.map +1 -1
  167. package/lib/protocol.js +1 -1
  168. package/lib/protocol.js.map +1 -1
  169. package/lib/protocolTreeDocumentStorageService.d.ts +4 -4
  170. package/lib/protocolTreeDocumentStorageService.d.ts.map +1 -1
  171. package/lib/protocolTreeDocumentStorageService.js.map +1 -1
  172. package/lib/public.d.ts +14 -0
  173. package/lib/quorum.d.ts +1 -1
  174. package/lib/quorum.d.ts.map +1 -1
  175. package/lib/quorum.js +4 -0
  176. package/lib/quorum.js.map +1 -1
  177. package/lib/retriableDocumentStorageService.d.ts +2 -2
  178. package/lib/retriableDocumentStorageService.d.ts.map +1 -1
  179. package/lib/retriableDocumentStorageService.js +3 -3
  180. package/lib/retriableDocumentStorageService.js.map +1 -1
  181. package/lib/serializedStateManager.d.ts +86 -16
  182. package/lib/serializedStateManager.d.ts.map +1 -1
  183. package/lib/serializedStateManager.js +174 -77
  184. package/lib/serializedStateManager.js.map +1 -1
  185. package/lib/utils.d.ts +24 -9
  186. package/lib/utils.d.ts.map +1 -1
  187. package/lib/utils.js +69 -15
  188. package/lib/utils.js.map +1 -1
  189. package/package.json +37 -58
  190. package/src/attachment.ts +10 -8
  191. package/src/audience.ts +3 -2
  192. package/src/catchUpMonitor.ts +2 -2
  193. package/src/connectionManager.ts +27 -20
  194. package/src/connectionStateHandler.ts +7 -7
  195. package/src/container.ts +90 -143
  196. package/src/containerContext.ts +22 -12
  197. package/src/containerStorageAdapter.ts +7 -6
  198. package/src/contracts.ts +4 -5
  199. package/src/debugLogger.ts +3 -4
  200. package/src/deltaManager.ts +40 -30
  201. package/src/deltaQueue.ts +2 -2
  202. package/src/error.ts +5 -4
  203. package/src/loader.ts +25 -23
  204. package/src/location-redirection-utilities/resolveWithLocationRedirection.ts +4 -4
  205. package/src/noopHeuristic.ts +3 -3
  206. package/src/packageVersion.ts +1 -1
  207. package/src/protocol.ts +2 -2
  208. package/src/protocolTreeDocumentStorageService.ts +4 -1
  209. package/src/quorum.ts +2 -1
  210. package/src/retriableDocumentStorageService.ts +6 -5
  211. package/src/serializedStateManager.ts +299 -111
  212. package/src/utils.ts +103 -24
  213. package/api-extractor-cjs.json +0 -8
  214. package/dist/container-loader-alpha.d.ts +0 -275
  215. package/dist/container-loader-beta.d.ts +0 -101
  216. package/dist/container-loader-public.d.ts +0 -101
  217. package/dist/container-loader-untrimmed.d.ts +0 -331
  218. package/lib/container-loader-alpha.d.ts +0 -275
  219. package/lib/container-loader-beta.d.ts +0 -101
  220. package/lib/container-loader-public.d.ts +0 -101
  221. package/lib/container-loader-untrimmed.d.ts +0 -331
  222. package/lib/test/attachment.spec.js +0 -380
  223. package/lib/test/attachment.spec.js.map +0 -1
  224. package/lib/test/catchUpMonitor.spec.js +0 -88
  225. package/lib/test/catchUpMonitor.spec.js.map +0 -1
  226. package/lib/test/connectionManager.spec.js +0 -201
  227. package/lib/test/connectionManager.spec.js.map +0 -1
  228. package/lib/test/connectionStateHandler.spec.js +0 -555
  229. package/lib/test/connectionStateHandler.spec.js.map +0 -1
  230. package/lib/test/container.spec.js +0 -64
  231. package/lib/test/container.spec.js.map +0 -1
  232. package/lib/test/deltaManager.spec.js +0 -405
  233. package/lib/test/deltaManager.spec.js.map +0 -1
  234. package/lib/test/loader.spec.js +0 -212
  235. package/lib/test/loader.spec.js.map +0 -1
  236. package/lib/test/locationRedirectionTests.spec.js +0 -44
  237. package/lib/test/locationRedirectionTests.spec.js.map +0 -1
  238. package/lib/test/serializedStateManager.spec.js +0 -148
  239. package/lib/test/serializedStateManager.spec.js.map +0 -1
  240. package/lib/test/snapshotConversionTest.spec.js +0 -79
  241. package/lib/test/snapshotConversionTest.spec.js.map +0 -1
  242. package/lib/test/types/validateContainerLoaderPrevious.generated.js +0 -38
  243. package/lib/test/types/validateContainerLoaderPrevious.generated.js.map +0 -1
  244. package/lib/test/utils.spec.js +0 -31
  245. package/lib/test/utils.spec.js.map +0 -1
  246. /package/{dist → lib}/tsdoc-metadata.json +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"file":"connectionStateHandler.spec.js","sourceRoot":"","sources":["../../src/test/connectionStateHandler.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { strict as assert } from \"assert\";\nimport { TypedEventEmitter } from \"@fluid-internal/client-utils\";\nimport {\n\tIClient,\n\tIClientConfiguration,\n\tConnectionMode,\n\tITokenClaims,\n\tISequencedClient,\n} from \"@fluidframework/protocol-definitions\";\nimport { IDeltaManager, IDeltaManagerEvents } from \"@fluidframework/container-definitions\";\nimport { SinonFakeTimers, useFakeTimers } from \"sinon\";\nimport { ITelemetryBaseProperties } from \"@fluidframework/core-interfaces\";\nimport { createChildLogger, TelemetryEventCategory } from \"@fluidframework/telemetry-utils\";\nimport { Audience } from \"../audience.js\";\nimport { ConnectionState } from \"../connectionState.js\";\nimport {\n\tIConnectionStateHandlerInputs,\n\tIConnectionStateHandler,\n\tcreateConnectionStateHandlerCore,\n} from \"../connectionStateHandler.js\";\nimport { IConnectionDetailsInternal } from \"../contracts.js\";\nimport { ProtocolHandler } from \"../protocol.js\";\n\nclass MockDeltaManagerForCatchingUp\n\textends TypedEventEmitter<IDeltaManagerEvents>\n\timplements Pick<IDeltaManager<any, any>, \"lastSequenceNumber\" | \"lastKnownSeqNumber\">\n{\n\tlastSequenceNumber: number = 5;\n\tlastKnownSeqNumber: number = 10;\n\tcatchUp(seq = 10) {\n\t\tthis.lastKnownSeqNumber = seq;\n\t\tthis.lastSequenceNumber = seq;\n\t\tthis.emit(\"op\", { sequenceNumber: this.lastKnownSeqNumber });\n\t}\n}\n\ndescribe(\"ConnectionStateHandler Tests\", () => {\n\tlet clock: SinonFakeTimers;\n\tlet handlerInputs: IConnectionStateHandlerInputs;\n\tlet connectionStateHandler: IConnectionStateHandler;\n\tlet protocolHandler: ProtocolHandler;\n\tlet shouldClientJoinWrite: boolean;\n\tlet connectionDetails: IConnectionDetailsInternal;\n\tlet connectionDetails2: IConnectionDetailsInternal;\n\tlet connectionDetails3: IConnectionDetailsInternal;\n\tconst expectedTimeout = 90000;\n\tconst pendingClientId = \"pendingClientId\";\n\tconst pendingClientId2 = \"pendingClientId2\";\n\tconst pendingClientId3 = \"pendingClientId3\";\n\tlet deltaManagerForCatchingUp: MockDeltaManagerForCatchingUp;\n\tlet connectionStateHandler_receivedAddMemberEvent: (id: string) => void;\n\tlet connectionStateHandler_receivedJoinSignalEvent: (\n\t\tdetails: IConnectionDetailsInternal,\n\t) => void;\n\tlet connectionStateHandler_receivedRemoveMemberEvent: (id: string) => void;\n\n\t// Stash the real setTimeout because sinon fake timers will hijack it.\n\tconst realSetTimeout = setTimeout;\n\n\t// function to yield control in the Javascript event loop.\n\tasync function yieldEventLoop(): Promise<void> {\n\t\tawait new Promise<void>((resolve) => {\n\t\t\trealSetTimeout(resolve, 0);\n\t\t});\n\t}\n\n\tasync function tickClock(tickValue: number) {\n\t\tclock.tick(tickValue);\n\n\t\t// Yield the event loop because the outbound op will be processed asynchronously.\n\t\tawait yieldEventLoop();\n\t}\n\n\tfunction createHandler(\n\t\tconnectedRaisedWhenCaughtUp: boolean,\n\t\treadClientsWaitForJoinSignal: boolean,\n\t) {\n\t\tconst handler = createConnectionStateHandlerCore(\n\t\t\tconnectedRaisedWhenCaughtUp,\n\t\t\treadClientsWaitForJoinSignal,\n\t\t\thandlerInputs,\n\t\t\tdeltaManagerForCatchingUp as any,\n\t\t\tundefined,\n\t\t);\n\t\thandler.initProtocol(protocolHandler);\n\t\treturn handler;\n\t}\n\n\tbefore(() => {\n\t\tclock = useFakeTimers();\n\t});\n\n\tbeforeEach(() => {\n\t\tconnectionDetails = {\n\t\t\tclientId: pendingClientId,\n\t\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\t\t\tclaims: {} as ITokenClaims,\n\t\t\tmode: \"read\",\n\t\t\tversion: \"0.1\",\n\t\t\tinitialClients: [],\n\t\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\t\t\tserviceConfiguration: {} as IClientConfiguration,\n\t\t\tcheckpointSequenceNumber: undefined,\n\t\t\treason: { text: \"test\" },\n\t\t};\n\t\tconnectionDetails2 = {\n\t\t\tclientId: pendingClientId2,\n\t\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\t\t\tclaims: {} as ITokenClaims,\n\t\t\tmode: \"write\",\n\t\t\tversion: \"0.1\",\n\t\t\tinitialClients: [],\n\t\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\t\t\tserviceConfiguration: {} as IClientConfiguration,\n\t\t\tcheckpointSequenceNumber: undefined,\n\t\t\treason: { text: \"test\" },\n\t\t};\n\t\tconnectionDetails3 = {\n\t\t\tclientId: pendingClientId3,\n\t\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\t\t\tclaims: {} as ITokenClaims,\n\t\t\tmode: \"write\",\n\t\t\tversion: \"0.1\",\n\t\t\tinitialClients: [],\n\t\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\t\t\tserviceConfiguration: {} as IClientConfiguration,\n\t\t\tcheckpointSequenceNumber: undefined,\n\t\t\treason: { text: \"test\" },\n\t\t};\n\n\t\tprotocolHandler = new ProtocolHandler(\n\t\t\t{ minimumSequenceNumber: 0, sequenceNumber: 0 }, // attributes\n\t\t\t{ members: [], proposals: [], values: [] }, // quorumSnapshot\n\t\t\t(key, value) => 0, // sendProposal\n\t\t\tnew Audience(),\n\t\t\t(clientId: string) => false, // shouldClientHaveLeft\n\t\t);\n\t\tshouldClientJoinWrite = false;\n\t\thandlerInputs = {\n\t\t\tmaxClientLeaveWaitTime: expectedTimeout,\n\t\t\tshouldClientJoinWrite: () => shouldClientJoinWrite,\n\t\t\tlogConnectionIssue: (\n\t\t\t\teventName: string,\n\t\t\t\tcategory: TelemetryEventCategory,\n\t\t\t\tdetails?: ITelemetryBaseProperties,\n\t\t\t) => {\n\t\t\t\tthrow new Error(`logConnectionIssue: ${eventName} ${JSON.stringify(details)}`);\n\t\t\t},\n\t\t\tconnectionStateChanged: () => {},\n\t\t\tlogger: createChildLogger(),\n\t\t\tclientShouldHaveLeft: (clientId: string) => {},\n\t\t};\n\n\t\tdeltaManagerForCatchingUp = new MockDeltaManagerForCatchingUp();\n\n\t\tconnectionStateHandler = createHandler(\n\t\t\tfalse, // connectedRaisedWhenCaughtUp,\n\t\t\tfalse,\n\t\t); // readClientsWaitForJoinSignal\n\n\t\tconnectionStateHandler_receivedAddMemberEvent = (id: string) => {\n\t\t\tprotocolHandler.quorum.addMember(id, { client: {} } as any as ISequencedClient);\n\t\t};\n\t\tconnectionStateHandler_receivedRemoveMemberEvent = (id: string) => {\n\t\t\tprotocolHandler.quorum.removeMember(id);\n\t\t};\n\t\tconnectionStateHandler_receivedJoinSignalEvent = (details: IConnectionDetailsInternal) => {\n\t\t\tprotocolHandler.audience.addMember(details.clientId, {\n\t\t\t\tmode: details.mode,\n\t\t\t} as any as IClient);\n\t\t};\n\t});\n\n\tafterEach(() => {\n\t\t// Get rid of timers\n\t\tconnectionStateHandler.receivedDisconnectEvent({ text: \"the end of test\" });\n\t\tconnectionStateHandler.dispose();\n\t});\n\n\tit(\"Should move to connected state on normal flow for read client\", async () => {\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.Disconnected,\n\t\t\t\"Client should be in disconnected state\",\n\t\t);\n\t\tconnectionStateHandler.receivedConnectEvent(connectionDetails);\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.Connected,\n\t\t\t\"Read Client should be in connected state\",\n\t\t);\n\t});\n\n\tit(\"Should move to connected after catching up for read client #1\", async () => {\n\t\tconnectionStateHandler = createHandler(\n\t\t\ttrue, // connectedRaisedWhenCaughtUp\n\t\t\tfalse,\n\t\t); // readClientsWaitForJoinSignal\n\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.Disconnected,\n\t\t\t\"Client should be in Disconnected state\",\n\t\t);\n\t\tconnectionStateHandler.establishingConnection({ text: \"read\" });\n\t\tconnectionStateHandler.receivedConnectEvent(connectionDetails);\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.CatchingUp,\n\t\t\t\"Client should be in CatchingUp state\",\n\t\t);\n\n\t\tdeltaManagerForCatchingUp.catchUp();\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.Connected,\n\t\t\t\"Read Client should be in Connected state\",\n\t\t);\n\t});\n\n\tit(\"Should move to connected after catching up for read client #2\", async () => {\n\t\tconnectionStateHandler = createHandler(\n\t\t\ttrue, // connectedRaisedWhenCaughtUp\n\t\t\ttrue,\n\t\t); // readClientsWaitForJoinSignal\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.Disconnected,\n\t\t\t\"Client should be in Disconnected state\",\n\t\t);\n\n\t\tconnectionStateHandler.establishingConnection({ text: \"read\" });\n\t\tconnectionStateHandler.receivedConnectEvent(connectionDetails);\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.CatchingUp,\n\t\t\t\"Client should be in CatchingUp state\",\n\t\t);\n\n\t\tdeltaManagerForCatchingUp.catchUp();\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.CatchingUp,\n\t\t\t\"Client should be in CatchingUp state\",\n\t\t);\n\n\t\tconnectionStateHandler_receivedJoinSignalEvent(connectionDetails);\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.Connected,\n\t\t\t\"Read Client should be in Connected state\",\n\t\t);\n\t});\n\n\tit(\"Should move to connected after catching up for read client #3\", async () => {\n\t\tconnectionStateHandler = createHandler(\n\t\t\ttrue, // connectedRaisedWhenCaughtUp\n\t\t\ttrue,\n\t\t); // readClientsWaitForJoinSignal\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.Disconnected,\n\t\t\t\"Client should be in Disconnected state\",\n\t\t);\n\n\t\tconnectionStateHandler.establishingConnection({ text: \"read\" });\n\t\tconnectionStateHandler.receivedConnectEvent(connectionDetails);\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.CatchingUp,\n\t\t\t\"Client should be in CatchingUp state\",\n\t\t);\n\n\t\tconnectionStateHandler_receivedJoinSignalEvent(connectionDetails);\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.CatchingUp,\n\t\t\t\"Client should be in CatchingUp state\",\n\t\t);\n\n\t\tdeltaManagerForCatchingUp.catchUp();\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.Connected,\n\t\t\t\"Read Client should be in Connected state\",\n\t\t);\n\t});\n\n\tit(\"Should move to connected after receiving join op for read client\", async () => {\n\t\tconnectionStateHandler = createHandler(\n\t\t\tfalse, // connectedRaisedWhenCaughtUp\n\t\t\ttrue,\n\t\t); // readClientsWaitForJoinSignal\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.Disconnected,\n\t\t\t\"Client should be in Disconnected state\",\n\t\t);\n\n\t\tconnectionStateHandler.receivedConnectEvent(connectionDetails);\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.CatchingUp,\n\t\t\t\"Client should be in CatchingUp state\",\n\t\t);\n\n\t\tconnectionStateHandler_receivedAddMemberEvent(pendingClientId);\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.Connected,\n\t\t\t\"Read Client should be in Connected state\",\n\t\t);\n\t});\n\n\tit(\"Changes in lastKnownSeqNumber by join signal should be picked up\", async () => {\n\t\tconnectionStateHandler = createHandler(\n\t\t\ttrue, // connectedRaisedWhenCaughtUp\n\t\t\ttrue,\n\t\t); // readClientsWaitForJoinSignal\n\n\t\tconnectionStateHandler.establishingConnection({ text: \"write\" });\n\t\tconnectionStateHandler.receivedConnectEvent(connectionDetails);\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.CatchingUp,\n\t\t\t\"Client should be in CatchingUp state\",\n\t\t);\n\n\t\tconst lastKnown = deltaManagerForCatchingUp.lastKnownSeqNumber;\n\t\tconst signalRef = lastKnown + 10;\n\n\t\tdeltaManagerForCatchingUp.catchUp(lastKnown);\n\t\tdeltaManagerForCatchingUp.lastKnownSeqNumber = signalRef;\n\t\tconnectionStateHandler_receivedJoinSignalEvent(connectionDetails);\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.CatchingUp,\n\t\t\t\"Client should be in CatchingUp state\",\n\t\t);\n\n\t\tdeltaManagerForCatchingUp.catchUp(signalRef);\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.Connected,\n\t\t\t\"Read Client should be in Connected state\",\n\t\t);\n\t});\n\n\tit(\"Should move to connected state on normal flow for write client\", async () => {\n\t\tconnectionDetails.mode = \"write\";\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.Disconnected,\n\t\t\t\"Client should be in disconnected state\",\n\t\t);\n\t\tconnectionStateHandler.receivedConnectEvent(connectionDetails);\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.CatchingUp,\n\t\t\t\"Client should be in connecting state\",\n\t\t);\n\t\tconnectionStateHandler_receivedAddMemberEvent(\"anotherClientId\");\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.CatchingUp,\n\t\t\t\"Some other client joined.\",\n\t\t);\n\t\tconnectionStateHandler_receivedAddMemberEvent(pendingClientId);\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.Connected,\n\t\t\t\"Client should be in connected state\",\n\t\t);\n\t});\n\n\tit(\"Should move to connected state after catching up for write client\", async () => {\n\t\tconnectionDetails.mode = \"write\";\n\t\tconnectionStateHandler = createHandler(\n\t\t\ttrue, // connectedRaisedWhenCaughtUp\n\t\t\tfalse,\n\t\t); // readClientsWaitForJoinSignal\n\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.Disconnected,\n\t\t\t\"Client should be in Disconnected state\",\n\t\t);\n\n\t\tconnectionStateHandler.establishingConnection({ text: \"write\" });\n\t\tconnectionStateHandler.receivedConnectEvent(connectionDetails);\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.CatchingUp,\n\t\t\t\"Client should be in CatchingUp state\",\n\t\t);\n\t\tconnectionStateHandler_receivedAddMemberEvent(\"anotherClientId\");\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.CatchingUp,\n\t\t\t\"Some other client joined.\",\n\t\t);\n\t\tconnectionStateHandler_receivedAddMemberEvent(pendingClientId);\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.CatchingUp,\n\t\t\t\"Client should be in CatchingUp state until caught up\",\n\t\t);\n\t\tdeltaManagerForCatchingUp.catchUp();\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.Connected,\n\t\t\t\"Client should be in Connected state\",\n\t\t);\n\t});\n\n\tit(\"Connect write first, init protocol later #1\", async () => {\n\t\t// ConnectionStateManager without initialized protocol\n\t\tconnectionStateHandler = createConnectionStateHandlerCore(\n\t\t\tfalse, // connectedRaisedWhenCaughtUp,\n\t\t\tfalse, // readClientsWaitForJoinSignal\n\t\t\thandlerInputs,\n\t\t\tdeltaManagerForCatchingUp as any,\n\t\t\tundefined,\n\t\t);\n\n\t\tconnectionDetails.mode = \"write\";\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.Disconnected,\n\t\t\t\"Client should be in disconnected state\",\n\t\t);\n\t\tconnectionStateHandler.receivedConnectEvent(connectionDetails);\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.CatchingUp,\n\t\t\t\"Client should be in connecting state\",\n\t\t);\n\n\t\t// init protocol\n\t\tconnectionStateHandler.initProtocol(protocolHandler);\n\n\t\tconnectionStateHandler_receivedAddMemberEvent(pendingClientId);\n\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.Connected,\n\t\t\t\"Client should be in connected state\",\n\t\t);\n\t});\n\n\tit(\"Connect write first, init protocol later #2\", async () => {\n\t\t// ConnectionStateManager without initialized protocol\n\t\tconnectionStateHandler = createConnectionStateHandlerCore(\n\t\t\tfalse, // connectedRaisedWhenCaughtUp,\n\t\t\tfalse, // readClientsWaitForJoinSignal\n\t\t\thandlerInputs,\n\t\t\tdeltaManagerForCatchingUp as any,\n\t\t\tundefined,\n\t\t);\n\n\t\tconnectionDetails.mode = \"write\";\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.Disconnected,\n\t\t\t\"Client should be in disconnected state\",\n\t\t);\n\t\tconnectionStateHandler.receivedConnectEvent(connectionDetails);\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.CatchingUp,\n\t\t\t\"Client should be in connecting state\",\n\t\t);\n\n\t\t/*\n There is a tiny tiny race possible, where these events happen in this order:\n 1. A connection is established (no \"cached\" mode is used, so it happens in parallel / faster than other steps)\n 2. Some other client produces a summary\n 3. We get \"lucky\" and load from that summary as our initial snapshot\n 4. ConnectionStateHandler.initProtocol is called, \"self\" is already in the quorum.\n We could avoid this sequence (and delete this test case and handling in initProtocol()) if\n we move connection lower in Container.load().\n */\n\t\tconnectionStateHandler_receivedAddMemberEvent(pendingClientId);\n\n\t\t// init protocol\n\t\tconnectionStateHandler.initProtocol(protocolHandler);\n\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.Connected,\n\t\t\t\"Client should be in connected state\",\n\t\t);\n\t});\n\n\tit(\"Should wait for previous client to leave before moving to connected state\", async () => {\n\t\tconnectionDetails.mode = \"write\";\n\t\tconnectionStateHandler.receivedConnectEvent(connectionDetails);\n\t\tconnectionStateHandler_receivedAddMemberEvent(pendingClientId);\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.Connected,\n\t\t\t\"Client should be in connected state\",\n\t\t);\n\n\t\tshouldClientJoinWrite = true;\n\t\t// Disconnect the client\n\t\tconnectionStateHandler.receivedDisconnectEvent({ text: \"Test\" });\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.Disconnected,\n\t\t\t\"Client should be in disconnected state\",\n\t\t);\n\n\t\t// Make new client join so that it waits for previous client to leave\n\t\tconnectionStateHandler.receivedConnectEvent(connectionDetails2);\n\t\tconnectionStateHandler_receivedAddMemberEvent(pendingClientId2);\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.CatchingUp,\n\t\t\t\"Client 2 should be in connecting state as we are waiting for leave\",\n\t\t);\n\n\t\t// Send leave\n\t\tconnectionStateHandler_receivedRemoveMemberEvent(pendingClientId);\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.Connected,\n\t\t\t\"Client 2 should be in connected state\",\n\t\t);\n\t});\n\n\tit(\"Should wait for previous client to leave before moving to connected state, even if already in quorum\", async () => {\n\t\tconnectionDetails.mode = \"write\";\n\t\tconnectionStateHandler.receivedConnectEvent(connectionDetails);\n\t\tconnectionStateHandler_receivedAddMemberEvent(pendingClientId);\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.Connected,\n\t\t\t\"Client should be in connected state\",\n\t\t);\n\n\t\tshouldClientJoinWrite = true;\n\t\t// Disconnect the client\n\t\tconnectionStateHandler.receivedDisconnectEvent({ text: \"Test\" });\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.Disconnected,\n\t\t\t\"Client should be in disconnected state\",\n\t\t);\n\n\t\t// Make new client join so that it waits for previous client to leave\n\t\t// Put Client 2 in quorum before receiving connect event\n\t\tconnectionStateHandler_receivedAddMemberEvent(pendingClientId2);\n\t\tconnectionStateHandler.receivedConnectEvent(connectionDetails2);\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.CatchingUp,\n\t\t\t\"Client 2 should be in connecting state as we are waiting for leave\",\n\t\t);\n\n\t\t// Send leave\n\t\tconnectionStateHandler_receivedRemoveMemberEvent(pendingClientId);\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.Connected,\n\t\t\t\"Client 2 should be in connected state\",\n\t\t);\n\t});\n\n\tit(\"read connection following write connection won't have leave timer\", async () => {\n\t\t// Connect a write client, to be Disconnected\n\t\tconnectionDetails.mode = \"write\";\n\t\tconnectionStateHandler.receivedConnectEvent(connectionDetails);\n\t\tconnectionStateHandler_receivedAddMemberEvent(pendingClientId);\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.Connected,\n\t\t\t\"Client should be in connected state\",\n\t\t);\n\n\t\t// Disconnect the first client, indicating all pending ops were ack'd\n\t\tshouldClientJoinWrite = false;\n\t\tconnectionStateHandler.receivedDisconnectEvent({ text: \"Test\" });\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.Disconnected,\n\t\t\t\"Client should be in disconnected state\",\n\t\t);\n\n\t\t// Make new client join as read - no waiting for leave since shouldClientJoinWrite is false\n\t\tconnectionDetails3.mode = \"read\";\n\t\tconnectionStateHandler.receivedConnectEvent(connectionDetails3);\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.Connected,\n\t\t\t\"Client 2 should be in connected state\",\n\t\t);\n\t});\n\n\tit(\"Should wait for timeout before moving to connected state if no leave received\", async () => {\n\t\tconnectionDetails.mode = \"write\";\n\t\tconnectionStateHandler.receivedConnectEvent(connectionDetails);\n\t\tconnectionStateHandler_receivedAddMemberEvent(pendingClientId);\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.Connected,\n\t\t\t\"Client should be in connected state\",\n\t\t);\n\n\t\tshouldClientJoinWrite = true;\n\t\t// Disconnect the client\n\t\tconnectionStateHandler.receivedDisconnectEvent({ text: \"Test\" });\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.Disconnected,\n\t\t\t\"Client should be in disconnected state\",\n\t\t);\n\n\t\t// Make new client join so that it waits for previous client to leave\n\t\tconnectionStateHandler.receivedConnectEvent(connectionDetails2);\n\t\tconnectionStateHandler_receivedAddMemberEvent(pendingClientId2);\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.CatchingUp,\n\t\t\t\"Client 2 should be in connecting state as we are waiting for timeout\",\n\t\t);\n\n\t\t// Check state before timeout\n\t\tawait tickClock(expectedTimeout - 1);\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.CatchingUp,\n\t\t\t\"Client 2 should still be in connecting state as we are waiting for timeout\",\n\t\t);\n\n\t\tawait tickClock(1);\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.Connected,\n\t\t\t\"Client 2 should now be in connected state\",\n\t\t);\n\t});\n\n\tit(\"Should wait for Saved event before moving to connected state if no leave received\", async () => {\n\t\tconnectionDetails.mode = \"write\";\n\t\tconnectionStateHandler.receivedConnectEvent(connectionDetails);\n\t\tconnectionStateHandler_receivedAddMemberEvent(pendingClientId);\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.Connected,\n\t\t\t\"Client should be in connected state\",\n\t\t);\n\n\t\tshouldClientJoinWrite = true;\n\t\t// Disconnect the client\n\t\tconnectionStateHandler.receivedDisconnectEvent({ text: \"Test\" });\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.Disconnected,\n\t\t\t\"Client should be in disconnected state\",\n\t\t);\n\n\t\t// Make new client join so that it waits for previous client to leave\n\t\tconnectionStateHandler.receivedConnectEvent(connectionDetails2);\n\t\tconnectionStateHandler_receivedAddMemberEvent(pendingClientId2);\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.CatchingUp,\n\t\t\t\"Client 2 should be in connecting state as we are waiting for timeout\",\n\t\t);\n\n\t\t// Check state before timeout\n\t\tawait tickClock(expectedTimeout - 1);\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.CatchingUp,\n\t\t\t\"Client 2 should still be in connecting state as we are waiting for timeout\",\n\t\t);\n\n\t\t// Fire the container saved event.\n\t\tconnectionStateHandler.containerSaved();\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.Connected,\n\t\t\t\"Client 2 should now be in connected state\",\n\t\t);\n\t});\n\n\tit(\"All pending state should be cleared after disconnect\", async () => {\n\t\tconnectionDetails.mode = \"write\";\n\t\tconnectionStateHandler.receivedConnectEvent(connectionDetails);\n\t\tassert(\n\t\t\tconnectionStateHandler.pendingClientId !== undefined,\n\t\t\t\"pendingClientId should be set after receiving 'connect' event\",\n\t\t);\n\n\t\tconnectionStateHandler.receivedDisconnectEvent({ text: \"test\" });\n\t\tassert(\n\t\t\tconnectionStateHandler.pendingClientId === undefined,\n\t\t\t\"pendingClientId should not be set after receiving 'disconnect' event\",\n\t\t);\n\t});\n\n\tasync function testComplex(client3mode: ConnectionMode) {\n\t\tconnectionDetails.mode = \"write\";\n\t\tconnectionStateHandler.receivedConnectEvent(connectionDetails);\n\t\tconnectionStateHandler_receivedAddMemberEvent(pendingClientId);\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.Connected,\n\t\t\t\"Client 1 should be in connected state\",\n\t\t);\n\n\t\tshouldClientJoinWrite = true;\n\t\t// Disconnect the client\n\t\tconnectionStateHandler.receivedDisconnectEvent({ text: \"Test\" });\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.Disconnected,\n\t\t\t\"Client 1 should be in disconnected state\",\n\t\t);\n\n\t\t// Make new client join but disconnect it from connecting state\n\t\tconnectionStateHandler.receivedConnectEvent(connectionDetails2);\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.CatchingUp,\n\t\t\t\"Client 2 should be in connecting state\",\n\t\t);\n\t\tconnectionStateHandler.receivedDisconnectEvent({ text: \"Test\" });\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.Disconnected,\n\t\t\t\"Client 2 should be in disconnected state\",\n\t\t);\n\n\t\t// Make new client 3 join so that it waits for client 1 to leave\n\t\t// This is rather tricky case when client3mode === \"read\", as we are testing adding \"read\" client when\n\t\t// shouldClientJoinWrite() reports true.\n\t\tconnectionDetails3.mode = client3mode;\n\t\tconnectionStateHandler.receivedConnectEvent(connectionDetails3);\n\t\tconnectionStateHandler_receivedAddMemberEvent(pendingClientId3);\n\n\t\t// Send leave for client 2 and check that client 3 should not move to connected state as we were waiting\n\t\t// on client 1 leave\n\t\tconnectionStateHandler_receivedAddMemberEvent(pendingClientId2);\n\t\tconnectionStateHandler_receivedRemoveMemberEvent(pendingClientId2);\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.CatchingUp,\n\t\t\t\"Client 3 should still be in connecting state\",\n\t\t);\n\n\t\t// Client 1 leaves.\n\t\tconnectionStateHandler_receivedRemoveMemberEvent(pendingClientId);\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.Connected,\n\t\t\t\"Client 3 should move to connected state\",\n\t\t);\n\t\t// Timeout should not raise any error as timer should be cleared\n\t\tawait tickClock(expectedTimeout);\n\t}\n\n\tit(\"Should wait for client 1 to leave before moving to connected state(Client 3) when client 2 got disconnected from connecting state #1\", async () => {\n\t\treturn testComplex(\"read\");\n\t});\n\n\tit(\"Should wait for client 1 to leave before moving to connected state(Client 3) when client 2 got disconnected from connecting state #2\", async () => {\n\t\treturn testComplex(\"write\");\n\t});\n\n\tit(\"Should wait for client 1 timeout before moving to connected state(Client 3) when client 2 got disconnected from connecting state #3\", async () => {\n\t\tconnectionDetails.mode = \"write\";\n\t\tconnectionStateHandler.receivedConnectEvent(connectionDetails);\n\t\tconnectionStateHandler_receivedAddMemberEvent(pendingClientId);\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.Connected,\n\t\t\t\"Client 1 should be in connected state\",\n\t\t);\n\n\t\tshouldClientJoinWrite = true;\n\t\t// Disconnect the client\n\t\tconnectionStateHandler.receivedDisconnectEvent({ text: \"Test\" });\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.Disconnected,\n\t\t\t\"Client 1 should be in disconnected state\",\n\t\t);\n\n\t\t// Make new client join but disconnect it from connecting state\n\t\tconnectionStateHandler.receivedConnectEvent(connectionDetails2);\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.CatchingUp,\n\t\t\t\"Client 2 should be in connecting state\",\n\t\t);\n\t\tconnectionStateHandler.receivedDisconnectEvent({ text: \"Test\" });\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.Disconnected,\n\t\t\t\"Client 2 should be in disconnected state\",\n\t\t);\n\n\t\t// Make new client 3 join so that it waits for client 1 to leave\n\t\tconnectionStateHandler.receivedConnectEvent(connectionDetails3);\n\t\tconnectionStateHandler_receivedAddMemberEvent(pendingClientId3);\n\n\t\t// Send leave for client 2 and check that client 3 should not move to connected state as we were waiting\n\t\t// on client 1 leave.\n\t\tconnectionStateHandler_receivedAddMemberEvent(pendingClientId2);\n\t\tconnectionStateHandler_receivedRemoveMemberEvent(pendingClientId2);\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.CatchingUp,\n\t\t\t\"Client 3 should still be in connecting state\",\n\t\t);\n\n\t\t// Pass some time.\n\t\tawait tickClock(expectedTimeout - 1);\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.CatchingUp,\n\t\t\t\"Client 3 should still be in connecting state as timeout has not occured\",\n\t\t);\n\n\t\tawait tickClock(1);\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.Connected,\n\t\t\t\"Client 3 should move to connected state\",\n\t\t);\n\t\t// Sending client 1 leave now should not cause any error\n\t\tconnectionStateHandler_receivedRemoveMemberEvent(pendingClientId);\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.Connected,\n\t\t\t\"Client 3 should move to connected state\",\n\t\t);\n\t});\n\n\tit(\"Should wait for savedEvent before moving to connected state(Client 3) when client 2 got disconnected from connecting state\", async () => {\n\t\tconnectionDetails.mode = \"write\";\n\t\tconnectionStateHandler.receivedConnectEvent(connectionDetails);\n\t\tconnectionStateHandler_receivedAddMemberEvent(pendingClientId);\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.Connected,\n\t\t\t\"Client 1 should be in connected state\",\n\t\t);\n\n\t\tshouldClientJoinWrite = true;\n\t\t// Disconnect the client\n\t\tconnectionStateHandler.receivedDisconnectEvent({ text: \"Test\" });\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.Disconnected,\n\t\t\t\"Client 1 should be in disconnected state\",\n\t\t);\n\n\t\t// Make new client join but disconnect it from connecting state\n\t\tconnectionStateHandler.receivedConnectEvent(connectionDetails2);\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.CatchingUp,\n\t\t\t\"Client 2 should be in connecting state\",\n\t\t);\n\t\tconnectionStateHandler.receivedDisconnectEvent({ text: \"Test\" });\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.Disconnected,\n\t\t\t\"Client 2 should be in disconnected state\",\n\t\t);\n\n\t\t// Make new client 3 join so that it waits for client 1 to leave\n\t\tconnectionStateHandler.receivedConnectEvent(connectionDetails3);\n\t\tconnectionStateHandler_receivedAddMemberEvent(pendingClientId3);\n\n\t\t// Send leave for client 2 and check that client 3 should not move to connected state as we were waiting\n\t\t// on client 1 leave.\n\t\tconnectionStateHandler_receivedAddMemberEvent(pendingClientId2);\n\t\tconnectionStateHandler_receivedRemoveMemberEvent(pendingClientId2);\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.CatchingUp,\n\t\t\t\"Client 3 should still be in connecting state\",\n\t\t);\n\n\t\t// Pass some time.\n\t\tawait tickClock(expectedTimeout - 1);\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.CatchingUp,\n\t\t\t\"Client 3 should still be in connecting state as timeout has not occured\",\n\t\t);\n\n\t\tconnectionStateHandler.containerSaved();\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.Connected,\n\t\t\t\"Client 3 should move to connected state\",\n\t\t);\n\t\t// Sending client 1 leave now should not cause any error\n\t\tconnectionStateHandler_receivedRemoveMemberEvent(pendingClientId);\n\t\tassert.strictEqual(\n\t\t\tconnectionStateHandler.connectionState,\n\t\t\tConnectionState.Connected,\n\t\t\t\"Client 3 should move to connected state\",\n\t\t);\n\t});\n\n\tit(\n\t\t\"Should wait for client 1 to leave before moving to connected state(Client 3) when client 2 \" +\n\t\t\t\"got disconnected from connected state\",\n\t\tasync () => {\n\t\t\tconnectionDetails.mode = \"write\";\n\t\t\tconnectionStateHandler.receivedConnectEvent(connectionDetails);\n\t\t\tconnectionStateHandler_receivedAddMemberEvent(pendingClientId);\n\t\t\tassert.strictEqual(\n\t\t\t\tconnectionStateHandler.connectionState,\n\t\t\t\tConnectionState.Connected,\n\t\t\t\t\"Client 1 should be in connected state\",\n\t\t\t);\n\n\t\t\tshouldClientJoinWrite = true;\n\t\t\t// Disconnect the client\n\t\t\tconnectionStateHandler.receivedDisconnectEvent({ text: \"Test\" });\n\t\t\tassert.strictEqual(\n\t\t\t\tconnectionStateHandler.connectionState,\n\t\t\t\tConnectionState.Disconnected,\n\t\t\t\t\"Client 1 should be in disconnected state\",\n\t\t\t);\n\n\t\t\t// Make new client join but disconnect it from connected state\n\t\t\tconnectionStateHandler.receivedConnectEvent(connectionDetails2);\n\t\t\tconnectionStateHandler_receivedAddMemberEvent(pendingClientId2);\n\t\t\tassert.strictEqual(\n\t\t\t\tconnectionStateHandler.connectionState,\n\t\t\t\tConnectionState.CatchingUp,\n\t\t\t\t\"Client 2 should still be in connecting state\",\n\t\t\t);\n\t\t\tconnectionStateHandler.receivedDisconnectEvent({ text: \"Test\" });\n\t\t\tassert.strictEqual(\n\t\t\t\tconnectionStateHandler.connectionState,\n\t\t\t\tConnectionState.Disconnected,\n\t\t\t\t\"Client 2 should be in disconnected state\",\n\t\t\t);\n\n\t\t\t// Make new client 3 join so that it waits for client 1 to leave\n\t\t\tconnectionStateHandler.receivedConnectEvent(connectionDetails3);\n\t\t\tconnectionStateHandler_receivedAddMemberEvent(pendingClientId3);\n\t\t\tassert.strictEqual(\n\t\t\t\tconnectionStateHandler.connectionState,\n\t\t\t\tConnectionState.CatchingUp,\n\t\t\t\t\"Client 3 should still be in connecting state\",\n\t\t\t);\n\n\t\t\t// Send leave for client 2 and check that client 3 should not move to connected state as we were waiting\n\t\t\t// on client 1 leave\n\t\t\tconnectionStateHandler_receivedRemoveMemberEvent(pendingClientId2);\n\t\t\tassert.strictEqual(\n\t\t\t\tconnectionStateHandler.connectionState,\n\t\t\t\tConnectionState.CatchingUp,\n\t\t\t\t\"Client 3 should still be in connecting state\",\n\t\t\t);\n\n\t\t\t// Client 1 leaves.\n\t\t\tconnectionStateHandler_receivedRemoveMemberEvent(pendingClientId);\n\t\t\tassert.strictEqual(\n\t\t\t\tconnectionStateHandler.connectionState,\n\t\t\t\tConnectionState.Connected,\n\t\t\t\t\"Client 3 should move to connected state\",\n\t\t\t);\n\t\t\t// Timeout should not raise any error as timer should be cleared\n\t\t\tawait tickClock(expectedTimeout);\n\t\t},\n\t);\n\n\tit(\n\t\t\"Should wait for client 1 timeout before moving to connected state(Client 3) when client 2 \" +\n\t\t\t\"got disconnected from connected state\",\n\t\tasync () => {\n\t\t\tconnectionDetails.mode = \"write\";\n\t\t\tconnectionStateHandler.receivedConnectEvent(connectionDetails);\n\t\t\tconnectionStateHandler_receivedAddMemberEvent(pendingClientId);\n\t\t\tassert.strictEqual(\n\t\t\t\tconnectionStateHandler.connectionState,\n\t\t\t\tConnectionState.Connected,\n\t\t\t\t\"Client 1 should be in connected state\",\n\t\t\t);\n\n\t\t\tshouldClientJoinWrite = true;\n\t\t\t// Disconnect the client\n\t\t\tconnectionStateHandler.receivedDisconnectEvent({ text: \"Test\" });\n\t\t\tassert.strictEqual(\n\t\t\t\tconnectionStateHandler.connectionState,\n\t\t\t\tConnectionState.Disconnected,\n\t\t\t\t\"Client 1 should be in disconnected state\",\n\t\t\t);\n\n\t\t\t// Make new client join but disconnect it from connecting state\n\t\t\tconnectionStateHandler.receivedConnectEvent(connectionDetails2);\n\t\t\tconnectionStateHandler_receivedAddMemberEvent(pendingClientId2);\n\t\t\tassert.strictEqual(\n\t\t\t\tconnectionStateHandler.connectionState,\n\t\t\t\tConnectionState.CatchingUp,\n\t\t\t\t\"Client 2 should still be in connecting state\",\n\t\t\t);\n\t\t\tconnectionStateHandler.receivedDisconnectEvent({ text: \"Test\" });\n\t\t\tassert.strictEqual(\n\t\t\t\tconnectionStateHandler.connectionState,\n\t\t\t\tConnectionState.Disconnected,\n\t\t\t\t\"Client 2 should be in disconnected state\",\n\t\t\t);\n\n\t\t\t// Make new client 3 join so that it waits for client 1 to leave\n\t\t\tconnectionStateHandler.receivedConnectEvent(connectionDetails3);\n\t\t\tconnectionStateHandler_receivedAddMemberEvent(pendingClientId3);\n\n\t\t\t// Send leave for client 2 and check that client 3 should not move to connected state as we were waiting\n\t\t\t// on client 1 leave.\n\t\t\tconnectionStateHandler_receivedRemoveMemberEvent(\"pendingClientId2\");\n\t\t\tassert.strictEqual(\n\t\t\t\tconnectionStateHandler.connectionState,\n\t\t\t\tConnectionState.CatchingUp,\n\t\t\t\t\"Client 3 should still be in connecting state\",\n\t\t\t);\n\n\t\t\t// Pass some time.\n\t\t\tawait tickClock(expectedTimeout - 1);\n\t\t\tassert.strictEqual(\n\t\t\t\tconnectionStateHandler.connectionState,\n\t\t\t\tConnectionState.CatchingUp,\n\t\t\t\t\"Client 3 should still be in connecting state as timeout has not occured\",\n\t\t\t);\n\n\t\t\tawait tickClock(1);\n\t\t\tassert.strictEqual(\n\t\t\t\tconnectionStateHandler.connectionState,\n\t\t\t\tConnectionState.Connected,\n\t\t\t\t\"Client 3 should move to connected state\",\n\t\t\t);\n\n\t\t\t// Sending client 1 leave now should not cause any error\n\t\t\tconnectionStateHandler_receivedRemoveMemberEvent(pendingClientId);\n\t\t\tassert.strictEqual(\n\t\t\t\tconnectionStateHandler.connectionState,\n\t\t\t\tConnectionState.Connected,\n\t\t\t\t\"Client 3 should move to connected state\",\n\t\t\t);\n\t\t},\n\t);\n\n\tit(\n\t\t\"Client 3 should wait for client 2(which got disconnected without sending any ops) to leave \" +\n\t\t\t\"when client 2 already waited on client 1\",\n\t\tasync () => {\n\t\t\tconnectionDetails.mode = \"write\";\n\t\t\tconnectionStateHandler.receivedConnectEvent(connectionDetails);\n\t\t\tconnectionStateHandler_receivedAddMemberEvent(pendingClientId);\n\t\t\tassert.strictEqual(\n\t\t\t\tconnectionStateHandler.connectionState,\n\t\t\t\tConnectionState.Connected,\n\t\t\t\t\"Client 1 should be in connected state\",\n\t\t\t);\n\n\t\t\tshouldClientJoinWrite = true;\n\t\t\t// Disconnect the client\n\t\t\tconnectionStateHandler.receivedDisconnectEvent({ text: \"Test\" });\n\t\t\tassert.strictEqual(\n\t\t\t\tconnectionStateHandler.connectionState,\n\t\t\t\tConnectionState.Disconnected,\n\t\t\t\t\"Client 1 should be in disconnected state\",\n\t\t\t);\n\n\t\t\t// Make new client join but disconnect it from connected state\n\t\t\tconnectionStateHandler.receivedConnectEvent(connectionDetails2);\n\t\t\tconnectionStateHandler_receivedAddMemberEvent(pendingClientId2);\n\t\t\tassert.strictEqual(\n\t\t\t\tconnectionStateHandler.connectionState,\n\t\t\t\tConnectionState.CatchingUp,\n\t\t\t\t\"Client 2 should still be in connecting state\",\n\t\t\t);\n\t\t\t// Client 1 leaves.\n\t\t\tconnectionStateHandler_receivedRemoveMemberEvent(pendingClientId);\n\n\t\t\tassert.strictEqual(\n\t\t\t\tconnectionStateHandler.connectionState,\n\t\t\t\tConnectionState.Connected,\n\t\t\t\t\"Client 2 should move to connected state\",\n\t\t\t);\n\n\t\t\t// Client 2 leaves without sending any ops.\n\t\t\tconnectionStateHandler.receivedDisconnectEvent({ text: \"Test\" });\n\t\t\tassert.strictEqual(\n\t\t\t\tconnectionStateHandler.connectionState,\n\t\t\t\tConnectionState.Disconnected,\n\t\t\t\t\"Client 2 should be in disconnected state\",\n\t\t\t);\n\n\t\t\t// Make new client 3 join. Now it should not wait for previous client as client 2 already waited.\n\t\t\tconnectionStateHandler.receivedConnectEvent(connectionDetails3);\n\t\t\tassert.strictEqual(\n\t\t\t\tconnectionStateHandler.connectionState,\n\t\t\t\tConnectionState.CatchingUp,\n\t\t\t\t\"Client 3 should still be in connecting state\",\n\t\t\t);\n\t\t\tconnectionStateHandler_receivedAddMemberEvent(pendingClientId3);\n\t\t\tassert.strictEqual(\n\t\t\t\tconnectionStateHandler.connectionState,\n\t\t\t\tConnectionState.CatchingUp,\n\t\t\t\t\"Client 3 should still be in connecting state\",\n\t\t\t);\n\n\t\t\t// Client 2 leaves.\n\t\t\tconnectionStateHandler_receivedRemoveMemberEvent(\"pendingClientId2\");\n\t\t\tassert.strictEqual(\n\t\t\t\tconnectionStateHandler.connectionState,\n\t\t\t\tConnectionState.Connected,\n\t\t\t\t\"Client 3 should move to connected state\",\n\t\t\t);\n\t\t\t// Timeout should not raise any error as timer should be cleared\n\t\t\tawait tickClock(expectedTimeout);\n\t\t},\n\t);\n\n\tafterEach(() => {\n\t\tclock.reset();\n\t});\n\n\tafter(() => {\n\t\tclock.restore();\n\t});\n});\n"]}
@@ -1,64 +0,0 @@
1
- /*!
2
- * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
- * Licensed under the MIT License.
4
- */
5
- import assert from "assert";
6
- import { TypedEventEmitter } from "@fluid-internal/client-utils";
7
- import { waitContainerToCatchUp } from "../container.js";
8
- import { ConnectionState } from "../connectionState.js";
9
- class MockDeltaManager extends TypedEventEmitter {
10
- constructor() {
11
- super(...arguments);
12
- this.hasCheckpointSequenceNumber = true;
13
- this.lastKnownSeqNumber = 2;
14
- this.lastSequenceNumber = 1;
15
- }
16
- }
17
- class MockContainer extends TypedEventEmitter {
18
- constructor() {
19
- super(...arguments);
20
- this.deltaManager = new MockDeltaManager();
21
- this.closed = false;
22
- }
23
- get mockDeltaManager() {
24
- return this.deltaManager;
25
- }
26
- connect() {
27
- this.connectionState = ConnectionState.Connected;
28
- this.emit("connected");
29
- }
30
- }
31
- describe("Container", () => {
32
- describe("waitContainerToCatchUp", () => {
33
- it("Closed Container fails", async () => {
34
- const mockContainer = new MockContainer();
35
- mockContainer.closed = true;
36
- await assert.rejects(async () => waitContainerToCatchUp(mockContainer), "Passing a closed container should throw");
37
- });
38
- it("Connected Container waits for catching up", async () => {
39
- const mockContainer = new MockContainer();
40
- mockContainer.connectionState = ConnectionState.Connected;
41
- const waitP = waitContainerToCatchUp(mockContainer);
42
- mockContainer.mockDeltaManager.emit("op", { sequenceNumber: 2 });
43
- // Should resolve immediately, otherwise test will time out
44
- await waitP;
45
- });
46
- it("Connected and caught up Container resolves immediately", async () => {
47
- const mockContainer = new MockContainer();
48
- mockContainer.mockDeltaManager.lastSequenceNumber = 2; // to match lastKnownSeqNumber
49
- mockContainer.connectionState = ConnectionState.Connected;
50
- const waitP = waitContainerToCatchUp(mockContainer);
51
- // Should resolve immediately, otherwise test will time out
52
- await waitP;
53
- });
54
- it("Disconnected Container gets Connected then waits for catching up", async () => {
55
- const mockContainer = new MockContainer();
56
- mockContainer.connectionState = ConnectionState.Disconnected;
57
- const waitP = waitContainerToCatchUp(mockContainer);
58
- mockContainer.mockDeltaManager.emit("op", { sequenceNumber: 2 });
59
- // Should resolve immediately, otherwise test will time out
60
- await waitP;
61
- });
62
- });
63
- });
64
- //# sourceMappingURL=container.spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"container.spec.js","sourceRoot":"","sources":["../../src/test/container.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,MAAM,MAAM,QAAQ,CAAC;AAU5B,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAGjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD,MAAM,gBACL,SAAQ,iBAAsC;IAD/C;;QAOC,gCAA2B,GAAG,IAAI,CAAC;QACnC,uBAAkB,GAAG,CAAC,CAAC;QACvB,uBAAkB,GAAG,CAAC,CAAC;IACxB,CAAC;CAAA;AAED,MAAM,aACL,SAAQ,iBAAmC;IAD5C;;QAIC,iBAAY,GACX,IAAI,gBAAgB,EAAS,CAAC;QAG/B,WAAM,GAAyB,KAAK,CAAC;IAgBtC,CAAC;IARA,IAAI,gBAAgB;QACnB,OAAO,IAAI,CAAC,YAAuC,CAAC;IACrD,CAAC;IAED,OAAO;QACN,IAAI,CAAC,eAAe,GAAG,eAAe,CAAC,SAAS,CAAC;QACjD,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACxB,CAAC;CACD;AAED,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;IAC1B,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;QACvC,EAAE,CAAC,wBAAwB,EAAE,KAAK,IAAI,EAAE;YACvC,MAAM,aAAa,GAAG,IAAI,aAAa,EAAE,CAAC;YAC1C,aAAa,CAAC,MAAM,GAAG,IAAI,CAAC;YAE5B,MAAM,MAAM,CAAC,OAAO,CACnB,KAAK,IAAI,EAAE,CAAC,sBAAsB,CAAC,aAAkC,CAAC,EACtE,yCAAyC,CACzC,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2CAA2C,EAAE,KAAK,IAAI,EAAE;YAC1D,MAAM,aAAa,GAAG,IAAI,aAAa,EAAE,CAAC;YAC1C,aAAa,CAAC,eAAe,GAAG,eAAe,CAAC,SAAS,CAAC;YAE1D,MAAM,KAAK,GAAG,sBAAsB,CAAC,aAAkC,CAAC,CAAC;YACzE,aAAa,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,cAAc,EAAE,CAAC,EAAE,CAAC,CAAC;YAEjE,2DAA2D;YAC3D,MAAM,KAAK,CAAC;QACb,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;YACvE,MAAM,aAAa,GAAG,IAAI,aAAa,EAAE,CAAC;YAC1C,aAAa,CAAC,gBAAgB,CAAC,kBAAkB,GAAG,CAAC,CAAC,CAAC,8BAA8B;YACrF,aAAa,CAAC,eAAe,GAAG,eAAe,CAAC,SAAS,CAAC;YAE1D,MAAM,KAAK,GAAG,sBAAsB,CAAC,aAAkC,CAAC,CAAC;YAEzE,2DAA2D;YAC3D,MAAM,KAAK,CAAC;QACb,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,kEAAkE,EAAE,KAAK,IAAI,EAAE;YACjF,MAAM,aAAa,GAAG,IAAI,aAAa,EAAE,CAAC;YAC1C,aAAa,CAAC,eAAe,GAAG,eAAe,CAAC,YAAY,CAAC;YAE7D,MAAM,KAAK,GAAG,sBAAsB,CAAC,aAAkC,CAAC,CAAC;YACzE,aAAa,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,cAAc,EAAE,CAAC,EAAE,CAAC,CAAC;YAEjE,2DAA2D;YAC3D,MAAM,KAAK,CAAC;QACb,CAAC,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport assert from \"assert\";\nimport {\n\tAttachState,\n\tIAudience,\n\tIContainer,\n\tIContainerEvents,\n\tIDeltaManager,\n\tIDeltaManagerEvents,\n\tReadOnlyInfo,\n} from \"@fluidframework/container-definitions\";\nimport { TypedEventEmitter } from \"@fluid-internal/client-utils\";\nimport { IResolvedUrl } from \"@fluidframework/driver-definitions\";\nimport { ISequencedDocumentMessage, IDocumentMessage } from \"@fluidframework/protocol-definitions\";\nimport { waitContainerToCatchUp } from \"../container.js\";\nimport { ConnectionState } from \"../connectionState.js\";\n\nclass MockDeltaManager\n\textends TypedEventEmitter<IDeltaManagerEvents>\n\timplements\n\t\tPartial<\n\t\t\tOmit<IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>, \"on\" | \"off\" | \"once\">\n\t\t>\n{\n\thasCheckpointSequenceNumber = true;\n\tlastKnownSeqNumber = 2;\n\tlastSequenceNumber = 1;\n}\n\nclass MockContainer\n\textends TypedEventEmitter<IContainerEvents>\n\timplements Partial<Omit<IContainer, \"on\" | \"off\" | \"once\">>\n{\n\tdeltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage> =\n\t\tnew MockDeltaManager() as any;\n\tresolvedUrl?: IResolvedUrl | undefined;\n\tattachState?: AttachState | undefined;\n\tclosed?: boolean | undefined = false;\n\tisDirty?: boolean | undefined;\n\tconnectionState?: ConnectionState | undefined;\n\tconnected?: boolean | undefined;\n\taudience?: IAudience | undefined;\n\tclientId?: string | undefined;\n\treadOnlyInfo?: ReadOnlyInfo | undefined;\n\n\tget mockDeltaManager() {\n\t\treturn this.deltaManager as any as MockDeltaManager;\n\t}\n\n\tconnect() {\n\t\tthis.connectionState = ConnectionState.Connected;\n\t\tthis.emit(\"connected\");\n\t}\n}\n\ndescribe(\"Container\", () => {\n\tdescribe(\"waitContainerToCatchUp\", () => {\n\t\tit(\"Closed Container fails\", async () => {\n\t\t\tconst mockContainer = new MockContainer();\n\t\t\tmockContainer.closed = true;\n\n\t\t\tawait assert.rejects(\n\t\t\t\tasync () => waitContainerToCatchUp(mockContainer as any as IContainer),\n\t\t\t\t\"Passing a closed container should throw\",\n\t\t\t);\n\t\t});\n\n\t\tit(\"Connected Container waits for catching up\", async () => {\n\t\t\tconst mockContainer = new MockContainer();\n\t\t\tmockContainer.connectionState = ConnectionState.Connected;\n\n\t\t\tconst waitP = waitContainerToCatchUp(mockContainer as any as IContainer);\n\t\t\tmockContainer.mockDeltaManager.emit(\"op\", { sequenceNumber: 2 });\n\n\t\t\t// Should resolve immediately, otherwise test will time out\n\t\t\tawait waitP;\n\t\t});\n\n\t\tit(\"Connected and caught up Container resolves immediately\", async () => {\n\t\t\tconst mockContainer = new MockContainer();\n\t\t\tmockContainer.mockDeltaManager.lastSequenceNumber = 2; // to match lastKnownSeqNumber\n\t\t\tmockContainer.connectionState = ConnectionState.Connected;\n\n\t\t\tconst waitP = waitContainerToCatchUp(mockContainer as any as IContainer);\n\n\t\t\t// Should resolve immediately, otherwise test will time out\n\t\t\tawait waitP;\n\t\t});\n\n\t\tit(\"Disconnected Container gets Connected then waits for catching up\", async () => {\n\t\t\tconst mockContainer = new MockContainer();\n\t\t\tmockContainer.connectionState = ConnectionState.Disconnected;\n\n\t\t\tconst waitP = waitContainerToCatchUp(mockContainer as any as IContainer);\n\t\t\tmockContainer.mockDeltaManager.emit(\"op\", { sequenceNumber: 2 });\n\n\t\t\t// Should resolve immediately, otherwise test will time out\n\t\t\tawait waitP;\n\t\t});\n\t});\n});\n"]}
@@ -1,405 +0,0 @@
1
- /*!
2
- * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
- * Licensed under the MIT License.
4
- */
5
- import { strict as assert } from "assert";
6
- import { EventEmitter } from "@fluid-internal/client-utils";
7
- import { MockDocumentDeltaConnection, MockDocumentService } from "@fluid-private/test-loader-utils";
8
- import { createChildLogger, MockLogger, } from "@fluidframework/telemetry-utils";
9
- import { MessageType, } from "@fluidframework/protocol-definitions";
10
- import { useFakeTimers } from "sinon";
11
- import { DeltaManager } from "../deltaManager.js";
12
- import { NoopHeuristic } from "../noopHeuristic.js";
13
- import { ConnectionManager } from "../connectionManager.js";
14
- describe("Loader", () => {
15
- describe("Container Loader", () => {
16
- describe("Delta Manager", () => {
17
- let clock;
18
- let deltaManager;
19
- let logger;
20
- let deltaConnection;
21
- let clientSeqNumber = 0;
22
- let emitter;
23
- let seq;
24
- let expectedError;
25
- const docId = "docId";
26
- const submitEvent = "test-submit";
27
- const expectedTimeout = 2000;
28
- const noopCountFrequency = 300;
29
- // Stash the real setTimeout because sinon fake timers will hijack it.
30
- const realSetTimeout = setTimeout;
31
- async function startDeltaManager(reconnectAllowed = true, dmLogger = logger, deltaStorageFactory) {
32
- const service = new MockDocumentService(deltaStorageFactory, () => {
33
- // Always create new connection, as reusing old closed connection
34
- // Forces DM into infinite reconnection loop.
35
- deltaConnection = new MockDocumentDeltaConnection("test", (messages) => emitter.emit(submitEvent, messages));
36
- return deltaConnection;
37
- });
38
- const client = {
39
- mode: "write",
40
- details: { capabilities: { interactive: true } },
41
- };
42
- deltaManager = new DeltaManager(() => service, dmLogger, () => false, (props) => new ConnectionManager(() => service, () => false, client, reconnectAllowed, dmLogger, props));
43
- const noopHeuristic = new NoopHeuristic(expectedTimeout, noopCountFrequency);
44
- noopHeuristic.on("wantsNoop", () => {
45
- deltaManager.submit(MessageType.NoOp);
46
- noopHeuristic.notifyMessageSent();
47
- });
48
- await deltaManager.attachOpHandler(0, 0, {
49
- process: (message) => noopHeuristic.notifyMessageProcessed(message),
50
- processSignal() { },
51
- });
52
- await new Promise((resolve) => {
53
- deltaManager.on("connect", resolve);
54
- deltaManager.connect({ reason: { text: "test" } });
55
- });
56
- }
57
- // function to yield control in the Javascript event loop.
58
- async function yieldEventLoop() {
59
- await new Promise((resolve) => {
60
- realSetTimeout(resolve, 0);
61
- });
62
- }
63
- function generateOp(type = MessageType.Operation) {
64
- return {
65
- clientId: "Some client ID",
66
- clientSequenceNumber: ++clientSeqNumber,
67
- minimumSequenceNumber: 0,
68
- sequenceNumber: seq++,
69
- type,
70
- };
71
- }
72
- async function sendAndReceiveOps(count, type) {
73
- for (let num = 0; num < count; ++num) {
74
- assert(!deltaConnection.disposed, "disposed");
75
- deltaManager.submit(type);
76
- deltaConnection.emitOp(docId, [
77
- {
78
- clientId: "test",
79
- clientSequenceNumber: ++clientSeqNumber,
80
- minimumSequenceNumber: 0,
81
- sequenceNumber: seq++,
82
- type,
83
- },
84
- ]);
85
- }
86
- // Yield the event loop because the inbound op will be processed asynchronously.
87
- await yieldEventLoop();
88
- }
89
- async function emitSequentialOps(count) {
90
- for (let num = 0; num < count; ++num) {
91
- assert(!deltaConnection.disposed, "disposed");
92
- deltaConnection.emitOp(docId, [generateOp()]);
93
- }
94
- // Yield the event loop because the inbound op will be processed asynchronously.
95
- await yieldEventLoop();
96
- }
97
- async function tickClock(tickValue) {
98
- clock.tick(tickValue);
99
- // Yield the event loop because the outbound op will be processed asynchronously.
100
- await yieldEventLoop();
101
- }
102
- const flushPromises = async () => new Promise((resolve) => process.nextTick(resolve));
103
- before(() => {
104
- clock = useFakeTimers();
105
- });
106
- beforeEach(async () => {
107
- seq = 1;
108
- logger = createChildLogger({ namespace: "fluid:testDeltaManager" });
109
- emitter = new EventEmitter();
110
- clientSeqNumber = 0;
111
- expectedError = undefined;
112
- });
113
- afterEach(() => {
114
- clock.reset();
115
- });
116
- after(() => {
117
- clock.restore();
118
- });
119
- describe("Update Minimum Sequence Number", () => {
120
- // helper function asserting that there is exactly one well-formed no-op
121
- function assertOneValidNoOp(messages) {
122
- assert.strictEqual(1, messages.length);
123
- assert.strictEqual(MessageType.NoOp, messages[0].type);
124
- assert.strictEqual(undefined, messages[0].contents);
125
- }
126
- it("Infinite frequency parameters disables periodic noops completely", async () => {
127
- const noopHeuristic = new NoopHeuristic(Infinity, Infinity);
128
- noopHeuristic.on("wantsNoop", () => {
129
- assert.fail("Heuristic shouldn't request noops with Infinite thresholds");
130
- });
131
- for (let num = 0; num < 1000; ++num) {
132
- noopHeuristic.notifyMessageProcessed(generateOp());
133
- }
134
- await tickClock(1000 * 1000);
135
- });
136
- it("Infinite time frequency will not generate noops at time intervals", async () => {
137
- let counter = 0;
138
- const noopHeuristic = new NoopHeuristic(Infinity, 100);
139
- noopHeuristic.on("wantsNoop", () => {
140
- counter++;
141
- noopHeuristic.notifyMessageSent();
142
- });
143
- for (let num = 0; num < 99; ++num) {
144
- noopHeuristic.notifyMessageProcessed(generateOp());
145
- }
146
- await tickClock(1000 * 1000);
147
- assert.equal(counter, 0, "No noops requested after 99 ops");
148
- noopHeuristic.notifyMessageProcessed(generateOp());
149
- await tickClock(1);
150
- assert.equal(counter, 1, "One noop should be requested");
151
- });
152
- it("Infinite op frequency will not generate noops at op intervals", async () => {
153
- let counter = 0;
154
- const noopHeuristic = new NoopHeuristic(100, Infinity);
155
- noopHeuristic.on("wantsNoop", () => {
156
- counter++;
157
- noopHeuristic.notifyMessageSent();
158
- });
159
- for (let num = 0; num < 1000; ++num) {
160
- noopHeuristic.notifyMessageProcessed(generateOp());
161
- }
162
- assert.equal(counter, 0, "No noops requested after 99 ops");
163
- await tickClock(100);
164
- assert.equal(counter, 1, "One noop should be requested");
165
- });
166
- it("1k op frequency will generate noop at op intervals", async () => {
167
- let counter = 0;
168
- const noopHeuristic = new NoopHeuristic(Infinity, 1000);
169
- noopHeuristic.on("wantsNoop", () => {
170
- counter++;
171
- noopHeuristic.notifyMessageSent();
172
- });
173
- for (let num = 0; num < 1000; ++num) {
174
- noopHeuristic.notifyMessageProcessed(generateOp());
175
- }
176
- assert.equal(counter, 0, "No noops requested after 999 ops");
177
- await tickClock(1);
178
- assert.equal(counter, 1, "One noop should be requested");
179
- });
180
- it("Should update after op count threshold", async () => {
181
- let runCount = 0;
182
- await startDeltaManager();
183
- emitter.on(submitEvent, (messages) => {
184
- assertOneValidNoOp(messages);
185
- runCount++;
186
- });
187
- await emitSequentialOps(noopCountFrequency - 1);
188
- await tickClock(expectedTimeout - 1);
189
- assert.strictEqual(runCount, 0);
190
- await emitSequentialOps(1);
191
- assert.strictEqual(runCount, 1);
192
- await emitSequentialOps(noopCountFrequency - 1);
193
- await tickClock(expectedTimeout - 1);
194
- assert.strictEqual(runCount, 1);
195
- });
196
- it("Should update after time threshold reached", async () => {
197
- let runCount = 0;
198
- await startDeltaManager();
199
- emitter.on(submitEvent, (messages) => {
200
- assertOneValidNoOp(messages);
201
- runCount++;
202
- });
203
- await emitSequentialOps(noopCountFrequency - 1);
204
- await tickClock(expectedTimeout - 1);
205
- assert.strictEqual(runCount, 0);
206
- // should run after timeout
207
- await tickClock(1);
208
- assert.strictEqual(runCount, 1);
209
- // Now timeout again should not cause noop
210
- await tickClock(expectedTimeout);
211
- await emitSequentialOps(noopCountFrequency - 1);
212
- assert.strictEqual(runCount, 1);
213
- });
214
- it("Should not update when receiving just no-ops even after timeout", async () => {
215
- await startDeltaManager();
216
- emitter.on(submitEvent, (messages) => {
217
- assertOneValidNoOp(messages);
218
- assert.fail("Should not send no-op.");
219
- });
220
- await emitSequentialOps(noopCountFrequency + 1);
221
- await tickClock(expectedTimeout);
222
- });
223
- it("Should not update if op submitted during timeout", async () => {
224
- const ignoreContent = "ignoreThisMessage";
225
- let canIgnore = true;
226
- await startDeltaManager();
227
- emitter.on(submitEvent, (messages) => {
228
- // we can ignore our own op
229
- if (messages.length === 1 &&
230
- messages[0].type === MessageType.Operation &&
231
- messages[0].contents !== undefined &&
232
- JSON.parse(messages[0].contents) === ignoreContent &&
233
- canIgnore) {
234
- canIgnore = false;
235
- return;
236
- }
237
- assert.fail("Should not send no-op.");
238
- });
239
- await emitSequentialOps(1);
240
- await tickClock(expectedTimeout - 1);
241
- deltaManager.submit(MessageType.Operation, ignoreContent);
242
- await tickClock(1);
243
- // make extra sure
244
- await tickClock(expectedTimeout);
245
- });
246
- it("Should throw error with gap in client seq num", async () => {
247
- await startDeltaManager();
248
- deltaManager.inbound.on("error", (error) => {
249
- expectedError = error;
250
- });
251
- await sendAndReceiveOps(1, MessageType.Operation);
252
- // send op with gap in clientSeqNum
253
- deltaConnection.emitOp(docId, [
254
- {
255
- clientId: "test",
256
- clientSequenceNumber: clientSeqNumber + 2,
257
- minimumSequenceNumber: 0,
258
- sequenceNumber: seq++,
259
- type: MessageType.Operation,
260
- },
261
- ]);
262
- await yieldEventLoop();
263
- assert.strictEqual(expectedError.message, "gap in client sequence number: 1");
264
- });
265
- it("Should pass with one noop sent, 0 received and one gap", async () => {
266
- await startDeltaManager();
267
- deltaManager.inbound.on("error", (error) => {
268
- expectedError = error;
269
- });
270
- await sendAndReceiveOps(1, MessageType.Operation);
271
- // send 1 noop without receiving
272
- deltaManager.submit(MessageType.NoOp);
273
- // send op with gap in clientSeqNum
274
- deltaManager.submit(MessageType.Operation);
275
- deltaConnection.emitOp(docId, [
276
- {
277
- clientId: "test",
278
- clientSequenceNumber: clientSeqNumber + 2,
279
- minimumSequenceNumber: 0,
280
- sequenceNumber: seq,
281
- type: MessageType.Operation,
282
- },
283
- ]);
284
- await yieldEventLoop();
285
- assert.strictEqual(deltaManager.lastMessage?.sequenceNumber, seq, "discrepancy in last processed seqNum");
286
- assert.strictEqual(expectedError, undefined, `Error should not happen : ${expectedError}`);
287
- });
288
- it("Should throw error with one noop sent and received, gap = 1", async () => {
289
- await startDeltaManager();
290
- deltaManager.inbound.on("error", (error) => {
291
- expectedError = error;
292
- });
293
- await sendAndReceiveOps(1, MessageType.Operation);
294
- await sendAndReceiveOps(1, MessageType.NoOp);
295
- // send op with gap in clientSeqNum
296
- deltaConnection.emitOp(docId, [
297
- {
298
- clientId: "test",
299
- clientSequenceNumber: clientSeqNumber + 2,
300
- minimumSequenceNumber: 0,
301
- sequenceNumber: seq,
302
- type: MessageType.Operation,
303
- },
304
- ]);
305
- await yieldEventLoop();
306
- assert.strictEqual(expectedError.message, "gap in client sequence number: 1");
307
- });
308
- it("Should pass with 2 noop sent, 1 received, gap = 1", async () => {
309
- await startDeltaManager();
310
- deltaManager.inbound.on("error", (error) => {
311
- expectedError = error;
312
- });
313
- await sendAndReceiveOps(1, MessageType.Operation);
314
- await sendAndReceiveOps(1, MessageType.NoOp);
315
- // send second noop, without receiving
316
- deltaManager.submit(MessageType.NoOp);
317
- // send op with gap in clientSeqNum
318
- deltaManager.submit(MessageType.Operation);
319
- deltaConnection.emitOp(docId, [
320
- {
321
- clientId: "test",
322
- clientSequenceNumber: clientSeqNumber + 2,
323
- minimumSequenceNumber: 0,
324
- sequenceNumber: seq,
325
- type: MessageType.Operation,
326
- },
327
- ]);
328
- await yieldEventLoop();
329
- assert.strictEqual(deltaManager.lastMessage?.sequenceNumber, seq, "discrepancy in last processed seqNum");
330
- assert.strictEqual(expectedError, undefined, `Error should not happen : ${expectedError}`);
331
- });
332
- });
333
- describe("Readonly API", () => {
334
- it("Should override readonly", async () => {
335
- await startDeltaManager();
336
- // TS 5.1.6: Workaround 'TS2339: Property 'readonly' does not exist on type 'never'.'
337
- //
338
- // After observering that 'forceReadonly' has been asserted to be both true and
339
- // false, TypeScript coerces 'connectionManager' to 'never'. Wrapping the
340
- // assertion in lambda avoids this.
341
- const assertReadonlyIs = (expected) => {
342
- assert.strictEqual(deltaManager.readOnlyInfo.readonly, expected);
343
- };
344
- assertReadonlyIs(false);
345
- deltaManager.connectionManager.forceReadonly(true);
346
- assertReadonlyIs(true);
347
- deltaManager.connectionManager.forceReadonly(false);
348
- assertReadonlyIs(false);
349
- });
350
- it("Should raise readonly event when container was not readonly", async () => {
351
- await startDeltaManager();
352
- let runCount = 0;
353
- deltaManager.on("readonly", (readonly) => {
354
- assert.strictEqual(readonly, true);
355
- runCount++;
356
- });
357
- deltaManager.connectionManager.forceReadonly(true);
358
- assert.strictEqual(runCount, 1);
359
- });
360
- it("Shouldn't raise readonly event when container was already readonly", async () => {
361
- await startDeltaManager(false /* startDeltaManager */);
362
- // Closing underlying connection makes container readonly
363
- deltaConnection.dispose();
364
- assert.strictEqual(deltaManager.readOnlyInfo.readonly, true);
365
- deltaManager.on("readonly", () => {
366
- assert.fail("Shouldn't be called");
367
- });
368
- deltaManager.connectionManager.forceReadonly(true);
369
- });
370
- });
371
- it("Closed abort reason should be passed fetch abort signal", async () => {
372
- const mockLogger = new MockLogger();
373
- await startDeltaManager(undefined, mockLogger.toTelemetryLogger(), () => ({
374
- fetchMessages: (_from, _to, abortSignal, _cachedOnly) => {
375
- return {
376
- read: async () => {
377
- await new Promise((resolve) => {
378
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
379
- abortSignal.onabort = () => {
380
- resolve();
381
- };
382
- });
383
- throw new Error(abortSignal?.reason);
384
- },
385
- };
386
- },
387
- }));
388
- // Dispose will trigger abort
389
- deltaManager.dispose();
390
- await flushPromises();
391
- mockLogger.assertMatch([
392
- {
393
- eventName: "DeltaManager_GetDeltasAborted",
394
- reason: "DeltaManager is closed",
395
- },
396
- {
397
- eventName: "GetDeltas_Exception",
398
- error: "DeltaManager is closed",
399
- },
400
- ]);
401
- });
402
- });
403
- });
404
- });
405
- //# sourceMappingURL=deltaManager.spec.js.map