Unit tests for open flow message encode and decode

Change-Id: Id0d6975b760943d3fc2ad97d176fc538eab2c5bf
diff --git a/openflow/ctl/src/test/java/org/onosproject/openflow/ChannelAdapter.java b/openflow/ctl/src/test/java/org/onosproject/openflow/ChannelAdapter.java
new file mode 100644
index 0000000..75260a1
--- /dev/null
+++ b/openflow/ctl/src/test/java/org/onosproject/openflow/ChannelAdapter.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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.onosproject.openflow;
+
+import java.net.SocketAddress;
+
+import org.jboss.netty.channel.Channel;
+import org.jboss.netty.channel.ChannelConfig;
+import org.jboss.netty.channel.ChannelFactory;
+import org.jboss.netty.channel.ChannelFuture;
+import org.jboss.netty.channel.ChannelPipeline;
+
+/**
+ * Adapter for testing against a netty channel.
+ */
+public class ChannelAdapter implements Channel {
+    @Override
+    public Integer getId() {
+        return null;
+    }
+
+    @Override
+    public ChannelFactory getFactory() {
+        return null;
+    }
+
+    @Override
+    public Channel getParent() {
+        return null;
+    }
+
+    @Override
+    public ChannelConfig getConfig() {
+        return null;
+    }
+
+    @Override
+    public ChannelPipeline getPipeline() {
+        return null;
+    }
+
+    @Override
+    public boolean isOpen() {
+        return false;
+    }
+
+    @Override
+    public boolean isBound() {
+        return false;
+    }
+
+    @Override
+    public boolean isConnected() {
+        return false;
+    }
+
+    @Override
+    public SocketAddress getLocalAddress() {
+        return null;
+    }
+
+    @Override
+    public SocketAddress getRemoteAddress() {
+        return null;
+    }
+
+    @Override
+    public ChannelFuture write(Object o) {
+        return null;
+    }
+
+    @Override
+    public ChannelFuture write(Object o, SocketAddress socketAddress) {
+        return null;
+    }
+
+    @Override
+    public ChannelFuture bind(SocketAddress socketAddress) {
+        return null;
+    }
+
+    @Override
+    public ChannelFuture connect(SocketAddress socketAddress) {
+        return null;
+    }
+
+    @Override
+    public ChannelFuture disconnect() {
+        return null;
+    }
+
+    @Override
+    public ChannelFuture unbind() {
+        return null;
+    }
+
+    @Override
+    public ChannelFuture close() {
+        return null;
+    }
+
+    @Override
+    public ChannelFuture getCloseFuture() {
+        return null;
+    }
+
+    @Override
+    public int getInterestOps() {
+        return 0;
+    }
+
+    @Override
+    public boolean isReadable() {
+        return false;
+    }
+
+    @Override
+    public boolean isWritable() {
+        return false;
+    }
+
+    @Override
+    public ChannelFuture setInterestOps(int i) {
+        return null;
+    }
+
+    @Override
+    public ChannelFuture setReadable(boolean b) {
+        return null;
+    }
+
+    @Override
+    public Object getAttachment() {
+        return null;
+    }
+
+    @Override
+    public void setAttachment(Object o) {
+
+    }
+
+    @Override
+    public int compareTo(Channel o) {
+        return 0;
+    }
+}
diff --git a/openflow/ctl/src/test/java/org/onosproject/openflow/ChannelHandlerContextAdapter.java b/openflow/ctl/src/test/java/org/onosproject/openflow/ChannelHandlerContextAdapter.java
new file mode 100644
index 0000000..5b6c2a3
--- /dev/null
+++ b/openflow/ctl/src/test/java/org/onosproject/openflow/ChannelHandlerContextAdapter.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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.onosproject.openflow;
+
+import org.jboss.netty.channel.Channel;
+import org.jboss.netty.channel.ChannelEvent;
+import org.jboss.netty.channel.ChannelHandler;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.channel.ChannelPipeline;
+
+/**
+ * Adapter for testing against a netty channel handler context.
+ */
+public class ChannelHandlerContextAdapter implements ChannelHandlerContext {
+    @Override
+    public Channel getChannel() {
+        return null;
+    }
+
+    @Override
+    public ChannelPipeline getPipeline() {
+        return null;
+    }
+
+    @Override
+    public String getName() {
+        return null;
+    }
+
+    @Override
+    public ChannelHandler getHandler() {
+        return null;
+    }
+
+    @Override
+    public boolean canHandleUpstream() {
+        return false;
+    }
+
+    @Override
+    public boolean canHandleDownstream() {
+        return false;
+    }
+
+    @Override
+    public void sendUpstream(ChannelEvent channelEvent) {
+
+    }
+
+    @Override
+    public void sendDownstream(ChannelEvent channelEvent) {
+
+    }
+
+    @Override
+    public Object getAttachment() {
+        return null;
+    }
+
+    @Override
+    public void setAttachment(Object o) {
+
+    }
+}
diff --git a/openflow/ctl/src/test/java/org/onosproject/openflow/OfMessageAdapter.java b/openflow/ctl/src/test/java/org/onosproject/openflow/OfMessageAdapter.java
new file mode 100644
index 0000000..e9b38e3
--- /dev/null
+++ b/openflow/ctl/src/test/java/org/onosproject/openflow/OfMessageAdapter.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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.onosproject.openflow;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.projectfloodlight.openflow.protocol.OFMessage;
+import org.projectfloodlight.openflow.protocol.OFType;
+import org.projectfloodlight.openflow.protocol.OFVersion;
+
+import com.google.common.hash.PrimitiveSink;
+
+/**
+ * Adapter for testing against an OpenFlow message.
+ */
+public class OfMessageAdapter implements OFMessage {
+    @Override
+    public OFVersion getVersion() {
+        return null;
+    }
+
+    @Override
+    public OFType getType() {
+        return null;
+    }
+
+    @Override
+    public long getXid() {
+        return 0;
+    }
+
+    @Override
+    public void writeTo(ChannelBuffer channelBuffer) { }
+
+    @Override
+    public Builder createBuilder() {
+        return null;
+    }
+
+    @Override
+    public void putTo(PrimitiveSink sink) { }
+}
diff --git a/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/OFMessageDecoderTest.java b/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/OFMessageDecoderTest.java
new file mode 100644
index 0000000..ed1db23
--- /dev/null
+++ b/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/OFMessageDecoderTest.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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.onosproject.openflow.controller.impl;
+
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.buffer.ChannelBuffers;
+import org.junit.Test;
+import org.onosproject.openflow.ChannelAdapter;
+import org.onosproject.openflow.ChannelHandlerContextAdapter;
+import org.projectfloodlight.openflow.protocol.OFHello;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.instanceOf;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.hamcrest.Matchers.nullValue;
+
+/**
+ * Tests for the OpenFlow message decoder.
+ */
+public class OFMessageDecoderTest {
+
+    static class ConnectedChannel extends ChannelAdapter {
+        @Override
+        public boolean isConnected() {
+            return true;
+        }
+    }
+
+    private ChannelBuffer getHelloMessageBuffer() {
+        // OFHello, OF version 1, xid of 0, total of 8 bytes
+        byte[] messageData = {0x1, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x0};
+        ChannelBuffer channelBuffer = ChannelBuffers.dynamicBuffer();
+        channelBuffer.writeBytes(messageData);
+        return channelBuffer;
+    }
+
+    /**
+     * Tests decoding a message on a closed channel.
+     *
+     * @throws Exception when an exception is thrown from the decoder
+     */
+    @Test
+    public void testDecodeNoChannel() throws Exception {
+        OFMessageDecoder decoder = new OFMessageDecoder();
+        ChannelBuffer channelBuffer = getHelloMessageBuffer();
+        Object message =
+                decoder.decode(new ChannelHandlerContextAdapter(),
+                               new ChannelAdapter(),
+                               channelBuffer);
+        assertThat(message, nullValue());
+    }
+
+    /**
+     * Tests decoding a message.
+     *
+     * @throws Exception when an exception is thrown from the decoder
+     */
+    @Test
+    public void testDecode() throws Exception {
+        OFMessageDecoder decoder = new OFMessageDecoder();
+        ChannelBuffer channelBuffer = getHelloMessageBuffer();
+        Object message =
+                decoder.decode(new ChannelHandlerContextAdapter(),
+                               new ConnectedChannel(),
+                               channelBuffer);
+        assertThat(message, notNullValue());
+        assertThat(message, instanceOf(OFHello.class));
+    }
+
+}
diff --git a/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/OFMessageEncoderTest.java b/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/OFMessageEncoderTest.java
new file mode 100644
index 0000000..59685f1
--- /dev/null
+++ b/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/OFMessageEncoderTest.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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.onosproject.openflow.controller.impl;
+
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.junit.Test;
+import org.onosproject.openflow.OfMessageAdapter;
+import org.projectfloodlight.openflow.protocol.OFMessage;
+
+import com.google.common.collect.ImmutableList;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+
+/**
+ * Tests for the OpenFlow message encoder.
+ */
+public class OFMessageEncoderTest {
+
+    static class MockOfMessage extends OfMessageAdapter {
+        static int nextId = 1;
+        final int id;
+
+        MockOfMessage() {
+            id = nextId++;
+        }
+
+        @Override
+        public void writeTo(ChannelBuffer channelBuffer) {
+            String message = "message" + Integer.toString(id) + " ";
+            channelBuffer.writeBytes(message.getBytes(StandardCharsets.UTF_8));
+        }
+    }
+
+    /**
+     * Tests that encoding a non-list returns the object specified.
+     *
+     * @throws Exception on exception in the encoder
+     */
+    @Test
+    public void testNoList() throws Exception {
+        OFMessageEncoder encoder = new OFMessageEncoder();
+        MockOfMessage message = new MockOfMessage();
+        OFMessage returnedMessage =
+                (OFMessage) encoder.encode(null, null, message);
+        assertThat(message, is(returnedMessage));
+    }
+
+    /**
+     * Tests that encoding a list returns the proper encoded payload.
+     *
+     * @throws Exception on exception in the encoder
+     */
+    @Test
+    public void testList() throws Exception {
+        OFMessageEncoder encoder = new OFMessageEncoder();
+        MockOfMessage message1 = new MockOfMessage();
+        MockOfMessage message2 = new MockOfMessage();
+        MockOfMessage message3 = new MockOfMessage();
+        List<MockOfMessage> messages = ImmutableList.of(message1, message2, message3);
+        ChannelBuffer returnedChannel =
+                (ChannelBuffer) encoder.encode(null, null, messages);
+        assertThat(returnedChannel, notNullValue());
+        byte[] channelBytes = returnedChannel.array();
+        String expectedListMessage = "message1 message2 message3 ";
+        String listMessage =
+                (new String(channelBytes, StandardCharsets.UTF_8))
+                        .substring(0, expectedListMessage.length());
+        assertThat(listMessage, is(expectedListMessage));
+    }
+}
diff --git a/openflow/pom.xml b/openflow/pom.xml
index 437f743..91fe2f6 100644
--- a/openflow/pom.xml
+++ b/openflow/pom.xml
@@ -45,6 +45,24 @@
             <groupId>org.onosproject</groupId>
             <artifactId>onlab-junit</artifactId>
         </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.11</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>hamcrest-core</artifactId>
+            <version>1.3</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>hamcrest-library</artifactId>
+            <version>1.3</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <build>