/***********************************************************************************
*
* Copyright (c) 2014 Kamil Baczkowicz
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* The Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
*
* Kamil Baczkowicz - initial API and implementation and/or initial documentation
*
*/
package pl.baczkowicz.mqttspy.connectivity;
import javafx.scene.paint.Color;
import junit.framework.TestCase;
import org.eclipse.paho.client.mqttv3.MqttAsyncClient;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.jmock.Expectations;
import org.jmock.Mockery;
import org.jmock.lib.legacy.ClassImposteriser;
import org.junit.Before;
import org.junit.Test;
import pl.baczkowicz.mqttspy.configuration.ConfiguredConnectionDetails;
import pl.baczkowicz.mqttspy.connectivity.reconnection.ReconnectionManager;
import pl.baczkowicz.mqttspy.messages.FormattedMqttMessage;
import pl.baczkowicz.mqttspy.stats.StatisticsManager;
import pl.baczkowicz.mqttspy.ui.events.ConnectionStatusChangeEvent;
import pl.baczkowicz.mqttspy.ui.events.SubscriptionStatusChangeEvent;
import pl.baczkowicz.spy.common.generated.FormatterDetails;
import pl.baczkowicz.spy.eventbus.IKBus;
import pl.baczkowicz.spy.exceptions.ConfigurationException;
import pl.baczkowicz.spy.exceptions.XMLException;
import pl.baczkowicz.spy.formatting.FormattingManager;
import pl.baczkowicz.spy.ui.events.queuable.EventQueueManager;
public class MqttConnectionTest extends TestCase
{
private static final String name = "testClient";
private static final String serverURI = "localhost";
private static final String clientId = "testClientId";
private static final String subscription_TOPIC = "/#";
private static final String message_TOPIC = "/topic";
private MqttAsyncClient mockClient;
private Mockery context = new Mockery()
{
{
setImposteriser(ClassImposteriser.INSTANCE);
}
};
// private EventManager mockEventManager;
private IKBus mockEventBus;
private StatisticsManager statisticsManager;
private ReconnectionManager mockedReconnectionManager;
private FormattingManager mockedFormattingManager;
@Before
public void setUp() throws XMLException
{
mockClient = context.mock(MqttAsyncClient.class);
// mockEventManager = context.mock(EventManager.class);
mockEventBus = context.mock(IKBus.class);
mockedReconnectionManager = context.mock(ReconnectionManager.class);
mockedFormattingManager = context.mock(FormattingManager.class);
statisticsManager = new StatisticsManager();
statisticsManager.loadStats();
}
@Test
public void testUnsubscribeAndRemove() throws MqttException, ConfigurationException
{
// Set up connection
final ConfiguredConnectionDetails configuredConnectionDetails = new ConfiguredConnectionDetails();
configuredConnectionDetails.setName(name);
configuredConnectionDetails.getServerURI().add(serverURI);
configuredConnectionDetails.setClientID(clientId);
configuredConnectionDetails.setCleanSession(false);
configuredConnectionDetails.setConnectionTimeout(5);
configuredConnectionDetails.setKeepAliveInterval(5);
configuredConnectionDetails.setMinMessagesStoredPerTopic(10);
configuredConnectionDetails.setMaxMessagesStored(500);
final RuntimeConnectionProperties connectionProperties = new RuntimeConnectionProperties(configuredConnectionDetails);
context.checking(new Expectations()
{
{
oneOf(mockEventBus).publish(with(any(ConnectionStatusChangeEvent.class)));
}
});
final MqttAsyncConnection connection = new MqttAsyncConnection(
mockedReconnectionManager, connectionProperties, MqttConnectionStatus.CONNECTING,
mockEventBus, null, mockedFormattingManager, new EventQueueManager(), 100);
connection.setStatisticsManager(statisticsManager);
context.assertIsSatisfied();
connection.setClient(mockClient);
// This should add a subscription
final MqttSubscription subscription = new MqttSubscription(subscription_TOPIC, 0, Color.WHITE, 10, 100,
new EventQueueManager(), mockEventBus, mockedFormattingManager, 100);
context.checking(new Expectations()
{
{
oneOf(mockClient).subscribe(subscription_TOPIC, 0);
oneOf(mockClient).unsubscribe(subscription_TOPIC);
allowing(mockClient).isConnected();
will(returnValue(true));
// Note: not checking if passing the subscription object as param
allowing(mockEventBus).publish(with(any(SubscriptionStatusChangeEvent.class)));
allowing(mockedFormattingManager).formatMessage(with(any(FormattedMqttMessage.class)), with(any(FormatterDetails.class)));
}
});
//subscription.addObserver(mockObserver);
assertTrue(connection.subscribe(subscription));
// This should handle the message
FormattedMqttMessage message = new FormattedMqttMessage(1, message_TOPIC, new MqttMessage("test".getBytes()), connection);
connection.messageReceived(message);
// This should remove the subscription
connection.unsubscribeAndRemove(subscription);
// This should be ignored - no matching subscriptions
connection.messageReceived(message);
context.assertIsSatisfied();
}
@Test
public void testUnsubscribe() throws MqttException, ConfigurationException
{
// Set up connection
final ConfiguredConnectionDetails configuredConnectionDetails = new ConfiguredConnectionDetails();
configuredConnectionDetails.setName(name);
configuredConnectionDetails.getServerURI().add(serverURI);
configuredConnectionDetails.setClientID(clientId);
configuredConnectionDetails.setCleanSession(false);
configuredConnectionDetails.setConnectionTimeout(5);
configuredConnectionDetails.setKeepAliveInterval(5);
configuredConnectionDetails.setMinMessagesStoredPerTopic(10);
configuredConnectionDetails.setMaxMessagesStored(200);
final RuntimeConnectionProperties connectionProperties = new RuntimeConnectionProperties(configuredConnectionDetails);
context.checking(new Expectations()
{
{
oneOf(mockEventBus).publish(with(any(ConnectionStatusChangeEvent.class)));
}
});
final MqttAsyncConnection connection = new MqttAsyncConnection(
mockedReconnectionManager, connectionProperties, MqttConnectionStatus.CONNECTING,
mockEventBus, null, mockedFormattingManager, new EventQueueManager(), 100);
connection.setStatisticsManager(statisticsManager);
context.assertIsSatisfied();
connection.setClient(mockClient);
// This should add a subscription
final MqttSubscription subscription = new MqttSubscription(subscription_TOPIC, 0, Color.WHITE, 10, 100,
new EventQueueManager(), mockEventBus, mockedFormattingManager, 100);
// This should handle the message
FormattedMqttMessage message = new FormattedMqttMessage(1, message_TOPIC, new MqttMessage("test".getBytes()), connection);
context.checking(new Expectations()
{
{
oneOf(mockClient).subscribe(subscription_TOPIC, 0);
oneOf(mockClient).unsubscribe(subscription_TOPIC);
allowing(mockClient).isConnected();
will(returnValue(true));
// Note: not checking if passing the subscription object as param
allowing(mockEventBus).publish(with(any(SubscriptionStatusChangeEvent.class)));
allowing(mockedFormattingManager).formatMessage(with(any(FormattedMqttMessage.class)), with(any(FormatterDetails.class)));
}
});
assertTrue(connection.subscribe(subscription));
connection.messageReceived(message);
// This should remove the subscription
connection.unsubscribe(subscription, true);
// This should be ignored - subscription not active
connection.messageReceived(message);
context.assertIsSatisfied();
}
}