blob: 4f16c0a614dd87f0a77023b879aaac10e235fe11 [file] [log] [blame]
/*
* 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.servicecomb.foundation.vertx.client.tcp;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.servicecomb.foundation.test.scaffolding.exception.RuntimeExceptionWithoutStackTrace;
import org.apache.servicecomb.foundation.vertx.client.tcp.TcpClientConnection.Status;
import org.apache.servicecomb.foundation.vertx.tcp.TcpOutputStream;
import org.junit.Before;
import org.junit.Test;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.vertx.core.AsyncResult;
import io.vertx.core.Context;
import io.vertx.core.Handler;
import io.vertx.core.Promise;
import io.vertx.core.net.NetSocket;
import io.vertx.core.net.impl.NetSocketImpl;
import mockit.Deencapsulation;
import mockit.Expectations;
import mockit.Mock;
import mockit.MockUp;
import mockit.Mocked;
import org.junit.jupiter.api.Assertions;
public class TestTcpClientConnection {
@Mocked
Context context;
@Mocked
NetClientWrapper netClientWrapper;
String strEndpoint = "rest://localhost:8080";
TcpClientConnection tcpClientConnection;
Map<Long, TcpRequest> requestMap;
Queue<ByteBuf> writeQueue;
Queue<AbstractTcpClientPackage> packageQueue;
@Before
public void setup() {
tcpClientConnection = new TcpClientConnection(context, netClientWrapper, strEndpoint);
requestMap = Deencapsulation.getField(tcpClientConnection, "requestMap");
packageQueue = Deencapsulation.getField(tcpClientConnection, "packageQueue");
writeQueue = Deencapsulation.getField(tcpClientConnection, "writeQueue");
}
@Test
public void localSupportLogin() {
Assertions.assertFalse(tcpClientConnection.isLocalSupportLogin());
tcpClientConnection.setLocalSupportLogin(true);
Assertions.assertTrue(tcpClientConnection.isLocalSupportLogin());
}
@Test
public void createLogin() {
Assertions.assertNull(tcpClientConnection.createLogin());
}
@Test
public void onLoginResponse_buffer() {
Assertions.assertTrue(tcpClientConnection.onLoginResponse(null));
}
@Test
public void send_inWorkingStatus(@Mocked AbstractTcpClientPackage tcpClientPackage,
@Mocked TcpOutputStream tcpOutputStream) {
Deencapsulation.setField(tcpClientConnection, "status", Status.WORKING);
long msgId = 1;
ByteBuf byteBuf = Unpooled.buffer();
new Expectations(tcpClientConnection) {
{
tcpClientPackage.getMsgId();
result = msgId;
tcpClientPackage.createStream();
result = tcpOutputStream;
tcpOutputStream.getByteBuf();
result = byteBuf;
}
};
new MockUp<Context>(context) {
@Mock
void runOnContext(Handler<Void> action) {
}
};
tcpClientConnection.send(tcpClientPackage, ar -> {
});
Assertions.assertSame(byteBuf, writeQueue.poll());
Assertions.assertNull(writeQueue.poll());
Assertions.assertEquals(Status.WORKING, Deencapsulation.getField(tcpClientConnection, "status"));
}
@Test
public void send_inDisconnectedStatus(@Mocked AbstractTcpClientPackage tcpClientPackage,
@Mocked TcpOutputStream tcpOutputStream) {
long msgId = 1;
new Expectations(tcpClientConnection) {
{
tcpClientPackage.getMsgId();
result = msgId;
}
};
new MockUp<Context>(context) {
@Mock
void runOnContext(Handler<Void> action) {
action.handle(null);
}
};
tcpClientConnection.send(tcpClientPackage, ar -> {
});
Assertions.assertSame(tcpClientPackage, packageQueue.poll());
Assertions.assertNull(packageQueue.poll());
Assertions.assertEquals(Status.CONNECTING, Deencapsulation.getField(tcpClientConnection, "status"));
}
@Test
public void send_disconnectedToTryLogin(@Mocked AbstractTcpClientPackage tcpClientPackage,
@Mocked TcpOutputStream tcpOutputStream) {
long msgId = 1;
new Expectations(tcpClientConnection) {
{
tcpClientPackage.getMsgId();
result = msgId;
}
};
new MockUp<Context>(context) {
@Mock
void runOnContext(Handler<Void> action) {
Deencapsulation.setField(tcpClientConnection, "status", Status.TRY_LOGIN);
action.handle(null);
}
};
tcpClientConnection.send(tcpClientPackage, ar -> {
});
Assertions.assertSame(tcpClientPackage, packageQueue.poll());
Assertions.assertNull(packageQueue.poll());
Assertions.assertEquals(Status.TRY_LOGIN, Deencapsulation.getField(tcpClientConnection, "status"));
}
@Test
public void send_disconnectedToWorking(@Mocked AbstractTcpClientPackage tcpClientPackage,
@Mocked TcpOutputStream tcpOutputStream) {
long msgId = 1;
new Expectations(tcpClientConnection) {
{
tcpClientPackage.getMsgId();
result = msgId;
tcpClientConnection.write((ByteBuf) any);
}
};
new MockUp<Context>(context) {
@Mock
void runOnContext(Handler<Void> action) {
Deencapsulation.setField(tcpClientConnection, "status", Status.WORKING);
action.handle(null);
}
};
tcpClientConnection.send(tcpClientPackage, ar -> {
});
Assertions.assertNull(writeQueue.poll());
Assertions.assertNull(packageQueue.poll());
Assertions.assertEquals(Status.WORKING, Deencapsulation.getField(tcpClientConnection, "status"));
}
@Test
public void connect_success(@Mocked NetSocketImpl netSocket) {
Promise<NetSocket> promise = Promise.promise();
new MockUp<NetClientWrapper>(netClientWrapper) {
@Mock
void connect(boolean ssl, int port, String host, Handler<AsyncResult<NetSocket>> connectHandler) {
promise.complete(netSocket);
connectHandler.handle(promise.future());
}
};
tcpClientConnection.connect();
Assertions.assertSame(netSocket, tcpClientConnection.getNetSocket());
Assertions.assertEquals(Status.WORKING, Deencapsulation.getField(tcpClientConnection, "status"));
}
@Test
public void connect_failed() {
requestMap.put(10L, new TcpRequest(10, ar -> {
}));
Promise<NetSocket> promise = Promise.promise();
RuntimeException error = new RuntimeExceptionWithoutStackTrace();
new MockUp<NetClientWrapper>(netClientWrapper) {
@Mock
void connect(boolean ssl, int port, String host, Handler<AsyncResult<NetSocket>> connectHandler) {
promise.fail(error);
connectHandler.handle(promise.future());
}
};
tcpClientConnection.connect();
Assertions.assertEquals(Status.DISCONNECTED, Deencapsulation.getField(tcpClientConnection, "status"));
Assertions.assertEquals(0, requestMap.size());
}
@Test
public void onClosed(@Mocked NetSocketImpl netSocket) {
requestMap.put(10L, new TcpRequest(10, ar -> {
}));
tcpClientConnection.initNetSocket(netSocket);
tcpClientConnection.onClosed(null);
Assertions.assertEquals(Status.DISCONNECTED, Deencapsulation.getField(tcpClientConnection, "status"));
Assertions.assertEquals(0, requestMap.size());
}
@Test
public void onReply_notExist() {
// should not throw exception
tcpClientConnection.onReply(1, null, null);
}
@Test
public void on_exist() {
long msgId = 1L;
AtomicInteger count = new AtomicInteger();
requestMap.put(msgId, new TcpRequest(10, ar -> {
count.incrementAndGet();
}));
tcpClientConnection.onReply(msgId, null, null);
Assertions.assertEquals(1, count.get());
}
}