From 5df19609aebb974946eb055c313305f564f52f7f Mon Sep 17 00:00:00 2001 From: TomlongTK Date: Mon, 8 Jul 2024 12:06:50 +0800 Subject: [PATCH] WebSocket test cases --- .../case-configuration.yml | 57 +++++++ .../case-versions.conf | 25 +++ .../dubbo-samples-triple-websocket/pom.xml | 126 ++++++++++++++ .../dubbo/tri/websocket/demo/DemoService.java | 39 +++++ .../tri/websocket/demo/DemoServiceImpl.java | 121 ++++++++++++++ .../demo/WebSocketDemoApplication.java | 30 ++++ .../src/main/resources/application.yml | 30 ++++ .../tri/websocket/demo/test/HelloClient.java | 81 +++++++++ .../demo/test/WebSocketWithNettyTest.java | 156 ++++++++++++++++++ .../demo/test/WebSocketWithTomcatTest.java | 154 +++++++++++++++++ 2-advanced/pom.xml | 1 + 11 files changed, 820 insertions(+) create mode 100644 2-advanced/dubbo-samples-triple-websocket/case-configuration.yml create mode 100644 2-advanced/dubbo-samples-triple-websocket/case-versions.conf create mode 100644 2-advanced/dubbo-samples-triple-websocket/pom.xml create mode 100644 2-advanced/dubbo-samples-triple-websocket/src/main/java/org/apache/dubbo/tri/websocket/demo/DemoService.java create mode 100644 2-advanced/dubbo-samples-triple-websocket/src/main/java/org/apache/dubbo/tri/websocket/demo/DemoServiceImpl.java create mode 100644 2-advanced/dubbo-samples-triple-websocket/src/main/java/org/apache/dubbo/tri/websocket/demo/WebSocketDemoApplication.java create mode 100644 2-advanced/dubbo-samples-triple-websocket/src/main/resources/application.yml create mode 100644 2-advanced/dubbo-samples-triple-websocket/src/test/java/org/apache/dubbo/tri/websocket/demo/test/HelloClient.java create mode 100644 2-advanced/dubbo-samples-triple-websocket/src/test/java/org/apache/dubbo/tri/websocket/demo/test/WebSocketWithNettyTest.java create mode 100644 2-advanced/dubbo-samples-triple-websocket/src/test/java/org/apache/dubbo/tri/websocket/demo/test/WebSocketWithTomcatTest.java diff --git a/2-advanced/dubbo-samples-triple-websocket/case-configuration.yml b/2-advanced/dubbo-samples-triple-websocket/case-configuration.yml new file mode 100644 index 0000000000..45c7344fca --- /dev/null +++ b/2-advanced/dubbo-samples-triple-websocket/case-configuration.yml @@ -0,0 +1,57 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +services: + nacos: + image: nacos/nacos-server:${nacos-server.version:2.0.0} + environment: + - PREFER_HOST_MODE=hostname + - MODE=standalone + - NACOS_AUTH_ENABLE=true + - JVM_XMS=512m + - JVM_XMX=512m + - JVM_XMN=256m + + tri-websocket-server: + type: app + basedir: . + mainClass: org.apache.dubbo.tri.websocket.demo.WebSocketDemoApplication + systemProps: + - nacos.address=nacos + - nacos.port=8848 + waitPortsBeforeRun: + - nacos:8848 + checkPorts: + - 50052 + checkLog: "Current Spring Boot Application is await..." + depends_on: + - nacos + + test: + type: test + basedir: . + tests: + - "**/*Test.class" + systemProps: + - nacos.address=nacos + - nacos.port=8848 + - dubbo.address=tri-websocket-server + waitPortsBeforeRun: + - nacos:8848 + - tri-websocket-server:50052 + depends_on: + - nacos + - tri-websocket-server diff --git a/2-advanced/dubbo-samples-triple-websocket/case-versions.conf b/2-advanced/dubbo-samples-triple-websocket/case-versions.conf new file mode 100644 index 0000000000..427d630019 --- /dev/null +++ b/2-advanced/dubbo-samples-triple-websocket/case-versions.conf @@ -0,0 +1,25 @@ +# +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + + +# Supported component versions of the test case + +# Spring app +dubbo.version=3.3.* +spring.version=4.*, 5.* +java.version= [>= 8] diff --git a/2-advanced/dubbo-samples-triple-websocket/pom.xml b/2-advanced/dubbo-samples-triple-websocket/pom.xml new file mode 100644 index 0000000000..74f749be85 --- /dev/null +++ b/2-advanced/dubbo-samples-triple-websocket/pom.xml @@ -0,0 +1,126 @@ + + + + + org.apache + apache + 23 + + + 4.0.0 + + dubbo-samples-triple-websocket + + + 1.8 + 1.8 + UTF-8 + + 3.3.0-beta.5-SNAPSHOT + 2.7.18 + 1.5.6 + 4.0.1 + 9.0.83 + 4.13.2 + + 3.7.0 + + + + + + org.apache.dubbo + dubbo-dependencies-bom + ${dubbo.version} + pom + import + + + org.springframework.boot + spring-boot-dependencies + ${spring-boot.version} + pom + import + + + + + + + org.apache.dubbo + dubbo-spring-boot-starter + ${dubbo.version} + + + org.apache.dubbo + dubbo-nacos-spring-boot-starter + ${dubbo.version} + + + + org.springframework.boot + spring-boot-starter-web + ${spring-boot.version} + + + + javax.servlet + javax.servlet-api + ${servlet.version} + + + + org.apache.tomcat.embed + tomcat-embed-core + ${tomcat.version} + + + + org.springframework.boot + spring-boot-starter-test + ${spring-boot.version} + test + + + + org.java-websocket + Java-WebSocket + ${java-websocket.version} + test + + + + junit + junit + ${junit.version} + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + + + diff --git a/2-advanced/dubbo-samples-triple-websocket/src/main/java/org/apache/dubbo/tri/websocket/demo/DemoService.java b/2-advanced/dubbo-samples-triple-websocket/src/main/java/org/apache/dubbo/tri/websocket/demo/DemoService.java new file mode 100644 index 0000000000..0a2194211f --- /dev/null +++ b/2-advanced/dubbo-samples-triple-websocket/src/main/java/org/apache/dubbo/tri/websocket/demo/DemoService.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.tri.websocket.demo; + +import org.apache.dubbo.common.stream.StreamObserver; + +public interface DemoService { + + String sayHello(String name); + + String sayHelloError(String name); + + void greetServerStream(String request, StreamObserver response); + + void greetServerStreamError(String request, StreamObserver response); + + void greetServerStreamDirectError(String request, StreamObserver response); + + StreamObserver greetBiStream(StreamObserver response); + + StreamObserver greetBiStreamError(StreamObserver response); + + StreamObserver greetBiStreamDirectError(StreamObserver response); + +} diff --git a/2-advanced/dubbo-samples-triple-websocket/src/main/java/org/apache/dubbo/tri/websocket/demo/DemoServiceImpl.java b/2-advanced/dubbo-samples-triple-websocket/src/main/java/org/apache/dubbo/tri/websocket/demo/DemoServiceImpl.java new file mode 100644 index 0000000000..9e70302252 --- /dev/null +++ b/2-advanced/dubbo-samples-triple-websocket/src/main/java/org/apache/dubbo/tri/websocket/demo/DemoServiceImpl.java @@ -0,0 +1,121 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.tri.websocket.demo; + +import org.apache.dubbo.common.stream.StreamObserver; +import org.apache.dubbo.config.annotation.DubboService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@DubboService +public class DemoServiceImpl implements DemoService { + + private static final Logger LOGGER = LoggerFactory.getLogger(DemoServiceImpl.class); + + @Override + public String sayHello(String name) { + return "Hello, " + name; + } + + @Override + public String sayHelloError(String name) { + throw new RuntimeException("test error: " + name); + } + + @Override + public void greetServerStream(String request, StreamObserver response) { + for (int i = 0; i < 10; i++) { + response.onNext("Hello, " + request + i); + } + response.onCompleted(); + } + + @Override + public void greetServerStreamError(String request, StreamObserver response) { + response.onError(new RuntimeException("test error: " + request)); + } + + @Override + public void greetServerStreamDirectError(String request, StreamObserver response) { + throw new RuntimeException("test direct error: " + request); + } + + @Override + public StreamObserver greetBiStream(StreamObserver response) { + return new StreamObserver() { + @Override + public void onNext(String data) { + LOGGER.info(data); + response.onNext("Hello, " + data); + } + + @Override + public void onError(Throwable throwable) { + LOGGER.error("GreetBiStream on error", throwable); + } + + @Override + public void onCompleted() { + LOGGER.info("onCompleted"); + response.onCompleted(); + } + }; + } + + @Override + public StreamObserver greetBiStreamError(StreamObserver response) { + return new StreamObserver() { + @Override + public void onNext(String data) { + response.onError(new RuntimeException("test error: " + data)); + } + + @Override + public void onError(Throwable throwable) { + LOGGER.error("GreetBiStream on error", throwable); + } + + @Override + public void onCompleted() { + LOGGER.info("onCompleted"); + response.onCompleted(); + } + }; + } + + @Override + public StreamObserver greetBiStreamDirectError(StreamObserver response) { + return new StreamObserver() { + @Override + public void onNext(String data) { + throw new RuntimeException("test direct error: " + data); + } + + @Override + public void onError(Throwable throwable) { + LOGGER.error("GreetBiStream on error", throwable); + } + + @Override + public void onCompleted() { + LOGGER.info("onCompleted"); + response.onCompleted(); + } + }; + } + +} diff --git a/2-advanced/dubbo-samples-triple-websocket/src/main/java/org/apache/dubbo/tri/websocket/demo/WebSocketDemoApplication.java b/2-advanced/dubbo-samples-triple-websocket/src/main/java/org/apache/dubbo/tri/websocket/demo/WebSocketDemoApplication.java new file mode 100644 index 0000000000..86bc6c5602 --- /dev/null +++ b/2-advanced/dubbo-samples-triple-websocket/src/main/java/org/apache/dubbo/tri/websocket/demo/WebSocketDemoApplication.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.tri.websocket.demo; + +import org.apache.dubbo.config.spring.context.annotation.EnableDubbo; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +@EnableDubbo +public class WebSocketDemoApplication { + + public static void main(String[] args) { + SpringApplication.run(WebSocketDemoApplication.class, args); + } +} diff --git a/2-advanced/dubbo-samples-triple-websocket/src/main/resources/application.yml b/2-advanced/dubbo-samples-triple-websocket/src/main/resources/application.yml new file mode 100644 index 0000000000..c148561ae8 --- /dev/null +++ b/2-advanced/dubbo-samples-triple-websocket/src/main/resources/application.yml @@ -0,0 +1,30 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +server: + port: 8080 +dubbo: + application: + name: dubbo-springboot-triple-websocket + qos-port: 22222 + registry: + address: nacos://${nacos.address:localhost}:8848?username=nacos&password=nacos + protocol: + name: tri + port: 50052 + triple: + enable-websocket: true + parameters: + triple.servlet: true diff --git a/2-advanced/dubbo-samples-triple-websocket/src/test/java/org/apache/dubbo/tri/websocket/demo/test/HelloClient.java b/2-advanced/dubbo-samples-triple-websocket/src/test/java/org/apache/dubbo/tri/websocket/demo/test/HelloClient.java new file mode 100644 index 0000000000..e7a197890b --- /dev/null +++ b/2-advanced/dubbo-samples-triple-websocket/src/test/java/org/apache/dubbo/tri/websocket/demo/test/HelloClient.java @@ -0,0 +1,81 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.tri.websocket.demo.test; + +import org.java_websocket.client.WebSocketClient; +import org.java_websocket.handshake.ServerHandshake; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.net.URI; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.List; + +public class HelloClient extends WebSocketClient { + + private static final Logger LOGGER = LoggerFactory.getLogger(HelloClient.class); + + private final List responses = new ArrayList<>(); + + private int closeCode; + + private String closeMessage; + + public HelloClient(URI serverURI) { + super(serverURI); + } + + @Override + public void onOpen(ServerHandshake handshakedata) { + LOGGER.info("new connection opened:{}", handshakedata); + } + + @Override + public void onMessage(String message) {} + + @Override + public void onMessage(ByteBuffer message) { + String response = new String(message.array()); + responses.add(response); + } + + @Override + public void onClose(int code, String reason, boolean remote) { + LOGGER.info("closed with exit code {}, additional info: {}, remote close:{}", code, reason, remote); + closeCode = code; + closeMessage = reason; + } + + @Override + public void onError(Exception e) { + LOGGER.error("WebSocket on error", e); + } + + public List getResponses() { + return responses; + } + + public int getCloseCode() { + return closeCode; + } + + public String getCloseMessage() { + return closeMessage; + } + +} diff --git a/2-advanced/dubbo-samples-triple-websocket/src/test/java/org/apache/dubbo/tri/websocket/demo/test/WebSocketWithNettyTest.java b/2-advanced/dubbo-samples-triple-websocket/src/test/java/org/apache/dubbo/tri/websocket/demo/test/WebSocketWithNettyTest.java new file mode 100644 index 0000000000..7b20df1120 --- /dev/null +++ b/2-advanced/dubbo-samples-triple-websocket/src/test/java/org/apache/dubbo/tri/websocket/demo/test/WebSocketWithNettyTest.java @@ -0,0 +1,156 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.tri.websocket.demo.test; + +import io.netty.handler.codec.http.websocketx.WebSocketCloseStatus; +import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.runner.RunWith; +import org.springframework.test.context.junit4.SpringRunner; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; +import java.util.concurrent.TimeUnit; + +@RunWith(SpringRunner.class) +public class WebSocketWithNettyTest { + + private final String nettyAddress = "localhost:50052"; + + @Test + public void testHelloWithNetty() throws URISyntaxException, InterruptedException { + HelloClient helloClient = new HelloClient( + new URI("ws://" + nettyAddress + "/org.apache.dubbo.tri.websocket.demo.DemoService/sayHello")); + helloClient.connectBlocking(); + helloClient.send("{\"world\": 1}"); + List responses = helloClient.getResponses(); + TimeUnit.SECONDS.sleep(1); + helloClient.close(); + Assertions.assertEquals(1, responses.size()); + Assertions.assertEquals("\"Hello, {\\\"world\\\":1}\"", responses.get(0)); + helloClient.close(); + } + + @Test + public void testHelloErrorWithNetty() throws URISyntaxException, InterruptedException { + HelloClient helloClient = new HelloClient( + new URI("ws://" + nettyAddress + "/org.apache.dubbo.tri.websocket.demo.DemoService/sayHelloError")); + helloClient.connectBlocking(); + helloClient.send("{\"world\": 1}"); + TimeUnit.SECONDS.sleep(1); + List responses = helloClient.getResponses(); + Assertions.assertEquals(1, responses.size()); + Assertions.assertTrue(responses.get(0).contains("\"localizedMessage\":\"test error: {\\\"world\\\":1}\"")); + helloClient.close(); + } + + @Test + public void testServerStreamWithNetty() throws URISyntaxException, InterruptedException { + HelloClient helloClient = new HelloClient( + new URI("ws://" + nettyAddress + "/org.apache.dubbo.tri.websocket.demo.DemoService/greetServerStream")); + helloClient.connectBlocking(); + helloClient.send("{\"world\": 1}"); + TimeUnit.SECONDS.sleep(1); + helloClient.close(); + List responses = helloClient.getResponses(); + Assertions.assertEquals(10, responses.size()); + for (int i = 0; i < 10; i++) { + Assertions.assertEquals("\"Hello, {\\\"world\\\":1}" + i + "\"", responses.get(i)); + } + helloClient.close(); + } + + @Test + public void testServerStreamErrorWithNetty() throws URISyntaxException, InterruptedException { + HelloClient helloClient = new HelloClient( + new URI("ws://" + nettyAddress + "/org.apache.dubbo.tri.websocket.demo.DemoService/greetServerStreamError")); + helloClient.connectBlocking(); + helloClient.send("{\"world\": 1}"); + TimeUnit.SECONDS.sleep(1); + Assertions.assertEquals(WebSocketCloseStatus.INTERNAL_SERVER_ERROR.code(), helloClient.getCloseCode()); + Assertions.assertEquals("test error: {\"world\":1}", helloClient.getCloseMessage()); + helloClient.close(); + } + + @Test + public void testServerStreamDirectErrorWithNetty() throws URISyntaxException, InterruptedException { + HelloClient helloClient = new HelloClient( + new URI("ws://" + nettyAddress + "/org.apache.dubbo.tri.websocket.demo.DemoService/greetServerStreamDirectError")); + helloClient.connectBlocking(); + helloClient.send("{\"world\": 1}"); + TimeUnit.SECONDS.sleep(1); + Assertions.assertEquals(WebSocketCloseStatus.INTERNAL_SERVER_ERROR.code(), helloClient.getCloseCode()); + Assertions.assertEquals("test direct error: {\"world\":1}", helloClient.getCloseMessage()); + helloClient.close(); + } + + @Test + public void testBiStreamWithNetty() throws URISyntaxException, InterruptedException { + HelloClient helloClient = new HelloClient( + new URI("ws://" + nettyAddress + "/org.apache.dubbo.tri.websocket.demo.DemoService/greetBiStream")); + helloClient.connectBlocking(); + for (int i = 0; i < 10; i++) { + helloClient.send("{\"world\": " + i + "}"); + } + TimeUnit.SECONDS.sleep(1); + List responses = helloClient.getResponses(); + Assertions.assertEquals(10, responses.size()); + for (int i = 0; i < 10; i++) { + Assertions.assertEquals("\"Hello, {\\\"world\\\":" + i + "}\"", responses.get(i)); + } + + for (int i = 10; i < 20; i++) { + helloClient.send("{\"world\": " + i + "}"); + } + TimeUnit.SECONDS.sleep(1); + Assertions.assertEquals(20, responses.size()); + for (int i = 10; i < 20; i++) { + Assertions.assertEquals("\"Hello, {\\\"world\\\":" + i + "}\"", responses.get(i)); + } + + helloClient.close(); + } + + @Test + public void testBiStreamErrorWithNetty() throws URISyntaxException, InterruptedException { + HelloClient helloClient = new HelloClient( + new URI("ws://" + nettyAddress + "/org.apache.dubbo.tri.websocket.demo.DemoService/greetBiStreamError")); + helloClient.connectBlocking(); + for (int i = 0; i < 10; i++) { + helloClient.send("{\"world\": " + i + "}"); + } + TimeUnit.SECONDS.sleep(1); + Assertions.assertEquals(WebSocketCloseStatus.INTERNAL_SERVER_ERROR.code(), helloClient.getCloseCode()); + Assertions.assertEquals("test error: {\"world\":0}", helloClient.getCloseMessage()); + helloClient.close(); + } + + @Test + public void testBiStreamDirectErrorWithNetty() throws URISyntaxException, InterruptedException { + HelloClient helloClient = new HelloClient( + new URI("ws://" + nettyAddress + "/org.apache.dubbo.tri.websocket.demo.DemoService/greetBiStreamDirectError")); + helloClient.connectBlocking(); + for (int i = 0; i < 10; i++) { + helloClient.send("{\"world\": " + i + "}"); + } + TimeUnit.SECONDS.sleep(1); + Assertions.assertEquals(WebSocketCloseStatus.INTERNAL_SERVER_ERROR.code(), helloClient.getCloseCode()); + Assertions.assertEquals("test direct error: {\"world\":0}", helloClient.getCloseMessage()); + helloClient.close(); + } +} diff --git a/2-advanced/dubbo-samples-triple-websocket/src/test/java/org/apache/dubbo/tri/websocket/demo/test/WebSocketWithTomcatTest.java b/2-advanced/dubbo-samples-triple-websocket/src/test/java/org/apache/dubbo/tri/websocket/demo/test/WebSocketWithTomcatTest.java new file mode 100644 index 0000000000..3638db850d --- /dev/null +++ b/2-advanced/dubbo-samples-triple-websocket/src/test/java/org/apache/dubbo/tri/websocket/demo/test/WebSocketWithTomcatTest.java @@ -0,0 +1,154 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.tri.websocket.demo.test; + +import io.netty.handler.codec.http.websocketx.WebSocketCloseStatus; +import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.runner.RunWith; +import org.springframework.test.context.junit4.SpringRunner; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; +import java.util.concurrent.TimeUnit; + +@RunWith(SpringRunner.class) +public class WebSocketWithTomcatTest { + + private final String tomcatAddress = "localhost:8080"; + + @Test + public void testHelloWithTomcat() throws URISyntaxException, InterruptedException { + HelloClient helloClient = new HelloClient( + new URI("ws://" + tomcatAddress + "/org.apache.dubbo.tri.websocket.demo.DemoService/sayHello")); + helloClient.connectBlocking(); + helloClient.send("{\"world\": 1}"); + TimeUnit.SECONDS.sleep(1); + List responses = helloClient.getResponses(); + Assertions.assertEquals(1, responses.size()); + Assertions.assertEquals("\"Hello, {\\\"world\\\":1}\"", responses.get(0)); + helloClient.close(); + } + + @Test + public void testHelloErrorWithTomcat() throws URISyntaxException, InterruptedException { + HelloClient helloClient = new HelloClient( + new URI("ws://" + tomcatAddress + "/org.apache.dubbo.tri.websocket.demo.DemoService/sayHelloError")); + helloClient.connectBlocking(); + helloClient.send("{\"world\": 1}"); + TimeUnit.SECONDS.sleep(1); + List responses = helloClient.getResponses(); + Assertions.assertEquals(1, responses.size()); + Assertions.assertTrue(responses.get(0).contains("\"localizedMessage\":\"test error: {\\\"world\\\":1}\"")); + helloClient.close(); + } + + @Test + public void testServerStreamWithTomcat() throws URISyntaxException, InterruptedException { + HelloClient helloClient = new HelloClient( + new URI("ws://" + tomcatAddress + "/org.apache.dubbo.tri.websocket.demo.DemoService/greetServerStream")); + helloClient.connectBlocking(); + helloClient.send("{\"world\": 1}"); + TimeUnit.SECONDS.sleep(1); + List responses = helloClient.getResponses(); + Assertions.assertEquals(10, responses.size()); + for (int i = 0; i < 10; i++) { + Assertions.assertEquals("\"Hello, {\\\"world\\\":1}" + i + "\"", responses.get(i)); + } + helloClient.close(); + } + + @Test + public void testServerStreamErrorWithTomcat() throws URISyntaxException, InterruptedException { + HelloClient helloClient = new HelloClient( + new URI("ws://" + tomcatAddress + "/org.apache.dubbo.tri.websocket.demo.DemoService/greetServerStreamError")); + helloClient.connectBlocking(); + helloClient.send("{\"world\": 1}"); + TimeUnit.SECONDS.sleep(1); + Assertions.assertEquals(WebSocketCloseStatus.INTERNAL_SERVER_ERROR.code(), helloClient.getCloseCode()); + Assertions.assertEquals("test error: {\"world\":1}", helloClient.getCloseMessage()); + helloClient.close(); + } + + @Test + public void testServerStreamDirectErrorWithTomcat() throws URISyntaxException, InterruptedException { + HelloClient helloClient = new HelloClient( + new URI("ws://" + tomcatAddress + "/org.apache.dubbo.tri.websocket.demo.DemoService/greetServerStreamDirectError")); + helloClient.connectBlocking(); + helloClient.send("{\"world\": 1}"); + TimeUnit.SECONDS.sleep(1); + Assertions.assertEquals(WebSocketCloseStatus.INTERNAL_SERVER_ERROR.code(), helloClient.getCloseCode()); + Assertions.assertEquals("test direct error: {\"world\":1}", helloClient.getCloseMessage()); + helloClient.close(); + } + + @Test + public void testBiStreamWithTomcat() throws URISyntaxException, InterruptedException { + HelloClient helloClient = new HelloClient( + new URI("ws://" + tomcatAddress + "/org.apache.dubbo.tri.websocket.demo.DemoService/greetBiStream")); + helloClient.connectBlocking(); + for (int i = 0; i < 10; i++) { + helloClient.send("{\"world\": " + i + "}"); + } + TimeUnit.SECONDS.sleep(1); + List responses = helloClient.getResponses(); + Assertions.assertEquals(10, responses.size()); + for (int i = 0; i < 10; i++) { + Assertions.assertEquals("\"Hello, {\\\"world\\\":" + i + "}\"", responses.get(i)); + } + + for (int i = 10; i < 20; i++) { + helloClient.send("{\"world\": " + i + "}"); + } + TimeUnit.SECONDS.sleep(1); + Assertions.assertEquals(20, responses.size()); + for (int i = 10; i < 20; i++) { + Assertions.assertEquals("\"Hello, {\\\"world\\\":" + i + "}\"", responses.get(i)); + } + + helloClient.close(); + } + + @Test + public void testBiStreamErrorWithTomcat() throws URISyntaxException, InterruptedException { + HelloClient helloClient = new HelloClient( + new URI("ws://" + tomcatAddress + "/org.apache.dubbo.tri.websocket.demo.DemoService/greetBiStreamError")); + helloClient.connectBlocking(); + for (int i = 0; i < 10; i++) { + helloClient.send("{\"world\": " + i + "}"); + } + TimeUnit.SECONDS.sleep(1); + Assertions.assertEquals(WebSocketCloseStatus.INTERNAL_SERVER_ERROR.code(), helloClient.getCloseCode()); + Assertions.assertEquals("test error: {\"world\":0}", helloClient.getCloseMessage()); + helloClient.close(); + } + + @Test + public void testBiStreamDirectErrorWithTomcat() throws URISyntaxException, InterruptedException { + HelloClient helloClient = new HelloClient( + new URI("ws://" + tomcatAddress + "/org.apache.dubbo.tri.websocket.demo.DemoService/greetBiStreamDirectError")); + helloClient.connectBlocking(); + for (int i = 0; i < 10; i++) { + helloClient.send("{\"world\": " + i + "}"); + } + TimeUnit.SECONDS.sleep(1); + Assertions.assertEquals(WebSocketCloseStatus.INTERNAL_SERVER_ERROR.code(), helloClient.getCloseCode()); + Assertions.assertEquals("test direct error: {\"world\":0}", helloClient.getCloseMessage()); + helloClient.close(); + } +} diff --git a/2-advanced/pom.xml b/2-advanced/pom.xml index 1da1ddb60a..c7217c935b 100644 --- a/2-advanced/pom.xml +++ b/2-advanced/pom.xml @@ -69,5 +69,6 @@ dubbo-samples-triple-rest dubbo-samples-gateway dubbo-samples-multiple-protocols + dubbo-samples-triple-websocket