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();
     }

Reply via email to