forked from microsoft/FluidFramework
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtestObjectProvider.ts
More file actions
222 lines (193 loc) · 8.97 KB
/
Copy pathtestObjectProvider.ts
File metadata and controls
222 lines (193 loc) · 8.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
/*!
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
import { IContainer, IHostLoader, ILoaderOptions } from "@fluidframework/container-definitions";
import { Container, Loader, waitContainerToCatchUp } from "@fluidframework/container-loader";
import { IContainerRuntimeOptions } from "@fluidframework/container-runtime";
import { IFluidCodeDetails, IRequestHeader } from "@fluidframework/core-interfaces";
import { IDocumentServiceFactory, IUrlResolver } from "@fluidframework/driver-definitions";
import { ITestDriver } from "@fluidframework/test-driver-definitions";
import { v4 as uuid } from "uuid";
import { ChildLogger } from "@fluidframework/telemetry-utils";
import { LoaderContainerTracker } from "./loaderContainerTracker";
import { fluidEntryPoint, LocalCodeLoader } from "./localCodeLoader";
import { createAndAttachContainer } from "./localLoader";
import { ChannelFactoryRegistry } from "./testFluidObject";
const defaultCodeDetails: IFluidCodeDetails = {
package: "defaultTestPackage",
config: {},
};
export interface IOpProcessingController {
processIncoming(...containers: IContainer[]): Promise<void>;
processOutgoing(...containers: IContainer[]): Promise<void>;
pauseProcessing(...containers: IContainer[]): Promise<void>;
resumeProcessing(...containers: IContainer[]): void;
}
export interface ITestObjectProvider {
createLoader(packageEntries: Iterable<[IFluidCodeDetails, fluidEntryPoint]>, options?: ILoaderOptions): IHostLoader;
createContainer(entryPoint: fluidEntryPoint, options?: ILoaderOptions): Promise<IContainer>;
loadContainer(
entryPoint: fluidEntryPoint,
options?: ILoaderOptions,
requestHeader?: IRequestHeader,
): Promise<IContainer>;
/**
* Used to create a test Container. The Loader/ContainerRuntime/DataRuntime might be different versioned.
* In generateLocalCompatTest(), this Container and its runtime will be arbitrarily-versioned.
*/
makeTestLoader(testContainerConfig?: ITestContainerConfig): IHostLoader,
makeTestContainer(testContainerConfig?: ITestContainerConfig): Promise<IContainer>,
loadTestContainer(testContainerConfig?: ITestContainerConfig): Promise<IContainer>,
documentServiceFactory: IDocumentServiceFactory,
urlResolver: IUrlResolver,
defaultCodeDetails: IFluidCodeDetails,
opProcessingController: IOpProcessingController,
ensureSynchronized(): Promise<void>;
reset(): void,
documentId: string,
driver: ITestDriver;
}
export enum DataObjectFactoryType {
Primed, // default
Test,
}
export interface ITestContainerConfig {
// TestFluidDataObject instead of PrimedDataStore
fluidDataObjectType?: DataObjectFactoryType,
// And array of channel name and DDS factory pair to create on container creation time
registry?: ChannelFactoryRegistry,
// Container runtime options for the container instance
runtimeOptions?: IContainerRuntimeOptions,
}
export const createDocumentId = (): string => uuid();
/**
* Shared base class for test object provider. Contain code for loader and container creation and loading
*/
export class TestObjectProvider {
private readonly _loaderContainerTracker = new LoaderContainerTracker();
private _documentServiceFactory: IDocumentServiceFactory | undefined;
private _urlResolver: IUrlResolver | undefined;
private _documentId?: string;
/**
* Manage objects for loading and creating container, including the driver, loader, and OpProcessingController
* @param createFluidEntryPoint - callback to create a fluidEntryPoint, with an optiona; set of channel name
* and factory for TestFluidObject
*/
constructor(
public readonly LoaderConstructor: typeof Loader,
public readonly driver: ITestDriver,
private readonly createFluidEntryPoint: (testContainerConfig?: ITestContainerConfig) => fluidEntryPoint,
) {
}
get documentServiceFactory() {
if (!this._documentServiceFactory) {
this._documentServiceFactory = this.driver.createDocumentServiceFactory();
}
return this._documentServiceFactory;
}
get urlResolver() {
if (!this._urlResolver) {
this._urlResolver = this.driver.createUrlResolver();
}
return this._urlResolver;
}
get documentId() {
if (this._documentId === undefined) {
this._documentId = createDocumentId();
}
return this._documentId;
}
get defaultCodeDetails() {
return defaultCodeDetails;
}
get opProcessingController(): IOpProcessingController {
return this._loaderContainerTracker;
}
/**
* Create a loader. Container created/loaded thru this loader will not be automatically added
* to the OpProcessingController, and will need to be added manually if needed.
*
* Only the version of the loader will vary based on compat config. The version of
* containerRuntime/dataRuntime used in fluidEntryPoint will be used as is from what is passed in.
*
* @param packageEntries - list of code details and fluidEntryPoint pairs.
*/
public createLoader(packageEntries: Iterable<[IFluidCodeDetails, fluidEntryPoint]>, options?: ILoaderOptions) {
const codeLoader = new LocalCodeLoader(packageEntries);
const loader = new this.LoaderConstructor({
urlResolver: this.urlResolver,
documentServiceFactory: this.documentServiceFactory,
codeLoader,
logger: ChildLogger.create(getTestLogger?.(), undefined, { all: { driverType: this.driver.type } }),
options,
});
this._loaderContainerTracker.add(loader);
return loader;
}
/**
* Create a container using a default document id and code details.
* Container created is automatically added to the OpProcessingController to manage op flow
*
* Only the version of the loader will vary based on compat config. The version of
* containerRuntime/dataRuntime used in fluidEntryPoint will be used as is from what is passed in.
*
* @param packageEntries - list of code details and fluidEntryPoint pairs.
*/
public async createContainer(entryPoint: fluidEntryPoint, options?: ILoaderOptions) {
const loader = this.createLoader([[defaultCodeDetails, entryPoint]], options);
const container = await createAndAttachContainer(
defaultCodeDetails,
loader,
this.driver.createCreateNewRequest(this.documentId),
);
return container;
}
public async loadContainer(entryPoint: fluidEntryPoint, options?: ILoaderOptions, requestHeader?: IRequestHeader) {
const loader = this.createLoader([[defaultCodeDetails, entryPoint]], options);
return loader.resolve({ url: await this.driver.createContainerUrl(this.documentId), headers: requestHeader });
}
/**
* Make a test loader. Container created/loaded thru this loader will not be automatically added
* to the OpProcessingController, and will need to be added manually if needed.
* The version of the loader/containerRuntime/dataRuntime may vary based on compat config of the current run
* @param testContainerConfig - optional configuring the test Container
*/
public makeTestLoader(testContainerConfig?: ITestContainerConfig) {
return this.createLoader([[defaultCodeDetails, this.createFluidEntryPoint(testContainerConfig)]]);
}
/**
* Make a container using a default document id and code details
* Container loaded is automatically added to the OpProcessingController to manage op flow
* @param testContainerConfig - optional configuring the test Container
*/
public async makeTestContainer(testContainerConfig?: ITestContainerConfig): Promise<IContainer> {
const loader = this.makeTestLoader(testContainerConfig);
const container =
await createAndAttachContainer(
defaultCodeDetails,
loader,
this.driver.createCreateNewRequest(this.documentId));
return container;
}
/**
* Load a container using a default document id and code details.
* Container loaded is automatically added to the OpProcessingController to manage op flow
* @param testContainerConfig - optional configuring the test Container
*/
public async loadTestContainer(testContainerConfig?: ITestContainerConfig): Promise<Container> {
const loader = this.makeTestLoader(testContainerConfig);
const container = await loader.resolve({ url: await this.driver.createContainerUrl(this.documentId) });
await waitContainerToCatchUp(container);
return container;
}
public reset() {
this._loaderContainerTracker.reset();
this._documentServiceFactory = undefined;
this._urlResolver = undefined;
this._documentId = undefined;
}
public async ensureSynchronized() {
return this._loaderContainerTracker.ensureSynchronized();
}
}