Skip to content
Merged
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
6 changes: 6 additions & 0 deletions .github/workflows/websocket-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,9 @@ jobs:
- run: pnpm run lint

- run: pnpm run test

- name: Pull Autobahn Test Suite Docker image
run: docker pull crossbario/autobahn-testsuite

- name: Run Autobahn WebSocket Protocol Tests
run: cd test/autobahn && node run-wstest.js
17 changes: 17 additions & 0 deletions test/autobahn/config/fuzzingclient-linux.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@

{
"options": {"failByDrop": false},
"outdir": "./reports/servers",

"servers": [
{
"agent": "WebSocket-Node 1.0.27",
"url": "ws://localhost:8080",
"options": {"version": 18}
}
],

"cases": ["*"],
"exclude-cases": [],
"exclude-agent-cases": {}
}
17 changes: 12 additions & 5 deletions test/autobahn/parse-results.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,18 @@ function parseResults() {
// Print summary
console.log('Test Summary:');
console.log(` Total tests: ${summary.total}`);
console.log(` Required tests: ${summary.total - summary.unimplemented}`);
console.log(` Optional tests: ${summary.unimplemented}`);
console.log(` Passed (OK): ${summary.ok}`);
console.log(` Failed: ${summary.failed}`);
console.log(` Non-Strict: ${summary.nonStrict}`);
console.log(` Informational: ${summary.informational}`);
console.log(` Unimplemented: ${summary.unimplemented}`);

const passRate = ((summary.ok / summary.total) * 100).toFixed(1);

// Pass rate excludes optional, non-strict, and informational tests
const strictRequired = summary.total - summary.unimplemented - summary.nonStrict - summary.informational;
const passRate = strictRequired > 0
? ((summary.ok / strictRequired) * 100).toFixed(1)
: '0.0';
console.log(` Pass rate: ${passRate}%`);

// Print failed tests if any
Expand Down Expand Up @@ -121,7 +126,7 @@ function parseResults() {

// Print unimplemented tests summary (grouped by major version)
if (summary.unimplementedTests.length > 0) {
console.log('\n=== UNIMPLEMENTED TESTS (Informational) ===');
console.log('\n=== OPTIONAL FEATURES NOT IMPLEMENTED (Informational) ===');

// Group by major test category
const unimplementedByCategory = {};
Expand All @@ -140,14 +145,16 @@ function parseResults() {
}

console.log('\n');

// Exit with error code if there are actual failures
if (summary.failed > 0) {
console.error(`❌ ${summary.failed} test(s) failed!`);
process.exit(1);
} else {
console.log(`✅ All tests passed! (${summary.ok} OK, ${summary.nonStrict} non-strict, ${summary.informational} informational, ${summary.unimplemented} unimplemented)`);
}

return summary;
}

if (require.main === module) {
Expand Down
40 changes: 28 additions & 12 deletions test/autobahn/run-wstest.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,16 +106,22 @@ class AutobahnTestRunner {
runAutobahnTests() {
return new Promise((resolve, reject) => {
console.log('🐳 Starting Autobahn test suite with Docker...');


// Detect platform and use appropriate config and networking
const isLinux = process.platform === 'linux';
const configFile = isLinux ? 'fuzzingclient-linux.json' : 'fuzzingclient.json';

console.log(` Platform: ${process.platform}, using config: ${configFile}`);

const dockerArgs = [
'run',
'--rm',
...(isLinux ? ['--network=host'] : ['-p', '9001:9001']),
'-v', `${process.cwd()}/config:/config`,
'-v', `${process.cwd()}/reports:/reports`,
'-p', '9001:9001',
'--name', 'fuzzingclient',
'crossbario/autobahn-testsuite',
'wstest', '-m', 'fuzzingclient', '--spec', '/config/fuzzingclient.json'
'wstest', '-m', 'fuzzingclient', '--spec', `/config/${configFile}`
];

this.dockerProcess = spawn('docker', dockerArgs, {
Expand Down Expand Up @@ -157,26 +163,36 @@ class AutobahnTestRunner {

parseAndDisplayResults() {
console.log('📊 Parsing test results...\n');

const resultsPath = path.join(__dirname, 'reports', 'servers', 'index.json');

if (!fs.existsSync(resultsPath)) {
console.error('❌ Results file not found. Tests may not have completed properly.');
return;
process.exit(1);
}

try {
const originalProcessExit = process.exit;
// Prevent parseResults from exiting the process
process.exit = () => {};

parseResults();

let exitCode = 0;

// Intercept process.exit to capture the exit code
process.exit = (code) => {
exitCode = code || 0;
};

const summary = parseResults();

// Restore original function
process.exit = originalProcessExit;


// Exit with appropriate code if there were failures
if (exitCode !== 0 || (summary && summary.failed > 0)) {
process.exit(1);
}

} catch (error) {
console.error('❌ Failed to parse results:', error.message);
process.exit(1);
}
}

Expand Down