Run WebSocket Autobahn test for all Jetty, Javax and Core APIs (#7430)

* Run WebSocket Autobahn test for all Jetty, Javax and Core APIs

Signed-off-by: Lachlan Roberts <lachlan@webtide.com>

Signed-off-by: Olivier Lamy <oliver.lamy@gmail.com>
This commit is contained in:
Lachlan 2022-01-31 16:29:41 +11:00 committed by GitHub
parent 53762fbda4
commit b0e334f14a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 1053 additions and 413 deletions

View File

@ -10,8 +10,17 @@ pipeline {
// save some io during the build // save some io during the build
durabilityHint( 'PERFORMANCE_OPTIMIZED' ) durabilityHint( 'PERFORMANCE_OPTIMIZED' )
} }
parameters {
string( defaultValue: 'jetty-10.0.x', description: 'GIT branch name to build (jetty-10.0.x/jetty-11.0.x/etc.)',
name: 'JETTY_BRANCH' )
}
stages { stages {
stage("Checkout Jetty Branch") {
steps {
git url: 'https://github.com/eclipse/jetty.project/', branch: '${JETTY_BRANCH}'
}
}
stage( "Build / Test - JDK11" ) { stage( "Build / Test - JDK11" ) {
agent { agent {
node { label 'linux' } node { label 'linux' }
@ -19,8 +28,14 @@ pipeline {
steps { steps {
container( 'jetty-build' ) { container( 'jetty-build' ) {
timeout( time: 120, unit: 'MINUTES' ) { timeout( time: 120, unit: 'MINUTES' ) {
mavenBuild( "jdk11", "-T3 clean install -Djacoco.skip=true -Pautobahn", "maven3", true ) // mavenBuild( "jdk11", "-T3 clean install -Djacoco.skip=true -pl :test-websocket-autobahn -am -Pautobahn -Dtest=AutobahnTests", "maven3" ) //
junit testResults: '**/target/surefire-reports/*.xml,**/target/invoker-reports/TEST*.xml,**/target/autobahntestsuite-reports/*.xml' junit testResults: '**/target/surefire-reports/*.xml,**/target/invoker-reports/TEST*.xml,**/target/autobahntestsuite-reports/*.xml'
publishHTML([allowMissing: true, alwaysLinkToLastBuild: true, keepAll: true, reportDir: "${env.WORKSPACE}/tests/test-websocket-autobahn/target/reports/core/servers", reportFiles: 'index.html', reportName: 'Autobahn Report Core Server', reportTitles: ''])
publishHTML([allowMissing: true, alwaysLinkToLastBuild: true, keepAll: true, reportDir: "${env.WORKSPACE}/tests/test-websocket-autobahn/target/reports/core/clients", reportFiles: 'index.html', reportName: 'Autobahn Report Core Client', reportTitles: ''])
publishHTML([allowMissing: true, alwaysLinkToLastBuild: true, keepAll: true, reportDir: "${env.WORKSPACE}/tests/test-websocket-autobahn/target/reports/javax/servers", reportFiles: 'index.html', reportName: 'Autobahn Report Javax Server', reportTitles: ''])
publishHTML([allowMissing: true, alwaysLinkToLastBuild: true, keepAll: true, reportDir: "${env.WORKSPACE}/tests/test-websocket-autobahn/target/reports/javax/clients", reportFiles: 'index.html', reportName: 'Autobahn Report Javax Client', reportTitles: ''])
publishHTML([allowMissing: true, alwaysLinkToLastBuild: true, keepAll: true, reportDir: "${env.WORKSPACE}/tests/test-websocket-autobahn/target/reports/jetty/servers", reportFiles: 'index.html', reportName: 'Autobahn Report Jetty Server', reportTitles: ''])
publishHTML([allowMissing: true, alwaysLinkToLastBuild: true, keepAll: true, reportDir: "${env.WORKSPACE}/tests/test-websocket-autobahn/target/reports/jetty/clients", reportFiles: 'index.html', reportName: 'Autobahn Report Jetty Client', reportTitles: ''])
} }
} }
} }
@ -68,19 +83,16 @@ def slackNotif() {
* @paran mvnName maven installation to use * @paran mvnName maven installation to use
* @return the Jenkinsfile step representing a maven build * @return the Jenkinsfile step representing a maven build
*/ */
def mavenBuild(jdk, cmdline, mvnName, junitPublishDisabled) { def mavenBuild(jdk, cmdline, mvnName) {
def localRepo = ".repository" script {
def mavenOpts = '-Xms1g -Xmx4g -Djava.awt.headless=true' withEnv(["JAVA_HOME=${ tool "$jdk" }",
"PATH+MAVEN=${ tool "$jdk" }/bin:${tool "$mvnName"}/bin",
withMaven( "MAVEN_OPTS=-Xms2g -Xmx8g -Djava.awt.headless=true"]) {
maven: mvnName, configFileProvider(
jdk: "$jdk", [configFile(fileId: 'oss-settings.xml', variable: 'GLOBAL_MVN_SETTINGS')]) {
publisherStrategy: 'EXPLICIT', sh "mvn -Denforcer.skip=true -Dlicense.skip=true -Dspotbugs.skip=true -Dcheckstyle.skip=true --no-transfer-progress -s $GLOBAL_MVN_SETTINGS -Dmaven.repo.local=.repository -Pci -V -B -e -Djetty.testtracker.log=true $cmdline"
options: [junitPublisher(disabled: junitPublishDisabled), mavenLinkerPublisher(disabled: false), pipelineGraphPublisher(disabled: false)], }
mavenOpts: mavenOpts, }
mavenLocalRepo: localRepo) {
// Some common Maven command line + provided command line
sh "mvn -Pci -V -B -e -fae -Dmaven.test.failure.ignore=true -Djetty.testtracker.log=true $cmdline"
} }
} }

View File

@ -37,42 +37,9 @@
<artifactId>jetty-slf4j-impl</artifactId> <artifactId>jetty-slf4j-impl</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-utils</artifactId>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
<build> <build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<excludes>
<exclude>**/AutobahnTests**</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins> <plugins>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
@ -92,30 +59,4 @@
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
<profiles>
<profile>
<id>autobahn</id>
<activation>
<property>
<name>autobahn</name>
<value>true</value>
</property>
</activation>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<excludes>
<exclude>none</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</profile>
</profiles>
</project> </project>

View File

@ -1,18 +0,0 @@
{
"options": {
"failByDrop": false
},
"outdir": "./target/reports/servers",
"servers": [
{
"agent": "Jetty-10.0.0-SNAPSHOT",
"url": "ws://127.0.0.1:9001",
"options": {
"version": 18
}
}
],
"cases": ["*"],
"exclude-cases": [],
"exclude-agent-cases": {}
}

View File

@ -1,10 +0,0 @@
{
"options": {
"failByDrop": false
},
"url": "ws://127.0.0.1:9001",
"outdir": "./target/reports/clients",
"cases": ["*"],
"exclude-cases": [],
"exclude-agent-cases": {}
}

View File

@ -1,18 +0,0 @@
{
"options": {
"failByDrop": false
},
"outdir": "./target/reports/servers",
"servers": [
{
"agent": "Jetty-10.0.0-SNAPSHOT",
"url": "ws://127.0.0.1:9001",
"options": {
"version": 18
}
}
],
"cases": ["*"],
"exclude-cases": [],
"exclude-agent-cases": {}
}

View File

@ -1,10 +0,0 @@
{
"options": {
"failByDrop": false
},
"url": "ws://127.0.0.1:9001",
"outdir": "./target/reports/clients",
"cases": ["*"],
"exclude-cases": [],
"exclude-agent-cases": {}
}

View File

@ -57,5 +57,7 @@
<module>test-distribution</module> <module>test-distribution</module>
<module>test-cdi</module> <module>test-cdi</module>
<module>test-jpms</module> <module>test-jpms</module>
<module>test-websocket-autobahn</module>
</modules> </modules>
</project> </project>

View File

@ -7,6 +7,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>test-distribution</artifactId> <artifactId>test-distribution</artifactId>
<name>Jetty Tests :: Distribution Tests</name>
<packaging>jar</packaging> <packaging>jar</packaging>
<properties> <properties>

View File

@ -8,7 +8,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>test-jpms</artifactId> <artifactId>test-jpms</artifactId>
<packaging>pom</packaging> <packaging>pom</packaging>
<name>Jetty Tests :: JPMS Parent</name> <name>Jetty Tests :: JPMS</name>
<modules> <modules>
<module>test-jpms-websocket-core</module> <module>test-jpms-websocket-core</module>
</modules> </modules>

View File

@ -0,0 +1,141 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.eclipse.jetty.tests</groupId>
<artifactId>tests-parent</artifactId>
<version>10.0.8-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>test-websocket-autobahn</artifactId>
<name>Jetty Tests :: WebSocket Autobahn Tests</name>
<description>Run of Autobahn Testsuite for Jetty</description>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-util</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-jetty-client</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-jetty-server</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-javax-client</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-javax-server</artifactId>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-utils</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<excludes>
<exclude>**/AutobahnTests**</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<executions>
<execution>
<goals>
<goal>manifest</goal>
</goals>
<configuration>
<instructions>
<Bundle-Description>jetty.websocket Autobahn Tests</Bundle-Description>
<Export-Package>
org.eclipse.jetty.websocket.jetty.tests.*;version="${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}"
</Export-Package>
</instructions>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>autobahn</id>
<activation>
<property>
<name>autobahn</name>
<value>true</value>
</property>
</activation>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<forkedProcessTimeoutInSeconds>10800</forkedProcessTimeoutInSeconds>
<excludes>
<exclude>none</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</profile>
</profiles>
</project>

View File

@ -0,0 +1,19 @@
//
// ========================================================================
// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
package org.eclipse.jetty.websocket.tests;
public interface AutobahnClient
{
void runAutobahnClient(String hostname, int port, int[] caseNumbers);
}

View File

@ -0,0 +1,21 @@
//
// ========================================================================
// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
package org.eclipse.jetty.websocket.tests;
public interface AutobahnServer
{
void startAutobahnServer(int port) throws Exception;
void stopAutobahnServer() throws Exception;
}

View File

@ -0,0 +1,160 @@
//
// ========================================================================
// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
package org.eclipse.jetty.websocket.tests;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Duration;
import java.util.List;
import com.github.dockerjava.api.DockerClient;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.websocket.tests.core.CoreAutobahnClient;
import org.eclipse.jetty.websocket.tests.core.CoreAutobahnServer;
import org.eclipse.jetty.websocket.tests.javax.JavaxAutobahnClient;
import org.eclipse.jetty.websocket.tests.javax.JavaxAutobahnServer;
import org.eclipse.jetty.websocket.tests.jetty.JettyAutobahnClient;
import org.eclipse.jetty.websocket.tests.jetty.JettyAutobahnServer;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.output.Slf4jLogConsumer;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.utility.DockerImageName;
import org.testcontainers.utility.MountableFile;
import static org.eclipse.jetty.websocket.tests.AutobahnUtils.copyFromContainer;
import static org.eclipse.jetty.websocket.tests.AutobahnUtils.parseResults;
import static org.eclipse.jetty.websocket.tests.AutobahnUtils.throwIfFailed;
import static org.eclipse.jetty.websocket.tests.AutobahnUtils.writeJUnitXmlReport;
import static org.junit.jupiter.api.Assertions.assertTrue;
@Testcontainers(disabledWithoutDocker = true)
public class AutobahnTests
{
private static final Logger LOG = LoggerFactory.getLogger(AutobahnTests.class);
private static final Path USER_DIR = Paths.get(System.getProperty("user.dir"));
private Path reportDir;
private Path fuzzingServer;
private Path fuzzingClient;
private AutobahnServer server;
private AutobahnClient client;
@BeforeAll
public static void clean()
{
Path reportDir = USER_DIR.resolve("target/reports");
IO.delete(reportDir.toFile());
}
public void setup(String version) throws Exception
{
fuzzingServer = USER_DIR.resolve("fuzzingserver.json");
assertTrue(Files.exists(fuzzingServer), fuzzingServer + " not exists");
fuzzingClient = USER_DIR.resolve("fuzzingclient.json");
assertTrue(Files.exists(fuzzingClient), fuzzingClient + " not exists");
reportDir = USER_DIR.resolve("target/reports/" + version);
if (!Files.exists(reportDir))
Files.createDirectories(reportDir);
switch (version)
{
case "jetty":
server = new JettyAutobahnServer();
client = new JettyAutobahnClient();
break;
case "javax":
server = new JavaxAutobahnServer();
client = new JavaxAutobahnClient();
break;
case "core":
server = new CoreAutobahnServer();
client = new CoreAutobahnClient();
break;
default:
throw new IllegalStateException(version);
}
}
@ParameterizedTest
@ValueSource(strings = {"core", "jetty", "javax"})
public void testClient(String version) throws Exception
{
setup(version);
try (GenericContainer<?> container = new GenericContainer<>(DockerImageName.parse("jettyproject/autobahn-testsuite:latest"))
.withCommand("/bin/bash", "-c", "wstest -m fuzzingserver -s /config/fuzzingserver.json")
.withExposedPorts(9001)
.withCopyFileToContainer(MountableFile.forHostPath(fuzzingServer), "/config/fuzzingserver.json")
.withLogConsumer(new Slf4jLogConsumer(LOG))
.withStartupTimeout(Duration.ofHours(2)))
{
container.start();
Integer mappedPort = container.getMappedPort(9001);
client.runAutobahnClient(container.getContainerIpAddress(), mappedPort, null);
DockerClient dockerClient = container.getDockerClient();
String containerId = container.getContainerId();
copyFromContainer(dockerClient, containerId, reportDir, Paths.get("/target/reports/clients"));
}
LOG.info("Test Result Overview {}", reportDir.resolve("clients/index.html").toUri());
List<AutobahnUtils.AutobahnCaseResult> results = parseResults(reportDir.resolve("clients/index.json"));
String className = getClass().getName();
writeJUnitXmlReport(results, version + "-autobahn-client", className + ".client");
throwIfFailed(results);
}
@ParameterizedTest
@ValueSource(strings = {"core", "jetty", "javax"})
public void testServer(String version) throws Exception
{
setup(version);
// We need to expose the host port of the server to the Autobahn Client in docker container.
final int port = 9001;
org.testcontainers.Testcontainers.exposeHostPorts(port);
server.startAutobahnServer(port);
AutobahnUtils.FileSignalWaitStrategy strategy = new AutobahnUtils.FileSignalWaitStrategy(reportDir, Paths.get("/target/reports/servers"));
try (GenericContainer<?> container = new GenericContainer<>(DockerImageName.parse("jettyproject/autobahn-testsuite:latest"))
.withCommand("/bin/bash", "-c", "wstest -m fuzzingclient -s /config/fuzzingclient.json" + AutobahnUtils.FileSignalWaitStrategy.END_COMMAND)
.withLogConsumer(new Slf4jLogConsumer(LOG))
.withCopyFileToContainer(MountableFile.forHostPath(fuzzingClient), "/config/fuzzingclient.json")
.withStartupCheckStrategy(strategy)
.withStartupTimeout(Duration.ofHours(2)))
{
container.start();
}
finally
{
server.stopAutobahnServer();
}
LOG.info("Test Result Overview {}", reportDir.resolve("servers/index.html").toUri());
List<AutobahnUtils.AutobahnCaseResult> results = parseResults(reportDir.resolve("servers/index.json"));
String className = getClass().getName();
writeJUnitXmlReport(results, version + "-autobahn-server", className + ".server");
throwIfFailed(results);
}
}

View File

@ -11,7 +11,7 @@
// ======================================================================== // ========================================================================
// //
package org.eclipse.jetty.websocket.core.autobahn; package org.eclipse.jetty.websocket.tests;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
@ -31,110 +31,19 @@ import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.codehaus.plexus.util.xml.Xpp3Dom; import org.codehaus.plexus.util.xml.Xpp3Dom;
import org.codehaus.plexus.util.xml.Xpp3DomWriter; import org.codehaus.plexus.util.xml.Xpp3DomWriter;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.IO;
import org.json.simple.JSONObject; import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser; import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException; import org.json.simple.parser.ParseException;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.output.Slf4jLogConsumer;
import org.testcontainers.containers.startupcheck.StartupCheckStrategy; import org.testcontainers.containers.startupcheck.StartupCheckStrategy;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.utility.DockerImageName;
import org.testcontainers.utility.DockerStatus; import org.testcontainers.utility.DockerStatus;
import org.testcontainers.utility.MountableFile;
import static org.junit.jupiter.api.Assertions.assertTrue; public class AutobahnUtils
@Disabled("Disable this test so it doesn't run locally as it takes 1h+ to run.")
@Testcontainers
public class AutobahnTests
{ {
private static final Logger LOG = LoggerFactory.getLogger(AutobahnTests.class); private static final Logger LOG = LoggerFactory.getLogger(AutobahnUtils.class);
private static final Path USER_DIR = Paths.get(System.getProperty("user.dir"));
private static Path reportDir; public static void throwIfFailed(List<AutobahnCaseResult> results) throws Exception
private static Path fuzzingServer;
private static Path fuzzingClient;
@BeforeAll
public static void before() throws Exception
{
fuzzingServer = USER_DIR.resolve("fuzzingserver.json");
assertTrue(Files.exists(fuzzingServer), fuzzingServer + " not exists");
fuzzingClient = USER_DIR.resolve("fuzzingclient.json");
assertTrue(Files.exists(fuzzingClient), fuzzingClient + " not exists");
reportDir = USER_DIR.resolve("target/reports");
IO.delete(reportDir.toFile());
Files.createDirectory(reportDir);
}
@Test
public void testClient() throws Exception
{
try (GenericContainer<?> container = new GenericContainer<>(DockerImageName.parse("jettyproject/autobahn-testsuite:latest"))
.withCommand("/bin/bash", "-c", "wstest -m fuzzingserver -s /config/fuzzingserver.json")
.withExposedPorts(9001)
.withCopyFileToContainer(MountableFile.forHostPath(fuzzingServer), "/config/fuzzingserver.json")
.withLogConsumer(new Slf4jLogConsumer(LOG))
.withStartupTimeout(Duration.ofHours(2)))
{
container.start();
Integer mappedPort = container.getMappedPort(9001);
CoreAutobahnClient.main(new String[]{container.getContainerIpAddress(), mappedPort.toString()});
DockerClient dockerClient = container.getDockerClient();
String containerId = container.getContainerId();
copyFromContainer(dockerClient, containerId, reportDir, Paths.get("/target/reports/clients"));
}
LOG.info("Test Result Overview {}", reportDir.resolve("clients/index.html").toUri());
List<AutobahnCaseResult> results = parseResults(Paths.get("target/reports/clients/index.json"));
String className = getClass().getName();
writeJUnitXmlReport(results, "autobahn-client", className + ".client");
throwIfFailed(results);
}
@Test
public void testServer() throws Exception
{
// We need to expose the host port of the server to the Autobahn Client in docker container.
final int port = 9001;
org.testcontainers.Testcontainers.exposeHostPorts(port);
Server server = CoreAutobahnServer.startAutobahnServer(port);
FileSignalWaitStrategy strategy = new FileSignalWaitStrategy(reportDir, Paths.get("/target/reports/servers"));
try (GenericContainer<?> container = new GenericContainer<>(DockerImageName.parse("jettyproject/autobahn-testsuite:latest"))
.withCommand("/bin/bash", "-c", "wstest -m fuzzingclient -s /config/fuzzingclient.json" + FileSignalWaitStrategy.END_COMMAND)
.withLogConsumer(new Slf4jLogConsumer(LOG))
.withCopyFileToContainer(MountableFile.forHostPath(fuzzingClient), "/config/fuzzingclient.json")
.withStartupCheckStrategy(strategy)
.withStartupTimeout(Duration.ofHours(2)))
{
container.start();
}
finally
{
server.stop();
}
LOG.info("Test Result Overview {}", reportDir.resolve("servers/index.html").toUri());
List<AutobahnCaseResult> results = parseResults(Paths.get("target/reports/servers/index.json"));
String className = getClass().getName();
writeJUnitXmlReport(results, "autobahn-server", className + ".server");
throwIfFailed(results);
}
private void throwIfFailed(List<AutobahnCaseResult> results) throws Exception
{ {
StringBuilder message = new StringBuilder(); StringBuilder message = new StringBuilder();
for (AutobahnCaseResult result : results) for (AutobahnCaseResult result : results)
@ -147,7 +56,7 @@ public class AutobahnTests
throw new Exception("Failed Test Cases: " + message); throw new Exception("Failed Test Cases: " + message);
} }
private static class FileSignalWaitStrategy extends StartupCheckStrategy public static class FileSignalWaitStrategy extends StartupCheckStrategy
{ {
public static final String SIGNAL_FILE = "/signalComplete"; public static final String SIGNAL_FILE = "/signalComplete";
public static final String END_COMMAND = " && touch " + SIGNAL_FILE + " && sleep infinity"; public static final String END_COMMAND = " && touch " + SIGNAL_FILE + " && sleep infinity";
@ -163,7 +72,7 @@ public class AutobahnTests
} }
@Override @Override
public StartupCheckStrategy.StartupStatus checkStartupState(DockerClient dockerClient, String containerId) public StartupStatus checkStartupState(DockerClient dockerClient, String containerId)
{ {
// If the container was stopped then we have failed to copy out the file. // If the container was stopped then we have failed to copy out the file.
if (DockerStatus.isContainerStopped(getCurrentState(dockerClient, containerId))) if (DockerStatus.isContainerStopped(getCurrentState(dockerClient, containerId)))
@ -196,7 +105,7 @@ public class AutobahnTests
} }
} }
private static void copyFromContainer(DockerClient dockerClient, String containerId, Path target, Path source) throws Exception public static void copyFromContainer(DockerClient dockerClient, String containerId, Path target, Path source) throws Exception
{ {
try (TarArchiveInputStream tarArchiveInputStream = new TarArchiveInputStream(dockerClient try (TarArchiveInputStream tarArchiveInputStream = new TarArchiveInputStream(dockerClient
.copyArchiveFromContainerCmd(containerId, source.toString()) .copyArchiveFromContainerCmd(containerId, source.toString())
@ -217,8 +126,7 @@ public class AutobahnTests
} }
} }
private void writeJUnitXmlReport(List<AutobahnCaseResult> results, String surefireFileName, String testName) public static void writeJUnitXmlReport(List<AutobahnCaseResult> results, String surefireFileName, String testName) throws Exception
throws Exception
{ {
int failures = 0; int failures = 0;
long suiteDuration = 0; long suiteDuration = 0;
@ -259,8 +167,7 @@ public class AutobahnTests
} }
} }
private void addFailure(Xpp3Dom testCase, AutobahnCaseResult result) throws IOException, public static void addFailure(Xpp3Dom testCase, AutobahnCaseResult result) throws IOException, ParseException
ParseException
{ {
JSONParser parser = new JSONParser(); JSONParser parser = new JSONParser();
@ -292,7 +199,7 @@ public class AutobahnTests
} }
} }
private static List<AutobahnCaseResult> parseResults(Path jsonPath) throws Exception public static List<AutobahnCaseResult> parseResults(Path jsonPath) throws Exception
{ {
List<AutobahnCaseResult> results = new ArrayList<>(); List<AutobahnCaseResult> results = new ArrayList<>();
JSONParser parser = new JSONParser(); JSONParser parser = new JSONParser();

View File

@ -11,14 +11,13 @@
// ======================================================================== // ========================================================================
// //
package org.eclipse.jetty.websocket.core.autobahn; package org.eclipse.jetty.websocket.tests.core;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.time.Duration; import java.time.Duration;
import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.websocket.core.CoreSession; import org.eclipse.jetty.websocket.core.CoreSession;
import org.eclipse.jetty.websocket.core.TestMessageHandler;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;

View File

@ -11,7 +11,7 @@
// ======================================================================== // ========================================================================
// //
package org.eclipse.jetty.websocket.core.autobahn; package org.eclipse.jetty.websocket.tests.core;
import java.net.URI; import java.net.URI;
import java.util.concurrent.Future; import java.util.concurrent.Future;
@ -23,15 +23,15 @@ import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.Jetty; import org.eclipse.jetty.util.Jetty;
import org.eclipse.jetty.util.UrlEncoded; import org.eclipse.jetty.util.UrlEncoded;
import org.eclipse.jetty.websocket.core.CoreSession; import org.eclipse.jetty.websocket.core.CoreSession;
import org.eclipse.jetty.websocket.core.TestMessageHandler;
import org.eclipse.jetty.websocket.core.client.CoreClientUpgradeRequest; import org.eclipse.jetty.websocket.core.client.CoreClientUpgradeRequest;
import org.eclipse.jetty.websocket.core.client.WebSocketCoreClient; import org.eclipse.jetty.websocket.core.client.WebSocketCoreClient;
import org.eclipse.jetty.websocket.core.internal.MessageHandler; import org.eclipse.jetty.websocket.core.internal.MessageHandler;
import org.eclipse.jetty.websocket.tests.AutobahnClient;
import org.junit.jupiter.api.Assertions;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
/** /**
* WebSocket Client for use with <a href="https://github.com/crossbario/autobahn-testsuite">autobahn websocket testsuite</a> (wstest). * WebSocket Client for use with <a href="https://github.com/crossbario/autobahn-testsuite">autobahn websocket testsuite</a> (wstest).
@ -67,9 +67,9 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
* $ ls target/reports/clients/ * $ ls target/reports/clients/
* </pre> * </pre>
*/ */
public class CoreAutobahnClient public class CoreAutobahnClient implements AutobahnClient
{ {
public static void main(String[] args) throws Exception public static void main(String[] args)
{ {
String hostname = "localhost"; String hostname = "localhost";
int port = 9001; int port = 9001;
@ -92,11 +92,25 @@ public class CoreAutobahnClient
} }
} }
CoreAutobahnClient client = null; CoreAutobahnClient client = new CoreAutobahnClient();
client.runAutobahnClient(hostname, port, caseNumbers);
}
private static final Logger LOG = LoggerFactory.getLogger(CoreAutobahnClient.class);
private URI baseWebsocketUri;
private WebSocketCoreClient client;
private String userAgent;
@Override
public void runAutobahnClient(String hostname, int port, int[] caseNumbers)
{
try try
{ {
String userAgent = "JettyWebsocketClient/" + Jetty.VERSION; String userAgent = "CoreWebsocketClient/" + Jetty.VERSION;
client = new CoreAutobahnClient(hostname, port, userAgent); this.userAgent = userAgent;
this.baseWebsocketUri = new URI("ws://" + hostname + ":" + port);
this.client = new WebSocketCoreClient();
this.client.start();
LOG.info("Running test suite..."); LOG.info("Running test suite...");
LOG.info("Using Fuzzing Server: {}:{}", hostname, port); LOG.info("Using Fuzzing Server: {}:{}", hostname, port);
@ -104,12 +118,12 @@ public class CoreAutobahnClient
if (caseNumbers == null) if (caseNumbers == null)
{ {
int caseCount = client.getCaseCount(); int caseCount = getCaseCount();
LOG.info("Will run all {} cases ...", caseCount); LOG.info("Will run all {} cases ...", caseCount);
for (int caseNum = 1; caseNum <= caseCount; caseNum++) for (int caseNum = 1; caseNum <= caseCount; caseNum++)
{ {
LOG.info("Running case {} (of {}) ...", caseNum, caseCount); LOG.info("Running case {} (of {}) ...", caseNum, caseCount);
client.runCaseByNumber(caseNum); runCaseByNumber(caseNum);
} }
} }
else else
@ -117,48 +131,34 @@ public class CoreAutobahnClient
LOG.info("Will run {} cases ...", caseNumbers.length); LOG.info("Will run {} cases ...", caseNumbers.length);
for (int caseNum : caseNumbers) for (int caseNum : caseNumbers)
{ {
client.runCaseByNumber(caseNum); runCaseByNumber(caseNum);
} }
} }
LOG.info("All test cases executed."); LOG.info("All test cases executed.");
client.updateReports(); updateReports();
} }
catch (Throwable t) catch (Throwable t)
{ {
LOG.warn("Test Failed", t); LOG.warn("Test Failed", t);
throw t;
} }
finally finally
{ {
if (client != null) if (client != null)
client.shutdown(); shutdown();
} }
} }
private static final Logger LOG = LoggerFactory.getLogger(CoreAutobahnClient.class);
private final URI baseWebsocketUri;
private final WebSocketCoreClient client;
private final String userAgent;
public CoreAutobahnClient(String hostname, int port, String userAgent) throws Exception
{
this.userAgent = userAgent;
this.baseWebsocketUri = new URI("ws://" + hostname + ":" + port);
this.client = new WebSocketCoreClient();
this.client.start();
}
public int getCaseCount() throws Exception public int getCaseCount() throws Exception
{ {
URI wsUri = baseWebsocketUri.resolve("/getCaseCount"); URI wsUri = baseWebsocketUri.resolve("/getCaseCount");
TestMessageHandler onCaseCount = new TestMessageHandler(); TestMessageHandler onCaseCount = new TestMessageHandler();
CoreSession session = upgrade(onCaseCount, wsUri).get(5, TimeUnit.SECONDS); CoreSession session = upgrade(onCaseCount, wsUri).get(5, TimeUnit.SECONDS);
assertTrue(onCaseCount.openLatch.await(5, TimeUnit.SECONDS)); Assertions.assertTrue(onCaseCount.openLatch.await(5, TimeUnit.SECONDS));
String msg = onCaseCount.textMessages.poll(5, TimeUnit.SECONDS); String msg = onCaseCount.textMessages.poll(5, TimeUnit.SECONDS);
// Close the connection. // Close the connection.
session.close(Callback.NOOP); session.close(Callback.NOOP);
assertTrue(onCaseCount.closeLatch.await(5, TimeUnit.SECONDS)); Assertions.assertTrue(onCaseCount.closeLatch.await(5, TimeUnit.SECONDS));
assertNotNull(msg); assertNotNull(msg);
return Integer.decode(msg); return Integer.decode(msg);
@ -208,7 +208,7 @@ public class CoreAutobahnClient
TestMessageHandler onUpdateReports = new TestMessageHandler(); TestMessageHandler onUpdateReports = new TestMessageHandler();
Future<CoreSession> response = upgrade(onUpdateReports, wsUri); Future<CoreSession> response = upgrade(onUpdateReports, wsUri);
response.get(5, TimeUnit.SECONDS); response.get(5, TimeUnit.SECONDS);
assertTrue(onUpdateReports.closeLatch.await(15, TimeUnit.SECONDS)); Assertions.assertTrue(onUpdateReports.closeLatch.await(15, TimeUnit.SECONDS));
LOG.info("Reports updated."); LOG.info("Reports updated.");
LOG.info("Test suite finished!"); LOG.info("Test suite finished!");
} }

View File

@ -11,14 +11,13 @@
// ======================================================================== // ========================================================================
// //
package org.eclipse.jetty.websocket.core.autobahn; package org.eclipse.jetty.websocket.tests.core;
import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.websocket.core.TestWebSocketNegotiator;
import org.eclipse.jetty.websocket.core.WebSocketComponents; import org.eclipse.jetty.websocket.core.WebSocketComponents;
import org.eclipse.jetty.websocket.core.server.WebSocketUpgradeHandler; import org.eclipse.jetty.websocket.core.server.WebSocketUpgradeHandler;
import org.eclipse.jetty.websocket.tests.AutobahnServer;
/** /**
* WebSocket Server for use with <a href="https://github.com/crossbario/autobahn-testsuite">autobahn websocket testsuite</a> (wstest). * WebSocket Server for use with <a href="https://github.com/crossbario/autobahn-testsuite">autobahn websocket testsuite</a> (wstest).
@ -54,7 +53,7 @@ import org.eclipse.jetty.websocket.core.server.WebSocketUpgradeHandler;
* $ ls target/reports/servers/ * $ ls target/reports/servers/
* </pre> * </pre>
*/ */
public class CoreAutobahnServer public class CoreAutobahnServer implements AutobahnServer
{ {
public static void main(String[] args) throws Exception public static void main(String[] args) throws Exception
{ {
@ -62,25 +61,36 @@ public class CoreAutobahnServer
if (args != null && args.length > 0) if (args != null && args.length > 0)
port = Integer.parseInt(args[0]); port = Integer.parseInt(args[0]);
Server server = startAutobahnServer(port); CoreAutobahnServer server = new CoreAutobahnServer();
server.startAutobahnServer(port);
server.join(); server.join();
} }
public static Server startAutobahnServer(int port) throws Exception private Server _server;
public void startAutobahnServer(int port) throws Exception
{ {
Server server = new Server(port); _server = new Server();
ServerConnector connector = new ServerConnector(server); ServerConnector connector = new ServerConnector(_server);
connector.setIdleTimeout(10000); connector.setPort(port);
server.addConnector(connector); _server.addConnector(connector);
ContextHandler context = new ContextHandler("/");
server.setHandler(context);
WebSocketComponents components = new WebSocketComponents(); WebSocketComponents components = new WebSocketComponents();
WebSocketUpgradeHandler handler = new WebSocketUpgradeHandler(components); WebSocketUpgradeHandler handler = new WebSocketUpgradeHandler(components);
handler.addMapping("/*", new TestWebSocketNegotiator(new AutobahnFrameHandler())); handler.addMapping("/*", new TestWebSocketNegotiator(new AutobahnFrameHandler()));
_server.setHandler(handler);
context.setHandler(handler); _server.start();
server.start(); }
return server;
@Override
public void stopAutobahnServer() throws Exception
{
_server.stop();
}
public void join() throws InterruptedException
{
_server.join();
} }
} }

View File

@ -0,0 +1,82 @@
//
// ========================================================================
// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
package org.eclipse.jetty.websocket.tests.core;
import java.nio.ByteBuffer;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CountDownLatch;
import org.eclipse.jetty.util.BlockingArrayQueue;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.websocket.core.CloseStatus;
import org.eclipse.jetty.websocket.core.CoreSession;
import org.eclipse.jetty.websocket.core.internal.MessageHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TestMessageHandler extends MessageHandler
{
protected static final Logger LOG = LoggerFactory.getLogger(TestMessageHandler.class);
public CoreSession coreSession;
public BlockingQueue<String> textMessages = new BlockingArrayQueue<>();
public BlockingQueue<ByteBuffer> binaryMessages = new BlockingArrayQueue<>();
public CloseStatus closeStatus;
public volatile Throwable error;
public CountDownLatch openLatch = new CountDownLatch(1);
public CountDownLatch errorLatch = new CountDownLatch(1);
public CountDownLatch closeLatch = new CountDownLatch(1);
@Override
public void onOpen(CoreSession coreSession, Callback callback)
{
super.onOpen(coreSession, callback);
this.coreSession = coreSession;
openLatch.countDown();
}
@Override
public void onError(Throwable cause, Callback callback)
{
super.onError(cause, callback);
error = cause;
errorLatch.countDown();
}
@Override
public void onClosed(CloseStatus closeStatus, Callback callback)
{
super.onClosed(closeStatus, callback);
this.closeStatus = closeStatus;
closeLatch.countDown();
}
@Override
protected void onText(String message, Callback callback)
{
if (LOG.isDebugEnabled())
LOG.debug("onText {}", message);
textMessages.offer(message);
callback.succeeded();
}
@Override
protected void onBinary(ByteBuffer message, Callback callback)
{
if (LOG.isDebugEnabled())
LOG.debug("onBinary {}", message);
binaryMessages.offer(message);
callback.succeeded();
}
}

View File

@ -0,0 +1,47 @@
//
// ========================================================================
// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
package org.eclipse.jetty.websocket.tests.core;
import java.io.IOException;
import java.util.List;
import org.eclipse.jetty.websocket.core.FrameHandler;
import org.eclipse.jetty.websocket.core.server.WebSocketNegotiation;
import org.eclipse.jetty.websocket.core.server.WebSocketNegotiator;
public class TestWebSocketNegotiator extends WebSocketNegotiator.AbstractNegotiator
{
private final FrameHandler frameHandler;
public TestWebSocketNegotiator(FrameHandler frameHandler)
{
this(frameHandler, null);
}
public TestWebSocketNegotiator(FrameHandler frameHandler, Customizer customizer)
{
super(customizer);
this.frameHandler = frameHandler;
}
@Override
public FrameHandler negotiate(WebSocketNegotiation negotiation) throws IOException
{
List<String> offeredSubprotocols = negotiation.getOfferedSubprotocols();
if (!offeredSubprotocols.isEmpty())
negotiation.setSubprotocol(offeredSubprotocols.get(0));
return frameHandler;
}
}

View File

@ -0,0 +1,38 @@
//
// ========================================================================
// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
package org.eclipse.jetty.websocket.tests.javax;
import java.io.IOException;
import java.nio.ByteBuffer;
import javax.websocket.ClientEndpoint;
import javax.websocket.server.ServerEndpoint;
@ServerEndpoint("/")
@ClientEndpoint(configurator = HostConfigurator.class)
public class EchoSocket extends EventSocket
{
@Override
public void onMessage(String message) throws IOException
{
super.onMessage(message);
session.getBasicRemote().sendText(message);
}
@Override
public void onMessage(ByteBuffer message) throws IOException
{
super.onMessage(message);
session.getBasicRemote().sendBinary(message);
}
}

View File

@ -0,0 +1,96 @@
//
// ========================================================================
// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
package org.eclipse.jetty.websocket.tests.javax;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CountDownLatch;
import javax.websocket.ClientEndpoint;
import javax.websocket.CloseReason;
import javax.websocket.EndpointConfig;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import org.eclipse.jetty.util.BlockingArrayQueue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ServerEndpoint("/")
@ClientEndpoint(configurator = HostConfigurator.class)
public class EventSocket
{
private static final Logger LOG = LoggerFactory.getLogger(EventSocket.class);
public Session session;
public EndpointConfig endpointConfig;
public BlockingQueue<String> textMessages = new BlockingArrayQueue<>();
public BlockingQueue<ByteBuffer> binaryMessages = new BlockingArrayQueue<>();
public volatile Throwable error = null;
public volatile CloseReason closeReason = null;
public CountDownLatch openLatch = new CountDownLatch(1);
public CountDownLatch closeLatch = new CountDownLatch(1);
public CountDownLatch errorLatch = new CountDownLatch(1);
@OnOpen
public void onOpen(Session session, EndpointConfig endpointConfig)
{
this.session = session;
this.endpointConfig = endpointConfig;
if (LOG.isDebugEnabled())
LOG.debug("{} onOpen(): {}", toString(), session);
openLatch.countDown();
}
@OnMessage
public void onMessage(String message) throws IOException
{
if (LOG.isDebugEnabled())
LOG.debug("{} onMessage(): {}", toString(), message);
textMessages.offer(message);
}
@OnMessage
public void onMessage(ByteBuffer message) throws IOException
{
if (LOG.isDebugEnabled())
LOG.debug("{} onMessage(): {}", toString(), message);
binaryMessages.offer(message);
}
@OnClose
public void onClose(CloseReason reason)
{
if (LOG.isDebugEnabled())
LOG.debug("{} onClose(): {}", toString(), reason);
closeReason = reason;
closeLatch.countDown();
}
@OnError
public void onError(Throwable cause)
{
if (LOG.isDebugEnabled())
LOG.debug("{} onError(): {}", toString(), cause);
error = cause;
errorLatch.countDown();
}
}

View File

@ -0,0 +1,30 @@
//
// ========================================================================
// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
package org.eclipse.jetty.websocket.tests.javax;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import javax.websocket.ClientEndpointConfig;
import org.eclipse.jetty.http.HttpHeader;
public class HostConfigurator extends ClientEndpointConfig.Configurator
{
@Override
public void beforeRequest(Map<String, List<String>> headers)
{
headers.put(HttpHeader.HOST.asString(), Collections.singletonList("localhost:9001"));
}
}

View File

@ -11,7 +11,7 @@
// ======================================================================== // ========================================================================
// //
package org.eclipse.jetty.websocket.javax.tests.autobahn; package org.eclipse.jetty.websocket.tests.javax;
import java.net.URI; import java.net.URI;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -21,7 +21,8 @@ import org.eclipse.jetty.util.Jetty;
import org.eclipse.jetty.util.UrlEncoded; import org.eclipse.jetty.util.UrlEncoded;
import org.eclipse.jetty.util.component.LifeCycle; import org.eclipse.jetty.util.component.LifeCycle;
import org.eclipse.jetty.websocket.javax.client.internal.JavaxWebSocketClientContainer; import org.eclipse.jetty.websocket.javax.client.internal.JavaxWebSocketClientContainer;
import org.eclipse.jetty.websocket.javax.tests.EventSocket; import org.eclipse.jetty.websocket.tests.AutobahnClient;
import org.eclipse.jetty.websocket.tests.jetty.JettyAutobahnClient;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -62,7 +63,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
* $ ls target/reports/clients/ * $ ls target/reports/clients/
* </pre> * </pre>
*/ */
public class JavaxAutobahnClient public class JavaxAutobahnClient implements AutobahnClient
{ {
public static void main(String[] args) public static void main(String[] args)
{ {
@ -87,46 +88,8 @@ public class JavaxAutobahnClient
} }
} }
JavaxAutobahnClient client = null; JettyAutobahnClient client = new JettyAutobahnClient();
try client.runAutobahnClient(hostname, port, caseNumbers);
{
String userAgent = "JettyWebsocketClient/" + Jetty.VERSION;
client = new JavaxAutobahnClient(hostname, port, userAgent);
LOG.info("Running test suite...");
LOG.info("Using Fuzzing Server: {}:{}", hostname, port);
LOG.info("User Agent: {}", userAgent);
if (caseNumbers == null)
{
int caseCount = client.getCaseCount();
LOG.info("Will run all {} cases ...", caseCount);
for (int caseNum = 1; caseNum <= caseCount; caseNum++)
{
LOG.info("Running case {} (of {}) ...", caseNum, caseCount);
client.runCaseByNumber(caseNum);
}
}
else
{
LOG.info("Will run {} cases ...", caseNumbers.length);
for (int caseNum : caseNumbers)
{
client.runCaseByNumber(caseNum);
}
}
LOG.info("All test cases executed.");
client.updateReports();
}
catch (Throwable t)
{
LOG.warn("Test Failed", t);
}
finally
{
if (client != null)
client.stop();
}
} }
private static final Logger LOG = LoggerFactory.getLogger(JavaxAutobahnClient.class); private static final Logger LOG = LoggerFactory.getLogger(JavaxAutobahnClient.class);
@ -134,15 +97,53 @@ public class JavaxAutobahnClient
private JavaxWebSocketClientContainer clientContainer; private JavaxWebSocketClientContainer clientContainer;
private String userAgent; private String userAgent;
public JavaxAutobahnClient(String hostname, int port, String userAgent) throws Exception @Override
public void runAutobahnClient(String hostname, int port, int[] caseNumbers)
{ {
this.userAgent = userAgent; try
this.baseWebsocketUri = new URI("ws://" + hostname + ":" + port); {
this.clientContainer = new JavaxWebSocketClientContainer(); String userAgent = "JavaxWebsocketClient/" + Jetty.VERSION;
clientContainer.start(); this.userAgent = userAgent;
this.baseWebsocketUri = new URI("ws://" + hostname + ":" + port);
this.clientContainer = new JavaxWebSocketClientContainer();
clientContainer.start();
LOG.info("Running test suite...");
LOG.info("Using Fuzzing Server: {}:{}", hostname, port);
LOG.info("User Agent: {}", userAgent);
if (caseNumbers == null)
{
int caseCount = getCaseCount();
LOG.info("Will run all {} cases ...", caseCount);
for (int caseNum = 1; caseNum <= caseCount; caseNum++)
{
LOG.info("Running case {} (of {}) ...", caseNum, caseCount);
runCaseByNumber(caseNum);
}
}
else
{
LOG.info("Will run {} cases ...", caseNumbers.length);
for (int caseNum : caseNumbers)
{
runCaseByNumber(caseNum);
}
}
LOG.info("All test cases executed.");
updateReports();
}
catch (Throwable t)
{
LOG.warn("Test Failed", t);
}
finally
{
shutdown();
}
} }
public void stop() public void shutdown()
{ {
LifeCycle.stop(clientContainer); LifeCycle.stop(clientContainer);
} }

View File

@ -11,12 +11,13 @@
// ======================================================================== // ========================================================================
// //
package org.eclipse.jetty.websocket.javax.tests.autobahn; package org.eclipse.jetty.websocket.tests.javax;
import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.websocket.javax.server.config.JavaxWebSocketServletContainerInitializer; import org.eclipse.jetty.websocket.javax.server.config.JavaxWebSocketServletContainerInitializer;
import org.eclipse.jetty.websocket.tests.AutobahnServer;
/** /**
* WebSocket Server for use with <a href="https://github.com/crossbario/autobahn-testsuite">autobahn websocket testsuite</a> (wstest). * WebSocket Server for use with <a href="https://github.com/crossbario/autobahn-testsuite">autobahn websocket testsuite</a> (wstest).
@ -52,7 +53,7 @@ import org.eclipse.jetty.websocket.javax.server.config.JavaxWebSocketServletCont
* $ ls target/reports/servers/ * $ ls target/reports/servers/
* </pre> * </pre>
*/ */
public class JavaxAutobahnServer public class JavaxAutobahnServer implements AutobahnServer
{ {
public static void main(String[] args) throws Exception public static void main(String[] args) throws Exception
{ {
@ -60,18 +61,38 @@ public class JavaxAutobahnServer
if (args != null && args.length > 0) if (args != null && args.length > 0)
port = Integer.parseInt(args[0]); port = Integer.parseInt(args[0]);
Server server = new Server(port); JavaxAutobahnServer server = new JavaxAutobahnServer();
ServerConnector connector = new ServerConnector(server); server.startAutobahnServer(port);
connector.setIdleTimeout(10000); server.join();
server.addConnector(connector); }
private Server _server;
public void startAutobahnServer(int port) throws Exception
{
_server = new Server();
ServerConnector connector = new ServerConnector(_server);
connector.setPort(port);
_server.addConnector(connector);
ServletContextHandler context = new ServletContextHandler(); ServletContextHandler context = new ServletContextHandler();
context.setContextPath("/"); context.setContextPath("/");
server.setHandler(context); _server.setHandler(context);
JavaxWebSocketServletContainerInitializer.configure(context, (servletContext, container) -> JavaxWebSocketServletContainerInitializer.configure(context, (servletContext, container) ->
container.addEndpoint(JavaxAutobahnSocket.class)); container.addEndpoint(JavaxAutobahnSocket.class));
server.start(); _server.start();
server.join(); }
@Override
public void stopAutobahnServer() throws Exception
{
_server.stop();
}
public void join() throws InterruptedException
{
_server.join();
} }
} }

View File

@ -11,7 +11,7 @@
// ======================================================================== // ========================================================================
// //
package org.eclipse.jetty.websocket.javax.tests.autobahn; package org.eclipse.jetty.websocket.tests.javax;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
@ -27,7 +27,7 @@ import javax.websocket.server.ServerEndpoint;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ClientEndpoint @ClientEndpoint(configurator = HostConfigurator.class)
@ServerEndpoint("/") @ServerEndpoint("/")
public class JavaxAutobahnSocket public class JavaxAutobahnSocket
{ {

View File

@ -0,0 +1,37 @@
//
// ========================================================================
// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
package org.eclipse.jetty.websocket.tests.jetty;
import java.io.IOException;
import java.nio.ByteBuffer;
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
@WebSocket
public class EchoSocket extends EventSocket
{
@Override
public void onMessage(String message) throws IOException
{
super.onMessage(message);
session.getRemote().sendString(message);
}
@Override
public void onMessage(byte[] buf, int offset, int len) throws IOException
{
super.onMessage(buf, offset, len);
session.getRemote().sendBytes(ByteBuffer.wrap(buf, offset, len));
}
}

View File

@ -0,0 +1,101 @@
//
// ========================================================================
// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
package org.eclipse.jetty.websocket.tests.jetty;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CountDownLatch;
import org.eclipse.jetty.util.BlockingArrayQueue;
import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.api.StatusCode;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@WebSocket
public class EventSocket
{
private static final Logger LOG = LoggerFactory.getLogger(EventSocket.class);
public Session session;
private String behavior;
public BlockingQueue<String> textMessages = new BlockingArrayQueue<>();
public BlockingQueue<ByteBuffer> binaryMessages = new BlockingArrayQueue<>();
public volatile int closeCode = StatusCode.UNDEFINED;
public volatile String closeReason;
public volatile Throwable error = null;
public CountDownLatch openLatch = new CountDownLatch(1);
public CountDownLatch errorLatch = new CountDownLatch(1);
public CountDownLatch closeLatch = new CountDownLatch(1);
@OnWebSocketConnect
public void onOpen(Session session)
{
this.session = session;
behavior = session.getPolicy().getBehavior().name();
if (LOG.isDebugEnabled())
LOG.debug("{} onOpen(): {}", toString(), session);
openLatch.countDown();
}
@OnWebSocketMessage
public void onMessage(String message) throws IOException
{
if (LOG.isDebugEnabled())
LOG.debug("{} onMessage(): {}", toString(), message);
textMessages.offer(message);
}
@OnWebSocketMessage
public void onMessage(byte[] buf, int offset, int len) throws IOException
{
ByteBuffer message = ByteBuffer.wrap(buf, offset, len);
if (LOG.isDebugEnabled())
LOG.debug("{} onMessage(): {}", toString(), message);
binaryMessages.offer(message);
}
@OnWebSocketClose
public void onClose(int statusCode, String reason)
{
if (LOG.isDebugEnabled())
LOG.debug("{} onClose(): {}:{}", toString(), statusCode, reason);
this.closeCode = statusCode;
this.closeReason = reason;
closeLatch.countDown();
}
@OnWebSocketError
public void onError(Throwable cause)
{
if (LOG.isDebugEnabled())
LOG.debug("{} onError(): {}", toString(), cause);
error = cause;
errorLatch.countDown();
}
@Override
public String toString()
{
return String.format("[%s@%s]", behavior, Integer.toHexString(hashCode()));
}
}

View File

@ -11,28 +11,25 @@
// ======================================================================== // ========================================================================
// //
package org.eclipse.jetty.websocket.tests.autobahn; package org.eclipse.jetty.websocket.tests.jetty;
import java.io.IOException;
import java.net.URI; import java.net.URI;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.util.Jetty; import org.eclipse.jetty.util.Jetty;
import org.eclipse.jetty.util.UrlEncoded; import org.eclipse.jetty.util.UrlEncoded;
import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.api.StatusCode; import org.eclipse.jetty.websocket.api.StatusCode;
import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
import org.eclipse.jetty.websocket.client.WebSocketClient; import org.eclipse.jetty.websocket.client.WebSocketClient;
import org.eclipse.jetty.websocket.tests.EchoSocket; import org.eclipse.jetty.websocket.tests.AutobahnClient;
import org.eclipse.jetty.websocket.tests.EventSocket; import org.junit.jupiter.api.Assertions;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
/** /**
* WebSocket Client for use with <a href="https://github.com/crossbario/autobahn-testsuite">autobahn websocket testsuite</a> (wstest). * WebSocket Client for use with <a href="https://github.com/crossbario/autobahn-testsuite">autobahn websocket testsuite</a> (wstest).
@ -68,7 +65,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
* $ ls target/reports/clients/ * $ ls target/reports/clients/
* </pre> * </pre>
*/ */
public class JettyAutobahnClient public class JettyAutobahnClient implements AutobahnClient
{ {
public static void main(String[] args) public static void main(String[] args)
{ {
@ -93,46 +90,8 @@ public class JettyAutobahnClient
} }
} }
JettyAutobahnClient client = null; JettyAutobahnClient client = new JettyAutobahnClient();
try client.runAutobahnClient(hostname, port, caseNumbers);
{
String userAgent = "JettyWebsocketClient/" + Jetty.VERSION;
client = new JettyAutobahnClient(hostname, port, userAgent);
LOG.info("Running test suite...");
LOG.info("Using Fuzzing Server: {}:{}", hostname, port);
LOG.info("User Agent: {}", userAgent);
if (caseNumbers == null)
{
int caseCount = client.getCaseCount();
LOG.info("Will run all {} cases ...", caseCount);
for (int caseNum = 1; caseNum <= caseCount; caseNum++)
{
LOG.info("Running case {} (of {}) ...", caseNum, caseCount);
client.runCaseByNumber(caseNum);
}
}
else
{
LOG.info("Will run {} cases ...", caseNumbers.length);
for (int caseNum : caseNumbers)
{
client.runCaseByNumber(caseNum);
}
}
LOG.info("All test cases executed.");
client.updateReports();
}
catch (Throwable t)
{
LOG.warn("Test Failed", t);
}
finally
{
if (client != null)
client.shutdown();
}
} }
private static final Logger LOG = LoggerFactory.getLogger(JettyAutobahnClient.class); private static final Logger LOG = LoggerFactory.getLogger(JettyAutobahnClient.class);
@ -140,38 +99,76 @@ public class JettyAutobahnClient
private WebSocketClient client; private WebSocketClient client;
private String userAgent; private String userAgent;
public JettyAutobahnClient(String hostname, int port, String userAgent) throws Exception @Override
public void runAutobahnClient(String hostname, int port, int[] caseNumbers)
{ {
this.userAgent = userAgent; try
this.baseWebsocketUri = new URI("ws://" + hostname + ":" + port); {
this.client = new WebSocketClient(); String userAgent = "JettyWebsocketClient/" + Jetty.VERSION;
this.client.start(); this.userAgent = userAgent;
this.baseWebsocketUri = new URI("ws://" + hostname + ":" + port);
this.client = new WebSocketClient();
this.client.start();
LOG.info("Running test suite...");
LOG.info("Using Fuzzing Server: {}:{}", hostname, port);
LOG.info("User Agent: {}", userAgent);
if (caseNumbers == null)
{
int caseCount = getCaseCount();
LOG.info("Will run all {} cases ...", caseCount);
for (int caseNum = 1; caseNum <= caseCount; caseNum++)
{
LOG.info("Running case {} (of {}) ...", caseNum, caseCount);
runCaseByNumber(caseNum);
}
}
else
{
LOG.info("Will run {} cases ...", caseNumbers.length);
for (int caseNum : caseNumbers)
{
runCaseByNumber(caseNum);
}
}
LOG.info("All test cases executed.");
updateReports();
}
catch (Throwable t)
{
LOG.warn("Test Failed", t);
}
finally
{
shutdown();
}
} }
public int getCaseCount() throws IOException, InterruptedException public int getCaseCount() throws Exception
{ {
URI wsUri = baseWebsocketUri.resolve("/getCaseCount"); URI wsUri = baseWebsocketUri.resolve("/getCaseCount");
EventSocket onCaseCount = new EventSocket(); EventSocket onCaseCount = new EventSocket();
CompletableFuture<Session> response = client.connect(onCaseCount, wsUri); Future<Session> response = upgrade(onCaseCount, wsUri);
if (waitForUpgrade(wsUri, response)) if (waitForUpgrade(wsUri, response))
{ {
String msg = onCaseCount.textMessages.poll(10, TimeUnit.SECONDS); String msg = onCaseCount.textMessages.poll(10, TimeUnit.SECONDS);
onCaseCount.session.close(StatusCode.SHUTDOWN, null); onCaseCount.session.close(StatusCode.SHUTDOWN, null);
assertTrue(onCaseCount.closeLatch.await(2, TimeUnit.SECONDS)); Assertions.assertTrue(onCaseCount.closeLatch.await(2, TimeUnit.SECONDS));
assertNotNull(msg); assertNotNull(msg);
return Integer.decode(msg); return Integer.decode(msg);
} }
throw new IllegalStateException("Unable to get Case Count"); throw new IllegalStateException("Unable to get Case Count");
} }
public void runCaseByNumber(int caseNumber) throws IOException, InterruptedException public void runCaseByNumber(int caseNumber) throws Exception
{ {
URI wsUri = baseWebsocketUri.resolve("/runCase?case=" + caseNumber + "&agent=" + UrlEncoded.encodeString(userAgent)); URI wsUri = baseWebsocketUri.resolve("/runCase?case=" + caseNumber + "&agent=" + UrlEncoded.encodeString(userAgent));
LOG.info("test uri: {}", wsUri); LOG.info("test uri: {}", wsUri);
EchoSocket echoHandler = new JettyAutobahnSocket(); EchoSocket echoHandler = new JettyAutobahnSocket();
Future<Session> response = client.connect(echoHandler, wsUri); Future<Session> response = upgrade(echoHandler, wsUri);
if (waitForUpgrade(wsUri, response)) if (waitForUpgrade(wsUri, response))
{ {
// Wait up to 5 min as some of the tests can take a while // Wait up to 5 min as some of the tests can take a while
@ -195,13 +192,21 @@ public class JettyAutobahnClient
} }
} }
public void updateReports() throws IOException, InterruptedException, ExecutionException, TimeoutException public Future<Session> upgrade(Object handler, URI uri) throws Exception
{
// We manually set the port as we run the server in docker container.
ClientUpgradeRequest upgradeRequest = new ClientUpgradeRequest();
upgradeRequest.setHeader(HttpHeader.HOST.asString(), "localhost:9001");
return client.connect(handler, uri, upgradeRequest);
}
public void updateReports() throws Exception
{ {
URI wsUri = baseWebsocketUri.resolve("/updateReports?agent=" + UrlEncoded.encodeString(userAgent)); URI wsUri = baseWebsocketUri.resolve("/updateReports?agent=" + UrlEncoded.encodeString(userAgent));
EventSocket onUpdateReports = new EventSocket(); EventSocket onUpdateReports = new EventSocket();
Future<Session> response = client.connect(onUpdateReports, wsUri); Future<Session> response = upgrade(onUpdateReports, wsUri);
response.get(5, TimeUnit.SECONDS); response.get(5, TimeUnit.SECONDS);
assertTrue(onUpdateReports.closeLatch.await(15, TimeUnit.SECONDS)); Assertions.assertTrue(onUpdateReports.closeLatch.await(15, TimeUnit.SECONDS));
LOG.info("Reports updated."); LOG.info("Reports updated.");
LOG.info("Test suite finished!"); LOG.info("Test suite finished!");
} }

View File

@ -11,12 +11,13 @@
// ======================================================================== // ========================================================================
// //
package org.eclipse.jetty.websocket.tests.autobahn; package org.eclipse.jetty.websocket.tests.jetty;
import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer; import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer;
import org.eclipse.jetty.websocket.tests.AutobahnServer;
/** /**
* WebSocket Server for use with <a href="https://github.com/crossbario/autobahn-testsuite">autobahn websocket testsuite</a> (wstest). * WebSocket Server for use with <a href="https://github.com/crossbario/autobahn-testsuite">autobahn websocket testsuite</a> (wstest).
@ -52,7 +53,7 @@ import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerI
* $ ls target/reports/servers/ * $ ls target/reports/servers/
* </pre> * </pre>
*/ */
public class JettyAutobahnServer public class JettyAutobahnServer implements AutobahnServer
{ {
public static void main(String[] args) throws Exception public static void main(String[] args) throws Exception
{ {
@ -60,18 +61,39 @@ public class JettyAutobahnServer
if (args != null && args.length > 0) if (args != null && args.length > 0)
port = Integer.parseInt(args[0]); port = Integer.parseInt(args[0]);
Server server = new Server(port); JettyAutobahnServer server = new JettyAutobahnServer();
ServerConnector connector = new ServerConnector(server); server.startAutobahnServer(port);
connector.setIdleTimeout(10000); server.join();
server.addConnector(connector); }
private Server _server;
@Override
public void startAutobahnServer(int port) throws Exception
{
_server = new Server();
ServerConnector connector = new ServerConnector(_server);
connector.setPort(port);
_server.addConnector(connector);
ServletContextHandler context = new ServletContextHandler(); ServletContextHandler context = new ServletContextHandler();
context.setContextPath("/"); context.setContextPath("/");
server.setHandler(context); _server.setHandler(context);
JettyWebSocketServletContainerInitializer.configure(context, (servletContext, container) -> JettyWebSocketServletContainerInitializer.configure(context, (servletContext, container) ->
container.addMapping("/", (req, resp) -> new JettyAutobahnSocket())); container.addMapping("/", (req, resp) -> new JettyAutobahnSocket()));
server.start(); _server.start();
server.join(); }
@Override
public void stopAutobahnServer() throws Exception
{
_server.stop();
}
public void join() throws InterruptedException
{
_server.join();
} }
} }

View File

@ -11,12 +11,11 @@
// ======================================================================== // ========================================================================
// //
package org.eclipse.jetty.websocket.tests.autobahn; package org.eclipse.jetty.websocket.tests.jetty;
import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.api.annotations.WebSocket; import org.eclipse.jetty.websocket.api.annotations.WebSocket;
import org.eclipse.jetty.websocket.core.WebSocketConstants; import org.eclipse.jetty.websocket.core.WebSocketConstants;
import org.eclipse.jetty.websocket.tests.EchoSocket;
@WebSocket @WebSocket
public class JettyAutobahnSocket extends EchoSocket public class JettyAutobahnSocket extends EchoSocket

View File

@ -0,0 +1,4 @@
org.slf4j.simpleLogger.defaultLogLevel=info
org.slf4j.simpleLogger.showDateTime=true
org.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd HH:mm:ss
org.slf4j.simpleLogger.log.org.eclipse.jetty.websocket.tests=info