| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more contributor license |
| * agreements. See the NOTICE file distributed with this work for additional information regarding |
| * copyright ownership. The ASF licenses this file to You 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. |
| */ |
| package org.apache.geode.distributed; |
| |
| import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT; |
| import static org.apache.geode.internal.AvailablePortHelper.getRandomAvailableTCPPorts; |
| import static org.apache.geode.test.dunit.Assert.assertEquals; |
| import static org.apache.geode.test.dunit.Assert.assertFalse; |
| import static org.apache.geode.test.dunit.Assert.assertNotNull; |
| import static org.apache.geode.test.dunit.Assert.assertTrue; |
| import static org.apache.geode.test.dunit.Host.getHost; |
| |
| import java.io.File; |
| import java.util.Collection; |
| import java.util.HashSet; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.concurrent.Callable; |
| |
| import org.junit.Test; |
| import org.junit.experimental.categories.Category; |
| |
| import org.apache.geode.distributed.AbstractLauncher.Status; |
| import org.apache.geode.distributed.LocatorLauncher.Builder; |
| import org.apache.geode.distributed.LocatorLauncher.LocatorState; |
| import org.apache.geode.distributed.internal.ClusterDistributionManager; |
| import org.apache.geode.distributed.internal.DistributionConfig; |
| import org.apache.geode.distributed.internal.InternalDistributedSystem; |
| import org.apache.geode.distributed.internal.InternalLocator; |
| import org.apache.geode.distributed.internal.membership.InternalDistributedMember; |
| import org.apache.geode.internal.net.SocketCreator; |
| import org.apache.geode.internal.util.StopWatch; |
| import org.apache.geode.test.dunit.Host; |
| import org.apache.geode.test.dunit.SerializableCallable; |
| import org.apache.geode.test.dunit.SerializableRunnable; |
| import org.apache.geode.test.dunit.internal.JUnit4DistributedTestCase; |
| import org.apache.geode.test.junit.categories.ClientServerTest; |
| |
| /** |
| * Extracted from LocatorLauncherLocalIntegrationTest. |
| * |
| * @since GemFire 8.0 |
| */ |
| @Category({ClientServerTest.class}) |
| public class HostedLocatorsDUnitTest extends JUnit4DistributedTestCase { |
| |
| protected static final int TIMEOUT_MILLISECONDS = 5 * 60 * 1000; // 5 minutes |
| |
| protected transient volatile int locatorPort; |
| protected transient volatile LocatorLauncher launcher; |
| |
| @Override |
| public final void postSetUp() throws Exception { |
| disconnectAllFromDS(); |
| } |
| |
| @Override |
| public final void preTearDown() throws Exception { |
| disconnectAllFromDS(); |
| } |
| |
| @Test |
| public void testGetAllHostedLocators() throws Exception { |
| final InternalDistributedSystem system = getSystem(); |
| final String dunitLocator = system.getConfig().getLocators(); |
| assertNotNull(dunitLocator); |
| assertFalse(dunitLocator.isEmpty()); |
| |
| final int[] ports = getRandomAvailableTCPPorts(4); |
| |
| final String uniqueName = getUniqueName(); |
| for (int i = 0; i < 4; i++) { |
| final int whichvm = i; |
| getHost(0).getVM(whichvm).invoke(new SerializableCallable() { |
| @Override |
| public Object call() throws Exception { |
| try { |
| System.setProperty(DistributionConfig.GEMFIRE_PREFIX + "locators", dunitLocator); |
| System.setProperty(DistributionConfig.GEMFIRE_PREFIX + MCAST_PORT, "0"); |
| |
| final String name = uniqueName + "-" + whichvm; |
| final File subdir = new File(name); |
| subdir.mkdir(); |
| assertTrue(subdir.exists() && subdir.isDirectory()); |
| |
| final Builder builder = new Builder().setMemberName(name).setPort(ports[whichvm]) |
| .setRedirectOutput(true).setWorkingDirectory(name); |
| |
| launcher = builder.build(); |
| assertEquals(Status.ONLINE, launcher.start().getStatus()); |
| waitForLocatorToStart(launcher, TIMEOUT_MILLISECONDS, 10, true); |
| return null; |
| } finally { |
| System.clearProperty(DistributionConfig.GEMFIRE_PREFIX + "locators"); |
| System.clearProperty(DistributionConfig.GEMFIRE_PREFIX + MCAST_PORT); |
| } |
| } |
| }); |
| } |
| |
| final String host = SocketCreator.getLocalHost().getHostAddress(); |
| |
| final Set<String> locators = new HashSet<String>(); |
| locators.add(host + "[" |
| + dunitLocator.substring(dunitLocator.indexOf("[") + 1, dunitLocator.indexOf("]")) + "]"); |
| for (int port : ports) { |
| locators.add(host + "[" + port + "]"); |
| } |
| |
| // validation within non-locator |
| final ClusterDistributionManager dm = |
| (ClusterDistributionManager) system.getDistributionManager(); |
| |
| final Set<InternalDistributedMember> locatorIds = dm.getLocatorDistributionManagerIds(); |
| assertEquals(5, locatorIds.size()); |
| |
| final Map<InternalDistributedMember, Collection<String>> hostedLocators = |
| dm.getAllHostedLocators(); |
| assertTrue(!hostedLocators.isEmpty()); |
| assertEquals(5, hostedLocators.size()); |
| |
| for (InternalDistributedMember member : hostedLocators.keySet()) { |
| assertEquals(1, hostedLocators.get(member).size()); |
| final String hostedLocator = hostedLocators.get(member).iterator().next(); |
| assertTrue(locators + " does not contain " + hostedLocator, locators.contains(hostedLocator)); |
| } |
| |
| // validate fix for #46324 |
| for (int whichvm = 0; whichvm < 4; whichvm++) { |
| getHost(0).getVM(whichvm).invoke(new SerializableRunnable() { |
| @Override |
| public void run() { |
| final ClusterDistributionManager dm = |
| (ClusterDistributionManager) InternalDistributedSystem.getAnyInstance() |
| .getDistributionManager(); |
| final InternalDistributedMember self = dm.getDistributionManagerId(); |
| |
| final Set<InternalDistributedMember> locatorIds = dm.getLocatorDistributionManagerIds(); |
| assertTrue(locatorIds.contains(self)); |
| |
| final Map<InternalDistributedMember, Collection<String>> hostedLocators = |
| dm.getAllHostedLocators(); |
| assertTrue( |
| "hit bug #46324: " + hostedLocators + " is missing " |
| + InternalLocator.getLocatorStrings() + " for " + self, |
| hostedLocators.containsKey(self)); |
| } |
| }); |
| } |
| |
| // validation with locators |
| for (int whichvm = 0; whichvm < 4; whichvm++) { |
| getHost(0).getVM(whichvm).invoke(new SerializableRunnable() { |
| @Override |
| public void run() { |
| final ClusterDistributionManager dm = |
| (ClusterDistributionManager) InternalDistributedSystem.getAnyInstance() |
| .getDistributionManager(); |
| |
| final Set<InternalDistributedMember> locatorIds = dm.getLocatorDistributionManagerIds(); |
| assertEquals(5, locatorIds.size()); |
| |
| final Map<InternalDistributedMember, Collection<String>> hostedLocators = |
| dm.getAllHostedLocators(); |
| assertTrue(!hostedLocators.isEmpty()); |
| assertEquals(5, hostedLocators.size()); |
| |
| for (InternalDistributedMember member : hostedLocators.keySet()) { |
| assertEquals(1, hostedLocators.get(member).size()); |
| final String hostedLocator = hostedLocators.get(member).iterator().next(); |
| assertTrue(locators + " does not contain " + hostedLocator, |
| locators.contains(hostedLocator)); |
| } |
| } |
| }); |
| } |
| } |
| |
| @Test |
| public void testGetAllHostedLocatorsUsingPortZero() throws Exception { |
| final InternalDistributedSystem system = getSystem(); |
| final String dunitLocator = system.getConfig().getLocators(); |
| assertNotNull(dunitLocator); |
| assertFalse(dunitLocator.isEmpty()); |
| |
| // This will eventually contain the ports used by locators |
| final int[] ports = new int[] {0, 0, 0, 0}; |
| |
| final String uniqueName = getUniqueName(); |
| for (int i = 0; i < 4; i++) { |
| final int whichvm = i; |
| Integer port = (Integer) Host.getHost(0).getVM(whichvm).invoke(new SerializableCallable() { |
| @Override |
| public Object call() throws Exception { |
| try { |
| System.setProperty(DistributionConfig.GEMFIRE_PREFIX + "locators", dunitLocator); |
| System.setProperty(DistributionConfig.GEMFIRE_PREFIX + MCAST_PORT, "0"); |
| |
| final String name = uniqueName + "-" + whichvm; |
| final File subdir = new File(name); |
| subdir.mkdir(); |
| assertTrue(subdir.exists() && subdir.isDirectory()); |
| |
| final Builder builder = new Builder().setMemberName(name).setPort(ports[whichvm]) |
| .setRedirectOutput(true).setWorkingDirectory(name); |
| |
| launcher = builder.build(); |
| assertEquals(Status.ONLINE, launcher.start().getStatus()); |
| waitForLocatorToStart(launcher, TIMEOUT_MILLISECONDS, 10, true); |
| return launcher.getPort(); |
| } finally { |
| System.clearProperty(DistributionConfig.GEMFIRE_PREFIX + "locators"); |
| System.clearProperty(DistributionConfig.GEMFIRE_PREFIX + MCAST_PORT); |
| } |
| } |
| }); |
| ports[i] = port; |
| } |
| |
| final String host = SocketCreator.getLocalHost().getHostAddress(); |
| |
| final Set<String> locators = new HashSet<String>(); |
| locators.add(host + "[" |
| + dunitLocator.substring(dunitLocator.indexOf("[") + 1, dunitLocator.indexOf("]")) + "]"); |
| for (int port : ports) { |
| locators.add(host + "[" + port + "]"); |
| } |
| |
| // validation within non-locator |
| final ClusterDistributionManager dm = |
| (ClusterDistributionManager) system.getDistributionManager(); |
| |
| final Set<InternalDistributedMember> locatorIds = dm.getLocatorDistributionManagerIds(); |
| assertEquals(5, locatorIds.size()); |
| |
| final Map<InternalDistributedMember, Collection<String>> hostedLocators = |
| dm.getAllHostedLocators(); |
| assertTrue(!hostedLocators.isEmpty()); |
| assertEquals(5, hostedLocators.size()); |
| |
| for (InternalDistributedMember member : hostedLocators.keySet()) { |
| assertEquals(1, hostedLocators.get(member).size()); |
| final String hostedLocator = hostedLocators.get(member).iterator().next(); |
| assertTrue(locators + " does not contain " + hostedLocator, locators.contains(hostedLocator)); |
| } |
| |
| // validate fix for #46324 |
| for (int whichvm = 0; whichvm < 4; whichvm++) { |
| Host.getHost(0).getVM(whichvm).invoke(new SerializableRunnable() { |
| @Override |
| public void run() { |
| final ClusterDistributionManager dm = |
| (ClusterDistributionManager) InternalDistributedSystem.getAnyInstance() |
| .getDistributionManager(); |
| final InternalDistributedMember self = dm.getDistributionManagerId(); |
| |
| final Set<InternalDistributedMember> locatorIds = dm.getLocatorDistributionManagerIds(); |
| assertTrue(locatorIds.contains(self)); |
| |
| final Map<InternalDistributedMember, Collection<String>> hostedLocators = |
| dm.getAllHostedLocators(); |
| assertTrue( |
| "hit bug #46324: " + hostedLocators + " is missing " |
| + InternalLocator.getLocatorStrings() + " for " + self, |
| hostedLocators.containsKey(self)); |
| } |
| }); |
| } |
| |
| // validation with locators |
| for (int whichvm = 0; whichvm < 4; whichvm++) { |
| Host.getHost(0).getVM(whichvm).invoke(new SerializableRunnable() { |
| @Override |
| public void run() { |
| final ClusterDistributionManager dm = |
| (ClusterDistributionManager) InternalDistributedSystem.getAnyInstance() |
| .getDistributionManager(); |
| |
| final Set<InternalDistributedMember> locatorIds = dm.getLocatorDistributionManagerIds(); |
| assertEquals(5, locatorIds.size()); |
| |
| final Map<InternalDistributedMember, Collection<String>> hostedLocators = |
| dm.getAllHostedLocators(); |
| assertTrue(!hostedLocators.isEmpty()); |
| assertEquals(5, hostedLocators.size()); |
| |
| for (InternalDistributedMember member : hostedLocators.keySet()) { |
| assertEquals(1, hostedLocators.get(member).size()); |
| final String hostedLocator = hostedLocators.get(member).iterator().next(); |
| assertTrue(locators + " does not contain " + hostedLocator, |
| locators.contains(hostedLocator)); |
| } |
| } |
| }); |
| } |
| } |
| |
| protected void waitForLocatorToStart(final LocatorLauncher launcher, int timeout, int interval, |
| boolean throwOnTimeout) throws Exception { |
| assertEventuallyTrue("waiting for process to start: " + launcher.status(), |
| new Callable<Boolean>() { |
| @Override |
| public Boolean call() throws Exception { |
| try { |
| final LocatorState LocatorState = launcher.status(); |
| return (LocatorState != null && Status.ONLINE.equals(LocatorState.getStatus())); |
| } catch (RuntimeException e) { |
| return false; |
| } |
| } |
| }, timeout, interval); |
| } |
| |
| protected static void assertEventuallyTrue(final String message, final Callable<Boolean> callable, |
| final int timeout, final int interval) throws Exception { |
| boolean done = false; |
| for (StopWatch time = new StopWatch(true); !done && time.elapsedTimeMillis() < timeout; done = |
| (callable.call())) { |
| Thread.sleep(interval); |
| } |
| assertTrue(message, done); |
| } |
| } |