@fabricorg/databricks-testkit 0.1.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/LICENSE +21 -0
- package/README.md +82 -0
- package/dist/chunk-7JVDOSBO.js +94 -0
- package/dist/chunk-7JVDOSBO.js.map +1 -0
- package/dist/chunk-F3KU6VZS.js +56 -0
- package/dist/chunk-F3KU6VZS.js.map +1 -0
- package/dist/chunk-FBADA7LQ.js +195 -0
- package/dist/chunk-FBADA7LQ.js.map +1 -0
- package/dist/chunk-MLBZCHRM.js +37 -0
- package/dist/chunk-MLBZCHRM.js.map +1 -0
- package/dist/duckdb-context-FX23RUBV.js +4 -0
- package/dist/duckdb-context-FX23RUBV.js.map +1 -0
- package/dist/fixtures-CAWhzIHu.d.cts +27 -0
- package/dist/fixtures-CAWhzIHu.d.ts +27 -0
- package/dist/index.cjs +1152 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +301 -0
- package/dist/index.d.ts +301 -0
- package/dist/index.js +690 -0
- package/dist/index.js.map +1 -0
- package/dist/parity.cjs +411 -0
- package/dist/parity.cjs.map +1 -0
- package/dist/parity.d.cts +17 -0
- package/dist/parity.d.ts +17 -0
- package/dist/parity.js +45 -0
- package/dist/parity.js.map +1 -0
- package/dist/workspace-context-AIUYISUS.js +4 -0
- package/dist/workspace-context-AIUYISUS.js.map +1 -0
- package/package.json +66 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
import { T as TableFixture } from './fixtures-CAWhzIHu.js';
|
|
2
|
+
export { F as FixtureColumn, p as parseFixtureColumns, r as resolveFixtureRows } from './fixtures-CAWhzIHu.js';
|
|
3
|
+
import { DatabricksRestClient } from '@fabric-harness/databricks';
|
|
4
|
+
export { waitForDatabricksRun, waitForDatabricksStatement } from '@fabric-harness/databricks';
|
|
5
|
+
import { LakebasePoolFactory, LakebaseDatabaseProvider } from '@fabricorg/experiments-db-pool';
|
|
6
|
+
|
|
7
|
+
type TestProfile = 'local' | 'live';
|
|
8
|
+
/**
|
|
9
|
+
* One SQL surface, two engines (ADR-0006). `local` executes on DuckDB
|
|
10
|
+
* in-process; `live` executes on a Databricks SQL warehouse via the SQL
|
|
11
|
+
* Statement Execution API. Params are positional `?` in both profiles — the
|
|
12
|
+
* workspace context transparently rewrites them to the named markers the
|
|
13
|
+
* Statement Execution API requires.
|
|
14
|
+
*/
|
|
15
|
+
interface ExecutionContext {
|
|
16
|
+
readonly profile: TestProfile;
|
|
17
|
+
/** Execute a statement, discarding any result. */
|
|
18
|
+
exec(sql: string, params?: readonly unknown[]): Promise<void>;
|
|
19
|
+
/** Execute a query and return normalized row objects (bigint→number, timestamps→ISO). */
|
|
20
|
+
query(sql: string, params?: readonly unknown[]): Promise<Record<string, unknown>[]>;
|
|
21
|
+
/** Create + seed a table from a declarative fixture. */
|
|
22
|
+
loadFixture(fixture: TableFixture): Promise<void>;
|
|
23
|
+
/** Qualify a bare table name for this context (schema/catalog scoping). */
|
|
24
|
+
qual(table: string): string;
|
|
25
|
+
close(): Promise<void>;
|
|
26
|
+
}
|
|
27
|
+
declare function resolveProfile(env?: Record<string, string | undefined>): TestProfile;
|
|
28
|
+
interface CreateContextOptions {
|
|
29
|
+
profile?: TestProfile;
|
|
30
|
+
env?: Record<string, string | undefined>;
|
|
31
|
+
/** local profile: schema to create + qualify tables with. live profile: schema within the catalog. */
|
|
32
|
+
schema?: string;
|
|
33
|
+
/** Live profile only: observe each submitted SQL statement. */
|
|
34
|
+
onStatement?: (statement: {
|
|
35
|
+
sql: string;
|
|
36
|
+
statementId?: string;
|
|
37
|
+
}) => void;
|
|
38
|
+
}
|
|
39
|
+
/** Profile-dispatched factory. Lazy-imports each engine so the unused one stays out of the bundle. */
|
|
40
|
+
declare function createExecutionContext(options?: CreateContextOptions): Promise<ExecutionContext>;
|
|
41
|
+
|
|
42
|
+
interface DuckDbContextOptions {
|
|
43
|
+
/** Database file path; ':memory:' (default) for a throwaway in-process db. */
|
|
44
|
+
path?: string;
|
|
45
|
+
/** Optional schema to create + qualify tables with. */
|
|
46
|
+
schema?: string;
|
|
47
|
+
/** Injectable for tests of this module itself. */
|
|
48
|
+
connectionFactory?: (path: string) => Promise<DuckDbConnectionLike>;
|
|
49
|
+
}
|
|
50
|
+
/** Structural slice of the lazily-imported @duckdb/node-api connection. */
|
|
51
|
+
interface DuckDbConnectionLike {
|
|
52
|
+
run(sql: string, values?: unknown[]): Promise<unknown>;
|
|
53
|
+
runAndReadAll(sql: string, values?: unknown[]): Promise<{
|
|
54
|
+
getRowObjects(): Record<string, unknown>[];
|
|
55
|
+
}>;
|
|
56
|
+
closeSync(): void;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Hermetic local execution context on DuckDB — the `local` profile of the
|
|
60
|
+
* testing pyramid. No workspace, no credentials, sub-second.
|
|
61
|
+
*/
|
|
62
|
+
declare function createDuckDbContext(options?: DuckDbContextOptions): Promise<ExecutionContext>;
|
|
63
|
+
/**
|
|
64
|
+
* Normalize DuckDB values to plain JSON-ish values so assertions and golden
|
|
65
|
+
* files are engine-portable: bigint→number, TIMESTAMP→`YYYY-MM-DD HH:MM:SS`
|
|
66
|
+
* (UTC, microseconds trimmed), DECIMAL→number.
|
|
67
|
+
*/
|
|
68
|
+
declare function normalizeRow(row: Record<string, unknown>): Record<string, unknown>;
|
|
69
|
+
|
|
70
|
+
/** Structural slice of DatabricksRestClient the workspace context uses (injectable in tests). */
|
|
71
|
+
interface WorkspaceClientLike {
|
|
72
|
+
get<T>(path: string, query?: Record<string, string | number | boolean | undefined>): Promise<T>;
|
|
73
|
+
post<T>(path: string, body?: unknown, query?: Record<string, string | number | boolean | undefined>, options?: unknown): Promise<T>;
|
|
74
|
+
}
|
|
75
|
+
interface WorkspaceContextOptions {
|
|
76
|
+
env?: Record<string, string | undefined>;
|
|
77
|
+
/** Schema within the catalog used by qual(); defaults to DBX_TEST_SCHEMA. */
|
|
78
|
+
schema?: string;
|
|
79
|
+
/** Injectable client for hermetic tests; defaults to a DatabricksRestClient from env auth. */
|
|
80
|
+
client?: WorkspaceClientLike;
|
|
81
|
+
/** Injectable fetch for the OAuth M2M exchange. */
|
|
82
|
+
fetchImpl?: typeof fetch;
|
|
83
|
+
pollIntervalMs?: number;
|
|
84
|
+
timeoutMs?: number;
|
|
85
|
+
/** Drop tables seeded by this context on close. Defaults to true. */
|
|
86
|
+
cleanupFixtures?: boolean;
|
|
87
|
+
/** Observe submitted statements for redacted failure evidence. */
|
|
88
|
+
onStatement?: (statement: {
|
|
89
|
+
sql: string;
|
|
90
|
+
statementId?: string;
|
|
91
|
+
}) => void;
|
|
92
|
+
}
|
|
93
|
+
interface StatementResponse {
|
|
94
|
+
statement_id?: string;
|
|
95
|
+
status?: {
|
|
96
|
+
state?: string;
|
|
97
|
+
error?: {
|
|
98
|
+
message?: string;
|
|
99
|
+
};
|
|
100
|
+
};
|
|
101
|
+
manifest?: {
|
|
102
|
+
schema?: {
|
|
103
|
+
columns?: {
|
|
104
|
+
name: string;
|
|
105
|
+
type_name?: string;
|
|
106
|
+
position?: number;
|
|
107
|
+
}[];
|
|
108
|
+
};
|
|
109
|
+
};
|
|
110
|
+
result?: {
|
|
111
|
+
data_array?: (string | null)[][];
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Live execution context on a Databricks SQL warehouse via the SQL Statement
|
|
116
|
+
* Execution API (/api/2.0/sql/statements). The Statement Execution API takes
|
|
117
|
+
* NAMED parameter markers, so positional `?` params are rewritten to
|
|
118
|
+
* `:p1..:pn` — the ExecutionContext surface stays identical to the local
|
|
119
|
+
* profile.
|
|
120
|
+
*/
|
|
121
|
+
declare function createWorkspaceContext(options?: WorkspaceContextOptions): Promise<ExecutionContext>;
|
|
122
|
+
/** Rewrite positional `?` markers to the named `:pN` markers the Statement Execution API requires. */
|
|
123
|
+
declare function toNamedParameters(sql: string, params: readonly unknown[]): {
|
|
124
|
+
statement: string;
|
|
125
|
+
parameters: {
|
|
126
|
+
name: string;
|
|
127
|
+
value: string | null;
|
|
128
|
+
}[];
|
|
129
|
+
};
|
|
130
|
+
/** Map a terminal statement response to normalized row objects. */
|
|
131
|
+
declare function parseStatementRows(response: StatementResponse): Record<string, unknown>[];
|
|
132
|
+
/**
|
|
133
|
+
* Auth precedence (ADR-0006): DATABRICKS_BEARER (pre-minted, CI) →
|
|
134
|
+
* DATABRICKS_CLIENT_ID/SECRET (OAuth M2M) → DATABRICKS_TOKEN (PAT).
|
|
135
|
+
*/
|
|
136
|
+
declare function createClientFromEnv(env: Record<string, string | undefined>, fetchImpl?: typeof fetch): DatabricksRestClient;
|
|
137
|
+
declare function resolveTokenProvider(host: string, env: Record<string, string | undefined>, fetchImpl?: typeof fetch): string | (() => Promise<string>);
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Framework-free table assertions — they throw plain Errors so they work
|
|
141
|
+
* under vitest, cucumber-js steps, or the live check runner alike.
|
|
142
|
+
*/
|
|
143
|
+
declare function expectTable(ctx: ExecutionContext, table: string): {
|
|
144
|
+
toHaveRowCount(expected: number): Promise<void>;
|
|
145
|
+
/** Every partial row must match at least one table row on its own keys. */
|
|
146
|
+
toContainRows(partials: readonly Record<string, unknown>[]): Promise<void>;
|
|
147
|
+
/**
|
|
148
|
+
* Compare `SELECT * ORDER BY <orderBy>` against a committed golden JSON
|
|
149
|
+
* file. Set DBX_TEST_UPDATE_GOLDEN=1 to (re)write the golden instead —
|
|
150
|
+
* a reviewable, versioned event.
|
|
151
|
+
*/
|
|
152
|
+
toMatchGolden(goldenPath: string, options?: {
|
|
153
|
+
orderBy?: string;
|
|
154
|
+
}): Promise<void>;
|
|
155
|
+
};
|
|
156
|
+
/** Compare query results (not a whole table) against a golden file. */
|
|
157
|
+
declare function expectQueryToMatchGolden(ctx: ExecutionContext, sql: string, params: readonly unknown[], goldenPath: string): Promise<void>;
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Golden-result files: committed JSON snapshots of query results that every
|
|
161
|
+
* engine and every refactor must reproduce exactly — the frozen-vector
|
|
162
|
+
* pattern from @fabricorg/experiments-testkit generalized to warehouse rows.
|
|
163
|
+
*/
|
|
164
|
+
declare function compareToGolden(goldenPath: string, actual: readonly Record<string, unknown>[], label: string, env?: Record<string, string | undefined>): Promise<void>;
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Framework-free fake of the Databricks REST client surface, for unit tests
|
|
168
|
+
* of orchestration logic (submit → poll → terminal). Queue responses per
|
|
169
|
+
* (method, path-prefix); every call is recorded for assertions. Works under
|
|
170
|
+
* vitest without vi.fn so it is equally usable from cucumber-js worlds.
|
|
171
|
+
*/
|
|
172
|
+
interface RecordedCall {
|
|
173
|
+
method: 'GET' | 'POST';
|
|
174
|
+
path: string;
|
|
175
|
+
body?: unknown;
|
|
176
|
+
query?: Record<string, string | number | boolean | undefined>;
|
|
177
|
+
}
|
|
178
|
+
interface MockDatabricksClient {
|
|
179
|
+
get<T>(path: string, query?: Record<string, string | number | boolean | undefined>): Promise<T>;
|
|
180
|
+
post<T>(path: string, body?: unknown, query?: Record<string, string | number | boolean | undefined>, options?: unknown): Promise<T>;
|
|
181
|
+
/** Queue the next response for calls whose path starts with `pathPrefix`. FIFO per prefix. */
|
|
182
|
+
queue(method: 'GET' | 'POST', pathPrefix: string, response: unknown): MockDatabricksClient;
|
|
183
|
+
/** Queue an error for the next matching call. */
|
|
184
|
+
queueError(method: 'GET' | 'POST', pathPrefix: string, error: Error): MockDatabricksClient;
|
|
185
|
+
readonly calls: readonly RecordedCall[];
|
|
186
|
+
callsTo(method: 'GET' | 'POST', pathPrefix: string): RecordedCall[];
|
|
187
|
+
}
|
|
188
|
+
declare function createMockDatabricksClient(): MockDatabricksClient;
|
|
189
|
+
|
|
190
|
+
type LiveCheckStatus = 'pass' | 'fail' | 'not-configured';
|
|
191
|
+
interface LiveCheckContext {
|
|
192
|
+
env: Record<string, string | undefined>;
|
|
193
|
+
warehouse: ExecutionContext;
|
|
194
|
+
client: WorkspaceClientLike;
|
|
195
|
+
}
|
|
196
|
+
interface LiveCheck {
|
|
197
|
+
id: string;
|
|
198
|
+
description: string;
|
|
199
|
+
configured?: (env: Record<string, string | undefined>) => boolean;
|
|
200
|
+
run(context: LiveCheckContext): Promise<unknown>;
|
|
201
|
+
}
|
|
202
|
+
interface LiveCheckResult {
|
|
203
|
+
id: string;
|
|
204
|
+
description: string;
|
|
205
|
+
status: LiveCheckStatus;
|
|
206
|
+
durationMs: number;
|
|
207
|
+
details?: unknown;
|
|
208
|
+
error?: string;
|
|
209
|
+
}
|
|
210
|
+
interface LiveEvidence {
|
|
211
|
+
schemaVersion: 1;
|
|
212
|
+
kind: 'databricks-live-suite';
|
|
213
|
+
startedAt: string;
|
|
214
|
+
finishedAt: string;
|
|
215
|
+
success: boolean;
|
|
216
|
+
required: string[];
|
|
217
|
+
results: LiveCheckResult[];
|
|
218
|
+
}
|
|
219
|
+
interface LiveSuiteSpec {
|
|
220
|
+
checks: readonly LiveCheck[];
|
|
221
|
+
required?: readonly string[];
|
|
222
|
+
evidencePath?: string;
|
|
223
|
+
junitPath?: string;
|
|
224
|
+
env?: Record<string, string | undefined>;
|
|
225
|
+
}
|
|
226
|
+
interface LiveSuiteRuntime {
|
|
227
|
+
warehouse?: ExecutionContext;
|
|
228
|
+
client?: WorkspaceClientLike;
|
|
229
|
+
}
|
|
230
|
+
interface DefinedLiveSuite {
|
|
231
|
+
run(runtime?: LiveSuiteRuntime): Promise<LiveEvidence | undefined>;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Define an explicitly gated live suite. Without DBX_TEST_LIVE=1, run() is a
|
|
235
|
+
* silent no-op so the same command is safe in ordinary CI matrices.
|
|
236
|
+
*/
|
|
237
|
+
declare function defineLiveSuite(spec: LiveSuiteSpec): DefinedLiveSuite;
|
|
238
|
+
declare function runLiveSuite(spec: LiveSuiteSpec, runtime?: LiveSuiteRuntime): Promise<LiveEvidence | undefined>;
|
|
239
|
+
declare function renderJUnit(evidence: LiveEvidence): string;
|
|
240
|
+
|
|
241
|
+
declare function sqlRoundTripCheck(): LiveCheck;
|
|
242
|
+
interface DeltaColumnContract {
|
|
243
|
+
name: string;
|
|
244
|
+
type?: string;
|
|
245
|
+
}
|
|
246
|
+
declare function assertDeltaContract(table: string, rows: readonly Record<string, unknown>[], columns: readonly DeltaColumnContract[]): void;
|
|
247
|
+
declare function deltaContractCheck(tableEnv?: string, columns?: readonly DeltaColumnContract[]): LiveCheck;
|
|
248
|
+
declare function unityCatalogAccessCheck(): LiveCheck;
|
|
249
|
+
declare function jobRunCheck(): LiveCheck;
|
|
250
|
+
/** Trigger the deployed Lakeflow pipeline and require a completed update. */
|
|
251
|
+
declare function pipelineRefreshCheck(): LiveCheck;
|
|
252
|
+
declare function notebookSubmitCheck(): LiveCheck;
|
|
253
|
+
declare function dbtBuildCheck(): LiveCheck;
|
|
254
|
+
/** Wrap product-specific checks such as Auto Loader, Lakebase, notebooks, or dbt. */
|
|
255
|
+
declare function customLiveCheck(id: string, description: string, run: LiveCheck['run'], configured?: LiveCheck['configured']): LiveCheck;
|
|
256
|
+
|
|
257
|
+
interface LakebaseCheckOptions {
|
|
258
|
+
fetchImpl?: typeof fetch;
|
|
259
|
+
poolFactory?: LakebasePoolFactory;
|
|
260
|
+
}
|
|
261
|
+
declare function createLakebaseTestProvider(env: Record<string, string | undefined>, options?: LakebaseCheckOptions): LakebaseDatabaseProvider;
|
|
262
|
+
/** Verify the workspace identity can exchange a short-lived Lakebase credential. */
|
|
263
|
+
declare function lakebaseCredentialCheck(options?: LakebaseCheckOptions): LiveCheck;
|
|
264
|
+
/** Exercise the production provider before and after an explicit credential/pool refresh. */
|
|
265
|
+
declare function lakebaseRoundTripCheck(options?: LakebaseCheckOptions): LiveCheck;
|
|
266
|
+
|
|
267
|
+
/** Assert secret key metadata only; values are never requested. */
|
|
268
|
+
declare function secretScopeCheck(): LiveCheck;
|
|
269
|
+
interface AppHealthCheckOptions {
|
|
270
|
+
fetchImpl?: typeof fetch;
|
|
271
|
+
}
|
|
272
|
+
/** Verify app state, resource bindings, and the gateway-authenticated application health route. */
|
|
273
|
+
declare function appHealthCheck(options?: AppHealthCheckOptions): LiveCheck;
|
|
274
|
+
|
|
275
|
+
interface VolumeIOCheckOptions {
|
|
276
|
+
fetchImpl?: typeof fetch;
|
|
277
|
+
randomId?: () => string;
|
|
278
|
+
}
|
|
279
|
+
declare function normalizeVolumeRoot(value: string): string;
|
|
280
|
+
declare function ensureVolumeDirectory(env: Record<string, string | undefined>, directory: string, fetchImpl?: typeof fetch): Promise<void>;
|
|
281
|
+
declare function uploadVolumeFile(env: Record<string, string | undefined>, path: string, body: BodyInit | Uint8Array, fetchImpl?: typeof fetch): Promise<void>;
|
|
282
|
+
declare function deleteVolumeFile(env: Record<string, string | undefined>, path: string, fetchImpl?: typeof fetch): Promise<void>;
|
|
283
|
+
/** Upload, download, and delete a small probe through the Databricks Files API. */
|
|
284
|
+
declare function volumeIOCheck(options?: VolumeIOCheckOptions): LiveCheck;
|
|
285
|
+
|
|
286
|
+
interface AutoLoaderCheckOptions {
|
|
287
|
+
fetchImpl?: typeof fetch;
|
|
288
|
+
fixtureBody?: Uint8Array;
|
|
289
|
+
randomId?: () => string;
|
|
290
|
+
}
|
|
291
|
+
/** Exercise Files API -> isolated Lakeflow pipeline -> Delta output. */
|
|
292
|
+
declare function autoLoaderIngestionCheck(options?: AutoLoaderCheckOptions): LiveCheck;
|
|
293
|
+
|
|
294
|
+
interface PollOptions {
|
|
295
|
+
pollIntervalMs?: number;
|
|
296
|
+
timeoutMs?: number;
|
|
297
|
+
signal?: AbortSignal;
|
|
298
|
+
}
|
|
299
|
+
declare function waitForPipelineUpdate(client: WorkspaceClientLike, pipelineId: string, updateId: string, options?: PollOptions): Promise<Record<string, unknown>>;
|
|
300
|
+
|
|
301
|
+
export { type AppHealthCheckOptions, type AutoLoaderCheckOptions, type CreateContextOptions, type DefinedLiveSuite, type DeltaColumnContract, type DuckDbConnectionLike, type DuckDbContextOptions, type ExecutionContext, type LakebaseCheckOptions, type LiveCheck, type LiveCheckContext, type LiveCheckResult, type LiveCheckStatus, type LiveEvidence, type LiveSuiteRuntime, type LiveSuiteSpec, type MockDatabricksClient, type PollOptions, type RecordedCall, TableFixture, type TestProfile, type VolumeIOCheckOptions, type WorkspaceClientLike, type WorkspaceContextOptions, appHealthCheck, assertDeltaContract, autoLoaderIngestionCheck, compareToGolden, createClientFromEnv, createDuckDbContext, createExecutionContext, createLakebaseTestProvider, createMockDatabricksClient, createWorkspaceContext, customLiveCheck, dbtBuildCheck, defineLiveSuite, deleteVolumeFile, deltaContractCheck, ensureVolumeDirectory, expectQueryToMatchGolden, expectTable, jobRunCheck, lakebaseCredentialCheck, lakebaseRoundTripCheck, normalizeRow, normalizeVolumeRoot, notebookSubmitCheck, parseStatementRows, pipelineRefreshCheck, renderJUnit, resolveProfile, resolveTokenProvider, runLiveSuite, secretScopeCheck, sqlRoundTripCheck, toNamedParameters, unityCatalogAccessCheck, uploadVolumeFile, volumeIOCheck, waitForPipelineUpdate };
|