Fix intermittent ShardTest failures
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / test / java / org / opendaylight / controller / cluster / datastore / utils / MockDataTreeChangeListener.java
index d06fc435720fca6d40f0b7cb54e33f64b8307c8a..0696fcf832c9a3ff81fe7027cfb46b0618df2feb 100644 (file)
@@ -7,25 +7,27 @@
  */
 package org.opendaylight.controller.cluster.datastore.utils;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.fail;
 import com.google.common.collect.Lists;
 import com.google.common.util.concurrent.Uninterruptibles;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeChangeListener;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
-
-import javax.annotation.Nonnull;
+import java.util.Arrays;
 import java.util.Collection;
-import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
+import javax.annotation.Nonnull;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeChangeListener;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
 
 public class MockDataTreeChangeListener implements DOMDataTreeChangeListener {
 
     private final List<Collection<DataTreeCandidate>> changeList =
-            Collections.synchronizedList(Lists.<Collection<DataTreeCandidate>>newArrayList());
+            Lists.<Collection<DataTreeCandidate>>newArrayList();
 
     private volatile CountDownLatch changeLatch;
     private int expChangeEventCount;
@@ -37,12 +39,16 @@ public class MockDataTreeChangeListener implements DOMDataTreeChangeListener {
     public void reset(int expChangeEventCount) {
         changeLatch = new CountDownLatch(expChangeEventCount);
         this.expChangeEventCount = expChangeEventCount;
-        changeList.clear();
+        synchronized(changeList) {
+            changeList.clear();
+        }
     }
 
     @Override
     public void onDataTreeChanged(@Nonnull final Collection<DataTreeCandidate> changes) {
-        changeList.add(changes);
+        synchronized(changeList) {
+            changeList.add(changes);
+        }
         changeLatch.countDown();
     }
 
@@ -54,8 +60,37 @@ public class MockDataTreeChangeListener implements DOMDataTreeChangeListener {
         }
     }
 
+    public void verifyNotifiedData(YangInstanceIdentifier... paths) {
+        Set<YangInstanceIdentifier> pathSet = new HashSet<>(Arrays.asList(paths));
+        synchronized(changeList) {
+            for(Collection<DataTreeCandidate> list: changeList) {
+                for(DataTreeCandidate c: list) {
+                    pathSet.remove(c.getRootPath());
+                }
+            }
+        }
+
+        if(!pathSet.isEmpty()) {
+            fail(pathSet + " not present in " + changeList);
+        }
+    }
+
     public void expectNoMoreChanges(String assertMsg) {
-        Uninterruptibles.sleepUninterruptibly(1, TimeUnit.SECONDS);
-        assertEquals(assertMsg, expChangeEventCount, changeList.size());
+        Uninterruptibles.sleepUninterruptibly(500, TimeUnit.MILLISECONDS);
+        synchronized(changeList) {
+            assertEquals(assertMsg, expChangeEventCount, changeList.size());
+        }
+    }
+
+    public void verifyNoNotifiedData(YangInstanceIdentifier... paths) {
+        Set<YangInstanceIdentifier> pathSet = new HashSet<>(Arrays.asList(paths));
+        synchronized(changeList) {
+            for(Collection<DataTreeCandidate> list: changeList) {
+                for(DataTreeCandidate c: list) {
+                    assertFalse("Unexpected " + c.getRootPath() + " present in DataTreeCandidate",
+                            pathSet.contains(c.getRootPath()));
+                }
+            }
+        }
     }
 }