From 1e50fbad8d8605b73d5b2be8f5ae30b437b33780 Mon Sep 17 00:00:00 2001 From: Tom Pantelis Date: Thu, 6 Jul 2017 08:30:28 -0400 Subject: [PATCH] Bug 8163: Use MT DTCL executor in AbstractConcurrentDataBrokerTest Using a direct executor can cause deadlocks so the DTCL executor was made configurable to use a threadpool as an opt-in. Direct executor is still the default as many existing tests would break. Change-Id: I41e14f1e6d3b77a44e61dfc75abff29d11a777dc Signed-off-by: Tom Pantelis --- .../impl/test/Bug1125RegressionTest.java | 4 +-- .../test/Bug1333DataChangeListenerTest.java | 8 ++--- .../impl/test/Bug1418AugmentationTest.java | 26 ++++++-------- .../Bug2562DeserializedUnkeyedListTest.java | 3 +- .../impl/test/Bug3090MultiKeyList.java | 5 ++- .../ListInsertionDataChangeListenerTest.java | 28 +++++++-------- .../AbstractConcurrentDataBrokerTest.java | 16 ++++++++- .../AbstractDataBrokerTestCustomizer.java | 11 ++++-- .../test/AbstractDataChangeListenerTest.java | 36 ++++++++++++++----- .../ConcurrentDataBrokerTestCustomizer.java | 7 +++- .../test/DataBrokerTestCustomizer.java | 1 - 11 files changed, 88 insertions(+), 57 deletions(-) diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug1125RegressionTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug1125RegressionTest.java index 7f5d36f35e..9f9276954b 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug1125RegressionTest.java +++ b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug1125RegressionTest.java @@ -76,9 +76,7 @@ public class Bug1125RegressionTest extends AbstractDataChangeListenerTest { private void deleteAndListenAugment(final DataChangeScope scope, final InstanceIdentifier path) { writeInitialState(); - TestListener listener = createListener( - LogicalDatastoreType.OPERATIONAL, WILDCARDED_AUGMENT_PATH, - scope); + TestListener listener = createListener(LogicalDatastoreType.OPERATIONAL, WILDCARDED_AUGMENT_PATH, scope, false); delete(path); verifyRemoved(listener.event()); } diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug1333DataChangeListenerTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug1333DataChangeListenerTest.java index 60d56db581..e7b03d9b14 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug1333DataChangeListenerTest.java +++ b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug1333DataChangeListenerTest.java @@ -62,8 +62,7 @@ public class Bug1333DataChangeListenerTest extends AbstractDataChangeListenerTes @Test public void writeTopWithListItemAugmentedListenTopSubtree() { - TestListener listener = createListener(CONFIGURATION,TOP_PATH, DataChangeScope.SUBTREE); - listener.startCapture(); + TestListener listener = createListener(CONFIGURATION,TOP_PATH, DataChangeScope.SUBTREE, false); writeTopWithListItem(CONFIGURATION); @@ -81,8 +80,7 @@ public class Bug1333DataChangeListenerTest extends AbstractDataChangeListenerTes @Test public void writeTopWithListItemAugmentedListenAugmentSubtreeWildcarded() { - TestListener listener = createListener(CONFIGURATION,AUGMENT_WILDCARD, DataChangeScope.SUBTREE); - listener.startCapture(); + TestListener listener = createListener(CONFIGURATION,AUGMENT_WILDCARD, DataChangeScope.SUBTREE, false); writeTopWithListItem(CONFIGURATION); AsyncDataChangeEvent, DataObject> event = listener.event(); @@ -125,7 +123,7 @@ public class Bug1333DataChangeListenerTest extends AbstractDataChangeListenerTes public void deleteAugmentChildListenAugmentSubtreeWildcarded() { writeTopWithListItem(CONFIGURATION); - TestListener listener = createListener(CONFIGURATION, AUGMENT_WILDCARD, DataChangeScope.SUBTREE); + TestListener listener = createListener(CONFIGURATION, AUGMENT_WILDCARD, DataChangeScope.SUBTREE, false); InstanceIdentifier deletePath = path(TOP_FOO_KEY,USES_ONE_KEY); deleteItem(CONFIGURATION,deletePath); AsyncDataChangeEvent, DataObject> event = listener.event(); diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug1418AugmentationTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug1418AugmentationTest.java index fe32fa9d18..4393dcc5ef 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug1418AugmentationTest.java +++ b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug1418AugmentationTest.java @@ -8,6 +8,14 @@ package org.opendaylight.controller.md.sal.binding.impl.test; +import static org.opendaylight.controller.md.sal.binding.test.AssertCollections.assertContains; +import static org.opendaylight.controller.md.sal.binding.test.AssertCollections.assertEmpty; +import static org.opendaylight.controller.md.sal.test.model.util.ListsBindingUtils.TOP_FOO_KEY; +import static org.opendaylight.controller.md.sal.test.model.util.ListsBindingUtils.complexUsesAugment; +import static org.opendaylight.controller.md.sal.test.model.util.ListsBindingUtils.leafOnlyUsesAugment; +import static org.opendaylight.controller.md.sal.test.model.util.ListsBindingUtils.top; +import static org.opendaylight.controller.md.sal.test.model.util.ListsBindingUtils.topLevelList; + import org.junit.Test; import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; import org.opendaylight.controller.md.sal.binding.test.AbstractDataChangeListenerTest; @@ -24,15 +32,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controll import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import static org.junit.Assert.assertTrue; -import static org.opendaylight.controller.md.sal.binding.test.AssertCollections.assertContains; -import static org.opendaylight.controller.md.sal.binding.test.AssertCollections.assertEmpty; -import static org.opendaylight.controller.md.sal.test.model.util.ListsBindingUtils.top; -import static org.opendaylight.controller.md.sal.test.model.util.ListsBindingUtils.TOP_FOO_KEY; -import static org.opendaylight.controller.md.sal.test.model.util.ListsBindingUtils.topLevelList; -import static org.opendaylight.controller.md.sal.test.model.util.ListsBindingUtils.leafOnlyUsesAugment; -import static org.opendaylight.controller.md.sal.test.model.util.ListsBindingUtils.complexUsesAugment; - public class Bug1418AugmentationTest extends AbstractDataChangeListenerTest{ private static final InstanceIdentifier TOP = InstanceIdentifier.create(Top.class); private static final InstanceIdentifier TOP_FOO = TOP.child(TopLevelList.class, TOP_FOO_KEY); @@ -48,13 +47,12 @@ public class Bug1418AugmentationTest extends AbstractDataChangeListenerTest{ @Test public void leafOnlyAugmentationCreatedTest() { TestListener listener = createListener(LogicalDatastoreType.CONFIGURATION, SIMPLE_AUGMENT, - AsyncDataBroker.DataChangeScope.SUBTREE); + AsyncDataBroker.DataChangeScope.SUBTREE, false); WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction(); writeTx.put(LogicalDatastoreType.CONFIGURATION, TOP, top()); writeTx.put(LogicalDatastoreType.CONFIGURATION, TOP_FOO, topLevelList(new TopLevelListKey(TOP_FOO_KEY))); writeTx.put(LogicalDatastoreType.CONFIGURATION, SIMPLE_AUGMENT, leafOnlyUsesAugment("test leaf")); assertCommit(writeTx.submit()); - assertTrue(listener.hasEvent()); AsyncDataChangeEvent, DataObject> event = listener.event(); assertContains(event.getCreatedData(), SIMPLE_AUGMENT); assertEmpty(event.getUpdatedData()); @@ -74,7 +72,6 @@ public class Bug1418AugmentationTest extends AbstractDataChangeListenerTest{ writeTx = getDataBroker().newWriteOnlyTransaction(); writeTx.put(LogicalDatastoreType.CONFIGURATION, SIMPLE_AUGMENT, leafOnlyUsesAugment("test leaf changed")); assertCommit(writeTx.submit()); - assertTrue(listener.hasEvent()); AsyncDataChangeEvent, DataObject> event = listener.event(); assertContains(event.getUpdatedData(), SIMPLE_AUGMENT); assertContains(event.getOriginalData(), SIMPLE_AUGMENT); @@ -94,7 +91,6 @@ public class Bug1418AugmentationTest extends AbstractDataChangeListenerTest{ writeTx = getDataBroker().newWriteOnlyTransaction(); writeTx.delete(LogicalDatastoreType.CONFIGURATION, SIMPLE_AUGMENT); assertCommit(writeTx.submit()); - assertTrue(listener.hasEvent()); AsyncDataChangeEvent, DataObject> event = listener.event(); assertContains(event.getRemovedPaths(), SIMPLE_AUGMENT); assertContains(event.getOriginalData(), SIMPLE_AUGMENT); @@ -105,13 +101,12 @@ public class Bug1418AugmentationTest extends AbstractDataChangeListenerTest{ @Test public void complexAugmentationCreatedTest() { TestListener listener = createListener(LogicalDatastoreType.CONFIGURATION, COMPLEX_AUGMENT, - AsyncDataBroker.DataChangeScope.SUBTREE); + AsyncDataBroker.DataChangeScope.SUBTREE, false); WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction(); writeTx.put(LogicalDatastoreType.CONFIGURATION, TOP, top()); writeTx.put(LogicalDatastoreType.CONFIGURATION, TOP_FOO, topLevelList(new TopLevelListKey(TOP_FOO_KEY))); writeTx.put(LogicalDatastoreType.CONFIGURATION, COMPLEX_AUGMENT, complexUsesAugment(LIST_VIA_USES_KEY)); assertCommit(writeTx.submit()); - assertTrue(listener.hasEvent()); AsyncDataChangeEvent, DataObject> event = listener.event(); assertContains(event.getCreatedData(), COMPLEX_AUGMENT); assertContains(event.getCreatedData(), COMPLEX_AUGMENT.child(ListViaUses.class, LIST_VIA_USES_KEY)); @@ -132,7 +127,6 @@ public class Bug1418AugmentationTest extends AbstractDataChangeListenerTest{ writeTx = getDataBroker().newWriteOnlyTransaction(); writeTx.put(LogicalDatastoreType.CONFIGURATION, COMPLEX_AUGMENT, complexUsesAugment(LIST_VIA_USES_KEY_MOD)); assertCommit(writeTx.submit()); - assertTrue(listener.hasEvent()); AsyncDataChangeEvent, DataObject> event = listener.event(); assertContains(event.getUpdatedData(), COMPLEX_AUGMENT); assertContains(event.getCreatedData(), COMPLEX_AUGMENT.child(ListViaUses.class, LIST_VIA_USES_KEY_MOD)); diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug2562DeserializedUnkeyedListTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug2562DeserializedUnkeyedListTest.java index 1d4a708f4f..94d727287c 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug2562DeserializedUnkeyedListTest.java +++ b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug2562DeserializedUnkeyedListTest.java @@ -49,8 +49,7 @@ public class Bug2562DeserializedUnkeyedListTest extends AbstractDataChangeListen @Test public void writeListToList2562Root() { final AbstractDataChangeListenerTest.TestListener listenerRoot = createListener(LogicalDatastoreType.CONFIGURATION, - ROOT_PATH, AsyncDataBroker.DataChangeScope.ONE); - listenerRoot.startCapture(); + ROOT_PATH, AsyncDataBroker.DataChangeScope.ONE, false); writeRoot(LogicalDatastoreType.CONFIGURATION); final AsyncDataChangeEvent, DataObject> eventRoot = listenerRoot.event(); diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug3090MultiKeyList.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug3090MultiKeyList.java index 83bb6a4414..1efa3a7a6c 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug3090MultiKeyList.java +++ b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug3090MultiKeyList.java @@ -49,8 +49,7 @@ public class Bug3090MultiKeyList extends AbstractDataChangeListenerTest{ @Test public void listWithMultiKeyTest() { final AbstractDataChangeListenerTest.TestListener listener = createListener(CONFIGURATION, ROOT_PATH, - AsyncDataBroker.DataChangeScope.BASE); - listener.startCapture(); + AsyncDataBroker.DataChangeScope.BASE, false); write(CONFIGURATION); final AsyncDataChangeEvent, DataObject> event = listener.event(); @@ -59,4 +58,4 @@ public class Bug3090MultiKeyList extends AbstractDataChangeListenerTest{ assertEmpty(event.getUpdatedData()); assertEmpty(event.getRemovedPaths()); } -} \ No newline at end of file +} diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/ListInsertionDataChangeListenerTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/ListInsertionDataChangeListenerTest.java index 0bc73824bf..b2451391bc 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/ListInsertionDataChangeListenerTest.java +++ b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/ListInsertionDataChangeListenerTest.java @@ -31,9 +31,9 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; /** * This testsuite tests explanation for data change scope and data modifications * which were described in - * https://lists.opendaylight.org/pipermail/controller-dev/2014-July/005541.html + * https://lists.opendaylight.org/pipermail/controller-dev/2014-July/005541.html. */ -public class ListInsertionDataChangeListenerTest extends AbstractDataChangeListenerTest{ +public class ListInsertionDataChangeListenerTest extends AbstractDataChangeListenerTest { private static final InstanceIdentifier TOP = InstanceIdentifier.create(Top.class); private static final InstanceIdentifier WILDCARDED = TOP.child(TopLevelList.class); @@ -50,17 +50,17 @@ public class ListInsertionDataChangeListenerTest extends AbstractDataChangeListe @Test public void replaceTopNodeSubtreeListeners() { TestListener topListener = createListener(CONFIGURATION, TOP, DataChangeScope.SUBTREE); - TestListener allListener = createListener(CONFIGURATION, WILDCARDED, DataChangeScope.SUBTREE); + TestListener allListener = createListener(CONFIGURATION, WILDCARDED, DataChangeScope.SUBTREE, false); TestListener fooListener = createListener(CONFIGURATION, TOP_FOO, DataChangeScope.SUBTREE); - TestListener barListener = createListener(CONFIGURATION, TOP_BAR, DataChangeScope.SUBTREE); + TestListener barListener = createListener(CONFIGURATION, TOP_BAR, DataChangeScope.SUBTREE, false); ReadWriteTransaction writeTx = getDataBroker().newReadWriteTransaction(); writeTx.put(CONFIGURATION, TOP, top(topLevelList(TOP_BAR_KEY))); assertCommit(writeTx.submit()); - AsyncDataChangeEvent, DataObject> top = topListener.event(); - AsyncDataChangeEvent, DataObject> all = allListener.event(); - AsyncDataChangeEvent, DataObject> foo = fooListener.event(); - AsyncDataChangeEvent, DataObject> bar = barListener.event(); + final AsyncDataChangeEvent, DataObject> top = topListener.event(); + final AsyncDataChangeEvent, DataObject> all = allListener.event(); + final AsyncDataChangeEvent, DataObject> foo = fooListener.event(); + final AsyncDataChangeEvent, DataObject> bar = barListener.event(); // Listener for TOP element assertContains(top.getOriginalData(), TOP,TOP_FOO); @@ -105,9 +105,9 @@ public class ListInsertionDataChangeListenerTest extends AbstractDataChangeListe @Test public void mergeTopNodeSubtreeListeners() { TestListener topListener = createListener(CONFIGURATION, TOP, DataChangeScope.SUBTREE); - TestListener allListener = createListener(CONFIGURATION, WILDCARDED, DataChangeScope.SUBTREE); + TestListener allListener = createListener(CONFIGURATION, WILDCARDED, DataChangeScope.SUBTREE, false); TestListener fooListener = createListener(CONFIGURATION, TOP_FOO, DataChangeScope.SUBTREE); - TestListener barListener = createListener(CONFIGURATION, TOP_BAR, DataChangeScope.SUBTREE); + TestListener barListener = createListener(CONFIGURATION, TOP_BAR, DataChangeScope.SUBTREE, false); ReadWriteTransaction writeTx = getDataBroker().newReadWriteTransaction(); writeTx.merge(CONFIGURATION, TOP, top(topLevelList(TOP_BAR_KEY))); @@ -119,9 +119,9 @@ public class ListInsertionDataChangeListenerTest extends AbstractDataChangeListe @Test public void putTopBarNodeSubtreeListeners() { TestListener topListener = createListener(CONFIGURATION, TOP, DataChangeScope.SUBTREE); - TestListener allListener = createListener(CONFIGURATION, WILDCARDED, DataChangeScope.SUBTREE); + TestListener allListener = createListener(CONFIGURATION, WILDCARDED, DataChangeScope.SUBTREE, false); TestListener fooListener = createListener(CONFIGURATION, TOP_FOO, DataChangeScope.SUBTREE); - TestListener barListener = createListener(CONFIGURATION, TOP_BAR, DataChangeScope.SUBTREE); + TestListener barListener = createListener(CONFIGURATION, TOP_BAR, DataChangeScope.SUBTREE, false); ReadWriteTransaction writeTx = getDataBroker().newReadWriteTransaction(); writeTx.put(CONFIGURATION, TOP_BAR, topLevelList(TOP_BAR_KEY)); @@ -133,9 +133,9 @@ public class ListInsertionDataChangeListenerTest extends AbstractDataChangeListe @Test public void mergeTopBarNodeSubtreeListeners() { TestListener topListener = createListener(CONFIGURATION, TOP, DataChangeScope.SUBTREE); - TestListener allListener = createListener(CONFIGURATION, WILDCARDED, DataChangeScope.SUBTREE); + TestListener allListener = createListener(CONFIGURATION, WILDCARDED, DataChangeScope.SUBTREE, false); TestListener fooListener = createListener(CONFIGURATION, TOP_FOO, DataChangeScope.SUBTREE); - TestListener barListener = createListener(CONFIGURATION, TOP_BAR, DataChangeScope.SUBTREE); + TestListener barListener = createListener(CONFIGURATION, TOP_BAR, DataChangeScope.SUBTREE, false); ReadWriteTransaction writeTx = getDataBroker().newReadWriteTransaction(); writeTx.merge(CONFIGURATION, TOP_BAR, topLevelList(TOP_BAR_KEY)); diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/AbstractConcurrentDataBrokerTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/AbstractConcurrentDataBrokerTest.java index 3239850f2f..77c0c3f83f 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/AbstractConcurrentDataBrokerTest.java +++ b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/AbstractConcurrentDataBrokerTest.java @@ -19,10 +19,24 @@ package org.opendaylight.controller.md.sal.binding.test; * @author Michael Vorburger */ public abstract class AbstractConcurrentDataBrokerTest extends AbstractBaseDataBrokerTest { + private final boolean useMTDataTreeChangeListenerExecutor; + + protected AbstractConcurrentDataBrokerTest() { + this(false); + } + + protected AbstractConcurrentDataBrokerTest(final boolean useMTDataTreeChangeListenerExecutor) { + this.useMTDataTreeChangeListenerExecutor = useMTDataTreeChangeListenerExecutor; + } @Override protected AbstractDataBrokerTestCustomizer createDataBrokerTestCustomizer() { - return new ConcurrentDataBrokerTestCustomizer(); + ConcurrentDataBrokerTestCustomizer customizer = new ConcurrentDataBrokerTestCustomizer(); + if (useMTDataTreeChangeListenerExecutor) { + customizer.useMTDataTreeChangeListenerExecutor(); + } + + return customizer; } } diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/AbstractDataBrokerTestCustomizer.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/AbstractDataBrokerTestCustomizer.java index 02f3257b65..8d968b0a01 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/AbstractDataBrokerTestCustomizer.java +++ b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/AbstractDataBrokerTestCustomizer.java @@ -10,6 +10,7 @@ package org.opendaylight.controller.md.sal.binding.test; import com.google.common.collect.ImmutableMap; import com.google.common.util.concurrent.ListeningExecutorService; import com.google.common.util.concurrent.MoreExecutors; +import javassist.ClassPool; import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService; import org.opendaylight.controller.md.sal.binding.api.NotificationService; @@ -31,7 +32,6 @@ import org.opendaylight.yangtools.binding.data.codec.gen.impl.DataObjectSerializ import org.opendaylight.yangtools.binding.data.codec.gen.impl.StreamWriterGenerator; import org.opendaylight.yangtools.binding.data.codec.impl.BindingNormalizedNodeCodecRegistry; import org.opendaylight.yangtools.yang.model.api.SchemaContext; -import javassist.ClassPool; public abstract class AbstractDataBrokerTestCustomizer { @@ -40,6 +40,7 @@ public abstract class AbstractDataBrokerTestCustomizer { private final MockSchemaService schemaService; private ImmutableMap datastores; private final BindingToNormalizedNodeCodec bindingToNormalized; + private ListeningExecutorService dataTreeChangeListenerExecutor = MoreExecutors.newDirectExecutorService(); public ImmutableMap createDatastores() { return ImmutableMap.builder() @@ -60,13 +61,13 @@ public abstract class AbstractDataBrokerTestCustomizer { } public DOMStore createConfigurationDatastore() { - final InMemoryDOMDataStore store = new InMemoryDOMDataStore("CFG", MoreExecutors.newDirectExecutorService()); + final InMemoryDOMDataStore store = new InMemoryDOMDataStore("CFG", dataTreeChangeListenerExecutor); this.schemaService.registerSchemaContextListener(store); return store; } public DOMStore createOperationalDatastore() { - final InMemoryDOMDataStore store = new InMemoryDOMDataStore("OPER", MoreExecutors.newDirectExecutorService()); + final InMemoryDOMDataStore store = new InMemoryDOMDataStore("OPER", dataTreeChangeListenerExecutor); this.schemaService.registerSchemaContextListener(store); return store; } @@ -111,6 +112,10 @@ public abstract class AbstractDataBrokerTestCustomizer { return this.datastores; } + public void setDataTreeChangeListenerExecutor(ListeningExecutorService executor) { + this.dataTreeChangeListenerExecutor = executor; + } + public void updateSchema(final SchemaContext ctx) { this.schemaService.changeSchema(ctx); } diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/AbstractDataChangeListenerTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/AbstractDataChangeListenerTest.java index a82df937fd..2a5c0e8332 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/AbstractDataChangeListenerTest.java +++ b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/AbstractDataChangeListenerTest.java @@ -7,10 +7,13 @@ */ package org.opendaylight.controller.md.sal.binding.test; +import static org.junit.Assert.assertTrue; + +import com.google.common.util.concurrent.SettableFuture; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; - import org.opendaylight.controller.md.sal.binding.api.DataChangeListener; import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope; import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent; @@ -18,23 +21,25 @@ import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import com.google.common.util.concurrent.SettableFuture; - public abstract class AbstractDataChangeListenerTest extends AbstractConcurrentDataBrokerTest { protected static final class TestListener implements DataChangeListener { private final SettableFuture, DataObject>> event; - private boolean capture = false; + private final CountDownLatch initialEventLatch; + private volatile boolean capture = false; - private TestListener() { + private TestListener(boolean expectInitialEvent) { event = SettableFuture.create(); + initialEventLatch = new CountDownLatch(expectInitialEvent ? 1 : 0); } @Override public void onDataChanged(final AsyncDataChangeEvent, DataObject> arg) { if (capture) { event.set(arg); + } else { + initialEventLatch.countDown(); } } @@ -50,16 +55,31 @@ public abstract class AbstractDataChangeListenerTest extends AbstractConcurrentD return event.isDone(); } - public void startCapture() { + private void waitForInitialEvent() { + try { + assertTrue("Initial DataChangeEvent was not received", initialEventLatch.await(3, TimeUnit.SECONDS)); + } catch (InterruptedException e) { + throw new IllegalStateException(e); + } + this.capture = true; } } + protected AbstractDataChangeListenerTest() { + super(true); + } + protected final TestListener createListener(final LogicalDatastoreType store, final InstanceIdentifier path, final DataChangeScope scope) { - TestListener listener = new TestListener(); + return createListener(store, path, scope, true); + } + + protected final TestListener createListener(final LogicalDatastoreType store, final InstanceIdentifier path, + final DataChangeScope scope, boolean expectInitialEvent) { + TestListener listener = new TestListener(expectInitialEvent); getDataBroker().registerDataChangeListener(store, path, listener, scope); - listener.startCapture(); + listener.waitForInitialEvent(); return listener; } } diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/ConcurrentDataBrokerTestCustomizer.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/ConcurrentDataBrokerTestCustomizer.java index c8dba37441..0b2de070f8 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/ConcurrentDataBrokerTestCustomizer.java +++ b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/ConcurrentDataBrokerTestCustomizer.java @@ -14,7 +14,8 @@ import java.util.concurrent.Executors; /** * ConcurrentDataBrokerTestCustomizer. * - *

See {@link AbstractConcurrentDataBrokerTest} and bug 7538 for more details & background. + *

See {@link AbstractConcurrentDataBrokerTest} and + * bug 7538 for more details & background. * * @author Michael Vorburger */ @@ -24,4 +25,8 @@ public class ConcurrentDataBrokerTestCustomizer extends AbstractDataBrokerTestCu public ListeningExecutorService getCommitCoordinatorExecutor() { return MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor()); } + + public void useMTDataTreeChangeListenerExecutor() { + setDataTreeChangeListenerExecutor(MoreExecutors.listeningDecorator(Executors.newCachedThreadPool())); + } } diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/DataBrokerTestCustomizer.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/DataBrokerTestCustomizer.java index 8c7bf207cc..e037de452b 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/DataBrokerTestCustomizer.java +++ b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/DataBrokerTestCustomizer.java @@ -23,5 +23,4 @@ public class DataBrokerTestCustomizer extends AbstractDataBrokerTestCustomizer { public ListeningExecutorService getCommitCoordinatorExecutor() { return MoreExecutors.newDirectExecutorService(); } - } -- 2.36.6