/* * 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; import org.junit.Before; import org.junit.Test; import org.kaaproject.kaa.client.bootstrap.DefaultBootstrapManager; import org.kaaproject.kaa.client.channel.GenericTransportInfo; import org.kaaproject.kaa.client.channel.KaaInternalChannelManager; import org.kaaproject.kaa.client.channel.ServerType; import org.kaaproject.kaa.client.channel.TransportConnectionInfo; import org.kaaproject.kaa.client.channel.TransportProtocolId; import org.kaaproject.kaa.client.channel.failover.FailoverDecision; import org.kaaproject.kaa.client.channel.failover.FailoverStatus; import org.kaaproject.kaa.client.channel.failover.strategies.DefaultFailoverStrategy; import org.kaaproject.kaa.client.channel.impl.ChannelRuntimeException; import org.kaaproject.kaa.client.context.ExecutorContext; import org.kaaproject.kaa.client.context.SimpleExecutorContext; import org.kaaproject.kaa.client.context.TransportContext; import org.kaaproject.kaa.client.exceptions.KaaException; import org.kaaproject.kaa.client.exceptions.KaaInvalidConfigurationException; import org.kaaproject.kaa.client.exceptions.KaaRuntimeException; import org.kaaproject.kaa.client.exceptions.KaaUnsupportedPlatformException; import org.kaaproject.kaa.client.logging.AbstractLogCollector; import org.kaaproject.kaa.client.persistence.KaaClientState; import org.kaaproject.kaa.client.persistence.PersistentStorage; import org.kaaproject.kaa.client.profile.ProfileContainer; import org.kaaproject.kaa.client.profile.ProfileRuntimeException; import org.kaaproject.kaa.client.schema.SchemaRuntimeException; import org.kaaproject.kaa.client.transport.TransportException; import org.kaaproject.kaa.client.util.CommonsBase64; import org.kaaproject.kaa.common.endpoint.gen.ProtocolMetaData; import org.kaaproject.kaa.common.endpoint.gen.ProtocolVersionPair; import org.kaaproject.kaa.common.endpoint.security.KeyUtil; import org.kaaproject.kaa.schema.system.EmptyData; import org.mockito.Mockito; import org.springframework.test.util.ReflectionTestUtils; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.OutputStream; import java.security.GeneralSecurityException; import java.security.KeyPair; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class KaaClientTest { private KaaClientPlatformContext platformContext; private KaaClientProperties clientProperties; private KaaClientStateListener stateListener; private PersistentStorage storage; private DefaultBootstrapManager bsManagerMock; private GenericKaaClient client; @Before public void beforeTest() throws Exception { platformContext = Mockito.mock(KaaClientPlatformContext.class); clientProperties = Mockito.mock(KaaClientProperties.class); stateListener = Mockito.mock(KaaClientStateListener.class); storage = Mockito.mock(PersistentStorage.class); Mockito.when(platformContext.getBase64()).thenReturn(CommonsBase64.getInstance()); Mockito.when(platformContext.getProperties()).thenReturn(clientProperties); Mockito.when(platformContext.createPersistentStorage()).thenReturn(storage); ExecutorContext executorContext = new SimpleExecutorContext(); Mockito.when(platformContext.getExecutorContext()).thenReturn(executorContext); Mockito.when(clientProperties.getBootstrapServers()).thenReturn(buildDummyConnectionInfo()); Mockito.when(clientProperties.getPropertiesHash()).thenReturn("test".getBytes()); initStorageMock(storage); bsManagerMock = Mockito.mock(DefaultBootstrapManager.class); client = new AbstractKaaClient(platformContext, stateListener, true) { @Override protected DefaultBootstrapManager buildBootstrapManager(KaaClientProperties properties, KaaClientState kaaClientState, TransportContext transportContext) { return bsManagerMock; } }; client.setProfileContainer(new ProfileContainer() { @Override public EmptyData getProfile() { return new EmptyData(); } }); } @Test(expected = KaaRuntimeException.class) public void initKaaClientDefaultKeyStrategy() { KaaClient client = Kaa.newClient(platformContext, stateListener, false); } @Test public void initKaaClientUserStrategy() { KaaClient client = Kaa.newClient(platformContext, stateListener, true); } @Test public void basicLifeCycleTest() throws Exception { client.start(); Mockito.verify(stateListener, Mockito.timeout(1000)).onStarted(); Mockito.verify(bsManagerMock).receiveOperationsServerList(); client.pause(); Mockito.verify(stateListener, Mockito.timeout(1000)).onPaused(); client.resume(); Mockito.verify(stateListener, Mockito.timeout(1000)).onResume(); client.stop(); Mockito.verify(stateListener, Mockito.timeout(1000)).onStopped(); } @Test public void basicStartBSFailureTest() throws Exception { Mockito.doThrow(new TransportException("mock")).when(bsManagerMock).receiveOperationsServerList(); client.start(); Mockito.verify(stateListener, Mockito.timeout(1000)).onStartFailure(Mockito.any(KaaException.class)); Mockito.verify(bsManagerMock).receiveOperationsServerList(); client.stop(); Mockito.verify(stateListener, Mockito.timeout(1000)).onStopped(); } protected void initStorageMock(PersistentStorage storage) throws NoSuchAlgorithmException, IOException { KeyPair kp = KeyUtil.generateKeyPair(); Mockito.when(storage.exists(KaaClientProperties.CLIENT_PUBLIC_KEY_NAME_DEFAULT)).thenReturn(true); Mockito.when(storage.exists(KaaClientProperties.CLIENT_PRIVATE_KEY_NAME_DEFAULT)).thenReturn(true); Mockito.when(storage.openForRead(KaaClientProperties.CLIENT_PUBLIC_KEY_NAME_DEFAULT)).thenReturn( new ByteArrayInputStream(kp.getPublic().getEncoded())); Mockito.when(storage.openForRead(KaaClientProperties.CLIENT_PRIVATE_KEY_NAME_DEFAULT)).thenReturn( new ByteArrayInputStream(kp.getPrivate().getEncoded())); Mockito.when(storage.openForWrite(Mockito.anyString())).thenReturn(Mockito.mock(OutputStream.class)); } protected Map<TransportProtocolId, List<TransportConnectionInfo>> buildDummyConnectionInfo() { Map<TransportProtocolId, List<TransportConnectionInfo>> connectionInfo = new HashMap<>(); List<TransportConnectionInfo> connectionInfoList = new ArrayList<TransportConnectionInfo>(); connectionInfoList .add(new GenericTransportInfo(ServerType.BOOTSTRAP, new ProtocolMetaData(1, new ProtocolVersionPair(1, 1), null))); connectionInfo.put(new TransportProtocolId(1, 1), connectionInfoList); return connectionInfo; } @Test public void failureOnStartTest() throws TransportException { Mockito.doThrow(new KaaRuntimeException(new Exception("cause"))).when(bsManagerMock).receiveOperationsServerList(); client.start(); Mockito.verify(stateListener, Mockito.timeout(1000)).onStartFailure(Mockito.any(KaaException.class)); } @Test public void failureOnStopTest() { client.start(); AbstractLogCollector logCollector = Mockito.mock(AbstractLogCollector.class); Mockito.doThrow(new RuntimeException()).when(logCollector).stop(); ReflectionTestUtils.setField(client, "logCollector", logCollector); client.stop(); Mockito.verify(stateListener, Mockito.timeout(1000)).onStopFailure(Mockito.any(KaaException.class)); } @Test public void failureOnPauseTest() { client.start(); KaaClientState clientState = Mockito.mock(KaaClientState.class); Mockito.doThrow(new RuntimeException()).when(clientState).persist(); ReflectionTestUtils.setField(client, "kaaClientState", clientState); client.pause(); Mockito.verify(stateListener, Mockito.timeout(1000)).onPauseFailure(Mockito.any(KaaException.class)); } @Test public void failureOnResumeTest() { client.start(); Mockito.verify(stateListener, Mockito.timeout(1000)).onStarted(); client.pause(); Mockito.verify(stateListener, Mockito.timeout(1000)).onPaused(); KaaInternalChannelManager channelManager = Mockito.mock(KaaInternalChannelManager.class); Mockito.doThrow(new RuntimeException()).when(channelManager).resume(); ReflectionTestUtils.setField(client, "channelManager", channelManager); client.resume(); Mockito.verify(stateListener, Mockito.timeout(1000)).onResumeFailure(Mockito.any(KaaException.class)); } @Test public void exceptionCreationTest() { KaaUnsupportedPlatformException kaaUnsupportedPlatformException = new KaaUnsupportedPlatformException(new Exception()); ProfileRuntimeException profileRuntimeException = new ProfileRuntimeException(""); SchemaRuntimeException schemaRuntimeException1 = new SchemaRuntimeException(); SchemaRuntimeException schemaRuntimeException2 = new SchemaRuntimeException(""); KaaInvalidConfigurationException invalidConfigurationException = new KaaInvalidConfigurationException(new Exception()); ChannelRuntimeException channelRuntimeException1 = new ChannelRuntimeException(); ChannelRuntimeException channelRuntimeException2 = new ChannelRuntimeException(new Exception()); ChannelRuntimeException channelRuntimeException3 = new ChannelRuntimeException("", new Exception()); ChannelRuntimeException channelRuntimeException4 = new ChannelRuntimeException("", new Exception(), true, true); } @Test public void failureListenerTest() throws IOException, GeneralSecurityException { client.setFailoverStrategy(new DefaultFailoverStrategy() { @Override public FailoverDecision onFailover(FailoverStatus failoverStatus) { return new FailoverDecision(FailoverDecision.FailoverAction.FAILURE); } }); client.start(); ProtocolMetaData metaData = new ProtocolMetaData(1, new ProtocolVersionPair(1, 1), null); TransportConnectionInfo info = new GenericTransportInfo(ServerType.BOOTSTRAP, metaData); client.getChannelManager().onServerFailed(info, FailoverStatus.BOOTSTRAP_SERVERS_NA); Mockito.verify(stateListener, Mockito.timeout(500)).onStopped(); } }