Skip to content

Commit d8f3f5a

Browse files
refactor(ci, observability): move e2e charts to python
Signed-off-by: Nikita Korolev <nikita.korolev@flant.com>
1 parent 7a20dd1 commit d8f3f5a

25 files changed

Lines changed: 774 additions & 1259 deletions

.github/scripts/js/e2e/report/messenger-report.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const fs = require("fs");
1414

1515
const { listMatchingFiles } = require("./shared/fs-utils");
1616
const { REPORT_FILE_PATTERN } = require("./shared/report-model");
17-
const { renderClusterCharts } = require("./messenger/charts/chart-renderer");
17+
const { getClusterChartFiles } = require("./messenger/chart-files");
1818
const { makeThreadedReportInLoop } = require("./messenger/loop-client");
1919
const { readMessengerConfigFromEnv } = require("./messenger/config");
2020
const {
@@ -114,7 +114,7 @@ async function buildMessengerMessages({
114114
}) {
115115
const orderedReports = readReports(reportsDir, configuredClusters, core);
116116
const threadMessages = await buildThreadMessages(orderedReports, {
117-
renderClusterCharts,
117+
getClusterChartFiles,
118118
core,
119119
});
120120
return {

.github/scripts/js/e2e/report/messenger-report.test.js

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@
1313
const fs = require("fs");
1414
const path = require("path");
1515

16-
jest.mock("./messenger/charts/chart-renderer", () => ({
17-
renderClusterCharts: jest.fn().mockResolvedValue([]),
16+
jest.mock("./messenger/chart-files", () => ({
17+
getClusterChartFiles: jest.fn().mockResolvedValue([]),
1818
}));
1919

2020
const renderMessengerReport = require("./messenger-report");
21-
const { renderClusterCharts } = require("./messenger/charts/chart-renderer");
21+
const { getClusterChartFiles } = require("./messenger/chart-files");
2222
const { readMessengerConfigFromEnv } = require("./messenger/config");
2323
const { createCore, withTempDir } = require("./shared/test-utils");
2424

@@ -34,8 +34,8 @@ describe("messenger-report", () => {
3434
delete process.env.LOOP_STRICT_DELIVERY;
3535
delete process.env.LOOP_STRICT_FILE_UPLOAD;
3636
delete global.fetch;
37-
renderClusterCharts.mockReset();
38-
renderClusterCharts.mockResolvedValue([]);
37+
getClusterChartFiles.mockReset();
38+
getClusterChartFiles.mockResolvedValue([]);
3939
});
4040

4141
test("reads normalized messenger config from env", () => {
@@ -186,7 +186,7 @@ describe("messenger-report", () => {
186186
buffer: Buffer.from("png"),
187187
mimeType: "image/png",
188188
};
189-
renderClusterCharts.mockResolvedValue([chartFile]);
189+
getClusterChartFiles.mockResolvedValue([chartFile]);
190190
fs.writeFileSync(
191191
path.join(tempDir, "e2e_report_replicated.json"),
192192
JSON.stringify({
@@ -243,9 +243,11 @@ describe("messenger-report", () => {
243243
);
244244
}));
245245

246-
test("warns and surfaces a placeholder when chart rendering fails", async () =>
246+
test("warns and surfaces a placeholder when chart files are unavailable", async () =>
247247
inTempDir(async (tempDir) => {
248-
renderClusterCharts.mockRejectedValue(new Error("canvas unavailable"));
248+
getClusterChartFiles.mockRejectedValue(
249+
new Error("chart cli unavailable")
250+
);
249251
fs.writeFileSync(
250252
path.join(tempDir, "e2e_report_replicated.json"),
251253
JSON.stringify({
@@ -278,7 +280,7 @@ describe("messenger-report", () => {
278280

279281
expect(core.warning).toHaveBeenCalledWith(
280282
expect.stringContaining(
281-
"Unable to render duration charts for cluster replicated"
283+
"Unable to prepare duration chart files for cluster replicated"
282284
)
283285
);
284286
expect(result.threadMessages).toEqual([
@@ -589,7 +591,7 @@ describe("messenger-report", () => {
589591
buffer: Buffer.from("png"),
590592
mimeType: "image/png",
591593
};
592-
renderClusterCharts.mockResolvedValue([chartFile]);
594+
getClusterChartFiles.mockResolvedValue([chartFile]);
593595
fs.writeFileSync(
594596
path.join(tempDir, "e2e_report_replicated.json"),
595597
JSON.stringify({
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Copyright 2026 Flant JSC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
// Unless required by applicable law or agreed to in writing, software
8+
// distributed under the License is distributed on an "AS IS" BASIS,
9+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
// See the License for the specific language governing permissions and
11+
// limitations under the License.
12+
13+
const fs = require("fs");
14+
const path = require("path");
15+
16+
const { getReportClusterKey } = require("./model");
17+
18+
const defaultManifestPath = "tmp/messenger-charts/manifest.json";
19+
20+
function readChartManifest(manifestPath) {
21+
if (!fs.existsSync(manifestPath)) {
22+
return { clusters: {} };
23+
}
24+
25+
return JSON.parse(fs.readFileSync(manifestPath, "utf8"));
26+
}
27+
28+
function getClusterChartFiles(report) {
29+
const clusterKey = getReportClusterKey(report);
30+
if (!clusterKey) {
31+
return [];
32+
}
33+
34+
const manifestPath = process.env.CHARTS_MANIFEST || defaultManifestPath;
35+
const manifest = readChartManifest(manifestPath);
36+
const files = ((manifest.clusters || {})[clusterKey] || []).map((file) => ({
37+
name: file.name,
38+
buffer: fs.readFileSync(path.resolve(file.path)),
39+
mimeType: file.mimeType || "image/png",
40+
}));
41+
42+
return files;
43+
}
44+
45+
module.exports = {
46+
getClusterChartFiles,
47+
readChartManifest,
48+
};
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// Copyright 2026 Flant JSC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
// Unless required by applicable law or agreed to in writing, software
8+
// distributed under the License is distributed on an "AS IS" BASIS,
9+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
// See the License for the specific language governing permissions and
11+
// limitations under the License.
12+
13+
const fs = require("fs");
14+
const path = require("path");
15+
16+
const { getClusterChartFiles } = require("./chart-files");
17+
const { withTempDir } = require("../shared/test-utils");
18+
19+
describe("chart-files", () => {
20+
afterEach(() => {
21+
delete process.env.CHARTS_MANIFEST;
22+
});
23+
24+
test("returns no files when the manifest is missing", () => {
25+
expect(getClusterChartFiles({ cluster: "replicated" })).toEqual([]);
26+
});
27+
28+
test("loads chart files listed in the Python manifest", async () =>
29+
withTempDir("chart-files", async (tempDir) => {
30+
const chartPath = path.join(
31+
tempDir,
32+
"replicated-feature-duration-status.png"
33+
);
34+
const manifestPath = path.join(tempDir, "manifest.json");
35+
fs.writeFileSync(chartPath, Buffer.from("png"));
36+
fs.writeFileSync(
37+
manifestPath,
38+
JSON.stringify({
39+
clusters: {
40+
replicated: [
41+
{
42+
name: "replicated-feature-duration-status.png",
43+
path: chartPath,
44+
mimeType: "image/png",
45+
},
46+
],
47+
},
48+
})
49+
);
50+
process.env.CHARTS_MANIFEST = manifestPath;
51+
52+
const files = await getClusterChartFiles({ cluster: "replicated" });
53+
54+
expect(files.map(({ name }) => name)).toEqual([
55+
"replicated-feature-duration-status.png",
56+
]);
57+
expect(files[0].buffer).toEqual(Buffer.from("png"));
58+
expect(files[0].mimeType).toBe("image/png");
59+
}));
60+
});

.github/scripts/js/e2e/report/messenger/charts/__snapshots__/chart-config.test.js.snap

Lines changed: 0 additions & 101 deletions
This file was deleted.

.github/scripts/js/e2e/report/messenger/charts/builders/feature-duration-status.js

Lines changed: 0 additions & 76 deletions
This file was deleted.

0 commit comments

Comments
 (0)