Uploaded image for project: 'Cassandra'
  1. Cassandra
  2. CASSANDRA-19740

Cassandra Dtest AbstractCluster failed to create new instance config

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Triage Needed
    • Normal
    • Resolution: Unresolved
    • None
    • Test/dtest/java
    • None
    • All
    • None

    Description

      What happened

      In the Cassandra dtest framework, when newInstanceConfig() is explicitly called in the test code for generating a new instance configuration, it will throw an unexpected index out-of-bound exception when getting tokens from tokenSupplier.

      How to reproduce

      Put the following test under cassandra/test/distributed/org/apache/cassandra/distributed/upgrade/, and build dtest jars. I'm using version pair [5.0-alpha1, 5.0-alpha2], and this failure happens also in older versions.

      package org.apache.cassandra.distributed.upgrade;
      public class demoUpgradeTest extends UpgradeTestBase
          @Test
          public void demoTest() throws Throwable
          {
              new TestCase()
                      .nodes(2)
                      .nodesToUpgrade(1)
                      .withConfig(config -> config.with(Feature.GOSSIP, Feature.NETWORK))
                      .upgradesToCurrentFrom(v3X)
                      .setup((cluster) -> {
                          // do nothing.
                      })
                      .runAfterNodeUpgrade((cluster, node) -> {
                          IInstanceConfig config = cluster.newInstanceConfig();
                      }).run();
          }
      } 

      Run the test with

      $ ant test-jvm-dtest-some-Duse.jdk11=true -Dtest.name=org.apache.cassandra.distributed.upgrade.demoUpgradeTest 

      You will see the following failure:

      [junit-timeout] Testcase: demoUpgradeTest(org.apache.cassandra.distributed.upgrade.demoUpgradeTest)-_jdk11:    FAILED
      [junit-timeout] Error in test '5.0-alpha2 -> [5.0-alpha2]' while upgrading to '5.0-alpha2'; successful upgrades []
      [junit-timeout] junit.framework.AssertionFailedError: Error in test '5.0-alpha2 -> [5.0-alpha2]' while upgrading to '5.0-alpha2'; successful upgrades []
      [junit-timeout]     at org.apache.cassandra.distributed.upgrade.UpgradeTestBase$TestCase.run(UpgradeTestBase.java:442)
      [junit-timeout]     at org.apache.cassandra.distributed.upgrade.demoUpgradeTest.demoTest(demoUpgradeTest.java:104)
      [junit-timeout]     at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      [junit-timeout]     at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      [junit-timeout]     at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      [junit-timeout] Caused by: java.lang.ArrayIndexOutOfBoundsException: Index 2 out of bounds for length 2
      [junit-timeout]     at org.apache.cassandra.distributed.api.TokenSupplier.lambda$evenlyDistributedTokens$0(TokenSupplier.java:59)
      [junit-timeout]     at org.apache.cassandra.distributed.impl.AbstractCluster.createInstanceConfig(AbstractCluster.java:589)
      [junit-timeout]     at org.apache.cassandra.distributed.impl.AbstractCluster.newInstanceConfig(AbstractCluster.java:582)
      [junit-timeout]     at org.apache.cassandra.distributed.upgrade.demoUpgradeTest.lambda$demoTest$2(demoUpgradeTest.java:103)
      [junit-timeout]     at org.apache.cassandra.distributed.upgrade.UpgradeTestBase$TestCase.run(UpgradeTestBase.java:433) 

      The failure is caused by the code below in AbstractCluster.java

          public InstanceConfig newInstanceConfig()
          {
              return createInstanceConfig(size() + 1);     // here in our example -> 2 + 1
          }    @VisibleForTesting
          InstanceConfig createInstanceConfig(int nodeNum)   // nodeNum = 3 in the example
          {
              INodeProvisionStrategy provisionStrategy = nodeProvisionStrategy.create(subnet, portMap);
              Collection<String> tokens = tokenSupplier.tokens(nodeNum);  // however, here, tokenSupplier only has 2 tokens; we are trying to get the index of 3, which triggers the out-of-bound exception. 
              ...
          } 

      The code should carefully check the length of the tokenSupplier before actually fetching elements from it.

      Attachments

        Activity

          People

            Unassigned Unassigned
            FuzzingTeam ConfX
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated: