BUG-6973: Implement test for InstructionDeployer 34/53434/7
authorClaudio D. Gasparini <claudio.gasparini@pantheon.tech>
Tue, 14 Mar 2017 17:02:02 +0000 (18:02 +0100)
committerClaudio D. Gasparini <claudio.gasparini@pantheon.tech>
Sat, 15 Apr 2017 11:24:30 +0000 (13:24 +0200)
Cover InstructionDeployer with test

Change-Id: I8ed071a8a11dd0d9183fe6c5b45ae7616f6ce5f9
Signed-off-by: Claudio D. Gasparini <claudio.gasparini@pantheon.tech>
programming/impl/src/main/java/org/opendaylight/bgpcep/programming/impl/InstructionDeployerImpl.java [moved from programming/impl/src/main/java/org/opendaylight/bgpcep/programming/impl/InstructionDeployedImpl.java with 90% similarity]
programming/impl/src/main/resources/org/opendaylight/blueprint/programming.xml
programming/impl/src/test/java/org/opendaylight/bgpcep/programming/impl/InstructionDeployerImplTest.java [new file with mode: 0644]
programming/impl/src/test/java/org/opendaylight/bgpcep/programming/impl/ProgrammingServiceImplTest.java

similarity index 90%
rename from programming/impl/src/main/java/org/opendaylight/bgpcep/programming/impl/InstructionDeployedImpl.java
rename to programming/impl/src/main/java/org/opendaylight/bgpcep/programming/impl/InstructionDeployerImpl.java
index 5e84791bff1a250399b3d3292a02edb2b63fb54e..f7469b7bf80384a07f42610d6c9963952f444bb0 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.bgpcep.programming.impl;
 
+import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.Iterables;
 import com.google.common.util.concurrent.CheckedFuture;
@@ -17,6 +18,7 @@ import com.google.common.util.concurrent.ListeningExecutorService;
 import com.google.common.util.concurrent.MoreExecutors;
 import io.netty.util.Timer;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.Dictionary;
 import java.util.HashMap;
 import java.util.Hashtable;
@@ -43,15 +45,16 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.odl.prog
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.odl.programming.config.rev170301.odl.programming.OdlProgrammingConfigBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.odl.programming.config.rev170301.odl.programming.OdlProgrammingConfigKey;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceRegistration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public final class InstructionDeployedImpl implements IntructionDeployer,
+public final class InstructionDeployerImpl implements IntructionDeployer,
     ClusteredDataTreeChangeListener<OdlProgramming>, AutoCloseable {
-    private static final Logger LOG = LoggerFactory.getLogger(InstructionDeployedImpl.class);
+    private static final Logger LOG = LoggerFactory.getLogger(InstructionDeployerImpl.class);
 
     private final RpcProviderRegistry rpcProviderRegistry;
     private final ListeningExecutorService exec = MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor());
@@ -61,11 +64,11 @@ public final class InstructionDeployedImpl implements IntructionDeployer,
     private final BundleContext bundleContext;
     @GuardedBy("this")
     private final Map<String, ProgrammingServiceImpl> programmingServices = new HashMap<>();
-    private final ListenerRegistration<InstructionDeployedImpl> registration;
+    private final ListenerRegistration<InstructionDeployerImpl> registration;
     private final InstanceIdentifier<OdlProgramming> iid;
     private final ClusterSingletonServiceProvider cssp;
 
-    public InstructionDeployedImpl(final DataBroker dataProvider, final RpcProviderRegistry rpcProviderRegistry,
+    public InstructionDeployerImpl(final DataBroker dataProvider, final RpcProviderRegistry rpcProviderRegistry,
         final NotificationPublishService notifs, final Timer timer, final ClusterSingletonServiceProvider cssp,
         final BundleContext bundleContext) {
         this.dataProvider = Preconditions.checkNotNull(dataProvider);
@@ -77,16 +80,17 @@ public final class InstructionDeployedImpl implements IntructionDeployer,
         this.iid = InstanceIdentifier.create(OdlProgramming.class);
 
         final WriteTransaction wTx = dataProvider.newWriteOnlyTransaction();
-        wTx.merge(LogicalDatastoreType.CONFIGURATION, this.iid, new OdlProgrammingBuilder().build());
+        wTx.merge(LogicalDatastoreType.CONFIGURATION, this.iid, new OdlProgrammingBuilder()
+            .setOdlProgrammingConfig(Collections.emptyList()).build());
         Futures.addCallback(wTx.submit(), new FutureCallback<Void>() {
             @Override
             public void onSuccess(final Void result) {
-                LOG.debug("Instruction Instance {} initialized successfully.", InstructionDeployedImpl.this.iid);
+                LOG.debug("Instruction Instance {} initialized successfully.", InstructionDeployerImpl.this.iid);
             }
 
             @Override
             public void onFailure(final Throwable t) {
-                LOG.error("Failed to initialize Instruction Instance {}.", InstructionDeployedImpl.this.iid, t);
+                LOG.error("Failed to initialize Instruction Instance {}.", InstructionDeployerImpl.this.iid, t);
             }
         });
 
@@ -94,6 +98,12 @@ public final class InstructionDeployedImpl implements IntructionDeployer,
             new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, this.iid), this);
     }
 
+    @VisibleForTesting
+    InstanceIdentifier<OdlProgramming> getInstructionIID(){
+        return this.iid;
+    }
+
+
     private synchronized void createInstruction(final String instructionId) {
         if (this.programmingServices.containsKey(instructionId)) {
             LOG.warn("Instruction Scheduler {} already exist. New instance won't be created", instructionId);
@@ -172,9 +182,12 @@ public final class InstructionDeployedImpl implements IntructionDeployer,
     @Override
     public synchronized void onDataTreeChanged(@Nonnull final Collection<DataTreeModification<OdlProgramming>> changes) {
         final DataTreeModification<OdlProgramming> dataTreeModification = Iterables.getOnlyElement(changes);
-        final DataObjectModification<OdlProgramming> rootNode = dataTreeModification.getRootNode();
-        rootNode.getModifiedChildren()
-            .forEach(dto->handleModification((DataObjectModification<OdlProgrammingConfig>) dto));
+        final Collection<DataObjectModification<? extends DataObject>> rootNode = dataTreeModification.getRootNode()
+            .getModifiedChildren();
+        if(rootNode.isEmpty()) {
+            return;
+        }
+        rootNode.forEach(dto->handleModification((DataObjectModification<OdlProgrammingConfig>) dto));
     }
 
     private void handleModification(final DataObjectModification<OdlProgrammingConfig> config) {
index 38bd0fe749af098e10ed3d14278052d9e5190e83..0522b45e730f7d4db7b743958779774034d35316 100644 (file)
@@ -19,7 +19,7 @@
     <reference id="clusterSingletonServiceProvider"
                interface="org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider"/>
 
-    <bean id="IntructionDeployerImpl" class="org.opendaylight.bgpcep.programming.impl.InstructionDeployedImpl"
+    <bean id="IntructionDeployerImpl" class="org.opendaylight.bgpcep.programming.impl.InstructionDeployerImpl"
           destroy-method="close">
         <argument ref="dataBroker"/>
         <argument ref="rpcRegistry"/>
diff --git a/programming/impl/src/test/java/org/opendaylight/bgpcep/programming/impl/InstructionDeployerImplTest.java b/programming/impl/src/test/java/org/opendaylight/bgpcep/programming/impl/InstructionDeployerImplTest.java
new file mode 100644 (file)
index 0000000..ae3dfbb
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2017 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.bgpcep.programming.impl;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.verify;
+import static org.mockito.MockitoAnnotations.initMocks;
+import static org.opendaylight.protocol.util.CheckUtil.checkNotPresentConfiguration;
+import static org.opendaylight.protocol.util.CheckUtil.checkPresentConfiguration;
+
+import io.netty.util.Timer;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
+import org.opendaylight.controller.md.sal.binding.test.AbstractDataBrokerTest;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
+import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
+import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.odl.programming.config.rev170301.odl.programming.OdlProgrammingConfig;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.odl.programming.config.rev170301.odl.programming.OdlProgrammingConfigKey;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+
+public class InstructionDeployerImplTest extends AbstractDataBrokerTest {
+    @Mock
+    private RpcProviderRegistry rpcRegistry;
+    @Mock
+    private NotificationPublishService notifs;
+    @Mock
+    private Timer timer;
+    @Mock
+    private ClusterSingletonServiceProvider cssp;
+    @Mock
+    private ClusterSingletonServiceRegistration singletonServiceRegistration;
+    @Mock
+    private BundleContext bundleContext;
+    @Mock
+    private ServiceRegistration serviceRegistration;
+
+    @Before
+    public void setUp() throws Exception {
+        initMocks(this);
+        doAnswer(invocationOnMock -> this.singletonServiceRegistration).when(this.cssp)
+            .registerClusterSingletonService(any(ClusterSingletonService.class));
+
+        doReturn(this.serviceRegistration).when(this.bundleContext).registerService(any(String.class), any(), any());
+    }
+
+    @Test
+    public void testInstructionDeployer() throws Exception {
+        final InstructionDeployerImpl deployer = new InstructionDeployerImpl(getDataBroker(), this.rpcRegistry,
+            this.notifs, this.timer, this.cssp, this.bundleContext);
+
+        checkPresentConfiguration(getDataBroker(), deployer.getInstructionIID());
+
+        final String instructionId = "newInstruction";
+        deployer.writeConfiguration(instructionId);
+        final KeyedInstanceIdentifier<OdlProgrammingConfig, OdlProgrammingConfigKey> intructionIID =
+            deployer.getInstructionIID().child(OdlProgrammingConfig.class, new OdlProgrammingConfigKey(instructionId));
+        checkPresentConfiguration(getDataBroker(), intructionIID);
+        verify(this.cssp, timeout(100)).registerClusterSingletonService(any());
+        verify(this.bundleContext, timeout(100)).registerService(any(String.class), any(), any());
+
+        deployer.removeConfiguration(instructionId);
+        checkNotPresentConfiguration(getDataBroker(), intructionIID);
+        verify(this.singletonServiceRegistration, timeout(100)).close();
+        verify(this.serviceRegistration, timeout(100)).unregister();
+
+        deployer.close();
+    }
+}
\ No newline at end of file
index 0fc0d821c9d464b1d2aef93017ea9eb1f22bab2a..50857ef71008fdd8036ddab660142f21fc01cf65 100644 (file)
@@ -17,6 +17,7 @@ import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
+import static org.mockito.MockitoAnnotations.initMocks;
 import static org.opendaylight.protocol.util.CheckUtil.checkNotPresentOperational;
 import static org.opendaylight.protocol.util.CheckUtil.checkPresentOperational;
 
@@ -32,7 +33,6 @@ import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mock;
 import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
 import org.opendaylight.bgpcep.programming.NanotimeUtil;
 import org.opendaylight.bgpcep.programming.spi.Instruction;
 import org.opendaylight.bgpcep.programming.spi.SchedulerException;
@@ -82,7 +82,7 @@ public class ProgrammingServiceImplTest extends AbstractDataBrokerTest {
 
     @Before
     public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
+        initMocks(this);
         doAnswer(invocationOnMock -> {
             this.singletonService = (ClusterSingletonService) invocationOnMock.getArguments()[0];
             return this.singletonServiceRegistration;