Skip to content

Commit cc04cd0

Browse files
committed
Refactor testing
1 parent bcf0ab7 commit cc04cd0

File tree

12 files changed

+352
-285
lines changed

12 files changed

+352
-285
lines changed

Makefile

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,18 +68,20 @@ start-local: setup-local build
6868
@echo "Starting mock external processor..."
6969
@-kill $$(cat /tmp/extproc_mock.pid 2>/dev/null) 2>/dev/null || true
7070
@rm -f /tmp/extproc_mock.pid
71-
@(EPP_UPSTREAM=localhost:8080 MOCK_ROLE=EPP ./target/debug/extproc_mock 0.0.0.0:9001 >/dev/null 2>&1 & echo $$! > /tmp/extproc_mock.pid) || true
71+
@(EPP_UPSTREAM=127.0.0.1:8000 MOCK_ROLE=EPP ./target/debug/extproc_mock 0.0.0.0:9001 >/dev/null 2>&1 & echo $$! > /tmp/extproc_mock.pid) || true
7272
@sleep 1
7373
@echo "Starting echo server..."
7474
@-kill $$(cat /tmp/echo-server.pid 2>/dev/null) 2>/dev/null || true
7575
@rm -f /tmp/echo-server.pid
7676
@cd docker/echo-server && [ ! -f package.json ] && npm init -y >/dev/null 2>&1 || true
7777
@cd docker/echo-server && [ ! -d node_modules ] && npm install express >/dev/null 2>&1 || true
78-
@(cd docker/echo-server && PORT=8080 node custom-echo-server.js >/dev/null 2>&1 & echo $$! > /tmp/echo-server.pid) || true
78+
@(cd docker/echo-server && PORT=8000 node custom-echo-server.js >/dev/null 2>&1 & echo $$! > /tmp/echo-server.pid) || true
7979
@sleep 1
8080
@echo "✅ Local services started. Run 'make test-local' to run tests."
8181

8282
start-docker: setup-docker
83+
@echo "==> Generating nginx configuration for Docker..."
84+
./tests/generate-config.sh -e docker -o /tmp/nginx-docker.conf -s bbr_on_epp_on
8385
@echo "==> Starting Docker services..."
8486
docker compose -f $(DOCKER_COMPOSE_MAIN) up --build -d
8587
@echo "✅ Docker services started. Run 'make test-docker' to run tests."
@@ -93,19 +95,19 @@ start-kind: setup-kind
9395
# TEST TARGETS - Run automated tests
9496
# ============================================================================
9597

96-
test-local:
98+
test-local: start-local
9799
@echo "==> Running local tests..."
98100
@echo "Building module for NGINX version: $$(nginx -v 2>&1 | sed 's|nginx version: nginx/||')"
99101
./tests/test-config.sh
100102
@echo "✅ Local tests complete."
101103

102-
test-docker:
104+
test-docker: start-docker
103105
@echo "==> Running Docker tests..."
104106
@echo "Building module for NGINX version: $$(grep 'FROM nginx:' docker/nginx/Dockerfile | head -1 | sed 's/.*nginx://' | sed 's/-.*//')"
105107
DOCKER_ENVIRONMENT=main ./tests/test-config.sh
106108
@echo "✅ Docker tests complete."
107109

108-
test-kind:
110+
test-kind: start-kind
109111
@echo "==> Running tests against reference EPP in kind cluster..."
110112
./tests/kind-ngf/scripts/test-kind.sh
111113
@echo "✅ Kind tests complete."
@@ -137,7 +139,7 @@ clean: stop
137139
@# Clean build artifacts
138140
cargo clean
139141
@# Clean temp files
140-
rm -f /tmp/nginx-ngx-inference-*.log /tmp/nginx-ngx-inference-test.conf
142+
rm -f /tmp/nginx-ngx-inference-*.log /tmp/nginx-ngx-inference-*.conf
141143
@# Remove nginx temp directories
142144
rm -rf /tmp/nginx_client_body_temp /tmp/nginx_proxy_temp /tmp/nginx_fastcgi_temp /tmp/nginx_scgi_temp /tmp/nginx_uwsgi_temp
143145
@# Clean echo server node_modules

bin/extproc_mock.rs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,34 @@ impl ExternalProcessor for ExtProcMock {
216216
}
217217
}
218218

219+
async fn shutdown_signal() {
220+
let ctrl_c = async {
221+
tokio::signal::ctrl_c()
222+
.await
223+
.expect("failed to install Ctrl+C handler");
224+
};
225+
226+
#[cfg(unix)]
227+
let terminate = async {
228+
tokio::signal::unix::signal(tokio::signal::unix::SignalKind::terminate())
229+
.expect("failed to install signal handler")
230+
.recv()
231+
.await;
232+
};
233+
234+
#[cfg(not(unix))]
235+
let terminate = std::future::pending::<()>();
236+
237+
tokio::select! {
238+
_ = ctrl_c => {
239+
eprintln!("extproc_mock: received SIGINT, shutting down gracefully...");
240+
},
241+
_ = terminate => {
242+
eprintln!("extproc_mock: received SIGTERM, shutting down gracefully...");
243+
},
244+
}
245+
}
246+
219247
#[tokio::main(flavor = "multi_thread")]
220248
async fn main() -> Result<(), Box<dyn std::error::Error>> {
221249
let addr: SocketAddr = std::env::args()
@@ -246,9 +274,12 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
246274
};
247275

248276
println!("extproc_mock listening on {}", addr);
277+
249278
tonic::transport::Server::builder()
250279
.add_service(ExternalProcessorServer::new(svc))
251-
.serve(addr)
280+
.serve_with_shutdown(addr, shutdown_signal())
252281
.await?;
282+
283+
eprintln!("extproc_mock: shutdown complete");
253284
Ok(())
254285
}

docker/echo-server/custom-echo-server.js

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,30 @@ app.use('/', (req, res) => {
3636
res.json(response);
3737
});
3838

39-
app.listen(port, '0.0.0.0', () => {
39+
const server = app.listen(port, '0.0.0.0', () => {
4040
console.log(`Custom echo server listening on port ${port} with 50MB body limit`);
41-
});
41+
});
42+
43+
// Graceful shutdown handler
44+
const gracefulShutdown = (signal) => {
45+
console.log(`\n${signal} received. Starting graceful shutdown...`);
46+
47+
server.close((err) => {
48+
if (err) {
49+
console.error('Error during shutdown:', err);
50+
process.exit(1);
51+
}
52+
console.log('Echo server closed successfully');
53+
process.exit(0);
54+
});
55+
56+
// Force shutdown after 5 seconds if graceful shutdown takes too long
57+
setTimeout(() => {
58+
console.error('Forcing shutdown after timeout');
59+
process.exit(1);
60+
}, 5000);
61+
};
62+
63+
// Listen for termination signals
64+
process.on('SIGTERM', () => gracefulShutdown('SIGTERM'));
65+
process.on('SIGINT', () => gracefulShutdown('SIGINT'));

docker/nginx/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ FROM rust:1.91-alpine3.22 AS builder
1010
WORKDIR /work
1111

1212
# Install build dependencies for Alpine (NGINX requirements)
13-
RUN apk add --no-cache \
13+
RUN apk add \
1414
clang-dev \
1515
pcre2-dev \
1616
openssl-dev \

docker/nginx/nginx-test.conf

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

tests/docker-compose.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ services:
66
context: ..
77
container_name: ngx-inference-nginx
88
ports:
9-
- "8081:80"
9+
- "8081:8081"
1010
depends_on:
1111
- mock-epp
1212
- echo-server
1313
volumes:
14-
- ../docker/nginx/nginx-test.conf:/etc/nginx/nginx.conf:ro
14+
- /tmp/nginx-docker.conf:/etc/nginx/nginx.conf:ro
1515

1616
# Mock External Processor for EPP (Endpoint Picker Processor) listening on :9001
1717
mock-epp:

tests/generate-config.sh

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ if [[ "$ENVIRONMENT" != "local" && "$ENVIRONMENT" != "docker" && "$ENVIRONMENT"
9090
exit 1
9191
fi
9292

93-
# Set module path and endpoints based on environment
93+
# Set module path, endpoints, and ports based on environment
9494
if [[ "$ENVIRONMENT" == "local" ]]; then
9595
if [[ "$(uname)" == "Darwin" ]]; then
9696
MODULE_PATH="$PROJECT_ROOT/target/debug/libngx_inference.dylib"
@@ -99,10 +99,11 @@ if [[ "$ENVIRONMENT" == "local" ]]; then
9999
MODULE_PATH="$PROJECT_ROOT/target/debug/libngx_inference.so"
100100
MIMETYPES_PATH="/etc/nginx/mime.types"
101101
fi
102-
UPSTREAM_HOST="localhost:8080"
103-
EPP_HOST="localhost:9001"
102+
UPSTREAM_HOST="127.0.0.1:8000"
103+
EPP_HOST="127.0.0.1:9001"
104104
ERROR_LOG="/tmp/nginx-ngx-inference-error.log"
105105
ACCESS_LOG="/tmp/nginx-ngx-inference-access.log"
106+
NGINX_PORT="8080"
106107
elif [[ "$ENVIRONMENT" == "kind" ]]; then
107108
MODULE_PATH="/usr/lib/nginx/modules/libngx_inference.so"
108109
MIMETYPES_PATH="/etc/nginx/mime.types"
@@ -114,13 +115,16 @@ elif [[ "$ENVIRONMENT" == "kind" ]]; then
114115
# In Kubernetes, log to stdout/stderr for kubectl logs to work
115116
ERROR_LOG="/dev/stderr"
116117
ACCESS_LOG="/dev/stdout"
118+
NGINX_PORT="8082"
117119
elif [[ "$ENVIRONMENT" == "docker" ]]; then
118120
MODULE_PATH="/usr/lib/nginx/modules/libngx_inference.so"
119121
MIMETYPES_PATH="/etc/nginx/mime.types"
120122
UPSTREAM_HOST="echo-server:80"
121123
EPP_HOST="mock-epp:9001"
122-
ERROR_LOG="/tmp/nginx-ngx-inference-error.log"
123-
ACCESS_LOG="/tmp/nginx-ngx-inference-access.log"
124+
# In Docker, log to stdout/stderr for docker logs to work
125+
ERROR_LOG="/dev/stderr"
126+
ACCESS_LOG="/dev/stdout"
127+
NGINX_PORT="8081"
124128
else
125129
# Default/fallback configuration
126130
MODULE_PATH="/usr/lib/nginx/modules/libngx_inference.so"
@@ -158,13 +162,17 @@ if [[ -n "$SERVER_CONFIG" ]]; then
158162
if [[ "$ENVIRONMENT" == "kind" ]]; then
159163
# In Kubernetes, use the kube-dns service IP
160164
RESOLVER="10.96.0.10"
165+
elif [[ "$ENVIRONMENT" == "docker" ]]; then
166+
# In Docker, use Docker's internal DNS server
167+
RESOLVER="127.0.0.11"
161168
else
162-
# For local/docker, use system resolver, filtering out invalid IPv6 addresses
169+
# For local, use system resolver, filtering out invalid IPv6 addresses
163170
RESOLVER=$(grep '^nameserver' /etc/resolv.conf | grep -v '^nameserver fe80::' | awk '{print $2}' | head -1 || echo "8.8.8.8")
164171
fi
165172

166-
# Read server config and replace references with environment-specific hosts
173+
# Read server config and replace references with environment-specific hosts and port
167174
SERVER_CONFIG_CONTENT=$(cat "$SERVER_CONFIG_FILE" | \
175+
sed "s|listen 8081;|listen $NGINX_PORT;|g" | \
168176
sed "s|http://localhost:8080|http://$UPSTREAM_HOST|g" | \
169177
sed "s|\"localhost:8080\"|\"$UPSTREAM_HOST\"|g" | \
170178
sed "s|\"127.0.0.1:8080\"|\"$UPSTREAM_HOST\"|g" | \

0 commit comments

Comments
 (0)