From a12683b9e6445f48216ce0ca357dfcf359c8e3b3 Mon Sep 17 00:00:00 2001 From: Michael Vorburger Date: Thu, 27 Oct 2016 19:27:36 +0200 Subject: [PATCH] ConstantSchemaAbstractDataBrokerTest, faster than AbstractDataBrokerTest 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 --- .../binding/test/AbstractDataBrokerTest.java | 2 +- .../binding/test/AbstractSchemaAwareTest.java | 18 ++++----- .../ConstantSchemaAbstractDataBrokerTest.java | 26 +++++++++++++ .../binding/test/DataBrokerTestModule.java | 2 +- .../binding/test/SchemaContextSingleton.java | 38 +++++++++++++++++++ .../test/tests/DataBrokerTestModuleTest.java | 15 ++++++++ 6 files changed, 88 insertions(+), 13 deletions(-) create mode 100644 opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/ConstantSchemaAbstractDataBrokerTest.java create mode 100644 opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/SchemaContextSingleton.java diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/AbstractDataBrokerTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/AbstractDataBrokerTest.java index 5789270dee..828ba2c0c0 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/AbstractDataBrokerTest.java +++ b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/AbstractDataBrokerTest.java @@ -37,7 +37,7 @@ public class AbstractDataBrokerTest extends AbstractSchemaAwareTest { // Intentionally left No-op, subclasses may customize it } - protected DataBrokerTestCustomizer createDataBrokerTestCustomizer() { + protected DataBrokerTestCustomizer createDataBrokerTestCustomizer() { return new DataBrokerTestCustomizer(); } diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/AbstractSchemaAwareTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/AbstractSchemaAwareTest.java index 6d758aa7bd..21f806508f 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/AbstractSchemaAwareTest.java +++ b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/AbstractSchemaAwareTest.java @@ -15,29 +15,25 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext; public abstract class AbstractSchemaAwareTest { - private Iterable moduleInfos; - private SchemaContext schemaContext; - - protected Iterable getModuleInfos() throws Exception { return BindingReflections.loadModuleInfos(); } + protected SchemaContext getSchemaContext() throws Exception { + Iterable moduleInfos = getModuleInfos(); + ModuleInfoBackedContext moduleContext = ModuleInfoBackedContext.create(); + moduleContext.addModuleInfos(moduleInfos); + return moduleContext.tryToCreateSchemaContext().get(); + } @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)} - * - * @param 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 index 0000000000..ca643ffcb1 --- /dev/null +++ b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/ConstantSchemaAbstractDataBrokerTest.java @@ -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()); + } + +} diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/DataBrokerTestModule.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/DataBrokerTestModule.java index 96facbed9c..c71049e444 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/DataBrokerTestModule.java +++ b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/DataBrokerTestModule.java @@ -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. - AbstractDataBrokerTest dataBrokerTest = new AbstractDataBrokerTest(); + ConstantSchemaAbstractDataBrokerTest dataBrokerTest = new ConstantSchemaAbstractDataBrokerTest(); 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 index 0000000000..49eb5aaf5c --- /dev/null +++ b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/SchemaContextSingleton.java @@ -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). + * + *

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 supplier) throws Exception { + if (staticSchemaContext == null) { + staticSchemaContext = supplier.get(); + } + return staticSchemaContext; + } + + private SchemaContextSingleton() { } + + @FunctionalInterface + public interface Supplier { + T get() throws Exception; + } +} diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/tests/DataBrokerTestModuleTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/tests/DataBrokerTestModuleTest.java index 30ea7f82fe..4fbb851011 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/tests/DataBrokerTestModuleTest.java +++ b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/tests/DataBrokerTestModuleTest.java @@ -9,6 +9,7 @@ package org.opendaylight.controller.md.sal.binding.test.tests; 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; @@ -23,4 +24,18 @@ public class DataBrokerTestModuleTest { 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); + } } -- 2.36.6