Skip to content
This repository was archived by the owner on Apr 13, 2020. It is now read-only.

Commit d1862fc

Browse files
authored
Default Routing for isDefault Ring (#427)
- When a ring is marked as `isDefault: true`, `spk hld reconcile` will now generate an additional IngressRoute and Middleware. - The IngressRoute will not have a `Ring` route match rule - The IngressRoute points to the same backend service as its ringed counterpart. - Only one ring can be marked `isDefault: true` -- validation is run at `spk hld reconcile` execute time, throwing an error if more than one `isDefault`. - Refactored IngressRoute tests - Added compatibility configuration for eslint and prettier. closes microsoft/bedrock#1084
1 parent a7c2ce4 commit d1862fc

12 files changed

+634
-252
lines changed

jest.config.js

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
module.exports = {
2-
preset: 'ts-jest',
3-
testEnvironment: 'node',
4-
};
2+
preset: "ts-jest",
3+
testEnvironment: "node",
4+
rootDir: "src"
5+
};
+151
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
import * as fs from "fs";
2+
import * as mocks from "../../test/mockFactory";
3+
import { BedrockFile } from "../../types";
4+
import * as reconcile from "./reconcile";
5+
6+
jest.mock("fs");
7+
8+
beforeEach(() => {
9+
jest.resetAllMocks();
10+
});
11+
12+
describe("createMiddlewareForRing", () => {
13+
const tests: {
14+
name: string;
15+
actual: () => unknown;
16+
expected: unknown;
17+
effects?: (() => void)[];
18+
}[] = [
19+
{
20+
name: "isDefault === false; creates one (1) middleware",
21+
actual: (): unknown =>
22+
reconcile.createMiddlewareForRing(
23+
"path-to-ring",
24+
"my-service",
25+
"my-ring",
26+
"v1",
27+
false
28+
),
29+
expected: { ringed: expect.anything(), default: undefined },
30+
effects: [
31+
(): void => {
32+
expect(fs.writeFileSync).toHaveBeenCalledTimes(1);
33+
expect(fs.writeFileSync).toHaveBeenCalledWith(
34+
expect.anything(),
35+
expect.not.stringContaining("\n---\n")
36+
);
37+
},
38+
],
39+
},
40+
41+
{
42+
name: "isDefault === true; creates two (2) middleware",
43+
actual: (): unknown =>
44+
reconcile.createMiddlewareForRing(
45+
"path-to-ring",
46+
"my-service",
47+
"my-ring",
48+
"v1",
49+
true
50+
),
51+
expected: {
52+
ringed: expect.objectContaining({
53+
metadata: { name: "my-service-my-ring" },
54+
}),
55+
default: expect.objectContaining({ metadata: { name: "my-service" } }),
56+
},
57+
effects: [
58+
(): void => {
59+
expect(fs.writeFileSync).toHaveBeenCalledTimes(1);
60+
expect(fs.writeFileSync).toHaveBeenCalledWith(
61+
expect.anything(),
62+
expect.stringContaining("\n---\n")
63+
);
64+
},
65+
],
66+
},
67+
];
68+
69+
for (const { name, actual, expected, effects } of tests) {
70+
it(name, () => {
71+
expect(actual()).toStrictEqual(expected);
72+
for (const effect of effects ?? []) {
73+
effect();
74+
}
75+
});
76+
}
77+
});
78+
79+
describe("createIngressRouteForRing", () => {
80+
const { services } = mocks.createTestBedrockYaml(false) as BedrockFile;
81+
const tests: {
82+
name: string;
83+
actual: () => unknown;
84+
expected: unknown;
85+
effects?: (() => void)[];
86+
}[] = [
87+
{
88+
name: "isDefault === false; creates one (1) IngressRoute",
89+
actual: (): unknown =>
90+
reconcile.createIngressRouteForRing(
91+
"path-to-ring",
92+
"my-service",
93+
Object.values(services)[0],
94+
{ ringed: { metadata: { name: "my-service-my-ring" } } },
95+
"my-ring",
96+
"version-path",
97+
false
98+
),
99+
expected: [
100+
expect.objectContaining({ metadata: { name: "my-service-my-ring" } }),
101+
],
102+
effects: [
103+
(): void => {
104+
// Should write out one yaml document (no "---")
105+
expect(fs.writeFileSync).toHaveBeenCalledTimes(1);
106+
expect(fs.writeFileSync).toHaveBeenCalledWith(
107+
expect.anything(),
108+
expect.not.stringContaining("\n---\n")
109+
);
110+
},
111+
],
112+
},
113+
114+
{
115+
name: "isDefault === true; creates two (2) IngressRoute",
116+
actual: (): unknown =>
117+
reconcile.createIngressRouteForRing(
118+
"foo",
119+
"my-service",
120+
Object.values(services)[0],
121+
{ ringed: { metadata: { name: "my-service-my-ring" } } },
122+
"my-ring",
123+
"version-path",
124+
true
125+
),
126+
expected: [
127+
expect.objectContaining({ metadata: { name: "my-service-my-ring" } }),
128+
expect.objectContaining({ metadata: { name: "my-service" } }),
129+
],
130+
effects: [
131+
(): void => {
132+
// Should write out two yaml documents (with "---")
133+
expect(fs.writeFileSync).toHaveBeenCalledTimes(1);
134+
expect(fs.writeFileSync).toHaveBeenCalledWith(
135+
expect.anything(),
136+
expect.stringContaining("\n---\n")
137+
);
138+
},
139+
],
140+
},
141+
];
142+
143+
for (const { name, actual, expected, effects } of tests) {
144+
it(name, () => {
145+
expect(actual()).toStrictEqual(expected);
146+
for (const effect of effects ?? []) {
147+
effect();
148+
}
149+
});
150+
}
151+
});

src/commands/hld/reconcile.test.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import path from "path";
22
import { create as createBedrockYaml } from "../../lib/bedrockYaml";
33
import { disableVerboseLogging, enableVerboseLogging } from "../../logger";
44
import { BedrockFile, BedrockServiceConfig } from "../../types";
5+
import * as reconcile from "./reconcile";
56
import {
67
addChartToRing,
78
checkForFabrikate,
@@ -14,13 +15,12 @@ import {
1415
execAndLog,
1516
execute,
1617
getFullPathPrefix,
17-
ReconcileDependencies,
1818
normalizedName,
19+
ReconcileDependencies,
1920
reconcileHld,
2021
testAndGetAbsPath,
2122
validateInputs,
2223
} from "./reconcile";
23-
import * as reconcile from "./reconcile";
2424

2525
beforeAll(() => {
2626
enableVerboseLogging();

0 commit comments

Comments
 (0)