From 8fb595df69c025b679bb70368509d427c6805abe Mon Sep 17 00:00:00 2001 From: Stuart Douglas Date: Thu, 5 Jan 2017 13:07:40 +1100 Subject: [PATCH] Test that attempts to replicate the failure --- .../service/MultipleDependenciesTestCase.java | 95 ++++++++++++++++++- 1 file changed, 94 insertions(+), 1 deletion(-) diff --git a/src/test/java/org/jboss/msc/service/MultipleDependenciesTestCase.java b/src/test/java/org/jboss/msc/service/MultipleDependenciesTestCase.java index 769f8cc29..6f6e29eb1 100644 --- a/src/test/java/org/jboss/msc/service/MultipleDependenciesTestCase.java +++ b/src/test/java/org/jboss/msc/service/MultipleDependenciesTestCase.java @@ -29,14 +29,20 @@ import static org.junit.Assert.fail; import java.lang.reflect.Field; +import java.security.SecureRandom; import java.util.ArrayList; import java.util.Collection; +import java.util.HashSet; import java.util.List; +import java.util.Random; import java.util.Set; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; import org.jboss.msc.util.TestServiceListener; import org.jboss.msc.value.Values; +import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; @@ -49,6 +55,7 @@ */ public class MultipleDependenciesTestCase extends AbstractServiceTest { + public static final String MODULE = "module"; private static Field dependenciesField; private static final ServiceName firstServiceName = ServiceName.of("firstService"); private static final ServiceName secondServiceName = ServiceName.of("secondService"); @@ -67,6 +74,92 @@ public static void initDependenciesField() throws Exception { dependenciesField.setAccessible(true); } + @Test + public void testSomeThings2() throws Exception { + for(int i = 0; i < 1000; ++i) { + + ServiceName s3 = ServiceName.JBOSS.append("s3"); + ServiceName s2 = ServiceName.JBOSS.append("s2"); + ServiceName s1 = ServiceName.JBOSS.append("s1"); + ServiceController c3 = serviceContainer.addService(s3, new RootService(s3, s2.append(MODULE))) + .install(); + ServiceController c2 = serviceContainer.addService(s2, new RootService(s2, s1.append(MODULE))) + .install(); + ServiceController c1 = serviceContainer.addService(s1, new RootService(s1)) + .install(); + serviceContainer.awaitStability(); + final CountDownLatch latch = new CountDownLatch(1); + c1.addListener(new AbstractServiceListener() { + @Override + public void transition(ServiceController controller, ServiceController.Transition transition) { + if (transition.getAfter() == ServiceController.Substate.REMOVED) { + latch.countDown(); + } + } + }); + c1.setMode(ServiceController.Mode.REMOVE); + latch.await(); + c1 = serviceContainer.addService(s1, new RootService(s1)) + .install(); + if(!serviceContainer.awaitStability(2, TimeUnit.SECONDS)) { + serviceContainer.dumpServices(); + Assert.fail(); + } + c1.setMode(ServiceController.Mode.REMOVE); + c2.setMode(ServiceController.Mode.REMOVE); + c3.setMode(ServiceController.Mode.REMOVE); + if(!serviceContainer.awaitStability(2, TimeUnit.SECONDS)) { + serviceContainer.dumpServices(); + Assert.fail(); + } + } + } + + private class RootService extends AbstractService { + final ServiceName baseName; + private final ServiceName[] serviceNames; + + private RootService(ServiceName baseName, ServiceName... serviceNames) { + this.baseName = baseName; + this.serviceNames = serviceNames; + } + + @Override + public void start(final StartContext context) throws StartException { + ServiceName module = baseName.append(MODULE); + context.getChildTarget().addService(baseName.append("firstModuleUse"), new FirstModuleUseService()) + .addDependency(module) + .install(); + context.getChildTarget().addService(module, Service.NULL) + .addDependencies(serviceNames) + .install(); + } + } + + private class FirstModuleUseService extends AbstractService { + + volatile boolean first = true; + + @Override + public void start(final StartContext context) throws StartException { + if(first) { + first = false; + } else { + first = true; + context.getController().getParent().addListener(new AbstractServiceListener() { + @Override + public void transition(ServiceController controller, ServiceController.Transition transition) { + if(transition.getAfter() == ServiceController.Substate.DOWN) { + controller.setMode(ServiceController.Mode.ACTIVE); + controller.removeListener(this); + } + } + }); + context.getController().getParent().setMode(ServiceController.Mode.NEVER); + } + } + } + @Test public void test() throws Exception { serviceContainer.addListener(listener); @@ -218,4 +311,4 @@ private List> getServiceDependencies(ServiceController< } return depInstances; } -} \ No newline at end of file +}