diff --git a/CHANGES.txt b/CHANGES.txt
index 5a59323aa0..4844c9eb61 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,6 +1,7 @@
3.11.15
* Fix Splitter sometimes creating more splits than requested (CASSANDRA-18013)
Merged from 3.0:
+ * Introduce check for names of test classes (CASSANDRA-17964)
* Suppress CVE-2021-1471, CVE-2021-3064, CVE-2021-4235 (CASSANDRA-18149)
* Switch to snakeyaml's SafeConstructor (CASSANDRA-18150)
* Expand build.dir property in rat targets (CASSANDRA-18183)
diff --git a/build.xml b/build.xml
index 590e523fce..e379340841 100644
--- a/build.xml
+++ b/build.xml
@@ -68,6 +68,7 @@
+
@@ -383,7 +384,7 @@
-
+
@@ -1118,6 +1119,7 @@
+
@@ -1125,12 +1127,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/anttasks/org/apache/cassandra/anttasks/TestNameCheckTask.java b/test/anttasks/org/apache/cassandra/anttasks/TestNameCheckTask.java
new file mode 100644
index 0000000000..a5222261f2
--- /dev/null
+++ b/test/anttasks/org/apache/cassandra/anttasks/TestNameCheckTask.java
@@ -0,0 +1,85 @@
+/*
+ * 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.cassandra.anttasks;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Stream;
+
+import org.junit.Test;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.reflections.Reflections;
+import org.reflections.scanners.Scanners;
+import org.reflections.util.ConfigurationBuilder;
+
+import static java.util.stream.Collectors.toList;
+
+public class TestNameCheckTask extends Task
+{
+ private static final Reflections reflections = new Reflections(new ConfigurationBuilder()
+ .forPackage("org.apache.cassandra")
+ .setScanners(Scanners.MethodsAnnotated, Scanners.SubTypes)
+ .setExpandSuperTypes(true)
+ .setParallel(true));
+
+ public TestNameCheckTask()
+ {
+ }
+
+ @Override
+ public void execute() throws BuildException
+ {
+ Set methodsAnnotatedWith = reflections.getMethodsAnnotatedWith(Test.class);
+ List testFiles = methodsAnnotatedWith.stream().map(Method::getDeclaringClass).distinct()
+ .flatMap(TestNameCheckTask::expand)
+ .map(TestNameCheckTask::normalize)
+ .map(Class::getCanonicalName)
+ .filter(s -> !s.endsWith("Test"))
+ .distinct().sorted()
+ .collect(toList());
+
+ if (!testFiles.isEmpty())
+ throw new BuildException("Detected tests that have a bad naming convention. All tests have to end on 'Test': \n" + String.join("\n", testFiles));
+ }
+
+ private static Class> normalize(Class> klass)
+ {
+ for (; klass.getEnclosingClass() != null; klass = klass.getEnclosingClass())
+ {
+ }
+ return klass;
+ }
+
+ private static Stream> expand(Class> klass)
+ {
+ Set extends Class>> subTypes = reflections.getSubTypesOf(klass);
+ if (subTypes == null || subTypes.isEmpty())
+ return Stream.of(klass);
+ Stream> subs = (Stream>) subTypes.stream();
+ // assume we include if not abstract
+ if (!Modifier.isAbstract(klass.getModifiers()))
+ subs = Stream.concat(Stream.of(klass), subs);
+ return subs;
+ }
+
+
+}
diff --git a/test/distributed/org/apache/cassandra/distributed/test/ByteBuddyExamples.java b/test/distributed/org/apache/cassandra/distributed/test/ByteBuddyExamplesTest.java
similarity index 98%
rename from test/distributed/org/apache/cassandra/distributed/test/ByteBuddyExamples.java
rename to test/distributed/org/apache/cassandra/distributed/test/ByteBuddyExamplesTest.java
index b49572dc4b..aea3609c84 100644
--- a/test/distributed/org/apache/cassandra/distributed/test/ByteBuddyExamples.java
+++ b/test/distributed/org/apache/cassandra/distributed/test/ByteBuddyExamplesTest.java
@@ -41,7 +41,7 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
-public class ByteBuddyExamples extends TestBaseImpl
+public class ByteBuddyExamplesTest extends TestBaseImpl
{
@Test
public void writeFailureTest() throws Throwable
diff --git a/test/distributed/org/apache/cassandra/distributed/test/BytemanExamples.java b/test/distributed/org/apache/cassandra/distributed/test/BytemanExamplesTest.java
similarity index 99%
rename from test/distributed/org/apache/cassandra/distributed/test/BytemanExamples.java
rename to test/distributed/org/apache/cassandra/distributed/test/BytemanExamplesTest.java
index 41bcfb498d..6d542b8bdd 100644
--- a/test/distributed/org/apache/cassandra/distributed/test/BytemanExamples.java
+++ b/test/distributed/org/apache/cassandra/distributed/test/BytemanExamplesTest.java
@@ -29,7 +29,7 @@ import org.junit.Test;
import org.apache.cassandra.distributed.Cluster;
import org.apache.cassandra.distributed.shared.Byteman;
-public class BytemanExamples
+public class BytemanExamplesTest
{
@Test
public void rewriteFromText() throws IOException
diff --git a/test/distributed/org/apache/cassandra/distributed/test/ReprepareTestOldBehaviour.java b/test/distributed/org/apache/cassandra/distributed/test/ReprepareOldBehaviourTest.java
similarity index 98%
rename from test/distributed/org/apache/cassandra/distributed/test/ReprepareTestOldBehaviour.java
rename to test/distributed/org/apache/cassandra/distributed/test/ReprepareOldBehaviourTest.java
index 9900febaea..ff23e79431 100644
--- a/test/distributed/org/apache/cassandra/distributed/test/ReprepareTestOldBehaviour.java
+++ b/test/distributed/org/apache/cassandra/distributed/test/ReprepareOldBehaviourTest.java
@@ -30,7 +30,7 @@ import static org.apache.cassandra.distributed.api.Feature.GOSSIP;
import static org.apache.cassandra.distributed.api.Feature.NATIVE_PROTOCOL;
import static org.apache.cassandra.distributed.api.Feature.NETWORK;
-public class ReprepareTestOldBehaviour extends ReprepareTestBase
+public class ReprepareOldBehaviourTest extends ReprepareTestBase
{
@Test
public void testReprepareMixedVersion() throws Throwable
@@ -77,7 +77,7 @@ public class ReprepareTestOldBehaviour extends ReprepareTestBase
}
}
- @Test
+ @Test // see CASSANDRA-18021
public void testReprepareMixedVersionWithoutReset() throws Throwable
{
try (ICluster c = init(builder().withNodes(2)
diff --git a/test/long/org/apache/cassandra/cql3/CachingBench.java b/test/microbench/org/apache/cassandra/test/microbench/CachingBenchTest.java
similarity index 98%
rename from test/long/org/apache/cassandra/cql3/CachingBench.java
rename to test/microbench/org/apache/cassandra/test/microbench/CachingBenchTest.java
index 25f746b195..4af7a3bc02 100644
--- a/test/long/org/apache/cassandra/cql3/CachingBench.java
+++ b/test/microbench/org/apache/cassandra/test/microbench/CachingBenchTest.java
@@ -16,7 +16,7 @@
* limitations under the License.
*/
-package org.apache.cassandra.cql3;
+package org.apache.cassandra.test.microbench;
import java.util.ArrayList;
import java.util.Arrays;
@@ -38,6 +38,8 @@ import org.apache.cassandra.config.Config.CommitLogSync;
import org.apache.cassandra.config.Config.DiskAccessMode;
import org.apache.cassandra.cache.ChunkCache;
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.compaction.CompactionManager;
import org.apache.cassandra.db.rows.Row;
@@ -48,7 +50,7 @@ import org.apache.cassandra.io.sstable.format.SSTableReader;
import org.apache.cassandra.io.util.FileUtils;
import org.apache.cassandra.utils.FBUtilities;
-public class CachingBench extends CQLTester
+public class CachingBenchTest extends CQLTester
{
private static final String STRATEGY = "LeveledCompactionStrategy";
diff --git a/test/long/org/apache/cassandra/cql3/GcCompactionBench.java b/test/microbench/org/apache/cassandra/test/microbench/GcCompactionBenchTest.java
similarity index 98%
rename from test/long/org/apache/cassandra/cql3/GcCompactionBench.java
rename to test/microbench/org/apache/cassandra/test/microbench/GcCompactionBenchTest.java
index 203367dba5..59f74d814a 100644
--- a/test/long/org/apache/cassandra/cql3/GcCompactionBench.java
+++ b/test/microbench/org/apache/cassandra/test/microbench/GcCompactionBenchTest.java
@@ -16,7 +16,7 @@
* limitations under the License.
*/
-package org.apache.cassandra.cql3;
+package org.apache.cassandra.test.microbench;
import java.util.ArrayList;
import java.util.Arrays;
@@ -36,6 +36,8 @@ import org.junit.Test;
import junit.framework.Assert;
import org.apache.cassandra.config.Config.CommitLogSync;
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.compaction.CompactionManager;
import org.apache.cassandra.db.rows.Row;
@@ -46,7 +48,7 @@ import org.apache.cassandra.io.sstable.format.SSTableReader;
import org.apache.cassandra.schema.CompactionParams.TombstoneOption;
import org.apache.cassandra.utils.FBUtilities;
-public class GcCompactionBench extends CQLTester
+public class GcCompactionBenchTest extends CQLTester
{
private static final String SIZE_TIERED_STRATEGY = "SizeTieredCompactionStrategy', 'min_sstable_size' : '0";
private static final String LEVELED_STRATEGY = "LeveledCompactionStrategy', 'sstable_size_in_mb' : '16";
diff --git a/test/unit/org/apache/cassandra/cql3/BatchTests.java b/test/unit/org/apache/cassandra/cql3/BatchTest.java
similarity index 99%
rename from test/unit/org/apache/cassandra/cql3/BatchTests.java
rename to test/unit/org/apache/cassandra/cql3/BatchTest.java
index 260db4eeed..28b0d5cbf7 100644
--- a/test/unit/org/apache/cassandra/cql3/BatchTests.java
+++ b/test/unit/org/apache/cassandra/cql3/BatchTest.java
@@ -30,7 +30,7 @@ import org.junit.Test;
import java.io.IOException;
-public class BatchTests extends CQLTester
+public class BatchTest extends CQLTester
{
private static EmbeddedCassandraService cassandra;
diff --git a/test/unit/org/apache/cassandra/utils/UUIDTests.java b/test/unit/org/apache/cassandra/utils/UUIDTest.java
similarity index 98%
rename from test/unit/org/apache/cassandra/utils/UUIDTests.java
rename to test/unit/org/apache/cassandra/utils/UUIDTest.java
index 0d57c47d87..9fa4957e2f 100644
--- a/test/unit/org/apache/cassandra/utils/UUIDTests.java
+++ b/test/unit/org/apache/cassandra/utils/UUIDTest.java
@@ -34,11 +34,10 @@ import org.junit.Test;
import com.google.common.collect.Sets;
import org.apache.cassandra.db.marshal.TimeUUIDType;
-import org.apache.cassandra.utils.UUIDGen;
import org.cliffc.high_scale_lib.NonBlockingHashMap;
-public class UUIDTests
+public class UUIDTest
{
@Test
public void verifyType1()