ConstantSchemaAbstractDataBrokerTest, faster than AbstractDataBrokerTest 70/47770/10
authorMichael Vorburger <vorburger@redhat.com>
Thu, 27 Oct 2016 17:27:36 +0000 (19:27 +0200)
committerTom Pantelis <tpanteli@brocade.com>
Wed, 30 Nov 2016 00:06:01 +0000 (00:06 +0000)
In something like AclServiceTest, of which I'm going to be writing a lot
more shortly, which runs e.g. 7 @Test methods under a fresh DataBroker,
there is no need to re-re-re-re do the bloody slow creation of
SchemaContext every time (because its content is based on the classpath,
wihch is fixed for a given single test).

This optimization approx. halfs the time e.g. for AclServiceTest, from
ca. 30s to ca. 15s.

Implemented on the train & ferry traveling back from EclipseCon ;)

Change-Id: Ic47f8abf9833bafcce13655b46cbce3e02aed050
Signed-off-by: Michael Vorburger <vorburger@redhat.com>
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/AbstractDataBrokerTest.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 [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/DataBrokerTestModule.java
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/SchemaContextSingleton.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/tests/DataBrokerTestModuleTest.java

index 5789270dee4e60953e5d7e4805bacffcbb96b6e4..828ba2c0c0fc84bfff2fd56a6f84317e21c7e5b2 100644 (file)
@@ -37,7 +37,7 @@ public class AbstractDataBrokerTest extends AbstractSchemaAwareTest {
         // Intentionally left No-op, subclasses may customize it
     }
 
         // Intentionally left No-op, subclasses may customize it
     }
 
-   protected DataBrokerTestCustomizer createDataBrokerTestCustomizer() {
+    protected DataBrokerTestCustomizer createDataBrokerTestCustomizer() {
         return new DataBrokerTestCustomizer();
     }
 
         return new DataBrokerTestCustomizer();
     }
 
index 6d758aa7bd7a651f585314be5b81b86c03279433..21f806508fb12e286d17826d368b649e738147b6 100644 (file)
@@ -15,29 +15,25 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
 public abstract class AbstractSchemaAwareTest  {
 
 
 public abstract class AbstractSchemaAwareTest  {
 
-    private Iterable<YangModuleInfo> moduleInfos;
-    private SchemaContext schemaContext;
-
-
     protected Iterable<YangModuleInfo> getModuleInfos() throws Exception {
         return BindingReflections.loadModuleInfos();
     }
 
     protected Iterable<YangModuleInfo> getModuleInfos() throws Exception {
         return BindingReflections.loadModuleInfos();
     }
 
+    protected SchemaContext getSchemaContext() throws Exception {
+        Iterable<YangModuleInfo> moduleInfos = getModuleInfos();
+        ModuleInfoBackedContext moduleContext = ModuleInfoBackedContext.create();
+        moduleContext.addModuleInfos(moduleInfos);
+        return moduleContext.tryToCreateSchemaContext().get();
+    }
 
     @Before
     public final void setup() throws Exception {
 
     @Before
     public final void setup() throws Exception {
-        moduleInfos = getModuleInfos();
-        ModuleInfoBackedContext moduleContext = ModuleInfoBackedContext.create();
-        moduleContext.addModuleInfos(moduleInfos);
-        schemaContext = moduleContext.tryToCreateSchemaContext().get();
-        setupWithSchema(schemaContext);
+        setupWithSchema(getSchemaContext());
     }
 
     /**
      * Setups test with Schema context.
      * This method is called before {@link #setupWithSchemaService(SchemaService)}
     }
 
     /**
      * Setups test with Schema context.
      * This method is called before {@link #setupWithSchemaService(SchemaService)}
-     *
-     * @param context
      */
     protected abstract void setupWithSchema(SchemaContext context);
 
      */
     protected abstract void setupWithSchema(SchemaContext context);
 
diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/ConstantSchemaAbstractDataBrokerTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/ConstantSchemaAbstractDataBrokerTest.java
new file mode 100644 (file)
index 0000000..ca643ff
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2016 Red Hat, Inc. 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.controller.md.sal.binding.test;
+
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+/**
+ * AbstractDataBrokerTest which creates the SchemaContext
+ * only once, and keeps it in a static, instead of re-recreating
+ * it for each Test, and is thus faster.
+ *
+ * @author Michael Vorburger
+ */
+public class ConstantSchemaAbstractDataBrokerTest extends AbstractDataBrokerTest {
+
+    @Override
+    protected SchemaContext getSchemaContext() throws Exception {
+        return SchemaContextSingleton.getSchemaContext(() -> super.getSchemaContext());
+    }
+
+}
index 96facbed9cdd3dbd9e95919fa91c2c6d208d55ff..c71049e444041e53a131f9877637f88a82a97bba 100644 (file)
@@ -21,7 +21,7 @@ public class DataBrokerTestModule {
             // into this DataBrokerTestModule, and make AbstractDataBrokerTest
             // use it, instead of the way around it currently is (the opposite);
             // this is just for historical reasons... and works for now.
             // into this DataBrokerTestModule, and make AbstractDataBrokerTest
             // use it, instead of the way around it currently is (the opposite);
             // this is just for historical reasons... and works for now.
-            AbstractDataBrokerTest dataBrokerTest = new AbstractDataBrokerTest();
+            ConstantSchemaAbstractDataBrokerTest dataBrokerTest = new ConstantSchemaAbstractDataBrokerTest();
             dataBrokerTest.setup();
             return dataBrokerTest.getDataBroker();
         } catch (Exception e) {
             dataBrokerTest.setup();
             return dataBrokerTest.getDataBroker();
         } catch (Exception e) {
diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/SchemaContextSingleton.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/SchemaContextSingleton.java
new file mode 100644 (file)
index 0000000..49eb5aa
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2016 Red Hat, Inc. 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.controller.md.sal.binding.test;
+
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+/**
+ * {@link SchemaContext} singleton holder (static).
+ *
+ * <p>This is useful in scenarios such as unit tests, but not OSGi environments,
+ * where there is a flat classpath and thus really only one single
+ * SchemaContext.
+ *
+ * @author Michael Vorburger
+ */
+public final class SchemaContextSingleton {
+
+    private static SchemaContext staticSchemaContext;
+
+    public static synchronized SchemaContext getSchemaContext(Supplier<SchemaContext> supplier) throws Exception {
+        if (staticSchemaContext == null) {
+            staticSchemaContext = supplier.get();
+        }
+        return staticSchemaContext;
+    }
+
+    private SchemaContextSingleton() { }
+
+    @FunctionalInterface
+    public interface Supplier<T> {
+        T get() throws Exception;
+    }
+}
index 30ea7f82feb907f44299902eca63fe9c7af0142c..4fbb8510110bfa8ace307b7f1ae8f18c428d8d55 100644 (file)
@@ -9,6 +9,7 @@ package org.opendaylight.controller.md.sal.binding.test.tests;
 
 import static com.google.common.truth.Truth.assertThat;
 
 
 import static com.google.common.truth.Truth.assertThat;
 
+import org.junit.Ignore;
 import org.junit.Test;
 import org.opendaylight.controller.md.sal.binding.test.DataBrokerTestModule;
 
 import org.junit.Test;
 import org.opendaylight.controller.md.sal.binding.test.DataBrokerTestModule;
 
@@ -23,4 +24,18 @@ public class DataBrokerTestModuleTest {
     public void ensureDataBrokerTestModuleWorksWithoutException() {
         assertThat(DataBrokerTestModule.dataBroker()).isNotNull();
     }
     public void ensureDataBrokerTestModuleWorksWithoutException() {
         assertThat(DataBrokerTestModule.dataBroker()).isNotNull();
     }
+
+    @Test
+    @Ignore // This test is flaky on build server VMs (although fine locally)
+    public void slowYangLoadingShouldOnlyHappenOnceAndNotDelayEachDataBroker() {
+        // TODO Write a lil' Timer utility class to make this kind of timing test code more readable
+        long startAtMs = System.currentTimeMillis();
+        DataBrokerTestModule.dataBroker();
+        long firstDataBrokerAtMs = System.currentTimeMillis();
+        long firstDataBrokerDurationMs = firstDataBrokerAtMs - startAtMs;
+        DataBrokerTestModule.dataBroker();
+        long secondDataBrokerDurationMs = System.currentTimeMillis() - firstDataBrokerAtMs;
+        assertThat(Math.abs(secondDataBrokerDurationMs - firstDataBrokerDurationMs))
+                .isLessThan(firstDataBrokerDurationMs / 4);
+    }
 }
 }