From f94d7521936e66febee983ee7633aacaaf9d7390 Mon Sep 17 00:00:00 2001 From: "waqas.ikram" Date: Tue, 5 Jun 2018 16:18:01 +0100 Subject: Adding apex plugins/plugins-context modules Change-Id: I36fc295ffbd22661bf8bd091bfb20ebf6dcc7f5e Issue-ID: POLICY-862 Signed-off-by: waqas.ikram --- .../plugins-context/plugins-context-test/pom.xml | 99 +++++++ .../context/test/HazelcastContextInjection.java | 162 +++++++++++ .../apex/plugins/context/test/package-info.java | 26 ++ .../test/distribution/TestContextAlbumUpdate.java | 94 +++++++ .../distribution/TestContextInstantiation.java | 86 ++++++ .../test/distribution/TestContextUpdate.java | 94 +++++++ .../TestSequentialContextInstantiation.java | 101 +++++++ .../context/test/locking/CuratorManagerTest.java | 99 +++++++ .../test/locking/TestConcurrentContext.java | 313 +++++++++++++++++++++ 9 files changed, 1074 insertions(+) create mode 100644 plugins/plugins-context/plugins-context-test/pom.xml create mode 100644 plugins/plugins-context/plugins-context-test/src/main/java/org/onap/policy/apex/plugins/context/test/HazelcastContextInjection.java create mode 100644 plugins/plugins-context/plugins-context-test/src/main/java/org/onap/policy/apex/plugins/context/test/package-info.java create mode 100644 plugins/plugins-context/plugins-context-test/src/test/java/org/onap/policy/apex/plugins/context/test/distribution/TestContextAlbumUpdate.java create mode 100644 plugins/plugins-context/plugins-context-test/src/test/java/org/onap/policy/apex/plugins/context/test/distribution/TestContextInstantiation.java create mode 100644 plugins/plugins-context/plugins-context-test/src/test/java/org/onap/policy/apex/plugins/context/test/distribution/TestContextUpdate.java create mode 100644 plugins/plugins-context/plugins-context-test/src/test/java/org/onap/policy/apex/plugins/context/test/distribution/TestSequentialContextInstantiation.java create mode 100644 plugins/plugins-context/plugins-context-test/src/test/java/org/onap/policy/apex/plugins/context/test/locking/CuratorManagerTest.java create mode 100644 plugins/plugins-context/plugins-context-test/src/test/java/org/onap/policy/apex/plugins/context/test/locking/TestConcurrentContext.java (limited to 'plugins/plugins-context/plugins-context-test') diff --git a/plugins/plugins-context/plugins-context-test/pom.xml b/plugins/plugins-context/plugins-context-test/pom.xml new file mode 100644 index 000000000..7239abe66 --- /dev/null +++ b/plugins/plugins-context/plugins-context-test/pom.xml @@ -0,0 +1,99 @@ + + + 4.0.0 + + org.onap.policy.apex-pdp.plugins.plugins-context + plugins-context + 2.0.0-SNAPSHOT + + + plugins-context-test + ${project.artifactId} + [${project.parent.artifactId}] module to run context tests using various plugins + + + + org.onap.policy.apex-pdp.core + core-infrastructure + ${project.version} + test + + + org.onap.policy.apex-pdp.plugins.plugins-context.context-distribution + context-distribution-hazelcast + ${project.version} + + + org.onap.policy.apex-pdp.plugins.plugins-context.context-distribution + context-distribution-infinispan + ${project.version} + + + org.onap.policy.apex-pdp.plugins.plugins-context.context-locking + context-locking-curator + ${project.version} + + + org.onap.policy.apex-pdp.plugins.plugins-context.context-locking + context-locking-hazelcast + ${project.version} + + + org.onap.policy.apex-pdp.context + context-test + ${project.version} + test + + + org.apache.curator + curator-test + 4.0.0 + test + + + log4j + log4j + + + + + + + + + org.apache.maven.plugins + maven-site-plugin + + true + true + + + + org.apache.maven.plugins + maven-surefire-plugin + + always + + + + + \ No newline at end of file diff --git a/plugins/plugins-context/plugins-context-test/src/main/java/org/onap/policy/apex/plugins/context/test/HazelcastContextInjection.java b/plugins/plugins-context/plugins-context-test/src/main/java/org/onap/policy/apex/plugins/context/test/HazelcastContextInjection.java new file mode 100644 index 000000000..4c21103c3 --- /dev/null +++ b/plugins/plugins-context/plugins-context-test/src/main/java/org/onap/policy/apex/plugins/context/test/HazelcastContextInjection.java @@ -0,0 +1,162 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.plugins.context.test; + +import java.util.Map.Entry; +import java.util.Random; + +import org.onap.policy.apex.context.ContextAlbum; +import org.onap.policy.apex.context.ContextException; +import org.onap.policy.apex.context.Distributor; +import org.onap.policy.apex.context.impl.distribution.DistributorFactory; +import org.onap.policy.apex.context.parameters.ContextParameters; +import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey; +import org.onap.policy.apex.model.basicmodel.concepts.AxKeyInformation; +import org.onap.policy.apex.model.basicmodel.service.ModelService; +import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbum; +import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbums; +import org.onap.policy.apex.model.contextmodel.concepts.AxContextModel; +import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema; +import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchemas; + +/** + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public final class HazelcastContextInjection { + private static final int ONE_SECOND = 1000; + private static final int SIXTY_SECONDS = 60; + private static final int MAX_INT_10000 = 10000; + + /** + * Default constructor is private to avoid subclassing. + */ + private HazelcastContextInjection() {} + + /** + * The main method. + * + * @param args the arguments to the method + * @throws ContextException exceptions thrown on context injection + */ + public static void main(final String[] args) throws ContextException { + // For convenience, I created model programmatically, it can of course be read in from a + // policy model + final AxContextModel contextModel = createContextModel(); + + // The model must be registered in the model service. + ModelService.registerModel(AxContextSchemas.class, contextModel.getSchemas()); + ModelService.registerModel(AxContextAlbums.class, contextModel.getAlbums()); + + // Configure APex to use Hazelcast distribution and locking + final ContextParameters contextParameters = new ContextParameters(); + contextParameters.getDistributorParameters() + .setPluginClass("com.ericsson.apex.plugins.context.distribution.hazelcast.HazelcastContextDistributor"); + contextParameters.getLockManagerParameters() + .setPluginClass("com.ericsson.apex.plugins.context.locking.hazelcast.HazelcastLockManager"); + + // Fire up our distribution + final AxArtifactKey distributorKey = new AxArtifactKey("ApexDistributor", "0.0.1"); + final Distributor contextDistributor = new DistributorFactory().getDistributor(distributorKey); + contextDistributor.init(distributorKey); + + // Now, get a handle on the album + final ContextAlbum myContextAlbum = + contextDistributor.createContextAlbum(new AxArtifactKey("LongContextAlbum", "0.0.1")); + + final int jvmID = new Random().nextInt(MAX_INT_10000); + final String myLongKey = "MyLong_" + jvmID; + final String commonLongKey = "CommonLong"; + + // Put the long value for this JVM into the map + myContextAlbum.put(myLongKey, new Long(0L)); + + // Put the common long value to be used across JVMS in the map if its not htere already + myContextAlbum.lockForWriting(commonLongKey); + if (myContextAlbum.get(commonLongKey) == null) { + myContextAlbum.put(commonLongKey, new Long(0L)); + } + myContextAlbum.unlockForWriting(commonLongKey); + + // Run for 60 seconds to show multi JVM + for (int i = 0; i < SIXTY_SECONDS; i++) { + System.out.println("JVM " + jvmID + " iteration " + i); + + for (final Entry albumEntry : myContextAlbum.entrySet()) { + myContextAlbum.lockForReading(albumEntry.getKey()); + System.out.println(albumEntry.getKey() + "-->" + albumEntry.getValue()); + myContextAlbum.unlockForReading(albumEntry.getKey()); + } + System.out.println("old " + myLongKey + ": " + myContextAlbum.get(myLongKey)); + + myContextAlbum.lockForReading(commonLongKey); + System.out.println("old CommonLong: " + myContextAlbum.get(commonLongKey)); + myContextAlbum.unlockForReading(commonLongKey); + + Long myLong = (Long) myContextAlbum.get(myLongKey); + myLong++; + myContextAlbum.put(myLongKey, myLong); + + myContextAlbum.lockForWriting(commonLongKey); + Long commonLong = (Long) myContextAlbum.get(commonLongKey); + commonLong++; + myContextAlbum.put(commonLongKey, commonLong); + myContextAlbum.unlockForWriting(commonLongKey); + + System.out.println("new myLong: " + myContextAlbum.get(myLongKey)); + System.out.println("new commonLong: " + myContextAlbum.get(commonLongKey)); + + try { + Thread.sleep(ONE_SECOND); + } catch (final Exception e) { + e.printStackTrace(); + } + } + + contextDistributor.clear(); + } + + /** + * This method just creates a simple context model programatically. + * + * @return a context model + */ + public static AxContextModel createContextModel() { + final AxContextSchema longSchema = + new AxContextSchema(new AxArtifactKey("LongSchema", "0.0.1"), "Java", "java.lang.Long"); + + final AxContextSchemas schemas = new AxContextSchemas(new AxArtifactKey("Schemas", "0.0.1")); + schemas.getSchemasMap().put(longSchema.getKey(), longSchema); + + final AxContextAlbum longAlbumDefinition = new AxContextAlbum(new AxArtifactKey("LongContextAlbum", "0.0.1"), + "APPLICATION", true, longSchema.getKey()); + + final AxContextAlbums albums = new AxContextAlbums(new AxArtifactKey("context", "0.0.1")); + albums.getAlbumsMap().put(longAlbumDefinition.getKey(), longAlbumDefinition); + + final AxKeyInformation keyInformation = new AxKeyInformation(new AxArtifactKey("KeyInfoMapKey", "0.0.1")); + final AxContextModel contextModel = + new AxContextModel(new AxArtifactKey("LongContextModel", "0.0.1"), schemas, albums, keyInformation); + contextModel.setKeyInformation(keyInformation); + keyInformation.generateKeyInfo(contextModel); + + return contextModel; + } +} diff --git a/plugins/plugins-context/plugins-context-test/src/main/java/org/onap/policy/apex/plugins/context/test/package-info.java b/plugins/plugins-context/plugins-context-test/src/main/java/org/onap/policy/apex/plugins/context/test/package-info.java new file mode 100644 index 000000000..eab36189d --- /dev/null +++ b/plugins/plugins-context/plugins-context-test/src/main/java/org/onap/policy/apex/plugins/context/test/package-info.java @@ -0,0 +1,26 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +/** + * Is used to inject context into context maps for test purposes. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +package org.onap.policy.apex.plugins.context.test; diff --git a/plugins/plugins-context/plugins-context-test/src/test/java/org/onap/policy/apex/plugins/context/test/distribution/TestContextAlbumUpdate.java b/plugins/plugins-context/plugins-context-test/src/test/java/org/onap/policy/apex/plugins/context/test/distribution/TestContextAlbumUpdate.java new file mode 100644 index 000000000..c24ef40e4 --- /dev/null +++ b/plugins/plugins-context/plugins-context-test/src/test/java/org/onap/policy/apex/plugins/context/test/distribution/TestContextAlbumUpdate.java @@ -0,0 +1,94 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.plugins.context.test.distribution; + +import java.io.IOException; + +import org.junit.After; +import org.junit.Test; +import org.onap.policy.apex.context.parameters.ContextParameters; +import org.onap.policy.apex.context.parameters.DistributorParameters; +import org.onap.policy.apex.model.basicmodel.concepts.ApexException; +import org.onap.policy.apex.model.basicmodel.handling.ApexModelException; +import org.onap.policy.apex.plugins.context.distribution.infinispan.InfinispanDistributorParameters; +import org.slf4j.ext.XLogger; +import org.slf4j.ext.XLoggerFactory; + +import org.onap.policy.apex.context.test.distribution.ContextAlbumUpdate; + +public class TestContextAlbumUpdate { + // Logger for this class + private static final XLogger logger = XLoggerFactory.getXLogger(TestContextAlbumUpdate.class); + + @Test + public void testContextAlbumUpdateJVMLocalVarSet() throws ApexModelException, IOException, ApexException { + logger.debug("Running testContextAlbumUpdateJVMLocalVarSet test . . ."); + + final ContextParameters contextParameters = new ContextParameters(); + contextParameters.getDistributorParameters() + .setPluginClass(DistributorParameters.DEFAULT_DISTRIBUTOR_PLUGIN_CLASS); + new ContextAlbumUpdate().testContextAlbumUpdate(); + + logger.debug("Ran testContextAlbumUpdateJVMLocalVarSet test"); + } + + @Test + public void testContextAlbumUpdateHazelcast() throws ApexModelException, IOException, ApexException { + logger.debug("Running testContextAlbumUpdateHazelcast test . . ."); + + final ContextParameters contextParameters = new ContextParameters(); + contextParameters.getDistributorParameters().setPluginClass( + "org.onap.policy.apex.plugins.context.distribution.hazelcast.HazelcastContextDistributor"); + new ContextAlbumUpdate().testContextAlbumUpdate(); + + logger.debug("Ran testContextAlbumUpdateHazelcast test"); + } + + @Test + public void testContextAlbumUpdateInfinispan() throws ApexModelException, IOException, ApexException { + logger.debug("Running testContextAlbumUpdateInfinispan test . . ."); + + final ContextParameters contextParameters = new ContextParameters(); + contextParameters.getDistributorParameters().setPluginClass( + "org.onap.policy.apex.plugins.context.distribution.infinispan.InfinispanContextDistributor"); + new InfinispanDistributorParameters(); + + new ContextAlbumUpdate().testContextAlbumUpdate(); + + logger.debug("Ran testContextAlbumUpdateInfinispan test"); + } + + @Test + public void testContextAlbumUpdateJVMLocalVarNotSet() throws ApexModelException, IOException, ApexException { + logger.debug("Running testContextAlbumUpdateJVMLocalVarNotSet test . . ."); + + new ContextParameters(); + new ContextAlbumUpdate().testContextAlbumUpdate(); + + logger.debug("Ran testContextAlbumUpdateJVMLocalVarNotSet test"); + } + + /** + * Test context update cleardown. + */ + @After + public void testContextAlbumUpdateCleardown() {} +} diff --git a/plugins/plugins-context/plugins-context-test/src/test/java/org/onap/policy/apex/plugins/context/test/distribution/TestContextInstantiation.java b/plugins/plugins-context/plugins-context-test/src/test/java/org/onap/policy/apex/plugins/context/test/distribution/TestContextInstantiation.java new file mode 100644 index 000000000..a13b798ef --- /dev/null +++ b/plugins/plugins-context/plugins-context-test/src/test/java/org/onap/policy/apex/plugins/context/test/distribution/TestContextInstantiation.java @@ -0,0 +1,86 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.plugins.context.test.distribution; + +import java.io.IOException; + +import org.junit.Test; +import org.onap.policy.apex.context.parameters.ContextParameters; +import org.onap.policy.apex.context.parameters.DistributorParameters; +import org.onap.policy.apex.context.test.distribution.ContextInstantiation; +import org.onap.policy.apex.model.basicmodel.concepts.ApexException; +import org.onap.policy.apex.model.basicmodel.handling.ApexModelException; +import org.onap.policy.apex.plugins.context.distribution.infinispan.InfinispanDistributorParameters; +import org.slf4j.ext.XLogger; +import org.slf4j.ext.XLoggerFactory; + +public class TestContextInstantiation { + // Logger for this class + private static final XLogger logger = XLoggerFactory.getXLogger(TestContextInstantiation.class); + + @Test + public void testContextInstantiationJVMLocalVarSet() throws ApexModelException, IOException, ApexException { + logger.debug("Running testContextInstantiationJVMLocalVarSet test . . ."); + + final ContextParameters contextParameters = new ContextParameters(); + contextParameters.getDistributorParameters() + .setPluginClass(DistributorParameters.DEFAULT_DISTRIBUTOR_PLUGIN_CLASS); + new ContextInstantiation().testContextInstantiation(); + + logger.debug("Ran testContextInstantiationJVMLocalVarSet test"); + } + + @Test + public void testContextInstantiationHazelcast() throws ApexModelException, IOException, ApexException { + logger.debug("Running testContextInstantiationHazelcast test . . ."); + + final ContextParameters contextParameters = new ContextParameters(); + contextParameters.getDistributorParameters().setPluginClass( + "org.onap.policy.apex.plugins.context.distribution.hazelcast.HazelcastContextDistributor"); + new ContextInstantiation().testContextInstantiation(); + + logger.debug("Ran testContextInstantiationHazelcast test"); + } + + @Test + public void testContextInstantiationInfinispan() throws ApexModelException, IOException, ApexException { + logger.debug("Running testContextInstantiationInfinispan test . . ."); + + final ContextParameters contextParameters = new ContextParameters(); + contextParameters.getDistributorParameters().setPluginClass( + "org.onap.policy.apex.plugins.context.distribution.infinispan.InfinispanContextDistributor"); + new InfinispanDistributorParameters(); + + new ContextInstantiation().testContextInstantiation(); + + logger.debug("Ran testContextInstantiationInfinispan test"); + } + + @Test + public void testContextInstantiationJVMLocalVarNotSet() throws ApexModelException, IOException, ApexException { + logger.debug("Running testContextInstantiationJVMLocalVarNotSet test . . ."); + + new ContextParameters(); + new ContextInstantiation().testContextInstantiation(); + + logger.debug("Ran testContextInstantiationJVMLocalVarNotSet test"); + } +} diff --git a/plugins/plugins-context/plugins-context-test/src/test/java/org/onap/policy/apex/plugins/context/test/distribution/TestContextUpdate.java b/plugins/plugins-context/plugins-context-test/src/test/java/org/onap/policy/apex/plugins/context/test/distribution/TestContextUpdate.java new file mode 100644 index 000000000..3abfd1873 --- /dev/null +++ b/plugins/plugins-context/plugins-context-test/src/test/java/org/onap/policy/apex/plugins/context/test/distribution/TestContextUpdate.java @@ -0,0 +1,94 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.plugins.context.test.distribution; + +import java.io.IOException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.onap.policy.apex.context.parameters.ContextParameters; +import org.onap.policy.apex.context.parameters.DistributorParameters; +import org.onap.policy.apex.context.test.distribution.ContextUpdate; +import org.onap.policy.apex.model.basicmodel.concepts.ApexException; +import org.onap.policy.apex.model.basicmodel.handling.ApexModelException; +import org.onap.policy.apex.plugins.context.distribution.infinispan.InfinispanDistributorParameters; +import org.slf4j.ext.XLogger; +import org.slf4j.ext.XLoggerFactory; + +public class TestContextUpdate { + // Logger for this class + private static final XLogger logger = XLoggerFactory.getXLogger(TestContextUpdate.class); + + @Before + public void beforeTest() {} + + @After + public void afterTest() {} + + @Test + public void testContextUpdateJVMLocalVarSet() throws ApexModelException, IOException, ApexException { + logger.debug("Running testContextUpdateJVMLocalVarSet test . . ."); + + final ContextParameters contextParameters = new ContextParameters(); + contextParameters.getDistributorParameters() + .setPluginClass(DistributorParameters.DEFAULT_DISTRIBUTOR_PLUGIN_CLASS); + new ContextUpdate().testContextUpdate(); + + logger.debug("Ran testContextUpdateJVMLocalVarSet test"); + } + + @Test + public void testContextUpdateHazelcast() throws ApexModelException, IOException, ApexException { + logger.debug("Running testContextUpdateHazelcast test . . ."); + + final ContextParameters contextParameters = new ContextParameters(); + contextParameters.getDistributorParameters().setPluginClass( + "org.onap.policy.apex.plugins.context.distribution.hazelcast.HazelcastContextDistributor"); + new ContextUpdate().testContextUpdate(); + + logger.debug("Ran testContextUpdateHazelcast test"); + } + + @Test + public void testContextUpdateInfinispan() throws ApexModelException, IOException, ApexException { + logger.debug("Running testContextUpdateInfinispan test . . ."); + + final ContextParameters contextParameters = new ContextParameters(); + contextParameters.getDistributorParameters().setPluginClass( + "org.onap.policy.apex.plugins.context.distribution.infinispan.InfinispanContextDistributor"); + new InfinispanDistributorParameters(); + + new ContextUpdate().testContextUpdate(); + + logger.debug("Ran testContextUpdateInfinispan test"); + } + + @Test + public void testContextUpdateJVMLocalVarNotSet() throws ApexModelException, IOException, ApexException { + logger.debug("Running testContextUpdateJVMLocalVarNotSet test . . ."); + + new ContextParameters(); + new ContextUpdate().testContextUpdate(); + + logger.debug("Ran testContextUpdateJVMLocalVarNotSet test"); + } +} diff --git a/plugins/plugins-context/plugins-context-test/src/test/java/org/onap/policy/apex/plugins/context/test/distribution/TestSequentialContextInstantiation.java b/plugins/plugins-context/plugins-context-test/src/test/java/org/onap/policy/apex/plugins/context/test/distribution/TestSequentialContextInstantiation.java new file mode 100644 index 000000000..cc3f52015 --- /dev/null +++ b/plugins/plugins-context/plugins-context-test/src/test/java/org/onap/policy/apex/plugins/context/test/distribution/TestSequentialContextInstantiation.java @@ -0,0 +1,101 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.plugins.context.test.distribution; + +import java.io.IOException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.onap.policy.apex.context.parameters.ContextParameters; +import org.onap.policy.apex.context.parameters.DistributorParameters; +import org.onap.policy.apex.context.test.distribution.SequentialContextInstantiation; +import org.onap.policy.apex.model.basicmodel.concepts.ApexException; +import org.onap.policy.apex.model.basicmodel.handling.ApexModelException; +import org.onap.policy.apex.plugins.context.distribution.infinispan.InfinispanDistributorParameters; +import org.slf4j.ext.XLogger; +import org.slf4j.ext.XLoggerFactory; + +/** + * The Class TestContextInstantiation. + * + * @author Sergey Sachkov (sergey.sachkov@ericsson.com) + */ +public class TestSequentialContextInstantiation { + // Logger for this class + private static final XLogger logger = XLoggerFactory.getXLogger(TestSequentialContextInstantiation.class); + + @Before + public void beforeTest() {} + + @After + public void afterTest() {} + + @Test + public void testSequentialContextInstantiationJVMLocalVarSet() + throws ApexModelException, IOException, ApexException { + logger.debug("Running testSequentialContextInstantiationJVMLocalVarSet test . . ."); + + final ContextParameters contextParameters = new ContextParameters(); + contextParameters.getDistributorParameters() + .setPluginClass(DistributorParameters.DEFAULT_DISTRIBUTOR_PLUGIN_CLASS); + new SequentialContextInstantiation().testSequentialContextInstantiation(); + + logger.debug("Ran testSequentialContextInstantiationJVMLocalVarSet test"); + } + + @Test + public void testSequentialContextInstantiationHazelcast() throws ApexModelException, IOException, ApexException { + logger.debug("Running testSequentialContextInstantiationHazelcast test . . ."); + + final ContextParameters contextParameters = new ContextParameters(); + contextParameters.getDistributorParameters().setPluginClass( + "org.onap.policy.apex.plugins.context.distribution.hazelcast.HazelcastContextDistributor"); + new SequentialContextInstantiation().testSequentialContextInstantiation(); + + logger.debug("Ran testSequentialContextInstantiationHazelcast test"); + } + + @Test + public void testSequentialContextInstantiationInfinispan() throws ApexModelException, IOException, ApexException { + logger.debug("Running testSequentialContextInstantiationInfinispan test . . ."); + + final ContextParameters contextParameters = new ContextParameters(); + contextParameters.getDistributorParameters().setPluginClass( + "org.onap.policy.apex.plugins.context.distribution.infinispan.InfinispanContextDistributor"); + new InfinispanDistributorParameters(); + + new SequentialContextInstantiation().testSequentialContextInstantiation(); + + logger.debug("Ran testSequentialContextInstantiationInfinispan test"); + } + + @Test + public void testSequentialContextInstantiationJVMLocalVarNotSet() + throws ApexModelException, IOException, ApexException { + logger.debug("Running testSequentialContextInstantiationJVMLocalVarNotSet test . . ."); + + new ContextParameters(); + new SequentialContextInstantiation().testSequentialContextInstantiation(); + + logger.debug("Ran testSequentialContextInstantiationJVMLocalVarNotSet test"); + } +} diff --git a/plugins/plugins-context/plugins-context-test/src/test/java/org/onap/policy/apex/plugins/context/test/locking/CuratorManagerTest.java b/plugins/plugins-context/plugins-context-test/src/test/java/org/onap/policy/apex/plugins/context/test/locking/CuratorManagerTest.java new file mode 100644 index 000000000..0b9d60673 --- /dev/null +++ b/plugins/plugins-context/plugins-context-test/src/test/java/org/onap/policy/apex/plugins/context/test/locking/CuratorManagerTest.java @@ -0,0 +1,99 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.plugins.context.test.locking; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.fail; + +import java.io.IOException; + +import org.apache.curator.test.TestingServer; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.onap.policy.apex.context.ContextException; +import org.onap.policy.apex.context.parameters.ContextParameters; +import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey; +import org.onap.policy.apex.plugins.context.locking.curator.CuratorLockManager; +import org.onap.policy.apex.plugins.context.locking.curator.CuratorLockManagerParameters; + +public class CuratorManagerTest { + // Zookeeper test server + TestingServer zkTestServer; + + @Before + public void beforeTest() throws Exception { + zkTestServer = new TestingServer(62181); + } + + @After + public void afterTest() throws IOException { + zkTestServer.stop(); + } + + @Test + public void testCuratorManagerConfigProperty() { + final ContextParameters contextParameters = new ContextParameters(); + contextParameters.setLockManagerParameters(new CuratorLockManagerParameters()); + + ((CuratorLockManagerParameters) contextParameters.getLockManagerParameters()).setZookeeperAddress(null); + + try { + final CuratorLockManager curatorManager = new CuratorLockManager(); + curatorManager.init(new AxArtifactKey()); + assertNull(curatorManager); + } catch (final ContextException e) { + assertEquals(e.getMessage(), + "could not set up Curator locking, check if the curator Zookeeper address parameter is set correctly"); + } + + ((CuratorLockManagerParameters) contextParameters.getLockManagerParameters()).setZookeeperAddress("zooby"); + + try { + final CuratorLockManager curatorManager = new CuratorLockManager(); + curatorManager.init(new AxArtifactKey()); + fail("Curator manager test should fail"); + } catch (final ContextException e) { + assertEquals(e.getMessage(), + "could not connect to Zookeeper server at \"zooby\", see error log for details"); + } + + ((CuratorLockManagerParameters) contextParameters.getLockManagerParameters()) + .setZookeeperAddress("localhost:62181"); + + try { + final CuratorLockManager curatorManager0 = new CuratorLockManager(); + curatorManager0.init(new AxArtifactKey()); + assertNotNull(curatorManager0); + + final CuratorLockManager curatorManager1 = new CuratorLockManager(); + curatorManager1.init(new AxArtifactKey()); + assertNotNull(curatorManager1); + + curatorManager0.shutdown(); + curatorManager1.shutdown(); + } catch (final ContextException e) { + assertNull(e); + } + } +} diff --git a/plugins/plugins-context/plugins-context-test/src/test/java/org/onap/policy/apex/plugins/context/test/locking/TestConcurrentContext.java b/plugins/plugins-context/plugins-context-test/src/test/java/org/onap/policy/apex/plugins/context/test/locking/TestConcurrentContext.java new file mode 100644 index 000000000..e02009a55 --- /dev/null +++ b/plugins/plugins-context/plugins-context-test/src/test/java/org/onap/policy/apex/plugins/context/test/locking/TestConcurrentContext.java @@ -0,0 +1,313 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.plugins.context.test.locking; + +import static org.junit.Assert.assertEquals; + +import java.io.File; +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.NetworkInterface; +import java.util.Collections; +import java.util.Enumeration; +import java.util.TreeSet; + +import org.apache.curator.shaded.com.google.common.io.Files; +import org.apache.zookeeper.server.NIOServerCnxnFactory; +import org.apache.zookeeper.server.ZooKeeperServer; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.onap.policy.apex.context.parameters.ContextParameters; +import org.onap.policy.apex.context.parameters.DistributorParameters; +import org.onap.policy.apex.context.parameters.LockManagerParameters; +import org.onap.policy.apex.context.test.locking.ConcurrentContext; +import org.onap.policy.apex.model.basicmodel.concepts.ApexException; +import org.onap.policy.apex.model.basicmodel.handling.ApexModelException; +import org.onap.policy.apex.model.basicmodel.service.ParameterService; +import org.onap.policy.apex.plugins.context.distribution.infinispan.InfinispanDistributorParameters; +import org.onap.policy.apex.plugins.context.locking.curator.CuratorLockManagerParameters; +import org.slf4j.ext.XLogger; +import org.slf4j.ext.XLoggerFactory; + +import com.hazelcast.config.Config; + +/** + * The Class TestConcurrentContext tests concurrent use of context. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class TestConcurrentContext { + // Logger for this class + private static final XLogger logger = XLoggerFactory.getXLogger(TestConcurrentContext.class); + + // Test parameters + private static final int ZOOKEEPER_START_PORT = 62181; + private static final int TEST_JVM_COUNT_SINGLE_JVM = 1; + private static final int TEST_JVM_COUNT_MULTI_JVM = 3; + private static final int TEST_THREAD_COUNT_SINGLE_JVM = 64; + private static final int TEST_THREAD_COUNT_MULTI_JVM = 20; + private static final int TEST_THREAD_LOOPS = 100; + + private NIOServerCnxnFactory zookeeperFactory; + + // We need to increment the Zookeeper port because sometimes the port is not released at the end + // of the test for a few seconds. + private static int nextZookeeperPort = ZOOKEEPER_START_PORT; + private int zookeeperPort; + + @BeforeClass + public static void configure() throws Exception { + System.setProperty("java.net.preferIPv4Stack", "true"); + System.setProperty("hazelcast.config", "src/test/resources/hazelcast/hazelcast.xml"); + + // The JGroups IP address must be set to a real (not loopback) IP address for Infinispan to + // work. IN order to ensure that all + // the JVMs in a test pick up the same IP address, this function sets the address to be the + // first non-loopback IPv4 address + // on a host + final TreeSet ipAddressSet = new TreeSet(); + + final Enumeration nets = NetworkInterface.getNetworkInterfaces(); + for (final NetworkInterface netint : Collections.list(nets)) { + final Enumeration inetAddresses = netint.getInetAddresses(); + for (final InetAddress inetAddress : Collections.list(inetAddresses)) { + // Look for real IPv4 internet addresses + if (!inetAddress.isLoopbackAddress() && inetAddress.getAddress().length == 4) { + ipAddressSet.add(inetAddress.getHostAddress()); + } + } + } + + if (ipAddressSet.size() == 0) { + throw new Exception("cound not find real IP address for test"); + } + System.out.println("For Infinispan, setting jgroups.tcp.address to: " + ipAddressSet.first()); + System.setProperty("jgroups.tcp.address", ipAddressSet.first()); + + final Config config = new Config(); + config.getNetworkConfig().setPublicAddress(ipAddressSet.first()); + config.getNetworkConfig().getInterfaces().addInterface(ipAddressSet.first()); + } + + @AfterClass + public static void teardown() throws IOException {} + + private void startZookeeperServer() throws IOException, InterruptedException { + final File zookeeperDirectory = Files.createTempDir(); + + zookeeperPort = nextZookeeperPort++; + + final ZooKeeperServer server = new ZooKeeperServer(zookeeperDirectory, zookeeperDirectory, 5000); + zookeeperFactory = new NIOServerCnxnFactory(); + zookeeperFactory.configure(new InetSocketAddress(zookeeperPort), 100); + + zookeeperFactory.startup(server); + } + + private void stopZookeeperServer() { + zookeeperFactory.shutdown(); + } + + @Test + public void testConcurrentContextJVMLocalVarSet() throws ApexModelException, IOException, ApexException { + logger.debug("Running testConcurrentContextJVMLocalVarSet test . . ."); + + final ContextParameters contextParameters = new ContextParameters(); + contextParameters.getLockManagerParameters() + .setPluginClass("org.onap.policy.apex.context.impl.locking.jvmlocal.JVMLocalLockManager"); + final long result = new ConcurrentContext().testConcurrentContext("JVMLocalVarSet", TEST_JVM_COUNT_SINGLE_JVM, + TEST_THREAD_COUNT_SINGLE_JVM, TEST_THREAD_LOOPS); + + assertEquals(TEST_JVM_COUNT_SINGLE_JVM * TEST_THREAD_COUNT_SINGLE_JVM * TEST_THREAD_LOOPS, result); + + logger.debug("Ran testConcurrentContextJVMLocalVarSet test"); + } + + @Test + public void testConcurrentContextJVMLocalNoVarSet() throws ApexModelException, IOException, ApexException { + logger.debug("Running testConcurrentContextJVMLocalNoVarSet test . . ."); + + new ContextParameters(); + final long result = new ConcurrentContext().testConcurrentContext("JVMLocalNoVarSet", TEST_JVM_COUNT_SINGLE_JVM, + TEST_THREAD_COUNT_SINGLE_JVM, TEST_THREAD_LOOPS); + + assertEquals(TEST_JVM_COUNT_SINGLE_JVM * TEST_THREAD_COUNT_SINGLE_JVM * TEST_THREAD_LOOPS, result); + + logger.debug("Ran testConcurrentContextJVMLocalNoVarSet test"); + } + + @Test + public void testConcurrentContextMultiJVMNoLock() throws ApexModelException, IOException, ApexException { + logger.debug("Running testConcurrentContextMultiJVMNoLock test . . ."); + + final ContextParameters contextParameters = new ContextParameters(); + contextParameters.getDistributorParameters() + .setPluginClass("org.onap.policy.apex.context.impl.distribution.jvmlocal.JVMLocalDistributor"); + contextParameters.getLockManagerParameters() + .setPluginClass("org.onap.policy.apex.context.impl.locking.jvmlocal.JVMLocalLockManager"); + + final long result = new ConcurrentContext().testConcurrentContext("testConcurrentContextMultiJVMNoLock", + TEST_JVM_COUNT_MULTI_JVM, TEST_THREAD_COUNT_MULTI_JVM, TEST_THREAD_LOOPS); + + // No concurrent map so result will be zero + assertEquals(0, result); + + logger.debug("Ran testConcurrentContextMultiJVMNoLock test"); + } + + @Test + public void testConcurrentContextHazelcastLock() throws ApexModelException, IOException, ApexException { + logger.debug("Running testConcurrentContextHazelcastLock test . . ."); + + final ContextParameters contextParameters = new ContextParameters(); + contextParameters.getDistributorParameters() + .setPluginClass(DistributorParameters.DEFAULT_DISTRIBUTOR_PLUGIN_CLASS); + contextParameters.getLockManagerParameters() + .setPluginClass("org.onap.policy.apex.plugins.context.locking.hazelcast.HazelcastLockManager"); + final long result = new ConcurrentContext().testConcurrentContext("HazelcastLock", TEST_JVM_COUNT_SINGLE_JVM, + TEST_THREAD_COUNT_SINGLE_JVM, TEST_THREAD_LOOPS); + + assertEquals(TEST_JVM_COUNT_SINGLE_JVM * TEST_THREAD_COUNT_SINGLE_JVM * TEST_THREAD_LOOPS, result); + logger.debug("Ran testConcurrentContextHazelcastLock test"); + } + + @Test + public void testConcurrentContextCuratorLock() + throws ApexModelException, IOException, ApexException, InterruptedException { + logger.debug("Running testConcurrentContextCuratorLock test . . ."); + + startZookeeperServer(); + + final ContextParameters contextParameters = new ContextParameters(); + contextParameters.getDistributorParameters() + .setPluginClass(DistributorParameters.DEFAULT_DISTRIBUTOR_PLUGIN_CLASS); + + final CuratorLockManagerParameters curatorParameters = new CuratorLockManagerParameters(); + curatorParameters.setPluginClass("org.onap.policy.apex.plugins.context.locking.curator.CuratorLockManager"); + curatorParameters.setZookeeperAddress("127.0.0.1:" + zookeeperPort); + contextParameters.setLockManagerParameters(curatorParameters); + ParameterService.registerParameters(LockManagerParameters.class, curatorParameters); + + final long result = new ConcurrentContext().testConcurrentContext("CuratorLock", TEST_JVM_COUNT_SINGLE_JVM, + TEST_THREAD_COUNT_SINGLE_JVM, TEST_THREAD_LOOPS); + + assertEquals(TEST_JVM_COUNT_SINGLE_JVM * TEST_THREAD_COUNT_SINGLE_JVM * TEST_THREAD_LOOPS, result); + + stopZookeeperServer(); + logger.debug("Ran testConcurrentContextCuratorLock test"); + } + + @Test + public void testConcurrentContextHazelcastMultiJVMHazelcastLock() + throws ApexModelException, IOException, ApexException { + logger.debug("Running testConcurrentContextHazelcastMultiJVMHazelcastLock test . . ."); + + final ContextParameters contextParameters = new ContextParameters(); + contextParameters.getDistributorParameters().setPluginClass( + "org.onap.policy.apex.plugins.context.distribution.hazelcast.HazelcastContextDistributor"); + contextParameters.getLockManagerParameters() + .setPluginClass("org.onap.policy.apex.plugins.context.locking.hazelcast.HazelcastLockManager"); + final long result = new ConcurrentContext().testConcurrentContext("HazelcastMultiHazelcastlock", + TEST_JVM_COUNT_MULTI_JVM, TEST_THREAD_COUNT_MULTI_JVM, TEST_THREAD_LOOPS); + + assertEquals(TEST_JVM_COUNT_MULTI_JVM * TEST_THREAD_COUNT_MULTI_JVM * TEST_THREAD_LOOPS, result); + logger.debug("Ran testConcurrentContextHazelcastMultiJVMHazelcastLock test"); + } + + @Test + public void testConcurrentContextInfinispanMultiJVMHazelcastlock() + throws ApexModelException, IOException, ApexException { + logger.debug("Running testConcurrentContextInfinispanMultiJVMHazelcastlock test . . ."); + + final ContextParameters contextParameters = new ContextParameters(); + final InfinispanDistributorParameters infinispanParameters = new InfinispanDistributorParameters(); + infinispanParameters.setPluginClass( + "org.onap.policy.apex.plugins.context.distribution.infinispan.InfinispanContextDistributor"); + infinispanParameters.setConfigFile("infinispan/infinispan-context-test.xml"); + contextParameters.setDistributorParameters(infinispanParameters); + contextParameters.getLockManagerParameters() + .setPluginClass("org.onap.policy.apex.plugins.context.locking.hazelcast.HazelcastLockManager"); + + final long result = new ConcurrentContext().testConcurrentContext("InfinispanMultiHazelcastlock", + TEST_JVM_COUNT_MULTI_JVM, TEST_THREAD_COUNT_MULTI_JVM, TEST_THREAD_LOOPS); + + assertEquals(TEST_JVM_COUNT_MULTI_JVM * TEST_THREAD_COUNT_MULTI_JVM * TEST_THREAD_LOOPS, result); + logger.debug("Ran testConcurrentContextInfinispanMultiJVMHazelcastlock test"); + } + + @Test + public void testConcurrentContextInfinispanMultiJVMCuratorLock() + throws ApexModelException, IOException, ApexException, InterruptedException { + logger.debug("Running testConcurrentContextInfinispanMultiJVMCuratorLock test . . ."); + + startZookeeperServer(); + + final ContextParameters contextParameters = new ContextParameters(); + final InfinispanDistributorParameters infinispanParameters = new InfinispanDistributorParameters(); + infinispanParameters.setPluginClass( + "org.onap.policy.apex.plugins.context.distribution.infinispan.InfinispanContextDistributor"); + infinispanParameters.setConfigFile("infinispan/infinispan-context-test.xml"); + contextParameters.setDistributorParameters(infinispanParameters); + + final CuratorLockManagerParameters curatorParameters = new CuratorLockManagerParameters(); + curatorParameters.setPluginClass("org.onap.policy.apex.plugins.context.locking.curator.CuratorLockManager"); + curatorParameters.setZookeeperAddress("127.0.0.1:" + zookeeperPort); + contextParameters.setLockManagerParameters(curatorParameters); + ParameterService.registerParameters(LockManagerParameters.class, curatorParameters); + + final long result = new ConcurrentContext().testConcurrentContext("InfinispanMultiCuratorLock", + TEST_JVM_COUNT_MULTI_JVM, TEST_THREAD_COUNT_MULTI_JVM, TEST_THREAD_LOOPS); + + assertEquals(TEST_JVM_COUNT_MULTI_JVM * TEST_THREAD_COUNT_MULTI_JVM * TEST_THREAD_LOOPS, result); + + stopZookeeperServer(); + + logger.debug("Ran testConcurrentContextInfinispanMultiJVMCuratorLock test"); + } + + @Test + public void testConcurrentContextHazelcastMultiJVMCuratorLock() + throws ApexModelException, IOException, ApexException, InterruptedException { + logger.debug("Running testConcurrentContextHazelcastMultiJVMCuratorLock test . . ."); + + startZookeeperServer(); + + final ContextParameters contextParameters = new ContextParameters(); + contextParameters.getDistributorParameters().setPluginClass( + "org.onap.policy.apex.plugins.context.distribution.hazelcast.HazelcastContextDistributor"); + + final CuratorLockManagerParameters curatorParameters = new CuratorLockManagerParameters(); + curatorParameters.setPluginClass("org.onap.policy.apex.plugins.context.locking.curator.CuratorLockManager"); + curatorParameters.setZookeeperAddress("127.0.0.1:" + zookeeperPort); + contextParameters.setLockManagerParameters(curatorParameters); + ParameterService.registerParameters(LockManagerParameters.class, curatorParameters); + + final long result = new ConcurrentContext().testConcurrentContext("HazelcastMultiCuratorLock", + TEST_JVM_COUNT_MULTI_JVM, TEST_THREAD_COUNT_MULTI_JVM, TEST_THREAD_LOOPS); + + assertEquals(TEST_JVM_COUNT_MULTI_JVM * TEST_THREAD_COUNT_MULTI_JVM * TEST_THREAD_LOOPS, result); + + stopZookeeperServer(); + logger.debug("Ran testConcurrentContextHazelcastMultiJVMCuratorLock test"); + } +} -- cgit 1.2.3-korg