Skip to content

Commit 3c4b5e7

Browse files
committed
FIX: Integration Tests and add cleanup job for hetzner resources
1 parent 7f71365 commit 3c4b5e7

File tree

8 files changed

+122
-17
lines changed

8 files changed

+122
-17
lines changed

.github/workflows/test-integration.yml

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
- uses: actions/checkout@v5
1818
- uses: actions/setup-node@v4
1919
with:
20-
node-version: "19"
20+
node-version: 24
2121
- run: npm install
2222
working-directory: ./launcher
2323
- id: get-import-tests
@@ -47,7 +47,7 @@ jobs:
4747
- uses: actions/checkout@v5
4848
- uses: actions/setup-node@v4
4949
with:
50-
node-version: "19"
50+
node-version: 24
5151
- run: npm install
5252
working-directory: ./launcher
5353
- run: npm run test ${{ matrix.test.name }}
@@ -69,7 +69,7 @@ jobs:
6969
- uses: actions/checkout@v5
7070
- uses: actions/setup-node@v4
7171
with:
72-
node-version: "19"
72+
node-version: 24
7373
- run: npm install
7474
working-directory: ./launcher
7575
- run: npm run test ${{ matrix.test.name }}
@@ -90,11 +90,32 @@ jobs:
9090
- uses: actions/checkout@v5
9191
- uses: actions/setup-node@v4
9292
with:
93-
node-version: "19"
93+
node-version: 24
9494
- run: npm install
9595
working-directory: ./launcher
9696
- run: npm run test ${{ matrix.test.name }}
9797
working-directory: ./launcher
9898
env:
9999
HCLOUD_TOKEN: ${{ secrets.HCLOUD_TOKEN }}
100100
IS_DEV: "true"
101+
102+
Cleanup:
103+
runs-on: ubuntu-22.04
104+
name: Cleanup
105+
needs:
106+
- Validator-Import-test
107+
- Execution-Client-test
108+
- Other-Integration-test
109+
if: ${{ always() }} # run even if dependencies failed or were cancelled
110+
steps:
111+
- uses: actions/checkout@v5
112+
- uses: actions/setup-node@v4
113+
with:
114+
node-version: 24
115+
- run: npm install
116+
working-directory: ./launcher
117+
- run: npm run test:cleanup
118+
working-directory: ./launcher
119+
env:
120+
HCLOUD_TOKEN: ${{ secrets.HCLOUD_TOKEN }}
121+
IS_DEV: "true"

launcher/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
"test:other": "jest --silent --testPathPattern 'tests/(?!.*Service).*\\.int\\.js$'",
2525
"test:beacon": "jest --silent --testPathPattern 'tests/(?=.*BeaconService).*\\.int\\.js$'",
2626
"test:service": "jest --silent --testPathPattern 'tests/(?=.*Service)(?!.*Beacon).*\\.int\\.js$'",
27+
"test:cleanup": "node src/backend/tests/integration/Cleanup.js",
2728
"watch:css": "npx tailwindcss -i ./src/main.css -o ./public/output.css --watch",
2829
"lint:fix": "eslint src --fix",
2930
"stereum": "concurrently \"npm:electron:serve\" \"npm:watch:css\"",
@@ -111,4 +112,4 @@
111112
"type": "git",
112113
"url": "git@github.com:stereum-dev/ethereum-node.git"
113114
}
114-
}
115+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import axios from "axios";
2+
3+
async function cleanup() {
4+
const apiToken = process.env.HCLOUD_TOKEN;
5+
if (!apiToken) {
6+
console.error("HCLOUD_TOKEN environment variable is not set.");
7+
return;
8+
}
9+
10+
const config = {
11+
headers: {
12+
Authorization: `Bearer ${apiToken}`,
13+
},
14+
};
15+
16+
// Cleanup servers with names containing "integration-test"
17+
try {
18+
const response = await axios.get("https://api.hetzner.cloud/v1/servers", config);
19+
const servers = response.data.servers;
20+
let currentPage = response.data.meta.pagination.page + 1;
21+
const lastPage = response.data.meta.pagination.last_page;
22+
23+
while (currentPage <= lastPage) {
24+
const pagedResponse = await axios.get(`https://api.hetzner.cloud/v1/servers?page=${currentPage}`, config);
25+
servers.push(...pagedResponse.data.servers);
26+
currentPage++;
27+
}
28+
29+
const integrationTestServers = servers.filter((server) => server.name.includes("integration-test"));
30+
31+
for (const server of integrationTestServers) {
32+
try {
33+
await axios.delete(`https://api.hetzner.cloud/v1/servers/${server.id}`, config);
34+
console.log(`Deleted server: ${server.name} (ID: ${server.id})`);
35+
} catch (deleteError) {
36+
console.error(`Failed to delete server: ${server.name} (ID: ${server.id})`, deleteError);
37+
}
38+
}
39+
40+
if (integrationTestServers.length === 0) {
41+
console.log("No integration-test servers found.");
42+
}
43+
} catch (error) {
44+
console.error("Error fetching servers:", error);
45+
}
46+
47+
// Cleanup SSH keys with names containing "integration-test"
48+
try {
49+
const response = await axios.get("https://api.hetzner.cloud/v1/ssh_keys", config);
50+
const sshKeys = response.data.ssh_keys;
51+
let currentPage = response.data.meta.pagination.page + 1;
52+
const lastPage = response.data.meta.pagination.last_page;
53+
54+
while (currentPage <= lastPage) {
55+
const pagedResponse = await axios.get(`https://api.hetzner.cloud/v1/ssh_keys?page=${currentPage}`, config);
56+
sshKeys.push(...pagedResponse.data.ssh_keys);
57+
currentPage++;
58+
}
59+
60+
const integrationTestKeys = sshKeys.filter((key) => key.name.includes("integration-test"));
61+
62+
for (const key of integrationTestKeys) {
63+
try {
64+
await axios.delete(`https://api.hetzner.cloud/v1/ssh_keys/${key.id}`, config);
65+
console.log(`Deleted SSH key: ${key.name} (ID: ${key.id})`);
66+
} catch (deleteError) {
67+
console.error(`Failed to delete SSH key: ${key.name} (ID: ${key.id})`, deleteError);
68+
}
69+
}
70+
71+
if (integrationTestKeys.length === 0) {
72+
console.log("No integration-test SSH keys found.");
73+
}
74+
} catch (error) {
75+
console.error("Error fetching SSH keys:", error);
76+
}
77+
}
78+
79+
cleanup();

launcher/src/backend/tests/integration/L2GethService.int.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ jest.setTimeout(500000);
1111

1212
test("l2geth installation", async () => {
1313
const testServer = new HetznerServer();
14-
const keyResponse = await testServer.createSSHKey("L2Geth--integration-test--ubuntu-2204");
14+
const keyResponse = await testServer.createSSHKey("Layer2-Geth--integration-test--ubuntu-2204");
1515

1616
const serverSettings = {
17-
name: "L2Geth--integration-test--ubuntu-2204",
17+
name: "Layer2-Geth--integration-test--ubuntu-2204",
1818
image: "ubuntu-22.04",
1919
server_type: "cpx21",
2020
start_after_create: true,

launcher/src/backend/tests/integration/NethermindService.int.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,11 @@ test("nethermind installationm", async () => {
7272
await testServer.Sleep(30000);
7373
status = await nodeConnection.sshService.exec(`docker logs stereum-${executionClient.id}`);
7474
if (
75-
/Nethermind initialization completed/.test(status.stdout) &&
75+
/Initialization Completed/.test(status.stdout) &&
7676
/Peers/.test(status.stdout) &&
77-
/http:\/\/0\.0\.0\.0:8545 ; http:\/\/0\.0\.0\.0:8546 ; http:\/\/0\.0\.0\.0:8551/.test(status.stdout)
77+
/http:\/\/0\.0\.0\.0:8545/.test(status.stdout) &&
78+
/http:\/\/0\.0\.0\.0:8546/.test(status.stdout) &&
79+
/http:\/\/0\.0\.0\.0:8551/.test(status.stdout)
7880
) {
7981
condition = true;
8082
}
@@ -98,7 +100,9 @@ test("nethermind installationm", async () => {
98100
expect((docker.stdout.match(new RegExp("Up", "g")) || []).length).toBe(1);
99101
}
100102

101-
expect(status.stdout).toMatch(/Nethermind initialization completed/);
103+
expect(status.stdout).toMatch(/Initialization Completed/);
102104
expect(status.stdout).toMatch(/Peers/);
103-
expect(status.stdout).toMatch(/http:\/\/0\.0\.0\.0:8545 ; http:\/\/0\.0\.0\.0:8546 ; http:\/\/0\.0\.0\.0:8551/);
105+
expect(status.stdout).toMatch(/http:\/\/0\.0\.0\.0:8545/);
106+
expect(status.stdout).toMatch(/http:\/\/0\.0\.0\.0:8546/);
107+
expect(status.stdout).toMatch(/http:\/\/0\.0\.0\.0:8551/);
104108
});

launcher/src/backend/tests/integration/OpErigonService.int.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ jest.setTimeout(1200000);
1111

1212
test("op-erigon installation", async () => {
1313
const testServer = new HetznerServer();
14-
const keyResponse = await testServer.createSSHKey("OpErigon--integration-test--ubuntu-2204");
14+
const keyResponse = await testServer.createSSHKey("Optimism-Erigon--integration-test--ubuntu-2204");
1515

1616
const serverSettings = {
17-
name: "OpErigon--integration-test--ubuntu-2204",
17+
name: "Optimism-Erigon--integration-test--ubuntu-2204",
1818
image: "ubuntu-22.04",
1919
server_type: "cpx21",
2020
start_after_create: true,

launcher/src/backend/tests/integration/OpGethService.int.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ jest.setTimeout(500000);
1111

1212
test("op-geth installation", async () => {
1313
const testServer = new HetznerServer();
14-
const keyResponse = await testServer.createSSHKey("OpGeth--integration-test--ubuntu-2204");
14+
const keyResponse = await testServer.createSSHKey("Optimism-Geth--integration-test--ubuntu-2204");
1515

1616
const serverSettings = {
17-
name: "OpGeth--integration-test--ubuntu-2204",
17+
name: "Optimism-Geth--integration-test--ubuntu-2204",
1818
image: "ubuntu-22.04",
1919
server_type: "cpx21",
2020
start_after_create: true,

launcher/src/backend/tests/integration/OpRethService.int.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ jest.setTimeout(500000);
1111

1212
test("op-reth installation", async () => {
1313
const testServer = new HetznerServer();
14-
const keyResponse = await testServer.createSSHKey("OpReth--integration-test--ubuntu-2204");
14+
const keyResponse = await testServer.createSSHKey("Optimism-Reth--integration-test--ubuntu-2204");
1515

1616
const serverSettings = {
17-
name: "OpReth--integration-test--ubuntu-2204",
17+
name: "Optimism-Reth--integration-test--ubuntu-2204",
1818
image: "ubuntu-22.04",
1919
server_type: "cpx21",
2020
start_after_create: true,

0 commit comments

Comments
 (0)