/* * Copyright 2014-2016 CyberVision, Inc. * * Licensed 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.kaaproject.kaa.client.channel; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import org.junit.Test; import org.kaaproject.kaa.client.channel.connectivity.ConnectivityChecker; import org.kaaproject.kaa.client.channel.failover.FailoverManager; import org.kaaproject.kaa.client.channel.impl.channels.DefaultOperationTcpChannel; import org.kaaproject.kaa.client.persistence.KaaClientState; import org.kaaproject.kaa.common.TransportType; import org.kaaproject.kaa.common.avro.AvroByteArrayConverter; import org.kaaproject.kaa.common.channels.protocols.kaatcp.messages.Disconnect; import org.kaaproject.kaa.common.channels.protocols.kaatcp.messages.Disconnect.DisconnectReason; import org.kaaproject.kaa.common.channels.protocols.kaatcp.messages.PingResponse; import org.kaaproject.kaa.common.endpoint.gen.SyncRequest; import org.kaaproject.kaa.common.endpoint.gen.SyncResponse; import org.kaaproject.kaa.common.endpoint.gen.SyncResponseResultType; import org.kaaproject.kaa.common.endpoint.security.KeyUtil; import org.mockito.Mockito; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PipedInputStream; import java.io.PipedOutputStream; import java.net.Socket; import java.net.UnknownHostException; import java.security.KeyPair; import java.security.NoSuchAlgorithmException; public class DefaultOperationTcpChannelTest { private final KeyPair clientKeys; public DefaultOperationTcpChannelTest() throws Exception { clientKeys = KeyUtil.generateKeyPair(); } @Test public void testDefaultOperationTcpChannel() { KaaClientState clientState = Mockito.mock(KaaClientState.class); FailoverManager failoverManager = Mockito.mock(FailoverManager.class); KaaDataChannel tcpChannel = new DefaultOperationTcpChannel(clientState, failoverManager, null); assertNotNull("New channel's id is null", tcpChannel.getId()); assertNotNull("New channel does not support any of transport types", tcpChannel.getSupportedTransportTypes()); assertNotEquals(0, tcpChannel.getSupportedTransportTypes().size()); } @Test public void testSync() throws Exception { KaaClientState clientState = Mockito.mock(KaaClientState.class); Mockito.when(clientState.getPrivateKey()).thenReturn(clientKeys.getPrivate()); Mockito.when(clientState.getPublicKey()).thenReturn(clientKeys.getPublic()); FailoverManager failoverManager = Mockito.mock(FailoverManager.class); TestOperationTcpChannel tcpChannel = new TestOperationTcpChannel(clientState, failoverManager); AvroByteArrayConverter<SyncResponse> responseCreator = new AvroByteArrayConverter<SyncResponse>(SyncResponse.class); AvroByteArrayConverter<SyncRequest> requestCreator = new AvroByteArrayConverter<SyncRequest>(SyncRequest.class); KaaDataMultiplexer multiplexer = Mockito.mock(KaaDataMultiplexer.class); Mockito.when(multiplexer.compileRequest(Mockito.anyMapOf(TransportType.class, ChannelDirection.class))).thenReturn(requestCreator.toByteArray(new SyncRequest())); KaaDataDemultiplexer demultiplexer = Mockito.mock(KaaDataDemultiplexer.class); tcpChannel.setMultiplexer(multiplexer); tcpChannel.setDemultiplexer(demultiplexer); tcpChannel.sync(TransportType.USER); // will cause call to KaaDataMultiplexer.compileRequest(...) after "CONNECT" messsage tcpChannel.sync(TransportType.PROFILE); TransportConnectionInfo server = IpTransportInfoTest.createTestServerInfo(ServerType.OPERATIONS, TransportProtocolIdConstants.TCP_TRANSPORT_ID, "localhost", 9009, KeyUtil.generateKeyPair().getPublic()); tcpChannel.setServer(server); // causes call to KaaDataMultiplexer.compileRequest(...) for "CONNECT" messsage byte[] rawConnack = new byte[]{0x20, 0x02, 0x00, 0x01}; tcpChannel.os.write(rawConnack); SyncResponse response = new SyncResponse(); response.setStatus(SyncResponseResultType.SUCCESS); tcpChannel.os.write(new org.kaaproject.kaa.common.channels.protocols.kaatcp.messages.SyncResponse(responseCreator.toByteArray(response), false, false).getFrame().array()); Thread.sleep(1000); // sleep a bit to let the message to be received tcpChannel.sync(TransportType.USER); // causes call to KaaDataMultiplexer.compileRequest(...) for "KAA_SYNC" messsage Mockito.verify(multiplexer, Mockito.times(2)).compileRequest(Mockito.anyMapOf(TransportType.class, ChannelDirection.class)); tcpChannel.sync(TransportType.EVENT); Mockito.verify(multiplexer, Mockito.times(3)).compileRequest(Mockito.anyMapOf(TransportType.class, ChannelDirection.class)); Mockito.verify(tcpChannel.socketMock, Mockito.times(3)).getOutputStream(); Mockito.reset(multiplexer); tcpChannel.os.write(new PingResponse().getFrame().array()); tcpChannel.syncAll(); Mockito.verify(multiplexer, Mockito.times(1)).compileRequest(tcpChannel.getSupportedTransportTypes()); tcpChannel.os.write(new Disconnect(DisconnectReason.INTERNAL_ERROR).getFrame().array()); tcpChannel.syncAll(); Mockito.verify(multiplexer, Mockito.times(1)).compileRequest(tcpChannel.getSupportedTransportTypes()); tcpChannel.shutdown(); } @Test public void testConnectivity() throws NoSuchAlgorithmException { KaaClientState clientState = Mockito.mock(KaaClientState.class); Mockito.when(clientState.getPrivateKey()).thenReturn(clientKeys.getPrivate()); Mockito.when(clientState.getPublicKey()).thenReturn(clientKeys.getPublic()); FailoverManager failoverManager = Mockito.mock(FailoverManager.class); DefaultOperationTcpChannel channel = new DefaultOperationTcpChannel(clientState, failoverManager, null); TransportConnectionInfo server = IpTransportInfoTest.createTestServerInfo(ServerType.OPERATIONS, TransportProtocolIdConstants.TCP_TRANSPORT_ID, "www.test.fake", 999, KeyUtil.generateKeyPair().getPublic()); ConnectivityChecker checker = Mockito.mock(ConnectivityChecker.class); Mockito.when(checker.checkConnectivity()).thenReturn(false); channel.setConnectivityChecker(checker); } class TestOperationTcpChannel extends DefaultOperationTcpChannel { public Socket socketMock; public OutputStream os; public InputStream is; public TestOperationTcpChannel(KaaClientState state, FailoverManager failoverManager) throws IOException { super(state, failoverManager, null); PipedInputStream in = new PipedInputStream(4096); PipedOutputStream out = new PipedOutputStream(in); os = out; is = in; socketMock = Mockito.mock(Socket.class); Mockito.when(socketMock.getOutputStream()).thenReturn(os); Mockito.when(socketMock.getInputStream()).thenReturn(is); } @Override protected Socket createSocket(String host, int port) throws UnknownHostException, IOException { return socketMock; } @Override public void shutdown() { super.shutdown(); } } }