forked from apache/geode
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
GEODE-7344: DSFID implements BasicSerializable (apache#4364)
- Loading branch information
Showing
21 changed files
with
595 additions
and
226 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
244 changes: 244 additions & 0 deletions
244
...ava/org/apache/geode/distributed/internal/tcpserver/TcpServerProductVersionDUnitTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,244 @@ | ||
/* | ||
* 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.internal.tcpserver; | ||
|
||
import static org.apache.geode.distributed.ConfigurationProperties.ENABLE_CLUSTER_CONFIGURATION; | ||
import static org.apache.geode.distributed.ConfigurationProperties.NAME; | ||
import static org.apache.geode.distributed.ConfigurationProperties.USE_CLUSTER_CONFIGURATION; | ||
import static org.apache.geode.distributed.internal.membership.adapter.SocketCreatorAdapter.asTcpSocketCreator; | ||
import static org.assertj.core.api.Assertions.assertThat; | ||
|
||
import java.io.File; | ||
import java.io.Serializable; | ||
import java.lang.reflect.Constructor; | ||
import java.lang.reflect.InvocationTargetException; | ||
import java.util.Arrays; | ||
import java.util.Collection; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.Properties; | ||
import java.util.stream.Collectors; | ||
|
||
import org.jetbrains.annotations.NotNull; | ||
import org.junit.AfterClass; | ||
import org.junit.BeforeClass; | ||
import org.junit.Rule; | ||
import org.junit.Test; | ||
import org.junit.runner.RunWith; | ||
import org.junit.runners.Parameterized; | ||
|
||
import org.apache.geode.distributed.Locator; | ||
import org.apache.geode.distributed.internal.DistributionConfigImpl; | ||
import org.apache.geode.distributed.internal.membership.gms.membership.GMSJoinLeave; | ||
import org.apache.geode.internal.AvailablePortHelper; | ||
import org.apache.geode.internal.InternalDataSerializer; | ||
import org.apache.geode.internal.net.SocketCreator; | ||
import org.apache.geode.internal.net.SocketCreatorFactory; | ||
import org.apache.geode.internal.security.SecurableCommunicationChannel; | ||
import org.apache.geode.test.dunit.DistributedTestUtils; | ||
import org.apache.geode.test.dunit.Host; | ||
import org.apache.geode.test.dunit.SerializableRunnableIF; | ||
import org.apache.geode.test.dunit.VM; | ||
import org.apache.geode.test.dunit.rules.DistributedRule; | ||
import org.apache.geode.test.junit.runners.CategoryWithParameterizedRunnerFactory; | ||
import org.apache.geode.test.version.TestVersion; | ||
import org.apache.geode.test.version.VersionManager; | ||
|
||
/** | ||
* In version 1.12 TcpServer changed: the three pairs of message types used to derive from | ||
* DataSerializable, but as of 1.12 they derive from BasicSerializable. | ||
* | ||
* This test verifies that the current version (1.12 or later) is compatible with the latest | ||
* version before 1.12 | ||
*/ | ||
@RunWith(Parameterized.class) | ||
@Parameterized.UseParametersRunnerFactory(CategoryWithParameterizedRunnerFactory.class) | ||
public class TcpServerProductVersionDUnitTest implements Serializable { | ||
|
||
private static final TestVersion FIRST_NEW_VERSION = TestVersion.valueOf("1.12.0"); | ||
|
||
@Rule | ||
public DistributedRule distributedRule = | ||
DistributedRule.builder().withVMCount(0).build(); | ||
|
||
@BeforeClass | ||
public static void beforeClass() { | ||
SocketCreatorFactory.close(); | ||
} | ||
|
||
@AfterClass | ||
public static void afterClass() { | ||
SocketCreatorFactory.close(); | ||
} | ||
|
||
private static final TestVersion oldProductVersion = getOldProductVersion(); | ||
private static final TestVersion currentProductVersion = | ||
TestVersion.valueOf(VersionManager.CURRENT_VERSION); | ||
|
||
@Parameterized.Parameters(name = "{0}") | ||
public static Collection<VersionConfiguration> data() { | ||
return Arrays.asList(VersionConfiguration.values()); | ||
} | ||
|
||
/* | ||
* We want the newest _available_ version older than FIRST_NEW_VERSION | ||
*/ | ||
private static TestVersion getOldProductVersion() { | ||
|
||
final Map<Boolean, List<TestVersion>> groups = | ||
VersionManager.getInstance().getVersionsWithoutCurrent().stream() | ||
.map(TestVersion::valueOf) | ||
.collect(Collectors.partitioningBy(v -> v.lessThan(FIRST_NEW_VERSION))); | ||
|
||
final List<TestVersion> olderVersions = groups.get(true); | ||
|
||
if (olderVersions.size() < 1) { | ||
throw new AssertionError("Time to decommission TcpServerProductVersionDUnitTest " | ||
+ "because there are no supported versions older than " + FIRST_NEW_VERSION); | ||
} | ||
|
||
return olderVersions.get(olderVersions.size() - 1); | ||
} | ||
|
||
private enum VersionConfiguration { | ||
|
||
// OLD_OLD(oldProductVersion, oldProductVersion), | ||
OLD_CURRENT(oldProductVersion, currentProductVersion), | ||
CURRENT_OLD(currentProductVersion, oldProductVersion); | ||
// CURRENT_CURRENT(currentProductVersion, currentProductVersion); | ||
|
||
final TestVersion clientProductVersion; | ||
final TestVersion locatorProductVersion; | ||
|
||
VersionConfiguration(final TestVersion clientProductVersion, | ||
final TestVersion locatorProductVersion) { | ||
this.clientProductVersion = clientProductVersion; | ||
this.locatorProductVersion = locatorProductVersion; | ||
} | ||
|
||
} | ||
|
||
private final VersionConfiguration versions; | ||
|
||
public TcpServerProductVersionDUnitTest(final VersionConfiguration versions) { | ||
this.versions = versions; | ||
} | ||
|
||
@Test | ||
public void testAllMessageTypes() { | ||
System.out.println("BB: controller clientProductVersion is " + versions.clientProductVersion | ||
+ " and FIRST_NEW_VERSION is " + FIRST_NEW_VERSION); | ||
VM clientVM = Host.getHost(0).getVM(versions.clientProductVersion.toString(), 0); | ||
VM locatorVM = Host.getHost(0).getVM(versions.locatorProductVersion.toString(), 1); | ||
int locatorPort = createLocator(locatorVM, true); | ||
|
||
clientVM.invoke(() -> System.out.println("BB: client vm started")); | ||
|
||
clientVM.invoke("issue version request", | ||
createRequestResponseFunction(locatorPort, VersionRequest.class.getName(), | ||
VersionResponse.class.getName())); | ||
clientVM.invoke("issue info request", | ||
createRequestResponseFunction(locatorPort, InfoRequest.class.getName(), | ||
InfoResponse.class.getName())); | ||
clientVM.invoke("issue shutdown request", | ||
createRequestResponseFunction(locatorPort, ShutdownRequest.class.getName(), | ||
ShutdownResponse.class.getName())); | ||
} | ||
|
||
@NotNull | ||
private SerializableRunnableIF createRequestResponseFunction( | ||
final int locatorPort, | ||
final String requestClassName, | ||
final String responseClassName) { | ||
|
||
return () -> { | ||
|
||
final Class<?> requestClass = Class.forName(requestClassName); | ||
final Object requestMessage = requestClass.newInstance(); | ||
|
||
final TcpClient tcpClient; | ||
System.out.println("BB: clientVM clientProductVersion is " + versions.clientProductVersion | ||
+ " and FIRST_NEW_VERSION is " + FIRST_NEW_VERSION); | ||
if (versions.clientProductVersion.greaterThanOrEqualTo(FIRST_NEW_VERSION)) { | ||
tcpClient = getTcpClient(); | ||
} else { | ||
tcpClient = getLegacyTcpClient(); | ||
} | ||
|
||
final Object response = tcpClient | ||
.requestToServer(SocketCreator.getLocalHost(), locatorPort, requestMessage, 1000); | ||
|
||
final Class<?> responseClass = Class.forName(responseClassName); | ||
|
||
assertThat(response).isInstanceOf(responseClass); | ||
}; | ||
|
||
} | ||
|
||
/* | ||
* The TcpClient class changed in version FIRST_NEW_VERSION. That version (and later) | ||
* no longer has the old constructor TcpClient(final Properties), so we have to access | ||
* that constructor via reflection. | ||
*/ | ||
private TcpClient getLegacyTcpClient() | ||
throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, | ||
InstantiationException { | ||
|
||
final Constructor<TcpClient> constructor = TcpClient.class.getConstructor(Properties.class); | ||
return constructor.newInstance(getDistributedSystemProperties()); | ||
} | ||
|
||
@NotNull | ||
private TcpClient getTcpClient() { | ||
|
||
SocketCreatorFactory | ||
.setDistributionConfig(new DistributionConfigImpl(getDistributedSystemProperties())); | ||
|
||
return new TcpClient( | ||
asTcpSocketCreator( | ||
SocketCreatorFactory | ||
.getSocketCreatorForComponent(SecurableCommunicationChannel.LOCATOR)), | ||
InternalDataSerializer.getDSFIDSerializer().getObjectSerializer(), | ||
InternalDataSerializer.getDSFIDSerializer().getObjectDeserializer()); | ||
} | ||
|
||
private int createLocator(VM memberVM, boolean usingOldVersion) { | ||
return memberVM.invoke("create locator", () -> { | ||
System.setProperty(GMSJoinLeave.BYPASS_DISCOVERY_PROPERTY, "true"); | ||
try { | ||
int port = 0; | ||
// for stress-tests make sure that an older-version locator doesn't try | ||
// to read state persisted by another run's newer-version locator | ||
if (usingOldVersion) { | ||
port = AvailablePortHelper.getRandomAvailableTCPPort(); | ||
DistributedTestUtils.deleteLocatorStateFile(port); | ||
} | ||
return Locator.startLocatorAndDS(port, new File(""), getDistributedSystemProperties()) | ||
.getPort(); | ||
} finally { | ||
System.clearProperty(GMSJoinLeave.BYPASS_DISCOVERY_PROPERTY); | ||
} | ||
}); | ||
} | ||
|
||
public Properties getDistributedSystemProperties() { | ||
Properties properties = new Properties(); | ||
properties.setProperty(ENABLE_CLUSTER_CONFIGURATION, "false"); | ||
properties.setProperty(USE_CLUSTER_CONFIGURATION, "false"); | ||
properties.setProperty(NAME, "vm" + VM.getCurrentVMNum()); | ||
return properties; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.