Changed lib structure to be modular

This commit is contained in:
selva.andre
2012-05-10 22:00:57 +02:00
parent 0dc403d278
commit 2cbf237887
75 changed files with 87 additions and 65 deletions
@@ -0,0 +1,63 @@
package org.dna.mqtt.moquette.proto;
import org.dna.mqtt.moquette.proto.ConnAckDecoder;
import org.apache.mina.filter.codec.demux.MessageDecoderResult;
import org.dna.mqtt.moquette.proto.messages.AbstractMessage;
import org.apache.mina.filter.codec.demux.MessageDecoder;
import org.apache.mina.core.buffer.IoBuffer;
import org.dna.mqtt.moquette.proto.TestUtils.MockProtocolDecoderOutput;
import org.dna.mqtt.moquette.proto.messages.ConnAckMessage;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
/**
*
* @author andrea
*/
public class ConnAckDecoderTest {
IoBuffer m_buff;
ConnAckDecoder m_msgdec;
MockProtocolDecoderOutput<ConnAckMessage> m_mockProtoDecoder;
@Before
public void setUp() {
m_buff = IoBuffer.allocate(4);
m_msgdec = new ConnAckDecoder();
m_mockProtoDecoder = new MockProtocolDecoderOutput<ConnAckMessage>();
}
@Test
public void testDecodable_OK() {
m_buff.put((byte)(AbstractMessage.CONNACK << 4)).flip();
assertEquals(MessageDecoder.OK , m_msgdec.decodable(null, m_buff));
}
@Test
public void testDecodable_NOT_OK() {
m_buff.put((byte)(AbstractMessage.CONNECT << 4)).flip();
assertEquals(MessageDecoder.NOT_OK , m_msgdec.decodable(null, m_buff));
}
@Test
public void testHeader() throws Exception {
m_buff = IoBuffer.allocate(14);
initHeader(m_buff);
m_buff.flip();
//Exercise
MessageDecoderResult res = m_msgdec.decode(null, m_buff, m_mockProtoDecoder);
assertNotNull(m_mockProtoDecoder.getMessage());
assertEquals(MessageDecoder.OK, res);
assertEquals(ConnAckMessage.CONNECTION_ACCEPTED, m_mockProtoDecoder.getMessage().getReturnCode());
}
private void initHeader(IoBuffer buff) {
buff.clear().put((byte)(AbstractMessage.CONNACK << 4)).put((byte)2);
//reserved
buff.put((byte)0);
//return code
buff.put(ConnAckMessage.CONNECTION_ACCEPTED);
}
}
@@ -0,0 +1,28 @@
package org.dna.mqtt.moquette.proto;
import org.dna.mqtt.moquette.proto.ConnAckEncoder;
import org.dna.mqtt.moquette.proto.messages.ConnAckMessage;
import org.junit.Test;
import static org.junit.Assert.*;
/**
*
* @author andrea
*/
public class ConnAckEncoderTest {
@Test
public void testHeaderEncode() throws Exception {
TestUtils.MockProtocolEncoderOutput mockProtoEncoder = new TestUtils.MockProtocolEncoderOutput();
ConnAckEncoder encoder = new ConnAckEncoder();
ConnAckMessage msg = new ConnAckMessage();
//Exercise
encoder.encode(null, msg, mockProtoEncoder);
//Verify
assertEquals(0x20, mockProtoEncoder.getBuffer().get()); //1 byte
assertEquals(0x02, mockProtoEncoder.getBuffer().get()); //2 byte, length
assertEquals(ConnAckMessage.CONNECTION_ACCEPTED, mockProtoEncoder.getBuffer().skip(1).get());
}
}
@@ -0,0 +1,188 @@
package org.dna.mqtt.moquette.proto;
import org.dna.mqtt.moquette.proto.ConnectDecoder;
import org.dna.mqtt.moquette.proto.Utils;
import org.dna.mqtt.moquette.proto.messages.AbstractMessage;
import org.dna.mqtt.moquette.proto.messages.ConnectMessage;
import org.dna.mqtt.moquette.proto.TestUtils.MockProtocolDecoderOutput;
import org.apache.mina.filter.codec.demux.MessageDecoderResult;
import java.io.UnsupportedEncodingException;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.filter.codec.demux.MessageDecoder;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
public class ConnectDecoderTest {
IoBuffer m_buff;
ConnectDecoder m_msgdec;
MockProtocolDecoderOutput<ConnectMessage> m_mockProtoDecoder;
@Before
public void setUp() {
m_buff = IoBuffer.allocate(4);
m_msgdec = new ConnectDecoder();
m_mockProtoDecoder = new MockProtocolDecoderOutput<ConnectMessage>();
}
@Test
public void testDecodable_OK() {
m_buff.put((byte)(AbstractMessage.CONNECT << 4)).flip();
assertEquals(MessageDecoder.OK , m_msgdec.decodable(null, m_buff));
}
@Test
public void testDecodable_NOT_OK() {
m_buff.put((byte)(AbstractMessage.CONNACK << 4)).flip();
assertEquals(MessageDecoder.NOT_OK , m_msgdec.decodable(null, m_buff));
}
@Test
public void testDecodable_NEED_DATA() {
m_buff = IoBuffer.allocate(0);
assertFalse(m_buff.hasRemaining());
assertEquals(MessageDecoder.NEED_DATA , m_msgdec.decodable(null, m_buff));
}
@Test
public void testDecodeRemainingLenght() {
//1 byte length
m_buff.put((byte)0x0).flip();
assertEquals(0, Utils.decodeRemainingLenght(m_buff));
m_buff.clear().put((byte) 0x007F).flip();
assertEquals(127, Utils.decodeRemainingLenght(m_buff));
//2 byte length
m_buff.clear().put((byte) 0x80).put((byte) 0x01).flip();
assertEquals(128, Utils.decodeRemainingLenght(m_buff));
m_buff.clear().put((byte) 0xFF).put((byte) 0x7F).flip();
assertEquals(16383, Utils.decodeRemainingLenght(m_buff));
//3 byte length
m_buff.clear().put((byte) 0x80).put((byte) 0x80).put((byte)0x01).flip();
assertEquals(16384, Utils.decodeRemainingLenght(m_buff));
m_buff.clear().put((byte) 0xFF).put((byte) 0xFF).put((byte)0x7F).flip();
assertEquals(2097151, Utils.decodeRemainingLenght(m_buff));
//4 byte length
m_buff.clear().put((byte) 0x80).put((byte) 0x80).put((byte)0x80).put((byte)0x01).flip();
assertEquals(2097152, Utils.decodeRemainingLenght(m_buff));
m_buff.clear().put((byte) 0xFF).put((byte) 0xFF).put((byte) 0xFF).put((byte)0x7F).flip();
assertEquals(268435455, Utils.decodeRemainingLenght(m_buff));
}
@Test
public void testBaseHeader() throws Exception {
m_buff = IoBuffer.allocate(14);
initBaseHeader(m_buff);
m_buff.flip();
//Excercise
m_msgdec.decode(null, m_buff, m_mockProtoDecoder);
//Verify
verifyBaseHeader(m_mockProtoDecoder.getMessage());
}
@Test
public void testBaseHeader_ClientID() throws UnsupportedEncodingException, Exception {
m_buff = IoBuffer.allocate(40);
initHeader(m_buff, (byte) 38);
encodeString(m_buff, "ABCDEFGH");
encodeString(m_buff, "Topic");
encodeString(m_buff, "Message");
m_buff.flip();
//Excercise
m_msgdec.decode(null, m_buff, m_mockProtoDecoder);
//Verify
verifyBaseHeader(m_mockProtoDecoder.getMessage());
assertEquals("ABCDEFGH", m_mockProtoDecoder.getMessage().getClientID());
assertEquals("Topic", m_mockProtoDecoder.getMessage().getWillTopic());
assertEquals("Message", m_mockProtoDecoder.getMessage().getWillMessage());
}
@Test
public void testBaseHeader_extra_with_user_pwd() throws UnsupportedEncodingException, Exception {
m_buff = IoBuffer.allocate(55);
initHeader(m_buff, (byte) 53);
encodeString(m_buff, "ABCDEFGH");
encodeString(m_buff, "Topic");
encodeString(m_buff, "Message");
encodeString(m_buff, "Fakeuser");
encodeString(m_buff, "pwd");
m_buff.flip();
//Excercise
m_msgdec.decode(null, m_buff, m_mockProtoDecoder);
//Verify
verifyBaseHeader(m_mockProtoDecoder.getMessage());
assertEquals("ABCDEFGH", m_mockProtoDecoder.getMessage().getClientID());
assertEquals("Topic", m_mockProtoDecoder.getMessage().getWillTopic());
assertEquals("Message", m_mockProtoDecoder.getMessage().getWillMessage());
assertEquals("Fakeuser", m_mockProtoDecoder.getMessage().getUsername());
assertEquals("pwd", m_mockProtoDecoder.getMessage().getPassword());
}
@Test
public void testBadFlagUserPwd() throws UnsupportedEncodingException, Exception {
m_buff = IoBuffer.allocate(14);
m_buff.clear().put((byte)(AbstractMessage.CONNECT << 4)).put((byte)12);
//Proto name
encodeString(m_buff, "MQIsdp");
//version
m_buff.put((byte)3);
//conn flags
m_buff.put((byte)0x4E); //sets user to false and password to true
//keepAlive
m_buff.put((byte)0).put((byte) 0x0A);
m_buff.flip();
//Excercise
MessageDecoderResult res = m_msgdec.decode(null, m_buff, m_mockProtoDecoder);
assertNull(m_mockProtoDecoder.getMessage());
assertEquals(MessageDecoder.NOT_OK, res);
}
/**
* Encode and insert the given stirng into the given buff
*/
private IoBuffer encodeString(IoBuffer buff, String str) throws UnsupportedEncodingException {
buff.put(Utils.encodeString(str));
return buff;
}
private void initBaseHeader(IoBuffer buff) throws UnsupportedEncodingException {
initHeader(buff, (byte)0x0C);
}
private void initHeader(IoBuffer buff, byte remaingLength) throws UnsupportedEncodingException {
buff.clear().put((byte)(AbstractMessage.CONNECT << 4)).put(remaingLength);
//Proto name
encodeString(buff, "MQIsdp");
//version
buff.put((byte)3);
//conn flags
buff.put((byte)0xCE);
//keepAlive
buff.put((byte)0).put((byte) 0x0A);
}
private void verifyBaseHeader(ConnectMessage connMessage) {
assertNotNull(connMessage);
assertEquals("MQIsdp", connMessage.getProtocolName());
assertEquals(3, connMessage.getProcotolVersion());
assertTrue(connMessage.isUserFlag());
assertTrue(connMessage.isPasswordFlag());
assertTrue(connMessage.isCleanSession());
assertEquals(10, connMessage.getKeepAlive());
assertTrue(connMessage.isWillFlag());
assertFalse(connMessage.isWillRetain());
assertEquals(1, connMessage.getWillQos());
}
}
@@ -0,0 +1,147 @@
package org.dna.mqtt.moquette.proto;
import org.dna.mqtt.moquette.proto.ConnectEncoder;
import org.dna.mqtt.moquette.proto.Utils;
import org.dna.mqtt.moquette.proto.messages.ConnectMessage;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
import static org.dna.mqtt.moquette.proto.TestUtils.*;
/**
*
* @author andrea
*/
public class ConnectEncoderTest {
ConnectEncoder m_encoder;
TestUtils.MockProtocolEncoderOutput m_mockProtoEncoder;
@Before
public void setUp() {
m_encoder = new ConnectEncoder();
m_mockProtoEncoder = new TestUtils.MockProtocolEncoderOutput();
}
@Test(expected=IllegalAccessException.class)
public void testEncodeRemainingLength_invalid_upper() throws IllegalAccessException {
Utils.encodeRemainingLength(Utils.MAX_LENGTH_LIMIT + 1);
}
@Test(expected=IllegalAccessException.class)
public void testEncodeRemainingLength_invalid_lower() throws IllegalAccessException {
Utils.encodeRemainingLength(-1);
}
@Test
public void testEncodeRemainingLenght() throws IllegalAccessException {
//1 byte length
verifyBuff(1, new byte[]{0}, Utils.encodeRemainingLength(0));
verifyBuff(1, new byte[]{0x7F}, Utils.encodeRemainingLength(127));
//2 byte length
verifyBuff(2, new byte[]{(byte)0x80, 0x01}, Utils.encodeRemainingLength(128));
verifyBuff(2, new byte[]{(byte)0xFF, 0x7F}, Utils.encodeRemainingLength(16383));
//3 byte length
verifyBuff(3, new byte[]{(byte)0x80, (byte)0x80, 0x01}, Utils.encodeRemainingLength(16384));
verifyBuff(3, new byte[]{(byte)0xFF, (byte)0xFF, 0x7F}, Utils.encodeRemainingLength(2097151));
//4 byte length
verifyBuff(4, new byte[]{(byte)0x80, (byte)0x80, (byte)0x80, 0x01}, Utils.encodeRemainingLength(2097152));
verifyBuff(4, new byte[]{(byte)0xFF, (byte)0xFF, (byte)0xFF, 0x7F}, Utils.encodeRemainingLength(268435455));
}
@Test
public void testBaseHeader() throws Exception {
ConnectMessage msg = new ConnectMessage();
msg.setWillRetain(true);
msg.setWillQos((byte)2);
msg.setWillFlag(false);
msg.setCleanSession(true);
msg.setKeepAlive(512);
//Exercise
m_encoder.encode(null, msg, m_mockProtoEncoder);
//Verify
assertEquals(0x10, m_mockProtoEncoder.getBuffer().get()); //1 byte
assertEquals(12, m_mockProtoEncoder.getBuffer().get()); //remaining length
verifyString("MQIsdp", m_mockProtoEncoder.getBuffer());
assertEquals(0x03, m_mockProtoEncoder.getBuffer().get()); //protocol version
assertEquals(0x32, m_mockProtoEncoder.getBuffer().get()); //flags
assertEquals(2, m_mockProtoEncoder.getBuffer().get()); //keepAliveTimer msb
assertEquals(0, m_mockProtoEncoder.getBuffer().get()); //keepAliveTimer lsb
}
@Test
public void testCompleteHeader() throws Exception {
ConnectMessage msg = new ConnectMessage();
msg.setWillRetain(true);
msg.setWillQos((byte)2);
msg.setWillFlag(true);
msg.setCleanSession(true);
msg.setKeepAlive(512);
//variable part
msg.setClientID("ABCDEF");
msg.setWillTopic("Topic");
msg.setWillMessage("Message");
//Exercise
m_encoder.encode(null, msg, m_mockProtoEncoder);
//Verify
assertEquals(0x10, m_mockProtoEncoder.getBuffer().get()); //1 byte
assertEquals(36, m_mockProtoEncoder.getBuffer().get()); //remaining length
verifyString("MQIsdp", m_mockProtoEncoder.getBuffer());
assertEquals(0x03, m_mockProtoEncoder.getBuffer().get()); //protocol version
assertEquals(0x36, m_mockProtoEncoder.getBuffer().get()); //flags
assertEquals(2, m_mockProtoEncoder.getBuffer().get()); //keepAliveTimer msb
assertEquals(0, m_mockProtoEncoder.getBuffer().get()); //keepAliveTimer lsb
//Variable part
verifyString("ABCDEF", m_mockProtoEncoder.getBuffer());
verifyString("Topic", m_mockProtoEncoder.getBuffer());
verifyString("Message", m_mockProtoEncoder.getBuffer());
}
@Test
public void testCompleteHeaderWIthUser_password() throws Exception {
ConnectMessage msg = new ConnectMessage();
msg.setUserFlag(true);
msg.setPasswordFlag(true);
msg.setWillRetain(true);
msg.setWillQos((byte)2);
msg.setWillFlag(true);
msg.setCleanSession(true);
msg.setKeepAlive(512);
//variable part
msg.setClientID("ABCDEF");
msg.setWillTopic("Topic");
msg.setWillMessage("Message");
msg.setUsername("Pablo");
msg.setPassword("PBL");
//Exercise
m_encoder.encode(null, msg, m_mockProtoEncoder);
//Verify
assertEquals(0x10, m_mockProtoEncoder.getBuffer().get()); //1 byte
assertEquals(48, m_mockProtoEncoder.getBuffer().get()); //remaining length
verifyString("MQIsdp", m_mockProtoEncoder.getBuffer());
assertEquals(0x03, m_mockProtoEncoder.getBuffer().get()); //protocol version
assertEquals((byte)0xF6, (byte)m_mockProtoEncoder.getBuffer().get()); //flags
assertEquals(2, m_mockProtoEncoder.getBuffer().get()); //keepAliveTimer msb
assertEquals(0, m_mockProtoEncoder.getBuffer().get()); //keepAliveTimer lsb
//Variable part
verifyString("ABCDEF", m_mockProtoEncoder.getBuffer());
verifyString("Topic", m_mockProtoEncoder.getBuffer());
verifyString("Message", m_mockProtoEncoder.getBuffer());
verifyString("Pablo", m_mockProtoEncoder.getBuffer());//username
verifyString("PBL", m_mockProtoEncoder.getBuffer());//password
}
}
@@ -0,0 +1,52 @@
package org.dna.mqtt.moquette.proto;
import org.dna.mqtt.moquette.proto.PubAckDecoder;
import org.dna.mqtt.moquette.proto.Utils;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.filter.codec.demux.MessageDecoder;
import org.apache.mina.filter.codec.demux.MessageDecoderResult;
import org.dna.mqtt.moquette.proto.TestUtils.MockProtocolDecoderOutput;
import org.dna.mqtt.moquette.proto.messages.PubAckMessage;
import org.dna.mqtt.moquette.proto.messages.AbstractMessage;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
/**
*
* @author andrea
*/
public class PubAckDecoderTest {
IoBuffer m_buff;
PubAckDecoder m_msgdec;
MockProtocolDecoderOutput<PubAckMessage> m_mockProtoDecoder;
@Before
public void setUp() {
m_buff = IoBuffer.allocate(4);
m_msgdec = new PubAckDecoder();
m_mockProtoDecoder = new MockProtocolDecoderOutput<PubAckMessage>();
}
@Test
public void testHeader() throws Exception {
m_buff = IoBuffer.allocate(14);
int messageId = 0xAABB;
initHeader(m_buff, messageId);
m_buff.flip();
//Exercise
MessageDecoderResult res = m_msgdec.decode(null, m_buff, m_mockProtoDecoder);
assertNotNull(m_mockProtoDecoder.getMessage());
assertEquals(MessageDecoder.OK, res);
assertEquals(messageId, m_mockProtoDecoder.getMessage().getMessageID());
}
private void initHeader(IoBuffer buff, int messageID) {
buff.clear().put((byte)(AbstractMessage.PUBACK << 4)).put((byte)2);
//return code
Utils.writeWord(buff, messageID);
}
}
@@ -0,0 +1,31 @@
package org.dna.mqtt.moquette.proto;
import org.dna.mqtt.moquette.proto.PubAckEncoder;
import org.dna.mqtt.moquette.proto.messages.PubAckMessage;
import org.junit.Test;
import static org.junit.Assert.*;
/**
*
* @author andrea
*/
public class PubAckEncoderTest {
@Test
public void testHeaderEncode() throws Exception {
int messageID = 0xAABB;
TestUtils.MockProtocolEncoderOutput mockProtoEncoder = new TestUtils.MockProtocolEncoderOutput();
PubAckEncoder encoder = new PubAckEncoder();
PubAckMessage msg = new PubAckMessage();
msg.setMessageID(messageID);
//Exercise
encoder.encode(null, msg, mockProtoEncoder);
//Verify
assertEquals(0x40, mockProtoEncoder.getBuffer().get()); //1 byte
assertEquals(0x02, mockProtoEncoder.getBuffer().get()); //2 byte, length
assertEquals((byte)0xAA, mockProtoEncoder.getBuffer().get());
assertEquals((byte)0xBB, mockProtoEncoder.getBuffer().get());
}
}
@@ -0,0 +1,114 @@
package org.dna.mqtt.moquette.proto;
import org.dna.mqtt.moquette.proto.PublishDecoder;
import org.dna.mqtt.moquette.proto.Utils;
import org.apache.mina.filter.codec.demux.MessageDecoderResult;
import org.dna.mqtt.moquette.proto.messages.PublishMessage;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.filter.codec.demux.MessageDecoder;
import org.dna.mqtt.moquette.proto.TestUtils.MockProtocolDecoderOutput;
import org.dna.mqtt.moquette.proto.messages.AbstractMessage;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
/**
*
* @author andrea
*/
public class PublishDecoderTest {
IoBuffer m_buff;
PublishDecoder m_msgdec;
MockProtocolDecoderOutput<PublishMessage> m_mockProtoDecoder;
@Before
public void setUp() {
m_buff = IoBuffer.allocate(4);
m_msgdec = new PublishDecoder();
m_mockProtoDecoder = new MockProtocolDecoderOutput<PublishMessage>();
}
@Test
public void testDecodable_OK() {
m_buff.put((byte) (AbstractMessage.PUBLISH << 4)).flip();
assertEquals(MessageDecoder.OK, m_msgdec.decodable(null, m_buff));
}
@Test
public void testHeader() throws Exception {
m_buff = IoBuffer.allocate(14);
initHeader(m_buff);
m_buff.flip();
//Exercise
MessageDecoderResult res = m_msgdec.decode(null, m_buff, m_mockProtoDecoder);
assertNotNull(m_mockProtoDecoder.getMessage());
assertEquals(MessageDecoder.OK, res);
assertEquals("Fake Topic", m_mockProtoDecoder.getMessage().getTopicName());
assertNull(m_mockProtoDecoder.getMessage().getMessageID());
}
@Test
public void testHeaderWithMessageID() throws Exception {
m_buff = IoBuffer.allocate(14).setAutoExpand(true);
int messageID = 123;
initHeaderWithMessageID(m_buff, messageID);
m_buff.flip();
//Exercise
MessageDecoderResult res = m_msgdec.decode(null, m_buff, m_mockProtoDecoder);
assertNotNull(m_mockProtoDecoder.getMessage());
assertEquals(MessageDecoder.OK, res);
assertEquals("Fake Topic", m_mockProtoDecoder.getMessage().getTopicName());
assertEquals(messageID, (int) m_mockProtoDecoder.getMessage().getMessageID());
}
@Test
public void testHeaderWithMessageID_Payload() throws Exception {
m_buff = IoBuffer.allocate(14).setAutoExpand(true);
int messageID = 123;
byte[] payload = new byte[]{0x0A, 0x0B, 0x0C};
initHeaderWithMessageID_Payload(m_buff, messageID, payload);
m_buff.flip();
//Exercise
MessageDecoderResult res = m_msgdec.decode(null, m_buff, m_mockProtoDecoder);
assertNotNull(m_mockProtoDecoder.getMessage());
assertEquals(MessageDecoder.OK, res);
assertEquals("Fake Topic", m_mockProtoDecoder.getMessage().getTopicName());
assertEquals(messageID, (int) m_mockProtoDecoder.getMessage().getMessageID());
TestUtils.verifyEquals(payload, m_mockProtoDecoder.getMessage().getPayload());
}
private void initHeader(IoBuffer buff) throws IllegalAccessException {
IoBuffer tmp = IoBuffer.allocate(4).setAutoExpand(true).put(Utils.encodeString("Fake Topic")).flip();
buff.clear().put((byte) (AbstractMessage.PUBLISH << 4)).put(Utils.encodeRemainingLength(tmp.remaining()));
//topic name
buff.put(tmp);
}
private void initHeaderWithMessageID(IoBuffer buff, int messageID) throws IllegalAccessException {
IoBuffer tmp = IoBuffer.allocate(4).setAutoExpand(true).put(Utils.encodeString("Fake Topic"));
Utils.writeWord(tmp, messageID);
tmp.flip();
buff.clear().put((byte) (AbstractMessage.PUBLISH << 4 | 0x02)) //set Qos to 1
.put(Utils.encodeRemainingLength(tmp.remaining()));
//topic name
buff.put(tmp);
}
private void initHeaderWithMessageID_Payload(IoBuffer buff, int messageID, byte[] payload) throws IllegalAccessException {
IoBuffer tmp = IoBuffer.allocate(4).setAutoExpand(true).put(Utils.encodeString("Fake Topic"));
Utils.writeWord(tmp, messageID);
tmp.put(payload);
tmp.flip();
buff.clear().put((byte) (AbstractMessage.PUBLISH << 4 | 0x02)) //set Qos to 1
.put(Utils.encodeRemainingLength(tmp.remaining()));
//topic name
buff.put(tmp);
}
}
@@ -0,0 +1,121 @@
package org.dna.mqtt.moquette.proto;
import org.dna.mqtt.moquette.proto.PublishEncoder;
import org.dna.mqtt.moquette.proto.messages.AbstractMessage.QOSType;
import org.dna.mqtt.moquette.proto.messages.PublishMessage;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
import static org.dna.mqtt.moquette.proto.TestUtils.*;
/**
*
* @author andrea
*/
public class PublishEncoderTest {
PublishEncoder m_encoder;
TestUtils.MockProtocolEncoderOutput m_mockProtoEncoder;
@Before
public void setUp() {
m_encoder = new PublishEncoder();
m_mockProtoEncoder = new TestUtils.MockProtocolEncoderOutput();
}
@Test
public void testEncodeWithQos_0_noMessageID() throws Exception {
String topic = "pictures/photos";
PublishMessage msg = new PublishMessage();
msg.setQos(QOSType.MOST_ONE);
msg.setTopicName(topic);
//variable part
byte[] payload = new byte[]{0x0A, 0x0B, 0x0C};
msg.setPayload(payload);
//Exercise
m_encoder.encode(null, msg, m_mockProtoEncoder);
//Verify
assertEquals(0x30, m_mockProtoEncoder.getBuffer().get()); //1 byte
assertEquals(24, m_mockProtoEncoder.getBuffer().get()); //remaining length
//Variable part
verifyString(topic, m_mockProtoEncoder.getBuffer());
verifyBuff(payload.length, payload, m_mockProtoEncoder.getBuffer());
}
@Test
public void testEncodeWithQos_1_MessageID() throws Exception {
String topic = "pictures/photos";
PublishMessage msg = new PublishMessage();
msg.setQos(QOSType.LEAST_ONE);
msg.setMessageID(1);
msg.setTopicName(topic);
//variable part
byte[] payload = new byte[]{0x0A, 0x0B, 0x0C};
msg.setPayload(payload);
//Exercise
m_encoder.encode(null, msg, m_mockProtoEncoder);
//Verify
assertEquals(0x32, m_mockProtoEncoder.getBuffer().get()); //1 byte
assertEquals(26, m_mockProtoEncoder.getBuffer().get()); //remaining length
//Variable part
verifyString(topic, m_mockProtoEncoder.getBuffer());
assertEquals(0, m_mockProtoEncoder.getBuffer().get()); //MessageID MSB
assertEquals(1, m_mockProtoEncoder.getBuffer().get()); //MessageID LSB
verifyBuff(payload.length, payload, m_mockProtoEncoder.getBuffer());
}
@Test(expected = IllegalArgumentException.class)
public void testEncodeWithQos_1_noMessageID_fail() throws Exception {
String topic = "pictures/photos";
PublishMessage msg = new PublishMessage();
msg.setQos(QOSType.LEAST_ONE);
msg.setTopicName(topic);
//Exercise
m_encoder.encode(null, msg, m_mockProtoEncoder);
}
@Test(expected = IllegalArgumentException.class)
public void testEncode_empty_topic() throws Exception {
PublishMessage msg = new PublishMessage();
msg.setQos(QOSType.LEAST_ONE);
msg.setMessageID(1);
//Exercise
m_encoder.encode(null, msg, m_mockProtoEncoder);
}
@Test(expected = IllegalArgumentException.class)
public void testEncode_null_topic() throws Exception {
PublishMessage msg = new PublishMessage();
msg.setQos(QOSType.LEAST_ONE);
msg.setMessageID(1);
msg.setTopicName(null);
//Exercise
m_encoder.encode(null, msg, m_mockProtoEncoder);
}
@Test(expected = IllegalArgumentException.class)
public void testEncode_qos_reserved() throws Exception {
PublishMessage msg = new PublishMessage();
msg.setQos(QOSType.RESERVED);
msg.setMessageID(1);
msg.setTopicName(null);
//variable part
byte[] payload = new byte[]{0x0A, 0x0B, 0x0C};
msg.setPayload(payload);
//Exercise
m_encoder.encode(null, msg, m_mockProtoEncoder);
}
}
@@ -0,0 +1,60 @@
package org.dna.mqtt.moquette.proto;
import org.dna.mqtt.moquette.proto.SubAckDecoder;
import org.dna.mqtt.moquette.proto.Utils;
import java.util.List;
import org.dna.mqtt.moquette.proto.messages.SubAckMessage;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.filter.codec.demux.MessageDecoderResult;
import org.dna.mqtt.moquette.proto.TestUtils.MockProtocolDecoderOutput;
import org.dna.mqtt.moquette.proto.messages.AbstractMessage;
import org.dna.mqtt.moquette.proto.messages.AbstractMessage.QOSType;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
/**
*
* @author andrea
*/
public class SubAckDecoderTest {
IoBuffer m_buff;
SubAckDecoder m_msgdec;
MockProtocolDecoderOutput<SubAckMessage> m_mockProtoDecoder;
@Before
public void setUp() {
m_buff = IoBuffer.allocate(7);
m_msgdec = new SubAckDecoder();
m_mockProtoDecoder = new MockProtocolDecoderOutput<SubAckMessage>();
}
@Test
public void testBadQos() throws Exception {
initHeaderQos(m_buff, 0xAABB, QOSType.LEAST_ONE, QOSType.MOST_ONE, QOSType.MOST_ONE);
m_buff.flip();
//Excercise
MessageDecoderResult res = m_msgdec.decode(null, m_buff, m_mockProtoDecoder);
//Verify
assertEquals(MessageDecoderResult.OK, res);
assertEquals(0xAABB, m_mockProtoDecoder.getMessage().getMessageID());
List<QOSType> qoses = m_mockProtoDecoder.getMessage().types();
assertEquals(3, qoses.size());
assertEquals(QOSType.LEAST_ONE, qoses.get(0));
assertEquals(QOSType.MOST_ONE, qoses.get(1));
assertEquals(QOSType.MOST_ONE, qoses.get(2));
}
private void initHeaderQos(IoBuffer buff, int messageID, QOSType... qoss) throws IllegalAccessException {
buff.clear().put((byte) (AbstractMessage.SUBSCRIBE << 4)).
put(Utils.encodeRemainingLength(3));
Utils.writeWord(buff, messageID);
for (QOSType qos : qoss) {
buff.put((byte)qos.ordinal());
}
}
}
@@ -0,0 +1,58 @@
package org.dna.mqtt.moquette.proto;
import org.dna.mqtt.moquette.proto.SubAckEncoder;
import org.dna.mqtt.moquette.proto.messages.AbstractMessage;
import org.dna.mqtt.moquette.proto.messages.AbstractMessage.QOSType;
import org.dna.mqtt.moquette.proto.messages.SubAckMessage;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
/**
*
* @author andrea
*/
public class SubAckEncoderTest {
SubAckEncoder m_encoder;
TestUtils.MockProtocolEncoderOutput m_mockProtoEncoder;
@Before
public void setUp() {
m_encoder = new SubAckEncoder();
m_mockProtoEncoder = new TestUtils.MockProtocolEncoderOutput();
}
@Test(expected = IllegalArgumentException.class)
public void testEncodeWithNoQoss() throws Exception {
SubAckMessage msg = new SubAckMessage();
msg.setMessageID(123);
//Exercise
m_encoder.encode(null, msg, m_mockProtoEncoder);
}
@Test
public void testEncodeWithMultipleQos() throws Exception {
SubAckMessage msg = new SubAckMessage();
int messageID = 0xAABB;
msg.setMessageID(messageID);
msg.addType(QOSType.MOST_ONE);
msg.addType(QOSType.LEAST_ONE);
msg.addType(QOSType.EXACTLY_ONCE);
//Exercise
m_encoder.encode(null, msg, m_mockProtoEncoder);
//Verify
assertEquals((byte) (AbstractMessage.SUBACK << 4 ), m_mockProtoEncoder.getBuffer().get()); //1 byte
assertEquals(5, m_mockProtoEncoder.getBuffer().get()); //remaining length
//Variable part
assertEquals((byte)0xAA, m_mockProtoEncoder.getBuffer().get()); //MessageID MSB
assertEquals((byte)0xBB, m_mockProtoEncoder.getBuffer().get()); //MessageID LSB
assertEquals((byte)QOSType.MOST_ONE.ordinal(), m_mockProtoEncoder.getBuffer().get());
assertEquals((byte)QOSType.LEAST_ONE.ordinal(), m_mockProtoEncoder.getBuffer().get());
assertEquals((byte)QOSType.EXACTLY_ONCE.ordinal(), m_mockProtoEncoder.getBuffer().get());
}
}
@@ -0,0 +1,79 @@
package org.dna.mqtt.moquette.proto;
import org.dna.mqtt.moquette.proto.SubscribeDecoder;
import org.dna.mqtt.moquette.proto.Utils;
import org.dna.mqtt.moquette.proto.messages.SubscribeMessage.Couple;
import org.dna.mqtt.moquette.proto.messages.SubscribeMessage;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.filter.codec.demux.MessageDecoderResult;
import org.dna.mqtt.moquette.proto.TestUtils.MockProtocolDecoderOutput;
import org.dna.mqtt.moquette.proto.messages.AbstractMessage;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
/**
*
* @author andrea
*/
public class SubscribeDecoderTest {
IoBuffer m_buff;
SubscribeDecoder m_msgdec;
MockProtocolDecoderOutput<SubscribeMessage> m_mockProtoDecoder;
@Before
public void setUp() {
m_buff = IoBuffer.allocate(4);
m_msgdec = new SubscribeDecoder();
m_mockProtoDecoder = new MockProtocolDecoderOutput<SubscribeMessage>();
}
@Test
public void testBadQos() throws Exception {
m_buff = IoBuffer.allocate(2);
initHeaderBadQos(m_buff);
m_buff.flip();
//Excercise
MessageDecoderResult res = m_msgdec.decode(null, m_buff, m_mockProtoDecoder);
//Verify
assertEquals(MessageDecoderResult.NOT_OK, res);
}
@Test
public void testMultiTopic() throws Exception {
m_buff = IoBuffer.allocate(4).setAutoExpand(true);
Couple c1 = new Couple((byte)2, "a/b");
Couple c2 = new Couple((byte)1, "c/d/e");
initMultiTopic(m_buff, 123, c1, c2);
m_buff.flip();
//Excercise
MessageDecoderResult res = m_msgdec.decode(null, m_buff, m_mockProtoDecoder);
//Verify
assertEquals(MessageDecoderResult.OK, res);
assertEquals(2, m_mockProtoDecoder.getMessage().subscriptions().size());
}
private void initHeaderBadQos(IoBuffer buff) {
buff.clear().put((byte)(AbstractMessage.SUBSCRIBE << 4)).put((byte)0);
}
private void initMultiTopic(IoBuffer buff, int messageID, Couple... topics) throws IllegalAccessException {
IoBuffer topicBuffer = IoBuffer.allocate(4).setAutoExpand(true);
Utils.writeWord(topicBuffer, messageID);
for (Couple couple : topics) {
topicBuffer.put(Utils.encodeString(couple.getTopic()));
topicBuffer.put((byte)couple.getQos());
}
topicBuffer.flip();
buff.clear().put((byte)(AbstractMessage.SUBSCRIBE << 4 | (byte)0x02))
.put(Utils.encodeRemainingLength(topicBuffer.remaining()));
buff.put(topicBuffer);
}
}
@@ -0,0 +1,70 @@
package org.dna.mqtt.moquette.proto;
import org.dna.mqtt.moquette.proto.UnsubscribeEncoder;
import org.dna.mqtt.moquette.proto.messages.UnsubscribeMessage;
import org.dna.mqtt.moquette.proto.messages.AbstractMessage.QOSType;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
import static org.dna.mqtt.moquette.proto.TestUtils.*;
/**
*
* @author andrea
*/
public class SubscribeEncoderTest {
UnsubscribeMessage m_msg;
UnsubscribeEncoder m_encoder;
TestUtils.MockProtocolEncoderOutput m_mockProtoEncoder;
@Before
public void setUp() {
m_encoder = new UnsubscribeEncoder();
m_mockProtoEncoder = new TestUtils.MockProtocolEncoderOutput();
m_msg = new UnsubscribeMessage();
m_msg.setMessageID(0xAABB);
}
@Test
public void testEncodeWithMultiTopic() throws Exception {
m_msg.setQos(QOSType.LEAST_ONE);
//variable part
String topic1 = "a/b";
String topic2 = "a/b/c";
m_msg.addTopic(topic1);
m_msg.addTopic(topic2);
//Exercise
m_encoder.encode(null, m_msg, m_mockProtoEncoder);
//Verify
assertEquals((byte)0xA2, (byte)m_mockProtoEncoder.getBuffer().get()); //1 byte
assertEquals(18, m_mockProtoEncoder.getBuffer().get()); //remaining length
//verify M1ssageID
assertEquals((byte)0xAA, m_mockProtoEncoder.getBuffer().get());
assertEquals((byte)0xBB, m_mockProtoEncoder.getBuffer().get());
//Variable part
verifyString(topic1, m_mockProtoEncoder.getBuffer());
verifyString(topic2, m_mockProtoEncoder.getBuffer());
}
@Test(expected = IllegalArgumentException.class)
public void testEncode_empty_topics() throws Exception {
m_msg.setQos(QOSType.LEAST_ONE);
//Exercise
m_encoder.encode(null, m_msg, m_mockProtoEncoder);
}
@Test(expected = IllegalArgumentException.class)
public void testEncode_badQos() throws Exception {
m_msg.setQos(QOSType.EXACTLY_ONCE);
//Exercise
m_encoder.encode(null, m_msg, m_mockProtoEncoder);
}
}
@@ -0,0 +1,98 @@
package org.dna.mqtt.moquette.proto;
import org.dna.mqtt.moquette.proto.Utils;
import org.dna.mqtt.moquette.proto.messages.AbstractMessage;
import java.io.UnsupportedEncodingException;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.filterchain.IoFilter.NextFilter;
import org.apache.mina.core.future.WriteFuture;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;
import org.apache.mina.filter.codec.ProtocolEncoderOutput;
import static org.junit.Assert.*;
/**
*
* @author andrea
*/
public class TestUtils {
static final class MockProtocolDecoderOutput<T extends AbstractMessage> implements ProtocolDecoderOutput {
protected T m_connMessage;
public T getMessage() {
return m_connMessage;
}
public void write(Object message) {
m_connMessage = (T) message;
}
public void flush(NextFilter nextFilter, IoSession session) {
throw new UnsupportedOperationException("Not supported yet.");
}
}
static final class MockProtocolEncoderOutput implements ProtocolEncoderOutput {
protected IoBuffer m_buffer;
public IoBuffer getBuffer() {
return m_buffer;
}
public void write(Object buffer) {
m_buffer = (IoBuffer) buffer;
}
public void mergeAll() {
throw new UnsupportedOperationException("Not supported yet.");
}
public WriteFuture flush() {
throw new UnsupportedOperationException("Not supported yet.");
}
}
/**
* Verify the presence of the given string starting from the current position
* inside the buffer.
*/
static void verifyString(String str, IoBuffer buff) throws UnsupportedEncodingException {
IoBuffer tmpBuff = IoBuffer.allocate(2).setAutoExpand(true);
byte[] raw = str.getBytes("UTF-8");
Utils.writeWord(tmpBuff, raw.length);
tmpBuff.put(raw).flip();
verifyIoBuffer(tmpBuff, buff);
}
static void verifyIoBuffer(IoBuffer expected, IoBuffer found) {
while(expected.hasRemaining()) {
assertEquals(expected.get(), found.get());
}
}
/**
* Verify that the given bytes buffer og the given numBytes length is present
* in the buff starting from the current position.
*/
static void verifyBuff(int numBytes, byte[] bytes, IoBuffer buff) {
assertTrue(numBytes <= buff.remaining());
byte[] toCheck = new byte[numBytes];
buff.get(toCheck);
for (int i = 0; i < numBytes; i++) {
assertEquals(bytes[i], toCheck[i]);
}
}
static void verifyEquals(byte[] expected, byte[] found) {
assertEquals(expected.length, found.length);
for (int i = 0; i < expected.length; i++) {
assertEquals(expected[i], found[i]);
}
}
}
@@ -0,0 +1,79 @@
package org.dna.mqtt.moquette.proto;
import org.dna.mqtt.moquette.proto.Utils;
import org.dna.mqtt.moquette.proto.UnsubscribeDecoder;
import org.dna.mqtt.moquette.proto.messages.UnsubscribeMessage;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.filter.codec.demux.MessageDecoderResult;
import org.dna.mqtt.moquette.proto.TestUtils.MockProtocolDecoderOutput;
import org.dna.mqtt.moquette.proto.messages.AbstractMessage;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
/**
*
* @author andrea
*/
public class UnsubscribeDecoderTest {
IoBuffer m_buff;
UnsubscribeDecoder m_msgdec;
MockProtocolDecoderOutput<UnsubscribeMessage> m_mockProtoDecoder;
@Before
public void setUp() {
m_buff = IoBuffer.allocate(4);
m_msgdec = new UnsubscribeDecoder();
m_mockProtoDecoder = new MockProtocolDecoderOutput<UnsubscribeMessage>();
}
@Test
public void testBadQos() throws Exception {
m_buff = IoBuffer.allocate(2);
initHeaderBadQos(m_buff);
m_buff.flip();
//Excercise
MessageDecoderResult res = m_msgdec.decode(null, m_buff, m_mockProtoDecoder);
//Verify
assertEquals(MessageDecoderResult.NOT_OK, res);
}
@Test
public void testMultiTopic() throws Exception {
m_buff = IoBuffer.allocate(4).setAutoExpand(true);
String topic1 = "a/b";
String topic2 = "c/d/e";
initMultiTopic(m_buff, 123, topic1, topic2);
m_buff.flip();
//Excercise
MessageDecoderResult res = m_msgdec.decode(null, m_buff, m_mockProtoDecoder);
//Verify
assertEquals(MessageDecoderResult.OK, res);
assertEquals(2, m_mockProtoDecoder.getMessage().topics().size());
assertEquals(topic1, m_mockProtoDecoder.getMessage().topics().get(0));
assertEquals(topic2, m_mockProtoDecoder.getMessage().topics().get(1));
}
private void initHeaderBadQos(IoBuffer buff) {
buff.clear().put((byte)(AbstractMessage.UNSUBSCRIBE << 4)).put((byte)0);
}
private void initMultiTopic(IoBuffer buff, int messageID, String... topics) throws IllegalAccessException {
IoBuffer topicBuffer = IoBuffer.allocate(4).setAutoExpand(true);
Utils.writeWord(topicBuffer, messageID);
for (String topic : topics) {
topicBuffer.put(Utils.encodeString(topic));
}
topicBuffer.flip();
buff.clear().put((byte)(AbstractMessage.SUBSCRIBE << 4 | (byte)0x02))
.put(Utils.encodeRemainingLength(topicBuffer.remaining()));
buff.put(topicBuffer);
}
}
@@ -0,0 +1,77 @@
package org.dna.mqtt.moquette.proto;
import org.dna.mqtt.moquette.proto.SubscribeEncoder;
import org.dna.mqtt.moquette.proto.messages.SubscribeMessage.Couple;
import org.dna.mqtt.moquette.proto.messages.SubscribeMessage;
import org.dna.mqtt.moquette.proto.messages.AbstractMessage.QOSType;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
import static org.dna.mqtt.moquette.proto.TestUtils.*;
/**
*
* @author andrea
*/
public class UnsubscribeEncoderTest {
SubscribeEncoder m_encoder;
TestUtils.MockProtocolEncoderOutput m_mockProtoEncoder;
@Before
public void setUp() {
m_encoder = new SubscribeEncoder();
m_mockProtoEncoder = new TestUtils.MockProtocolEncoderOutput();
}
@Test
public void testEncodeWithMultiTopic() throws Exception {
SubscribeMessage msg = new SubscribeMessage();
msg.setQos(QOSType.LEAST_ONE);
msg.setMessageID(0xAABB);
//variable part
Couple c1 = new Couple((byte)1, "a/b");
Couple c2 = new Couple((byte)0, "a/b/c");
msg.addSubscription(c1);
msg.addSubscription(c2);
//Exercise
m_encoder.encode(null, msg, m_mockProtoEncoder);
//Verify
assertEquals((byte)0x82, (byte)m_mockProtoEncoder.getBuffer().get()); //1 byte
assertEquals(20, m_mockProtoEncoder.getBuffer().get()); //remaining length
//verify M1ssageID
assertEquals((byte)0xAA, m_mockProtoEncoder.getBuffer().get());
assertEquals((byte)0xBB, m_mockProtoEncoder.getBuffer().get());
//Variable part
verifyString(c1.getTopic(), m_mockProtoEncoder.getBuffer());
assertEquals(c1.getQos(), m_mockProtoEncoder.getBuffer().get());
verifyString(c2.getTopic(), m_mockProtoEncoder.getBuffer());
assertEquals(c2.getQos(), m_mockProtoEncoder.getBuffer().get());
}
@Test(expected = IllegalArgumentException.class)
public void testEncode_empty_subscription() throws Exception {
SubscribeMessage msg = new SubscribeMessage();
msg.setQos(QOSType.LEAST_ONE);
msg.setMessageID(0xAABB);
//Exercise
m_encoder.encode(null, msg, m_mockProtoEncoder);
}
@Test(expected = IllegalArgumentException.class)
public void testEncode_badQos() throws Exception {
SubscribeMessage msg = new SubscribeMessage();
msg.setQos(QOSType.EXACTLY_ONCE);
msg.setMessageID(0xAABB);
//Exercise
m_encoder.encode(null, msg, m_mockProtoEncoder);
}
}
@@ -0,0 +1,87 @@
package org.dna.mqtt.moquette.server;
import org.apache.mina.core.write.WriteRequest;
import org.dna.mqtt.moquette.proto.messages.ConnAckMessage;
import org.apache.mina.core.filterchain.IoFilterAdapter;
import org.apache.mina.core.session.DummySession;
import org.apache.mina.core.session.IoSession;
import org.dna.mqtt.moquette.messaging.spi.IMessaging;
import org.dna.mqtt.moquette.proto.messages.ConnectMessage;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
/**
*
* @author andrea
*/
public class MQTTHandlerTest {
byte m_returnCode;
IoSession m_session;
MQTTHandler m_handler;
ConnectMessage connMsg;
@Before
public void setUp() {
m_handler = new MQTTHandler();
connMsg = new ConnectMessage();
connMsg.setProcotolVersion((byte) 0x03);
m_session = new DummySession();
m_session.getFilterChain().addFirst("MessageCatcher", new IoFilterAdapter() {
@Override
public void filterWrite(NextFilter nextFilter, IoSession session,
WriteRequest writeRequest) throws Exception {
try {
ConnAckMessage buf = (ConnAckMessage) writeRequest.getMessage();
m_returnCode = buf.getReturnCode();
} catch (Exception ex) {
throw new AssertionError("Wrong return code");
}
}
});
}
@Test
public void testHandleConnect_BadProtocol() {
connMsg.setProcotolVersion((byte) 0x02);
//Exercise
m_handler.handleConnect(m_session, connMsg);
//Verify
assertEquals(ConnAckMessage.UNNACEPTABLE_PROTOCOL_VERSION, m_returnCode);
}
@Test
public void testConnect_badClientID() {
connMsg.setClientID("extremely_long_clientID_greater_than_23");
//Exercise
m_handler.handleConnect(m_session, connMsg);
//Verify
assertEquals(ConnAckMessage.IDENTIFIER_REJECTED, m_returnCode);
}
@Test
public void testWill() {
connMsg.setClientID("123");
connMsg.setWillFlag(true);
connMsg.setWillTopic("topic");
connMsg.setWillMessage("Topic message");
IMessaging mockedMessaging = mock(IMessaging.class);
//Exercise
m_handler.setMessaging(mockedMessaging);
m_handler.handleConnect(m_session, connMsg);
//Verify
assertEquals(ConnAckMessage.CONNECTION_ACCEPTED, m_returnCode);
verify(mockedMessaging).publish(eq("topic"), eq("Topic message"), anyByte(), anyBoolean());
}
}