Cache reflection operations in AbstractSchemaAwareTest 32/75332/9
authorRobert Varga <robert.varga@pantheon.tech>
Mon, 20 Aug 2018 16:11:28 +0000 (18:11 +0200)
committerStephen Kitt <skitt@redhat.com>
Wed, 22 Aug 2018 07:44:10 +0000 (07:44 +0000)
The design of AbstractSchemaAwareTest requires reflection-based
loading of SchemaContext for each test case, which is slow.

Instantiate weak caches to speed up tests which are co-located
on the same class loader.

Change-Id: I1a79d7e99f6efcccab37445f3de25a74cb6f02b6
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
14 files changed:
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug1125RegressionTest.java
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug1333DataChangeListenerTest.java
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug1418AugmentationTest.java
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug2562DeserializedUnkeyedListTest.java
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug3090MultiKeyList.java
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/DataTreeChangeListenerTest.java
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/ForwardedNotificationAdapterTest.java
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/ListInsertionDataChangeListenerTest.java
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/AbstractSchemaAwareTest.java
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/ConstantSchemaAbstractDataBrokerTest.java
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/SchemaContextSingleton.java
opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/md/sal/binding/data/WildcardedDataChangeListenerTest.java
opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/DeleteNestedAugmentationListenParentTest.java
opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/WriteParentListenAugmentTest.java

index 1348af1e72b6262a83cd78e2a0501f425df724cf..cf278bd8ab5684d5a20c7896c2955fb81476ee9e 100644 (file)
@@ -5,7 +5,6 @@
  * 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.controller.md.sal.binding.impl.test;
 
 import static org.opendaylight.controller.md.sal.test.model.util.ListsBindingUtils.TOP_FOO_KEY;
@@ -13,6 +12,7 @@ import static org.opendaylight.controller.md.sal.test.model.util.ListsBindingUti
 import static org.opendaylight.controller.md.sal.test.model.util.ListsBindingUtils.topLevelList;
 
 import com.google.common.collect.ImmutableSet;
+import java.util.Set;
 import org.junit.Test;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.binding.test.AbstractDataTreeChangeListenerTest;
@@ -46,7 +46,7 @@ public class Bug1125RegressionTest extends AbstractDataTreeChangeListenerTest {
                     TreeComplexUsesAugment.class);
 
     @Override
-    protected Iterable<YangModuleInfo> getModuleInfos() throws Exception {
+    protected Set<YangModuleInfo> getModuleInfos() throws Exception {
         return ImmutableSet.of(BindingReflections.getModuleInfo(Top.class),
                 BindingReflections.getModuleInfo(TreeComplexUsesAugment.class));
     }
index 90156f1fd82eb7b39f0aac3d033755987966bfb1..1665bef48b79c73a97f2001f25b1354fc3ba1206 100644 (file)
@@ -17,6 +17,7 @@ import static org.opendaylight.controller.md.sal.test.model.util.ListsBindingUti
 import static org.opendaylight.controller.md.sal.test.model.util.ListsBindingUtils.topLevelList;
 
 import com.google.common.collect.ImmutableSet;
+import java.util.Set;
 import org.junit.Test;
 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.opendaylight.controller.md.sal.binding.test.AbstractDataTreeChangeListenerTest;
@@ -44,7 +45,7 @@ public class Bug1333DataChangeListenerTest extends AbstractDataTreeChangeListene
             TOP_PATH.child(TopLevelList.class).augmentation(TreeComplexUsesAugment.class);
 
     @Override
-    protected Iterable<YangModuleInfo> getModuleInfos() throws Exception {
+    protected Set<YangModuleInfo> getModuleInfos() throws Exception {
         return ImmutableSet.of(BindingReflections.getModuleInfo(Top.class),
                 BindingReflections.getModuleInfo(TreeComplexUsesAugment.class));
     }
index 7c114e7ef98d481df4e2361685504b52cc6118ce..f10674226e713a8aee49ee96cd4843ea20c8661a 100644 (file)
@@ -17,6 +17,7 @@ import static org.opendaylight.controller.md.sal.test.model.util.ListsBindingUti
 import static org.opendaylight.controller.md.sal.test.model.util.ListsBindingUtils.topLevelList;
 
 import com.google.common.collect.ImmutableSet;
+import java.util.Set;
 import org.junit.Test;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.binding.test.AbstractDataTreeChangeListenerTest;
@@ -43,7 +44,7 @@ public class Bug1418AugmentationTest extends AbstractDataTreeChangeListenerTest
             new ListViaUsesKey("list key modified");
 
     @Override
-    protected Iterable<YangModuleInfo> getModuleInfos() throws Exception {
+    protected Set<YangModuleInfo> getModuleInfos() throws Exception {
         return ImmutableSet.of(BindingReflections.getModuleInfo(Top.class),
                 BindingReflections.getModuleInfo(TreeComplexUsesAugment.class),
                 BindingReflections.getModuleInfo(TreeLeafOnlyUsesAugment.class));
index 70b43073b2fa70afd61951370e8a5f3aae712c40..bb3fbc2448649e68315c740ed8b52539adb02fa2 100644 (file)
@@ -5,11 +5,11 @@
  * 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.controller.md.sal.binding.impl.test;
 
 import com.google.common.collect.ImmutableSet;
 import java.util.Arrays;
+import java.util.Set;
 import org.junit.Test;
 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.opendaylight.controller.md.sal.binding.test.AbstractDataTreeChangeListenerTest;
@@ -29,7 +29,7 @@ public class Bug2562DeserializedUnkeyedListTest extends AbstractDataTreeChangeLi
     private static final InstanceIdentifier<Root> ROOT_PATH = InstanceIdentifier.create(Root.class);
 
     @Override
-    protected Iterable<YangModuleInfo> getModuleInfos() throws Exception {
+    protected Set<YangModuleInfo> getModuleInfos() throws Exception {
         return ImmutableSet.of(BindingReflections.getModuleInfo(Root.class));
     }
 
index a150d2432cae5d105cd202092eba6b3cbd776f81..bf6f1b288d48d552a157323c28838ee6e1bfb3eb 100644 (file)
@@ -32,7 +32,7 @@ public class Bug3090MultiKeyList extends AbstractDataTreeChangeListenerTest {
     private static final InstanceIdentifier<Root> ROOT_PATH = InstanceIdentifier.create(Root.class);
 
     @Override
-    protected Iterable<YangModuleInfo> getModuleInfos() throws Exception {
+    protected Set<YangModuleInfo> getModuleInfos() throws Exception {
         return ImmutableSet.of(BindingReflections.getModuleInfo(Root.class));
     }
 
@@ -61,7 +61,7 @@ public class Bug3090MultiKeyList extends AbstractDataTreeChangeListenerTest {
         listener.verify();
     }
 
-    private boolean checkData(Root expected, Root actual) {
+    private static boolean checkData(final Root expected, final Root actual) {
         if (actual == null) {
             return false;
         }
index 58176a073c65736fc3a29ef221c08e7fb59f81ab..91d86c1d5907e34a181ea383b47442f602e82c45 100644 (file)
@@ -5,7 +5,6 @@
  * 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.controller.md.sal.binding.impl.test;
 
 import static org.junit.Assert.assertEquals;
@@ -27,6 +26,7 @@ import com.google.common.collect.Iterables;
 import com.google.common.util.concurrent.SettableFuture;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Set;
 import java.util.concurrent.TimeUnit;
 import org.junit.Before;
 import org.junit.Test;
@@ -88,7 +88,7 @@ public class DataTreeChangeListenerTest extends AbstractConcurrentDataBrokerTest
     }
 
     @Override
-    protected Iterable<YangModuleInfo> getModuleInfos() throws Exception {
+    protected Set<YangModuleInfo> getModuleInfos() throws Exception {
         return ImmutableSet.of(
                 BindingReflections.getModuleInfo(TwoLevelList.class),
                 BindingReflections.getModuleInfo(TreeComplexUsesAugment.class)
index 7c65043156075a31a61c4496616e3f7b9629e053..7eef5db4503a0c06c8719f33aac0c0f5843a4361 100644 (file)
@@ -15,6 +15,7 @@ import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Set;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
@@ -39,7 +40,7 @@ public class ForwardedNotificationAdapterTest extends AbstractNotificationBroker
     private static final Logger LOG = LoggerFactory.getLogger(ForwardedNotificationAdapterTest.class);
 
     @Override
-    protected Iterable<YangModuleInfo> getModuleInfos() throws Exception {
+    protected Set<YangModuleInfo> getModuleInfos() throws Exception {
         return ImmutableSet.of(BindingReflections.getModuleInfo(TwoLevelListChanged.class));
 
     }
index 01e5e0e0c3e316b00ce27c2ade5a68a7cefc094e..143cb8e1cbb52bb9e4c58acda8e4fc673e820795 100644 (file)
@@ -45,7 +45,7 @@ public class ListInsertionDataChangeListenerTest extends AbstractDataTreeChangeL
     private static final InstanceIdentifier<TopLevelList> TOP_BAR = TOP.child(TopLevelList.class, TOP_BAR_KEY);
 
     @Override
-    protected Iterable<YangModuleInfo> getModuleInfos() throws Exception {
+    protected Set<YangModuleInfo> getModuleInfos() throws Exception {
         return ImmutableSet.of(BindingReflections.getModuleInfo(Top.class));
     }
 
@@ -160,7 +160,8 @@ public class ListInsertionDataChangeListenerTest extends AbstractDataTreeChangeL
         barListener.verify();
     }
 
-    private Function<DataTreeModification<Top>, Boolean> topSubtreeModified(TopLevelList topFoo, TopLevelList topBar) {
+    private Function<DataTreeModification<Top>, Boolean> topSubtreeModified(final TopLevelList topFoo,
+            final TopLevelList topBar) {
         return match(ModificationType.SUBTREE_MODIFIED, TOP,
             (Function<Top, Boolean>) dataBefore -> Objects.equals(top(topFoo), dataBefore),
             dataAfter -> {
index aebe05dd038f891c83d5a766b5be09f89eef9946..db77bc5799fe494b1a1bc9f091c55569f4b6e813 100644 (file)
@@ -7,23 +7,42 @@
  */
 package org.opendaylight.controller.md.sal.binding.test;
 
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import com.google.common.collect.ImmutableSet;
+import java.util.Set;
 import org.junit.Before;
 import org.opendaylight.mdsal.binding.generator.impl.ModuleInfoBackedContext;
 import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections;
 import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
-public abstract class AbstractSchemaAwareTest  {
+public abstract class AbstractSchemaAwareTest {
+    private static final LoadingCache<ClassLoader, Set<YangModuleInfo>> MODULE_INFO_CACHE = CacheBuilder.newBuilder()
+            .weakKeys().weakValues().build(new CacheLoader<ClassLoader, Set<YangModuleInfo>>() {
+                @Override
+                public Set<YangModuleInfo> load(final ClassLoader key) {
+                    return BindingReflections.loadModuleInfos(key);
+                }
+            });
+    private static final LoadingCache<Set<YangModuleInfo>, SchemaContext> SCHEMA_CONTEXT_CACHE =
+            CacheBuilder.newBuilder().weakValues().build(new CacheLoader<Set<YangModuleInfo>, SchemaContext>() {
+                @Override
+                public SchemaContext load(final Set<YangModuleInfo> key) {
+                    final ModuleInfoBackedContext moduleContext = ModuleInfoBackedContext.create();
+                    moduleContext.addModuleInfos(key);
+                    return moduleContext.tryToCreateSchemaContext().get();
+                }
+            });
 
-    protected Iterable<YangModuleInfo> getModuleInfos() throws Exception {
-        return BindingReflections.loadModuleInfos();
+    protected Set<YangModuleInfo> getModuleInfos() throws Exception {
+        return MODULE_INFO_CACHE.getUnchecked(Thread.currentThread().getContextClassLoader());
     }
 
     protected SchemaContext getSchemaContext() throws Exception {
-        final Iterable<YangModuleInfo> moduleInfos = getModuleInfos();
-        final ModuleInfoBackedContext moduleContext = ModuleInfoBackedContext.create();
-        moduleContext.addModuleInfos(moduleInfos);
-        return moduleContext.tryToCreateSchemaContext().get();
+        // ImmutableSet guarantees non-null
+        return SCHEMA_CONTEXT_CACHE.getUnchecked(ImmutableSet.copyOf(getModuleInfos()));
     }
 
     @Before
index 7e245a3b15c079422864aaf5b00cc9221fef1fe8..93f15b70e9ed1ad7c2b87dbf01278ee778fce55f 100644 (file)
@@ -15,7 +15,10 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext;
  * it for each Test, and is thus faster.
  *
  * @author Michael Vorburger
+ * @deprecated This class is no longer useful, as {@link AbstractSchemaAwareTest#getSchemaContext()} provides effective
+ *             caching.
  */
+@Deprecated
 public class ConstantSchemaAbstractDataBrokerTest extends AbstractConcurrentDataBrokerTest {
 
     public ConstantSchemaAbstractDataBrokerTest() {
index 49eb5aaf5cb400a381e245eb189f64a1a8b23810..32f84a85081b4c33e702f1fd06cc274efb3de4b2 100644 (file)
@@ -17,12 +17,14 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext;
  * SchemaContext.
  *
  * @author Michael Vorburger
+ * @deprecated This class should not be used, as it pollutes the classpath.
  */
+@Deprecated
 public final class SchemaContextSingleton {
 
     private static SchemaContext staticSchemaContext;
 
-    public static synchronized SchemaContext getSchemaContext(Supplier<SchemaContext> supplier) throws Exception {
+    public static synchronized SchemaContext getSchemaContext(final Supplier<SchemaContext> supplier) throws Exception {
         if (staticSchemaContext == null) {
             staticSchemaContext = supplier.get();
         }
index ff6d02bb9abb93ce88c8165f1b4d69cea1c17fb2..4f11c50e53ddd656749afd6e4913395ec5431ee7 100644 (file)
@@ -13,6 +13,7 @@ import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastor
 import com.google.common.collect.ImmutableSet;
 import com.google.common.util.concurrent.Uninterruptibles;
 import java.util.Collections;
+import java.util.Set;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
@@ -80,7 +81,7 @@ public class WildcardedDataChangeListenerTest extends AbstractDataTreeChangeList
             .withKey(LIST_VIA_USES_KEY).setName("john").build();
 
     @Override
-    protected Iterable<YangModuleInfo> getModuleInfos() throws Exception {
+    protected Set<YangModuleInfo> getModuleInfos() throws Exception {
         return ImmutableSet.of(BindingReflections.getModuleInfo(Top.class),
                 BindingReflections.getModuleInfo(TreeComplexUsesAugment.class));
     }
index d91267454aea067254771d13eb00b40b24478057..81d7e9dc619e2484aabe1e11fbd82eab51c8e29f 100644 (file)
@@ -5,10 +5,10 @@
  * 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.controller.sal.binding.test.bugfix;
 
 import com.google.common.collect.ImmutableSet;
+import java.util.Set;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
@@ -52,7 +52,7 @@ public class DeleteNestedAugmentationListenParentTest extends AbstractDataTreeCh
             .build();
 
     @Override
-    protected Iterable<YangModuleInfo> getModuleInfos() throws Exception {
+    protected Set<YangModuleInfo> getModuleInfos() throws Exception {
         return ImmutableSet.of(BindingReflections.getModuleInfo(Top.class),
                 BindingReflections.getModuleInfo(List11SimpleAugment.class));
     }
index d05e0b64ffebf45c874035a82017b7ea8fe16ac6..09836147f2d6b44555493b9ff728df510c42b628 100644 (file)
@@ -11,6 +11,7 @@ import static org.junit.Assert.assertEquals;
 import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.OPERATIONAL;
 
 import com.google.common.collect.ImmutableSet;
+import java.util.Set;
 import java.util.concurrent.TimeUnit;
 import org.junit.Test;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
@@ -42,7 +43,7 @@ public class WriteParentListenAugmentTest extends AbstractDataTreeChangeListener
             .builder(Top.class).child(TopLevelList.class, TLL_KEY).augmentation(TreeComplexUsesAugment.class).build();
 
     @Override
-    protected Iterable<YangModuleInfo> getModuleInfos() throws Exception {
+    protected Set<YangModuleInfo> getModuleInfos() throws Exception {
         return ImmutableSet.of(BindingReflections.getModuleInfo(Top.class),
                 BindingReflections.getModuleInfo(TreeComplexUsesAugment.class));
     }