|
| 1 | +#!/usr/bin/env bash |
| 2 | +# Smoke test for mux npm package |
| 3 | +# Tests that the package can be installed and the server starts correctly |
| 4 | + |
| 5 | +set -euo pipefail |
| 6 | + |
| 7 | +# Colors for output |
| 8 | +RED='\033[0;31m' |
| 9 | +GREEN='\033[0;32m' |
| 10 | +YELLOW='\033[1;33m' |
| 11 | +NC='\033[0m' # No Color |
| 12 | + |
| 13 | +# Logging functions |
| 14 | +log_info() { |
| 15 | + echo -e "${GREEN}[INFO]${NC} $*" |
| 16 | +} |
| 17 | + |
| 18 | +log_error() { |
| 19 | + echo -e "${RED}[ERROR]${NC} $*" >&2 |
| 20 | +} |
| 21 | + |
| 22 | +log_warning() { |
| 23 | + echo -e "${YELLOW}[WARNING]${NC} $*" |
| 24 | +} |
| 25 | + |
| 26 | +# Cleanup function |
| 27 | +cleanup() { |
| 28 | + local exit_code=$? |
| 29 | + log_info "Cleaning up..." |
| 30 | + |
| 31 | + # Kill server if it's running |
| 32 | + if [[ -n "${SERVER_PID:-}" ]] && kill -0 "$SERVER_PID" 2>/dev/null; then |
| 33 | + log_info "Stopping server (PID: $SERVER_PID)..." |
| 34 | + kill "$SERVER_PID" 2>/dev/null || true |
| 35 | + wait "$SERVER_PID" 2>/dev/null || true |
| 36 | + fi |
| 37 | + |
| 38 | + # Remove test directory |
| 39 | + if [[ -n "${TEST_DIR:-}" ]] && [[ -d "$TEST_DIR" ]]; then |
| 40 | + log_info "Removing test directory: $TEST_DIR" |
| 41 | + rm -rf "$TEST_DIR" |
| 42 | + fi |
| 43 | + |
| 44 | + if [[ $exit_code -eq 0 ]]; then |
| 45 | + log_info "✅ Smoke test completed successfully" |
| 46 | + else |
| 47 | + log_error "❌ Smoke test failed with exit code $exit_code" |
| 48 | + fi |
| 49 | + |
| 50 | + exit $exit_code |
| 51 | +} |
| 52 | + |
| 53 | +trap cleanup EXIT INT TERM |
| 54 | + |
| 55 | +# Configuration |
| 56 | +PACKAGE_TARBALL="${PACKAGE_TARBALL:-}" |
| 57 | +SERVER_PORT="${SERVER_PORT:-3000}" |
| 58 | +SERVER_HOST="${SERVER_HOST:-localhost}" |
| 59 | +STARTUP_TIMEOUT="${STARTUP_TIMEOUT:-30}" |
| 60 | +HEALTHCHECK_TIMEOUT="${HEALTHCHECK_TIMEOUT:-10}" |
| 61 | + |
| 62 | +# Validate required arguments |
| 63 | +if [[ -z "$PACKAGE_TARBALL" ]]; then |
| 64 | + log_error "PACKAGE_TARBALL environment variable must be set" |
| 65 | + log_error "Usage: PACKAGE_TARBALL=/path/to/package.tgz $0" |
| 66 | + exit 1 |
| 67 | +fi |
| 68 | + |
| 69 | +if [[ ! -f "$PACKAGE_TARBALL" ]]; then |
| 70 | + log_error "Package tarball not found: $PACKAGE_TARBALL" |
| 71 | + exit 1 |
| 72 | +fi |
| 73 | + |
| 74 | +# Convert to absolute path before changing directories |
| 75 | +PACKAGE_TARBALL=$(realpath "$PACKAGE_TARBALL") |
| 76 | + |
| 77 | +log_info "Starting smoke test for package: $PACKAGE_TARBALL" |
| 78 | + |
| 79 | +# Create temporary test directory |
| 80 | +TEST_DIR=$(mktemp -d) |
| 81 | +log_info "Created test directory: $TEST_DIR" |
| 82 | + |
| 83 | +cd "$TEST_DIR" |
| 84 | + |
| 85 | +# Initialize a minimal package.json to avoid npm warnings |
| 86 | +cat >package.json <<EOF |
| 87 | +{ |
| 88 | + "name": "mux-smoke-test", |
| 89 | + "version": "1.0.0", |
| 90 | + "private": true |
| 91 | +} |
| 92 | +EOF |
| 93 | + |
| 94 | +# Install the package |
| 95 | +log_info "Installing package..." |
| 96 | +if ! npm install --no-save "$PACKAGE_TARBALL"; then |
| 97 | + log_error "Failed to install package" |
| 98 | + exit 1 |
| 99 | +fi |
| 100 | + |
| 101 | +log_info "✅ Package installed successfully" |
| 102 | + |
| 103 | +# Verify the binary is available |
| 104 | +if [[ ! -f "node_modules/.bin/mux" ]]; then |
| 105 | + log_error "mux binary not found in node_modules/.bin/" |
| 106 | + exit 1 |
| 107 | +fi |
| 108 | + |
| 109 | +log_info "✅ mux binary found" |
| 110 | + |
| 111 | +# Start the server in background |
| 112 | +log_info "Starting mux server on $SERVER_HOST:$SERVER_PORT..." |
| 113 | +node_modules/.bin/mux server --host "$SERVER_HOST" --port "$SERVER_PORT" >server.log 2>&1 & |
| 114 | +SERVER_PID=$! |
| 115 | + |
| 116 | +log_info "Server started with PID: $SERVER_PID" |
| 117 | + |
| 118 | +# Wait for server to start |
| 119 | +log_info "Waiting for server to start (timeout: ${STARTUP_TIMEOUT}s)..." |
| 120 | +ELAPSED=0 |
| 121 | +while [[ $ELAPSED -lt $STARTUP_TIMEOUT ]]; do |
| 122 | + if ! kill -0 "$SERVER_PID" 2>/dev/null; then |
| 123 | + log_error "Server process died unexpectedly" |
| 124 | + log_error "Server log:" |
| 125 | + cat server.log |
| 126 | + exit 1 |
| 127 | + fi |
| 128 | + |
| 129 | + # Try to connect to the server |
| 130 | + if curl -sf "http://${SERVER_HOST}:${SERVER_PORT}/health" >/dev/null 2>&1; then |
| 131 | + log_info "✅ Server is responding" |
| 132 | + break |
| 133 | + fi |
| 134 | + |
| 135 | + sleep 1 |
| 136 | + ELAPSED=$((ELAPSED + 1)) |
| 137 | +done |
| 138 | + |
| 139 | +if [[ $ELAPSED -ge $STARTUP_TIMEOUT ]]; then |
| 140 | + log_error "Server failed to start within ${STARTUP_TIMEOUT}s" |
| 141 | + log_error "Server log:" |
| 142 | + cat server.log |
| 143 | + exit 1 |
| 144 | +fi |
| 145 | + |
| 146 | +# Test healthcheck endpoint |
| 147 | +log_info "Testing healthcheck endpoint..." |
| 148 | +HEALTH_RESPONSE=$(curl -sf "http://${SERVER_HOST}:${SERVER_PORT}/health" || true) |
| 149 | + |
| 150 | +if [[ -z "$HEALTH_RESPONSE" ]]; then |
| 151 | + log_error "Healthcheck returned empty response" |
| 152 | + exit 1 |
| 153 | +fi |
| 154 | + |
| 155 | +log_info "Healthcheck response: $HEALTH_RESPONSE" |
| 156 | + |
| 157 | +# Verify healthcheck response format |
| 158 | +if ! echo "$HEALTH_RESPONSE" | jq -e '.status == "ok"' >/dev/null 2>&1; then |
| 159 | + log_error "Healthcheck response does not contain expected 'status: ok'" |
| 160 | + log_error "Response: $HEALTH_RESPONSE" |
| 161 | + exit 1 |
| 162 | +fi |
| 163 | + |
| 164 | +log_info "✅ Healthcheck endpoint returned valid response" |
| 165 | + |
| 166 | +# Test that server is actually serving content |
| 167 | +log_info "Testing root endpoint..." |
| 168 | +if ! curl -sf "http://${SERVER_HOST}:${SERVER_PORT}/" >/dev/null 2>&1; then |
| 169 | + log_error "Failed to fetch root endpoint" |
| 170 | + exit 1 |
| 171 | +fi |
| 172 | + |
| 173 | +log_info "✅ Root endpoint is accessible" |
| 174 | + |
| 175 | +# All tests passed |
| 176 | +log_info "🎉 All smoke tests passed!" |
0 commit comments