Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
*.fasl
*~
\#*
.\#*
.\#*
ocicl*
autobahn/reports
autobahn/server.log
15 changes: 15 additions & 0 deletions autobahn/fuzzingclient.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"outdir": "./reports/clients",
"servers": [
{
"agent": "CLWS",
"url": "ws://localhost:12345/echo",
"options": {
"version": 18
}
}
],
"cases": ["*"],
"exclude-cases": [],
"exclude-agent-cases": {}
}
92 changes: 92 additions & 0 deletions autobahn/run-autobahn-server.lisp
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
;;;; run-autobahn-server.lisp
;;;; Starts CLWS server for Autobahn Test Suite fuzzing
;;;;
;;;; This script relies on .sbclrc to set up ocicl runtime
;;;; Run with: sbcl --load run-autobahn-server.lisp

;; Suppress IOLIB/COMMON-LISP package conflict warnings
#+sbcl
(setf sb-ext:*on-package-variance* '(:warn nil))

;; Add /tmp/clws to ASDF registry so it can find clws.asd
(let* ((this-dir (make-pathname :name nil :type nil
:defaults (or *load-truename* *default-pathname-defaults*)))
(project-root (truename (merge-pathnames "../" this-dir))))
(pushnew project-root asdf:*central-registry* :test #'equal))

;; Load CLWS
(format t "~%Loading CLWS system...~%")
(force-output)

;; Don't suppress warnings/errors during loading
(setf *compile-verbose* t
*compile-print* t
*load-verbose* t)

(handler-case
(asdf:load-system :clws)
(error (e)
(format t "~%~%========================================~%")
(format t "ERROR loading CLWS:~%")
(format t "~A~%" e)
(format t "========================================~%~%")
(force-output)
(uiop:quit 1)))

(format t "~%CLWS loaded successfully!~%")
(force-output)

(in-package :clws)

(format t "Starting CLWS server for Autobahn testing...~%")
(format t "Server URL: ws://localhost:12345/echo~%")
(format t "Press Ctrl+C to stop~%~%")

;;; Define echo resource for testing
(defclass echo-resource (ws-resource) ())

(defmethod resource-client-connected ((res echo-resource) client)
(declare (ignore res client))
nil)

(defmethod resource-client-disconnected ((res echo-resource) client)
(declare (ignore res client))
nil)

(defmethod resource-received-text ((res echo-resource) client message)
;; Echo the message back
(write-to-client-text client message))

(defmethod resource-received-binary ((res echo-resource) client message)
;; Echo the binary data back
(write-to-client-binary client message))

;; Register echo resource with permissive origin validation (Autobahn doesn't send Origin header)
;; Use any-origin function to accept all origins including nil
(register-global-resource
"/echo"
(make-instance 'echo-resource)
#'any-origin) ; Accept any origin for protocol conformance testing

(format t "[Server] Resource registered: /echo~%")

;; Start server thread
(bt:make-thread
(lambda ()
(format t "[Server] Starting server on port 12345~%")
(run-server 12345))
:name "clws-autobahn-server")

(sleep 1)

;; Start resource listener thread
(bt:make-thread
(lambda ()
(format t "[Server] Starting resource listener~%")
(run-resource-listener (find-global-resource "/echo")))
:name "clws-echo-resource")

(format t "~%[Server] CLWS test server is ready for Autobahn!~%~%")

;; Keep the script running
(loop (sleep 60))
138 changes: 138 additions & 0 deletions autobahn/run-autobahn.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
#!/bin/bash
###############################################################################
# run-autobahn-docker.sh
# Runs Autobahn Test Suite using Docker or Podman
###############################################################################

set -e

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

echo -e "${BLUE}╔══════════════════════════════╗${NC}"
echo -e "${BLUE}║ CLWS Autobahn Test Suite ║${NC}"
echo -e "${BLUE}╚══════════════════════════════╝${NC}"
echo

(cd ../; sbcl --eval "(asdf:load-system :clws)" --quit)
(cd ../; sbcl --eval "(asdf:load-system :clws)" --quit)

# Detect container runtime (Docker or Podman)
CONTAINER_CMD=""
if command -v podman &> /dev/null; then
CONTAINER_CMD="podman"
echo -e "${GREEN}✓ Using Podman${NC}"
elif command -v docker &> /dev/null; then
CONTAINER_CMD="docker"
echo -e "${GREEN}✓ Using Docker${NC}"
else
echo -e "${RED}Error: Neither Docker nor Podman found${NC}"
echo
echo "Install Podman (recommended for Fedora):"
echo " sudo dnf install podman"
echo
echo "Or install Docker:"
echo " https://docs.docker.com/get-docker/"
echo
exit 1
fi
echo

# Pull Autobahn container image if needed
echo -e "${BLUE}Checking for Autobahn container image...${NC}"
if ! $CONTAINER_CMD image inspect docker.io/crossbario/autobahn-testsuite &> /dev/null; then
echo "Pulling docker.io/crossbario/autobahn-testsuite..."
$CONTAINER_CMD pull docker.io/crossbario/autobahn-testsuite
else
echo -e "${GREEN}✓ Image already present${NC}"
fi
echo

# Start CLWS server in background
echo -e "${BLUE}Starting CLWS server...${NC}"
sbcl --noinform --load run-autobahn-server.lisp > server.log 2>&1 &
SERVER_PID=$!

echo "Server PID: $SERVER_PID"

# Function to cleanup on exit
cleanup() {
echo
echo -e "${YELLOW}Stopping CLWS server (PID: $SERVER_PID)...${NC}"
kill $SERVER_PID 2>/dev/null || true
wait $SERVER_PID 2>/dev/null || true
echo -e "${GREEN}✓ Server stopped${NC}"
}

trap cleanup EXIT INT TERM

# Wait for server to start
echo "Waiting for server to start..."
sleep 3

# Check if server is running
if ! kill -0 $SERVER_PID 2>/dev/null; then
echo -e "${RED}Error: Server failed to start${NC}"
echo "Server log:"
cat server.log
exit 1
fi

echo -e "${GREEN}✓ Server started${NC}"
echo

# Create reports directory
mkdir -p reports

# Run Autobahn test suite via container
echo -e "${BLUE}===========================================
Running Autobahn Test Suite via $CONTAINER_CMD
===========================================${NC}"
echo
echo "This will run 500+ protocol conformance tests..."
echo "This may take several minutes..."
echo

if $CONTAINER_CMD run -it --rm \
-v "${PWD}/fuzzingclient.json:/config/fuzzingclient.json:Z" \
-v "${PWD}/reports:/reports:Z" \
--network="host" \
docker.io/crossbario/autobahn-testsuite \
wstest -m fuzzingclient -s /config/fuzzingclient.json; then

echo
echo -e "${BLUE}===========================================
Autobahn Test Results
===========================================${NC}"
echo -e "${GREEN}✓ Test suite completed${NC}"
echo
echo "View detailed results:"
echo " Open: $(pwd)/reports/clients/index.html"
echo

# Try to display summary if index.html exists
if [ -f "reports/clients/index.html" ]; then
echo "Summary:"
# Extract test results from HTML (basic parsing)
if command -v grep &> /dev/null && command -v wc &> /dev/null; then
TOTAL=$(grep -o 'case_count">[0-9]*' reports/clients/index.html 2>/dev/null | sed 's/case_count">//' | head -1 || echo "?")
echo " Total test cases: $TOTAL"
fi
fi

EXIT_CODE=0
else
echo
echo -e "${RED}✗ Autobahn test suite failed${NC}"
echo "Check reports/clients/index.html for details"
EXIT_CODE=1
fi

exit $EXIT_CODE