22 */ |
22 */ |
23 |
23 |
24 package jdk.incubator.http.internal.websocket; |
24 package jdk.incubator.http.internal.websocket; |
25 |
25 |
26 import jdk.incubator.http.WebSocket; |
26 import jdk.incubator.http.WebSocket; |
27 import jdk.incubator.http.WebSocket.MessagePart; |
|
28 import org.testng.annotations.Test; |
27 import org.testng.annotations.Test; |
29 |
28 |
30 import java.net.URI; |
29 import java.net.URI; |
31 import java.nio.ByteBuffer; |
30 import java.util.List; |
32 import java.util.concurrent.CompletableFuture; |
31 import java.util.concurrent.CompletableFuture; |
33 import java.util.concurrent.CompletionStage; |
32 import java.util.concurrent.CompletionStage; |
34 import java.util.concurrent.TimeUnit; |
33 import java.util.concurrent.TimeUnit; |
35 import java.util.concurrent.atomic.AtomicInteger; |
|
36 |
34 |
37 import static java.util.concurrent.CompletableFuture.completedStage; |
35 import static java.util.concurrent.CompletableFuture.completedStage; |
38 import static jdk.incubator.http.WebSocket.MessagePart.FIRST; |
36 import static jdk.incubator.http.WebSocket.MessagePart.FIRST; |
39 import static jdk.incubator.http.WebSocket.MessagePart.LAST; |
37 import static jdk.incubator.http.WebSocket.MessagePart.LAST; |
40 import static jdk.incubator.http.WebSocket.MessagePart.PART; |
38 import static jdk.incubator.http.WebSocket.MessagePart.PART; |
41 import static jdk.incubator.http.WebSocket.MessagePart.WHOLE; |
39 import static jdk.incubator.http.WebSocket.MessagePart.WHOLE; |
42 import static jdk.incubator.http.WebSocket.NORMAL_CLOSURE; |
40 import static jdk.incubator.http.WebSocket.NORMAL_CLOSURE; |
43 import static jdk.incubator.http.internal.common.Pair.pair; |
41 import static jdk.incubator.http.internal.common.Pair.pair; |
44 import static jdk.incubator.http.internal.websocket.WebSocketImpl.newInstance; |
42 import static jdk.incubator.http.internal.websocket.MockListener.ListenerInvocation.onClose; |
|
43 import static jdk.incubator.http.internal.websocket.MockListener.ListenerInvocation.onError; |
|
44 import static jdk.incubator.http.internal.websocket.MockListener.ListenerInvocation.onOpen; |
|
45 import static jdk.incubator.http.internal.websocket.MockListener.ListenerInvocation.onText; |
|
46 import static org.testng.Assert.assertEquals; |
45 |
47 |
46 public class ReceivingTest { |
48 public class ReceivingTest { |
47 |
49 |
48 // TODO: request in onClose/onError |
50 // TODO: request in onClose/onError |
49 // TODO: throw exception in onClose/onError |
51 // TODO: throw exception in onClose/onError |
|
52 // TODO: exception is thrown from request() |
50 |
53 |
51 @Test |
54 @Test |
52 public void testNonPositiveRequest() { |
55 public void testNonPositiveRequest() throws Exception { |
53 URI uri = URI.create("ws://localhost"); |
56 MockListener listener = new MockListener(Long.MAX_VALUE) { |
54 String subprotocol = ""; |
|
55 CompletableFuture<Throwable> result = new CompletableFuture<>(); |
|
56 newInstance(uri, subprotocol, new MockListener(Long.MAX_VALUE) { |
|
57 |
|
58 final AtomicInteger onOpenCount = new AtomicInteger(); |
|
59 volatile WebSocket webSocket; |
|
60 |
|
61 @Override |
57 @Override |
62 public void onOpen(WebSocket webSocket) { |
58 protected void onOpen0(WebSocket webSocket) { |
63 int i = onOpenCount.incrementAndGet(); |
59 webSocket.request(0); |
64 if (i > 1) { |
|
65 result.completeExceptionally(new IllegalStateException()); |
|
66 } else { |
|
67 this.webSocket = webSocket; |
|
68 webSocket.request(0); |
|
69 } |
|
70 } |
60 } |
71 |
61 }; |
72 @Override |
62 MockTransport transport = new MockTransport() { |
73 public CompletionStage<?> onBinary(WebSocket webSocket, |
|
74 ByteBuffer message, |
|
75 MessagePart part) { |
|
76 result.completeExceptionally(new IllegalStateException()); |
|
77 return null; |
|
78 } |
|
79 |
|
80 @Override |
|
81 public CompletionStage<?> onText(WebSocket webSocket, |
|
82 CharSequence message, |
|
83 MessagePart part) { |
|
84 result.completeExceptionally(new IllegalStateException()); |
|
85 return null; |
|
86 } |
|
87 |
|
88 @Override |
|
89 public CompletionStage<?> onPing(WebSocket webSocket, |
|
90 ByteBuffer message) { |
|
91 result.completeExceptionally(new IllegalStateException()); |
|
92 return null; |
|
93 } |
|
94 |
|
95 @Override |
|
96 public CompletionStage<?> onPong(WebSocket webSocket, |
|
97 ByteBuffer message) { |
|
98 result.completeExceptionally(new IllegalStateException()); |
|
99 return null; |
|
100 } |
|
101 |
|
102 @Override |
|
103 public CompletionStage<?> onClose(WebSocket webSocket, |
|
104 int statusCode, |
|
105 String reason) { |
|
106 result.completeExceptionally(new IllegalStateException()); |
|
107 return null; |
|
108 } |
|
109 |
|
110 @Override |
|
111 public void onError(WebSocket webSocket, Throwable error) { |
|
112 if (!this.webSocket.equals(webSocket)) { |
|
113 result.completeExceptionally(new IllegalArgumentException()); |
|
114 } else if (error == null || error.getClass() != IllegalArgumentException.class) { |
|
115 result.completeExceptionally(new IllegalArgumentException()); |
|
116 } else { |
|
117 result.complete(null); |
|
118 } |
|
119 } |
|
120 }, new MockTransport() { |
|
121 @Override |
63 @Override |
122 protected Receiver newReceiver(MessageStreamConsumer consumer) { |
64 protected Receiver newReceiver(MessageStreamConsumer consumer) { |
123 return new MockReceiver(consumer, channel, pair(now(), m -> m.onText("1", WHOLE) )); |
65 return new MockReceiver(consumer, channel, pair(now(), m -> m.onText("1", WHOLE))); |
124 } |
66 } |
125 }); |
67 }; |
126 result.join(); |
68 WebSocket ws = newInstance(listener, transport); |
|
69 listener.onCloseOrOnErrorCalled().get(10, TimeUnit.SECONDS); |
|
70 List<MockListener.ListenerInvocation> invocations = listener.invocations(); |
|
71 assertEquals(invocations, List.of(onOpen(ws), onError(ws, IllegalArgumentException.class))); |
127 } |
72 } |
128 |
73 |
129 @Test |
74 @Test |
130 public void testText1() throws InterruptedException { |
75 public void testText1() throws Exception { |
131 URI uri = URI.create("ws://localhost"); |
76 MockListener listener = new MockListener(Long.MAX_VALUE); |
132 String subprotocol = ""; |
77 MockTransport transport = new MockTransport() { |
133 newInstance(uri, subprotocol, new MockListener(Long.MAX_VALUE), |
78 @Override |
134 new MockTransport() { |
79 protected Receiver newReceiver(MessageStreamConsumer consumer) { |
135 @Override |
80 return new MockReceiver(consumer, channel, |
136 protected Receiver newReceiver(MessageStreamConsumer consumer) { |
81 pair(now(), m -> m.onText("1", FIRST)), |
137 return new MockReceiver(consumer, channel, |
82 pair(now(), m -> m.onText("2", PART)), |
138 pair(now(), m -> m.onText("1", FIRST)), |
83 pair(now(), m -> m.onText("3", PART)), |
139 pair(now(), m -> m.onText("2", PART)), |
84 pair(now(), m -> m.onText("4", LAST)), |
140 pair(now(), m -> m.onText("3", PART)), |
85 pair(now(), m -> m.onClose(NORMAL_CLOSURE, "no reason"))); |
141 pair(now(), m -> m.onText("4", LAST)), |
86 } |
142 pair(now(), m -> m.onClose(NORMAL_CLOSURE, "no reason"))); |
87 }; |
143 } |
88 WebSocket ws = newInstance(listener, transport); |
144 }); |
89 listener.onCloseOrOnErrorCalled().get(10, TimeUnit.SECONDS); |
145 Thread.sleep(2000); |
90 List<MockListener.ListenerInvocation> invocations = listener.invocations(); |
|
91 assertEquals(invocations, List.of(onOpen(ws), |
|
92 onText(ws, "1", FIRST), |
|
93 onText(ws, "2", PART), |
|
94 onText(ws, "3", PART), |
|
95 onText(ws, "4", LAST), |
|
96 onClose(ws, NORMAL_CLOSURE, "no reason"))); |
146 } |
97 } |
147 |
98 |
148 private CompletionStage<?> inSeconds(long s) { |
99 private static CompletionStage<?> seconds(long s) { |
149 return new CompletableFuture<>().completeOnTimeout(null, s, TimeUnit.SECONDS); |
100 return new CompletableFuture<>().completeOnTimeout(null, s, TimeUnit.SECONDS); |
150 } |
101 } |
151 |
102 |
152 private CompletionStage<?> now() { |
103 private static CompletionStage<?> now() { |
153 return completedStage(null); |
104 return completedStage(null); |
154 } |
105 } |
|
106 |
|
107 private static WebSocket newInstance(WebSocket.Listener listener, |
|
108 TransportSupplier transport) { |
|
109 URI uri = URI.create("ws://localhost"); |
|
110 String subprotocol = ""; |
|
111 return WebSocketImpl.newInstance(uri, subprotocol, listener, transport); |
|
112 } |
155 } |
113 } |