From 112fcc41ad8c408faa26cbccf3b75aaf82496bf8 Mon Sep 17 00:00:00 2001 From: Michal Polkorab Date: Tue, 26 Aug 2014 10:55:25 +0200 Subject: [PATCH] Improved unit test coverage (covered some untested branches) - Fixed a typo in EncodeConstants javadoc - added access to Cache in ConnectionAdapterImpl (only for testing purposes) - removed check from SerializationFactory#messageToBuffer as it is done in SerializerRegistryImpl Change-Id: I2e752a883a296f6e097084243aca0b109dd62c27 Signed-off-by: Michal Polkorab --- .../protocol/api/util/EncodeConstants.java | 2 +- .../connection/ConnectionAdapterImpl.java | 13 +- .../serialization/SerializationFactory.java | 4 +- .../connection/ConnectionAdapterImplTest.java | 177 ++++++++++++++++++ .../connection/SimpleRpcListenerTest.java | 50 +++++ .../match/OxmIpv6ExtHdrDeserializerTest.java | 49 +++++ .../match/OxmIpv6FlabelDeserializerTest.java | 44 +++++ .../match/OxmMetadataDeserializerTest.java | 45 +++++ .../match/OxmMplsBosDeserializerTest.java | 43 +++++ .../match/OxmPbbIsidDeserializerTest.java | 43 +++++ .../match/OxmVlanVidDeserializerTest.java | 46 +++++ .../impl/util/ActionsDeserializerTest.java | 21 +++ .../impl/util/MatchDeserializerTest.java | 24 ++- .../impl/util/OF13ActionsSerializerTest.java | 43 ++++- .../impl/util/OF13MatchSerializerTest.java | 11 +- 15 files changed, 603 insertions(+), 12 deletions(-) create mode 100644 openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/connection/ConnectionAdapterImplTest.java create mode 100644 openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6ExtHdrDeserializerTest.java create mode 100644 openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6FlabelDeserializerTest.java create mode 100644 openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmMetadataDeserializerTest.java create mode 100644 openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmMplsBosDeserializerTest.java create mode 100644 openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmPbbIsidDeserializerTest.java create mode 100644 openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmVlanVidDeserializerTest.java diff --git a/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/util/EncodeConstants.java b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/util/EncodeConstants.java index b3f6dff5..bbd881e2 100644 --- a/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/util/EncodeConstants.java +++ b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/util/EncodeConstants.java @@ -18,7 +18,7 @@ public abstract class EncodeConstants { public static final byte PADDING = 8; /** OpenFlow v1.0 wire protocol number */ public static final byte OF10_VERSION_ID = 0x01; - /** OpenFlow v1.0 wire protocol number */ + /** OpenFlow v1.3 wire protocol number */ public static final byte OF13_VERSION_ID = 0x04; /** Index of length in Openflow header */ public static final int OFHEADER_LENGTH_INDEX = 2; diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/connection/ConnectionAdapterImpl.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/connection/ConnectionAdapterImpl.java index 9fe040fc..19baa930 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/connection/ConnectionAdapterImpl.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/connection/ConnectionAdapterImpl.java @@ -108,7 +108,7 @@ public class ConnectionAdapterImpl implements ConnectionFacade { }; /** expiring cache for future rpcResponses */ - private final Cache> responseCache; + private Cache> responseCache; private final ChannelOutboundQueue output; private final Channel channel; @@ -465,7 +465,6 @@ public class ConnectionAdapterImpl implements ConnectionFacade { }).start(); } - @Override public void setConnectionReadyListener( final ConnectionReadyListener connectionReadyListener) { @@ -476,4 +475,12 @@ public class ConnectionAdapterImpl implements ConnectionFacade { public InetSocketAddress getRemoteAddress() { return (InetSocketAddress) channel.remoteAddress(); } -} + + /** + * Used only for testing purposes + * @param cache + */ + public void setResponseCache(Cache> cache) { + this.responseCache = cache; + } +} \ No newline at end of file diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/SerializationFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/SerializationFactory.java index 34f4fb19..e318c683 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/SerializationFactory.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/SerializationFactory.java @@ -32,9 +32,7 @@ public class SerializationFactory { public void messageToBuffer(short version, ByteBuf out, DataObject message) { OFSerializer serializer = registry.getSerializer( new MessageTypeKey<>(version, message.getImplementedInterface())); - if (serializer != null) { - serializer.serialize(message, out); - } + serializer.serialize(message, out); } /** diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/connection/ConnectionAdapterImplTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/connection/ConnectionAdapterImplTest.java new file mode 100644 index 00000000..0435b3b9 --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/connection/ConnectionAdapterImplTest.java @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2014 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowjava.protocol.impl.connection; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import io.netty.channel.ChannelPipeline; +import io.netty.channel.socket.SocketChannel; + +import java.net.InetSocketAddress; +import java.util.concurrent.TimeUnit; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.opendaylight.openflowjava.protocol.api.connection.ConnectionReadyListener; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoRequestMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoRequestMessageBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessageBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterMessageBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessageBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloMessageBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessageBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OpenflowProtocolListener; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessageBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessageBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.DisconnectEvent; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.DisconnectEventBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.SwitchIdleEvent; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.SwitchIdleEventBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.SystemNotificationsListener; +import org.opendaylight.yangtools.yang.binding.DataObject; + +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.RemovalListener; +import com.google.common.cache.RemovalNotification; + +/** + * @author michal.polkorab + * + */ +public class ConnectionAdapterImplTest { + + private static final int RPC_RESPONSE_EXPIRATION = 1; + private static final RemovalListener> REMOVAL_LISTENER = + new RemovalListener>() { + @Override + public void onRemoval( + final RemovalNotification> notification) { + notification.getValue().discard(); + } + }; + + @Mock SocketChannel channel; + @Mock ChannelPipeline pipeline; + @Mock OpenflowProtocolListener messageListener; + @Mock SystemNotificationsListener systemListener; + @Mock ConnectionReadyListener readyListener; + @Mock Cache> mockCache; + + private ConnectionAdapterImpl adapter; + private Cache> cache; + + /** + * Initializes ConnectionAdapter + */ + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + when(channel.pipeline()).thenReturn(pipeline); + adapter = new ConnectionAdapterImpl(channel, InetSocketAddress.createUnresolved("10.0.0.1", 6653)); + adapter.setMessageListener(messageListener); + adapter.setSystemListener(systemListener); + adapter.setConnectionReadyListener(readyListener); + cache = CacheBuilder.newBuilder().concurrencyLevel(1).expireAfterWrite(RPC_RESPONSE_EXPIRATION, TimeUnit.MINUTES) + .removalListener(REMOVAL_LISTENER).build(); + adapter.setResponseCache(cache); + } + + /** + * Tests {@link ConnectionAdapterImpl#consume(DataObject)} with notifications + */ + @Test + public void testConsume() { + DataObject message = new EchoRequestMessageBuilder().build(); + adapter.consume(message); + verify(messageListener, times(1)).onEchoRequestMessage((EchoRequestMessage) message); + message = new ErrorMessageBuilder().build(); + adapter.consume(message); + verify(messageListener, times(1)).onErrorMessage((ErrorMessage) message); + message = new ExperimenterMessageBuilder().build(); + adapter.consume(message); + verify(messageListener, times(1)).onExperimenterMessage((ExperimenterMessage) message); + message = new FlowRemovedMessageBuilder().build(); + adapter.consume(message); + verify(messageListener, times(1)).onFlowRemovedMessage((FlowRemovedMessage) message); + message = new HelloMessageBuilder().build(); + adapter.consume(message); + verify(messageListener, times(1)).onHelloMessage((HelloMessage) message); + message = new MultipartReplyMessageBuilder().build(); + adapter.consume(message); + verify(messageListener, times(1)).onMultipartReplyMessage((MultipartReplyMessage) message); + message = new PacketInMessageBuilder().build(); + adapter.consume(message); + verify(messageListener, times(1)).onPacketInMessage((PacketInMessage) message); + message = new PortStatusMessageBuilder().build(); + adapter.consume(message); + verify(messageListener, times(1)).onPortStatusMessage((PortStatusMessage) message); + message = new SwitchIdleEventBuilder().build(); + adapter.consume(message); + verify(systemListener, times(1)).onSwitchIdleEvent((SwitchIdleEvent) message); + message = new DisconnectEventBuilder().build(); + adapter.consume(message); + verify(systemListener, times(1)).onDisconnectEvent((DisconnectEvent) message); + message = new EchoRequestMessageBuilder().build(); + adapter.consume(message); + verify(messageListener, times(1)).onEchoRequestMessage((EchoRequestMessage) message); + } + + /** + * Tests {@link ConnectionAdapterImpl#consume(DataObject)} with unexpected rpc + */ + @Test + public void testConsume2() { + adapter.setResponseCache(mockCache); + BarrierOutputBuilder barrierBuilder = new BarrierOutputBuilder(); + barrierBuilder.setXid(42L); + BarrierOutput barrier = barrierBuilder.build(); + adapter.consume(barrier); + verify(mockCache, times(1)).getIfPresent(any(RpcResponseKey.class)); + } + + /** + * Tests {@link ConnectionAdapterImpl#consume(DataObject)} with expected rpc + */ + @Test + public void testConsume3() { + BarrierInputBuilder inputBuilder = new BarrierInputBuilder(); + inputBuilder.setVersion((short) EncodeConstants.OF13_VERSION_ID); + inputBuilder.setXid(42L); + BarrierInput barrierInput = inputBuilder.build(); + RpcResponseKey key = new RpcResponseKey(42L, "org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierOutput"); + ResponseExpectedRpcListener listener = new ResponseExpectedRpcListener<>(barrierInput, + "failure", mockCache, key); + cache.put(key, listener); + BarrierOutputBuilder barrierBuilder = new BarrierOutputBuilder(); + barrierBuilder.setXid(42L); + BarrierOutput barrierOutput = barrierBuilder.build(); + adapter.consume(barrierOutput); + ResponseExpectedRpcListener ifPresent = cache.getIfPresent(key); + Assert.assertNull("Listener was not discarded", ifPresent); + } +} \ No newline at end of file diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/connection/SimpleRpcListenerTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/connection/SimpleRpcListenerTest.java index db9d689e..3f49196e 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/connection/SimpleRpcListenerTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/connection/SimpleRpcListenerTest.java @@ -9,12 +9,19 @@ package org.opendaylight.openflowjava.protocol.impl.connection; import static org.junit.Assert.fail; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import io.netty.util.concurrent.Future; import java.util.Collections; import java.util.concurrent.ExecutionException; import org.junit.Assert; +import org.junit.Before; import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; import org.opendaylight.controller.sal.common.util.Rpcs; import org.opendaylight.yangtools.yang.common.RpcError; import org.opendaylight.yangtools.yang.common.RpcResult; @@ -27,6 +34,16 @@ import com.google.common.util.concurrent.SettableFuture; */ public class SimpleRpcListenerTest { + @Mock Future future; + + /** + * Initializes mocks + */ + @Before + public void startUp() { + MockitoAnnotations.initMocks(this); + } + /** * Test SimpleRpcListener creation */ @@ -54,4 +71,37 @@ public class SimpleRpcListenerTest { fail("Problem accessing result"); } } + + /** + * Test rpc success + */ + @Test + public void testOperationComplete() { + when(future.isSuccess()).thenReturn(false); + SimpleRpcListener listener = new SimpleRpcListener("MESSAGE", "Failed to send message"); + listener.operationComplete(future); + verify(future, times(1)).cause(); + try { + Assert.assertEquals("Wrong result", 1, listener.getResult().get().getErrors().size()); + } catch (InterruptedException | ExecutionException e) { + Assert.fail(); + } + } + + /** + * Test rpc success + */ + @Test + public void testOperationComplete2() { + when(future.isSuccess()).thenReturn(true); + SimpleRpcListener listener = new SimpleRpcListener("MESSAGE", "Failed to send message"); + listener.operationComplete(future); + verify(future, times(0)).cause(); + try { + Assert.assertEquals("Wrong result", 0, listener.getResult().get().getErrors().size()); + Assert.assertEquals("Wrong result", true, listener.getResult().get().isSuccessful()); + } catch (InterruptedException | ExecutionException e) { + Assert.fail(); + } + } } \ No newline at end of file diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6ExtHdrDeserializerTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6ExtHdrDeserializerTest.java new file mode 100644 index 00000000..49b11872 --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6ExtHdrDeserializerTest.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2014 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowjava.protocol.impl.deserialization.match; + +import io.netty.buffer.ByteBuf; + +import org.junit.Assert; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MaskMatchEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PseudoFieldMatchEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.Ipv6ExthdrFlags; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Ipv6Exthdr; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.OpenflowBasicClass; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.grouping.MatchEntries; + +/** + * @author michal.polkorab + * + */ +public class OxmIpv6ExtHdrDeserializerTest { + + /** + * Tests {@link OxmIpv6ExtHdrDeserializer#deserialize(ByteBuf)} + */ + @Test + public void test() { + ByteBuf buffer = BufferHelper.buildBuffer("80 00 4E 02 01 FF"); + + buffer.skipBytes(4); // skip XID + OxmIpv6ExtHdrDeserializer deserializer = new OxmIpv6ExtHdrDeserializer(); + MatchEntries entry = deserializer.deserialize(buffer); + + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry.getOxmClass()); + Assert.assertEquals("Wrong entry field", Ipv6Exthdr.class, entry.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", false, entry.isHasMask()); + Assert.assertEquals("Wrong entry value", + new Ipv6ExthdrFlags(true, true, true, true, true, true, true, true, true), + entry.getAugmentation(PseudoFieldMatchEntry.class).getPseudoField()); + Assert.assertEquals("Wrong entry mask", null, entry.getAugmentation(MaskMatchEntry.class)); + Assert.assertTrue("Unread data", buffer.readableBytes() == 0); + } +} \ No newline at end of file diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6FlabelDeserializerTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6FlabelDeserializerTest.java new file mode 100644 index 00000000..9b0d1a4d --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6FlabelDeserializerTest.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2014 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowjava.protocol.impl.deserialization.match; + +import io.netty.buffer.ByteBuf; + +import org.junit.Assert; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Ipv6FlabelMatchEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Ipv6Flabel; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.OpenflowBasicClass; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.grouping.MatchEntries; + +/** + * @author michal.polkorab + * + */ +public class OxmIpv6FlabelDeserializerTest { + + /** + * Tests {@link OxmIpv6FlabelDeserializer#deserialize(ByteBuf)} + */ + @Test + public void test() { + ByteBuf buffer = BufferHelper.buildBuffer("80 00 38 04 00 00 00 02"); + + buffer.skipBytes(4); // skip XID + OxmIpv6FlabelDeserializer deserializer = new OxmIpv6FlabelDeserializer(); + MatchEntries entry = deserializer.deserialize(buffer); + + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry.getOxmClass()); + Assert.assertEquals("Wrong entry field", Ipv6Flabel.class, entry.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", false, entry.isHasMask()); + Assert.assertEquals("Wrong entry value", 2, + entry.getAugmentation(Ipv6FlabelMatchEntry.class).getIpv6Flabel().getValue().intValue()); + } +} \ No newline at end of file diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmMetadataDeserializerTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmMetadataDeserializerTest.java new file mode 100644 index 00000000..0cf62839 --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmMetadataDeserializerTest.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2014 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowjava.protocol.impl.deserialization.match; + +import io.netty.buffer.ByteBuf; + +import org.junit.Assert; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; +import org.opendaylight.openflowjava.util.ByteBufUtils; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MetadataMatchEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Metadata; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.OpenflowBasicClass; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.grouping.MatchEntries; + +/** + * @author michal.polkorab + * + */ +public class OxmMetadataDeserializerTest { + + /** + * Tests {@link OxmMetadataDeserializer#deserialize(ByteBuf)} + */ + @Test + public void test() { + ByteBuf buffer = BufferHelper.buildBuffer("80 00 04 08 00 00 00 00 00 00 00 03"); + + buffer.skipBytes(4); // skip XID + OxmMetadataDeserializer deserializer = new OxmMetadataDeserializer(); + MatchEntries entry = deserializer.deserialize(buffer); + + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry.getOxmClass()); + Assert.assertEquals("Wrong entry field", Metadata.class, entry.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", false, entry.isHasMask()); + Assert.assertArrayEquals("Wrong entry value", ByteBufUtils.hexStringToBytes("00 00 00 00 00 00 00 03"), + entry.getAugmentation(MetadataMatchEntry.class).getMetadata()); + } +} \ No newline at end of file diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmMplsBosDeserializerTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmMplsBosDeserializerTest.java new file mode 100644 index 00000000..e8a379c7 --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmMplsBosDeserializerTest.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2014 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowjava.protocol.impl.deserialization.match; + +import io.netty.buffer.ByteBuf; + +import org.junit.Assert; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.BosMatchEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.MplsBos; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.OpenflowBasicClass; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.grouping.MatchEntries; + +/** + * @author michal.polkorab + * + */ +public class OxmMplsBosDeserializerTest { + + /** + * Tests {@link OxmMplsBosDeserializer#deserialize(ByteBuf)} + */ + @Test + public void test() { + ByteBuf buffer = BufferHelper.buildBuffer("80 00 48 01 00"); + + buffer.skipBytes(4); // skip XID + OxmMplsBosDeserializer deserializer = new OxmMplsBosDeserializer(); + MatchEntries entry = deserializer.deserialize(buffer); + + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry.getOxmClass()); + Assert.assertEquals("Wrong entry field", MplsBos.class, entry.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", false, entry.isHasMask()); + Assert.assertEquals("Wrong entry value", false, entry.getAugmentation(BosMatchEntry.class).isBos()); + } +} \ No newline at end of file diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmPbbIsidDeserializerTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmPbbIsidDeserializerTest.java new file mode 100644 index 00000000..b33c8a26 --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmPbbIsidDeserializerTest.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2014 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowjava.protocol.impl.deserialization.match; + +import io.netty.buffer.ByteBuf; + +import org.junit.Assert; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.IsidMatchEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.OpenflowBasicClass; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.PbbIsid; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.grouping.MatchEntries; + +/** + * @author michal.polkorab + * + */ +public class OxmPbbIsidDeserializerTest { + + /** + * Tests {@link OxmPbbIsidDeserializer#deserialize(ByteBuf)} + */ + @Test + public void test() { + ByteBuf buffer = BufferHelper.buildBuffer("80 00 4A 03 00 00 02"); + + buffer.skipBytes(4); // skip XID + OxmPbbIsidDeserializer deserializer = new OxmPbbIsidDeserializer(); + MatchEntries entry = deserializer.deserialize(buffer); + + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry.getOxmClass()); + Assert.assertEquals("Wrong entry field", PbbIsid.class, entry.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", false, entry.isHasMask()); + Assert.assertEquals("Wrong entry value", 2, entry.getAugmentation(IsidMatchEntry.class).getIsid().intValue()); + } +} \ No newline at end of file diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmVlanVidDeserializerTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmVlanVidDeserializerTest.java new file mode 100644 index 00000000..a51cc122 --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmVlanVidDeserializerTest.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2014 Pantheon Technologies s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowjava.protocol.impl.deserialization.match; + +import io.netty.buffer.ByteBuf; + +import org.junit.Assert; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.VlanVidMatchEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.OpenflowBasicClass; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.VlanVid; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.grouping.MatchEntries; + +/** + * @author michal.polkorab + * + */ +public class OxmVlanVidDeserializerTest { + + /** + * Tests {@link OxmVlanVidDeserializer#deserialize(ByteBuf)} + */ + @Test + public void test() { + ByteBuf buffer = BufferHelper.buildBuffer("80 00 0C 02 20 0A"); + + buffer.skipBytes(4); // skip XID + OxmVlanVidDeserializer deserializer = new OxmVlanVidDeserializer(); + MatchEntries entry = deserializer.deserialize(buffer); + + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry.getOxmClass()); + Assert.assertEquals("Wrong entry field", VlanVid.class, entry.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", false, entry.isHasMask()); + Assert.assertEquals("Wrong entry value", 10, + entry.getAugmentation(VlanVidMatchEntry.class).getVlanVid().intValue()); + Assert.assertEquals("Wrong entry value", false, + entry.getAugmentation(VlanVidMatchEntry.class).isCfiBit()); + } +} \ No newline at end of file diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/ActionsDeserializerTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/ActionsDeserializerTest.java index 06fbe466..e0dfb8f7 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/ActionsDeserializerTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/ActionsDeserializerTest.java @@ -17,6 +17,7 @@ import org.junit.Test; import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.protocol.impl.deserialization.DeserializerRegistryImpl; +import org.opendaylight.openflowjava.protocol.impl.deserialization.action.AbstractActionDeserializer; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.EthertypeAction; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.GroupIdAction; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MaxLengthAction; @@ -142,4 +143,24 @@ public class ActionsDeserializerTest { Assert.assertTrue("Unread data in message", message.readableBytes() == 0); } + /** + * Tests {@link AbstractActionDeserializer#deserializeHeader(ByteBuf)} + */ + @Test + public void testDeserializeHeader() { + ByteBuf message = BufferHelper.buildBuffer("00 00 00 04 00 19 00 04"); + + message.skipBytes(4); // skip XID + CodeKeyMaker keyMaker = CodeKeyMakerFactory.createActionsKeyMaker(EncodeConstants.OF13_VERSION_ID); + List actions = ListDeserializer.deserializeHeaders(EncodeConstants.OF13_VERSION_ID, + message.readableBytes(), message, keyMaker, registry); + + Assert.assertEquals("Wrong action type", "org.opendaylight.yang.gen.v1.urn.opendaylight." + + "openflow.common.action.rev130731.Output", actions.get(0).getType().getName()); + Assert.assertEquals("Wrong action port", null, actions.get(0).getAugmentation(PortAction.class)); + Assert.assertEquals("Wrong action max-length", null, actions.get(0).getAugmentation(MaxLengthAction.class)); + Assert.assertEquals("Wrong action type", "org.opendaylight.yang.gen.v1.urn.opendaylight." + + "openflow.common.action.rev130731.SetField", actions.get(1).getType().getName()); + Assert.assertEquals("Wrong action oxm field", null, actions.get(1).getAugmentation(OxmFieldsAction.class)); + } } diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/MatchDeserializerTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/MatchDeserializerTest.java index b0db8353..c9021b28 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/MatchDeserializerTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/MatchDeserializerTest.java @@ -15,6 +15,7 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry; +import org.opendaylight.openflowjava.protocol.api.extensibility.HeaderDeserializer; import org.opendaylight.openflowjava.protocol.api.extensibility.MessageCodeKey; import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; import org.opendaylight.openflowjava.protocol.api.keys.MatchEntryDeserializerKey; @@ -194,7 +195,7 @@ public class MatchDeserializerTest { + "80 00 48 01 01 " + "80 00 4B 06 00 00 02 00 00 01 " + "80 00 4D 10 00 00 00 00 00 00 00 07 00 00 00 00 00 00 00 FF " - + "80 00 4F 04 01 66 03 04 " + + "80 00 4F 04 00 00 03 04 " + "00 00 00 00"); Match match = matchDeserializer.deserialize(buffer); @@ -474,11 +475,28 @@ public class MatchDeserializerTest { Assert.assertEquals("Wrong entry field", Ipv6Exthdr.class, entry39.getOxmMatchField()); Assert.assertEquals("Wrong entry hasMask", true, entry39.isHasMask()); Assert.assertEquals("Wrong entry value", - new Ipv6ExthdrFlags(true, false, true, false, true, false, true, false, true), + new Ipv6ExthdrFlags(false, false, false, false, false, false, false, false, false), entry39.getAugmentation(PseudoFieldMatchEntry.class).getPseudoField()); Assert.assertArrayEquals("Wrong entry mask", ByteBufUtils.hexStringToBytes("03 04"), entry39.getAugmentation(MaskMatchEntry.class).getMask()); Assert.assertTrue("Unread data", buffer.readableBytes() == 0); } -} + /** + * Testing header deserialization + */ + @Test + public void testHeaders() { + ByteBuf buffer = ByteBufUtils.hexStringToByteBuf("80 00 18 04 00 01 02 03"); + + MatchEntryDeserializerKey key = new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, + 0x8000, 12); + key.setExperimenterId(null); + HeaderDeserializer entryDeserializer = registry.getDeserializer(key); + MatchEntries entry = entryDeserializer.deserializeHeader(buffer); + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry.getOxmClass()); + Assert.assertEquals("Wrong entry field", Ipv4Dst.class, entry.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", false, entry.isHasMask()); + Assert.assertEquals("Wrong Ipv4 address", null, entry.getAugmentation(Ipv4AddressMatchEntry.class)); + } +} \ No newline at end of file diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF13ActionsSerializerTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF13ActionsSerializerTest.java index bcc335c3..f801dee3 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF13ActionsSerializerTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF13ActionsSerializerTest.java @@ -243,4 +243,45 @@ public class OF13ActionsSerializerTest { Assert.assertTrue("Unread data", out.readableBytes() == 0); } -} + /** + * Testing correct serialization of actions + */ + @Test + public void testHeaders() { + List actions = new ArrayList<>(); + ActionBuilder actionBuilder = new ActionBuilder(); + actionBuilder.setType(Output.class); + PortActionBuilder port = new PortActionBuilder(); + port.setPort(new PortNumber(42L)); + actionBuilder.addAugmentation(PortAction.class, port.build()); + MaxLengthActionBuilder maxLen = new MaxLengthActionBuilder(); + maxLen.setMaxLength(52); + actionBuilder.addAugmentation(MaxLengthAction.class, maxLen.build()); + actions.add(actionBuilder.build()); + actionBuilder = new ActionBuilder(); + actionBuilder.setType(SetField.class); + OxmFieldsActionBuilder matchEntries = new OxmFieldsActionBuilder(); + List entries = new ArrayList<>(); + MatchEntriesBuilder matchBuilder = new MatchEntriesBuilder(); + matchBuilder.setOxmClass(OpenflowBasicClass.class); + matchBuilder.setOxmMatchField(InPort.class); + matchBuilder.setHasMask(false); + PortNumberMatchEntryBuilder portBuilder = new PortNumberMatchEntryBuilder(); + portBuilder.setPortNumber(new PortNumber(1L)); + matchBuilder.addAugmentation(PortNumberMatchEntry.class, portBuilder.build()); + entries.add(matchBuilder.build()); + matchEntries.setMatchEntries(entries); + actionBuilder.addAugmentation(OxmFieldsAction.class, matchEntries.build()); + actions.add(actionBuilder.build()); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + ListSerializer.serializeHeaderList(actions, TypeKeyMakerFactory + .createActionKeyMaker(EncodeConstants.OF13_VERSION_ID), registry, out); + + Assert.assertEquals("Wrong action type", 0, out.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 4, out.readUnsignedShort()); + Assert.assertEquals("Wrong action type", 25, out.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 4, out.readUnsignedShort()); + Assert.assertTrue("Unread data", out.readableBytes() == 0); + } +} \ No newline at end of file diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF13MatchSerializerTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF13MatchSerializerTest.java index 17bc3267..453662e5 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF13MatchSerializerTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF13MatchSerializerTest.java @@ -106,7 +106,7 @@ public class OF13MatchSerializerTest { /** * Test for correct serialization of Ipv6Address match entry */ - @Test + @Test(expected=IllegalStateException.class) public void testIpv6Various() { MatchBuilder builder = new MatchBuilder(); builder.setType(OxmMatchType.class); @@ -165,6 +165,15 @@ public class OF13MatchSerializerTest { addressBuilder.setIpv6Address(new Ipv6Address("1:2:3:4:5:6:7:8:9")); entriesBuilder.addAugmentation(Ipv6AddressMatchEntry.class, addressBuilder.build()); entries.add(entriesBuilder.build()); + // ipv6 match entry with too abbreviated Ipv6 address + entriesBuilder = new MatchEntriesBuilder(); + entriesBuilder.setOxmClass(OpenflowBasicClass.class); + entriesBuilder.setOxmMatchField(Ipv6NdTarget.class); + entriesBuilder.setHasMask(false); + addressBuilder = new Ipv6AddressMatchEntryBuilder(); + addressBuilder.setIpv6Address(new Ipv6Address("1:2::::8")); + entriesBuilder.addAugmentation(Ipv6AddressMatchEntry.class, addressBuilder.build()); + entries.add(entriesBuilder.build()); builder.setMatchEntries(entries); Match match = builder.build(); ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); -- 2.36.6