use of org.jboss.arquillian.extension.byteman.api.BMRules in project wildfly by wildfly.
the class LastNodeToLeaveRemoteEJBTestCase method testDNRContentsAfterLastNodeToLeave.
// Byteman rules to capture the DNR contents after each invocation
@BMRules({ @BMRule(name = "Set up results linkMap (SETUP)", targetClass = "org.jboss.ejb.protocol.remote.RemotingEJBDiscoveryProvider", targetMethod = "<init>", helper = "org.jboss.as.test.clustering.cluster.ejb.remote.byteman.LastNodeToLeaveTestHelper", targetLocation = "EXIT", condition = "debug(\" setting up the map \")", action = "createNodeListMap();"), @BMRule(name = "Track calls to start (COLLECT)", targetClass = "org.jboss.as.test.clustering.cluster.ejb.remote.byteman.LastNodeToLeaveRemoteEJBTestCase", targetMethod = "getStartedNodes", helper = "org.jboss.as.test.clustering.cluster.ejb.remote.byteman.LastNodeToLeaveTestHelper", targetLocation = "EXIT", binding = "startedNodes = $!;", condition = "debug(\"checking for started nodes\")", action = "updateStartedNodes(startedNodes);"), @BMRule(name = "Track calls to ClusterNodeSelector (COLLECT)", targetClass = "org.jboss.as.test.clustering.cluster.ejb.remote.byteman.LastNodeToLeaveRemoteEJBTestCase$CustomClusterNodeSelector", targetMethod = "selectNode", helper = "org.jboss.as.test.clustering.cluster.ejb.remote.byteman.LastNodeToLeaveTestHelper", binding = "clusterName : String = $1;connectedNodes : String[] = $2; totalAvailableNodes : String[] = $3;", condition = "debug(\"checking call to cluster node selector\")", action = "addConnectedNodesEntryForThread(clusterName, connectedNodes, totalAvailableNodes);"), @BMRule(name = "Return test result to test case (RETURN)", targetClass = "org.jboss.as.test.clustering.cluster.ejb.remote.byteman.LastNodeToLeaveRemoteEJBTestCase", targetMethod = "getTestResult", helper = "org.jboss.as.test.clustering.cluster.ejb.remote.byteman.LastNodeToLeaveTestHelper", targetLocation = "ENTRY", condition = "debug(\"returning the result\")", action = "return getNodeListMap();") })
@Test
@RunAsClient
public void testDNRContentsAfterLastNodeToLeave() throws Exception {
List<Future<?>> futures = new ArrayList<>(THREADS);
LOGGER.debugf("%n *** Starting test case test()%n");
LOGGER.debugf("*** Started nodes = %s", getStartedNodes());
ExecutorService executorService = Executors.newFixedThreadPool(THREADS);
for (int i = 0; i < THREADS; ++i) {
// start a client thread
Runnable task = () -> {
LOGGER.debugf("%s *** Starting test thread %s%s", Thread.currentThread().getName());
EJBClientContext oldContext = null;
try {
// install the correct Jakarta Enterprise Beans client context
oldContext = EJBClientContext.getContextManager().getGlobalDefault();
EJBClientContext newContext = createModifiedEJBClientContext(oldContext);
EJBClientContext.getContextManager().setThreadDefault(newContext);
// look up the IncrementorBean and repeatedly invoke on it
try (NamingEJBDirectory directory = new RemoteEJBDirectory(MODULE_NAME)) {
Incrementor bean = directory.lookupStateless(StatelessIncrementorBean.class, Incrementor.class);
LOGGER.debugf("%s +++ Looked up bean for thread %s%n", Thread.currentThread().getName());
while (!Thread.currentThread().isInterrupted()) {
try {
// invoke on the incrementor bean and note where it executes
LOGGER.debugf("%s +++ Thread %s invoking on bean...%n", Thread.currentThread().getName());
Result<Integer> result = bean.increment();
String target = result.getNode();
LOGGER.debugf("%s +++ Thread %s got result %s from node %s%n", Thread.currentThread().getName(), result.getValue(), target);
Thread.sleep(INVOCATION_WAIT);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} catch (NoSuchEJBException e) {
LOGGER.debugf("%n +++ Got NoSuchEJBException from node, skipping...%n");
}
}
} catch (NamingException | EJBException e) {
LOGGER.errorf("%n +++ Exception looking up bean for thread %s%n", Thread.currentThread().getName());
assertNull("Cause of EJBException has not been removed", e.getCause());
}
LOGGER.debugf("%n *** Stopping test thread %s%n", Thread.currentThread().getName());
} finally {
if (oldContext != null) {
EJBClientContext.getContextManager().setThreadDefault(null);
}
}
};
futures.add(executorService.submit(task));
}
// Let the system stabilize
Thread.sleep(GRACE_TIME_TO_REPLICATE);
// now shutdown the entire cluster then start one node back up again, to check last node behaviour
LOGGER.debugf("%n *** Stopping node %s%n", NODE_3);
stop(NODE_3);
LOGGER.debugf("*** Started nodes = %s", getStartedNodes());
// Let the system stabilize
Thread.sleep(GRACE_TIME_TO_MEMBERSHIP_CHANGE);
LOGGER.debugf("%n*** Stopping node %s%n", NODE_2);
stop(NODE_2);
LOGGER.debugf("*** Started nodes = %s", getStartedNodes());
// Let the system stabilize
Thread.sleep(GRACE_TIME_TO_MEMBERSHIP_CHANGE);
LOGGER.debugf("%n *** Stopping node %s%n", NODE_1);
stop(NODE_1);
LOGGER.debugf("*** Started nodes = %s", getStartedNodes());
// Let the system stabilize
Thread.sleep(GRACE_TIME_TO_MEMBERSHIP_CHANGE);
LOGGER.debugf("%n *** Starting node %s%n", NODE_1);
start(NODE_1);
LOGGER.debugf("*** Started nodes = %s", getStartedNodes());
// Let the system stabilize
Thread.sleep(GRACE_TIME_TO_MEMBERSHIP_CHANGE);
// stop the client
for (Future<?> future : futures) {
future.cancel(true);
}
executorService.shutdown();
// get the test results for all threads from the rule
Map<String, List<List<Set<String>>>> results = getTestResult();
// validate the test
for (Map.Entry<String, List<List<Set<String>>>> entry : results.entrySet()) {
String thread = entry.getKey();
LOGGER.debugf("Collected data for thread: %s", thread);
List<List<Set<String>>> nodeEntries = entry.getValue();
for (List<Set<String>> nodeEntry : nodeEntries) {
Set<String> startedNodes = nodeEntry.get(0);
Set<String> connectedNodes = nodeEntry.get(1);
Set<String> totalAvailableNodes = nodeEntry.get(2);
LOGGER.debugf("started nodes = %s, connected nodes = %s, total available nodes = %s", startedNodes, connectedNodes, totalAvailableNodes);
Assert.assertTrue("Assertion violation: thread " + thread + " has stale nodes in discovered node registry(DNR): " + " started = " + startedNodes + ", connected = " + connectedNodes + ", total available = " + totalAvailableNodes, startedNodes.containsAll(connectedNodes) && startedNodes.containsAll(totalAvailableNodes));
}
}
System.out.println("\n *** Stopping test case test() \n");
}
Aggregations