blob: ed061de408639aaed267298d41f0dcfcd5c49d7c [file] [log] [blame]
/*
* 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);
}
}