@milaboratories/pl-client 3.16.2 → 3.17.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/core/capabilities.cjs.map +1 -1
  2. package/dist/core/capabilities.d.ts +1 -1
  3. package/dist/core/capabilities.d.ts.map +1 -1
  4. package/dist/core/capabilities.js.map +1 -1
  5. package/dist/core/transaction.cjs +37 -5
  6. package/dist/core/transaction.cjs.map +1 -1
  7. package/dist/core/transaction.d.ts +32 -3
  8. package/dist/core/transaction.d.ts.map +1 -1
  9. package/dist/core/transaction.js +37 -5
  10. package/dist/core/transaction.js.map +1 -1
  11. package/dist/core/tree_filter.cjs +2 -1
  12. package/dist/core/tree_filter.cjs.map +1 -1
  13. package/dist/core/tree_filter.d.ts +2 -1
  14. package/dist/core/tree_filter.d.ts.map +1 -1
  15. package/dist/core/tree_filter.js +2 -1
  16. package/dist/core/tree_filter.js.map +1 -1
  17. package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.cjs +33 -11
  18. package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.cjs.map +1 -1
  19. package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.d.ts +129 -37
  20. package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.d.ts.map +1 -1
  21. package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.js +33 -11
  22. package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.js.map +1 -1
  23. package/dist/test/test_config.cjs +92 -3
  24. package/dist/test/test_config.cjs.map +1 -1
  25. package/dist/test/test_config.d.ts +29 -4
  26. package/dist/test/test_config.d.ts.map +1 -1
  27. package/dist/test/test_config.js +88 -4
  28. package/dist/test/test_config.js.map +1 -1
  29. package/package.json +4 -4
  30. package/src/core/capabilities.ts +4 -0
  31. package/src/core/client.test.ts +5 -5
  32. package/src/core/ll_client.test.ts +8 -1
  33. package/src/core/ll_transaction.test.ts +9 -3
  34. package/src/core/transaction.test.ts +6 -6
  35. package/src/core/transaction.ts +53 -8
  36. package/src/core/tree_filter.ts +2 -1
  37. package/src/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.ts +158 -51
  38. package/src/test/test_config.test.ts +14 -1
  39. package/src/test/test_config.ts +102 -4
@@ -19,6 +19,8 @@ export interface TestConfig {
19
19
  test_proxy?: string;
20
20
  test_user?: string;
21
21
  test_password?: string;
22
+ test_admin_user?: string;
23
+ test_admin_password?: string;
22
24
  }
23
25
 
24
26
  const CONFIG_FILE = "test_config.json";
@@ -44,6 +46,12 @@ export function getTestConfig(): TestConfig {
44
46
 
45
47
  if (process.env.PL_TEST_PROXY !== undefined) conf.test_proxy = process.env.PL_TEST_PROXY;
46
48
 
49
+ if (process.env.PL_TEST_ADMIN_USER !== undefined)
50
+ conf.test_admin_user = process.env.PL_TEST_ADMIN_USER;
51
+
52
+ if (process.env.PL_TEST_ADMIN_PASSWORD !== undefined)
53
+ conf.test_admin_password = process.env.PL_TEST_ADMIN_PASSWORD;
54
+
47
55
  if (conf.address === undefined)
48
56
  throw new Error(
49
57
  `can't resolve platform address (checked ${CONFIG_FILE} file and PL_ADDRESS environment var)`,
@@ -52,13 +60,37 @@ export function getTestConfig(): TestConfig {
52
60
  return conf as TestConfig;
53
61
  }
54
62
 
55
- /** Default request timeout for tests (ms) */
56
- export const TEST_REQUEST_TIMEOUT = 500;
63
+ /**
64
+ * Default request timeout for tests (ms).
65
+ *
66
+ * Kept short so a hung call fails the test instead of the suite's own budget. A deploy the
67
+ * tests reach over cluster DNS needs more than that on first contact, where the deadline
68
+ * covers name resolution too:
69
+ *
70
+ * RpcError: Deadline exceeded after 0.500s,waiting for name resolution
71
+ *
72
+ * That call builds the shared client, so the whole file dies with it and retries only
73
+ * repeat the error against an undefined client. PL_TEST_REQUEST_TIMEOUT raises the budget
74
+ * where resolution is slow, and every other environment keeps the short one.
75
+ */
76
+ export const TEST_REQUEST_TIMEOUT = Number(process.env.PL_TEST_REQUEST_TIMEOUT ?? 500);
77
+
78
+ /** True when the address carries an explicit `request-timeout` query parameter. */
79
+ function addressStatesRequestTimeout(address: string): boolean {
80
+ if (address.indexOf("://") === -1) return false;
81
+ return new URL(address).searchParams.has("request-timeout");
82
+ }
57
83
 
58
- /** Returns PlClientConfig with reduced timeout for tests */
84
+ /** Returns PlClientConfig with reduced timeout for tests, unless the address sets its own */
59
85
  export function plAddressToTestConfig(address: string): PlClientConfig {
60
86
  const plConf = plAddressToConfig(address);
61
- plConf.defaultRequestTimeout = TEST_REQUEST_TIMEOUT;
87
+ // An explicit request-timeout in the address wins over TEST_REQUEST_TIMEOUT. In the k8s e2e
88
+ // deploy the client dials a cluster service DNS name, and the first call on a cold channel must
89
+ // finish name resolution and get a load-balancer pick before it is even sent; 500ms does not
90
+ // cover that, so whichever test happened to open the cold channel died with DEADLINE_EXCEEDED
91
+ // ("Waiting for LB pick") against a healthy backend. Addresses that carry no request-timeout
92
+ // keep the short default, so local runs still fail fast.
93
+ if (!addressStatesRequestTimeout(address)) plConf.defaultRequestTimeout = TEST_REQUEST_TIMEOUT;
62
94
  return plConf;
63
95
  }
64
96
 
@@ -178,6 +210,72 @@ export async function getTestLLClient(confOverrides: Partial<PlClientConfig> = {
178
210
  return await LLPlClient.build({ ...conf, ...confOverrides }, { auth });
179
211
  }
180
212
 
213
+ /** Returns a config logged in as the admin test user, or the ordinary test config where no
214
+ * admin credentials are set. A backend that needs no auth, and one whose single test user
215
+ * already holds the admin role, both leave PL_TEST_ADMIN_USER and PL_TEST_ADMIN_PASSWORD
216
+ * unset, and a test that asks for admin must still run there. */
217
+ export async function getTestAdminClientConf(): Promise<{ conf: PlClientConfig; auth: AuthOps }> {
218
+ const tConf = getTestConfig();
219
+
220
+ if (tConf.test_admin_user === undefined || tConf.test_admin_password === undefined)
221
+ return await getTestClientConf();
222
+
223
+ const plConf = plAddressToTestConfig(tConf.address);
224
+ const uClient = await UnauthenticatedPlClient.build(plConf);
225
+ const authInformation = await uClient.login(tConf.test_admin_user, tConf.test_admin_password);
226
+
227
+ return {
228
+ conf: plConf,
229
+ auth: {
230
+ authInformation,
231
+ onUpdate: () => {},
232
+ onAuthError: () => {},
233
+ onUpdateError: () => {},
234
+ },
235
+ };
236
+ }
237
+
238
+ export async function getTestAdminLLClient(confOverrides: Partial<PlClientConfig> = {}) {
239
+ const { conf, auth } = await getTestAdminClientConf();
240
+ return await LLPlClient.build({ ...conf, ...confOverrides }, { auth });
241
+ }
242
+
243
+ export async function getTestAdminClient(
244
+ alternativeRoot?: string,
245
+ confOverrides: Partial<PlClientConfig> = {},
246
+ ) {
247
+ const { conf, auth } = await getTestAdminClientConf();
248
+ if (alternativeRoot !== undefined && conf.alternativeRoot !== undefined)
249
+ throw new Error("test pl address configured with alternative root");
250
+ return await PlClient.init({ ...conf, ...confOverrides, alternativeRoot }, auth);
251
+ }
252
+
253
+ export async function withAdminTempRoot<T>(body: (pl: PlClient) => Promise<T>): Promise<T | void> {
254
+ const alternativeRoot = `test_${Date.now()}_${randomUUID()}`;
255
+ let altRootId: OptionalSignedResourceId = NullSignedResourceId;
256
+ try {
257
+ const client = await getTestAdminClient(alternativeRoot);
258
+ altRootId = client.clientRoot;
259
+ try {
260
+ const value = await body(client);
261
+ const rawClient = await getTestAdminClient();
262
+ try {
263
+ await rawClient.deleteAlternativeRoot(alternativeRoot);
264
+ } catch (cleanupErr: any) {
265
+ console.warn(`Failed to clean up alternative root ${alternativeRoot}:`, cleanupErr.message);
266
+ } finally {
267
+ await rawClient.close();
268
+ }
269
+ return value;
270
+ } finally {
271
+ await client.close();
272
+ }
273
+ } catch (err: any) {
274
+ console.log(`ALTERNATIVE ROOT: ${alternativeRoot} (${resourceIdToString(altRootId)})`);
275
+ throw err;
276
+ }
277
+ }
278
+
181
279
  export async function getTestClient(
182
280
  alternativeRoot?: string,
183
281
  confOverrides: Partial<PlClientConfig> = {},