/* * Copyright (c) 2016 Cisco Systems, Inc. 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.groupbasedpolicy.renderer.ios_xe_provider.impl.writer; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.when; import java.util.Collections; import com.google.common.base.Optional; import com.google.common.util.concurrent.Futures; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Matchers; import org.mockito.Mock; import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction; import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl; import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.ServiceChainingUtil; import org.opendaylight.yang.gen.v1.urn.ios.rev160308.ClassNameType; import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ClassMap; import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ClassMapBuilder; import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.PolicyMap; import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.PolicyMapBuilder; import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ServiceChain; import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ServiceChainBuilder; import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map.Class; import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map.ClassBuilder; import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.ServicePathBuilder; import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.function.forwarder.ServiceFfName; import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.function.forwarder.ServiceFfNameBuilder; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Test for {@link PolicyWriterUtil}. */ @RunWith(PowerMockRunner.class) @PrepareForTest({PolicyWriterUtil.class, NetconfTransactionCreator.class, ServiceChainingUtil.class}) public class PolicyWriterUtilTest { private static final Logger LOG = LoggerFactory.getLogger(PolicyWriterUtilTest.class); private static final String UNIT_CLASS_MAP_ENTRY_NAME = "unit-classMapEntry-name"; private static final String CLASS_MAP_NAME = "asd"; private static final String UNIT_POLICY_MAP_NAME = "unit-policyMap-name"; private static final String UNIT_CLASS_NAME = "unit-class-name"; private static final String UNIT_SERVICE_FORWARDER_NAME = "unit-service-forwarder-name"; // methods private static final String NETCONF_WRITE_ONLY_TRANSACTION = "netconfWriteOnlyTransaction"; private static final String NETCONF_READ_ONLY_TRANSACTION = "netconfReadOnlyTransaction"; private static final String NETCONF_READ = "netconfRead"; @Mock private DataBroker dataBroker; @Mock private WriteTransaction wTx; private java.util.Optional<WriteTransaction> wTxOptional; @Mock private ReadOnlyTransaction rTx; private java.util.Optional<ReadOnlyTransaction> rTxOptional; @Before public void setUp() throws Exception { wTxOptional = java.util.Optional.of(wTx); rTxOptional = java.util.Optional.of(rTx); } // TODO remove reflection-based stubs everywhere @Test public void testWriteClassMap() throws Exception { LOG.debug("scenario: fail with one entry, no writeOnlyTransaction"); final ClassMap classMap = new ClassMapBuilder().setName(UNIT_CLASS_MAP_ENTRY_NAME).build(); assertFalse(PolicyWriterUtil.writeClassMap(classMap, getLocation())); LOG.debug("scenario: fail with one entry, available writeOnlyTransaction, no readOnlyTransaction"); PowerMockito.stub(PowerMockito.method(NetconfTransactionCreator.class, NETCONF_WRITE_ONLY_TRANSACTION)).toReturn(wTxOptional); when(wTx.submit()).thenReturn(Futures.immediateCheckedFuture(null)); assertFalse(PolicyWriterUtil.writeClassMap(classMap, getLocation())); LOG.debug("scenario: succeed with one entry, available writeOnlyTransaction, available readOnlyTransaction"); PowerMockito.stub(PowerMockito.method(NetconfTransactionCreator.class, NETCONF_READ_ONLY_TRANSACTION)).toReturn(rTxOptional); when(rTx.read(eq(LogicalDatastoreType.CONFIGURATION), Matchers.<InstanceIdentifier<ClassMap>>any())) .thenReturn(Futures.immediateCheckedFuture(Optional.of( new ClassMapBuilder().setName(CLASS_MAP_NAME).build()))); assertTrue(PolicyWriterUtil.writeClassMap(classMap, getLocation())); LOG.debug("scenario: fail with one entry, available writeOnlyTransaction, available readOnlyTransaction, check->null"); PowerMockito.stub(PowerMockito.method(PolicyWriterUtil.class, NETCONF_READ)).toReturn(null); assertFalse(PolicyWriterUtil.writeClassMap(classMap, getLocation())); } @Test public void testRemoveClassMap() throws Exception { LOG.debug("scenario: pass through with null classMapEntries collection"); assertTrue(PolicyWriterUtil.removeClassMap(null, getLocation())); LOG.debug("scenario: pass through with empty classMapEntries collection"); final ClassMap classMap = new ClassMapBuilder().setName(UNIT_CLASS_MAP_ENTRY_NAME).build(); assertTrue(PolicyWriterUtil.removeClassMap(classMap, getLocation())); LOG.debug("scenario: fail with one entry, no writeOnlyTransaction"); PowerMockito.stub(PowerMockito.method(PolicyWriterUtil.class, NETCONF_READ)).toReturn(new ClassBuilder().build()); PowerMockito.stub(PowerMockito.method(NetconfTransactionCreator.class, NETCONF_WRITE_ONLY_TRANSACTION)) .toReturn(java.util.Optional.empty()); assertFalse(PolicyWriterUtil.removeClassMap(classMap, getLocation())); LOG.debug("scenario: fail with one entry, available writeOnlyTransaction, no readOnlyTransaction"); PowerMockito.stub(PowerMockito.method(NetconfTransactionCreator.class, NETCONF_WRITE_ONLY_TRANSACTION)).toReturn(wTxOptional); when(wTx.submit()).thenReturn(Futures.immediateCheckedFuture(null)); assertFalse(PolicyWriterUtil.removeClassMap(classMap, getLocation())); LOG.debug("scenario: succeed with one entry, available writeOnlyTransaction, available readOnlyTransaction"); PowerMockito.stub(PowerMockito.method(NetconfTransactionCreator.class, NETCONF_READ_ONLY_TRANSACTION)).toReturn(rTxOptional); PowerMockito.stub(PowerMockito.method(PolicyWriterUtil.class, NETCONF_READ)).toReturn(null); when(rTx.read(eq(LogicalDatastoreType.CONFIGURATION), Matchers.<InstanceIdentifier<ClassMap>>any())) .thenReturn(Futures.immediateCheckedFuture(Optional.absent())); assertTrue(PolicyWriterUtil.removeClassMap(classMap, getLocation())); LOG.debug("scenario: fail with one entry, available writeOnlyTransaction, available readOnlyTransaction, check->false"); PowerMockito.stub(PowerMockito.method(PolicyWriterUtil.class, NETCONF_READ)).toReturn(new ClassBuilder().build()); assertFalse(PolicyWriterUtil.removeClassMap(classMap, getLocation())); } @Test public void testWritePolicyMap() throws Exception { LOG.debug("scenario: fail with one entry, no writeOnlyTransaction"); final PolicyMap policyMap = new PolicyMapBuilder().setName(UNIT_POLICY_MAP_NAME).build(); assertFalse(PolicyWriterUtil.writePolicyMap(policyMap, getLocation())); LOG.debug("scenario: fail with one entry, available writeOnlyTransaction, no readOnlyTransaction"); PowerMockito.stub(PowerMockito.method(NetconfTransactionCreator.class, NETCONF_WRITE_ONLY_TRANSACTION)).toReturn(wTxOptional); when(wTx.submit()).thenReturn(Futures.immediateCheckedFuture(null)); assertFalse(PolicyWriterUtil.writePolicyMap(policyMap, getLocation())); LOG.debug("scenario: fail with empty classEntries collection"); assertFalse(PolicyWriterUtil.writePolicyMap(policyMap, getLocation())); LOG.debug("scenario: succeed with one entry, available writeOnlyTransaction, available readOnlyTransaction"); PowerMockito.stub(PowerMockito.method(NetconfTransactionCreator.class, NETCONF_READ_ONLY_TRANSACTION)).toReturn(rTxOptional); when(rTx.read(eq(LogicalDatastoreType.CONFIGURATION), Matchers.<InstanceIdentifier<ClassMap>>any())) .thenReturn(Futures.immediateCheckedFuture(Optional.of( new ClassMapBuilder().setName(CLASS_MAP_NAME).build()))); assertTrue(PolicyWriterUtil.writePolicyMap(policyMap, getLocation())); LOG.debug("scenario: fail with one entry, available writeOnlyTransaction, available readOnlyTransaction, check->null"); PowerMockito.stub(PowerMockito.method(PolicyWriterUtil.class, NETCONF_READ)).toReturn(null); assertFalse(PolicyWriterUtil.writePolicyMap(policyMap, getLocation())); } @Test public void testRemovePolicyMap() throws Exception { final PolicyMap policyMap = new PolicyMapBuilder().setName(UNIT_POLICY_MAP_NAME).build(); PowerMockito.stub(PowerMockito.method(NetconfTransactionCreator.class, NETCONF_WRITE_ONLY_TRANSACTION)).toReturn(wTxOptional); when(wTx.submit()).thenReturn(Futures.immediateCheckedFuture(null)); PowerMockito.stub(PowerMockito.method(NetconfTransactionCreator.class, NETCONF_READ_ONLY_TRANSACTION)).toReturn(rTxOptional); when(rTx.read(eq(LogicalDatastoreType.CONFIGURATION), Matchers.<InstanceIdentifier<ClassMap>>any())) .thenReturn(Futures.immediateCheckedFuture(Optional.of( new ClassMapBuilder().setName(CLASS_MAP_NAME).build()))); PolicyWriterUtil.writePolicyMap(policyMap, getLocation()); LOG.debug("scenario: fail to remove"); PowerMockito.stub(PowerMockito.method(PolicyWriterUtil.class, NETCONF_READ)).toReturn(new ClassBuilder().build()); assertFalse(PolicyWriterUtil.removePolicyMap(getLocation())); LOG.debug("scenario: remove succeed"); PowerMockito.stub(PowerMockito.method(PolicyWriterUtil.class, NETCONF_READ)).toReturn(null); assertTrue(PolicyWriterUtil.removePolicyMap(getLocation())); } @Test public void testRemovePolicyMapEntry() throws Exception { LOG.debug("scenario: pass through with empty classEntries collection"); final Class entry = new ClassBuilder().setName(new ClassNameType(UNIT_CLASS_NAME)).build(); assertTrue(PolicyWriterUtil.removePolicyMapEntry(entry, getLocation())); LOG.debug("scenario: fail with one entry, no writeOnlyTransaction"); PowerMockito.stub(PowerMockito.method(PolicyWriterUtil.class, NETCONF_READ)).toReturn(new ClassBuilder().build()); assertFalse(PolicyWriterUtil.removePolicyMapEntry(entry, getLocation())); LOG.debug("scenario: fail with one entry, available writeOnlyTransaction, no readOnlyTransaction"); PowerMockito.stub(PowerMockito.method(NetconfTransactionCreator.class, NETCONF_WRITE_ONLY_TRANSACTION)).toReturn(wTxOptional); when(wTx.submit()).thenReturn(Futures.immediateCheckedFuture(null)); assertTrue(PolicyWriterUtil.removePolicyMapEntry(entry, getLocation())); } @Test public void testWriteInterface() throws Exception { LOG.debug("scenario: fail with no writeOnlyTransaction"); assertFalse(PolicyWriterUtil.writeInterface(getLocation())); LOG.debug("scenario: fail - available writeOnlyTransaction, no submit future"); PowerMockito.stub(PowerMockito.method(NetconfTransactionCreator.class, NETCONF_WRITE_ONLY_TRANSACTION)).toReturn(wTxOptional); assertFalse(PolicyWriterUtil.writeInterface(getLocation())); LOG.debug("scenario: succeed - available writeOnlyTransaction, available future"); when(wTx.submit()).thenReturn(Futures.immediateCheckedFuture(null)); assertTrue(PolicyWriterUtil.writeInterface(getLocation())); } @Test public void testRemoveInterface() throws Exception { PowerMockito.stub(PowerMockito.method(NetconfTransactionCreator.class, NETCONF_WRITE_ONLY_TRANSACTION)).toReturn(wTxOptional); when(wTx.submit()).thenReturn(Futures.immediateCheckedFuture(null)); PolicyWriterUtil.writeInterface(getLocation()); PowerMockito.stub(PowerMockito.method(PolicyWriterUtil.class, NETCONF_READ)).toReturn(new ClassBuilder().build()); assertTrue(PolicyWriterUtil.removeInterface(getLocation())); PowerMockito.stub(PowerMockito.method(PolicyWriterUtil.class, NETCONF_READ)).toReturn(null); assertTrue(PolicyWriterUtil.removeInterface(getLocation())); PowerMockito.stub(PowerMockito.method(PolicyWriterUtil.class, NETCONF_READ)).toReturn(new ClassBuilder().build()); when(wTx.submit()).thenThrow(TransactionCommitFailedException.class); assertFalse(PolicyWriterUtil.removeInterface(getLocation())); } @Test public void testWriteRemote() throws Exception { LOG.debug("scenario: succeed with empty List<ServiceFfName>"); final ServiceFfName forwarder = new ServiceFfNameBuilder().setName(UNIT_SERVICE_FORWARDER_NAME).build(); assertFalse(PolicyWriterUtil.writeRemote(forwarder, getLocation())); LOG.debug("scenario: fail - available writeOnlyTransaction, no submit future"); PowerMockito.stub(PowerMockito.method(NetconfTransactionCreator.class, NETCONF_WRITE_ONLY_TRANSACTION)).toReturn(wTxOptional); assertFalse(PolicyWriterUtil.writeRemote(forwarder, getLocation())); LOG.debug("scenario: succeed - available writeOnlyTransaction, available future"); when(wTx.submit()).thenReturn(Futures.immediateCheckedFuture(null)); assertTrue(PolicyWriterUtil.writeRemote(forwarder, getLocation())); } @Test public void testRemoveRemote() throws Exception { final ServiceFfName forwarder = new ServiceFfNameBuilder().setName(UNIT_SERVICE_FORWARDER_NAME).build(); PowerMockito.stub(PowerMockito.method(NetconfTransactionCreator.class, NETCONF_WRITE_ONLY_TRANSACTION)).toReturn(wTxOptional); when(wTx.submit()).thenReturn(Futures.immediateCheckedFuture(null)); PolicyWriterUtil.writeRemote(forwarder, getLocation()); PowerMockito.stub(PowerMockito.method(PolicyWriterUtil.class, NETCONF_READ)).toReturn(new ClassBuilder().build()); assertTrue(PolicyWriterUtil.removeRemote(forwarder, getLocation())); PowerMockito.stub(PowerMockito.method(PolicyWriterUtil.class, NETCONF_READ)).toReturn(null); assertTrue(PolicyWriterUtil.removeRemote(forwarder, getLocation())); PowerMockito.stub(PowerMockito.method(PolicyWriterUtil.class, NETCONF_READ)).toReturn(new ClassBuilder().build()); when(wTx.submit()).thenThrow(TransactionCommitFailedException.class); assertFalse(PolicyWriterUtil.removeRemote(forwarder, getLocation())); } @Test public void testWriteServicePath() throws Exception { LOG.debug("scenario: fail with no writeOnlyTransaction"); final ServiceChain serviceChain = new ServiceChainBuilder() .setServicePath(Collections.singletonList(new ServicePathBuilder() .setServicePathId(42L) .build())) .build(); assertFalse(PolicyWriterUtil.writeServicePath(serviceChain, getLocation())); LOG.debug("scenario: fail - available writeOnlyTransaction, no submit future"); PowerMockito.stub(PowerMockito.method(NetconfTransactionCreator.class, NETCONF_WRITE_ONLY_TRANSACTION)).toReturn(wTxOptional); assertFalse(PolicyWriterUtil.writeServicePath(serviceChain, getLocation())); LOG.debug("scenario: succeed - available writeOnlyTransaction, available future"); when(wTx.submit()).thenReturn(Futures.immediateCheckedFuture(null)); assertTrue(PolicyWriterUtil.writeServicePath(serviceChain, getLocation())); } @Test public void testRemoveServicePath() throws Exception { LOG.debug("scenario: fail with service path present, no writeOnlyTransaction"); PowerMockito.stub(PowerMockito.method(PolicyWriterUtil.class, NETCONF_READ)).toReturn(new ClassBuilder().build()); final ServiceChain serviceChain = new ServiceChainBuilder() .setServicePath(Collections.singletonList(new ServicePathBuilder() .setServicePathId(42L) .build())) .build(); assertFalse(PolicyWriterUtil.removeServicePath(serviceChain, getLocation())); LOG.debug("scenario: fail with service path present, available writeOnlyTransaction, no submit future"); PowerMockito.stub(PowerMockito.method(NetconfTransactionCreator.class, NETCONF_WRITE_ONLY_TRANSACTION)).toReturn(wTxOptional); assertFalse(PolicyWriterUtil.removeServicePath(serviceChain, getLocation())); LOG.debug("scenario: fail with service path present, available writeOnlyTransaction, available future"); when(wTx.submit()).thenReturn(Futures.immediateCheckedFuture(null)); assertTrue(PolicyWriterUtil.removeServicePath(serviceChain, getLocation())); } private PolicyManagerImpl.PolicyMapLocation getLocation() { final String POLICY_MAP = "policy-map"; final String INTERFACE = "interface"; final NodeId nodeId = new NodeId("node-id"); final String IP_ADDRESS = "ip-address"; return new PolicyManagerImpl.PolicyMapLocation(POLICY_MAP, INTERFACE, nodeId, IP_ADDRESS, dataBroker); } }