This is an automated email from the ASF dual-hosted git repository.
albumenj pushed a commit to branch 3.0
in repository https://gitbox.apache.org/repos/asf/dubbo.git
The following commit(s) were added to refs/heads/3.0 by this push:
new 36f23a4 Add unit test for
CloseTimerTask,ReconnectTimerTask,HeaderExchangeServer (#9046)
36f23a4 is described below
commit 36f23a44dc570d7bc68b5e596d2d701119e4143a
Author: 灼华 <[email protected]>
AuthorDate: Thu Oct 21 11:14:50 2021 +0800
Add unit test for CloseTimerTask,ReconnectTimerTask,HeaderExchangeServer
(#9046)
---
.../support/header/HeaderExchangeServer.java | 2 +-
.../support/header/HeartbeatTimerTask.java | 5 +-
.../exchange/support/DefaultFutureTest.java | 2 +-
.../support/header/CloseTimerTaskTest.java | 73 ++++++++++++++++++
.../support/header/HeaderExchangeChannelTest.java | 14 ++--
.../support/header/HeaderExchangeServerTest.java | 90 ++++++++++++++++++++++
.../exchange/support/header/MockChannel.java | 24 +++++-
.../support/header/ReconnectTimerTaskTest.java | 78 +++++++++++++++++++
.../remoting/transport/netty4/NettyClient.java | 2 +-
9 files changed, 277 insertions(+), 13 deletions(-)
diff --git
a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/header/HeaderExchangeServer.java
b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/header/HeaderExchangeServer.java
index d0d940d..49683b8 100644
---
a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/header/HeaderExchangeServer.java
+++
b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/header/HeaderExchangeServer.java
@@ -114,7 +114,7 @@ public class HeaderExchangeServer implements ExchangeServer
{
}
startClose();
if (timeout > 0) {
- final long max = (long) timeout;
+ final long max = timeout;
final long start = System.currentTimeMillis();
if
(getUrl().getParameter(Constants.CHANNEL_SEND_READONLYEVENT_KEY, true)) {
sendChannelReadOnlyEvent();
diff --git
a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/header/HeartbeatTimerTask.java
b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/header/HeartbeatTimerTask.java
index 12e0f48..f814c6c 100644
---
a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/header/HeartbeatTimerTask.java
+++
b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/header/HeartbeatTimerTask.java
@@ -44,8 +44,9 @@ public class HeartbeatTimerTask extends AbstractTimerTask {
try {
Long lastRead = lastRead(channel);
Long lastWrite = lastWrite(channel);
- if ((lastRead != null && now() - lastRead > heartbeat)
- || (lastWrite != null && now() - lastWrite > heartbeat)) {
+ Long now = now();
+ if ((lastRead != null && now - lastRead > heartbeat)
+ || (lastWrite != null && now - lastWrite > heartbeat)) {
Request req = new Request();
req.setVersion(Version.getProtocolVersion());
req.setTwoWay(true);
diff --git
a/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/exchange/support/DefaultFutureTest.java
b/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/exchange/support/DefaultFutureTest.java
index 9f93929..fa7a779 100644
---
a/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/exchange/support/DefaultFutureTest.java
+++
b/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/exchange/support/DefaultFutureTest.java
@@ -122,7 +122,7 @@ public class DefaultFutureTest {
}
/**
* for example, it will print like this:
- *before a future is create , time is : 2021-01-22 10:55:03
+ * before a future is created , time is : 2021-01-22 10:55:03
* null
* after a future is timeout , time is : 2021-01-22 10:55:05
*/
diff --git
a/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/exchange/support/header/CloseTimerTaskTest.java
b/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/exchange/support/header/CloseTimerTaskTest.java
new file mode 100644
index 0000000..9d6ac83
--- /dev/null
+++
b/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/exchange/support/header/CloseTimerTaskTest.java
@@ -0,0 +1,73 @@
+/*
+ * 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.remoting.exchange.support.header;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.timer.HashedWheelTimer;
+import org.apache.dubbo.remoting.Channel;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.util.Collections;
+import java.util.concurrent.TimeUnit;
+
+import static
org.apache.dubbo.common.constants.CommonConstants.DUBBO_VERSION_KEY;
+import static org.apache.dubbo.remoting.Constants.HEARTBEAT_CHECK_TICK;
+
+/**
+ * {@link CloseTimerTask}
+ */
+public class CloseTimerTaskTest {
+
+ private URL url = URL.valueOf("dubbo://localhost:20880");
+
+ private MockChannel channel;
+
+ private CloseTimerTask closeTimerTask;
+ private HashedWheelTimer closeTimer;
+
+ @BeforeEach
+ public void setup() throws Exception {
+ long tickDuration = 1000;
+ closeTimer = new HashedWheelTimer(tickDuration / HEARTBEAT_CHECK_TICK,
TimeUnit.MILLISECONDS);
+ channel = new MockChannel() {
+ @Override
+ public URL getUrl() {
+ return url;
+ }
+ };
+
+ AbstractTimerTask.ChannelProvider cp = () ->
Collections.<Channel>singletonList(channel);
+ closeTimerTask = new CloseTimerTask(cp, tickDuration /
HEARTBEAT_CHECK_TICK, (int) tickDuration);
+ }
+
+ @Test
+ public void testClose() throws Exception {
+ long now = System.currentTimeMillis();
+
+ url = url.addParameter(DUBBO_VERSION_KEY, "2.1.1");
+ channel.setAttribute(HeartbeatHandler.KEY_READ_TIMESTAMP, now - 1000);
+ channel.setAttribute(HeartbeatHandler.KEY_WRITE_TIMESTAMP, now - 1000);
+
+ closeTimer.newTimeout(closeTimerTask, 250, TimeUnit.MILLISECONDS);
+
+ Thread.sleep(2000L);
+ Assertions.assertTrue(channel.isClosed());
+ }
+
+}
diff --git
a/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/exchange/support/header/HeaderExchangeChannelTest.java
b/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/exchange/support/header/HeaderExchangeChannelTest.java
index 2affe7d..513408a 100644
---
a/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/exchange/support/header/HeaderExchangeChannelTest.java
+++
b/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/exchange/support/header/HeaderExchangeChannelTest.java
@@ -142,8 +142,8 @@ public class HeaderExchangeChannelTest {
public void requestTest01() throws RemotingException {
Assertions.assertThrows(RemotingException.class, () -> {
header.close(1000);
- Object requestob = new Object();
- header.request(requestob);
+ Object requestObject = new Object();
+ header.request(requestObject);
});
}
@@ -152,11 +152,11 @@ public class HeaderExchangeChannelTest {
Channel channel = Mockito.mock(MockChannel.class);
header = new HeaderExchangeChannel(channel);
when(channel.getUrl()).thenReturn(url);
- Object requestob = new Object();
- header.request(requestob);
+ Object requestObject = new Object();
+ header.request(requestObject);
ArgumentCaptor<Request> argumentCaptor =
ArgumentCaptor.forClass(Request.class);
verify(channel, times(1)).send(argumentCaptor.capture());
- Assertions.assertEquals(argumentCaptor.getValue().getData(),
requestob);
+ Assertions.assertEquals(argumentCaptor.getValue().getData(),
requestObject);
}
@Test
@@ -169,8 +169,8 @@ public class HeaderExchangeChannelTest {
}
};
header = new HeaderExchangeChannel(channel);
- Object requestob = new Object();
- header.request(requestob, 1000);
+ Object requestObject = new Object();
+ header.request(requestObject, 1000);
});
}
diff --git
a/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/exchange/support/header/HeaderExchangeServerTest.java
b/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/exchange/support/header/HeaderExchangeServerTest.java
new file mode 100644
index 0000000..a2acc23
--- /dev/null
+++
b/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/exchange/support/header/HeaderExchangeServerTest.java
@@ -0,0 +1,90 @@
+/*
+ * 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.remoting.exchange.support.header;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.url.component.ServiceConfigURL;
+import org.apache.dubbo.remoting.Channel;
+import org.apache.dubbo.remoting.Constants;
+import org.apache.dubbo.remoting.RemotingException;
+import org.apache.dubbo.remoting.RemotingServer;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+
+import java.net.InetSocketAddress;
+import java.util.Arrays;
+import java.util.Collection;
+
+/**
+ * {@link HeaderExchangeServer}
+ */
+public class HeaderExchangeServerTest {
+
+ @Test
+ public void test() throws InterruptedException, RemotingException {
+ RemotingServer server = Mockito.mock(RemotingServer.class);
+ URL url = new ServiceConfigURL("dubbo", "127.0.0.1", 20881);
+ Mockito.when(server.getUrl()).thenReturn(url);
+ Mockito.when(server.canHandleIdle()).thenReturn(false);
+ HeaderExchangeServer headerExchangeServer = new
HeaderExchangeServer(server);
+ Assertions.assertEquals(headerExchangeServer.getServer(), server);
+ Assertions.assertEquals(headerExchangeServer.getUrl(), url);
+
+ // test getChannels() and getExchangeChannels()
+ Channel channel1 = Mockito.mock(Channel.class);
+ Channel channel2 = Mockito.mock(Channel.class);
+ Channel exchangeChannel1 = new HeaderExchangeChannel(channel1);
+ Channel exchangeChannel2 = new HeaderExchangeChannel(channel2);
+
Mockito.when(channel1.getAttribute(HeaderExchangeChannel.class.getName() +
".CHANNEL")).thenReturn(exchangeChannel1);
+
Mockito.when(channel2.getAttribute(HeaderExchangeChannel.class.getName() +
".CHANNEL")).thenReturn(exchangeChannel2);
+ Collection<Channel> exChannels = Arrays.asList(exchangeChannel1,
exchangeChannel2);
+ Mockito.when(server.getChannels()).thenReturn(Arrays.asList(channel1,
channel2));
+ Assertions.assertEquals(headerExchangeServer.getChannels(),
exChannels);
+ Assertions.assertEquals(headerExchangeServer.getExchangeChannels(),
exChannels);
+
+ // test getChannel(InetSocketAddress) and
getExchangeChannel(InetSocketAddress)
+ InetSocketAddress address1 = Mockito.mock(InetSocketAddress.class);
+ InetSocketAddress address2 = Mockito.mock(InetSocketAddress.class);
+
Mockito.when(server.getChannel(Mockito.eq(address1))).thenReturn(channel1);
+
Mockito.when(server.getChannel(Mockito.eq(address2))).thenReturn(channel2);
+ Assertions.assertEquals(headerExchangeServer.getChannel(address1),
exchangeChannel1);
+ Assertions.assertEquals(headerExchangeServer.getChannel(address2),
exchangeChannel2);
+
Assertions.assertEquals(headerExchangeServer.getExchangeChannel(address1),
exchangeChannel1);
+
Assertions.assertEquals(headerExchangeServer.getExchangeChannel(address2),
exchangeChannel2);
+
+ // test send(Object message) and send(Object message, boolean sent)
+ headerExchangeServer.send("test");
+ Mockito.verify(server, Mockito.times(1)).send("test");
+ headerExchangeServer.send("test", true);
+ Mockito.verify(server, Mockito.times(1)).send("test", true);
+
+ // test reset(URL url)
+ url = url.addParameter(Constants.HEARTBEAT_KEY,
3000).addParameter(Constants.HEARTBEAT_TIMEOUT_KEY, 3000 * 3);
+ headerExchangeServer.reset(url);
+
+ // test close(int timeout)
+ Mockito.when(exchangeChannel1.isConnected()).thenReturn(true);
+ headerExchangeServer.close(1000);
+ Mockito.verify(server, Mockito.times(1)).startClose();
+ Thread.sleep(1000);
+ Mockito.verify(server, Mockito.times(1)).close(1000);
+ Assertions.assertThrows(RemotingException.class, () ->
headerExchangeServer.send("test"));
+ Assertions.assertThrows(RemotingException.class, () ->
headerExchangeServer.send("test", true));
+ }
+
+}
diff --git
a/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/exchange/support/header/MockChannel.java
b/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/exchange/support/header/MockChannel.java
index 7c0f733..0512dff 100644
---
a/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/exchange/support/header/MockChannel.java
+++
b/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/exchange/support/header/MockChannel.java
@@ -17,9 +17,11 @@
package org.apache.dubbo.remoting.exchange.support.header;
+import org.apache.dubbo.common.Parameters;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.remoting.Channel;
import org.apache.dubbo.remoting.ChannelHandler;
+import org.apache.dubbo.remoting.Client;
import org.apache.dubbo.remoting.RemotingException;
import java.net.InetSocketAddress;
@@ -29,12 +31,13 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
-public class MockChannel implements Channel {
+public class MockChannel implements Channel, Client {
private Map<String, Object> attributes = new HashMap<String, Object>();
private volatile boolean closed = false;
private volatile boolean closing = false;
+ private volatile int reconnectCount = 0;
private List<Object> sentObjects = new ArrayList<Object>();
@Override
@@ -119,4 +122,23 @@ public class MockChannel implements Channel {
public boolean isClosing() {
return closing;
}
+
+ @Override
+ public void reset(URL url) {
+
+ }
+
+ @Override
+ public void reconnect() throws RemotingException {
+ reconnectCount++;
+ }
+
+ @Override
+ public void reset(Parameters parameters) {
+
+ }
+
+ public int getReconnectCount() {
+ return reconnectCount;
+ }
}
diff --git
a/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/exchange/support/header/ReconnectTimerTaskTest.java
b/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/exchange/support/header/ReconnectTimerTaskTest.java
new file mode 100644
index 0000000..48e2666
--- /dev/null
+++
b/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/exchange/support/header/ReconnectTimerTaskTest.java
@@ -0,0 +1,78 @@
+/*
+ * 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.remoting.exchange.support.header;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.timer.HashedWheelTimer;
+import org.apache.dubbo.remoting.Channel;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.util.Collections;
+import java.util.concurrent.TimeUnit;
+
+import static
org.apache.dubbo.common.constants.CommonConstants.DUBBO_VERSION_KEY;
+import static org.apache.dubbo.remoting.Constants.HEARTBEAT_CHECK_TICK;
+
+public class ReconnectTimerTaskTest {
+
+ private URL url = URL.valueOf("dubbo://localhost:20880");
+
+ private MockChannel channel;
+
+ private ReconnectTimerTask reconnectTimerTask;
+ private HashedWheelTimer reconnectTimer;
+ private boolean isConnected = false;
+
+ @BeforeEach
+ public void setup() throws Exception {
+ long tickDuration = 1000;
+ reconnectTimer = new HashedWheelTimer(tickDuration /
HEARTBEAT_CHECK_TICK, TimeUnit.MILLISECONDS);
+ channel = new MockChannel() {
+ @Override
+ public URL getUrl() {
+ return url;
+ }
+
+ @Override
+ public boolean isConnected() {
+ return isConnected;
+ }
+ };
+
+ AbstractTimerTask.ChannelProvider cp = () ->
Collections.<Channel>singletonList(channel);
+ reconnectTimerTask = new ReconnectTimerTask(cp, tickDuration /
HEARTBEAT_CHECK_TICK, (int) tickDuration);
+ }
+
+ @Test
+ public void testReconnect() throws Exception {
+ long now = System.currentTimeMillis();
+
+ url = url.addParameter(DUBBO_VERSION_KEY, "2.1.1");
+ channel.setAttribute(HeartbeatHandler.KEY_READ_TIMESTAMP, now - 1000);
+ channel.setAttribute(HeartbeatHandler.KEY_WRITE_TIMESTAMP, now - 1000);
+
+ reconnectTimer.newTimeout(reconnectTimerTask, 250,
TimeUnit.MILLISECONDS);
+
+ Thread.sleep(2000L);
+ Assertions.assertTrue(channel.getReconnectCount() > 0);
+ isConnected = true;
+ Thread.sleep(2000L);
+ Assertions.assertTrue(channel.getReconnectCount() > 1);
+ }
+}
diff --git
a/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyClient.java
b/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyClient.java
index 998f5e3..7cbf253 100644
---
a/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyClient.java
+++
b/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyClient.java
@@ -206,7 +206,7 @@ public class NettyClient extends AbstractClient {
@Override
protected void doClose() throws Throwable {
- // can't shutdown nioEventLoopGroup because the method will be invoked
when closing one channel but not a client,
+ // can't shut down nioEventLoopGroup because the method will be
invoked when closing one channel but not a client,
// but when and how to close the nioEventLoopGroup ?
// nioEventLoopGroup.shutdownGracefully();
}