Teach sal-remoterpc-connector to route actions
[controller.git] / opendaylight / md-sal / sal-remoterpc-connector / src / test / java / org / opendaylight / controller / remote / rpc / registry / gossip / BucketStoreTest.java
index fd6664af9e618872eb6f8a656cc7beddb68aa0bc..ed6d12c34d6883d22905ae7f9d025164a8122688 100644 (file)
@@ -9,61 +9,128 @@ package org.opendaylight.controller.remote.rpc.registry.gossip;
 
 import akka.actor.ActorRef;
 import akka.actor.ActorSystem;
+import akka.actor.Address;
 import akka.actor.Props;
 import akka.testkit.TestActorRef;
-import akka.testkit.TestProbe;
+import akka.testkit.javadsl.TestKit;
+import com.google.common.collect.ImmutableMap;
 import com.typesafe.config.ConfigFactory;
-import org.junit.After;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
 import org.junit.AfterClass;
 import org.junit.Assert;
-import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
+import org.opendaylight.controller.remote.rpc.RemoteOpsProviderConfig;
 import org.opendaylight.controller.remote.rpc.TerminationMonitor;
 
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.spy;
-
 public class BucketStoreTest {
 
-    private static ActorSystem system;
-    private static BucketStore store;
+    /**
+     * Dummy class to eliminate rawtype warnings.
+     *
+     * @author gwu
+     *
+     */
+    private static class T implements BucketData<T> {
+        @Override
+        public Optional<ActorRef> getWatchActor() {
+            return Optional.empty();
+        }
+    }
 
-    private BucketStore mockStore;
+    private static ActorSystem system;
 
     @BeforeClass
     public static void setup() {
-
-        system = ActorSystem.create("opendaylight-rpc", ConfigFactory.load().getConfig("odl-cluster"));
+        system = ActorSystem.create("opendaylight-rpc", ConfigFactory.load().getConfig("unit-test"));
         system.actorOf(Props.create(TerminationMonitor.class), "termination-monitor");
-
-        store = createStore();
     }
 
     @AfterClass
     public static void teardown() {
-        system.shutdown();
-    }
-
-    @Before
-    public void createMocks(){
-        mockStore = spy(store);
-    }
-
-    @After
-    public void resetMocks(){
-        reset(mockStore);
+        TestKit.shutdownActorSystem(system);
     }
 
+    /**
+     * Given remote buckets, should merge with local copy of remote buckets.
+     */
     @Test
-    public void testReceiveUpdateBucket_WhenInputBucketShouldUpdateVersion(){
-        Bucket bucket = new BucketImpl();
-        Long expectedVersion = bucket.getVersion();
-
-        mockStore.receiveUpdateBucket(bucket);
+    public void testReceiveUpdateRemoteBuckets() {
+
+        final BucketStoreActor<T> store = createStore();
+
+        Address localAddress = system.provider().getDefaultAddress();
+        Bucket<T> localBucket = new BucketImpl<>(0L, new T());
+
+        final Address a1 = new Address("tcp", "system1");
+        final Address a2 = new Address("tcp", "system2");
+        final Address a3 = new Address("tcp", "system3");
+
+        final Bucket<T> b1 = new BucketImpl<>(0L, new T());
+        final Bucket<T> b2 = new BucketImpl<>(0L, new T());
+        final Bucket<T> b3 = new BucketImpl<>(0L, new T());
+
+        //Given remote buckets
+        store.updateRemoteBuckets(ImmutableMap.of(a1, b1, a2, b2, localAddress, localBucket));
+
+        //Should NOT contain local bucket
+        //Should contain ONLY 3 entries i.e a1, a2
+        Map<Address, Bucket<T>> remoteBucketsInStore = store.getRemoteBuckets();
+        Assert.assertFalse("remote buckets contains local bucket", remoteBucketsInStore.containsKey(localAddress));
+        Assert.assertTrue(remoteBucketsInStore.size() == 2);
+
+        //Add a new remote bucket
+        Address a4 = new Address("tcp", "system4");
+        Bucket<T> b4 = new BucketImpl<>(0L, new T());
+        store.updateRemoteBuckets(ImmutableMap.of(a4, b4));
+
+        //Should contain a4
+        //Should contain 4 entries now i.e a1, a2, a4
+        remoteBucketsInStore = store.getRemoteBuckets();
+        Assert.assertTrue("Does not contain a4", remoteBucketsInStore.containsKey(a4));
+        Assert.assertTrue(remoteBucketsInStore.size() == 3);
+
+        //Update a bucket
+        Bucket<T> b3New = new BucketImpl<>(0L, new T());
+        Map<Address, Bucket<?>> remoteBuckets = new HashMap<>(3);
+        remoteBuckets.put(a3, b3New);
+        remoteBuckets.put(a1, null);
+        remoteBuckets.put(a2, null);
+        store.updateRemoteBuckets(remoteBuckets);
+
+        //Should only update a3
+        remoteBucketsInStore = store.getRemoteBuckets();
+        Bucket<T> b3InStore = remoteBucketsInStore.get(a3);
+        Assert.assertEquals(b3New.getVersion(), b3InStore.getVersion());
+
+        //Should NOT update a1 and a2
+        Bucket<T> b1InStore = remoteBucketsInStore.get(a1);
+        Bucket<T> b2InStore = remoteBucketsInStore.get(a2);
+        Assert.assertEquals(b1.getVersion(), b1InStore.getVersion());
+        Assert.assertEquals(b2.getVersion(), b2InStore.getVersion());
+        Assert.assertTrue(remoteBucketsInStore.size() == 4);
+
+        //Should update versions map
+        //versions map contains versions for all remote buckets (4).
+        Map<Address, Long> versionsInStore = store.getVersions();
+        Assert.assertEquals(4, versionsInStore.size());
+        Assert.assertEquals((Long)b1.getVersion(), versionsInStore.get(a1));
+        Assert.assertEquals((Long)b2.getVersion(), versionsInStore.get(a2));
+        Assert.assertEquals((Long)b3New.getVersion(), versionsInStore.get(a3));
+        Assert.assertEquals((Long)b4.getVersion(), versionsInStore.get(a4));
+
+        //Send older version of bucket
+        remoteBuckets.clear();
+        remoteBuckets.put(a3, b3);
+        store.updateRemoteBuckets(remoteBuckets);
+
+        //Should NOT update a3
+        remoteBucketsInStore = store.getRemoteBuckets();
+        b3InStore = remoteBucketsInStore.get(a3);
+        Assert.assertEquals(b3InStore.getVersion(), b3New.getVersion());
 
-        Assert.assertEquals(bucket, mockStore.getLocalBucket());
-        Assert.assertEquals(expectedVersion, mockStore.getLocalBucket().getVersion());
     }
 
     /**
@@ -71,12 +138,28 @@ public class BucketStoreTest {
      *
      * @return instance of BucketStore class
      */
-    private static BucketStore createStore(){
-        TestProbe mockActor = new TestProbe(system);
-        ActorRef mockGossiper = mockActor.ref();
-        final Props props = Props.create(BucketStore.class, mockGossiper);
-        final TestActorRef<BucketStore> testRef = TestActorRef.create(system, props, "testStore");
+    private static BucketStoreActor<T> createStore() {
+        final Props props = Props.create(TestingBucketStoreActor.class,
+                new RemoteOpsProviderConfig(system.settings().config()), "testing-store",new T());
+        return TestActorRef.<BucketStoreActor<T>>create(system, props, "testStore").underlyingActor();
+    }
+
+    private static final class TestingBucketStoreActor extends BucketStoreActor<T> {
+
+        protected TestingBucketStoreActor(final RemoteOpsProviderConfig config,
+                                          final String persistenceId,
+                                          final T initialData) {
+            super(config, persistenceId, initialData);
+        }
+
+        @Override
+        protected void onBucketRemoved(final Address address, final Bucket<T> bucket) {
+
+        }
+
+        @Override
+        protected void onBucketsUpdated(final Map<Address, Bucket<T>> newBuckets) {
 
-        return testRef.underlyingActor();
+        }
     }
-}
\ No newline at end of file
+}