Skip to content

Commit 53e27e2

Browse files
committed
fix: improve e2e test cleanup and reliability
- Add cleanup function with trap for EXIT/INT/TERM signals in shell script - Pre-compile before spawning nodes to avoid build lock contention - Kill orphan concord_e2e processes at test start and exit - Add --no-compile flag to spawned nodes - Start telemetry apps on spawned nodes to avoid handler warnings - Improve error messages when node is not distributed - Add try/catch and pkill fallback in stop_cluster/1
1 parent bfbef22 commit 53e27e2

File tree

3 files changed

+68
-12
lines changed

3 files changed

+68
-12
lines changed

e2e_test/support/e2e_cluster_helper.ex

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,10 @@ defmodule Concord.E2E.ClusterHelper do
100100

101101
# Load Concord application code (but don't start it - we'll manually start Ra servers)
102102
:rpc.call(node, Application, :load, [:concord])
103+
104+
# Start telemetry apps to avoid handler warnings
105+
:rpc.call(node, Application, :ensure_all_started, [:telemetry])
106+
:rpc.call(node, Application, :ensure_all_started, [:telemetry_poller])
103107
end)
104108

105109
# Initialize Ra cluster on all nodes with full member list
@@ -128,13 +132,20 @@ defmodule Concord.E2E.ClusterHelper do
128132
# Check if port is still open before closing to avoid errors
129133
Enum.each(ports, fn port ->
130134
if Port.info(port) != nil do
131-
Port.close(port)
135+
try do
136+
Port.close(port)
137+
catch
138+
_, _ -> :ok
139+
end
132140
end
133141
end)
134142

135143
# Give time for graceful shutdown
136144
Process.sleep(500)
137145

146+
# Force kill any remaining processes
147+
System.cmd("pkill", ["-9", "-f", "concord_e2e"], stderr_to_stdout: true)
148+
138149
# Clean up data directories
139150
cleanup_data_dirs()
140151

@@ -278,7 +289,8 @@ defmodule Concord.E2E.ClusterHelper do
278289
"-S",
279290
"mix",
280291
"run",
281-
"--no-start"
292+
"--no-start",
293+
"--no-compile"
282294
]
283295

284296
# Spawn the node as a separate OS process

e2e_test/test_helper.exs

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,39 @@
1+
# Clean up orphan processes from previous runs
2+
defmodule Concord.E2E.Cleanup do
3+
def kill_orphans do
4+
IO.puts("Cleaning up orphan e2e processes...")
5+
System.cmd("pkill", ["-9", "-f", "concord_e2e"], stderr_to_stdout: true)
6+
Process.sleep(500)
7+
end
8+
end
9+
10+
Concord.E2E.Cleanup.kill_orphans()
11+
112
# Ensure the test runner node is alive (distributed Erlang)
213
# This should be handled by the mix alias passing --name flag
314
case Node.alive?() do
415
true ->
5-
IO.puts("✓ Test runner node is alive: #{Node.self()}")
16+
IO.puts("✓ Test runner node: #{Node.self()}")
617
IO.puts("✓ Cookie: #{Node.get_cookie()}")
718

819
false ->
920
IO.puts("""
10-
✗ Error: Test runner node is not alive!
11-
12-
E2E tests require distributed Erlang to spawn cluster nodes.
13-
The mix alias should handle this automatically.
14-
15-
If running manually, use:
16-
MIX_ENV=e2e_test elixir --name test@127.0.0.1 --cookie test_cookie -S mix test e2e_test/
21+
╔════════════════════════════════════════════════════════════════════════════╗
22+
║ ERROR: Test runner node is not distributed! ║
23+
╠════════════════════════════════════════════════════════════════════════════╣
24+
║ ║
25+
║ E2E tests require distributed Erlang to spawn cluster nodes. ║
26+
║ ║
27+
║ Use one of these methods: ║
28+
║ ║
29+
║ 1. mix test.e2e (recommended) ║
30+
║ 2. ./scripts/run_e2e_tests.sh e2e_test/ ║
31+
║ ║
32+
║ Manual invocation: ║
33+
║ MIX_ENV=e2e_test elixir --name test@127.0.0.1 --cookie test_cookie \\
34+
║ -S mix test e2e_test/ ║
35+
║ ║
36+
╚════════════════════════════════════════════════════════════════════════════╝
1737
""")
1838

1939
System.halt(1)
@@ -22,6 +42,12 @@ end
2242
# Start required applications
2343
{:ok, _} = Application.ensure_all_started(:telemetry)
2444

45+
# Register cleanup on exit
46+
System.at_exit(fn _ ->
47+
IO.puts("\nCleaning up e2e processes on exit...")
48+
System.cmd("pkill", ["-9", "-f", "concord_e2e"], stderr_to_stdout: true)
49+
end)
50+
2551
# Start ExUnit with specific configuration for e2e tests
2652
ExUnit.start(
2753
exclude: [:skip],

scripts/run_e2e_tests.sh

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,29 @@ RED='\033[0;31m'
1010
YELLOW='\033[1;33m'
1111
NC='\033[0m' # No Color
1212

13-
echo -e "${YELLOW}=== Starting E2E Test Suite ===${NC}"
14-
1513
# Set MIX_ENV
1614
export MIX_ENV=e2e_test
1715

16+
# Function to clean up orphan processes
17+
cleanup() {
18+
echo -e "\n${YELLOW}Cleaning up e2e processes...${NC}"
19+
pkill -9 -f "concord_e2e" 2>/dev/null || true
20+
rm -rf ./data/e2e_test 2>/dev/null || true
21+
}
22+
23+
# Trap to ensure cleanup on exit/interrupt
24+
trap cleanup EXIT INT TERM
25+
26+
# Clean up orphans before starting
27+
cleanup
28+
sleep 1
29+
30+
echo -e "${YELLOW}=== Starting E2E Test Suite ===${NC}"
31+
32+
# Pre-compile to avoid build lock contention
33+
echo -e "${YELLOW}Pre-compiling...${NC}"
34+
mix compile --force
35+
1836
# Parse arguments
1937
TEST_PATH="${1:-e2e_test/}"
2038
NODE_NAME="${NODE_NAME:-test@127.0.0.1}"

0 commit comments

Comments
 (0)