@fluidframework/azure-end-to-end-tests 2.101.1 → 2.102.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.
- package/CHANGELOG.md +4 -0
- package/eslint.config.mts +4 -0
- package/lib/packageVersion.js +9 -0
- package/lib/packageVersion.js.map +1 -0
- package/lib/test/AzureClientFactory.js.map +1 -1
- package/lib/test/audience.spec.js +16 -16
- package/lib/test/audience.spec.js.map +1 -1
- package/lib/test/containerCreate.spec.js +27 -24
- package/lib/test/containerCreate.spec.js.map +1 -1
- package/lib/test/ddsTests.spec.js +17 -17
- package/lib/test/ddsTests.spec.js.map +1 -1
- package/lib/test/multiprocess/childClient.tool.js +3 -2
- package/lib/test/multiprocess/childClient.tool.js.map +1 -1
- package/lib/test/signals.spec.js +4 -4
- package/lib/test/signals.spec.js.map +1 -1
- package/lib/test/tree.spec.js +8 -8
- package/lib/test/tree.spec.js.map +1 -1
- package/lib/test/utils.js +3 -0
- package/lib/test/utils.js.map +1 -1
- package/lib/test/viewContainerVersion.spec.js +9 -9
- package/lib/test/viewContainerVersion.spec.js.map +1 -1
- package/package.json +29 -27
- package/src/packageVersion.ts +9 -0
- package/src/test/.mocharc.js +15 -0
- package/src/test/AzureClientFactory.ts +4 -3
- package/src/test/audience.spec.ts +36 -16
- package/src/test/containerCreate.spec.ts +31 -24
- package/src/test/ddsTests.spec.ts +29 -17
- package/src/test/multiprocess/childClient.tool.ts +7 -2
- package/src/test/signals.spec.ts +12 -4
- package/src/test/tree.spec.ts +8 -8
- package/src/test/tsconfig.json +6 -3
- package/src/test/utils.ts +4 -0
- package/src/test/viewContainerVersion.spec.ts +9 -9
- package/src/test/.mocharc.cjs +0 -11
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"childClient.tool.js","sourceRoot":"","sources":["../../../src/test/multiprocess/childClient.tool.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 \"node:assert\";\n\nimport {\n\tAzureClient,\n\ttype AzureContainerServices,\n\ttype AzureLocalConnectionConfig,\n\ttype AzureRemoteConnectionConfig,\n\ttype ITelemetryBaseEvent,\n} from \"@fluidframework/azure-client\";\nimport { AttachState } from \"@fluidframework/container-definitions\";\nimport { ConnectionState } from \"@fluidframework/container-loader\";\nimport type { ITelemetryBaseLogger, LogLevel } from \"@fluidframework/core-interfaces\";\nimport type { ScopeType } from \"@fluidframework/driver-definitions/legacy\";\nimport type { ContainerSchema, IFluidContainer } from \"@fluidframework/fluid-static\";\nimport { getPresence } from \"@fluidframework/fluid-static\";\nimport {\n\ttype Attendee,\n\ttype Presence,\n\tStateFactory,\n\ttype LatestRaw,\n\ttype LatestMapRaw,\n\ttype StatesWorkspace,\n} from \"@fluidframework/presence\";\nimport { InsecureTokenProvider } from \"@fluidframework/test-runtime-utils/internal\";\nimport { timeoutPromise } from \"@fluidframework/test-utils/internal\";\n\nimport { createAzureTokenProvider } from \"../AzureTokenFactory.js\";\nimport { TestDataObject } from \"../TestDataObject.js\";\n\nimport type {\n\tMessageFromChild as MessageToParent,\n\tMessageToChild as MessageFromParent,\n\tUserIdAndName,\n\tEventEntry,\n} from \"./messageTypes.js\";\n\nconst testLabel = process.argv[2];\n// Identifier given to child process\nconst process_id = process.argv[3];\nconst verbosity = process.argv[4] ?? \"\";\n\nconst useAzure = process.env.FLUID_CLIENT === \"azure\";\nconst tenantId = useAzure\n\t? (process.env.azure__fluid__relay__service__tenantId as string)\n\t: \"frs-client-tenant\";\nconst endPoint = process.env.azure__fluid__relay__service__endpoint as string;\nif (useAzure && endPoint === undefined) {\n\tthrow new Error(\"Azure Fluid Relay service endpoint is missing\");\n}\n\nconst containerSchema = {\n\tinitialObjects: {\n\t\t// A DataObject is added as otherwise fluid-static complains \"Container cannot be initialized without any DataTypes\"\n\t\t_unused: TestDataObject,\n\t},\n} as const satisfies ContainerSchema;\n\nfunction log(...data: unknown[]): void {\n\tconsole.log(`[${testLabel}] [${new Date().toISOString()}] [${process_id}]`, ...data);\n}\n\nfunction telemetryEventInterestLevel(eventName: string): \"none\" | \"basic\" | \"details\" {\n\tif (eventName.includes(\":Signal\") || eventName.includes(\":Join\")) {\n\t\treturn \"details\";\n\t} else if (eventName.includes(\":Container:\") || eventName.includes(\":Presence:\")) {\n\t\treturn \"basic\";\n\t}\n\treturn \"none\";\n}\n\nfunction selectiveVerboseLog(\n\tevent: ITelemetryBaseEvent,\n\tlogLevel: LogLevel | undefined,\n): void {\n\tconst interest = telemetryEventInterestLevel(event.eventName);\n\tif (interest === \"none\") {\n\t\treturn;\n\t}\n\tconst content: Record<string, unknown> = {\n\t\teventName: event.eventName,\n\t\tcontainerConnectionState: event.containerConnectionState,\n\t};\n\tif (interest === \"details\") {\n\t\tcontent.details = event.details;\n\t}\n\tlog(`[${logLevel ?? \"unspecified\"}]`, content);\n}\n\n/**\n * Get or create a Fluid container.\n */\nconst getOrCreateContainer = async (params: {\n\tlogger: ITelemetryBaseLogger;\n\tonDisconnected: () => void;\n\tcontainerId?: string;\n\tuser: UserIdAndName;\n\tscopes?: ScopeType[];\n\tcreateScopes?: ScopeType[];\n\tconnectTimeoutMs: number;\n}): Promise<{\n\tcontainer: IFluidContainer<typeof containerSchema>;\n\tservices: AzureContainerServices;\n\tclient: AzureClient;\n\tcontainerId: string;\n\tconnected: Promise<void>;\n}> => {\n\tlet container: IFluidContainer<typeof containerSchema>;\n\tlet { containerId } = params;\n\tconst { logger, onDisconnected, user, scopes, createScopes, connectTimeoutMs } = params;\n\tconst connectionProps: AzureRemoteConnectionConfig | AzureLocalConnectionConfig = useAzure\n\t\t? {\n\t\t\t\ttenantId,\n\t\t\t\ttokenProvider: createAzureTokenProvider(\n\t\t\t\t\tuser.id ?? \"foo\",\n\t\t\t\t\tuser.name ?? \"bar\",\n\t\t\t\t\tscopes,\n\t\t\t\t\tcreateScopes,\n\t\t\t\t),\n\t\t\t\tendpoint: endPoint,\n\t\t\t\ttype: \"remote\",\n\t\t\t}\n\t\t: {\n\t\t\t\ttokenProvider: new InsecureTokenProvider(\"fooBar\", user, scopes, createScopes),\n\t\t\t\tendpoint: \"http://localhost:7071\",\n\t\t\t\ttype: \"local\",\n\t\t\t};\n\tconst client = new AzureClient({\n\t\tconnection: connectionProps,\n\t\tlogger,\n\t\tconfigProvider: {\n\t\t\tgetRawConfig: (v: string) => {\n\t\t\t\t// At higher client counts, summarizer will get invoked, taking up resources\n\t\t\t\t// and spewing telemetry. None of current tests need summarization, so disable it.\n\t\t\t\tif (v === \"Fluid.ContainerRuntime.Test.DisableSummaries\") {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn undefined;\n\t\t\t},\n\t\t},\n\t});\n\tlet services: AzureContainerServices;\n\tif (containerId === undefined) {\n\t\t({ container, services } = await client.createContainer(containerSchema, \"2\"));\n\t\tcontainerId = await container.attach();\n\t} else {\n\t\t({ container, services } = await client.getContainer(containerId, containerSchema, \"2\"));\n\t}\n\tcontainer.on(\"disconnected\", onDisconnected);\n\n\tconst connected =\n\t\tcontainer.connectionState === ConnectionState.Connected\n\t\t\t? Promise.resolve()\n\t\t\t: timeoutPromise((resolve) => container.once(\"connected\", () => resolve()), {\n\t\t\t\t\tdurationMs: connectTimeoutMs,\n\t\t\t\t\terrorMsg: \"container connect() timeout\",\n\t\t\t\t});\n\n\tassert.strictEqual(\n\t\tcontainer.attachState,\n\t\tAttachState.Attached,\n\t\t\"Container is not attached after attach is called\",\n\t);\n\n\treturn {\n\t\tclient,\n\t\tcontainer,\n\t\tservices,\n\t\tcontainerId,\n\t\tconnected,\n\t};\n};\n\nfunction createSendFunction(): (msg: MessageToParent) => void {\n\tif (process.send) {\n\t\tconst sendFn = process.send.bind(process);\n\t\tif (verbosity.includes(\"msgs\")) {\n\t\t\treturn (msg: MessageToParent) => {\n\t\t\t\tlog(`Sending`, msg);\n\t\t\t\tsendFn(msg);\n\t\t\t};\n\t\t}\n\t\treturn sendFn;\n\t}\n\tthrow new Error(\"process.send is not defined\");\n}\n\nconst send = createSendFunction();\n\nfunction isStringOrNumberRecord(value: unknown): value is Record<string, string | number> {\n\tif (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n\t\treturn false;\n\t}\n\n\tconst stringKeys = Object.keys(value);\n\tconst allKeys = Reflect.ownKeys(value);\n\n\tif (stringKeys.length !== allKeys.length) {\n\t\t// If there are non-string/symbol keys, return false\n\t\treturn false;\n\t}\n\tfor (const key of stringKeys) {\n\t\tif (!(typeof value[key] === \"string\" || typeof value[key] === \"number\")) {\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn true;\n}\n\n// NOTE:\n// - This schema intentionally uses optional keys (latest?, latestMap?) so tests can register\n// states conditionally at runtime.\n// - Optional keys are not explicitly supported in StatesWorkspace typing today, which means\n// workspace.states.<key> is typed as any. As a result, usages below require casts\n// (e.g., to LatestRaw / LatestMapRaw) to recover concrete types.\n// - Track adding proper optional-key support to Presence state workspace typing here:\n// Work item: AB#47518\n// - Fallout: Until the above is addressed, keep the casts in place and document new usages accordingly.\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\ntype WorkspaceSchema = {\n\tlatest?: ReturnType<typeof StateFactory.latest<{ value: string }, \"latest\">>;\n\tlatestMap?: ReturnType<\n\t\ttypeof StateFactory.latestMap<\n\t\t\t{ value: Record<string, string | number> },\n\t\t\tstring,\n\t\t\t\"latestMap\"\n\t\t>\n\t>;\n};\nconst WorkspaceSchema: WorkspaceSchema = {};\n\nclass MessageHandler {\n\tprivate readonly log: EventEntry[] = [];\n\tprivate msgQueue: undefined | Exclude<MessageFromParent, { command: \"ping\" | \"connect\" }>[];\n\tprivate container: IFluidContainer | undefined;\n\tprivate presence: Presence | undefined;\n\tprivate readonly workspaces = new Map<string, StatesWorkspace<WorkspaceSchema>>();\n\n\tprivate send(msg: MessageToParent): void {\n\t\tthis.log.push({\n\t\t\ttimestamp: Date.now(),\n\t\t\tagentId: process_id,\n\t\t\teventCategory: \"messageSent\",\n\t\t\teventName: msg.event,\n\t\t\tdetails:\n\t\t\t\tmsg.event === \"debugReportComplete\" && msg.log\n\t\t\t\t\t? JSON.stringify({ logLength: msg.log.length })\n\t\t\t\t\t: JSON.stringify(msg),\n\t\t});\n\t\tsend(msg);\n\t}\n\n\tprivate readonly sendAttendeeConnected = (attendee: Attendee): void => {\n\t\tthis.send({\n\t\t\tevent: \"attendeeConnected\",\n\t\t\tattendeeId: attendee.attendeeId,\n\t\t});\n\t};\n\tprivate readonly sendAttendeeDisconnected = (attendee: Attendee): void => {\n\t\tthis.send({\n\t\t\tevent: \"attendeeDisconnected\",\n\t\t\tattendeeId: attendee.attendeeId,\n\t\t});\n\t};\n\n\tprivate readonly logger: ITelemetryBaseLogger = {\n\t\tsend: (event: ITelemetryBaseEvent, logLevel?: LogLevel) => {\n\t\t\t// Filter out non-interactive client telemetry\n\t\t\tconst clientType = event.clientType;\n\t\t\tif (typeof clientType === \"string\" && clientType.startsWith(\"noninteractive\")) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Special case unexpected telemetry event\n\t\t\tif (event.eventName.endsWith(\":JoinResponseWhenAlone\")) {\n\t\t\t\tthis.send({\n\t\t\t\t\tevent: \"error\",\n\t\t\t\t\terror: `Unexpected ClientJoin response. Details: ${JSON.stringify(event.details)}\\nLog: ${JSON.stringify(this.log)}`,\n\t\t\t\t});\n\t\t\t\t// Keep going\n\t\t\t}\n\n\t\t\tconst interest = telemetryEventInterestLevel(event.eventName);\n\t\t\tif (interest === \"none\") {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.log.push({\n\t\t\t\ttimestamp: Date.now(),\n\t\t\t\tagentId: process_id,\n\t\t\t\teventCategory: \"telemetry\",\n\t\t\t\teventName: event.eventName,\n\t\t\t\tdetails:\n\t\t\t\t\ttypeof event.details === \"string\" ? event.details : JSON.stringify(event.details),\n\t\t\t});\n\t\t\tif (verbosity.includes(\"telem\")) {\n\t\t\t\tselectiveVerboseLog(event, logLevel);\n\t\t\t}\n\t\t},\n\t};\n\n\tprivate readonly onDisconnected = (): void => {\n\t\t// Test state is a bit fragile and does not account for reconnections.\n\t\tthis.send({ event: \"error\", error: `${process_id}: Container disconnected` });\n\t};\n\n\tprivate registerWorkspace(\n\t\tworkspaceId: string,\n\t\toptions: { latest?: boolean; latestMap?: boolean },\n\t): void {\n\t\tif (!this.presence) {\n\t\t\tthis.send({ event: \"error\", error: `${process_id} is not connected to presence` });\n\t\t\treturn;\n\t\t}\n\t\tconst { latest, latestMap } = options;\n\t\tconst workspace: StatesWorkspace<WorkspaceSchema> = this.presence.states.getWorkspace(\n\t\t\t`test:${workspaceId}`,\n\t\t\tWorkspaceSchema,\n\t\t);\n\n\t\tif (latest && !workspace.states.latest) {\n\t\t\tworkspace.add(\"latest\", StateFactory.latest({ local: { value: \"initial\" } }));\n\t\t\t// Cast required due to optional keys in WorkspaceSchema\n\t\t\t// TODO: AB#47518\n\t\t\tconst latestState = workspace.states.latest as LatestRaw<{ value: string }>;\n\t\t\tlatestState.events.on(\"remoteUpdated\", (update) => {\n\t\t\t\tthis.send({\n\t\t\t\t\tevent: \"latestValueUpdated\",\n\t\t\t\t\tworkspaceId,\n\t\t\t\t\tattendeeId: update.attendee.attendeeId,\n\t\t\t\t\tvalue: update.value.value,\n\t\t\t\t});\n\t\t\t});\n\t\t\tfor (const remote of latestState.getRemotes()) {\n\t\t\t\tthis.send({\n\t\t\t\t\tevent: \"latestValueUpdated\",\n\t\t\t\t\tworkspaceId,\n\t\t\t\t\tattendeeId: remote.attendee.attendeeId,\n\t\t\t\t\tvalue: remote.value.value,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tif (latestMap && !workspace.states.latestMap) {\n\t\t\tworkspace.add(\n\t\t\t\t\"latestMap\",\n\t\t\t\tStateFactory.latestMap<{ value: Record<string, string | number> }>({\n\t\t\t\t\tlocal: {},\n\t\t\t\t}),\n\t\t\t);\n\t\t\t// Cast required due to optional keys in WorkspaceSchema\n\t\t\t// TODO: AB#47518\n\t\t\tconst latestMapState = workspace.states.latestMap as LatestMapRaw<{\n\t\t\t\tvalue: Record<string, string | number>;\n\t\t\t}>;\n\t\t\tlatestMapState.events.on(\"remoteUpdated\", (update) => {\n\t\t\t\tfor (const [key, valueWithMetadata] of update.items) {\n\t\t\t\t\tthis.send({\n\t\t\t\t\t\tevent: \"latestMapValueUpdated\",\n\t\t\t\t\t\tworkspaceId,\n\t\t\t\t\t\tattendeeId: update.attendee.attendeeId,\n\t\t\t\t\t\tkey: String(key),\n\t\t\t\t\t\tvalue: valueWithMetadata.value.value,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\t\t\tfor (const remote of latestMapState.getRemotes()) {\n\t\t\t\tfor (const [key, valueWithMetadata] of remote.items) {\n\t\t\t\t\tthis.send({\n\t\t\t\t\t\tevent: \"latestMapValueUpdated\",\n\t\t\t\t\t\tworkspaceId,\n\t\t\t\t\t\tattendeeId: remote.attendee.attendeeId,\n\t\t\t\t\t\tkey: String(key),\n\t\t\t\t\t\tvalue: valueWithMetadata.value.value,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.workspaces.set(workspaceId, workspace);\n\t\tthis.send({\n\t\t\tevent: \"workspaceRegistered\",\n\t\t\tworkspaceId,\n\t\t\tlatest: latest ?? false,\n\t\t\tlatestMap: latestMap ?? false,\n\t\t});\n\t}\n\n\tpublic async onMessage(msg: MessageFromParent): Promise<void> {\n\t\tif (verbosity.includes(\"msgs\")) {\n\t\t\tthis.log.push({\n\t\t\t\ttimestamp: Date.now(),\n\t\t\t\tagentId: process_id,\n\t\t\t\teventCategory: \"messageReceived\",\n\t\t\t\teventName: msg.command,\n\t\t\t});\n\t\t\tlog(`Received`, msg);\n\t\t}\n\n\t\tif (msg.command === \"ping\") {\n\t\t\tthis.handlePing();\n\t\t\treturn;\n\t\t}\n\n\t\tif (msg.command === \"connect\") {\n\t\t\tawait this.handleConnect(msg);\n\t\t\treturn;\n\t\t}\n\n\t\t// All other message must wait if connect is in progress\n\t\tif (this.msgQueue !== undefined) {\n\t\t\tthis.msgQueue.push(msg);\n\t\t\treturn;\n\t\t}\n\n\t\tthis.processMessage(msg);\n\t}\n\n\tprivate processMessage(\n\t\tmsg: Exclude<MessageFromParent, { command: \"ping\" | \"connect\" }>,\n\t): void {\n\t\tswitch (msg.command) {\n\t\t\tcase \"debugReport\": {\n\t\t\t\tthis.handleDebugReport(msg);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"disconnectSelf\": {\n\t\t\t\tthis.handleDisconnectSelf();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"setLatestValue\": {\n\t\t\t\tthis.handleSetLatestValue(msg);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"setLatestMapValue\": {\n\t\t\t\tthis.handleSetLatestMapValue(msg);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"getLatestValue\": {\n\t\t\t\tthis.handleGetLatestValue(msg);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"getLatestMapValue\": {\n\t\t\t\tthis.handleGetLatestMapValue(msg);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"registerWorkspace\": {\n\t\t\t\tthis.registerWorkspace(msg.workspaceId, {\n\t\t\t\t\tlatest: msg.latest,\n\t\t\t\t\tlatestMap: msg.latestMap,\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tconsole.error(`${process_id}: Unknown command:`, msg);\n\t\t\t\tthis.send({\n\t\t\t\t\tevent: \"error\",\n\t\t\t\t\terror: `${process_id} Unknown command: ${JSON.stringify(msg)}`,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate handlePing(): void {\n\t\tthis.send({ event: \"ack\" });\n\t}\n\n\tprivate async handleConnect(\n\t\tmsg: Extract<MessageFromParent, { command: \"connect\" }>,\n\t): Promise<void> {\n\t\tif (!msg.user) {\n\t\t\tthis.send({ event: \"error\", error: `${process_id}: No azure user information given` });\n\t\t\treturn;\n\t\t}\n\t\tif (this.container) {\n\t\t\tthis.send({ event: \"error\", error: `${process_id}: Container already loaded` });\n\t\t\treturn;\n\t\t}\n\n\t\t// Prevent reentrance. Queue messages until after connect is fully processed.\n\t\tthis.msgQueue = [];\n\n\t\ttry {\n\t\t\tconst { container, containerId, connected } = await getOrCreateContainer({\n\t\t\t\t...msg,\n\t\t\t\tlogger: this.logger,\n\t\t\t\tonDisconnected: this.onDisconnected,\n\t\t\t});\n\t\t\tthis.container = container;\n\t\t\tconst presence = getPresence(container);\n\t\t\tthis.presence = presence;\n\n\t\t\t// wait for 'ConnectionState.Connected'\n\t\t\tawait connected.catch((error) => {\n\t\t\t\t(error as Error).message += `\\nLog: ${JSON.stringify(this.log)}`;\n\t\t\t\tthrow error;\n\t\t\t});\n\n\t\t\t// Acknowledge connection before sending current attendee information\n\t\t\tthis.send({\n\t\t\t\tevent: \"connected\",\n\t\t\t\tcontainerId,\n\t\t\t\tattendeeId: presence.attendees.getMyself().attendeeId,\n\t\t\t});\n\n\t\t\t// Send existing attendees excluding self to parent/orchestrator\n\t\t\tconst self = presence.attendees.getMyself();\n\t\t\tfor (const attendee of presence.attendees.getAttendees()) {\n\t\t\t\tif (attendee !== self && attendee.getConnectionStatus() === \"Connected\") {\n\t\t\t\t\tthis.sendAttendeeConnected(attendee);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Listen for presence events to notify parent/orchestrator when a new attendee joins or leaves the session.\n\t\t\tpresence.attendees.events.on(\"attendeeConnected\", this.sendAttendeeConnected);\n\t\t\tpresence.attendees.events.on(\"attendeeDisconnected\", this.sendAttendeeDisconnected);\n\t\t} finally {\n\t\t\t// Process any queued messages received while connecting\n\t\t\tfor (const queuedMsg of this.msgQueue) {\n\t\t\t\tthis.processMessage(queuedMsg);\n\t\t\t}\n\t\t\tthis.msgQueue = undefined;\n\t\t}\n\t}\n\n\tprivate handleDebugReport(\n\t\tmsg: Extract<MessageFromParent, { command: \"debugReport\" }>,\n\t): void {\n\t\tif (msg.reportAttendees) {\n\t\t\tif (this.presence) {\n\t\t\t\tconst attendees = this.presence.attendees.getAttendees();\n\t\t\t\tlet connectedCount = 0;\n\t\t\t\tfor (const attendee of attendees) {\n\t\t\t\t\tif (attendee.getConnectionStatus() === \"Connected\") {\n\t\t\t\t\t\tconnectedCount++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tlog(`Report: ${attendees.size} attendees, ${connectedCount} connected`);\n\t\t\t} else {\n\t\t\t\tthis.send({ event: \"error\", error: `${process_id} is not connected to presence` });\n\t\t\t}\n\t\t}\n\n\t\tconst debugReport: Extract<MessageToParent, { event: \"debugReportComplete\" }> = {\n\t\t\tevent: \"debugReportComplete\",\n\t\t};\n\t\tif (msg.sendEventLog) {\n\t\t\tdebugReport.log = this.log;\n\t\t}\n\t\tthis.send(debugReport);\n\t}\n\n\tprivate handleDisconnectSelf(): void {\n\t\tif (!this.container) {\n\t\t\tthis.send({ event: \"error\", error: `${process_id} is not connected to container` });\n\t\t\treturn;\n\t\t}\n\t\t// There are no current scenarios where disconnect without presence is expected.\n\t\tif (!this.presence) {\n\t\t\tthis.send({ event: \"error\", error: `${process_id} is not connected to presence` });\n\t\t\treturn;\n\t\t}\n\t\t// Disconnect event is treated as an error in normal handling.\n\t\t// Remove listener as this disconnect is intentional.\n\t\tthis.container.off(\"disconnected\", this.onDisconnected);\n\t\tthis.container.disconnect();\n\t\tthis.send({\n\t\t\tevent: \"disconnectedSelf\",\n\t\t\tattendeeId: this.presence.attendees.getMyself().attendeeId,\n\t\t});\n\t}\n\n\tprivate handleSetLatestValue(\n\t\tmsg: Extract<MessageFromParent, { command: \"setLatestValue\" }>,\n\t): void {\n\t\tif (!this.presence) {\n\t\t\tthis.send({ event: \"error\", error: `${process_id} is not connected to presence` });\n\t\t\treturn;\n\t\t}\n\t\tconst workspace = this.workspaces.get(msg.workspaceId);\n\t\tif (!workspace) {\n\t\t\tthis.send({\n\t\t\t\tevent: \"error\",\n\t\t\t\terror: `${process_id} workspace ${msg.workspaceId} not found`,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\t// Cast required due to optional keys in WorkspaceSchema\n\t\t// TODO: AB#47518\n\t\tconst latestState = workspace.states.latest as LatestRaw<{ value: string }> | undefined;\n\t\tif (!latestState) {\n\t\t\tthis.send({\n\t\t\t\tevent: \"error\",\n\t\t\t\terror: `${process_id} latest state not registered for workspace ${msg.workspaceId}`,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tif (typeof msg.value !== \"string\") {\n\t\t\treturn;\n\t\t}\n\t\tlatestState.local = { value: msg.value };\n\t}\n\n\tprivate handleSetLatestMapValue(\n\t\tmsg: Extract<MessageFromParent, { command: \"setLatestMapValue\" }>,\n\t): void {\n\t\tif (!this.presence) {\n\t\t\tthis.send({ event: \"error\", error: `${process_id} is not connected to presence` });\n\t\t\treturn;\n\t\t}\n\t\tif (typeof msg.key !== \"string\") {\n\t\t\tthis.send({ event: \"error\", error: `${process_id} invalid key type` });\n\t\t\treturn;\n\t\t}\n\t\tconst workspace = this.workspaces.get(msg.workspaceId);\n\t\tif (!workspace) {\n\t\t\tthis.send({\n\t\t\t\tevent: \"error\",\n\t\t\t\terror: `${process_id} workspace ${msg.workspaceId} not found`,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\t// Cast required due to optional keys in WorkspaceSchema\n\t\t// TODO: AB#47518\n\t\tconst latestMapState = workspace.states.latestMap as\n\t\t\t| LatestMapRaw<{ value: Record<string, string | number> }>\n\t\t\t| undefined;\n\t\tif (!latestMapState) {\n\t\t\tthis.send({\n\t\t\t\tevent: \"error\",\n\t\t\t\terror: `${process_id} latestMap state not registered for workspace ${msg.workspaceId}`,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tif (!isStringOrNumberRecord(msg.value)) {\n\t\t\treturn;\n\t\t}\n\t\tlatestMapState.local.set(msg.key, { value: msg.value });\n\t}\n\n\tprivate handleGetLatestValue(\n\t\tmsg: Extract<MessageFromParent, { command: \"getLatestValue\" }>,\n\t): void {\n\t\tif (!this.presence) {\n\t\t\tthis.send({ event: \"error\", error: `${process_id} is not connected to presence` });\n\t\t\treturn;\n\t\t}\n\t\tconst workspace = this.workspaces.get(msg.workspaceId);\n\t\tif (!workspace) {\n\t\t\tthis.send({\n\t\t\t\tevent: \"error\",\n\t\t\t\terror: `${process_id} workspace ${msg.workspaceId} not found`,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\t// Cast required due to optional keys in WorkspaceSchema\n\t\t// TODO: AB#47518\n\t\tconst latestState = workspace.states.latest as LatestRaw<{ value: string }> | undefined;\n\t\tif (!latestState) {\n\t\t\tthis.send({\n\t\t\t\tevent: \"error\",\n\t\t\t\terror: `${process_id} latest state not registered for workspace ${msg.workspaceId}`,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tlet value: { value: string };\n\t\tif (msg.attendeeId) {\n\t\t\tconst attendee = this.presence.attendees.getAttendee(msg.attendeeId);\n\t\t\tconst remoteData = latestState.getRemote(attendee);\n\t\t\tvalue = remoteData.value;\n\t\t} else {\n\t\t\tvalue = latestState.local;\n\t\t}\n\t\tthis.send({\n\t\t\tevent: \"latestValueGetResponse\",\n\t\t\tworkspaceId: msg.workspaceId,\n\t\t\tattendeeId: msg.attendeeId,\n\t\t\tvalue: value.value,\n\t\t});\n\t}\n\n\tprivate handleGetLatestMapValue(\n\t\tmsg: Extract<MessageFromParent, { command: \"getLatestMapValue\" }>,\n\t): void {\n\t\tif (!this.presence) {\n\t\t\tthis.send({ event: \"error\", error: `${process_id} is not connected to presence` });\n\t\t\treturn;\n\t\t}\n\t\tif (typeof msg.key !== \"string\") {\n\t\t\tthis.send({ event: \"error\", error: `${process_id} invalid key type` });\n\t\t\treturn;\n\t\t}\n\t\tconst workspace = this.workspaces.get(msg.workspaceId);\n\t\tif (!workspace) {\n\t\t\tthis.send({\n\t\t\t\tevent: \"error\",\n\t\t\t\terror: `${process_id} workspace ${msg.workspaceId} not found`,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\t// Cast required due to optional keys in WorkspaceSchema\n\t\t// TODO: AB#47518\n\t\tconst latestMapState = workspace.states.latestMap as\n\t\t\t| LatestMapRaw<{ value: Record<string, string | number> }>\n\t\t\t| undefined;\n\t\tif (!latestMapState) {\n\t\t\tthis.send({\n\t\t\t\tevent: \"error\",\n\t\t\t\terror: `${process_id} latestMap state not registered for workspace ${msg.workspaceId}`,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tlet value: { value: Record<string, string | number> } | undefined;\n\t\tif (msg.attendeeId) {\n\t\t\tconst attendee = this.presence.attendees.getAttendee(msg.attendeeId);\n\t\t\tconst remoteData = latestMapState.getRemote(attendee);\n\t\t\tconst keyData = remoteData.get(msg.key);\n\t\t\tvalue = keyData?.value;\n\t\t} else {\n\t\t\tvalue = latestMapState.local.get(msg.key);\n\t\t}\n\t\tthis.send({\n\t\t\tevent: \"latestMapValueGetResponse\",\n\t\t\tworkspaceId: msg.workspaceId,\n\t\t\tattendeeId: msg.attendeeId,\n\t\t\tkey: msg.key,\n\t\t\tvalue: value?.value,\n\t\t});\n\t}\n}\n\nfunction setupMessageHandler(): void {\n\tconst messageHandler = new MessageHandler();\n\tprocess.on(\"message\", (msg: MessageFromParent) => {\n\t\tmessageHandler.onMessage(msg).catch((error: Error) => {\n\t\t\tconsole.error(`[${testLabel}] Error in client ${process_id}`, error);\n\t\t\tsend({ event: \"error\", error: `${process_id}: ${error.message}` });\n\t\t});\n\t});\n}\n\nsetupMessageHandler();\n"]}
|
|
1
|
+
{"version":3,"file":"childClient.tool.js","sourceRoot":"","sources":["../../../src/test/multiprocess/childClient.tool.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 \"node:assert\";\n\nimport {\n\tAzureClient,\n\ttype AzureContainerServices,\n\ttype AzureLocalConnectionConfig,\n\ttype AzureRemoteConnectionConfig,\n\ttype ITelemetryBaseEvent,\n} from \"@fluidframework/azure-client\";\nimport { AttachState } from \"@fluidframework/container-definitions\";\nimport { ConnectionState } from \"@fluidframework/container-loader\";\nimport type { ITelemetryBaseLogger, LogLevel } from \"@fluidframework/core-interfaces\";\nimport type { ScopeType } from \"@fluidframework/driver-definitions/legacy\";\nimport type { ContainerSchema, IFluidContainer } from \"@fluidframework/fluid-static\";\nimport { getPresence } from \"@fluidframework/fluid-static\";\nimport {\n\ttype Attendee,\n\ttype Presence,\n\tStateFactory,\n\ttype LatestRaw,\n\ttype LatestMapRaw,\n\ttype StatesWorkspace,\n} from \"@fluidframework/presence\";\nimport { InsecureTokenProvider } from \"@fluidframework/test-runtime-utils/internal\";\nimport { timeoutPromise } from \"@fluidframework/test-utils/internal\";\n\nimport { createAzureTokenProvider } from \"../AzureTokenFactory.js\";\nimport { TestDataObject } from \"../TestDataObject.js\";\nimport { currentVersion } from \"../utils.js\";\n\nimport type {\n\tMessageFromChild as MessageToParent,\n\tMessageToChild as MessageFromParent,\n\tUserIdAndName,\n\tEventEntry,\n} from \"./messageTypes.js\";\n\nconst testLabel = process.argv[2];\n// Identifier given to child process\nconst process_id = process.argv[3];\nconst verbosity = process.argv[4] ?? \"\";\n\nconst useAzure = process.env.FLUID_CLIENT === \"azure\";\nconst tenantId = useAzure\n\t? (process.env.azure__fluid__relay__service__tenantId as string)\n\t: \"frs-client-tenant\";\nconst endPoint = process.env.azure__fluid__relay__service__endpoint as string;\nif (useAzure && endPoint === undefined) {\n\tthrow new Error(\"Azure Fluid Relay service endpoint is missing\");\n}\n\nconst containerSchema = {\n\tinitialObjects: {\n\t\t// A DataObject is added as otherwise fluid-static complains \"Container cannot be initialized without any DataTypes\"\n\t\t_unused: TestDataObject,\n\t},\n} as const satisfies ContainerSchema;\n\nfunction log(...data: unknown[]): void {\n\tconsole.log(`[${testLabel}] [${new Date().toISOString()}] [${process_id}]`, ...data);\n}\n\nfunction telemetryEventInterestLevel(eventName: string): \"none\" | \"basic\" | \"details\" {\n\tif (eventName.includes(\":Signal\") || eventName.includes(\":Join\")) {\n\t\treturn \"details\";\n\t} else if (eventName.includes(\":Container:\") || eventName.includes(\":Presence:\")) {\n\t\treturn \"basic\";\n\t}\n\treturn \"none\";\n}\n\nfunction selectiveVerboseLog(\n\tevent: ITelemetryBaseEvent,\n\tlogLevel: LogLevel | undefined,\n): void {\n\tconst interest = telemetryEventInterestLevel(event.eventName);\n\tif (interest === \"none\") {\n\t\treturn;\n\t}\n\tconst content: Record<string, unknown> = {\n\t\teventName: event.eventName,\n\t\tcontainerConnectionState: event.containerConnectionState,\n\t};\n\tif (interest === \"details\") {\n\t\tcontent.details = event.details;\n\t}\n\tlog(`[${logLevel ?? \"unspecified\"}]`, content);\n}\n\n/**\n * Get or create a Fluid container.\n */\nconst getOrCreateContainer = async (params: {\n\tlogger: ITelemetryBaseLogger;\n\tonDisconnected: () => void;\n\tcontainerId?: string;\n\tuser: UserIdAndName;\n\tscopes?: ScopeType[];\n\tcreateScopes?: ScopeType[];\n\tconnectTimeoutMs: number;\n}): Promise<{\n\tcontainer: IFluidContainer<typeof containerSchema>;\n\tservices: AzureContainerServices;\n\tclient: AzureClient;\n\tcontainerId: string;\n\tconnected: Promise<void>;\n}> => {\n\tlet container: IFluidContainer<typeof containerSchema>;\n\tlet { containerId } = params;\n\tconst { logger, onDisconnected, user, scopes, createScopes, connectTimeoutMs } = params;\n\tconst connectionProps: AzureRemoteConnectionConfig | AzureLocalConnectionConfig = useAzure\n\t\t? {\n\t\t\t\ttenantId,\n\t\t\t\ttokenProvider: createAzureTokenProvider(\n\t\t\t\t\tuser.id ?? \"foo\",\n\t\t\t\t\tuser.name ?? \"bar\",\n\t\t\t\t\tscopes,\n\t\t\t\t\tcreateScopes,\n\t\t\t\t),\n\t\t\t\tendpoint: endPoint,\n\t\t\t\ttype: \"remote\",\n\t\t\t}\n\t\t: {\n\t\t\t\ttokenProvider: new InsecureTokenProvider(\"fooBar\", user, scopes, createScopes),\n\t\t\t\tendpoint: \"http://localhost:7071\",\n\t\t\t\ttype: \"local\",\n\t\t\t};\n\tconst client = new AzureClient({\n\t\tconnection: connectionProps,\n\t\tlogger,\n\t\tconfigProvider: {\n\t\t\tgetRawConfig: (v: string) => {\n\t\t\t\t// At higher client counts, summarizer will get invoked, taking up resources\n\t\t\t\t// and spewing telemetry. None of current tests need summarization, so disable it.\n\t\t\t\tif (v === \"Fluid.ContainerRuntime.Test.DisableSummaries\") {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn undefined;\n\t\t\t},\n\t\t},\n\t});\n\tlet services: AzureContainerServices;\n\tif (containerId === undefined) {\n\t\t({ container, services } = await client.createContainer(containerSchema, currentVersion));\n\t\tcontainerId = await container.attach();\n\t} else {\n\t\t({ container, services } = await client.getContainer(\n\t\t\tcontainerId,\n\t\t\tcontainerSchema,\n\t\t\tcurrentVersion,\n\t\t));\n\t}\n\tcontainer.on(\"disconnected\", onDisconnected);\n\n\tconst connected =\n\t\tcontainer.connectionState === ConnectionState.Connected\n\t\t\t? Promise.resolve()\n\t\t\t: timeoutPromise((resolve) => container.once(\"connected\", () => resolve()), {\n\t\t\t\t\tdurationMs: connectTimeoutMs,\n\t\t\t\t\terrorMsg: \"container connect() timeout\",\n\t\t\t\t});\n\n\tassert.strictEqual(\n\t\tcontainer.attachState,\n\t\tAttachState.Attached,\n\t\t\"Container is not attached after attach is called\",\n\t);\n\n\treturn {\n\t\tclient,\n\t\tcontainer,\n\t\tservices,\n\t\tcontainerId,\n\t\tconnected,\n\t};\n};\n\nfunction createSendFunction(): (msg: MessageToParent) => void {\n\tif (process.send) {\n\t\tconst sendFn = process.send.bind(process);\n\t\tif (verbosity.includes(\"msgs\")) {\n\t\t\treturn (msg: MessageToParent) => {\n\t\t\t\tlog(`Sending`, msg);\n\t\t\t\tsendFn(msg);\n\t\t\t};\n\t\t}\n\t\treturn sendFn;\n\t}\n\tthrow new Error(\"process.send is not defined\");\n}\n\nconst send = createSendFunction();\n\nfunction isStringOrNumberRecord(value: unknown): value is Record<string, string | number> {\n\tif (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n\t\treturn false;\n\t}\n\n\tconst stringKeys = Object.keys(value);\n\tconst allKeys = Reflect.ownKeys(value);\n\n\tif (stringKeys.length !== allKeys.length) {\n\t\t// If there are non-string/symbol keys, return false\n\t\treturn false;\n\t}\n\tfor (const key of stringKeys) {\n\t\tif (!(typeof value[key] === \"string\" || typeof value[key] === \"number\")) {\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn true;\n}\n\n// NOTE:\n// - This schema intentionally uses optional keys (latest?, latestMap?) so tests can register\n// states conditionally at runtime.\n// - Optional keys are not explicitly supported in StatesWorkspace typing today, which means\n// workspace.states.<key> is typed as any. As a result, usages below require casts\n// (e.g., to LatestRaw / LatestMapRaw) to recover concrete types.\n// - Track adding proper optional-key support to Presence state workspace typing here:\n// Work item: AB#47518\n// - Fallout: Until the above is addressed, keep the casts in place and document new usages accordingly.\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\ntype WorkspaceSchema = {\n\tlatest?: ReturnType<typeof StateFactory.latest<{ value: string }, \"latest\">>;\n\tlatestMap?: ReturnType<\n\t\ttypeof StateFactory.latestMap<\n\t\t\t{ value: Record<string, string | number> },\n\t\t\tstring,\n\t\t\t\"latestMap\"\n\t\t>\n\t>;\n};\nconst WorkspaceSchema: WorkspaceSchema = {};\n\nclass MessageHandler {\n\tprivate readonly log: EventEntry[] = [];\n\tprivate msgQueue: undefined | Exclude<MessageFromParent, { command: \"ping\" | \"connect\" }>[];\n\tprivate container: IFluidContainer | undefined;\n\tprivate presence: Presence | undefined;\n\tprivate readonly workspaces = new Map<string, StatesWorkspace<WorkspaceSchema>>();\n\n\tprivate send(msg: MessageToParent): void {\n\t\tthis.log.push({\n\t\t\ttimestamp: Date.now(),\n\t\t\tagentId: process_id,\n\t\t\teventCategory: \"messageSent\",\n\t\t\teventName: msg.event,\n\t\t\tdetails:\n\t\t\t\tmsg.event === \"debugReportComplete\" && msg.log\n\t\t\t\t\t? JSON.stringify({ logLength: msg.log.length })\n\t\t\t\t\t: JSON.stringify(msg),\n\t\t});\n\t\tsend(msg);\n\t}\n\n\tprivate readonly sendAttendeeConnected = (attendee: Attendee): void => {\n\t\tthis.send({\n\t\t\tevent: \"attendeeConnected\",\n\t\t\tattendeeId: attendee.attendeeId,\n\t\t});\n\t};\n\tprivate readonly sendAttendeeDisconnected = (attendee: Attendee): void => {\n\t\tthis.send({\n\t\t\tevent: \"attendeeDisconnected\",\n\t\t\tattendeeId: attendee.attendeeId,\n\t\t});\n\t};\n\n\tprivate readonly logger: ITelemetryBaseLogger = {\n\t\tsend: (event: ITelemetryBaseEvent, logLevel?: LogLevel) => {\n\t\t\t// Filter out non-interactive client telemetry\n\t\t\tconst clientType = event.clientType;\n\t\t\tif (typeof clientType === \"string\" && clientType.startsWith(\"noninteractive\")) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Special case unexpected telemetry event\n\t\t\tif (event.eventName.endsWith(\":JoinResponseWhenAlone\")) {\n\t\t\t\tthis.send({\n\t\t\t\t\tevent: \"error\",\n\t\t\t\t\terror: `Unexpected ClientJoin response. Details: ${JSON.stringify(event.details)}\\nLog: ${JSON.stringify(this.log)}`,\n\t\t\t\t});\n\t\t\t\t// Keep going\n\t\t\t}\n\n\t\t\tconst interest = telemetryEventInterestLevel(event.eventName);\n\t\t\tif (interest === \"none\") {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.log.push({\n\t\t\t\ttimestamp: Date.now(),\n\t\t\t\tagentId: process_id,\n\t\t\t\teventCategory: \"telemetry\",\n\t\t\t\teventName: event.eventName,\n\t\t\t\tdetails:\n\t\t\t\t\ttypeof event.details === \"string\" ? event.details : JSON.stringify(event.details),\n\t\t\t});\n\t\t\tif (verbosity.includes(\"telem\")) {\n\t\t\t\tselectiveVerboseLog(event, logLevel);\n\t\t\t}\n\t\t},\n\t};\n\n\tprivate readonly onDisconnected = (): void => {\n\t\t// Test state is a bit fragile and does not account for reconnections.\n\t\tthis.send({ event: \"error\", error: `${process_id}: Container disconnected` });\n\t};\n\n\tprivate registerWorkspace(\n\t\tworkspaceId: string,\n\t\toptions: { latest?: boolean; latestMap?: boolean },\n\t): void {\n\t\tif (!this.presence) {\n\t\t\tthis.send({ event: \"error\", error: `${process_id} is not connected to presence` });\n\t\t\treturn;\n\t\t}\n\t\tconst { latest, latestMap } = options;\n\t\tconst workspace: StatesWorkspace<WorkspaceSchema> = this.presence.states.getWorkspace(\n\t\t\t`test:${workspaceId}`,\n\t\t\tWorkspaceSchema,\n\t\t);\n\n\t\tif (latest && !workspace.states.latest) {\n\t\t\tworkspace.add(\"latest\", StateFactory.latest({ local: { value: \"initial\" } }));\n\t\t\t// Cast required due to optional keys in WorkspaceSchema\n\t\t\t// TODO: AB#47518\n\t\t\tconst latestState = workspace.states.latest as LatestRaw<{ value: string }>;\n\t\t\tlatestState.events.on(\"remoteUpdated\", (update) => {\n\t\t\t\tthis.send({\n\t\t\t\t\tevent: \"latestValueUpdated\",\n\t\t\t\t\tworkspaceId,\n\t\t\t\t\tattendeeId: update.attendee.attendeeId,\n\t\t\t\t\tvalue: update.value.value,\n\t\t\t\t});\n\t\t\t});\n\t\t\tfor (const remote of latestState.getRemotes()) {\n\t\t\t\tthis.send({\n\t\t\t\t\tevent: \"latestValueUpdated\",\n\t\t\t\t\tworkspaceId,\n\t\t\t\t\tattendeeId: remote.attendee.attendeeId,\n\t\t\t\t\tvalue: remote.value.value,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tif (latestMap && !workspace.states.latestMap) {\n\t\t\tworkspace.add(\n\t\t\t\t\"latestMap\",\n\t\t\t\tStateFactory.latestMap<{ value: Record<string, string | number> }>({\n\t\t\t\t\tlocal: {},\n\t\t\t\t}),\n\t\t\t);\n\t\t\t// Cast required due to optional keys in WorkspaceSchema\n\t\t\t// TODO: AB#47518\n\t\t\tconst latestMapState = workspace.states.latestMap as LatestMapRaw<{\n\t\t\t\tvalue: Record<string, string | number>;\n\t\t\t}>;\n\t\t\tlatestMapState.events.on(\"remoteUpdated\", (update) => {\n\t\t\t\tfor (const [key, valueWithMetadata] of update.items) {\n\t\t\t\t\tthis.send({\n\t\t\t\t\t\tevent: \"latestMapValueUpdated\",\n\t\t\t\t\t\tworkspaceId,\n\t\t\t\t\t\tattendeeId: update.attendee.attendeeId,\n\t\t\t\t\t\tkey: String(key),\n\t\t\t\t\t\tvalue: valueWithMetadata.value.value,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\t\t\tfor (const remote of latestMapState.getRemotes()) {\n\t\t\t\tfor (const [key, valueWithMetadata] of remote.items) {\n\t\t\t\t\tthis.send({\n\t\t\t\t\t\tevent: \"latestMapValueUpdated\",\n\t\t\t\t\t\tworkspaceId,\n\t\t\t\t\t\tattendeeId: remote.attendee.attendeeId,\n\t\t\t\t\t\tkey: String(key),\n\t\t\t\t\t\tvalue: valueWithMetadata.value.value,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.workspaces.set(workspaceId, workspace);\n\t\tthis.send({\n\t\t\tevent: \"workspaceRegistered\",\n\t\t\tworkspaceId,\n\t\t\tlatest: latest ?? false,\n\t\t\tlatestMap: latestMap ?? false,\n\t\t});\n\t}\n\n\tpublic async onMessage(msg: MessageFromParent): Promise<void> {\n\t\tif (verbosity.includes(\"msgs\")) {\n\t\t\tthis.log.push({\n\t\t\t\ttimestamp: Date.now(),\n\t\t\t\tagentId: process_id,\n\t\t\t\teventCategory: \"messageReceived\",\n\t\t\t\teventName: msg.command,\n\t\t\t});\n\t\t\tlog(`Received`, msg);\n\t\t}\n\n\t\tif (msg.command === \"ping\") {\n\t\t\tthis.handlePing();\n\t\t\treturn;\n\t\t}\n\n\t\tif (msg.command === \"connect\") {\n\t\t\tawait this.handleConnect(msg);\n\t\t\treturn;\n\t\t}\n\n\t\t// All other message must wait if connect is in progress\n\t\tif (this.msgQueue !== undefined) {\n\t\t\tthis.msgQueue.push(msg);\n\t\t\treturn;\n\t\t}\n\n\t\tthis.processMessage(msg);\n\t}\n\n\tprivate processMessage(\n\t\tmsg: Exclude<MessageFromParent, { command: \"ping\" | \"connect\" }>,\n\t): void {\n\t\tswitch (msg.command) {\n\t\t\tcase \"debugReport\": {\n\t\t\t\tthis.handleDebugReport(msg);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"disconnectSelf\": {\n\t\t\t\tthis.handleDisconnectSelf();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"setLatestValue\": {\n\t\t\t\tthis.handleSetLatestValue(msg);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"setLatestMapValue\": {\n\t\t\t\tthis.handleSetLatestMapValue(msg);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"getLatestValue\": {\n\t\t\t\tthis.handleGetLatestValue(msg);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"getLatestMapValue\": {\n\t\t\t\tthis.handleGetLatestMapValue(msg);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"registerWorkspace\": {\n\t\t\t\tthis.registerWorkspace(msg.workspaceId, {\n\t\t\t\t\tlatest: msg.latest,\n\t\t\t\t\tlatestMap: msg.latestMap,\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tconsole.error(`${process_id}: Unknown command:`, msg);\n\t\t\t\tthis.send({\n\t\t\t\t\tevent: \"error\",\n\t\t\t\t\terror: `${process_id} Unknown command: ${JSON.stringify(msg)}`,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate handlePing(): void {\n\t\tthis.send({ event: \"ack\" });\n\t}\n\n\tprivate async handleConnect(\n\t\tmsg: Extract<MessageFromParent, { command: \"connect\" }>,\n\t): Promise<void> {\n\t\tif (!msg.user) {\n\t\t\tthis.send({ event: \"error\", error: `${process_id}: No azure user information given` });\n\t\t\treturn;\n\t\t}\n\t\tif (this.container) {\n\t\t\tthis.send({ event: \"error\", error: `${process_id}: Container already loaded` });\n\t\t\treturn;\n\t\t}\n\n\t\t// Prevent reentrance. Queue messages until after connect is fully processed.\n\t\tthis.msgQueue = [];\n\n\t\ttry {\n\t\t\tconst { container, containerId, connected } = await getOrCreateContainer({\n\t\t\t\t...msg,\n\t\t\t\tlogger: this.logger,\n\t\t\t\tonDisconnected: this.onDisconnected,\n\t\t\t});\n\t\t\tthis.container = container;\n\t\t\tconst presence = getPresence(container);\n\t\t\tthis.presence = presence;\n\n\t\t\t// wait for 'ConnectionState.Connected'\n\t\t\tawait connected.catch((error) => {\n\t\t\t\t(error as Error).message += `\\nLog: ${JSON.stringify(this.log)}`;\n\t\t\t\tthrow error;\n\t\t\t});\n\n\t\t\t// Acknowledge connection before sending current attendee information\n\t\t\tthis.send({\n\t\t\t\tevent: \"connected\",\n\t\t\t\tcontainerId,\n\t\t\t\tattendeeId: presence.attendees.getMyself().attendeeId,\n\t\t\t});\n\n\t\t\t// Send existing attendees excluding self to parent/orchestrator\n\t\t\tconst self = presence.attendees.getMyself();\n\t\t\tfor (const attendee of presence.attendees.getAttendees()) {\n\t\t\t\tif (attendee !== self && attendee.getConnectionStatus() === \"Connected\") {\n\t\t\t\t\tthis.sendAttendeeConnected(attendee);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Listen for presence events to notify parent/orchestrator when a new attendee joins or leaves the session.\n\t\t\tpresence.attendees.events.on(\"attendeeConnected\", this.sendAttendeeConnected);\n\t\t\tpresence.attendees.events.on(\"attendeeDisconnected\", this.sendAttendeeDisconnected);\n\t\t} finally {\n\t\t\t// Process any queued messages received while connecting\n\t\t\tfor (const queuedMsg of this.msgQueue) {\n\t\t\t\tthis.processMessage(queuedMsg);\n\t\t\t}\n\t\t\tthis.msgQueue = undefined;\n\t\t}\n\t}\n\n\tprivate handleDebugReport(\n\t\tmsg: Extract<MessageFromParent, { command: \"debugReport\" }>,\n\t): void {\n\t\tif (msg.reportAttendees) {\n\t\t\tif (this.presence) {\n\t\t\t\tconst attendees = this.presence.attendees.getAttendees();\n\t\t\t\tlet connectedCount = 0;\n\t\t\t\tfor (const attendee of attendees) {\n\t\t\t\t\tif (attendee.getConnectionStatus() === \"Connected\") {\n\t\t\t\t\t\tconnectedCount++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tlog(`Report: ${attendees.size} attendees, ${connectedCount} connected`);\n\t\t\t} else {\n\t\t\t\tthis.send({ event: \"error\", error: `${process_id} is not connected to presence` });\n\t\t\t}\n\t\t}\n\n\t\tconst debugReport: Extract<MessageToParent, { event: \"debugReportComplete\" }> = {\n\t\t\tevent: \"debugReportComplete\",\n\t\t};\n\t\tif (msg.sendEventLog) {\n\t\t\tdebugReport.log = this.log;\n\t\t}\n\t\tthis.send(debugReport);\n\t}\n\n\tprivate handleDisconnectSelf(): void {\n\t\tif (!this.container) {\n\t\t\tthis.send({ event: \"error\", error: `${process_id} is not connected to container` });\n\t\t\treturn;\n\t\t}\n\t\t// There are no current scenarios where disconnect without presence is expected.\n\t\tif (!this.presence) {\n\t\t\tthis.send({ event: \"error\", error: `${process_id} is not connected to presence` });\n\t\t\treturn;\n\t\t}\n\t\t// Disconnect event is treated as an error in normal handling.\n\t\t// Remove listener as this disconnect is intentional.\n\t\tthis.container.off(\"disconnected\", this.onDisconnected);\n\t\tthis.container.disconnect();\n\t\tthis.send({\n\t\t\tevent: \"disconnectedSelf\",\n\t\t\tattendeeId: this.presence.attendees.getMyself().attendeeId,\n\t\t});\n\t}\n\n\tprivate handleSetLatestValue(\n\t\tmsg: Extract<MessageFromParent, { command: \"setLatestValue\" }>,\n\t): void {\n\t\tif (!this.presence) {\n\t\t\tthis.send({ event: \"error\", error: `${process_id} is not connected to presence` });\n\t\t\treturn;\n\t\t}\n\t\tconst workspace = this.workspaces.get(msg.workspaceId);\n\t\tif (!workspace) {\n\t\t\tthis.send({\n\t\t\t\tevent: \"error\",\n\t\t\t\terror: `${process_id} workspace ${msg.workspaceId} not found`,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\t// Cast required due to optional keys in WorkspaceSchema\n\t\t// TODO: AB#47518\n\t\tconst latestState = workspace.states.latest as LatestRaw<{ value: string }> | undefined;\n\t\tif (!latestState) {\n\t\t\tthis.send({\n\t\t\t\tevent: \"error\",\n\t\t\t\terror: `${process_id} latest state not registered for workspace ${msg.workspaceId}`,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tif (typeof msg.value !== \"string\") {\n\t\t\treturn;\n\t\t}\n\t\tlatestState.local = { value: msg.value };\n\t}\n\n\tprivate handleSetLatestMapValue(\n\t\tmsg: Extract<MessageFromParent, { command: \"setLatestMapValue\" }>,\n\t): void {\n\t\tif (!this.presence) {\n\t\t\tthis.send({ event: \"error\", error: `${process_id} is not connected to presence` });\n\t\t\treturn;\n\t\t}\n\t\tif (typeof msg.key !== \"string\") {\n\t\t\tthis.send({ event: \"error\", error: `${process_id} invalid key type` });\n\t\t\treturn;\n\t\t}\n\t\tconst workspace = this.workspaces.get(msg.workspaceId);\n\t\tif (!workspace) {\n\t\t\tthis.send({\n\t\t\t\tevent: \"error\",\n\t\t\t\terror: `${process_id} workspace ${msg.workspaceId} not found`,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\t// Cast required due to optional keys in WorkspaceSchema\n\t\t// TODO: AB#47518\n\t\tconst latestMapState = workspace.states.latestMap as\n\t\t\t| LatestMapRaw<{ value: Record<string, string | number> }>\n\t\t\t| undefined;\n\t\tif (!latestMapState) {\n\t\t\tthis.send({\n\t\t\t\tevent: \"error\",\n\t\t\t\terror: `${process_id} latestMap state not registered for workspace ${msg.workspaceId}`,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tif (!isStringOrNumberRecord(msg.value)) {\n\t\t\treturn;\n\t\t}\n\t\tlatestMapState.local.set(msg.key, { value: msg.value });\n\t}\n\n\tprivate handleGetLatestValue(\n\t\tmsg: Extract<MessageFromParent, { command: \"getLatestValue\" }>,\n\t): void {\n\t\tif (!this.presence) {\n\t\t\tthis.send({ event: \"error\", error: `${process_id} is not connected to presence` });\n\t\t\treturn;\n\t\t}\n\t\tconst workspace = this.workspaces.get(msg.workspaceId);\n\t\tif (!workspace) {\n\t\t\tthis.send({\n\t\t\t\tevent: \"error\",\n\t\t\t\terror: `${process_id} workspace ${msg.workspaceId} not found`,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\t// Cast required due to optional keys in WorkspaceSchema\n\t\t// TODO: AB#47518\n\t\tconst latestState = workspace.states.latest as LatestRaw<{ value: string }> | undefined;\n\t\tif (!latestState) {\n\t\t\tthis.send({\n\t\t\t\tevent: \"error\",\n\t\t\t\terror: `${process_id} latest state not registered for workspace ${msg.workspaceId}`,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tlet value: { value: string };\n\t\tif (msg.attendeeId) {\n\t\t\tconst attendee = this.presence.attendees.getAttendee(msg.attendeeId);\n\t\t\tconst remoteData = latestState.getRemote(attendee);\n\t\t\tvalue = remoteData.value;\n\t\t} else {\n\t\t\tvalue = latestState.local;\n\t\t}\n\t\tthis.send({\n\t\t\tevent: \"latestValueGetResponse\",\n\t\t\tworkspaceId: msg.workspaceId,\n\t\t\tattendeeId: msg.attendeeId,\n\t\t\tvalue: value.value,\n\t\t});\n\t}\n\n\tprivate handleGetLatestMapValue(\n\t\tmsg: Extract<MessageFromParent, { command: \"getLatestMapValue\" }>,\n\t): void {\n\t\tif (!this.presence) {\n\t\t\tthis.send({ event: \"error\", error: `${process_id} is not connected to presence` });\n\t\t\treturn;\n\t\t}\n\t\tif (typeof msg.key !== \"string\") {\n\t\t\tthis.send({ event: \"error\", error: `${process_id} invalid key type` });\n\t\t\treturn;\n\t\t}\n\t\tconst workspace = this.workspaces.get(msg.workspaceId);\n\t\tif (!workspace) {\n\t\t\tthis.send({\n\t\t\t\tevent: \"error\",\n\t\t\t\terror: `${process_id} workspace ${msg.workspaceId} not found`,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\t// Cast required due to optional keys in WorkspaceSchema\n\t\t// TODO: AB#47518\n\t\tconst latestMapState = workspace.states.latestMap as\n\t\t\t| LatestMapRaw<{ value: Record<string, string | number> }>\n\t\t\t| undefined;\n\t\tif (!latestMapState) {\n\t\t\tthis.send({\n\t\t\t\tevent: \"error\",\n\t\t\t\terror: `${process_id} latestMap state not registered for workspace ${msg.workspaceId}`,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tlet value: { value: Record<string, string | number> } | undefined;\n\t\tif (msg.attendeeId) {\n\t\t\tconst attendee = this.presence.attendees.getAttendee(msg.attendeeId);\n\t\t\tconst remoteData = latestMapState.getRemote(attendee);\n\t\t\tconst keyData = remoteData.get(msg.key);\n\t\t\tvalue = keyData?.value;\n\t\t} else {\n\t\t\tvalue = latestMapState.local.get(msg.key);\n\t\t}\n\t\tthis.send({\n\t\t\tevent: \"latestMapValueGetResponse\",\n\t\t\tworkspaceId: msg.workspaceId,\n\t\t\tattendeeId: msg.attendeeId,\n\t\t\tkey: msg.key,\n\t\t\tvalue: value?.value,\n\t\t});\n\t}\n}\n\nfunction setupMessageHandler(): void {\n\tconst messageHandler = new MessageHandler();\n\tprocess.on(\"message\", (msg: MessageFromParent) => {\n\t\tmessageHandler.onMessage(msg).catch((error: Error) => {\n\t\t\tconsole.error(`[${testLabel}] Error in client ${process_id}`, error);\n\t\t\tsend({ event: \"error\", error: `${process_id}: ${error.message}` });\n\t\t});\n\t});\n}\n\nsetupMessageHandler();\n"]}
|
package/lib/test/signals.spec.js
CHANGED
|
@@ -9,7 +9,7 @@ import { timeoutPromise } from "@fluidframework/test-utils/internal";
|
|
|
9
9
|
import { createAzureClient, createContainerFromPayload, getContainerIdFromPayloadResponse, ScopeType, } from "./AzureClientFactory.js";
|
|
10
10
|
import { SignalerTestDataObject } from "./TestDataObject.js";
|
|
11
11
|
import * as ephemeralSummaryTrees from "./ephemeralSummaryTrees.js";
|
|
12
|
-
import { configProvider, getTestMatrix } from "./utils.js";
|
|
12
|
+
import { configProvider, getTestMatrix, currentVersion } from "./utils.js";
|
|
13
13
|
async function createSignalListenerPromise(signaler, signalType, expectedPayload, name = "Signal", timeoutMs = 10_000) {
|
|
14
14
|
return timeoutPromise((resolve, reject) => {
|
|
15
15
|
signaler.onSignal(signalType, (clientId, local, receivedPayload) => {
|
|
@@ -62,16 +62,16 @@ for (const testOpts of testMatrix) {
|
|
|
62
62
|
if (isEphemeral) {
|
|
63
63
|
const containerResponse = await createContainerFromPayload(ephemeralSummaryTrees.sendAndRecieveSignals, "test-user-id-1", "test-user-name-1");
|
|
64
64
|
containerId = getContainerIdFromPayloadResponse(containerResponse);
|
|
65
|
-
({ container, services } = await client.getContainer(containerId, schema,
|
|
65
|
+
({ container, services } = await client.getContainer(containerId, schema, currentVersion));
|
|
66
66
|
}
|
|
67
67
|
else {
|
|
68
|
-
({ container, services } = await client.createContainer(schema,
|
|
68
|
+
({ container, services } = await client.createContainer(schema, currentVersion));
|
|
69
69
|
containerId = await container.attach();
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
72
|
else {
|
|
73
73
|
containerId = id;
|
|
74
|
-
({ container, services } = await client.getContainer(containerId, schema,
|
|
74
|
+
({ container, services } = await client.getContainer(containerId, schema, currentVersion));
|
|
75
75
|
}
|
|
76
76
|
if (container.connectionState !== ConnectionState.Connected) {
|
|
77
77
|
await timeoutPromise((resolve) => container.once("connected", () => resolve()), {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signals.spec.js","sourceRoot":"","sources":["../../src/test/signals.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 \"node:assert\";\n\nimport type { AzureClient, AzureContainerServices } from \"@fluidframework/azure-client\";\nimport { AttachState } from \"@fluidframework/container-definitions\";\nimport { ConnectionState } from \"@fluidframework/container-loader\";\nimport type { ContainerSchema, IFluidContainer } from \"@fluidframework/fluid-static\";\nimport { timeoutPromise } from \"@fluidframework/test-utils/internal\";\n\nimport {\n\tcreateAzureClient,\n\tcreateContainerFromPayload,\n\tgetContainerIdFromPayloadResponse,\n\tScopeType,\n} from \"./AzureClientFactory.js\";\nimport { SignalerTestDataObject } from \"./TestDataObject.js\";\nimport * as ephemeralSummaryTrees from \"./ephemeralSummaryTrees.js\";\nimport { configProvider, getTestMatrix } from \"./utils.js\";\n\ninterface UserIdAndName {\n\treadonly id: string;\n\treadonly name: string;\n}\n\nasync function createSignalListenerPromise<T>(\n\tsignaler: SignalerTestDataObject,\n\tsignalType: string,\n\texpectedPayload: T,\n\tname: string = \"Signal\",\n\ttimeoutMs: number = 10_000,\n): Promise<T> {\n\treturn timeoutPromise(\n\t\t(resolve, reject) => {\n\t\t\tsignaler.onSignal<T>(signalType, (clientId, local, receivedPayload) => {\n\t\t\t\ttry {\n\t\t\t\t\tassert.deepStrictEqual(\n\t\t\t\t\t\treceivedPayload,\n\t\t\t\t\t\texpectedPayload,\n\t\t\t\t\t\t\"Received payload does not match expected payload\",\n\t\t\t\t\t);\n\t\t\t\t} catch (error) {\n\t\t\t\t\treturn reject(error);\n\t\t\t\t}\n\t\t\t\tresolve(receivedPayload);\n\t\t\t});\n\t\t},\n\t\t{ durationMs: timeoutMs, errorMsg: `${name}: listener timeout` },\n\t);\n}\n\nconst testMatrix = getTestMatrix();\nfor (const testOpts of testMatrix) {\n\tdescribe(`Fluid Signals (${testOpts.variant})`, () => {\n\t\tconst connectedContainers: IFluidContainer[] = [];\n\t\tconst connectTimeoutMs = 10_000;\n\t\tconst isEphemeral: boolean = testOpts.options.isEphemeral;\n\t\tconst user1 = {\n\t\t\tid: \"test-user-id-1\",\n\t\t\tname: \"test-user-name-2\",\n\t\t} as const satisfies UserIdAndName;\n\t\tconst user2 = {\n\t\t\tid: \"test-user-id-1\",\n\t\t\tname: \"test-user-name-2\",\n\t\t} as const satisfies UserIdAndName;\n\t\tconst user3 = {\n\t\t\tid: \"test-user-id-1\",\n\t\t\tname: \"test-user-name-2\",\n\t\t} as const satisfies UserIdAndName;\n\n\t\tafterEach(async () => {\n\t\t\tfor (const container of connectedContainers) {\n\t\t\t\tcontainer.disconnect();\n\t\t\t\tcontainer.dispose();\n\t\t\t}\n\t\t\tconnectedContainers.splice(0, connectedContainers.length);\n\t\t});\n\n\t\tconst getOrCreateSignalerContainer = async (\n\t\t\tid: string | undefined,\n\t\t\tuser: UserIdAndName,\n\t\t\tconfig?: ReturnType<typeof configProvider>,\n\t\t\tscopes?: ScopeType[],\n\t\t): Promise<{\n\t\t\tcontainer: IFluidContainer;\n\t\t\tsignaler: SignalerTestDataObject;\n\t\t\tservices: AzureContainerServices;\n\t\t\tclient: AzureClient;\n\t\t\tcontainerId: string;\n\t\t}> => {\n\t\t\tconst client = createAzureClient(user.id, user.name, undefined, config, scopes);\n\t\t\tconst schema: ContainerSchema = {\n\t\t\t\tinitialObjects: {\n\t\t\t\t\tsignaler: SignalerTestDataObject,\n\t\t\t\t},\n\t\t\t};\n\t\t\tlet container: IFluidContainer;\n\t\t\tlet services: AzureContainerServices;\n\t\t\tlet containerId: string;\n\t\t\tif (id === undefined) {\n\t\t\t\tif (isEphemeral) {\n\t\t\t\t\tconst containerResponse = await createContainerFromPayload(\n\t\t\t\t\t\tephemeralSummaryTrees.sendAndRecieveSignals,\n\t\t\t\t\t\t\"test-user-id-1\",\n\t\t\t\t\t\t\"test-user-name-1\",\n\t\t\t\t\t);\n\t\t\t\t\tcontainerId = getContainerIdFromPayloadResponse(containerResponse);\n\t\t\t\t\t({ container, services } = await client.getContainer(containerId, schema, \"2\"));\n\t\t\t\t} else {\n\t\t\t\t\t({ container, services } = await client.createContainer(schema, \"2\"));\n\t\t\t\t\tcontainerId = await container.attach();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcontainerId = id;\n\t\t\t\t({ container, services } = await client.getContainer(containerId, schema, \"2\"));\n\t\t\t}\n\n\t\t\tif (container.connectionState !== ConnectionState.Connected) {\n\t\t\t\tawait timeoutPromise((resolve) => container.once(\"connected\", () => resolve()), {\n\t\t\t\t\tdurationMs: connectTimeoutMs,\n\t\t\t\t\terrorMsg: \"container connect() timeout\",\n\t\t\t\t});\n\t\t\t}\n\t\t\tconnectedContainers.push(container);\n\n\t\t\tassert.strictEqual(typeof containerId, \"string\", \"Attach did not return a string ID\");\n\t\t\tassert.strictEqual(\n\t\t\t\tcontainer.attachState,\n\t\t\t\tAttachState.Attached,\n\t\t\t\t\"Container is not attached after attach is called\",\n\t\t\t);\n\n\t\t\tconst signaler = container.initialObjects.signaler as SignalerTestDataObject;\n\t\t\treturn {\n\t\t\t\tclient,\n\t\t\t\tcontainer,\n\t\t\t\tsignaler,\n\t\t\t\tservices,\n\t\t\t\tcontainerId,\n\t\t\t};\n\t\t};\n\n\t\t/**\n\t\t * Scenario: Client sends a signal and connected clients receive it.\n\t\t *\n\t\t * Expected behavior: While 2 clients are connected to a container,\n\t\t * a signal sent by 1 client should be received by both clients.\n\t\t */\n\t\tit(\"can send and receive signals\", async () => {\n\t\t\tconst { signaler, containerId } = await getOrCreateSignalerContainer(undefined, user1);\n\t\t\tconst { signaler: signaler2 } = await getOrCreateSignalerContainer(\n\t\t\t\tcontainerId,\n\t\t\t\tuser2,\n\t\t\t\tconfigProvider({\n\t\t\t\t\t\"Fluid.Container.ForceWriteConnection\": true,\n\t\t\t\t}),\n\t\t\t);\n\n\t\t\tconst signalName = \"test-signal\";\n\t\t\tconst signalPayload = { test: \"payload\" };\n\n\t\t\tconst listenerPromises = [\n\t\t\t\tcreateSignalListenerPromise(\n\t\t\t\t\tsignaler2,\n\t\t\t\t\tsignalName,\n\t\t\t\t\tsignalPayload,\n\t\t\t\t\t\"Write client listening for write client signal\",\n\t\t\t\t),\n\t\t\t\tcreateSignalListenerPromise(\n\t\t\t\t\tsignaler,\n\t\t\t\t\tsignalName,\n\t\t\t\t\tsignalPayload,\n\t\t\t\t\t\"Write client listening for its own signal\",\n\t\t\t\t),\n\t\t\t];\n\n\t\t\tsignaler.submitSignal(signalName, signalPayload);\n\n\t\t\tawait assert.doesNotReject(\n\t\t\t\tPromise.all(listenerPromises),\n\t\t\t\t\"Listening clients should receive signals.\",\n\t\t\t);\n\t\t});\n\n\t\t/**\n\t\t * Scenario: Read and Write clients send signals and connected clients receive them.\n\t\t *\n\t\t * Expected behavior: While 2 clients are connected (1 writer, 2 readers) to a container,\n\t\t * a signal sent by any 1 client should be received by all 3 clients, regardless of read/write permissions.\n\t\t */\n\t\tit(\"can send and receive read-only client signals\", async function () {\n\t\t\tconst { signaler: writeSignaler, containerId } = await getOrCreateSignalerContainer(\n\t\t\t\tundefined,\n\t\t\t\tuser1,\n\t\t\t);\n\t\t\tconst { signaler: readSignaler } = await getOrCreateSignalerContainer(\n\t\t\t\tcontainerId,\n\t\t\t\tuser2,\n\t\t\t\tundefined,\n\t\t\t\t[ScopeType.DocRead],\n\t\t\t);\n\t\t\tconst { signaler: readSignaler2 } = await getOrCreateSignalerContainer(\n\t\t\t\tcontainerId,\n\t\t\t\tuser3,\n\t\t\t\tundefined,\n\t\t\t\t[ScopeType.DocRead],\n\t\t\t);\n\n\t\t\tconst signalName = \"test-signal\";\n\n\t\t\tconst signalPayload1 = { test: \"payload\" };\n\t\t\tconst listenerPromises1 = [\n\t\t\t\tcreateSignalListenerPromise(\n\t\t\t\t\twriteSignaler,\n\t\t\t\t\tsignalName,\n\t\t\t\t\tsignalPayload1,\n\t\t\t\t\t\"Write client listening for read client signal\",\n\t\t\t\t),\n\t\t\t\tcreateSignalListenerPromise(\n\t\t\t\t\treadSignaler2,\n\t\t\t\t\tsignalName,\n\t\t\t\t\tsignalPayload1,\n\t\t\t\t\t\"Read client 2 listening for read client signal\",\n\t\t\t\t),\n\t\t\t\tcreateSignalListenerPromise(\n\t\t\t\t\treadSignaler,\n\t\t\t\t\tsignalName,\n\t\t\t\t\tsignalPayload1,\n\t\t\t\t\t\"Read client listening for its own signal\",\n\t\t\t\t),\n\t\t\t];\n\t\t\treadSignaler.submitSignal(signalName, signalPayload1);\n\t\t\tawait assert.doesNotReject(\n\t\t\t\tPromise.all(listenerPromises1),\n\t\t\t\t\"Listening clients should receive signals from read clients.\",\n\t\t\t);\n\n\t\t\tconst signalPayload2 = { test: \"payload2\" };\n\t\t\tconst listenerPromises2 = [\n\t\t\t\tcreateSignalListenerPromise(\n\t\t\t\t\treadSignaler,\n\t\t\t\t\tsignalName,\n\t\t\t\t\tsignalPayload2,\n\t\t\t\t\t\"Read client listening for write client signal\",\n\t\t\t\t),\n\t\t\t\tcreateSignalListenerPromise(\n\t\t\t\t\treadSignaler2,\n\t\t\t\t\tsignalName,\n\t\t\t\t\tsignalPayload2,\n\t\t\t\t\t\"Read client 2 listening for write client signal\",\n\t\t\t\t),\n\t\t\t\tcreateSignalListenerPromise(\n\t\t\t\t\twriteSignaler,\n\t\t\t\t\tsignalName,\n\t\t\t\t\tsignalPayload2,\n\t\t\t\t\t\"Write client listening for its own signal\",\n\t\t\t\t),\n\t\t\t];\n\t\t\twriteSignaler.submitSignal(signalName, signalPayload2);\n\t\t\tawait assert.doesNotReject(\n\t\t\t\tPromise.all(listenerPromises2),\n\t\t\t\t\"Listening clients should receive signals from write clients.\",\n\t\t\t);\n\t\t});\n\t});\n}\n"]}
|
|
1
|
+
{"version":3,"file":"signals.spec.js","sourceRoot":"","sources":["../../src/test/signals.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 \"node:assert\";\n\nimport type { AzureClient, AzureContainerServices } from \"@fluidframework/azure-client\";\nimport { AttachState } from \"@fluidframework/container-definitions\";\nimport { ConnectionState } from \"@fluidframework/container-loader\";\nimport type { ContainerSchema, IFluidContainer } from \"@fluidframework/fluid-static\";\nimport { timeoutPromise } from \"@fluidframework/test-utils/internal\";\n\nimport {\n\tcreateAzureClient,\n\tcreateContainerFromPayload,\n\tgetContainerIdFromPayloadResponse,\n\tScopeType,\n} from \"./AzureClientFactory.js\";\nimport { SignalerTestDataObject } from \"./TestDataObject.js\";\nimport * as ephemeralSummaryTrees from \"./ephemeralSummaryTrees.js\";\nimport { configProvider, getTestMatrix, currentVersion } from \"./utils.js\";\n\ninterface UserIdAndName {\n\treadonly id: string;\n\treadonly name: string;\n}\n\nasync function createSignalListenerPromise<T>(\n\tsignaler: SignalerTestDataObject,\n\tsignalType: string,\n\texpectedPayload: T,\n\tname: string = \"Signal\",\n\ttimeoutMs: number = 10_000,\n): Promise<T> {\n\treturn timeoutPromise(\n\t\t(resolve, reject) => {\n\t\t\tsignaler.onSignal<T>(signalType, (clientId, local, receivedPayload) => {\n\t\t\t\ttry {\n\t\t\t\t\tassert.deepStrictEqual(\n\t\t\t\t\t\treceivedPayload,\n\t\t\t\t\t\texpectedPayload,\n\t\t\t\t\t\t\"Received payload does not match expected payload\",\n\t\t\t\t\t);\n\t\t\t\t} catch (error) {\n\t\t\t\t\treturn reject(error);\n\t\t\t\t}\n\t\t\t\tresolve(receivedPayload);\n\t\t\t});\n\t\t},\n\t\t{ durationMs: timeoutMs, errorMsg: `${name}: listener timeout` },\n\t);\n}\n\nconst testMatrix = getTestMatrix();\nfor (const testOpts of testMatrix) {\n\tdescribe(`Fluid Signals (${testOpts.variant})`, () => {\n\t\tconst connectedContainers: IFluidContainer[] = [];\n\t\tconst connectTimeoutMs = 10_000;\n\t\tconst isEphemeral: boolean = testOpts.options.isEphemeral;\n\t\tconst user1 = {\n\t\t\tid: \"test-user-id-1\",\n\t\t\tname: \"test-user-name-2\",\n\t\t} as const satisfies UserIdAndName;\n\t\tconst user2 = {\n\t\t\tid: \"test-user-id-1\",\n\t\t\tname: \"test-user-name-2\",\n\t\t} as const satisfies UserIdAndName;\n\t\tconst user3 = {\n\t\t\tid: \"test-user-id-1\",\n\t\t\tname: \"test-user-name-2\",\n\t\t} as const satisfies UserIdAndName;\n\n\t\tafterEach(async () => {\n\t\t\tfor (const container of connectedContainers) {\n\t\t\t\tcontainer.disconnect();\n\t\t\t\tcontainer.dispose();\n\t\t\t}\n\t\t\tconnectedContainers.splice(0, connectedContainers.length);\n\t\t});\n\n\t\tconst getOrCreateSignalerContainer = async (\n\t\t\tid: string | undefined,\n\t\t\tuser: UserIdAndName,\n\t\t\tconfig?: ReturnType<typeof configProvider>,\n\t\t\tscopes?: ScopeType[],\n\t\t): Promise<{\n\t\t\tcontainer: IFluidContainer;\n\t\t\tsignaler: SignalerTestDataObject;\n\t\t\tservices: AzureContainerServices;\n\t\t\tclient: AzureClient;\n\t\t\tcontainerId: string;\n\t\t}> => {\n\t\t\tconst client = createAzureClient(user.id, user.name, undefined, config, scopes);\n\t\t\tconst schema: ContainerSchema = {\n\t\t\t\tinitialObjects: {\n\t\t\t\t\tsignaler: SignalerTestDataObject,\n\t\t\t\t},\n\t\t\t};\n\t\t\tlet container: IFluidContainer;\n\t\t\tlet services: AzureContainerServices;\n\t\t\tlet containerId: string;\n\t\t\tif (id === undefined) {\n\t\t\t\tif (isEphemeral) {\n\t\t\t\t\tconst containerResponse = await createContainerFromPayload(\n\t\t\t\t\t\tephemeralSummaryTrees.sendAndRecieveSignals,\n\t\t\t\t\t\t\"test-user-id-1\",\n\t\t\t\t\t\t\"test-user-name-1\",\n\t\t\t\t\t);\n\t\t\t\t\tcontainerId = getContainerIdFromPayloadResponse(containerResponse);\n\t\t\t\t\t({ container, services } = await client.getContainer(\n\t\t\t\t\t\tcontainerId,\n\t\t\t\t\t\tschema,\n\t\t\t\t\t\tcurrentVersion,\n\t\t\t\t\t));\n\t\t\t\t} else {\n\t\t\t\t\t({ container, services } = await client.createContainer(schema, currentVersion));\n\t\t\t\t\tcontainerId = await container.attach();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcontainerId = id;\n\t\t\t\t({ container, services } = await client.getContainer(\n\t\t\t\t\tcontainerId,\n\t\t\t\t\tschema,\n\t\t\t\t\tcurrentVersion,\n\t\t\t\t));\n\t\t\t}\n\n\t\t\tif (container.connectionState !== ConnectionState.Connected) {\n\t\t\t\tawait timeoutPromise((resolve) => container.once(\"connected\", () => resolve()), {\n\t\t\t\t\tdurationMs: connectTimeoutMs,\n\t\t\t\t\terrorMsg: \"container connect() timeout\",\n\t\t\t\t});\n\t\t\t}\n\t\t\tconnectedContainers.push(container);\n\n\t\t\tassert.strictEqual(typeof containerId, \"string\", \"Attach did not return a string ID\");\n\t\t\tassert.strictEqual(\n\t\t\t\tcontainer.attachState,\n\t\t\t\tAttachState.Attached,\n\t\t\t\t\"Container is not attached after attach is called\",\n\t\t\t);\n\n\t\t\tconst signaler = container.initialObjects.signaler as SignalerTestDataObject;\n\t\t\treturn {\n\t\t\t\tclient,\n\t\t\t\tcontainer,\n\t\t\t\tsignaler,\n\t\t\t\tservices,\n\t\t\t\tcontainerId,\n\t\t\t};\n\t\t};\n\n\t\t/**\n\t\t * Scenario: Client sends a signal and connected clients receive it.\n\t\t *\n\t\t * Expected behavior: While 2 clients are connected to a container,\n\t\t * a signal sent by 1 client should be received by both clients.\n\t\t */\n\t\tit(\"can send and receive signals\", async () => {\n\t\t\tconst { signaler, containerId } = await getOrCreateSignalerContainer(undefined, user1);\n\t\t\tconst { signaler: signaler2 } = await getOrCreateSignalerContainer(\n\t\t\t\tcontainerId,\n\t\t\t\tuser2,\n\t\t\t\tconfigProvider({\n\t\t\t\t\t\"Fluid.Container.ForceWriteConnection\": true,\n\t\t\t\t}),\n\t\t\t);\n\n\t\t\tconst signalName = \"test-signal\";\n\t\t\tconst signalPayload = { test: \"payload\" };\n\n\t\t\tconst listenerPromises = [\n\t\t\t\tcreateSignalListenerPromise(\n\t\t\t\t\tsignaler2,\n\t\t\t\t\tsignalName,\n\t\t\t\t\tsignalPayload,\n\t\t\t\t\t\"Write client listening for write client signal\",\n\t\t\t\t),\n\t\t\t\tcreateSignalListenerPromise(\n\t\t\t\t\tsignaler,\n\t\t\t\t\tsignalName,\n\t\t\t\t\tsignalPayload,\n\t\t\t\t\t\"Write client listening for its own signal\",\n\t\t\t\t),\n\t\t\t];\n\n\t\t\tsignaler.submitSignal(signalName, signalPayload);\n\n\t\t\tawait assert.doesNotReject(\n\t\t\t\tPromise.all(listenerPromises),\n\t\t\t\t\"Listening clients should receive signals.\",\n\t\t\t);\n\t\t});\n\n\t\t/**\n\t\t * Scenario: Read and Write clients send signals and connected clients receive them.\n\t\t *\n\t\t * Expected behavior: While 2 clients are connected (1 writer, 2 readers) to a container,\n\t\t * a signal sent by any 1 client should be received by all 3 clients, regardless of read/write permissions.\n\t\t */\n\t\tit(\"can send and receive read-only client signals\", async function () {\n\t\t\tconst { signaler: writeSignaler, containerId } = await getOrCreateSignalerContainer(\n\t\t\t\tundefined,\n\t\t\t\tuser1,\n\t\t\t);\n\t\t\tconst { signaler: readSignaler } = await getOrCreateSignalerContainer(\n\t\t\t\tcontainerId,\n\t\t\t\tuser2,\n\t\t\t\tundefined,\n\t\t\t\t[ScopeType.DocRead],\n\t\t\t);\n\t\t\tconst { signaler: readSignaler2 } = await getOrCreateSignalerContainer(\n\t\t\t\tcontainerId,\n\t\t\t\tuser3,\n\t\t\t\tundefined,\n\t\t\t\t[ScopeType.DocRead],\n\t\t\t);\n\n\t\t\tconst signalName = \"test-signal\";\n\n\t\t\tconst signalPayload1 = { test: \"payload\" };\n\t\t\tconst listenerPromises1 = [\n\t\t\t\tcreateSignalListenerPromise(\n\t\t\t\t\twriteSignaler,\n\t\t\t\t\tsignalName,\n\t\t\t\t\tsignalPayload1,\n\t\t\t\t\t\"Write client listening for read client signal\",\n\t\t\t\t),\n\t\t\t\tcreateSignalListenerPromise(\n\t\t\t\t\treadSignaler2,\n\t\t\t\t\tsignalName,\n\t\t\t\t\tsignalPayload1,\n\t\t\t\t\t\"Read client 2 listening for read client signal\",\n\t\t\t\t),\n\t\t\t\tcreateSignalListenerPromise(\n\t\t\t\t\treadSignaler,\n\t\t\t\t\tsignalName,\n\t\t\t\t\tsignalPayload1,\n\t\t\t\t\t\"Read client listening for its own signal\",\n\t\t\t\t),\n\t\t\t];\n\t\t\treadSignaler.submitSignal(signalName, signalPayload1);\n\t\t\tawait assert.doesNotReject(\n\t\t\t\tPromise.all(listenerPromises1),\n\t\t\t\t\"Listening clients should receive signals from read clients.\",\n\t\t\t);\n\n\t\t\tconst signalPayload2 = { test: \"payload2\" };\n\t\t\tconst listenerPromises2 = [\n\t\t\t\tcreateSignalListenerPromise(\n\t\t\t\t\treadSignaler,\n\t\t\t\t\tsignalName,\n\t\t\t\t\tsignalPayload2,\n\t\t\t\t\t\"Read client listening for write client signal\",\n\t\t\t\t),\n\t\t\t\tcreateSignalListenerPromise(\n\t\t\t\t\treadSignaler2,\n\t\t\t\t\tsignalName,\n\t\t\t\t\tsignalPayload2,\n\t\t\t\t\t\"Read client 2 listening for write client signal\",\n\t\t\t\t),\n\t\t\t\tcreateSignalListenerPromise(\n\t\t\t\t\twriteSignaler,\n\t\t\t\t\tsignalName,\n\t\t\t\t\tsignalPayload2,\n\t\t\t\t\t\"Write client listening for its own signal\",\n\t\t\t\t),\n\t\t\t];\n\t\t\twriteSignaler.submitSignal(signalName, signalPayload2);\n\t\t\tawait assert.doesNotReject(\n\t\t\t\tPromise.all(listenerPromises2),\n\t\t\t\t\"Listening clients should receive signals from write clients.\",\n\t\t\t);\n\t\t});\n\t});\n}\n"]}
|
package/lib/test/tree.spec.js
CHANGED
|
@@ -10,7 +10,7 @@ import { allowUnused, asAlpha } from "@fluidframework/tree/alpha";
|
|
|
10
10
|
import { SharedTree } from "@fluidframework/tree/legacy";
|
|
11
11
|
import { createAzureClient, createContainerFromPayload, getContainerIdFromPayloadResponse, } from "./AzureClientFactory.js";
|
|
12
12
|
import * as ephemeralSummaryTrees from "./ephemeralSummaryTrees.js";
|
|
13
|
-
import { getTestMatrix } from "./utils.js";
|
|
13
|
+
import { getTestMatrix, currentVersion } from "./utils.js";
|
|
14
14
|
const sf = new SchemaFactory("d302b84c-75f6-4ecd-9663-524f467013e3");
|
|
15
15
|
/**
|
|
16
16
|
* Define a class that is an array of strings
|
|
@@ -66,7 +66,7 @@ for (const testOpts of testMatrix) {
|
|
|
66
66
|
let containerId;
|
|
67
67
|
let treeData;
|
|
68
68
|
if (summaryTree === undefined) {
|
|
69
|
-
const { container } = await client.createContainer(schema,
|
|
69
|
+
const { container } = await client.createContainer(schema, currentVersion);
|
|
70
70
|
treeData = container.initialObjects.tree1.viewWith(treeConfiguration);
|
|
71
71
|
treeData.initialize(new StringArray([]));
|
|
72
72
|
containerId = await container.attach();
|
|
@@ -75,7 +75,7 @@ for (const testOpts of testMatrix) {
|
|
|
75
75
|
else {
|
|
76
76
|
const containerResponse = await createContainerFromPayload(summaryTree, "test-user-id-1", "test-user-name-1");
|
|
77
77
|
containerId = getContainerIdFromPayloadResponse(containerResponse);
|
|
78
|
-
const { container } = await client.getContainer(containerId, schema,
|
|
78
|
+
const { container } = await client.getContainer(containerId, schema, currentVersion);
|
|
79
79
|
treeData = container.initialObjects.tree1.viewWith(treeConfiguration);
|
|
80
80
|
await waitForConnection(container);
|
|
81
81
|
}
|
|
@@ -100,7 +100,7 @@ for (const testOpts of testMatrix) {
|
|
|
100
100
|
it("can create/load a container with SharedTree collaborate with basic ops", async () => {
|
|
101
101
|
const { containerId, treeData } = await createOrLoad(isEphemeral ? ephemeralSummaryTrees.createLoadContainerWithSharedTree : undefined);
|
|
102
102
|
treeData.root.insertNew("test string 1");
|
|
103
|
-
const resources = client.getContainer(containerId, schema,
|
|
103
|
+
const resources = client.getContainer(containerId, schema, currentVersion);
|
|
104
104
|
await assert.doesNotReject(resources, () => true, "container cannot be retrieved from Azure Fluid Relay");
|
|
105
105
|
const { container: container2 } = await resources;
|
|
106
106
|
assert.deepStrictEqual(Object.keys(container2.initialObjects), Object.keys(schema.initialObjects));
|
|
@@ -127,7 +127,7 @@ for (const testOpts of testMatrix) {
|
|
|
127
127
|
}) {
|
|
128
128
|
}
|
|
129
129
|
it("can read and edit data", async () => {
|
|
130
|
-
const { container } = await client.createContainer(schema,
|
|
130
|
+
const { container } = await client.createContainer(schema, currentVersion);
|
|
131
131
|
await container.attach();
|
|
132
132
|
const view = container.initialObjects.tree1.viewWith(new TreeViewConfiguration({ schema: User, enableSchemaValidation: true }));
|
|
133
133
|
const tags = [
|
|
@@ -160,7 +160,7 @@ for (const testOpts of testMatrix) {
|
|
|
160
160
|
assert.equal(user.data.get("Favorite Sport"), "Ultimate Frisbee");
|
|
161
161
|
});
|
|
162
162
|
it("can handle undo/redo and transactions", async () => {
|
|
163
|
-
const { container } = await client.createContainer(schema,
|
|
163
|
+
const { container } = await client.createContainer(schema, currentVersion);
|
|
164
164
|
await container.attach();
|
|
165
165
|
const view = asAlpha(container.initialObjects.tree1.viewWith(new TreeViewConfiguration({ schema: User, enableSchemaValidation: true })));
|
|
166
166
|
view.initialize(new User({
|
|
@@ -199,7 +199,7 @@ for (const testOpts of testMatrix) {
|
|
|
199
199
|
it("can use identifiers and the static Tree APIs", async () => {
|
|
200
200
|
class Widget extends sf.object("Widget", { id: sf.identifier }) {
|
|
201
201
|
}
|
|
202
|
-
const { container } = await client.createContainer(schema,
|
|
202
|
+
const { container } = await client.createContainer(schema, currentVersion);
|
|
203
203
|
await container.attach();
|
|
204
204
|
const view = container.initialObjects.tree1.viewWith(new TreeViewConfiguration({
|
|
205
205
|
schema: sf.array(Widget),
|
|
@@ -229,7 +229,7 @@ for (const testOpts of testMatrix) {
|
|
|
229
229
|
}) {
|
|
230
230
|
}
|
|
231
231
|
allowUnused();
|
|
232
|
-
const { container } = await client.createContainer(schema,
|
|
232
|
+
const { container } = await client.createContainer(schema, currentVersion);
|
|
233
233
|
await container.attach();
|
|
234
234
|
const view = container.initialObjects.tree1.viewWith(new TreeViewConfiguration({ schema: Doll, enableSchemaValidation: true }));
|
|
235
235
|
// These nodes in the initial tree are unhydrated...
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tree.spec.js","sourceRoot":"","sources":["../../src/test/tree.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 \"node:assert\";\n\nimport type { AzureClient } from \"@fluidframework/azure-client\";\nimport { ConnectionState } from \"@fluidframework/container-loader\";\nimport type { ContainerSchema, IFluidContainer } from \"@fluidframework/fluid-static\";\nimport { timeoutPromise } from \"@fluidframework/test-utils/internal\";\nimport type { Revertible, TreeView, ValidateRecursiveSchema } from \"@fluidframework/tree\";\nimport { SchemaFactory, Tree, TreeStatus, TreeViewConfiguration } from \"@fluidframework/tree\";\nimport { allowUnused, asAlpha } from \"@fluidframework/tree/alpha\";\nimport { SharedTree } from \"@fluidframework/tree/legacy\";\n\nimport {\n\tcreateAzureClient,\n\tcreateContainerFromPayload,\n\tgetContainerIdFromPayloadResponse,\n} from \"./AzureClientFactory.js\";\nimport * as ephemeralSummaryTrees from \"./ephemeralSummaryTrees.js\";\nimport { getTestMatrix } from \"./utils.js\";\n\nconst sf = new SchemaFactory(\"d302b84c-75f6-4ecd-9663-524f467013e3\");\n\n/**\n * Define a class that is an array of strings\n * This class is used to create an array in the SharedTree\n */\nclass StringArray extends sf.array(\"StringArray\", sf.string) {\n\t/**\n\t * Remove the first item in the list if the list is not empty\n\t */\n\tpublic removeFirst(): void {\n\t\tif (this.length > 0) this.removeAt(0);\n\t}\n\n\t/**\n\t * Add an item to the beginning of the list\n\t */\n\tpublic insertNew(str: string): void {\n\t\tthis.insertAtStart(str);\n\t}\n}\n\n/**\n * This object is passed into the SharedTree via the schematize method.\n */\nconst treeConfiguration = new TreeViewConfiguration(\n\t// Specify the root type - StringArray.\n\t{ schema: StringArray },\n);\n\nconst testMatrix = getTestMatrix();\nfor (const testOpts of testMatrix) {\n\tdescribe(`SharedTree with AzureClient (${testOpts.variant})`, () => {\n\t\tconst connectTimeoutMs = 10_000;\n\t\tconst isEphemeral: boolean = testOpts.options.isEphemeral;\n\t\tlet client: AzureClient;\n\t\tconst schema = {\n\t\t\tinitialObjects: {\n\t\t\t\ttree1: SharedTree,\n\t\t\t},\n\t\t} satisfies ContainerSchema;\n\n\t\tbeforeEach(\"createAzureClient\", () => {\n\t\t\tclient = createAzureClient();\n\t\t});\n\n\t\tasync function waitForConnection(container: IFluidContainer): Promise<void> {\n\t\t\tif (container.connectionState !== ConnectionState.Connected) {\n\t\t\t\tawait timeoutPromise((resolve) => container.once(\"connected\", () => resolve()), {\n\t\t\t\t\tdurationMs: connectTimeoutMs,\n\t\t\t\t\terrorMsg: \"container1 connect() timeout\",\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Either creates a new azure client with a SharedTree, or loads an azure client from the existing summary tree (the \"ephemeral\" case).\n\t\t */\n\t\tasync function createOrLoad(\n\t\t\tsummaryTree?: (typeof ephemeralSummaryTrees)[keyof typeof ephemeralSummaryTrees],\n\t\t): Promise<{ containerId: string; treeData: TreeView<typeof StringArray> }> {\n\t\t\tlet containerId: string;\n\t\t\tlet treeData: TreeView<typeof StringArray>;\n\n\t\t\tif (summaryTree === undefined) {\n\t\t\t\tconst { container } = await client.createContainer(schema, \"2\");\n\t\t\t\ttreeData = container.initialObjects.tree1.viewWith(treeConfiguration);\n\t\t\t\ttreeData.initialize(new StringArray([]));\n\t\t\t\tcontainerId = await container.attach();\n\t\t\t\tawait waitForConnection(container);\n\t\t\t} else {\n\t\t\t\tconst containerResponse = await createContainerFromPayload(\n\t\t\t\t\tsummaryTree,\n\t\t\t\t\t\"test-user-id-1\",\n\t\t\t\t\t\"test-user-name-1\",\n\t\t\t\t);\n\n\t\t\t\tcontainerId = getContainerIdFromPayloadResponse(containerResponse);\n\t\t\t\tconst { container } = await client.getContainer(containerId, schema, \"2\");\n\t\t\t\ttreeData = container.initialObjects.tree1.viewWith(treeConfiguration);\n\t\t\t\tawait waitForConnection(container);\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tcontainerId,\n\t\t\t\ttreeData,\n\t\t\t};\n\t\t}\n\n\t\tit(\"can create/load a container with SharedTree and do basic ops\", async () => {\n\t\t\tconst { treeData } = await createOrLoad(\n\t\t\t\tisEphemeral ? ephemeralSummaryTrees.createContainerWithSharedTree : undefined,\n\t\t\t);\n\n\t\t\ttreeData.root.insertNew(\"test string 1\");\n\t\t\tassert.strictEqual(treeData.root.length, 1);\n\t\t\tassert.strictEqual(treeData.root.at(0), \"test string 1\");\n\n\t\t\ttreeData.root.insertNew(\"test string 2\");\n\t\t\tassert.strictEqual(treeData.root.length, 2);\n\t\t\tassert.strictEqual(treeData.root.at(0), \"test string 2\");\n\t\t\tassert.strictEqual(treeData.root.at(1), \"test string 1\");\n\n\t\t\ttreeData.root.removeFirst();\n\t\t\tassert.strictEqual(treeData.root.length, 1);\n\t\t\tassert.strictEqual(treeData.root.at(0), \"test string 1\");\n\t\t});\n\n\t\tit(\"can create/load a container with SharedTree collaborate with basic ops\", async () => {\n\t\t\tconst { containerId, treeData } = await createOrLoad(\n\t\t\t\tisEphemeral ? ephemeralSummaryTrees.createLoadContainerWithSharedTree : undefined,\n\t\t\t);\n\n\t\t\ttreeData.root.insertNew(\"test string 1\");\n\n\t\t\tconst resources = client.getContainer(containerId, schema, \"2\");\n\t\t\tawait assert.doesNotReject(\n\t\t\t\tresources,\n\t\t\t\t() => true,\n\t\t\t\t\"container cannot be retrieved from Azure Fluid Relay\",\n\t\t\t);\n\t\t\tconst { container: container2 } = await resources;\n\t\t\tassert.deepStrictEqual(\n\t\t\t\tObject.keys(container2.initialObjects),\n\t\t\t\tObject.keys(schema.initialObjects),\n\t\t\t);\n\n\t\t\tif (container2.connectionState !== ConnectionState.Connected) {\n\t\t\t\tawait timeoutPromise((resolve) => container2.once(\"connected\", () => resolve()), {\n\t\t\t\t\tdurationMs: connectTimeoutMs,\n\t\t\t\t\terrorMsg: \"container2 connect() timeout\",\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst treeData2 = container2.initialObjects.tree1.viewWith(treeConfiguration);\n\t\t\tassert.strictEqual(treeData2.root.length, 1);\n\t\t\tassert.strictEqual(treeData2.root.at(0), \"test string 1\");\n\t\t});\n\n\t\tif (!isEphemeral) {\n\t\t\t{\n\t\t\t\tclass Nicknames extends sf.array(\"Nicknames\", sf.string) {}\n\t\t\t\tclass UserData extends sf.map(\"UserData\", [sf.string, sf.number, sf.boolean]) {}\n\t\t\t\tclass User extends sf.object(\"User\", {\n\t\t\t\t\tname: sf.string,\n\t\t\t\t\tnicknames: Nicknames,\n\t\t\t\t\tdata: UserData,\n\t\t\t\t}) {}\n\n\t\t\t\tit(\"can read and edit data\", async () => {\n\t\t\t\t\tconst { container } = await client.createContainer(schema, \"2\");\n\t\t\t\t\tawait container.attach();\n\t\t\t\t\tconst view = container.initialObjects.tree1.viewWith(\n\t\t\t\t\t\tnew TreeViewConfiguration({ schema: User, enableSchemaValidation: true }),\n\t\t\t\t\t);\n\n\t\t\t\t\tconst tags: [string, string | number | boolean][] = [\n\t\t\t\t\t\t[\"Age\", 32],\n\t\t\t\t\t\t[\"Favorite Snack\", \"Potato Chips\"],\n\t\t\t\t\t\t[\"Awake\", true],\n\t\t\t\t\t];\n\n\t\t\t\t\tview.initialize(\n\t\t\t\t\t\tnew User({\n\t\t\t\t\t\t\tname: \"Pardes\",\n\t\t\t\t\t\t\tnicknames: [\"Alex\", \"Duder\"],\n\t\t\t\t\t\t\tdata: new Map(tags),\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\n\t\t\t\t\tconst user = view.root;\n\t\t\t\t\t// Read data\n\t\t\t\t\tassert.equal(user.name, \"Pardes\");\n\t\t\t\t\tassert.deepEqual([...user.nicknames], [\"Alex\", \"Duder\"]);\n\t\t\t\t\tassert.equal(user.data.get(\"Age\"), 32);\n\t\t\t\t\tassert.equal(user.data.get(\"Favorite Snack\"), \"Potato Chips\");\n\t\t\t\t\tassert.equal(user.data.get(\"Awake\"), true);\n\t\t\t\t\t// Mutate data\n\t\t\t\t\tuser.name = \"Pardesio\";\n\t\t\t\t\tuser.nicknames.insertAt(1, \"Alexp\");\n\t\t\t\t\tuser.data.set(\"Awake\", false);\n\t\t\t\t\tuser.data.set(\"Favorite Sport\", \"Ultimate Frisbee\");\n\t\t\t\t\t// Read mutated data\n\t\t\t\t\tassert.equal(user.name, \"Pardesio\");\n\t\t\t\t\tassert.deepEqual([...user.nicknames], [\"Alex\", \"Alexp\", \"Duder\"]);\n\t\t\t\t\tassert.equal(user.data.get(\"Age\"), 32);\n\t\t\t\t\tassert.equal(user.data.get(\"Awake\"), false);\n\t\t\t\t\tassert.equal(user.data.get(\"Favorite Sport\"), \"Ultimate Frisbee\");\n\t\t\t\t});\n\n\t\t\t\tit(\"can handle undo/redo and transactions\", async () => {\n\t\t\t\t\tconst { container } = await client.createContainer(schema, \"2\");\n\t\t\t\t\tawait container.attach();\n\t\t\t\t\tconst view = asAlpha(\n\t\t\t\t\t\tcontainer.initialObjects.tree1.viewWith(\n\t\t\t\t\t\t\tnew TreeViewConfiguration({ schema: User, enableSchemaValidation: true }),\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\n\t\t\t\t\tview.initialize(\n\t\t\t\t\t\tnew User({\n\t\t\t\t\t\t\tname: \"Shrek\",\n\t\t\t\t\t\t\tnicknames: [\"Ogre\"],\n\t\t\t\t\t\t\tdata: new Map([[\"Color\", \"a5bf2e\"]]),\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\n\t\t\t\t\tconst user = view.root;\n\t\t\t\t\t// Capture the Revertible so that changes can be undone\n\t\t\t\t\tlet revertible: Revertible | undefined;\n\t\t\t\t\tview.events.on(\"changed\", (_, getRevertible) => {\n\t\t\t\t\t\tassert(getRevertible !== undefined);\n\t\t\t\t\t\trevertible = getRevertible();\n\t\t\t\t\t});\n\t\t\t\t\t// Change a field, then revert the change\n\t\t\t\t\tuser.name = \"Donkey\";\n\t\t\t\t\tassert.equal(user.name, \"Donkey\");\n\t\t\t\t\tassert(revertible !== undefined);\n\t\t\t\t\trevertible.revert();\n\t\t\t\t\tassert.equal(user.name, \"Shrek\");\n\t\t\t\t\t// Run a transaction which changes multiple fields, then revert it\n\t\t\t\t\tTree.runTransaction(user, (u) => {\n\t\t\t\t\t\tu.name = \"Donkey\";\n\t\t\t\t\t\tu.nicknames.removeRange();\n\t\t\t\t\t\tu.data.set(\"Color\", \"8e8170\");\n\t\t\t\t\t});\n\n\t\t\t\t\tassert.equal(user.name, \"Donkey\");\n\t\t\t\t\tassert.equal(user.nicknames.length, 0);\n\t\t\t\t\tassert.equal(user.data.get(\"Color\"), \"8e8170\");\n\t\t\t\t\trevertible.revert();\n\t\t\t\t\tassert.equal(user.name, \"Shrek\");\n\t\t\t\t\tassert.equal(user.nicknames[0], \"Ogre\");\n\t\t\t\t\tassert.equal(user.data.get(\"Color\"), \"a5bf2e\");\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tit(\"can use identifiers and the static Tree APIs\", async () => {\n\t\t\t\tclass Widget extends sf.object(\"Widget\", { id: sf.identifier }) {}\n\n\t\t\t\tconst { container } = await client.createContainer(schema, \"2\");\n\t\t\t\tawait container.attach();\n\t\t\t\tconst view = container.initialObjects.tree1.viewWith(\n\t\t\t\t\tnew TreeViewConfiguration({\n\t\t\t\t\t\tschema: sf.array(Widget),\n\t\t\t\t\t\tenableSchemaValidation: true,\n\t\t\t\t\t}),\n\t\t\t\t);\n\n\t\t\t\tview.initialize([new Widget({}), new Widget({ id: \"fidget\" })]);\n\n\t\t\t\tconst widget = view.root.at(0);\n\t\t\t\tassert(widget !== undefined);\n\t\t\t\tconst fidget = view.root.at(-1);\n\t\t\t\tassert(fidget !== undefined);\n\t\t\t\t// Test various Tree.* APIs and ensure they are working\n\t\t\t\tassert.equal(Tree.contains(view.root, widget), true);\n\t\t\t\tassert.equal(Tree.contains(fidget, widget), false);\n\t\t\t\tassert.equal(Tree.is(fidget, Widget), true);\n\t\t\t\tassert.equal(Tree.is(view.root, Widget), false);\n\t\t\t\tassert.equal(Tree.key(widget), 0);\n\t\t\t\tassert.equal(Tree.key(fidget), 1);\n\t\t\t\tassert.equal(Tree.parent(widget), view.root);\n\t\t\t\tassert.equal(Tree.schema(fidget), Widget);\n\t\t\t\tassert.equal(typeof Tree.shortId(widget), \"number\");\n\t\t\t\tassert.equal(Tree.shortId(fidget), \"fidget\");\n\t\t\t\tassert.equal(Tree.status(widget), TreeStatus.InDocument);\n\t\t\t});\n\n\t\t\tit(\"can listen to events on a recursive tree\", async () => {\n\t\t\t\tclass Doll extends sf.objectRecursive(\"Matryoshka\", {\n\t\t\t\t\tnested: sf.optionalRecursive([() => Doll]),\n\t\t\t\t}) {}\n\t\t\t\tallowUnused<ValidateRecursiveSchema<typeof Doll>>();\n\n\t\t\t\tconst { container } = await client.createContainer(schema, \"2\");\n\t\t\t\tawait container.attach();\n\t\t\t\tconst view = container.initialObjects.tree1.viewWith(\n\t\t\t\t\tnew TreeViewConfiguration({ schema: Doll, enableSchemaValidation: true }),\n\t\t\t\t);\n\n\t\t\t\t// These nodes in the initial tree are unhydrated...\n\t\t\t\tconst depth1 = new Doll({ nested: new Doll({}) });\n\t\t\t\tconst depth0 = new Doll({ nested: depth1 });\n\t\t\t\tview.initialize(depth0);\n\t\t\t\t// ...and confirmed to be the same nodes we get when we read the tree after initialization\n\t\t\t\tassert.equal(view.root, depth0);\n\t\t\t\tassert.equal(view.root.nested, depth1);\n\t\t\t\t// Record a list of the node events fired\n\t\t\t\tconst eventLog: string[] = [];\n\t\t\t\tTree.on(depth0, \"nodeChanged\", () => {\n\t\t\t\t\teventLog.push(\"depth0.nested changed\");\n\t\t\t\t});\n\t\t\t\tTree.on(depth1, \"nodeChanged\", () => {\n\t\t\t\t\teventLog.push(\"depth1.nested changed\");\n\t\t\t\t});\n\t\t\t\t// This event registration happens on the unhydrated (not yet inserted) node\n\t\t\t\tconst newDepth2 = new Doll({});\n\t\t\t\tTree.on(newDepth2, \"nodeChanged\", () => {\n\t\t\t\t\teventLog.push(\"depth2.nested changed\");\n\t\t\t\t});\n\t\t\t\t// Fire the events by doing mutations\n\t\t\t\tdepth1.nested = newDepth2; // \"depth1.nested changed\"\n\t\t\t\tassert.equal(depth1.nested, newDepth2);\n\t\t\t\tdepth1.nested.nested = new Doll({}); // \"depth2.nested changed\"\n\t\t\t\tdepth0.nested = new Doll({}); // \"depth0.nested changed\"\n\t\t\t\t// Ensure the events fired in the expected order\n\t\t\t\tassert.deepEqual(eventLog, [\n\t\t\t\t\t\"depth1.nested changed\",\n\t\t\t\t\t\"depth2.nested changed\",\n\t\t\t\t\t\"depth0.nested changed\",\n\t\t\t\t]);\n\t\t\t});\n\t\t}\n\t});\n}\n"]}
|
|
1
|
+
{"version":3,"file":"tree.spec.js","sourceRoot":"","sources":["../../src/test/tree.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 \"node:assert\";\n\nimport type { AzureClient } from \"@fluidframework/azure-client\";\nimport { ConnectionState } from \"@fluidframework/container-loader\";\nimport type { ContainerSchema, IFluidContainer } from \"@fluidframework/fluid-static\";\nimport { timeoutPromise } from \"@fluidframework/test-utils/internal\";\nimport type { Revertible, TreeView, ValidateRecursiveSchema } from \"@fluidframework/tree\";\nimport { SchemaFactory, Tree, TreeStatus, TreeViewConfiguration } from \"@fluidframework/tree\";\nimport { allowUnused, asAlpha } from \"@fluidframework/tree/alpha\";\nimport { SharedTree } from \"@fluidframework/tree/legacy\";\n\nimport {\n\tcreateAzureClient,\n\tcreateContainerFromPayload,\n\tgetContainerIdFromPayloadResponse,\n} from \"./AzureClientFactory.js\";\nimport * as ephemeralSummaryTrees from \"./ephemeralSummaryTrees.js\";\nimport { getTestMatrix, currentVersion } from \"./utils.js\";\n\nconst sf = new SchemaFactory(\"d302b84c-75f6-4ecd-9663-524f467013e3\");\n\n/**\n * Define a class that is an array of strings\n * This class is used to create an array in the SharedTree\n */\nclass StringArray extends sf.array(\"StringArray\", sf.string) {\n\t/**\n\t * Remove the first item in the list if the list is not empty\n\t */\n\tpublic removeFirst(): void {\n\t\tif (this.length > 0) this.removeAt(0);\n\t}\n\n\t/**\n\t * Add an item to the beginning of the list\n\t */\n\tpublic insertNew(str: string): void {\n\t\tthis.insertAtStart(str);\n\t}\n}\n\n/**\n * This object is passed into the SharedTree via the schematize method.\n */\nconst treeConfiguration = new TreeViewConfiguration(\n\t// Specify the root type - StringArray.\n\t{ schema: StringArray },\n);\n\nconst testMatrix = getTestMatrix();\nfor (const testOpts of testMatrix) {\n\tdescribe(`SharedTree with AzureClient (${testOpts.variant})`, () => {\n\t\tconst connectTimeoutMs = 10_000;\n\t\tconst isEphemeral: boolean = testOpts.options.isEphemeral;\n\t\tlet client: AzureClient;\n\t\tconst schema = {\n\t\t\tinitialObjects: {\n\t\t\t\ttree1: SharedTree,\n\t\t\t},\n\t\t} satisfies ContainerSchema;\n\n\t\tbeforeEach(\"createAzureClient\", () => {\n\t\t\tclient = createAzureClient();\n\t\t});\n\n\t\tasync function waitForConnection(container: IFluidContainer): Promise<void> {\n\t\t\tif (container.connectionState !== ConnectionState.Connected) {\n\t\t\t\tawait timeoutPromise((resolve) => container.once(\"connected\", () => resolve()), {\n\t\t\t\t\tdurationMs: connectTimeoutMs,\n\t\t\t\t\terrorMsg: \"container1 connect() timeout\",\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Either creates a new azure client with a SharedTree, or loads an azure client from the existing summary tree (the \"ephemeral\" case).\n\t\t */\n\t\tasync function createOrLoad(\n\t\t\tsummaryTree?: (typeof ephemeralSummaryTrees)[keyof typeof ephemeralSummaryTrees],\n\t\t): Promise<{ containerId: string; treeData: TreeView<typeof StringArray> }> {\n\t\t\tlet containerId: string;\n\t\t\tlet treeData: TreeView<typeof StringArray>;\n\n\t\t\tif (summaryTree === undefined) {\n\t\t\t\tconst { container } = await client.createContainer(schema, currentVersion);\n\t\t\t\ttreeData = container.initialObjects.tree1.viewWith(treeConfiguration);\n\t\t\t\ttreeData.initialize(new StringArray([]));\n\t\t\t\tcontainerId = await container.attach();\n\t\t\t\tawait waitForConnection(container);\n\t\t\t} else {\n\t\t\t\tconst containerResponse = await createContainerFromPayload(\n\t\t\t\t\tsummaryTree,\n\t\t\t\t\t\"test-user-id-1\",\n\t\t\t\t\t\"test-user-name-1\",\n\t\t\t\t);\n\n\t\t\t\tcontainerId = getContainerIdFromPayloadResponse(containerResponse);\n\t\t\t\tconst { container } = await client.getContainer(containerId, schema, currentVersion);\n\t\t\t\ttreeData = container.initialObjects.tree1.viewWith(treeConfiguration);\n\t\t\t\tawait waitForConnection(container);\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tcontainerId,\n\t\t\t\ttreeData,\n\t\t\t};\n\t\t}\n\n\t\tit(\"can create/load a container with SharedTree and do basic ops\", async () => {\n\t\t\tconst { treeData } = await createOrLoad(\n\t\t\t\tisEphemeral ? ephemeralSummaryTrees.createContainerWithSharedTree : undefined,\n\t\t\t);\n\n\t\t\ttreeData.root.insertNew(\"test string 1\");\n\t\t\tassert.strictEqual(treeData.root.length, 1);\n\t\t\tassert.strictEqual(treeData.root.at(0), \"test string 1\");\n\n\t\t\ttreeData.root.insertNew(\"test string 2\");\n\t\t\tassert.strictEqual(treeData.root.length, 2);\n\t\t\tassert.strictEqual(treeData.root.at(0), \"test string 2\");\n\t\t\tassert.strictEqual(treeData.root.at(1), \"test string 1\");\n\n\t\t\ttreeData.root.removeFirst();\n\t\t\tassert.strictEqual(treeData.root.length, 1);\n\t\t\tassert.strictEqual(treeData.root.at(0), \"test string 1\");\n\t\t});\n\n\t\tit(\"can create/load a container with SharedTree collaborate with basic ops\", async () => {\n\t\t\tconst { containerId, treeData } = await createOrLoad(\n\t\t\t\tisEphemeral ? ephemeralSummaryTrees.createLoadContainerWithSharedTree : undefined,\n\t\t\t);\n\n\t\t\ttreeData.root.insertNew(\"test string 1\");\n\n\t\t\tconst resources = client.getContainer(containerId, schema, currentVersion);\n\t\t\tawait assert.doesNotReject(\n\t\t\t\tresources,\n\t\t\t\t() => true,\n\t\t\t\t\"container cannot be retrieved from Azure Fluid Relay\",\n\t\t\t);\n\t\t\tconst { container: container2 } = await resources;\n\t\t\tassert.deepStrictEqual(\n\t\t\t\tObject.keys(container2.initialObjects),\n\t\t\t\tObject.keys(schema.initialObjects),\n\t\t\t);\n\n\t\t\tif (container2.connectionState !== ConnectionState.Connected) {\n\t\t\t\tawait timeoutPromise((resolve) => container2.once(\"connected\", () => resolve()), {\n\t\t\t\t\tdurationMs: connectTimeoutMs,\n\t\t\t\t\terrorMsg: \"container2 connect() timeout\",\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst treeData2 = container2.initialObjects.tree1.viewWith(treeConfiguration);\n\t\t\tassert.strictEqual(treeData2.root.length, 1);\n\t\t\tassert.strictEqual(treeData2.root.at(0), \"test string 1\");\n\t\t});\n\n\t\tif (!isEphemeral) {\n\t\t\t{\n\t\t\t\tclass Nicknames extends sf.array(\"Nicknames\", sf.string) {}\n\t\t\t\tclass UserData extends sf.map(\"UserData\", [sf.string, sf.number, sf.boolean]) {}\n\t\t\t\tclass User extends sf.object(\"User\", {\n\t\t\t\t\tname: sf.string,\n\t\t\t\t\tnicknames: Nicknames,\n\t\t\t\t\tdata: UserData,\n\t\t\t\t}) {}\n\n\t\t\t\tit(\"can read and edit data\", async () => {\n\t\t\t\t\tconst { container } = await client.createContainer(schema, currentVersion);\n\t\t\t\t\tawait container.attach();\n\t\t\t\t\tconst view = container.initialObjects.tree1.viewWith(\n\t\t\t\t\t\tnew TreeViewConfiguration({ schema: User, enableSchemaValidation: true }),\n\t\t\t\t\t);\n\n\t\t\t\t\tconst tags: [string, string | number | boolean][] = [\n\t\t\t\t\t\t[\"Age\", 32],\n\t\t\t\t\t\t[\"Favorite Snack\", \"Potato Chips\"],\n\t\t\t\t\t\t[\"Awake\", true],\n\t\t\t\t\t];\n\n\t\t\t\t\tview.initialize(\n\t\t\t\t\t\tnew User({\n\t\t\t\t\t\t\tname: \"Pardes\",\n\t\t\t\t\t\t\tnicknames: [\"Alex\", \"Duder\"],\n\t\t\t\t\t\t\tdata: new Map(tags),\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\n\t\t\t\t\tconst user = view.root;\n\t\t\t\t\t// Read data\n\t\t\t\t\tassert.equal(user.name, \"Pardes\");\n\t\t\t\t\tassert.deepEqual([...user.nicknames], [\"Alex\", \"Duder\"]);\n\t\t\t\t\tassert.equal(user.data.get(\"Age\"), 32);\n\t\t\t\t\tassert.equal(user.data.get(\"Favorite Snack\"), \"Potato Chips\");\n\t\t\t\t\tassert.equal(user.data.get(\"Awake\"), true);\n\t\t\t\t\t// Mutate data\n\t\t\t\t\tuser.name = \"Pardesio\";\n\t\t\t\t\tuser.nicknames.insertAt(1, \"Alexp\");\n\t\t\t\t\tuser.data.set(\"Awake\", false);\n\t\t\t\t\tuser.data.set(\"Favorite Sport\", \"Ultimate Frisbee\");\n\t\t\t\t\t// Read mutated data\n\t\t\t\t\tassert.equal(user.name, \"Pardesio\");\n\t\t\t\t\tassert.deepEqual([...user.nicknames], [\"Alex\", \"Alexp\", \"Duder\"]);\n\t\t\t\t\tassert.equal(user.data.get(\"Age\"), 32);\n\t\t\t\t\tassert.equal(user.data.get(\"Awake\"), false);\n\t\t\t\t\tassert.equal(user.data.get(\"Favorite Sport\"), \"Ultimate Frisbee\");\n\t\t\t\t});\n\n\t\t\t\tit(\"can handle undo/redo and transactions\", async () => {\n\t\t\t\t\tconst { container } = await client.createContainer(schema, currentVersion);\n\t\t\t\t\tawait container.attach();\n\t\t\t\t\tconst view = asAlpha(\n\t\t\t\t\t\tcontainer.initialObjects.tree1.viewWith(\n\t\t\t\t\t\t\tnew TreeViewConfiguration({ schema: User, enableSchemaValidation: true }),\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\n\t\t\t\t\tview.initialize(\n\t\t\t\t\t\tnew User({\n\t\t\t\t\t\t\tname: \"Shrek\",\n\t\t\t\t\t\t\tnicknames: [\"Ogre\"],\n\t\t\t\t\t\t\tdata: new Map([[\"Color\", \"a5bf2e\"]]),\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\n\t\t\t\t\tconst user = view.root;\n\t\t\t\t\t// Capture the Revertible so that changes can be undone\n\t\t\t\t\tlet revertible: Revertible | undefined;\n\t\t\t\t\tview.events.on(\"changed\", (_, getRevertible) => {\n\t\t\t\t\t\tassert(getRevertible !== undefined);\n\t\t\t\t\t\trevertible = getRevertible();\n\t\t\t\t\t});\n\t\t\t\t\t// Change a field, then revert the change\n\t\t\t\t\tuser.name = \"Donkey\";\n\t\t\t\t\tassert.equal(user.name, \"Donkey\");\n\t\t\t\t\tassert(revertible !== undefined);\n\t\t\t\t\trevertible.revert();\n\t\t\t\t\tassert.equal(user.name, \"Shrek\");\n\t\t\t\t\t// Run a transaction which changes multiple fields, then revert it\n\t\t\t\t\tTree.runTransaction(user, (u) => {\n\t\t\t\t\t\tu.name = \"Donkey\";\n\t\t\t\t\t\tu.nicknames.removeRange();\n\t\t\t\t\t\tu.data.set(\"Color\", \"8e8170\");\n\t\t\t\t\t});\n\n\t\t\t\t\tassert.equal(user.name, \"Donkey\");\n\t\t\t\t\tassert.equal(user.nicknames.length, 0);\n\t\t\t\t\tassert.equal(user.data.get(\"Color\"), \"8e8170\");\n\t\t\t\t\trevertible.revert();\n\t\t\t\t\tassert.equal(user.name, \"Shrek\");\n\t\t\t\t\tassert.equal(user.nicknames[0], \"Ogre\");\n\t\t\t\t\tassert.equal(user.data.get(\"Color\"), \"a5bf2e\");\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tit(\"can use identifiers and the static Tree APIs\", async () => {\n\t\t\t\tclass Widget extends sf.object(\"Widget\", { id: sf.identifier }) {}\n\n\t\t\t\tconst { container } = await client.createContainer(schema, currentVersion);\n\t\t\t\tawait container.attach();\n\t\t\t\tconst view = container.initialObjects.tree1.viewWith(\n\t\t\t\t\tnew TreeViewConfiguration({\n\t\t\t\t\t\tschema: sf.array(Widget),\n\t\t\t\t\t\tenableSchemaValidation: true,\n\t\t\t\t\t}),\n\t\t\t\t);\n\n\t\t\t\tview.initialize([new Widget({}), new Widget({ id: \"fidget\" })]);\n\n\t\t\t\tconst widget = view.root.at(0);\n\t\t\t\tassert(widget !== undefined);\n\t\t\t\tconst fidget = view.root.at(-1);\n\t\t\t\tassert(fidget !== undefined);\n\t\t\t\t// Test various Tree.* APIs and ensure they are working\n\t\t\t\tassert.equal(Tree.contains(view.root, widget), true);\n\t\t\t\tassert.equal(Tree.contains(fidget, widget), false);\n\t\t\t\tassert.equal(Tree.is(fidget, Widget), true);\n\t\t\t\tassert.equal(Tree.is(view.root, Widget), false);\n\t\t\t\tassert.equal(Tree.key(widget), 0);\n\t\t\t\tassert.equal(Tree.key(fidget), 1);\n\t\t\t\tassert.equal(Tree.parent(widget), view.root);\n\t\t\t\tassert.equal(Tree.schema(fidget), Widget);\n\t\t\t\tassert.equal(typeof Tree.shortId(widget), \"number\");\n\t\t\t\tassert.equal(Tree.shortId(fidget), \"fidget\");\n\t\t\t\tassert.equal(Tree.status(widget), TreeStatus.InDocument);\n\t\t\t});\n\n\t\t\tit(\"can listen to events on a recursive tree\", async () => {\n\t\t\t\tclass Doll extends sf.objectRecursive(\"Matryoshka\", {\n\t\t\t\t\tnested: sf.optionalRecursive([() => Doll]),\n\t\t\t\t}) {}\n\t\t\t\tallowUnused<ValidateRecursiveSchema<typeof Doll>>();\n\n\t\t\t\tconst { container } = await client.createContainer(schema, currentVersion);\n\t\t\t\tawait container.attach();\n\t\t\t\tconst view = container.initialObjects.tree1.viewWith(\n\t\t\t\t\tnew TreeViewConfiguration({ schema: Doll, enableSchemaValidation: true }),\n\t\t\t\t);\n\n\t\t\t\t// These nodes in the initial tree are unhydrated...\n\t\t\t\tconst depth1 = new Doll({ nested: new Doll({}) });\n\t\t\t\tconst depth0 = new Doll({ nested: depth1 });\n\t\t\t\tview.initialize(depth0);\n\t\t\t\t// ...and confirmed to be the same nodes we get when we read the tree after initialization\n\t\t\t\tassert.equal(view.root, depth0);\n\t\t\t\tassert.equal(view.root.nested, depth1);\n\t\t\t\t// Record a list of the node events fired\n\t\t\t\tconst eventLog: string[] = [];\n\t\t\t\tTree.on(depth0, \"nodeChanged\", () => {\n\t\t\t\t\teventLog.push(\"depth0.nested changed\");\n\t\t\t\t});\n\t\t\t\tTree.on(depth1, \"nodeChanged\", () => {\n\t\t\t\t\teventLog.push(\"depth1.nested changed\");\n\t\t\t\t});\n\t\t\t\t// This event registration happens on the unhydrated (not yet inserted) node\n\t\t\t\tconst newDepth2 = new Doll({});\n\t\t\t\tTree.on(newDepth2, \"nodeChanged\", () => {\n\t\t\t\t\teventLog.push(\"depth2.nested changed\");\n\t\t\t\t});\n\t\t\t\t// Fire the events by doing mutations\n\t\t\t\tdepth1.nested = newDepth2; // \"depth1.nested changed\"\n\t\t\t\tassert.equal(depth1.nested, newDepth2);\n\t\t\t\tdepth1.nested.nested = new Doll({}); // \"depth2.nested changed\"\n\t\t\t\tdepth0.nested = new Doll({}); // \"depth0.nested changed\"\n\t\t\t\t// Ensure the events fired in the expected order\n\t\t\t\tassert.deepEqual(eventLog, [\n\t\t\t\t\t\"depth1.nested changed\",\n\t\t\t\t\t\"depth2.nested changed\",\n\t\t\t\t\t\"depth0.nested changed\",\n\t\t\t\t]);\n\t\t\t});\n\t\t}\n\t});\n}\n"]}
|
package/lib/test/utils.js
CHANGED
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
|
+
// `pkgVersion` is this package's own version, which tracks the Fluid Framework release group; we use it as
|
|
6
|
+
// `minVersionForCollab` in tests so they exercise the latest defaults rather than a hardcoded version.
|
|
7
|
+
export { pkgVersion as currentVersion } from "../packageVersion.js";
|
|
5
8
|
export const waitForMember = async (audience, id) => {
|
|
6
9
|
const allMembers = audience.getMembers();
|
|
7
10
|
const member = allMembers.get(id);
|
package/lib/test/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/test/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,EACjC,QAAwB,EACxB,EAAU,EACa,EAAE;IACzB,MAAM,UAAU,GAAG,QAAQ,CAAC,UAAU,EAAE,CAAC;IACzC,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAClC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO,MAAM,CAAC;IACf,CAAC;IACD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC9B,MAAM,OAAO,GAAG,CAAC,QAAgB,EAAE,SAAkB,EAAQ,EAAE;YAC9D,IAAI,SAAS,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;gBACzB,OAAO,CAAC,SAAwB,CAAC,CAAC;YACnC,CAAC;QACF,CAAC,CAAC;QACF,QAAQ,CAAC,EAAE,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,OAAO,GAAG,KAAK,EAAK,GAAe,EAAE,GAAW,EAAc,EAAE;IAC5E,MAAM,UAAU,GAAG,GAAG,CAAC,GAAG,CAAI,GAAG,CAAC,CAAC;IACnC,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,UAAU,CAAC;IACnB,CAAC;IAED,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC9B,MAAM,OAAO,GAAG,CAAC,OAAsB,EAAQ,EAAE;YAChD,IAAI,OAAO,CAAC,GAAG,KAAK,GAAG,EAAE,CAAC;gBACzB,GAAG,CAAC,GAAG,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;gBACjC,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAI,OAAO,CAAC,GAAG,CAAC,CAAC;gBACtC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;oBACzB,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;gBACnD,CAAC;gBACD,OAAO,CAAC,KAAK,CAAC,CAAC;YAChB,CAAC;QACF,CAAC,CAAC;QACF,GAAG,CAAC,EAAE,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG,CAC7B,QAAqC,EACf,EAAE,CAAC,CAAC;IAC1B,YAAY,EAAE,CAAC,IAAY,EAAe,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC;CAC3D,CAAC,CAAC;AAEH;;;;;;GAMG;AACH,MAAM,UAAU,aAAa;IAC5B,MAAM,UAAU,GAAG;QAClB;YACC,OAAO,EAAE,mBAAmB;YAC5B,OAAO,EAAE;gBACR,WAAW,EAAE,KAAK;aAClB;SACD;KACD,CAAC;IAEF,6FAA6F;IAC7F,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,KAAK,OAAO,CAAC;IACtD,IAAI,QAAQ,EAAE,CAAC;QACd,UAAU,CAAC,IAAI,CAAC;YACf,OAAO,EAAE,qBAAqB;YAC9B,OAAO,EAAE;gBACR,WAAW,EAAE,IAAI;aACjB;SACD,CAAC,CAAC;IACJ,CAAC;IAED,OAAO,UAAU,CAAC;AACnB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { AzureMember, IAzureAudience } from \"@fluidframework/azure-client\";\nimport type { ConfigTypes, IConfigProviderBase } from \"@fluidframework/core-interfaces\";\nimport type { IMember } from \"@fluidframework/fluid-static\";\nimport type { ISharedMap, IValueChanged } from \"@fluidframework/map/legacy\";\n\nexport const waitForMember = async (\n\taudience: IAzureAudience,\n\tid: string,\n): Promise<AzureMember> => {\n\tconst allMembers = audience.getMembers();\n\tconst member = allMembers.get(id);\n\tif (member !== undefined) {\n\t\treturn member;\n\t}\n\treturn new Promise((resolve) => {\n\t\tconst handler = (clientId: string, newMember: IMember): void => {\n\t\t\tif (newMember.id === id) {\n\t\t\t\tresolve(newMember as AzureMember);\n\t\t\t}\n\t\t};\n\t\taudience.on(\"memberAdded\", handler);\n\t});\n};\n\nexport const mapWait = async <T>(map: ISharedMap, key: string): Promise<T> => {\n\tconst maybeValue = map.get<T>(key);\n\tif (maybeValue !== undefined) {\n\t\treturn maybeValue;\n\t}\n\n\treturn new Promise((resolve) => {\n\t\tconst handler = (changed: IValueChanged): void => {\n\t\t\tif (changed.key === key) {\n\t\t\t\tmap.off(\"valueChanged\", handler);\n\t\t\t\tconst value = map.get<T>(changed.key);\n\t\t\t\tif (value === undefined) {\n\t\t\t\t\tthrow new Error(\"Unexpected valueChanged result\");\n\t\t\t\t}\n\t\t\t\tresolve(value);\n\t\t\t}\n\t\t};\n\t\tmap.on(\"valueChanged\", handler);\n\t});\n};\n\nexport const configProvider = (\n\tsettings: Record<string, ConfigTypes>,\n): IConfigProviderBase => ({\n\tgetRawConfig: (name: string): ConfigTypes => settings[name],\n});\n\n/**\n * This function creates a test matrix which allows the Azure Client to run the same tests against different sets of parameters.\n * Currently, there is only a test-set for Durable containers and one for Ephemeral containers.\n * The Ephemeral container tests will not run for local tests.\n *\n * @returns The test matrix\n */\nexport function getTestMatrix(): { variant: string; options: { isEphemeral: boolean } }[] {\n\tconst testMatrix = [\n\t\t{\n\t\t\tvariant: \"Durable Container\",\n\t\t\toptions: {\n\t\t\t\tisEphemeral: false,\n\t\t\t},\n\t\t},\n\t];\n\n\t// We only need to test ephemeral container behaviors when running against an azure container\n\tconst useAzure = process.env.FLUID_CLIENT === \"azure\";\n\tif (useAzure) {\n\t\ttestMatrix.push({\n\t\t\tvariant: \"Ephemeral Container\",\n\t\t\toptions: {\n\t\t\t\tisEphemeral: true,\n\t\t\t},\n\t\t});\n\t}\n\n\treturn testMatrix;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/test/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,2GAA2G;AAC3G,uGAAuG;AACvG,OAAO,EAAE,UAAU,IAAI,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEpE,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,EACjC,QAAwB,EACxB,EAAU,EACa,EAAE;IACzB,MAAM,UAAU,GAAG,QAAQ,CAAC,UAAU,EAAE,CAAC;IACzC,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAClC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO,MAAM,CAAC;IACf,CAAC;IACD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC9B,MAAM,OAAO,GAAG,CAAC,QAAgB,EAAE,SAAkB,EAAQ,EAAE;YAC9D,IAAI,SAAS,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;gBACzB,OAAO,CAAC,SAAwB,CAAC,CAAC;YACnC,CAAC;QACF,CAAC,CAAC;QACF,QAAQ,CAAC,EAAE,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,OAAO,GAAG,KAAK,EAAK,GAAe,EAAE,GAAW,EAAc,EAAE;IAC5E,MAAM,UAAU,GAAG,GAAG,CAAC,GAAG,CAAI,GAAG,CAAC,CAAC;IACnC,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,UAAU,CAAC;IACnB,CAAC;IAED,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC9B,MAAM,OAAO,GAAG,CAAC,OAAsB,EAAQ,EAAE;YAChD,IAAI,OAAO,CAAC,GAAG,KAAK,GAAG,EAAE,CAAC;gBACzB,GAAG,CAAC,GAAG,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;gBACjC,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAI,OAAO,CAAC,GAAG,CAAC,CAAC;gBACtC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;oBACzB,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;gBACnD,CAAC;gBACD,OAAO,CAAC,KAAK,CAAC,CAAC;YAChB,CAAC;QACF,CAAC,CAAC;QACF,GAAG,CAAC,EAAE,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG,CAC7B,QAAqC,EACf,EAAE,CAAC,CAAC;IAC1B,YAAY,EAAE,CAAC,IAAY,EAAe,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC;CAC3D,CAAC,CAAC;AAEH;;;;;;GAMG;AACH,MAAM,UAAU,aAAa;IAC5B,MAAM,UAAU,GAAG;QAClB;YACC,OAAO,EAAE,mBAAmB;YAC5B,OAAO,EAAE;gBACR,WAAW,EAAE,KAAK;aAClB;SACD;KACD,CAAC;IAEF,6FAA6F;IAC7F,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,KAAK,OAAO,CAAC;IACtD,IAAI,QAAQ,EAAE,CAAC;QACd,UAAU,CAAC,IAAI,CAAC;YACf,OAAO,EAAE,qBAAqB;YAC9B,OAAO,EAAE;gBACR,WAAW,EAAE,IAAI;aACjB;SACD,CAAC,CAAC;IACJ,CAAC;IAED,OAAO,UAAU,CAAC;AACnB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { AzureMember, IAzureAudience } from \"@fluidframework/azure-client\";\nimport type { ConfigTypes, IConfigProviderBase } from \"@fluidframework/core-interfaces\";\nimport type { IMember } from \"@fluidframework/fluid-static\";\nimport type { ISharedMap, IValueChanged } from \"@fluidframework/map/legacy\";\n\n// `pkgVersion` is this package's own version, which tracks the Fluid Framework release group; we use it as\n// `minVersionForCollab` in tests so they exercise the latest defaults rather than a hardcoded version.\nexport { pkgVersion as currentVersion } from \"../packageVersion.js\";\n\nexport const waitForMember = async (\n\taudience: IAzureAudience,\n\tid: string,\n): Promise<AzureMember> => {\n\tconst allMembers = audience.getMembers();\n\tconst member = allMembers.get(id);\n\tif (member !== undefined) {\n\t\treturn member;\n\t}\n\treturn new Promise((resolve) => {\n\t\tconst handler = (clientId: string, newMember: IMember): void => {\n\t\t\tif (newMember.id === id) {\n\t\t\t\tresolve(newMember as AzureMember);\n\t\t\t}\n\t\t};\n\t\taudience.on(\"memberAdded\", handler);\n\t});\n};\n\nexport const mapWait = async <T>(map: ISharedMap, key: string): Promise<T> => {\n\tconst maybeValue = map.get<T>(key);\n\tif (maybeValue !== undefined) {\n\t\treturn maybeValue;\n\t}\n\n\treturn new Promise((resolve) => {\n\t\tconst handler = (changed: IValueChanged): void => {\n\t\t\tif (changed.key === key) {\n\t\t\t\tmap.off(\"valueChanged\", handler);\n\t\t\t\tconst value = map.get<T>(changed.key);\n\t\t\t\tif (value === undefined) {\n\t\t\t\t\tthrow new Error(\"Unexpected valueChanged result\");\n\t\t\t\t}\n\t\t\t\tresolve(value);\n\t\t\t}\n\t\t};\n\t\tmap.on(\"valueChanged\", handler);\n\t});\n};\n\nexport const configProvider = (\n\tsettings: Record<string, ConfigTypes>,\n): IConfigProviderBase => ({\n\tgetRawConfig: (name: string): ConfigTypes => settings[name],\n});\n\n/**\n * This function creates a test matrix which allows the Azure Client to run the same tests against different sets of parameters.\n * Currently, there is only a test-set for Durable containers and one for Ephemeral containers.\n * The Ephemeral container tests will not run for local tests.\n *\n * @returns The test matrix\n */\nexport function getTestMatrix(): { variant: string; options: { isEphemeral: boolean } }[] {\n\tconst testMatrix = [\n\t\t{\n\t\t\tvariant: \"Durable Container\",\n\t\t\toptions: {\n\t\t\t\tisEphemeral: false,\n\t\t\t},\n\t\t},\n\t];\n\n\t// We only need to test ephemeral container behaviors when running against an azure container\n\tconst useAzure = process.env.FLUID_CLIENT === \"azure\";\n\tif (useAzure) {\n\t\ttestMatrix.push({\n\t\t\tvariant: \"Ephemeral Container\",\n\t\t\toptions: {\n\t\t\t\tisEphemeral: true,\n\t\t\t},\n\t\t});\n\t}\n\n\treturn testMatrix;\n}\n"]}
|