diff --git a/src/java/org/apache/cassandra/auth/AuthKeyspace.java b/src/java/org/apache/cassandra/auth/AuthKeyspace.java index 33fa1ac6ec3e..fc22fd500671 100644 --- a/src/java/org/apache/cassandra/auth/AuthKeyspace.java +++ b/src/java/org/apache/cassandra/auth/AuthKeyspace.java @@ -62,10 +62,25 @@ private AuthKeyspace() public static final String CIDR_PERMISSIONS = "cidr_permissions"; public static final String CIDR_GROUPS = "cidr_groups"; public static final String IDENTITY_TO_ROLES = "identity_to_role"; - public static final Set TABLE_NAMES = ImmutableSet.of(ROLES, ROLE_MEMBERS, ROLE_PERMISSIONS, - RESOURCE_ROLE_INDEX, NETWORK_PERMISSIONS, - CIDR_PERMISSIONS, CIDR_GROUPS, - IDENTITY_TO_ROLES); + + /** + * Returns the set of table names that should exist in the system_auth keyspace. + * In compatibility mode (pre-5.0), CIDR and identity tables are excluded as they + * are Cassandra 5.0+ features. + * + * @return the set of table names appropriate for the current storage compatibility mode + */ + public static Set tableNames() + { + if (DatabaseDescriptor.getStorageCompatibilityMode().isBefore(CassandraVersion.CASSANDRA_5_0.major)) + return ImmutableSet.of(ROLES, ROLE_MEMBERS, ROLE_PERMISSIONS, + RESOURCE_ROLE_INDEX, NETWORK_PERMISSIONS); + else + return ImmutableSet.of(ROLES, ROLE_MEMBERS, ROLE_PERMISSIONS, + RESOURCE_ROLE_INDEX, NETWORK_PERMISSIONS, + CIDR_PERMISSIONS, CIDR_GROUPS, + IDENTITY_TO_ROLES); + } public static final long SUPERUSER_SETUP_DELAY = SUPERUSER_SETUP_DELAY_MS.getLong(); diff --git a/src/java/org/apache/cassandra/config/CassandraRelevantProperties.java b/src/java/org/apache/cassandra/config/CassandraRelevantProperties.java index f36e6501642b..c81b1190e9d6 100644 --- a/src/java/org/apache/cassandra/config/CassandraRelevantProperties.java +++ b/src/java/org/apache/cassandra/config/CassandraRelevantProperties.java @@ -1042,7 +1042,7 @@ public enum CassandraRelevantProperties * * This is a dev/CI only property. Do not use otherwise. */ - TEST_STORAGE_COMPATIBILITY_MODE("cassandra.test.storage_compatibility_mode", StorageCompatibilityMode.NONE.toString()), + TEST_STORAGE_COMPATIBILITY_MODE("cassandra.test.storage_compatibility_mode", StorageCompatibilityMode.HCD_1.toString()), TEST_STRICT_LCS_CHECKS("cassandra.test.strict_lcs_checks"), /** Turns some warnings into exceptions for testing. */ TEST_STRICT_RUNTIME_CHECKS("cassandra.strict.runtime.checks"), diff --git a/src/java/org/apache/cassandra/schema/SchemaConstants.java b/src/java/org/apache/cassandra/schema/SchemaConstants.java index f4fd749a0702..57ee02c825f9 100644 --- a/src/java/org/apache/cassandra/schema/SchemaConstants.java +++ b/src/java/org/apache/cassandra/schema/SchemaConstants.java @@ -195,7 +195,7 @@ public static Set getLocalAndReplicatedSystemTableNames() .addAll(SystemKeyspace.TABLE_NAMES) .addAll(SchemaKeyspaceTables.ALL) .addAll(TraceKeyspace.TABLE_NAMES) - .addAll(AuthKeyspace.TABLE_NAMES) + .addAll(AuthKeyspace.tableNames()) .addAll(SystemDistributedKeyspace.TABLE_NAMES) .build(); } diff --git a/test/distributed/org/apache/cassandra/distributed/impl/InstanceConfig.java b/test/distributed/org/apache/cassandra/distributed/impl/InstanceConfig.java index 10bb9af3dd40..c6912fc152f4 100644 --- a/test/distributed/org/apache/cassandra/distributed/impl/InstanceConfig.java +++ b/test/distributed/org/apache/cassandra/distributed/impl/InstanceConfig.java @@ -174,7 +174,8 @@ private InstanceConfig(int num, .set("default_secondary_index", "sai") .set("default_secondary_index_enabled", "true") - .set("storage_compatibility_mode", "NONE"); + // Respect TEST_STORAGE_COMPATIBILITY_MODE system property (defaults to HCD_1 in tests) + .set("storage_compatibility_mode", CassandraRelevantProperties.TEST_STORAGE_COMPATIBILITY_MODE.getString()); } this.featureFlags = EnumSet.noneOf(Feature.class); this.jmxPort = jmx_port; diff --git a/test/distributed/org/apache/cassandra/distributed/test/DropUDTWithRestartTest.java b/test/distributed/org/apache/cassandra/distributed/test/DropUDTWithRestartTest.java index 468140688ef5..ed53fe0d3193 100644 --- a/test/distributed/org/apache/cassandra/distributed/test/DropUDTWithRestartTest.java +++ b/test/distributed/org/apache/cassandra/distributed/test/DropUDTWithRestartTest.java @@ -47,14 +47,18 @@ import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; import org.junit.Ignore; +import org.junit.Assume; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.Session; +import org.apache.cassandra.config.CassandraRelevantProperties; import org.apache.cassandra.db.Keyspace; import org.apache.cassandra.distributed.Cluster; +import org.apache.cassandra.utils.CassandraVersion; +import org.apache.cassandra.utils.StorageCompatibilityMode; import org.apache.cassandra.distributed.api.ConsistencyLevel; import org.apache.cassandra.distributed.api.ICoordinator; import org.apache.cassandra.distributed.api.IInstance; @@ -301,6 +305,11 @@ public void loadCommitLogAndSSTablesWithDroppedColumnTestCassandra41() throws Ex @Test public void loadCommitLogAndSSTablesWithDroppedColumnTestCassandra5() throws Exception { + // Skip this test if running in compatibility mode < 5.0, as it loads CC5.0 format commit logs and SSTables + StorageCompatibilityMode mode = CassandraRelevantProperties.TEST_STORAGE_COMPATIBILITY_MODE.getEnum(true, StorageCompatibilityMode.class); + Assume.assumeFalse("Test requires Cassandra 5.0+ format data", + mode != null && mode.isBefore(CassandraVersion.CASSANDRA_5_0.major)); + // Cassandra limitations // - user types cannot include other non-frozen udt // - cannot drop non-frozen columns @@ -311,6 +320,11 @@ public void loadCommitLogAndSSTablesWithDroppedColumnTestCassandra5() throws Exc @Test public void loadCommitLogAndSSTablesWithDroppedColumnTestCC50() throws Exception { + // Skip this test if running in compatibility mode < 5.0, as it loads CC5.0 format commit logs and SSTables + StorageCompatibilityMode mode = CassandraRelevantProperties.TEST_STORAGE_COMPATIBILITY_MODE.getEnum(true, StorageCompatibilityMode.class); + Assume.assumeFalse("Test requires Cassandra 5.0+ format data", + mode != null && mode.isBefore(CassandraVersion.CASSANDRA_5_0.major)); + loadCommitLogAndSSTablesWithDroppedColumnTest(CC50_PRODUCT_PATH); } diff --git a/test/distributed/org/apache/cassandra/distributed/test/auth/CIDRAuthorizerConfigTest.java b/test/distributed/org/apache/cassandra/distributed/test/auth/CIDRAuthorizerConfigTest.java index 084a85542d6c..aa0f8e4f226b 100644 --- a/test/distributed/org/apache/cassandra/distributed/test/auth/CIDRAuthorizerConfigTest.java +++ b/test/distributed/org/apache/cassandra/distributed/test/auth/CIDRAuthorizerConfigTest.java @@ -21,14 +21,28 @@ import java.io.IOException; import com.google.common.collect.ImmutableMap; +import org.junit.Assume; +import org.junit.BeforeClass; import org.junit.Test; +import org.apache.cassandra.config.CassandraRelevantProperties; import org.apache.cassandra.config.ParameterizedClass; import org.apache.cassandra.distributed.Cluster; import org.apache.cassandra.distributed.test.TestBaseImpl; +import org.apache.cassandra.utils.CassandraVersion; +import org.apache.cassandra.utils.StorageCompatibilityMode; public class CIDRAuthorizerConfigTest extends TestBaseImpl { + @BeforeClass + public static void setup() throws Exception + { + // Skip this test if running in compatibility mode < 5.0, as CIDR authorization is a CC5.0+ feature + StorageCompatibilityMode mode = CassandraRelevantProperties.TEST_STORAGE_COMPATIBILITY_MODE.getEnum(true, StorageCompatibilityMode.class); + Assume.assumeFalse("CIDR features require Cassandra 5.0+", + mode != null && mode.isBefore(CassandraVersion.CASSANDRA_5_0.major)); + } + @Test public void testParameterizedClass() throws IOException { diff --git a/test/distributed/org/apache/cassandra/distributed/test/jmx/JMXGetterCheckTest.java b/test/distributed/org/apache/cassandra/distributed/test/jmx/JMXGetterCheckTest.java index 5f21c94ab3a2..d29330eb200e 100644 --- a/test/distributed/org/apache/cassandra/distributed/test/jmx/JMXGetterCheckTest.java +++ b/test/distributed/org/apache/cassandra/distributed/test/jmx/JMXGetterCheckTest.java @@ -33,16 +33,19 @@ import com.google.common.collect.ImmutableSet; import org.junit.Test; +import org.apache.cassandra.config.CassandraRelevantProperties; import org.apache.cassandra.distributed.Cluster; import org.apache.cassandra.distributed.api.Feature; import org.apache.cassandra.distributed.api.IInstanceConfig; import org.apache.cassandra.distributed.api.IInvokableInstance; import org.apache.cassandra.distributed.shared.JMXUtil; import org.apache.cassandra.distributed.test.TestBaseImpl; +import org.apache.cassandra.utils.CassandraVersion; +import org.apache.cassandra.utils.StorageCompatibilityMode; public class JMXGetterCheckTest extends TestBaseImpl { - private static final Set IGNORE_ATTRIBUTES = ImmutableSet.of( + private static final Set BASE_IGNORE_ATTRIBUTES = ImmutableSet.of( "org.apache.cassandra.net:type=MessagingService:BackPressurePerHost", // throws unsupported saying the feature was removed... dropped in CASSANDRA-15375 "org.apache.cassandra.db:type=DynamicEndpointSnitch:Scores" // when running in multiple-port-one-IP mode, this fails @@ -60,6 +63,21 @@ public class JMXGetterCheckTest extends TestBaseImpl "org.apache.cassandra.db:type=StorageService:startNativeTransport" // causes multiple loops to fail ); + private static Set getIgnoreAttributes() + { + // CIDR features require Cassandra 5.0+, skip CIDR-related attributes in compatibility mode + StorageCompatibilityMode mode = CassandraRelevantProperties.TEST_STORAGE_COMPATIBILITY_MODE.getEnum(true, StorageCompatibilityMode.class); + if (mode != null && mode.isBefore(CassandraVersion.CASSANDRA_5_0.major)) + { + return ImmutableSet.builder() + .addAll(BASE_IGNORE_ATTRIBUTES) + .add("org.apache.cassandra.db:type=CIDRFilteringMetricsTable:CountsMetricsFromVtable") + .add("org.apache.cassandra.db:type=CIDRFilteringMetricsTable:LatenciesMetricsFromVtable") + .build(); + } + return BASE_IGNORE_ATTRIBUTES; + } + @Test public void testGetters() throws Exception { @@ -81,6 +99,8 @@ public void testGetters() throws Exception */ public static void testAllValidGetters(Cluster cluster) throws Exception { + Set ignoreAttributes = getIgnoreAttributes(); + for (IInvokableInstance instance: cluster) { if (instance.isShutdown()) @@ -101,7 +121,7 @@ public static void testAllValidGetters(Cluster cluster) throws Exception for (MBeanAttributeInfo a : info.getAttributes()) { String fqn = String.format("%s:%s", name, a.getName()); - if (!a.isReadable() || IGNORE_ATTRIBUTES.contains(fqn)) + if (!a.isReadable() || ignoreAttributes.contains(fqn)) continue; try { diff --git a/test/unit/org/apache/cassandra/SchemaLoader.java b/test/unit/org/apache/cassandra/SchemaLoader.java index 2e28f7fe2da5..5786bf019cc5 100644 --- a/test/unit/org/apache/cassandra/SchemaLoader.java +++ b/test/unit/org/apache/cassandra/SchemaLoader.java @@ -308,14 +308,26 @@ public static void setupAuth(IRoleManager roleManager, IAuthenticator authentica DatabaseDescriptor.setAuthenticator(authenticator); DatabaseDescriptor.setAuthorizer(authorizer); DatabaseDescriptor.setNetworkAuthorizer(networkAuthorizer); - DatabaseDescriptor.setCIDRAuthorizer(cidrAuthorizer); + + // Only set and setup CIDR authorizer if storage compatibility mode supports it (5.0+) + // This matches the pattern in CQLTester and production behavior + if (!DatabaseDescriptor.getStorageCompatibilityMode().isBefore(5)) + { + DatabaseDescriptor.setCIDRAuthorizer(cidrAuthorizer); + } + SchemaTestUtil.announceNewKeyspace(AuthKeyspace.metadata()); DatabaseDescriptor.getRoleManager().setup(); DatabaseDescriptor.getAuthenticator().setup(); DatabaseDescriptor.getInternodeAuthenticator().setupInternode(); DatabaseDescriptor.getAuthorizer().setup(); DatabaseDescriptor.getNetworkAuthorizer().setup(); - DatabaseDescriptor.getCIDRAuthorizer().setup(); + + // Only setup CIDR authorizer if storage compatibility mode supports it (5.0+) + // This matches production behavior in StorageService.doAuthSetup() + if (!DatabaseDescriptor.getStorageCompatibilityMode().isBefore(5)) + DatabaseDescriptor.getCIDRAuthorizer().setup(); + Schema.instance.registerListener(new AuthSchemaChangeListener()); } diff --git a/test/unit/org/apache/cassandra/auth/AllowAllCIDRAuthorizerTest.java b/test/unit/org/apache/cassandra/auth/AllowAllCIDRAuthorizerTest.java index b5c0e876eecd..a4cc0ba8e7b2 100644 --- a/test/unit/org/apache/cassandra/auth/AllowAllCIDRAuthorizerTest.java +++ b/test/unit/org/apache/cassandra/auth/AllowAllCIDRAuthorizerTest.java @@ -24,11 +24,13 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Sets; import org.junit.Assert; +import org.junit.Assume; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.apache.cassandra.SchemaLoader; +import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.cql3.CQLTester; import org.apache.cassandra.cql3.QueryProcessor; import org.apache.cassandra.cql3.UntypedResultSet; @@ -36,6 +38,7 @@ import org.apache.cassandra.db.marshal.UTF8Type; import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.service.ClientState; +import org.apache.cassandra.utils.CassandraVersion; import static org.apache.cassandra.auth.AuthKeyspace.CIDR_GROUPS; import static org.apache.cassandra.auth.AuthKeyspace.CIDR_PERMISSIONS; @@ -60,6 +63,9 @@ private static void setupSuperUser() @BeforeClass public static void defineSchema() throws ConfigurationException { + Assume.assumeFalse("CIDR features require Cassandra 5.0+", + DatabaseDescriptor.getStorageCompatibilityMode().isBefore(CassandraVersion.CASSANDRA_5_0.major)); + SchemaLoader.prepareServer(); SchemaLoader.setupAuth(new AuthTestUtils.LocalCassandraRoleManager(), diff --git a/test/unit/org/apache/cassandra/auth/CIDRGroupsMappingManagerTest.java b/test/unit/org/apache/cassandra/auth/CIDRGroupsMappingManagerTest.java index a3a899d65dcf..4ae18e373c5c 100644 --- a/test/unit/org/apache/cassandra/auth/CIDRGroupsMappingManagerTest.java +++ b/test/unit/org/apache/cassandra/auth/CIDRGroupsMappingManagerTest.java @@ -26,14 +26,17 @@ import java.util.Set; import com.google.common.collect.ImmutableSet; +import org.junit.Assume; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.apache.cassandra.SchemaLoader; +import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.cql3.CIDR; import org.apache.cassandra.cql3.QueryProcessor; import org.apache.cassandra.exceptions.ConfigurationException; +import org.apache.cassandra.utils.CassandraVersion; import static org.apache.cassandra.schema.SchemaConstants.AUTH_KEYSPACE_NAME; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -56,6 +59,9 @@ private static void setupSuperUser() @BeforeClass public static void defineSchema() throws ConfigurationException { + Assume.assumeFalse("CIDR features require Cassandra 5.0+", + DatabaseDescriptor.getStorageCompatibilityMode().isBefore(CassandraVersion.CASSANDRA_5_0.major)); + SchemaLoader.prepareServer(); SchemaLoader.setupAuth(new AuthTestUtils.LocalCassandraRoleManager(), diff --git a/test/unit/org/apache/cassandra/auth/CassandraCIDRAuthorizerEnforceModeTest.java b/test/unit/org/apache/cassandra/auth/CassandraCIDRAuthorizerEnforceModeTest.java index ccd187bb807e..5bf484593dd9 100644 --- a/test/unit/org/apache/cassandra/auth/CassandraCIDRAuthorizerEnforceModeTest.java +++ b/test/unit/org/apache/cassandra/auth/CassandraCIDRAuthorizerEnforceModeTest.java @@ -28,6 +28,7 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Sets; import org.junit.Assert; +import org.junit.Assume; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; @@ -45,6 +46,7 @@ import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.exceptions.UnauthorizedException; import org.apache.cassandra.service.ClientState; +import org.apache.cassandra.utils.CassandraVersion; import org.assertj.core.api.Assertions; import static java.lang.String.format; @@ -72,6 +74,9 @@ private static void setupSuperUser() @BeforeClass public static void defineSchema() throws ConfigurationException { + Assume.assumeFalse("CIDR features require Cassandra 5.0+", + DatabaseDescriptor.getStorageCompatibilityMode().isBefore(CassandraVersion.CASSANDRA_5_0.major)); + SchemaLoader.prepareServer(); SchemaLoader.setupAuth(new AuthTestUtils.LocalCassandraRoleManager(), diff --git a/test/unit/org/apache/cassandra/auth/CassandraCIDRAuthorizerMonitorModeTest.java b/test/unit/org/apache/cassandra/auth/CassandraCIDRAuthorizerMonitorModeTest.java index fe92b2c886cc..459c50c7133a 100644 --- a/test/unit/org/apache/cassandra/auth/CassandraCIDRAuthorizerMonitorModeTest.java +++ b/test/unit/org/apache/cassandra/auth/CassandraCIDRAuthorizerMonitorModeTest.java @@ -23,6 +23,7 @@ import java.util.HashMap; import org.junit.Assert; +import org.junit.Assume; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; @@ -37,6 +38,7 @@ import org.apache.cassandra.db.Keyspace; import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.service.ClientState; +import org.apache.cassandra.utils.CassandraVersion; import static org.apache.cassandra.auth.AuthKeyspace.CIDR_GROUPS; import static org.apache.cassandra.auth.AuthKeyspace.CIDR_PERMISSIONS; @@ -59,6 +61,9 @@ private static void setupSuperUser() @BeforeClass public static void defineSchema() throws ConfigurationException { + Assume.assumeFalse("CIDR features require Cassandra 5.0+", + DatabaseDescriptor.getStorageCompatibilityMode().isBefore(CassandraVersion.CASSANDRA_5_0.major)); + SchemaLoader.prepareServer(); SchemaLoader.setupAuth(new AuthTestUtils.LocalCassandraRoleManager(), diff --git a/test/unit/org/apache/cassandra/auth/GrantAndRevokeTest.java b/test/unit/org/apache/cassandra/auth/GrantAndRevokeTest.java index 719c713555e1..db348e244753 100644 --- a/test/unit/org/apache/cassandra/auth/GrantAndRevokeTest.java +++ b/test/unit/org/apache/cassandra/auth/GrantAndRevokeTest.java @@ -23,6 +23,7 @@ import com.google.common.collect.Iterables; import org.junit.After; +import org.junit.Assume; import org.junit.BeforeClass; import org.junit.Test; @@ -38,6 +39,7 @@ import org.apache.cassandra.schema.TableMetadata; import org.apache.cassandra.service.CassandraDaemon; import org.apache.cassandra.transport.ProtocolVersion; +import org.apache.cassandra.utils.CassandraVersion; import static java.lang.String.format; import static org.apache.cassandra.schema.SchemaConstants.LOCAL_SYSTEM_KEYSPACE_NAMES; @@ -68,7 +70,7 @@ public static void setUpClass() public void tearDown() throws Throwable { useSuperUser(); - executeNet("DROP ROLE " + user); + executeNet("DROP ROLE IF EXISTS " + user); } @Test @@ -490,6 +492,9 @@ public void testGrantOnVirtualKeyspaces() throws Throwable @Test public void testAddIdentityPermissions() throws Throwable { + Assume.assumeFalse("ADD IDENTITY requires Cassandra 5.0+", + DatabaseDescriptor.getStorageCompatibilityMode().isBefore(CassandraVersion.CASSANDRA_5_0.major)); + useSuperUser(); executeNet(String.format("CREATE ROLE %s WITH LOGIN = TRUE AND password='%s'", user, pass)); @@ -506,6 +511,9 @@ public void testAddIdentityPermissions() throws Throwable @Test public void testRemoveIdentityPermissionsWithSpecificRolePermission() throws Throwable { + Assume.assumeFalse("DROP IDENTITY requires Cassandra 5.0+", + DatabaseDescriptor.getStorageCompatibilityMode().isBefore(CassandraVersion.CASSANDRA_5_0.major)); + useSuperUser(); String simpleUser = "user_1"; @@ -528,6 +536,9 @@ public void testRemoveIdentityPermissionsWithSpecificRolePermission() throws Thr @Test public void testRemoveIdentityPermissions() { + Assume.assumeFalse("DROP IDENTITY requires Cassandra 5.0+", + DatabaseDescriptor.getStorageCompatibilityMode().isBefore(CassandraVersion.CASSANDRA_5_0.major)); + useSuperUser(); executeNet(String.format("CREATE ROLE %s WITH LOGIN = TRUE AND password='%s'", user, pass)); diff --git a/test/unit/org/apache/cassandra/auth/MutualTlsAuthenticatorTest.java b/test/unit/org/apache/cassandra/auth/MutualTlsAuthenticatorTest.java index 0dc7984f26a8..a513792e982c 100644 --- a/test/unit/org/apache/cassandra/auth/MutualTlsAuthenticatorTest.java +++ b/test/unit/org/apache/cassandra/auth/MutualTlsAuthenticatorTest.java @@ -27,6 +27,7 @@ import java.util.concurrent.TimeoutException; import org.junit.After; +import org.junit.Assume; import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; @@ -41,6 +42,7 @@ import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.schema.SchemaConstants; import org.apache.cassandra.service.StorageService; +import org.apache.cassandra.utils.CassandraVersion; import org.apache.cassandra.utils.MBeanWrapper; import static org.apache.cassandra.auth.AuthTestUtils.getMockInetAddress; @@ -71,6 +73,9 @@ public static Collection versions() @BeforeClass public static void setup() { + Assume.assumeFalse("Mutual TLS authentication with identity mapping requires Cassandra 5.0+", + DatabaseDescriptor.getStorageCompatibilityMode().isBefore(CassandraVersion.CASSANDRA_5_0.major)); + SchemaLoader.loadSchema(); DatabaseDescriptor.daemonInitialization(); StorageService.instance.initServer(0); diff --git a/test/unit/org/apache/cassandra/cql3/CQLTester.java b/test/unit/org/apache/cassandra/cql3/CQLTester.java index 0c9619e367a1..c953143212fb 100644 --- a/test/unit/org/apache/cassandra/cql3/CQLTester.java +++ b/test/unit/org/apache/cassandra/cql3/CQLTester.java @@ -175,6 +175,7 @@ import org.apache.cassandra.schema.Schema; import org.apache.cassandra.schema.SchemaConstants; import org.apache.cassandra.schema.SchemaKeyspace; +import org.apache.cassandra.schema.SchemaKeyspaceTables; import org.apache.cassandra.schema.SchemaTestUtil; import org.apache.cassandra.schema.TableMetadata; import org.apache.cassandra.serializers.TypeSerializer; @@ -189,6 +190,7 @@ import org.apache.cassandra.transport.SimpleClient; import org.apache.cassandra.transport.messages.ResultMessage; import org.apache.cassandra.utils.ByteBufferUtil; +import org.apache.cassandra.utils.CassandraVersion; import org.apache.cassandra.utils.FBUtilities; import org.apache.cassandra.utils.JMXServerUtils; import org.apache.cassandra.utils.JVMStabilityInspector; @@ -209,7 +211,6 @@ import static org.apache.cassandra.cql3.SchemaElement.SchemaElementType.MATERIALIZED_VIEW; import static org.apache.cassandra.cql3.SchemaElement.SchemaElementType.TABLE; import static org.apache.cassandra.cql3.SchemaElement.SchemaElementType.TYPE; -import static org.apache.cassandra.index.sai.SAITester.vector; import static org.apache.cassandra.utils.Clock.Global.nanoTime; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -605,7 +606,11 @@ protected static void requireAuthentication() DatabaseDescriptor.setAuthenticator(new AuthTestUtils.LocalPasswordAuthenticator()); DatabaseDescriptor.setAuthorizer(new AuthTestUtils.LocalCassandraAuthorizer()); DatabaseDescriptor.setNetworkAuthorizer(new AuthTestUtils.LocalCassandraNetworkAuthorizer()); - DatabaseDescriptor.setCIDRAuthorizer(new AuthTestUtils.LocalCassandraCIDRAuthorizer()); + + // Only set CIDR authorizer if storage compatibility mode supports it (5.0+) + // This matches production behavior in StorageService.doAuthSetup() + if (!DatabaseDescriptor.getStorageCompatibilityMode().isBefore(5)) + DatabaseDescriptor.setCIDRAuthorizer(new AuthTestUtils.LocalCassandraCIDRAuthorizer()); // The CassandraRoleManager constructor set the supported and alterable options based on // DatabaseDescriptor authenticator type so it needs to be created only after the authenticator is set. @@ -614,7 +619,10 @@ protected static void requireAuthentication() public void setup() { loadRoleStatement(); - loadIdentityStatement(); + // Only load identity statement if storage compatibility mode supports it (5.0+) + // This matches CassandraRoleManager.setup() production behavior + if (DatabaseDescriptor.getStorageCompatibilityMode().major >= CassandraVersion.CASSANDRA_5_0.major) + loadIdentityStatement(); QueryProcessor.executeInternal(createDefaultRoleQuery()); } }; @@ -625,7 +633,12 @@ public void setup() DatabaseDescriptor.getAuthenticator().setup(); DatabaseDescriptor.getAuthorizer().setup(); DatabaseDescriptor.getNetworkAuthorizer().setup(); - DatabaseDescriptor.getCIDRAuthorizer().setup(); + + // Only setup CIDR authorizer if storage compatibility mode supports it (5.0+) + // This matches production behavior in StorageService.doAuthSetup() + if (!DatabaseDescriptor.getStorageCompatibilityMode().isBefore(5)) + DatabaseDescriptor.getCIDRAuthorizer().setup(); + Schema.instance.registerListener(new AuthSchemaChangeListener()); AuthCacheService.initializeAndRegisterCaches(); @@ -1481,7 +1494,7 @@ protected void waitForIndexBuilds(String index) /** * Index creation is asynchronous. This method waits until the specified index hasn't any building task running. *

- * This method differs from {@link #waitForIndexQueryable(String, String)} in that it doesn't require the + * This method differs from {@link #waitForIndexQueryable(String, String, long, TimeUnit)} in that it doesn't require the * index to be fully nor successfully built, so it can be used to wait for failing index builds. * * @param keyspace the index keyspace name @@ -1630,6 +1643,42 @@ protected static void assertSchemaChange(String query, Assert.assertEquals(expectedArgTypes != null ? Arrays.asList(expectedArgTypes) : null, schemaChange.argTypes); } + /** + * Assert a table schema option has the expected value. + * @param option The schema option name (e.g., "memtable", "compression") + * @param expected The expected value for the option + */ + protected void assertSchemaOption(String option, Object expected) throws Throwable + { + assertRows(execute(String.format("SELECT " + option + " FROM %s.%s WHERE keyspace_name = ? and table_name = ?;", + SchemaConstants.SCHEMA_KEYSPACE_NAME, + SchemaKeyspaceTables.TABLES), + KEYSPACE, + currentTable()), + row(expected)); + } + + /** + * Assert memtable option in HCD_1 mode where schema stores class name in {@code frozen>}. + * @param expectedConfigKey The config key used in CREATE/ALTER TABLE (e.g., "skiplist", "test_fullname") + * @param expectedSchemaMap The expected map value in schema (e.g., map("class", "SkipListMemtable")) + */ + protected void assertMemtableOptionVersion4(String expectedConfigKey, Object expectedSchemaMap) throws Throwable + { + // Assert the schema contains the correct map value + Object expectedSchemaValue; + if (expectedConfigKey == null || "default".equals(expectedConfigKey)) + { + // Default memtable is not written to schema at all + expectedSchemaValue = null; + } + else + { + expectedSchemaValue = expectedSchemaMap; + } + assertSchemaOption("memtable", expectedSchemaValue); + } + protected static void assertWarningsContain(Message.Response response, String message) { assertWarningsContain(response.getWarnings(), message); diff --git a/test/unit/org/apache/cassandra/cql3/SystemKeyspaceTablesNamesTest.java b/test/unit/org/apache/cassandra/cql3/SystemKeyspaceTablesNamesTest.java index fa7404c87ccd..d35689a0479a 100644 --- a/test/unit/org/apache/cassandra/cql3/SystemKeyspaceTablesNamesTest.java +++ b/test/unit/org/apache/cassandra/cql3/SystemKeyspaceTablesNamesTest.java @@ -76,8 +76,8 @@ public void testSystemTraceKeyspaceTableNames() public void testSystemAuthKeyspaceTableNames() { assertExpectedTablesInKeyspace(SchemaConstants.AUTH_KEYSPACE_NAME, - "AuthKeyspace.TABLE_NAMES", - AuthKeyspace.TABLE_NAMES); + "AuthKeyspace.tableNames()", + AuthKeyspace.tableNames()); } @Test diff --git a/test/unit/org/apache/cassandra/cql3/statements/AddIdentityStatementTest.java b/test/unit/org/apache/cassandra/cql3/statements/AddIdentityStatementTest.java index 424ea46ed076..14a9c34fdbb8 100644 --- a/test/unit/org/apache/cassandra/cql3/statements/AddIdentityStatementTest.java +++ b/test/unit/org/apache/cassandra/cql3/statements/AddIdentityStatementTest.java @@ -18,6 +18,7 @@ package org.apache.cassandra.cql3.statements; +import org.junit.Assume; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Rule; @@ -42,6 +43,7 @@ import org.apache.cassandra.service.ClientState; import org.apache.cassandra.service.QueryState; import org.apache.cassandra.transport.Dispatcher; +import org.apache.cassandra.utils.CassandraVersion; import static org.apache.cassandra.auth.AuthKeyspace.IDENTITY_TO_ROLES; import static org.apache.cassandra.schema.SchemaConstants.AUTH_KEYSPACE_NAME; @@ -69,6 +71,9 @@ private static void setupPrivilegedUser() @BeforeClass public static void defineSchema() throws ConfigurationException { + Assume.assumeFalse("Mutual TLS authentication with identity mapping requires Cassandra 5.0+", + DatabaseDescriptor.getStorageCompatibilityMode().isBefore(CassandraVersion.CASSANDRA_5_0.major)); + SchemaLoader.prepareServer(); SchemaLoader.setupAuth(new AuthTestUtils.LocalCassandraRoleManager(), new AuthTestUtils.LocalPasswordAuthenticator(), diff --git a/test/unit/org/apache/cassandra/cql3/statements/DescribeStatementTest.java b/test/unit/org/apache/cassandra/cql3/statements/DescribeStatementTest.java index 2a56a8d7211c..023e02ba7871 100644 --- a/test/unit/org/apache/cassandra/cql3/statements/DescribeStatementTest.java +++ b/test/unit/org/apache/cassandra/cql3/statements/DescribeStatementTest.java @@ -1078,20 +1078,32 @@ private static String testTableOutput() private static String tableParametersCql() { + // In compatibility mode (pre-5.0), some properties differ + boolean isCompatibilityMode = DatabaseDescriptor.getStorageCompatibilityMode().isBefore(5); + + String memtableFormat = isCompatibilityMode + ? " AND memtable = {}\n" + : " AND memtable = 'default'\n"; + + // allow_auto_snapshot and incremental_backups are not present in pre-5.0 compatibility mode + String autoSnapshotAndIncrementalBackups = isCompatibilityMode + ? "" + : " AND allow_auto_snapshot = true\n" + + " AND incremental_backups = true\n"; + return "additional_write_policy = '99p'\n" + - " AND allow_auto_snapshot = true\n" + + autoSnapshotAndIncrementalBackups + " AND bloom_filter_fp_chance = 0.01\n" + " AND caching = {'keys': 'ALL', 'rows_per_partition': 'NONE'}\n" + " AND cdc = false\n" + " AND comment = ''\n" + " AND compaction = " + cqlQuoted(CompactionParams.DEFAULT.asMap()) + "\n" + " AND compression = {'chunk_length_in_kb': '16', 'class': 'org.apache.cassandra.io.compress.LZ4Compressor'}\n" + - " AND memtable = 'default'\n" + + memtableFormat + " AND crc_check_chance = 1.0\n" + " AND default_time_to_live = 0\n" + " AND extensions = {}\n" + " AND gc_grace_seconds = 864000\n" + - " AND incremental_backups = true\n" + " AND max_index_interval = 2048\n" + " AND memtable_flush_period_in_ms = 0\n" + " AND min_index_interval = 128\n" + @@ -1106,19 +1118,31 @@ private static String cqlQuoted(Map map) private static String mvParametersCql() { + // In compatibility mode (pre-5.0), some properties differ + boolean isCompatibilityMode = DatabaseDescriptor.getStorageCompatibilityMode().isBefore(5); + + String memtableFormat = isCompatibilityMode + ? " AND memtable = {}\n" + : " AND memtable = 'default'\n"; + + // allow_auto_snapshot and incremental_backups are not present in pre-5.0 compatibility mode + String autoSnapshotAndIncrementalBackups = isCompatibilityMode + ? "" + : " AND allow_auto_snapshot = true\n" + + " AND incremental_backups = true\n"; + return "additional_write_policy = '99p'\n" + - " AND allow_auto_snapshot = true\n" + + autoSnapshotAndIncrementalBackups + " AND bloom_filter_fp_chance = 0.01\n" + " AND caching = {'keys': 'ALL', 'rows_per_partition': 'NONE'}\n" + " AND cdc = false\n" + " AND comment = ''\n" + " AND compaction = " + cqlQuoted(CompactionParams.DEFAULT.asMap()) + "\n" + " AND compression = {'chunk_length_in_kb': '16', 'class': 'org.apache.cassandra.io.compress.LZ4Compressor'}\n" + - " AND memtable = 'default'\n" + + memtableFormat + " AND crc_check_chance = 1.0\n" + " AND extensions = {}\n" + " AND gc_grace_seconds = 864000\n" + - " AND incremental_backups = true\n" + " AND max_index_interval = 2048\n" + " AND memtable_flush_period_in_ms = 0\n" + " AND min_index_interval = 128\n" + diff --git a/test/unit/org/apache/cassandra/cql3/statements/DropIdentityStatementTest.java b/test/unit/org/apache/cassandra/cql3/statements/DropIdentityStatementTest.java index 2a96c70c2ea5..506f44bc404b 100644 --- a/test/unit/org/apache/cassandra/cql3/statements/DropIdentityStatementTest.java +++ b/test/unit/org/apache/cassandra/cql3/statements/DropIdentityStatementTest.java @@ -20,6 +20,7 @@ import java.util.Map; +import org.junit.Assume; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Rule; @@ -40,6 +41,7 @@ import org.apache.cassandra.service.ClientState; import org.apache.cassandra.service.QueryState; import org.apache.cassandra.transport.Dispatcher; +import org.apache.cassandra.utils.CassandraVersion; import static org.apache.cassandra.auth.AuthKeyspace.IDENTITY_TO_ROLES; import static org.apache.cassandra.cql3.statements.AddIdentityStatementTest.defineSchema; @@ -60,6 +62,9 @@ public class DropIdentityStatementTest @BeforeClass public static void beforeClasss() throws ConfigurationException { + Assume.assumeFalse("Mutual TLS authentication with identity mapping requires Cassandra 5.0+", + DatabaseDescriptor.getStorageCompatibilityMode().isBefore(CassandraVersion.CASSANDRA_5_0.major)); + defineSchema(); } diff --git a/test/unit/org/apache/cassandra/cql3/validation/operations/AlterTest.java b/test/unit/org/apache/cassandra/cql3/validation/operations/AlterTest.java index ed17b0974b4c..44734d4b04b4 100644 --- a/test/unit/org/apache/cassandra/cql3/validation/operations/AlterTest.java +++ b/test/unit/org/apache/cassandra/cql3/validation/operations/AlterTest.java @@ -28,6 +28,8 @@ import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.cql3.CQLTester; import org.apache.cassandra.db.ColumnFamilyStore; +import org.apache.cassandra.utils.CassandraVersion; +import org.apache.cassandra.utils.StorageCompatibilityMode; import org.apache.cassandra.db.Keyspace; import org.apache.cassandra.db.memtable.Memtable; import org.apache.cassandra.db.memtable.SkipListMemtable; @@ -39,8 +41,6 @@ import org.apache.cassandra.locator.InetAddressAndPort; import org.apache.cassandra.locator.TokenMetadata; import org.apache.cassandra.schema.MemtableParams; -import org.apache.cassandra.schema.SchemaConstants; -import org.apache.cassandra.schema.SchemaKeyspaceTables; import org.apache.cassandra.service.StorageService; import org.apache.cassandra.utils.FBUtilities; @@ -638,22 +638,41 @@ public void testDoubleWith() throws Throwable @Test public void testAlterTableWithMemtable() throws Throwable { + StorageCompatibilityMode mode = DatabaseDescriptor.getStorageCompatibilityMode(); + createTable("CREATE TABLE %s (a text, b int, c int, primary key (a, b))"); assertSame(MemtableParams.DEFAULT.factory(), getCurrentColumnFamilyStore().metadata().params.memtable.factory()); - assertSchemaOption("memtable", null); - Class defaultClass = getCurrentColumnFamilyStore().getTracker().getView().getCurrentMemtable().getClass(); + Class defaultMemtableClass = getCurrentColumnFamilyStore().getTracker().getView().getCurrentMemtable().getClass(); - testMemtableConfig("skiplist", SkipListMemtable.FACTORY, SkipListMemtable.class); - testMemtableConfig("test_fullname", TestMemtable.FACTORY, SkipListMemtable.class); - testMemtableConfig("test_shortname", SkipListMemtable.FACTORY, SkipListMemtable.class); + if (mode.isBefore(CassandraVersion.CASSANDRA_5_0.major)) + { + assertMemtableOptionVersion4(null, null); + testMemtableConfigVersion4("skiplist", map("class", "SkipListMemtable"), SkipListMemtable.FACTORY, SkipListMemtable.class); + testMemtableConfigVersion4("test_fullname", map("class", "TestMemtable"), TestMemtable.FACTORY, SkipListMemtable.class); + testMemtableConfigVersion4("test_shortname", map("class", "TestMemtable", "skiplist", "true"), SkipListMemtable.FACTORY, SkipListMemtable.class); + } + else + { + assertMemtableOption(null); + testMemtableConfig("skiplist", SkipListMemtable.FACTORY, SkipListMemtable.class); + testMemtableConfig("test_fullname", TestMemtable.FACTORY, SkipListMemtable.class); + testMemtableConfig("test_shortname", SkipListMemtable.FACTORY, SkipListMemtable.class); + } // verify memtable does not change on other ALTER alterTable("ALTER TABLE %s" + " WITH compression = {'class': 'LZ4Compressor'};"); - assertSchemaOption("memtable", "test_shortname"); - - testMemtableConfig("default", MemtableParams.DEFAULT.factory(), defaultClass); + if (mode.isBefore(CassandraVersion.CASSANDRA_5_0.major)) + { + assertMemtableOptionVersion4("test_shortname", map("class", "TestMemtable", "skiplist", "true")); + testMemtableConfigVersion4("default", null, MemtableParams.DEFAULT.factory(), defaultMemtableClass); + } + else + { + assertMemtableOption("test_shortname"); + testMemtableConfig("default", MemtableParams.DEFAULT.factory(), defaultMemtableClass); + } assertAlterTableThrowsException(ConfigurationException.class, "The 'class_name' option must be specified.", @@ -691,14 +710,12 @@ public void testAlterTableWithMemtable() throws Throwable + " WITH memtable = 'unknown';"); } - void assertSchemaOption(String option, Object expected) throws Throwable + /** + * Assert memtable option where schema stores config key as text. + */ + void assertMemtableOption(String expectedConfigKey) throws Throwable { - assertRows(execute(format("SELECT " + option + " FROM %s.%s WHERE keyspace_name = ? and table_name = ?;", - SchemaConstants.SCHEMA_KEYSPACE_NAME, - SchemaKeyspaceTables.TABLES), - KEYSPACE, - currentTable()), - row(expected)); + assertSchemaOption("memtable", expectedConfigKey); } private void testMemtableConfig(String memtableConfig, Memtable.Factory factoryInstance, Class memtableClass) throws Throwable @@ -707,7 +724,17 @@ private void testMemtableConfig(String memtableConfig, Memtable.Factory factoryI + " WITH memtable = '" + memtableConfig + "';"); assertSame(factoryInstance, getCurrentColumnFamilyStore().metadata().params.memtable.factory()); Assert.assertTrue(memtableClass.isInstance(getCurrentColumnFamilyStore().getTracker().getView().getCurrentMemtable())); - assertSchemaOption("memtable", MemtableParams.DEFAULT.configurationKey().equals(memtableConfig) ? null : memtableConfig); + assertMemtableOption(MemtableParams.DEFAULT.configurationKey().equals(memtableConfig) ? null : memtableConfig); + } + + private void testMemtableConfigVersion4(String memtableConfig, Object expectedSchemaMap, Memtable.Factory factoryInstance, Class memtableClass) throws Throwable + { + alterTable("ALTER TABLE %s" + + " WITH memtable = '" + memtableConfig + "';"); + assertSame(factoryInstance, getCurrentColumnFamilyStore().metadata().params.memtable.factory()); + Assert.assertTrue(memtableClass.isInstance(getCurrentColumnFamilyStore().getTracker().getView().getCurrentMemtable())); + assertMemtableOptionVersion4(MemtableParams.DEFAULT.configurationKey().equals(memtableConfig) ? null : memtableConfig, + expectedSchemaMap); } @Test diff --git a/test/unit/org/apache/cassandra/cql3/validation/operations/CreateTest.java b/test/unit/org/apache/cassandra/cql3/validation/operations/CreateTest.java index 25ece3026372..878b9a788d06 100644 --- a/test/unit/org/apache/cassandra/cql3/validation/operations/CreateTest.java +++ b/test/unit/org/apache/cassandra/cql3/validation/operations/CreateTest.java @@ -32,6 +32,8 @@ import org.apache.cassandra.config.CassandraRelevantProperties; import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.cql3.CQLTester; +import org.apache.cassandra.utils.CassandraVersion; +import org.apache.cassandra.utils.StorageCompatibilityMode; import org.apache.cassandra.cql3.Duration; import org.apache.cassandra.db.Mutation; import org.apache.cassandra.db.memtable.Memtable; @@ -52,13 +54,11 @@ import org.apache.cassandra.schema.MemtableParams; import org.apache.cassandra.schema.Schema; import org.apache.cassandra.schema.SchemaConstants; -import org.apache.cassandra.schema.SchemaKeyspaceTables; import org.apache.cassandra.schema.TableMetadata; import org.apache.cassandra.service.StorageService; import org.apache.cassandra.triggers.ITrigger; import org.apache.cassandra.utils.ByteBufferUtil; -import static java.lang.String.format; import static org.apache.cassandra.cql3.Duration.NANOS_PER_HOUR; import static org.apache.cassandra.cql3.Duration.NANOS_PER_MICRO; import static org.apache.cassandra.cql3.Duration.NANOS_PER_MILLI; @@ -636,25 +636,53 @@ public static class InvalidMemtableFactoryField @Test public void testCreateTableWithMemtable() throws Throwable { + StorageCompatibilityMode mode = DatabaseDescriptor.getStorageCompatibilityMode(); + createTable("CREATE TABLE %s (a text, b int, c int, primary key (a, b))"); assertSame(MemtableParams.DEFAULT.factory(), getCurrentColumnFamilyStore().metadata().params.memtable.factory()); Class defaultClass = getCurrentColumnFamilyStore().getTracker().getView().getCurrentMemtable().getClass(); - assertSchemaOption("memtable", null); - - testMemtableConfig("skiplist", SkipListMemtable.FACTORY, SkipListMemtable.class); - testMemtableConfig("trie", MemtableParams.get("trie").factory(), TrieMemtable.class); - testMemtableConfig("skiplist_remapped", SkipListMemtable.FACTORY, SkipListMemtable.class); - testMemtableConfig("test_fullname", TestMemtable.FACTORY, SkipListMemtable.class); - testMemtableConfig("test_shortname", SkipListMemtable.FACTORY, SkipListMemtable.class); - testMemtableConfig("default", MemtableParams.DEFAULT.factory(), defaultClass); - - // Handle CC 4.0 memtable configuration given as a map - testMapMemtableConfig("", null, MemtableParams.DEFAULT.factory(), defaultClass); - testMapMemtableConfig("SkipListMemtable", "skiplist", MemtableParams.get("skiplist").factory(), SkipListMemtable.class); - testMapMemtableConfig("TrieMemtable","trie", MemtableParams.get("trie").factory(), TrieMemtable.class); - testMapMemtableConfig("TrieMemtableStage1", "trie", MemtableParams.get("trie").factory(), TrieMemtable.class); - testMapMemtableConfig("PersistentMemoryMemtable", "persistent_memory", MemtableParams.get("persistent_memory").factory(), PersistentMemoryMemtable.class); + if (mode.isBefore(CassandraVersion.CASSANDRA_5_0.major)) + { + // In CC4/HCD_1 mode, memtable is stored as frozen> in schema + assertMemtableOptionVersion4(null, null); + + testMemtableConfigVersion4("skiplist", map("class", "SkipListMemtable"), SkipListMemtable.FACTORY, SkipListMemtable.class); + // Note: trie config in test/conf/cassandra.yaml has shards: 4 parameter + testMemtableConfigVersion4("trie", map("class", "TrieMemtable", "shards", "4"), MemtableParams.get("trie").factory(), TrieMemtable.class); + testMemtableConfigVersion4("skiplist_remapped", map("class", "SkipListMemtable"), SkipListMemtable.FACTORY, SkipListMemtable.class); + testMemtableConfigVersion4("test_fullname", map("class", "TestMemtable"), TestMemtable.FACTORY, SkipListMemtable.class); + testMemtableConfigVersion4("test_shortname", map("class", "TestMemtable", "skiplist", "true"), SkipListMemtable.FACTORY, SkipListMemtable.class); + testMemtableConfigVersion4("default", null, MemtableParams.DEFAULT.factory(), defaultClass); + + // Handle CC 4.0 memtable configuration given as a map + // Note: empty map defaults to default memtable, which is stored as null in schema + testMapMemtableConfigVersion4("", null, MemtableParams.DEFAULT.factory(), defaultClass); + testMapMemtableConfigVersion4("SkipListMemtable", map("class", "SkipListMemtable"), MemtableParams.get("skiplist").factory(), SkipListMemtable.class); + // Note: trie config in test/conf/cassandra.yaml has shards: 4 parameter + testMapMemtableConfigVersion4("TrieMemtable", map("class", "TrieMemtable", "shards", "4"), MemtableParams.get("trie").factory(), TrieMemtable.class); + testMapMemtableConfigVersion4("TrieMemtableStage1", map("class", "TrieMemtable", "shards", "4"), MemtableParams.get("trie").factory(), TrieMemtable.class); + testMapMemtableConfigVersion4("PersistentMemoryMemtable", map("class", "PersistentMemoryMemtable"), MemtableParams.get("persistent_memory").factory(), PersistentMemoryMemtable.class); + } + else + { + // In CC5 mode, memtable is stored as text in schema + assertSchemaOption("memtable", null); + + testMemtableConfig("skiplist", SkipListMemtable.FACTORY, SkipListMemtable.class); + testMemtableConfig("trie", MemtableParams.get("trie").factory(), TrieMemtable.class); + testMemtableConfig("skiplist_remapped", SkipListMemtable.FACTORY, SkipListMemtable.class); + testMemtableConfig("test_fullname", TestMemtable.FACTORY, SkipListMemtable.class); + testMemtableConfig("test_shortname", SkipListMemtable.FACTORY, SkipListMemtable.class); + testMemtableConfig("default", MemtableParams.DEFAULT.factory(), defaultClass); + + // Handle CC 4.0 memtable configuration given as a map + testMapMemtableConfig("", null, MemtableParams.DEFAULT.factory(), defaultClass); + testMapMemtableConfig("SkipListMemtable", "skiplist", MemtableParams.get("skiplist").factory(), SkipListMemtable.class); + testMapMemtableConfig("TrieMemtable","trie", MemtableParams.get("trie").factory(), TrieMemtable.class); + testMapMemtableConfig("TrieMemtableStage1", "trie", MemtableParams.get("trie").factory(), TrieMemtable.class); + testMapMemtableConfig("PersistentMemoryMemtable", "persistent_memory", MemtableParams.get("persistent_memory").factory(), PersistentMemoryMemtable.class); + } assertThrowsConfigurationException("The 'class_name' option must be specified.", "CREATE TABLE %s (a text, b int, c int, primary key (a, b))" @@ -710,14 +738,27 @@ private void testMapMemtableConfig(String memtableConfig, String expectedMemtabl assertSchemaOption("memtable", expectedMemtableConfig); } - void assertSchemaOption(String option, Object expected) throws Throwable + private void testMemtableConfigVersion4(String memtableConfig, Object expectedSchemaMap, Memtable.Factory factoryInstance, Class memtableClass) throws Throwable { - assertRows(execute(format("SELECT " + option + " FROM %s.%s WHERE keyspace_name = ? and table_name = ?;", - SchemaConstants.SCHEMA_KEYSPACE_NAME, - SchemaKeyspaceTables.TABLES), - KEYSPACE, - currentTable()), - row(expected)); + createTable("CREATE TABLE %s (a text, b int, c int, primary key (a, b))" + + " WITH memtable = '" + memtableConfig + "';"); + assertSame(factoryInstance, getCurrentColumnFamilyStore().metadata().params.memtable.factory()); + Assert.assertTrue(memtableClass.isInstance(getCurrentColumnFamilyStore().getTracker().getView().getCurrentMemtable())); + + assertMemtableOptionVersion4(MemtableParams.DEFAULT.configurationKey().equals(memtableConfig) ? null : memtableConfig, + expectedSchemaMap); + } + + private void testMapMemtableConfigVersion4(String memtableConfig, Object expectedSchemaMap, Memtable.Factory factoryInstance, Class memtableClass) throws Throwable + { + String memtableMap = "".equals(memtableConfig) ? memtableConfig : String.format("'class' : '%s'", memtableConfig); + createTable("CREATE TABLE %s (a text, b int, c int, primary key (a, b))" + + " WITH memtable = {" + memtableMap + "};"); + assertSame(factoryInstance, getCurrentColumnFamilyStore().metadata().params.memtable.factory()); + Assert.assertTrue(memtableClass.isInstance(getCurrentColumnFamilyStore().getTracker().getView().getCurrentMemtable())); + + // For map-based CREATE, always write the expected schema map (not null) + assertSchemaOption("memtable", expectedSchemaMap); } @Test diff --git a/test/unit/org/apache/cassandra/db/SchemaCQLHelperTest.java b/test/unit/org/apache/cassandra/db/SchemaCQLHelperTest.java index 070b84f383e3..8ce64313b858 100644 --- a/test/unit/org/apache/cassandra/db/SchemaCQLHelperTest.java +++ b/test/unit/org/apache/cassandra/db/SchemaCQLHelperTest.java @@ -41,6 +41,7 @@ import org.apache.cassandra.SchemaLoader; import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.cql3.CQLTester; +import org.apache.cassandra.utils.CassandraVersion; import org.apache.cassandra.cql3.ColumnIdentifier; import org.apache.cassandra.cql3.FieldIdentifier; import org.apache.cassandra.cql3.statements.schema.IndexTarget; @@ -386,23 +387,33 @@ public void testCfmOptionsCQL() ColumnFamilyStore cfs = Keyspace.open(keyspace).getColumnFamilyStore(table); + boolean isCompatibilityMode = DatabaseDescriptor.getStorageCompatibilityMode().isBefore(5); + String memtableFormat = isCompatibilityMode + ? " AND memtable = {}\n" + : " AND memtable = 'default'\n"; + + // allow_auto_snapshot and incremental_backups are not present in pre-5.0 compatibility mode + String autoSnapshotAndIncrementalBackups = isCompatibilityMode + ? "" + : " AND allow_auto_snapshot = true\n" + + " AND incremental_backups = true\n"; + assertThat(SchemaCQLHelper.getTableMetadataAsCQL(cfs.metadata(), cfs.keyspace.getMetadata()), containsString("AND CLUSTERING ORDER BY (cl1 ASC)\n" + " AND DROPPED COLUMN RECORD reg1 ascii USING TIMESTAMP " + droppedTimestamp +"\n" + " AND additional_write_policy = 'ALWAYS'\n" + - " AND allow_auto_snapshot = true\n" + + autoSnapshotAndIncrementalBackups + " AND bloom_filter_fp_chance = 1.0\n" + " AND caching = {'keys': 'ALL', 'rows_per_partition': 'NONE'}\n" + " AND cdc = false\n" + " AND comment = 'comment'\n" + " AND compaction = {'class': 'org.apache.cassandra.db.compaction.LeveledCompactionStrategy', 'max_threshold': '32', 'min_threshold': '4', 'sstable_size_in_mb': '1'}\n" + " AND compression = {'chunk_length_in_kb': '64', 'class': 'org.apache.cassandra.io.compress.LZ4Compressor', 'min_compress_ratio': '2.0'}\n" + - " AND memtable = 'default'\n" + + memtableFormat + " AND crc_check_chance = 0.3\n" + " AND default_time_to_live = 4\n" + " AND extensions = {'ext1': 0x76616c31}\n" + " AND gc_grace_seconds = 5\n" + - " AND incremental_backups = true\n" + " AND max_index_interval = 7\n" + " AND memtable_flush_period_in_ms = 8\n" + " AND min_index_interval = 6\n" + @@ -840,11 +851,14 @@ public void testParseCc40MemtableFormat() ColumnFamilyStore cfs7 = Keyspace.open(keyspace).getColumnFamilyStore(tableName7); Assertions.assertThat(cfs7.metadata().params.memtable.configurationKey()).isEqualTo("trie"); - // Test parsing CC 4.0 format with ShardedSkipListMemtable (short name) - String tableName8 = createTable(keyspace, "CREATE TABLE %s (id int PRIMARY KEY, value text) WITH memtable = {'class': 'ShardedSkipListMemtable'}"); - ColumnFamilyStore cfs8 = Keyspace.open(keyspace).getColumnFamilyStore(tableName8); - Assertions.assertThat(cfs8.metadata().params.memtable.configurationKey()).isEqualTo("skiplist_sharded"); - + // Sharded memtables require Cassandra 5.0+, skip this test in compatibility mode + if (!DatabaseDescriptor.getStorageCompatibilityMode().isBefore(CassandraVersion.CASSANDRA_5_0.major)) + { + // Test parsing CC 4.0 format with ShardedSkipListMemtable (short name) + String tableName8 = createTable(keyspace, "CREATE TABLE %s (id int PRIMARY KEY, value text) WITH memtable = {'class': 'ShardedSkipListMemtable'}"); + ColumnFamilyStore cfs8 = Keyspace.open(keyspace).getColumnFamilyStore(tableName8); + Assertions.assertThat(cfs8.metadata().params.memtable.configurationKey()).isEqualTo("skiplist_sharded"); + } // Test parsing CC 4.0 format with empty map (default) String tableName9 = createTable(keyspace, "CREATE TABLE %s (id int PRIMARY KEY, value text) WITH memtable = {}"); ColumnFamilyStore cfs9 = Keyspace.open(keyspace).getColumnFamilyStore(tableName9); @@ -910,12 +924,16 @@ public void testToMapForCC4OutputFormat() Assertions.assertThat(cql2).contains("memtable = {'class': 'SkipListMemtable'"); Assertions.assertThat(cql2).doesNotContain("org.apache.cassandra.db.memtable.SkipListMemtable"); - String tableName3 = createTable(keyspace, "CREATE TABLE %s (id int PRIMARY KEY, value text) WITH memtable = 'skiplist_sharded'"); - ColumnFamilyStore cfs3 = Keyspace.open(keyspace).getColumnFamilyStore(tableName3); - String cql3 = SchemaCQLHelper.getTableMetadataAsCQL(cfs3.metadata(), cfs3.keyspace.getMetadata()); - // Should output short class name for standard Cassandra memtable - Assertions.assertThat(cql3).contains("memtable = {'class': 'ShardedSkipListMemtable'"); - Assertions.assertThat(cql3).doesNotContain("org.apache.cassandra.db.memtable.ShardedSkipListMemtable"); + // Sharded memtables require Cassandra 5.0+, skip this test in compatibility mode + if (!DatabaseDescriptor.getStorageCompatibilityMode().isBefore(CassandraVersion.CASSANDRA_5_0.major)) + { + String tableName3 = createTable(keyspace, "CREATE TABLE %s (id int PRIMARY KEY, value text) WITH memtable = 'skiplist_sharded'"); + ColumnFamilyStore cfs3 = Keyspace.open(keyspace).getColumnFamilyStore(tableName3); + String cql3 = SchemaCQLHelper.getTableMetadataAsCQL(cfs3.metadata(), cfs3.keyspace.getMetadata()); + // Should output short class name for standard Cassandra memtable + Assertions.assertThat(cql3).contains("memtable = {'class': 'ShardedSkipListMemtable'"); + Assertions.assertThat(cql3).doesNotContain("org.apache.cassandra.db.memtable.ShardedSkipListMemtable"); + } // Test that tables created with fully qualified class names also output short class names String tableName4 = createTable(keyspace, "CREATE TABLE %s (id int PRIMARY KEY, value text) WITH memtable = {'class': 'org.apache.cassandra.db.memtable.TrieMemtable'}"); diff --git a/test/unit/org/apache/cassandra/db/SystemKeyspaceMigrator41Test.java b/test/unit/org/apache/cassandra/db/SystemKeyspaceMigrator41Test.java index a804e152ae45..0c00857befa8 100644 --- a/test/unit/org/apache/cassandra/db/SystemKeyspaceMigrator41Test.java +++ b/test/unit/org/apache/cassandra/db/SystemKeyspaceMigrator41Test.java @@ -308,7 +308,9 @@ public void testMigrateCompactionHistory() throws Throwable assertEquals(compactAt, row.getTimestamp("compacted_at")); assertEquals("keyspace", row.getString("keyspace_name")); assertEquals(rowsMerged, row.getMap("rows_merged", Int32Type.instance, LongType.instance)); - assertEquals(ImmutableMap.of(), row.getMap("compaction_properties", UTF8Type.instance, UTF8Type.instance)); + // compaction_properties column only exists in Cassandra 5.0+ + if (!DatabaseDescriptor.getStorageCompatibilityMode().isBefore(CassandraVersion.CASSANDRA_5_0.major)) + assertEquals(ImmutableMap.of(), row.getMap("compaction_properties", UTF8Type.instance, UTF8Type.instance)); } assertEquals(1, rowCount); diff --git a/test/unit/org/apache/cassandra/db/commitlog/CommitLogDescriptorTest.java b/test/unit/org/apache/cassandra/db/commitlog/CommitLogDescriptorTest.java index eef2823012d3..a9577ae30f30 100644 --- a/test/unit/org/apache/cassandra/db/commitlog/CommitLogDescriptorTest.java +++ b/test/unit/org/apache/cassandra/db/commitlog/CommitLogDescriptorTest.java @@ -85,7 +85,13 @@ public void testVersions() Assert.assertEquals(1340512736956320000L, CommitLogDescriptor.fromFileName("CommitLog-2-1340512736956320000.log").id); - Assert.assertEquals(MessagingService.current_version, new CommitLogDescriptor(1340512736956320000L, null, neverEnabledEncryption).getMessagingVersion()); + // The CommitLogDescriptor constructor uses currentStorageVersion() which + // respects storage compatibility mode, so expect the storage messaging version. + int expectedVersion = StorageCompatibilityMode.current().storageMessagingVersion(); + Assert.assertEquals(expectedVersion, new CommitLogDescriptor(1340512736956320000L, null, neverEnabledEncryption).getMessagingVersion()); + + // CURRENT_VERSION is computed from MessagingService.current_version (doesn't respect SCM) + // but when we read from a filename, it should return the messaging version that corresponds to the version in the filename String newCLName = "CommitLog-" + CommitLogDescriptor.CURRENT_VERSION + "-1340512736956320000.log"; Assert.assertEquals(MessagingService.current_version, CommitLogDescriptor.fromFileName(newCLName).getMessagingVersion()); } diff --git a/test/unit/org/apache/cassandra/db/memtable/MemtableQuickTest.java b/test/unit/org/apache/cassandra/db/memtable/MemtableQuickTest.java index 279ec0992096..8fef89ce7c08 100644 --- a/test/unit/org/apache/cassandra/db/memtable/MemtableQuickTest.java +++ b/test/unit/org/apache/cassandra/db/memtable/MemtableQuickTest.java @@ -32,12 +32,15 @@ import org.slf4j.LoggerFactory; import org.apache.cassandra.Util; +import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.cql3.CQLTester; import org.apache.cassandra.cql3.UntypedResultSet; import org.apache.cassandra.db.ColumnFamilyStore; import org.apache.cassandra.db.Keyspace; import org.apache.cassandra.dht.Range; import org.apache.cassandra.io.sstable.format.SSTableReader; +import org.apache.cassandra.utils.CassandraVersion; +import org.apache.cassandra.utils.StorageCompatibilityMode; import org.apache.cassandra.utils.concurrent.Refs; @RunWith(Parameterized.class) @@ -60,12 +63,22 @@ public class MemtableQuickTest extends CQLTester @Parameterized.Parameters(name = "{0}") public static List parameters() { - return ImmutableList.of("skiplist", - "skiplist_sharded", - "skiplist_sharded_locking", - "trie", - "trie_stage1", - "persistent_memory"); + // Sharded memtables require Cassandra 5.0+, skip them in compatibility mode + StorageCompatibilityMode mode = DatabaseDescriptor.getStorageCompatibilityMode(); + boolean skipSharded = mode != null && mode.isBefore(CassandraVersion.CASSANDRA_5_0.major); + + ImmutableList.Builder params = ImmutableList.builder(); + params.add("skiplist"); + if (!skipSharded) + { + params.add("skiplist_sharded"); + params.add("skiplist_sharded_locking"); + } + params.add("trie"); + params.add("trie_stage1"); + params.add("persistent_memory"); + + return params.build(); } @BeforeClass diff --git a/test/unit/org/apache/cassandra/db/memtable/MemtableSizeTestBase.java b/test/unit/org/apache/cassandra/db/memtable/MemtableSizeTestBase.java index 0b9d8922092d..071b4c420895 100644 --- a/test/unit/org/apache/cassandra/db/memtable/MemtableSizeTestBase.java +++ b/test/unit/org/apache/cassandra/db/memtable/MemtableSizeTestBase.java @@ -40,7 +40,9 @@ import org.apache.cassandra.db.Keyspace; import org.apache.cassandra.dht.IPartitioner; import org.apache.cassandra.service.StorageService; +import org.apache.cassandra.utils.CassandraVersion; import org.apache.cassandra.utils.FBUtilities; +import org.apache.cassandra.utils.StorageCompatibilityMode; import org.github.jamm.MemoryMeter; import org.github.jamm.MemoryMeter.Guess; @@ -77,10 +79,18 @@ public abstract class MemtableSizeTestBase extends CQLTester @Parameterized.Parameters(name = "{0}") public static List parameters() { - return ImmutableList.of("skiplist", - "skiplist_sharded", - "trie_stage1", - "trie"); + // Sharded memtables require Cassandra 5.0+, skip them in compatibility mode + StorageCompatibilityMode mode = DatabaseDescriptor.getStorageCompatibilityMode(); + boolean skipSharded = mode != null && mode.isBefore(CassandraVersion.CASSANDRA_5_0.major); + + ImmutableList.Builder params = ImmutableList.builder(); + params.add("skiplist"); + if (!skipSharded) + params.add("skiplist_sharded"); + params.add("trie_stage1"); + params.add("trie"); + + return params.build(); } // Must be within 3% of the real usage. We are actually more precise than this, but the threshold is set higher to diff --git a/test/unit/org/apache/cassandra/db/virtual/CIDRFilteringMetricsTableTest.java b/test/unit/org/apache/cassandra/db/virtual/CIDRFilteringMetricsTableTest.java index 889d86213548..3c4985541d68 100644 --- a/test/unit/org/apache/cassandra/db/virtual/CIDRFilteringMetricsTableTest.java +++ b/test/unit/org/apache/cassandra/db/virtual/CIDRFilteringMetricsTableTest.java @@ -28,6 +28,7 @@ import com.google.common.collect.ImmutableList; import org.junit.Assert; +import org.junit.Assume; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; @@ -47,6 +48,7 @@ import org.apache.cassandra.db.Keyspace; import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.metrics.CIDRAuthorizerMetrics; +import org.apache.cassandra.utils.CassandraVersion; import static org.apache.cassandra.auth.AuthKeyspace.CIDR_GROUPS; import static org.apache.cassandra.auth.AuthKeyspace.CIDR_PERMISSIONS; @@ -71,6 +73,9 @@ private static void setupSuperUser() @BeforeClass public static void defineSchema() throws ConfigurationException { + Assume.assumeFalse("CIDR features require Cassandra 5.0+", + DatabaseDescriptor.getStorageCompatibilityMode().isBefore(CassandraVersion.CASSANDRA_5_0.major)); + SchemaLoader.prepareServer(); SchemaLoader.setupAuth(new AuthTestUtils.LocalCassandraRoleManager(), diff --git a/test/unit/org/apache/cassandra/tools/nodetool/CIDRFilteringStatsTest.java b/test/unit/org/apache/cassandra/tools/nodetool/CIDRFilteringStatsTest.java index ec415df09be2..4985d61eae64 100644 --- a/test/unit/org/apache/cassandra/tools/nodetool/CIDRFilteringStatsTest.java +++ b/test/unit/org/apache/cassandra/tools/nodetool/CIDRFilteringStatsTest.java @@ -21,6 +21,7 @@ import java.net.InetSocketAddress; import java.util.Collections; +import org.junit.Assume; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; @@ -28,6 +29,7 @@ import org.apache.cassandra.auth.AuthCacheService; import org.apache.cassandra.auth.AuthTestUtils; import org.apache.cassandra.auth.AuthenticatedUser; +import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.cql3.CIDR; import org.apache.cassandra.cql3.CQLTester; import org.apache.cassandra.db.virtual.CIDRFilteringMetricsTable; @@ -35,6 +37,7 @@ import org.apache.cassandra.db.virtual.VirtualKeyspaceRegistry; import org.apache.cassandra.schema.SchemaConstants; import org.apache.cassandra.tools.ToolRunner; +import org.apache.cassandra.utils.CassandraVersion; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertFalse; @@ -45,6 +48,9 @@ public class CIDRFilteringStatsTest extends CQLTester @BeforeClass public static void setup() throws Exception { + Assume.assumeFalse("CIDR features require Cassandra 5.0+", + DatabaseDescriptor.getStorageCompatibilityMode().isBefore(CassandraVersion.CASSANDRA_5_0.major)); + CQLTester.setUpClass(); CQLTester.requireAuthentication(); AuthCacheService.initializeAndRegisterCaches(); diff --git a/test/unit/org/apache/cassandra/tools/nodetool/CompactionHistoryTest.java b/test/unit/org/apache/cassandra/tools/nodetool/CompactionHistoryTest.java index 7dbda7768454..925647d19395 100644 --- a/test/unit/org/apache/cassandra/tools/nodetool/CompactionHistoryTest.java +++ b/test/unit/org/apache/cassandra/tools/nodetool/CompactionHistoryTest.java @@ -27,6 +27,7 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; +import org.junit.Assume; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; @@ -34,12 +35,14 @@ import org.junit.runners.Parameterized.Parameter; import org.junit.runners.Parameterized.Parameters; +import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.cql3.CQLTester; import org.apache.cassandra.db.ColumnFamilyStore; import org.apache.cassandra.db.Keyspace; import org.apache.cassandra.db.SystemKeyspace; import org.apache.cassandra.db.compaction.OperationType; import org.apache.cassandra.tools.ToolRunner.ToolResult; +import org.apache.cassandra.utils.CassandraVersion; import org.apache.cassandra.utils.FBUtilities; import static org.apache.cassandra.db.compaction.CompactionHistoryTabularData.COMPACTION_TYPE_PROPERTY; @@ -72,6 +75,8 @@ public static Collection data() @BeforeClass public static void setup() throws Exception { + Assume.assumeFalse("Compaction properties feature requires Cassandra 5.0+", + DatabaseDescriptor.getStorageCompatibilityMode().isBefore(CassandraVersion.CASSANDRA_5_0.major)); requireNetwork(); startJMXServer(); } diff --git a/test/unit/org/apache/cassandra/tools/nodetool/DropCIDRGroupTest.java b/test/unit/org/apache/cassandra/tools/nodetool/DropCIDRGroupTest.java index 4ec303068fba..545208a98451 100644 --- a/test/unit/org/apache/cassandra/tools/nodetool/DropCIDRGroupTest.java +++ b/test/unit/org/apache/cassandra/tools/nodetool/DropCIDRGroupTest.java @@ -23,15 +23,18 @@ import java.util.List; import java.util.Map; +import org.junit.Assume; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.apache.cassandra.auth.AuthCacheService; import org.apache.cassandra.auth.AuthTestUtils; +import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.cql3.CIDR; import org.apache.cassandra.cql3.CQLTester; import org.apache.cassandra.tools.ToolRunner; +import org.apache.cassandra.utils.CassandraVersion; import static org.assertj.core.api.Assertions.assertThat; @@ -40,6 +43,9 @@ public class DropCIDRGroupTest extends CQLTester @BeforeClass public static void setup() throws Exception { + Assume.assumeFalse("CIDR features require Cassandra 5.0+", + DatabaseDescriptor.getStorageCompatibilityMode().isBefore(CassandraVersion.CASSANDRA_5_0.major)); + CQLTester.setUpClass(); CQLTester.requireAuthentication(); AuthCacheService.initializeAndRegisterCaches(); diff --git a/test/unit/org/apache/cassandra/tools/nodetool/GetCIDRGroupsOfIPTest.java b/test/unit/org/apache/cassandra/tools/nodetool/GetCIDRGroupsOfIPTest.java index e8844053c3a1..45ec589bd7d5 100644 --- a/test/unit/org/apache/cassandra/tools/nodetool/GetCIDRGroupsOfIPTest.java +++ b/test/unit/org/apache/cassandra/tools/nodetool/GetCIDRGroupsOfIPTest.java @@ -23,15 +23,18 @@ import java.util.List; import java.util.Map; +import org.junit.Assume; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.apache.cassandra.auth.AuthCacheService; import org.apache.cassandra.auth.AuthTestUtils; +import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.cql3.CIDR; import org.apache.cassandra.cql3.CQLTester; import org.apache.cassandra.tools.ToolRunner; +import org.apache.cassandra.utils.CassandraVersion; import static org.assertj.core.api.Assertions.assertThat; @@ -40,6 +43,9 @@ public class GetCIDRGroupsOfIPTest extends CQLTester @BeforeClass public static void setup() throws Exception { + Assume.assumeFalse("CIDR features require Cassandra 5.0+", + DatabaseDescriptor.getStorageCompatibilityMode().isBefore(CassandraVersion.CASSANDRA_5_0.major)); + CQLTester.setUpClass(); CQLTester.requireAuthentication(); AuthCacheService.initializeAndRegisterCaches(); diff --git a/test/unit/org/apache/cassandra/tools/nodetool/InvalidateCIDRPermissionsCacheTest.java b/test/unit/org/apache/cassandra/tools/nodetool/InvalidateCIDRPermissionsCacheTest.java index ec75c587b0ff..3ff47cd166d1 100644 --- a/test/unit/org/apache/cassandra/tools/nodetool/InvalidateCIDRPermissionsCacheTest.java +++ b/test/unit/org/apache/cassandra/tools/nodetool/InvalidateCIDRPermissionsCacheTest.java @@ -20,6 +20,7 @@ import java.net.InetSocketAddress; +import org.junit.Assume; import org.junit.BeforeClass; import org.junit.Test; @@ -31,6 +32,7 @@ import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.cql3.CQLTester; import org.apache.cassandra.tools.ToolRunner; +import org.apache.cassandra.utils.CassandraVersion; import static org.apache.cassandra.auth.AuthTestUtils.ROLE_A; import static org.apache.cassandra.auth.AuthTestUtils.ROLE_B; @@ -44,6 +46,9 @@ public class InvalidateCIDRPermissionsCacheTest extends CQLTester @BeforeClass public static void setup() throws Exception { + Assume.assumeFalse("CIDR features require Cassandra 5.0+", + DatabaseDescriptor.getStorageCompatibilityMode().isBefore(CassandraVersion.CASSANDRA_5_0.major)); + DatabaseDescriptor.setRolesValidity(Integer.MAX_VALUE-1); CQLTester.setUpClass(); CQLTester.requireAuthentication(); diff --git a/test/unit/org/apache/cassandra/tools/nodetool/ListCIDRGroupTest.java b/test/unit/org/apache/cassandra/tools/nodetool/ListCIDRGroupTest.java index a6b377d9dcd5..1fde1e03a61f 100644 --- a/test/unit/org/apache/cassandra/tools/nodetool/ListCIDRGroupTest.java +++ b/test/unit/org/apache/cassandra/tools/nodetool/ListCIDRGroupTest.java @@ -24,14 +24,17 @@ import java.util.List; import java.util.Map; +import org.junit.Assume; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.apache.cassandra.auth.AuthCacheService; +import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.cql3.CIDR; import org.apache.cassandra.cql3.CQLTester; import org.apache.cassandra.tools.ToolRunner; +import org.apache.cassandra.utils.CassandraVersion; import static org.apache.cassandra.auth.AuthTestUtils.insertCidrsMappings; import static org.assertj.core.api.Assertions.assertThat; @@ -41,6 +44,9 @@ public class ListCIDRGroupTest extends CQLTester @BeforeClass public static void setup() throws Exception { + Assume.assumeFalse("CIDR features require Cassandra 5.0+", + DatabaseDescriptor.getStorageCompatibilityMode().isBefore(CassandraVersion.CASSANDRA_5_0.major)); + CQLTester.setUpClass(); CQLTester.requireAuthentication(); AuthCacheService.initializeAndRegisterCaches(); diff --git a/test/unit/org/apache/cassandra/tools/nodetool/ReloadCIDRGroupsCacheTest.java b/test/unit/org/apache/cassandra/tools/nodetool/ReloadCIDRGroupsCacheTest.java index 3237d77c32aa..64525f44e4cd 100644 --- a/test/unit/org/apache/cassandra/tools/nodetool/ReloadCIDRGroupsCacheTest.java +++ b/test/unit/org/apache/cassandra/tools/nodetool/ReloadCIDRGroupsCacheTest.java @@ -20,6 +20,7 @@ import java.net.InetSocketAddress; +import org.junit.Assume; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; @@ -31,6 +32,7 @@ import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.cql3.CQLTester; import org.apache.cassandra.tools.ToolRunner; +import org.apache.cassandra.utils.CassandraVersion; import static java.lang.String.format; import static org.apache.cassandra.auth.AuthKeyspace.CIDR_GROUPS; @@ -46,6 +48,9 @@ public class ReloadCIDRGroupsCacheTest extends CQLTester @BeforeClass public static void setup() throws Exception { + Assume.assumeFalse("CIDR features require Cassandra 5.0+", + DatabaseDescriptor.getStorageCompatibilityMode().isBefore(CassandraVersion.CASSANDRA_5_0.major)); + CQLTester.setUpClass(); CQLTester.requireAuthentication(); diff --git a/test/unit/org/apache/cassandra/tools/nodetool/TableHistogramsTest.java b/test/unit/org/apache/cassandra/tools/nodetool/TableHistogramsTest.java index 733b876c092c..f82997fa969b 100644 --- a/test/unit/org/apache/cassandra/tools/nodetool/TableHistogramsTest.java +++ b/test/unit/org/apache/cassandra/tools/nodetool/TableHistogramsTest.java @@ -42,7 +42,7 @@ public class TableHistogramsTest extends CQLTester private final int ALL_TABLE_SIZE = SystemKeyspace.TABLE_NAMES.size() + SchemaKeyspace.metadata().tables.size() + TraceKeyspace.TABLE_NAMES.size() + - AuthKeyspace.TABLE_NAMES.size() + + AuthKeyspace.tableNames().size() + SystemDistributedKeyspace.TABLE_NAMES.size(); @BeforeClass diff --git a/test/unit/org/apache/cassandra/tools/nodetool/UpdateCIDRGroupTest.java b/test/unit/org/apache/cassandra/tools/nodetool/UpdateCIDRGroupTest.java index b3fbb9d34d8e..98300c8977c0 100644 --- a/test/unit/org/apache/cassandra/tools/nodetool/UpdateCIDRGroupTest.java +++ b/test/unit/org/apache/cassandra/tools/nodetool/UpdateCIDRGroupTest.java @@ -18,13 +18,16 @@ package org.apache.cassandra.tools.nodetool; +import org.junit.Assume; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.apache.cassandra.auth.AuthCacheService; +import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.cql3.CQLTester; import org.apache.cassandra.tools.ToolRunner; +import org.apache.cassandra.utils.CassandraVersion; import static java.lang.String.format; import static org.apache.cassandra.auth.AuthKeyspace.CIDR_GROUPS; @@ -36,6 +39,9 @@ public class UpdateCIDRGroupTest extends CQLTester @BeforeClass public static void setup() throws Exception { + Assume.assumeFalse("CIDR features require Cassandra 5.0+", + DatabaseDescriptor.getStorageCompatibilityMode().isBefore(CassandraVersion.CASSANDRA_5_0.major)); + CQLTester.setUpClass(); CQLTester.requireAuthentication(); AuthCacheService.initializeAndRegisterCaches(); diff --git a/test/unit/org/apache/cassandra/utils/CassandraGenerators.java b/test/unit/org/apache/cassandra/utils/CassandraGenerators.java index b064ec98fc74..801eb60ae61c 100644 --- a/test/unit/org/apache/cassandra/utils/CassandraGenerators.java +++ b/test/unit/org/apache/cassandra/utils/CassandraGenerators.java @@ -206,7 +206,16 @@ public TableMetadataBuilder withKnownMemtables() { Set known = MemtableParams.knownDefinitions(); // for testing reason, some invalid types are added; filter out - List valid = known.stream().filter(name -> !name.startsWith("test_")).collect(Collectors.toList()); + // Also filter out CC5-only types (sharded memtables) when in HCD_1/CC4 mode + List valid = known.stream() + .filter(name -> !name.startsWith("test_")) + .filter(name -> { + // Filter out sharded memtables when in CC4 compatibility mode + if (DatabaseDescriptor.getStorageCompatibilityMode().isBefore(org.apache.cassandra.utils.CassandraVersion.CASSANDRA_5_0.major)) + return !name.toLowerCase().contains("sharded"); + return true; + }) + .collect(Collectors.toList()); memtableKeyGen = SourceDSL.arbitrary().pick(valid); return this; }