Skip to content

Commit 879a805

Browse files
authored
feat(FIR-37168): testConnection doesn't reset autostop timer (#122)
1 parent 3cf1284 commit 879a805

File tree

8 files changed

+126
-4
lines changed

8 files changed

+126
-4
lines changed

src/connection/base.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ export abstract class Connection {
5454

5555
abstract resolveEngineEndpoint(): Promise<string>;
5656

57+
abstract testConnection(): Promise<void>;
58+
5759
protected getRequestUrl(executeQueryOptions: ExecuteQueryOptions): string {
5860
const params = this.getBaseParameters(executeQueryOptions);
5961

@@ -81,7 +83,15 @@ export abstract class Connection {
8183
const strSettings = Object.entries(settings ?? {}).reduce<
8284
Record<string, string>
8385
>((acc, [key, value]) => {
84-
if (value !== undefined) {
86+
if (key === "internal") {
87+
// Unwrap internal settings from array
88+
const internalSettings = value as Record<string, string | number>[];
89+
internalSettings.forEach(setting => {
90+
Object.entries(setting).forEach(([internalKey, internalValue]) => {
91+
acc[internalKey] = internalValue.toString();
92+
});
93+
});
94+
} else if (value !== undefined) {
8595
acc[key] = value.toString();
8696
}
8797
return acc;

src/connection/connection_v1.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,4 +59,8 @@ export class ConnectionV1 extends BaseConnection {
5959
}
6060
return this.accountInfo;
6161
}
62+
63+
async testConnection() {
64+
await this.execute("select 1");
65+
}
6266
}

src/connection/connection_v2.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,9 @@ export class ConnectionV2 extends BaseConnection {
6969

7070
return this.engineEndpoint;
7171
}
72+
73+
async testConnection() {
74+
const settings = { internal: [{ auto_start_stop_control: "ignore" }] };
75+
await this.execute("select 1", { settings });
76+
}
7277
}

src/core/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,6 @@ export class FireboltCore {
3131
const connection = makeConnection(this.context, connectionOptions);
3232
await auth.authenticate();
3333
await connection.resolveEngineEndpoint();
34-
await connection.execute("select 1");
34+
await connection.testConnection();
3535
}
3636
}

src/types.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,10 @@ export enum OutputFormat {
3131

3232
export type QuerySettings = Record<
3333
string,
34-
string | number | boolean | undefined
34+
string | number | boolean | undefined | Record<string, string | number>[]
3535
> & {
3636
output_format?: OutputFormat;
37+
internal?: Record<string, string | number>[];
3738
};
3839

3940
export type RowParser = (row: string, isLastRow: boolean) => any;

test/unit/connection.test.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,36 @@ INFO: SYNTAX_ERROR - Unexpected character at {"failingLine":42,"startOffset":120
493493
expect(searchParamsUsed.get("param")).toEqual("value");
494494
});
495495

496+
it("handles settings in execute", async () => {
497+
server.use(
498+
rest.post(`https://some_engine.com`, async (req, res, ctx) => {
499+
const body = await req.text();
500+
const urlParams = Object.fromEntries(req.url.searchParams.entries());
501+
expect(urlParams).toHaveProperty("param");
502+
if (body.startsWith("SELECT 1")) {
503+
return res(ctx.json(emptyResponse));
504+
}
505+
})
506+
);
507+
508+
const connectionParams: ConnectionOptions = {
509+
auth: {
510+
client_id: "dummy",
511+
client_secret: "dummy"
512+
},
513+
database: "dummy",
514+
engineName: "dummy",
515+
account: "my_account"
516+
};
517+
const firebolt = Firebolt({
518+
apiEndpoint
519+
});
520+
521+
const connection = await firebolt.connect(connectionParams);
522+
await connection.execute("SELECT 1", { settings: { param: "value" } });
523+
});
524+
525+
496526
it("handles invalid set statements correctly", async () => {
497527
let searchParamsUsed = new URLSearchParams();
498528
let searchParamsUsed2 = new URLSearchParams();

test/unit/v1/connection.test.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { rest } from "msw";
33
import { ConnectionOptions, Firebolt } from "../../../src";
44
import { ConnectionV1 } from "../../../src/connection/connection_v1";
55

6-
76
const apiEndpoint = "fake.api.com";
87
const accountName = "my_account";
98

@@ -136,6 +135,33 @@ describe("Connection v1", () => {
136135
).resolveAccountInfo();
137136
expect(account_info.id).toBe("some_account");
138137
});
138+
it("testConnection works", async () => {
139+
// override select 1 response and check within it that query parameter is not set
140+
server.use(
141+
rest.post(`https://some_engine.com/`, (req, res, ctx) => {
142+
const urlParams = Object.fromEntries(req.url.searchParams.entries());
143+
expect(urlParams).not.toContain("auto_start_stop_control");
144+
return res(ctx.json(selectOneResponse));
145+
})
146+
);
147+
148+
const firebolt = Firebolt({ apiEndpoint });
149+
150+
const connectionParams: ConnectionOptions = {
151+
auth: {
152+
username: "user",
153+
password: "pass"
154+
},
155+
database: "dummy",
156+
engineName: "dummy",
157+
account: accountName
158+
};
159+
160+
const connection = await firebolt.connect(connectionParams);
161+
await connection.testConnection();
162+
// also test the method from core
163+
await firebolt.testConnection(connectionParams);
164+
});
139165
it("Can run set statements", async () => {
140166
const param = "my_var";
141167
const value = "1";

test/unit/v2/connection.test.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,52 @@ describe("Connection V2", () => {
162162

163163
expect(engineUrlCalls).toBe(1);
164164
});
165+
it("testConnection works", async () => {
166+
const firebolt = Firebolt({
167+
apiEndpoint
168+
});
169+
170+
server.use(
171+
rest.post(`https://id.fake.firebolt.io/oauth/token`, (req, res, ctx) => {
172+
return res(
173+
ctx.json({
174+
access_token: "fake_access_token"
175+
})
176+
);
177+
}),
178+
rest.get(
179+
`https://api.fake.firebolt.io/web/v3/account/my_account/engineUrl`,
180+
(req, res, ctx) => {
181+
return res(
182+
ctx.json({
183+
engineUrl: "https://some_system_engine.com"
184+
})
185+
);
186+
}
187+
),
188+
rest.post(
189+
`https://some_system_engine.com/${QUERY_URL}`,
190+
(req, res, ctx) => {
191+
const urlParams = Object.fromEntries(req.url.searchParams.entries());
192+
expect(urlParams).toHaveProperty("auto_start_stop_control");
193+
return res(ctx.json(engineUrlResponse));
194+
}
195+
)
196+
);
197+
198+
const connectionParams: ConnectionOptions = {
199+
auth: {
200+
client_id: "dummy",
201+
client_secret: "dummy"
202+
},
203+
account: "my_account"
204+
};
205+
206+
const connection = await firebolt.connect(connectionParams);
207+
await connection.testConnection();
208+
// also test the method from core
209+
await firebolt.testConnection(connectionParams);
210+
});
165211
it("respects useCache option", async () => {
166212
const firebolt = Firebolt({
167213
apiEndpoint

0 commit comments

Comments
 (0)