Skip to content

Commit 2db5627

Browse files
fix: Fix engine status parsing for engine get metods (#95)
1 parent 4111703 commit 2db5627

File tree

5 files changed

+159
-8
lines changed

5 files changed

+159
-8
lines changed

src/service/engine/index.ts

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@ import { ConnectionError, DeprecationError } from "../../common/errors";
22
import { ResourceManagerContext } from "../../types";
33
import { DatabaseModel } from "../database/model";
44
import { EngineModel } from "./model";
5-
import { EngineStatusSummary, CreateEngineOptions, EngineType } from "./types";
5+
import {
6+
EngineStatusSummary,
7+
CreateEngineOptions,
8+
EngineType,
9+
processEngineStatus
10+
} from "./types";
611

712
export class EngineService {
813
context: ResourceManagerContext;
@@ -31,6 +36,17 @@ export class EngineService {
3136
this.context = context;
3237
}
3338

39+
private parseStatusForEngine(
40+
value: string,
41+
name: string
42+
): EngineStatusSummary {
43+
const status = processEngineStatus(value);
44+
if (status === undefined) {
45+
throw new Error(`Engine ${name} has an unexpected status ${value}`);
46+
}
47+
return status;
48+
}
49+
3450
async getById(engineId: string) {
3551
throw new DeprecationError({
3652
message: "Can't call getById as engine IDs are deprecated"
@@ -52,7 +68,7 @@ export class EngineService {
5268
return new EngineModel(this.context.connection, {
5369
name,
5470
endpoint,
55-
current_status_summary: status as EngineStatusSummary
71+
current_status_summary: this.parseStatusForEngine(status, name)
5672
});
5773
}
5874

@@ -71,7 +87,7 @@ export class EngineService {
7187
new EngineModel(this.context.connection, {
7288
name,
7389
endpoint,
74-
current_status_summary: summary as EngineStatusSummary
90+
current_status_summary: this.parseStatusForEngine(summary, name)
7591
})
7692
);
7793
}
@@ -93,7 +109,7 @@ export class EngineService {
93109
new EngineModel(this.context.connection, {
94110
name,
95111
endpoint,
96-
current_status_summary: summary as EngineStatusSummary
112+
current_status_summary: this.parseStatusForEngine(summary, name)
97113
})
98114
);
99115
}

src/service/engine/model.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ export class EngineModel {
7272
}
7373
const firstRow = data[0] as unknown[];
7474
const status = processEngineStatus(firstRow[0] as string);
75-
if (!status) {
75+
if (status === undefined) {
7676
throw new Error(
7777
`Engine ${this.name} has an unexpected status ${firstRow[0]}`
7878
);

src/service/engine/types.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,12 @@ export type Engine = {
77
};
88

99
export function processEngineStatus(
10-
value: string
10+
value: string | undefined
1111
): EngineStatusSummary | undefined {
1212
// Translate status from db to an EngineStatusSummary object
13+
if (value === undefined) {
14+
return undefined;
15+
}
1316
const enumKey = Object.keys(EngineStatusSummary).find(
1417
key =>
1518
EngineStatusSummary[

test/unit/v2/database.test.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { QUERY_URL } from "../../../src/common/api";
44
import { Firebolt } from "../../../src";
55
import { ConnectionError, DeprecationError } from "../../../src/common/errors";
66
import { CreateDatabaseOptions } from "../../../src/service/database/types";
7+
import { selectEngineResponse, selectEnginesResponse } from "./engine.test";
78

89
const apiEndpoint = "api.fake.firebolt.io";
910

@@ -40,6 +41,25 @@ const selectDbsResponse = {
4041
rows: 2
4142
};
4243

44+
const selectOtherEngineResponse = {
45+
meta: [
46+
{
47+
name: "engine_name",
48+
type: "text"
49+
},
50+
{
51+
name: "url",
52+
type: "text"
53+
},
54+
{
55+
name: "status",
56+
type: "text"
57+
}
58+
],
59+
data: [["some_other_engine", "https://some_other_engine.com", "Running"]],
60+
rows: 1
61+
};
62+
4363
describe("database service", () => {
4464
const server = setupServer();
4565

@@ -186,6 +206,31 @@ describe("database service", () => {
186206
});
187207

188208
it("create and delete database", async () => {
209+
server.use(
210+
// Query against system engine
211+
rest.post(
212+
`https://some_system_engine.com/${QUERY_URL}`,
213+
(req, res, ctx) => {
214+
const body = (String(req.body) ?? "").toLowerCase();
215+
if (
216+
body.includes("information_schema.engines") &&
217+
body.includes("some_engine")
218+
) {
219+
return res(ctx.json(selectEngineResponse));
220+
} else if (
221+
body.includes("information_schema.engines") &&
222+
body.includes("some_other_engine")
223+
) {
224+
return res(ctx.json(selectOtherEngineResponse));
225+
} else if (body.includes("information_schema.engines")) {
226+
return res(ctx.json(selectEnginesResponse));
227+
} else {
228+
return res(ctx.json(selectDbResponse));
229+
}
230+
}
231+
)
232+
);
233+
189234
const firebolt = Firebolt({ apiEndpoint });
190235
await firebolt.connect({
191236
account: "my_account",

test/unit/v2/engine.test.ts

Lines changed: 89 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {
1414

1515
const apiEndpoint = "api.fake.firebolt.io";
1616

17-
const selectEngineResponse = {
17+
export const selectEngineResponse = {
1818
meta: [
1919
{
2020
name: "engine_name",
@@ -33,7 +33,7 @@ const selectEngineResponse = {
3333
rows: 1
3434
};
3535

36-
const selectEnginesResponse = {
36+
export const selectEnginesResponse = {
3737
meta: [
3838
{
3939
name: "engine_name",
@@ -119,6 +119,36 @@ describe("engine service", () => {
119119
expect(engine).toBeTruthy();
120120
expect(engine.endpoint).toEqual("https://some_engine.com");
121121
});
122+
123+
it("gets engine by name v2 status", async () => {
124+
// Copy
125+
const engineResponse = JSON.parse(JSON.stringify(selectEngineResponse));
126+
engineResponse.data.forEach((row: string[]) => {
127+
row[2] = "RUNNING";
128+
});
129+
server.use(
130+
rest.post(
131+
`https://some_system_engine.com/${QUERY_URL}`,
132+
(req, res, ctx) => {
133+
return res(ctx.json(engineResponse));
134+
}
135+
)
136+
);
137+
138+
const firebolt = Firebolt({ apiEndpoint });
139+
await firebolt.connect({
140+
account: "my_account",
141+
auth: {
142+
client_id: "id",
143+
client_secret: "secret"
144+
}
145+
});
146+
const resourceManager = firebolt.resourceManager;
147+
const engine = await resourceManager.engine.getByName("some_engine");
148+
expect(engine).toBeTruthy();
149+
expect(engine.endpoint).toEqual("https://some_engine.com");
150+
});
151+
122152
it("starts engine", async () => {
123153
let startEngineCalled = false;
124154
const expectedEngine = "some_engine";
@@ -256,6 +286,58 @@ describe("engine service", () => {
256286
expect(engines[1].endpoint).toEqual("https://some_other_engine.com");
257287
});
258288

289+
it("gets all engines v2 status", async () => {
290+
// Copy
291+
const engineResponse = JSON.parse(JSON.stringify(selectEnginesResponse));
292+
engineResponse.data.forEach((row: string[]) => {
293+
row[2] = "RUNNING";
294+
});
295+
server.use(
296+
rest.post(
297+
`https://some_system_engine.com/${QUERY_URL}`,
298+
(req, res, ctx) => {
299+
return res(ctx.json(engineResponse));
300+
}
301+
)
302+
);
303+
304+
const connectionOptions = {
305+
account: "my_account",
306+
auth: {
307+
client_id: "id",
308+
client_secret: "secret"
309+
}
310+
};
311+
const firebolt = Firebolt({ apiEndpoint });
312+
const connection = await firebolt.connect(connectionOptions);
313+
// Also test diffrent way of instantiating a resource manager
314+
const logger = new Logger();
315+
const httpClient = new NodeHttpClient();
316+
new Authenticator(
317+
{
318+
httpClient,
319+
logger,
320+
apiEndpoint,
321+
queryFormatter: new QueryFormatter()
322+
},
323+
connectionOptions
324+
);
325+
const resourceManager = new ResourceManager({
326+
logger,
327+
connection,
328+
apiEndpoint,
329+
httpClient
330+
});
331+
const engines = await resourceManager.engine.getAll();
332+
expect(engines).toBeTruthy();
333+
expect(engines[0].current_status_summary).toEqual(
334+
EngineStatusSummary.RUNNING
335+
);
336+
expect(engines[1].current_status_summary).toEqual(
337+
EngineStatusSummary.RUNNING
338+
);
339+
});
340+
259341
it("does not start engine that errors out", async () => {
260342
let startEngineCalled = false;
261343
const expectedEngine = "some_engine";
@@ -298,6 +380,7 @@ describe("engine service", () => {
298380
const engine = await resourceManager.engine.getByName(expectedEngine);
299381
expect(engine.start()).rejects.toThrowError(ConnectionError);
300382
});
383+
301384
it("does not start engine that has unexpected status", async () => {
302385
let startEngineCalled = false;
303386
const expectedEngine = "some_engine";
@@ -463,6 +546,7 @@ describe("engine service", () => {
463546
expect(engine).toBeTruthy();
464547
expect(engine.endpoint).toEqual("https://some_engine.com");
465548
});
549+
466550
it("create engine with environment variable", async () => {
467551
const engine_version = "20.1.1";
468552
server.use(
@@ -495,10 +579,13 @@ describe("engine service", () => {
495579

496580
delete process.env.ENGINE_NAME;
497581
});
582+
498583
it("Parses different engine statuses correctly", async () => {
499584
const statuses = ["RUNNING", "Running", "running"];
500585
for (const status of statuses) {
501586
expect(processEngineStatus(status)).toEqual(EngineStatusSummary.RUNNING);
502587
}
588+
expect(processEngineStatus(undefined)).toBe(undefined);
589+
expect(processEngineStatus("unexisting")).not.toBeTruthy();
503590
});
504591
});

0 commit comments

Comments
 (0)