Geode supports rolling upgrade between both major and minor versions.  This means that we support shutting down locators one-by-one and restarting them with the new version, followed by doing the same with servers.  New clients are not allowed to run against old servers, so clients either remain using old versions or are rolled forward after locators and servers are using the new version.

It is the responsibility of committers to test that this functionality works properly.  This affects both the on-wire format of messages sent over the network or serialized to files and the functioning of distributed algorithms such as region creation, content update, distributed locking and so on.  If you introduce something that breaks rolling upgrade or backward-compatibility your change may be reverted or you may be assigned a high-priority ticket to fix the problem.  Reach out to other committers if you need help understanding how to fix the problem and write tests for it.

Beginning in early 2017 changes were incorporated into the develop branch to allow you to write distributed unit tests that create interactions between different versions of Geode.  This comes in the form of requesting a VM that is running the desired version.

VM server1 = Host.getHost(0).getVM(version, 0);

Versions are loaded into the distributed unit test framework automatically and are held in an instance of the class VersionManager.

List<String> versions = VersionManager.getInstance().getVersions();

List<String> versions = VersionManager.getInstance().getVersionsWithoutCurrent();

String currentVersion = VersionManager.CURRENT_VERSION;


Tests can be parameterized to be run with multiple versions.  An example of this is ClientServerMiscBCDUnitTest, which subclasses an existing test to run with mixed versions.  Its superclass was modified to run servers with the current version while clients are run with either the same or a different version.  The subclass then iterates through available "old versions" to test that old-version clients function correctly with servers using the new version of Geode.

public ClientServerMiscDUnitTest() {  testVersion = VersionManager.CURRENT_VERSION;  }

...

 host.getVM(testVersion, 0).invoke(() -> this.createClientCacheV(serverName, port1));


The subclass then uses a parameterized junit runner class:

@Category({DistributedTest.class, ClientServerTest.class, BackwardCompatibilityTest.class})

@RunWith(Parameterized.class)

@Parameterized.UseParametersRunnerFactory(CategoryWithParameterizedRunnerFactory.class)

public class ClientServerMiscBCDUnitTest extends ClientServerMiscDUnitTest {

  @Parameterized.Parameters

  public static Collection<String> data() {  return VersionManager.getInstance().getVersionsWithoutCurrent();  }

  public ClientServerMiscBCDUnitTest(String version) {

    super();

    testVersion = version;

  }


Note that the category BackwardCompatibilityTest was added to the subclass so that all BC tests can be run as a unit if desired.

Unit tests are compiled against the current version and run in a VM with the requested version.  If there are API changes you may need to use reflection to invoke methods if they only exist in one version or if their formal parameters have changed.  Examples of this can be found in RollingUpgradeDUnitTest.

Internals note:  When you request a VM the unit test framework will check the version it is currently running and, if it's not the requested version, bounce the VM.  The new VM will have the same working directory as the old VM and the directory's contents will be preserved.

Internals note: Old versions are defined as source-sets in the geode-old-versions module.  In general these will be as you'd expect: "1.0.0-incubating", "1.1.0", "1.2.0", etc.  These correspond to downloadable Geode releases.  To find the actual release being used in a VM you can invoke GemFireVersion.getGemFireVersion().

  • No labels