You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iceberg.apache.org by bl...@apache.org on 2021/10/19 23:12:41 UTC

[iceberg] branch master updated: Spark: Remove redundant abstract test classes (#3321)

This is an automated email from the ASF dual-hosted git repository.

blue pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iceberg.git


The following commit(s) were added to refs/heads/master by this push:
     new 1ee2d03  Spark: Remove redundant abstract test classes (#3321)
1ee2d03 is described below

commit 1ee2d03b2d716fc4224f8b92a51f69a228f8bdef
Author: Anton Okolnychyi <ao...@apple.com>
AuthorDate: Tue Oct 19 16:12:23 2021 -0700

    Spark: Remove redundant abstract test classes (#3321)
---
 .../apache/iceberg/TestScanTaskSerialization.java  |   2 +-
 .../iceberg/TestScanTaskSerialization24.java       |  23 ---
 .../actions/TestDeleteReachableFilesAction.java    |   7 +-
 .../actions/TestDeleteReachableFilesAction24.java  |  30 ---
 .../iceberg/actions/TestExpireSnapshotsAction.java |   2 +-
 .../actions/TestExpireSnapshotsAction24.java       |  23 ---
 .../actions/TestRemoveOrphanFilesAction.java       |   2 +-
 .../actions/TestRemoveOrphanFilesAction24.java     |  23 ---
 .../actions/TestRewriteDataFilesAction.java        |   2 +-
 .../actions/TestRewriteDataFilesAction24.java      |  23 ---
 .../actions/TestRewriteManifestsAction.java        |   2 +-
 .../actions/TestRewriteManifestsAction24.java      |  26 ---
 .../apache/iceberg/spark/source/TestAvroScan.java  |   2 +-
 .../iceberg/spark/source/TestAvroScan24.java       |  23 ---
 .../iceberg/spark/source/TestDataFrameWrites.java  |   2 +-
 .../spark/source/TestDataFrameWrites24.java        |  26 ---
 .../spark/source/TestDataSourceOptions.java        |   2 +-
 .../spark/source/TestDataSourceOptions24.java      |  23 ---
 .../spark/source/TestForwardCompatibility.java     |  15 +-
 .../spark/source/TestForwardCompatibility24.java   |  38 ----
 .../source/TestIcebergSourceHadoopTables.java      |   2 +-
 .../source/TestIcebergSourceHadoopTables24.java    |  23 ---
 .../spark/source/TestIcebergSourceHiveTables.java  |   2 +-
 .../source/TestIcebergSourceHiveTables24.java      |  23 ---
 .../iceberg/spark/source/TestIcebergSpark.java     |   2 +-
 .../iceberg/spark/source/TestIcebergSpark24.java   |  23 ---
 .../spark/source/TestIdentityPartitionData.java    |   2 +-
 .../spark/source/TestIdentityPartitionData24.java  |  26 ---
 .../iceberg/spark/source/TestParquetScan.java      |   2 +-
 .../iceberg/spark/source/TestParquetScan24.java    |  26 ---
 .../iceberg/spark/source/TestPartitionPruning.java |   2 +-
 .../spark/source/TestPartitionPruning24.java       |  26 ---
 .../iceberg/spark/source/TestPartitionValues.java  |   2 +-
 .../spark/source/TestPartitionValues24.java        |  26 ---
 .../spark/source/TestSnapshotSelection.java        |   2 +-
 .../spark/source/TestSnapshotSelection24.java      |  23 ---
 .../spark/source/TestSparkBaseDataReader.java      |   2 +-
 .../spark/source/TestSparkBaseDataReader24.java    |  23 ---
 .../iceberg/spark/source/TestSparkDataFile.java    |   2 +-
 .../iceberg/spark/source/TestSparkDataFile24.java  |  23 ---
 .../iceberg/spark/source/TestSparkDataWrite.java   |   2 +-
 .../iceberg/spark/source/TestSparkDataWrite24.java |  26 ---
 .../spark/source/TestSparkReadProjection.java      |   2 +-
 .../spark/source/TestSparkReadProjection24.java    |  26 ---
 .../spark/source/TestSparkReaderDeletes.java       |   2 +-
 .../spark/source/TestSparkReaderDeletes24.java     |  23 ---
 .../iceberg/spark/source/TestSparkSchema.java      |   2 +-
 .../iceberg/spark/source/TestSparkSchema24.java    |  23 ---
 .../spark/source/TestStructuredStreaming.java      |  15 +-
 .../spark/source/TestStructuredStreaming24.java    |  38 ----
 .../spark/source/TestTimestampWithoutZone.java     |   2 +-
 .../spark/source/TestTimestampWithoutZone24.java   |  26 ---
 .../spark/source/TestWriteMetricsConfig.java       |   2 +-
 .../spark/source/TestWriteMetricsConfig24.java     |  23 ---
 .../apache/iceberg/TestScanTaskSerialization.java  |   2 +-
 .../apache/iceberg/TestScanTaskSerialization3.java |  23 ---
 .../actions/TestDeleteReachableFilesAction.java    |   7 +-
 .../iceberg/actions/TestExpireSnapshotsAction.java |   2 +-
 .../actions/TestExpireSnapshotsAction3.java        |  23 ---
 .../actions/TestNewRewriteDataFilesAction3.java    |  46 -----
 .../iceberg/actions/TestRemoveFilesAction3.java    |  29 ---
 .../actions/TestRewriteDataFilesAction.java        |   2 +-
 .../actions/TestRewriteDataFilesAction3.java       |  23 ---
 .../actions/TestRewriteManifestsAction.java        |   2 +-
 .../actions/TestRewriteManifestsAction3.java       |  26 ---
 .../actions/TestNewRewriteDataFilesAction.java     |  20 +-
 .../apache/iceberg/spark/source/TestAvroScan.java  |   2 +-
 .../apache/iceberg/spark/source/TestAvroScan3.java |  23 ---
 .../iceberg/spark/source/TestDataFrameWrites.java  |   2 +-
 .../iceberg/spark/source/TestDataFrameWrites3.java |  26 ---
 .../spark/source/TestDataSourceOptions.java        |   2 +-
 .../spark/source/TestDataSourceOptions3.java       |  23 ---
 .../spark/source/TestForwardCompatibility.java     |  16 +-
 .../spark/source/TestForwardCompatibility3.java    |  39 ----
 .../source/TestIcebergSourceHadoopTables.java      |   2 +-
 .../source/TestIcebergSourceHadoopTables3.java     |  23 ---
 .../spark/source/TestIcebergSourceHiveTables.java  |   2 +-
 .../spark/source/TestIcebergSourceHiveTables3.java |  23 ---
 .../iceberg/spark/source/TestIcebergSpark.java     |   2 +-
 .../iceberg/spark/source/TestIcebergSpark3.java    |  23 ---
 .../spark/source/TestIdentityPartitionData.java    |   2 +-
 .../spark/source/TestIdentityPartitionData3.java   |  26 ---
 .../iceberg/spark/source/TestParquetScan.java      |   2 +-
 .../iceberg/spark/source/TestParquetScan3.java     |  26 ---
 .../iceberg/spark/source/TestPartitionPruning.java |   2 +-
 .../spark/source/TestPartitionPruning3.java        |  26 ---
 .../iceberg/spark/source/TestPartitionValues.java  |   2 +-
 .../iceberg/spark/source/TestPartitionValues3.java |  26 ---
 .../spark/source/TestSnapshotSelection.java        |   2 +-
 .../spark/source/TestSnapshotSelection3.java       |  23 ---
 .../spark/source/TestSparkBaseDataReader.java      |   2 +-
 .../spark/source/TestSparkBaseDataReader3.java     |  23 ---
 .../iceberg/spark/source/TestSparkDataFile.java    |   2 +-
 .../iceberg/spark/source/TestSparkDataFile3.java   |  23 ---
 .../iceberg/spark/source/TestSparkDataWrite.java   |   2 +-
 .../iceberg/spark/source/TestSparkDataWrite3.java  |  26 ---
 .../spark/source/TestSparkReadProjection.java      |   2 +-
 .../spark/source/TestSparkReadProjection3.java     |  26 ---
 .../spark/source/TestSparkReaderDeletes.java       |   2 +-
 .../spark/source/TestSparkReaderDeletes3.java      |  23 ---
 .../iceberg/spark/source/TestSparkSchema.java      | 213 ---------------------
 .../spark/source/TestStructuredStreaming.java      |  16 +-
 .../spark/source/TestStructuredStreaming3.java     |  39 ----
 .../spark/source/TestTimestampWithoutZone.java     |   2 +-
 .../spark/source/TestTimestampWithoutZone3.java    |  26 ---
 .../spark/source/TestWriteMetricsConfig.java       |   2 +-
 .../spark/source/TestWriteMetricsConfig3.java      |  23 ---
 107 files changed, 114 insertions(+), 1658 deletions(-)

diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/TestScanTaskSerialization.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/TestScanTaskSerialization.java
index 9d10725..e234ee2 100644
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/TestScanTaskSerialization.java
+++ b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/TestScanTaskSerialization.java
@@ -52,7 +52,7 @@ import org.junit.rules.TemporaryFolder;
 
 import static org.apache.iceberg.types.Types.NestedField.optional;
 
-public abstract class TestScanTaskSerialization extends SparkTestBase {
+public class TestScanTaskSerialization extends SparkTestBase {
 
   private static final HadoopTables TABLES = new HadoopTables(new Configuration());
   private static final Schema SCHEMA = new Schema(
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/TestScanTaskSerialization24.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/TestScanTaskSerialization24.java
deleted file mode 100644
index 28184b7..0000000
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/TestScanTaskSerialization24.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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.iceberg;
-
-public class TestScanTaskSerialization24 extends TestScanTaskSerialization {
-}
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/actions/TestDeleteReachableFilesAction.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/actions/TestDeleteReachableFilesAction.java
index b0e783b..0539280 100644
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/actions/TestDeleteReachableFilesAction.java
+++ b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/actions/TestDeleteReachableFilesAction.java
@@ -42,6 +42,7 @@ import org.apache.iceberg.relocated.com.google.common.collect.Lists;
 import org.apache.iceberg.relocated.com.google.common.collect.Maps;
 import org.apache.iceberg.relocated.com.google.common.collect.Sets;
 import org.apache.iceberg.spark.SparkTestBase;
+import org.apache.iceberg.spark.actions.SparkActions;
 import org.apache.iceberg.types.Types;
 import org.junit.Assert;
 import org.junit.Before;
@@ -51,7 +52,7 @@ import org.junit.rules.TemporaryFolder;
 
 import static org.apache.iceberg.types.Types.NestedField.optional;
 
-public abstract class TestDeleteReachableFilesAction extends SparkTestBase {
+public class TestDeleteReachableFilesAction extends SparkTestBase {
   private static final HadoopTables TABLES = new HadoopTables(new Configuration());
   private static final Schema SCHEMA = new Schema(
       optional(1, "c1", Types.IntegerType.get()),
@@ -338,5 +339,7 @@ public abstract class TestDeleteReachableFilesAction extends SparkTestBase {
     return ((HasTableOperations) tbl).operations().current().metadataFileLocation();
   }
 
-  abstract ActionsProvider sparkActions();
+  private ActionsProvider sparkActions() {
+    return SparkActions.get();
+  }
 }
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/actions/TestDeleteReachableFilesAction24.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/actions/TestDeleteReachableFilesAction24.java
deleted file mode 100644
index 80c31e9..0000000
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/actions/TestDeleteReachableFilesAction24.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.iceberg.actions;
-
-import org.apache.iceberg.spark.actions.SparkActions;
-
-public class TestDeleteReachableFilesAction24 extends TestDeleteReachableFilesAction {
-
-  @Override
-  ActionsProvider sparkActions() {
-    return SparkActions.get();
-  }
-}
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/actions/TestExpireSnapshotsAction.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/actions/TestExpireSnapshotsAction.java
index 5729a04..292ced5 100644
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/actions/TestExpireSnapshotsAction.java
+++ b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/actions/TestExpireSnapshotsAction.java
@@ -59,7 +59,7 @@ import org.junit.rules.TemporaryFolder;
 
 import static org.apache.iceberg.types.Types.NestedField.optional;
 
-public abstract class TestExpireSnapshotsAction extends SparkTestBase {
+public class TestExpireSnapshotsAction extends SparkTestBase {
   private static final HadoopTables TABLES = new HadoopTables(new Configuration());
   private static final Schema SCHEMA = new Schema(
       optional(1, "c1", Types.IntegerType.get()),
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/actions/TestExpireSnapshotsAction24.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/actions/TestExpireSnapshotsAction24.java
deleted file mode 100644
index d613e09..0000000
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/actions/TestExpireSnapshotsAction24.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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.iceberg.actions;
-
-public class TestExpireSnapshotsAction24 extends TestExpireSnapshotsAction{
-}
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/actions/TestRemoveOrphanFilesAction.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/actions/TestRemoveOrphanFilesAction.java
index cf85bc8..ada2c53 100644
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/actions/TestRemoveOrphanFilesAction.java
+++ b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/actions/TestRemoveOrphanFilesAction.java
@@ -57,7 +57,7 @@ import org.junit.rules.TemporaryFolder;
 
 import static org.apache.iceberg.types.Types.NestedField.optional;
 
-public abstract class TestRemoveOrphanFilesAction extends SparkTestBase {
+public class TestRemoveOrphanFilesAction extends SparkTestBase {
 
   private static final HadoopTables TABLES = new HadoopTables(new Configuration());
   protected static final Schema SCHEMA = new Schema(
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/actions/TestRemoveOrphanFilesAction24.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/actions/TestRemoveOrphanFilesAction24.java
deleted file mode 100644
index d3720cd..0000000
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/actions/TestRemoveOrphanFilesAction24.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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.iceberg.actions;
-
-public class TestRemoveOrphanFilesAction24 extends TestRemoveOrphanFilesAction {
-}
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/actions/TestRewriteDataFilesAction.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/actions/TestRewriteDataFilesAction.java
index 7b541de..3545fa3 100644
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/actions/TestRewriteDataFilesAction.java
+++ b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/actions/TestRewriteDataFilesAction.java
@@ -52,7 +52,7 @@ import org.junit.rules.TemporaryFolder;
 
 import static org.apache.iceberg.types.Types.NestedField.optional;
 
-public abstract class TestRewriteDataFilesAction extends SparkTestBase {
+public class TestRewriteDataFilesAction extends SparkTestBase {
 
   private static final HadoopTables TABLES = new HadoopTables(new Configuration());
   private static final Schema SCHEMA = new Schema(
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/actions/TestRewriteDataFilesAction24.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/actions/TestRewriteDataFilesAction24.java
deleted file mode 100644
index db9b603..0000000
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/actions/TestRewriteDataFilesAction24.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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.iceberg.actions;
-
-public class TestRewriteDataFilesAction24 extends TestRewriteDataFilesAction {
-}
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/actions/TestRewriteManifestsAction.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/actions/TestRewriteManifestsAction.java
index b2fdaa6..e83f37d 100644
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/actions/TestRewriteManifestsAction.java
+++ b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/actions/TestRewriteManifestsAction.java
@@ -52,7 +52,7 @@ import org.junit.runners.Parameterized;
 import static org.apache.iceberg.types.Types.NestedField.optional;
 
 @RunWith(Parameterized.class)
-public abstract class TestRewriteManifestsAction extends SparkTestBase {
+public class TestRewriteManifestsAction extends SparkTestBase {
 
   private static final HadoopTables TABLES = new HadoopTables(new Configuration());
   private static final Schema SCHEMA = new Schema(
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/actions/TestRewriteManifestsAction24.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/actions/TestRewriteManifestsAction24.java
deleted file mode 100644
index 87a207d..0000000
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/actions/TestRewriteManifestsAction24.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.iceberg.actions;
-
-public class TestRewriteManifestsAction24 extends TestRewriteManifestsAction {
-  public TestRewriteManifestsAction24(String snapshotIdInheritanceEnabled) {
-    super(snapshotIdInheritanceEnabled);
-  }
-}
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestAvroScan.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestAvroScan.java
index bd498b2..4d2e122 100644
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestAvroScan.java
+++ b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestAvroScan.java
@@ -48,7 +48,7 @@ import org.junit.rules.TemporaryFolder;
 
 import static org.apache.iceberg.Files.localOutput;
 
-public abstract class TestAvroScan extends AvroDataTest {
+public class TestAvroScan extends AvroDataTest {
   private static final Configuration CONF = new Configuration();
 
   @Rule
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestAvroScan24.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestAvroScan24.java
deleted file mode 100644
index 900f99a..0000000
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestAvroScan24.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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.iceberg.spark.source;
-
-public class TestAvroScan24 extends TestAvroScan {
-}
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestDataFrameWrites.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestDataFrameWrites.java
index e103636..1391362 100644
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestDataFrameWrites.java
+++ b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestDataFrameWrites.java
@@ -73,7 +73,7 @@ import static org.apache.iceberg.spark.data.TestHelpers.assertEqualsSafe;
 import static org.apache.iceberg.spark.data.TestHelpers.assertEqualsUnsafe;
 
 @RunWith(Parameterized.class)
-public abstract class TestDataFrameWrites extends AvroDataTest {
+public class TestDataFrameWrites extends AvroDataTest {
   private static final Configuration CONF = new Configuration();
 
   private final String format;
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestDataFrameWrites24.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestDataFrameWrites24.java
deleted file mode 100644
index af98cff..0000000
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestDataFrameWrites24.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.iceberg.spark.source;
-
-public class TestDataFrameWrites24 extends TestDataFrameWrites {
-  public TestDataFrameWrites24(String format) {
-    super(format);
-  }
-}
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestDataSourceOptions.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestDataSourceOptions.java
index d81982b..7ffb94b 100644
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestDataSourceOptions.java
+++ b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestDataSourceOptions.java
@@ -56,7 +56,7 @@ import org.junit.rules.TemporaryFolder;
 
 import static org.apache.iceberg.types.Types.NestedField.optional;
 
-public abstract class TestDataSourceOptions {
+public class TestDataSourceOptions {
 
   private static final Configuration CONF = new Configuration();
   private static final Schema SCHEMA = new Schema(
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestDataSourceOptions24.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestDataSourceOptions24.java
deleted file mode 100644
index 26af76e..0000000
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestDataSourceOptions24.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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.iceberg.spark.source;
-
-public class TestDataSourceOptions24 extends TestDataSourceOptions {
-}
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestForwardCompatibility.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestForwardCompatibility.java
index 2c7af66..4b16099 100644
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestForwardCompatibility.java
+++ b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestForwardCompatibility.java
@@ -59,11 +59,12 @@ import org.junit.BeforeClass;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
+import scala.collection.JavaConversions;
 
 import static org.apache.iceberg.Files.localInput;
 import static org.apache.iceberg.Files.localOutput;
 
-public abstract class TestForwardCompatibility {
+public class TestForwardCompatibility {
   private static final Configuration CONF = new Configuration();
 
   private static final Schema SCHEMA = new Schema(
@@ -94,10 +95,6 @@ public abstract class TestForwardCompatibility {
     currentSpark.stop();
   }
 
-  protected abstract <T> MemoryStream<T> newMemoryStream(int id, SQLContext sqlContext, Encoder<T> encoder);
-
-  protected abstract <T> void send(List<T> records, MemoryStream<T> stream);
-
   @Test
   public void testSparkWriteFailsUnknownTransform() throws IOException {
     File parent = temp.newFolder("avro");
@@ -207,4 +204,12 @@ public abstract class TestForwardCompatibility {
       TestHelpers.assertEqualsSafe(table.schema().asStruct(), expected.get(i), rows.get(i));
     }
   }
+
+  private <T> MemoryStream<T> newMemoryStream(int id, SQLContext sqlContext, Encoder<T> encoder) {
+    return new MemoryStream<>(id, sqlContext, encoder);
+  }
+
+  private <T> void send(List<T> records, MemoryStream<T> stream) {
+    stream.addData(JavaConversions.asScalaBuffer(records));
+  }
 }
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestForwardCompatibility24.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestForwardCompatibility24.java
deleted file mode 100644
index 4ca3b51..0000000
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestForwardCompatibility24.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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.iceberg.spark.source;
-
-import java.util.List;
-import org.apache.spark.sql.Encoder;
-import org.apache.spark.sql.SQLContext;
-import org.apache.spark.sql.execution.streaming.MemoryStream;
-import scala.collection.JavaConversions;
-
-public class TestForwardCompatibility24 extends TestForwardCompatibility {
-  @Override
-  protected <T> MemoryStream<T> newMemoryStream(int id, SQLContext sqlContext, Encoder<T> encoder) {
-    return new MemoryStream<>(id, sqlContext, encoder);
-  }
-
-  @Override
-  protected <T> void send(List<T> records, MemoryStream<T> stream) {
-    stream.addData(JavaConversions.asScalaBuffer(records));
-  }
-}
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestIcebergSourceHadoopTables.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestIcebergSourceHadoopTables.java
index b869d7f..f1cfc7a 100644
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestIcebergSourceHadoopTables.java
+++ b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestIcebergSourceHadoopTables.java
@@ -28,7 +28,7 @@ import org.apache.iceberg.catalog.TableIdentifier;
 import org.apache.iceberg.hadoop.HadoopTables;
 import org.junit.Before;
 
-public abstract class TestIcebergSourceHadoopTables extends TestIcebergSourceTablesBase {
+public class TestIcebergSourceHadoopTables extends TestIcebergSourceTablesBase {
 
   private static final HadoopTables TABLES = new HadoopTables(new Configuration());
 
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestIcebergSourceHadoopTables24.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestIcebergSourceHadoopTables24.java
deleted file mode 100644
index 1252f34..0000000
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestIcebergSourceHadoopTables24.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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.iceberg.spark.source;
-
-public class TestIcebergSourceHadoopTables24 extends TestIcebergSourceHadoopTables {
-}
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestIcebergSourceHiveTables.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestIcebergSourceHiveTables.java
index 70e920c..a51f9ee 100644
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestIcebergSourceHiveTables.java
+++ b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestIcebergSourceHiveTables.java
@@ -30,7 +30,7 @@ import org.apache.iceberg.catalog.TableIdentifier;
 import org.junit.After;
 import org.junit.BeforeClass;
 
-public abstract class TestIcebergSourceHiveTables extends TestIcebergSourceTablesBase {
+public class TestIcebergSourceHiveTables extends TestIcebergSourceTablesBase {
 
   private static TableIdentifier currentIdentifier;
 
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestIcebergSourceHiveTables24.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestIcebergSourceHiveTables24.java
deleted file mode 100644
index 7ba46cb..0000000
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestIcebergSourceHiveTables24.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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.iceberg.spark.source;
-
-public class TestIcebergSourceHiveTables24 extends TestIcebergSourceHiveTables {
-}
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestIcebergSpark.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestIcebergSpark.java
index 14785d7..e83709a 100644
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestIcebergSpark.java
+++ b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestIcebergSpark.java
@@ -31,7 +31,7 @@ import org.junit.Assert;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
-public abstract class TestIcebergSpark {
+public class TestIcebergSpark {
 
   private static SparkSession spark = null;
 
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestIcebergSpark24.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestIcebergSpark24.java
deleted file mode 100644
index c4fc260..0000000
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestIcebergSpark24.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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.iceberg.spark.source;
-
-public class TestIcebergSpark24 extends TestIcebergSpark {
-}
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestIdentityPartitionData.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestIdentityPartitionData.java
index 2e02a7c..e077983 100644
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestIdentityPartitionData.java
+++ b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestIdentityPartitionData.java
@@ -48,7 +48,7 @@ import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
 
 @RunWith(Parameterized.class)
-public abstract class TestIdentityPartitionData extends SparkTestBase {
+public class TestIdentityPartitionData extends SparkTestBase {
   private static final Configuration CONF = new Configuration();
   private static final HadoopTables TABLES = new HadoopTables(CONF);
 
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestIdentityPartitionData24.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestIdentityPartitionData24.java
deleted file mode 100644
index 9e382bf..0000000
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestIdentityPartitionData24.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.iceberg.spark.source;
-
-public class TestIdentityPartitionData24 extends TestIdentityPartitionData {
-  public TestIdentityPartitionData24(String format, boolean vectorized) {
-    super(format, vectorized);
-  }
-}
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestParquetScan.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestParquetScan.java
index 47fa9da..adfe8c7 100644
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestParquetScan.java
+++ b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestParquetScan.java
@@ -55,7 +55,7 @@ import org.junit.runners.Parameterized;
 import static org.apache.iceberg.Files.localOutput;
 
 @RunWith(Parameterized.class)
-public abstract class TestParquetScan extends AvroDataTest {
+public class TestParquetScan extends AvroDataTest {
   private static final Configuration CONF = new Configuration();
 
   private static SparkSession spark = null;
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestParquetScan24.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestParquetScan24.java
deleted file mode 100644
index 28d9a6a..0000000
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestParquetScan24.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.iceberg.spark.source;
-
-public class TestParquetScan24 extends TestParquetScan {
-  public TestParquetScan24(boolean vectorized) {
-    super(vectorized);
-  }
-}
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestPartitionPruning.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestPartitionPruning.java
index 3cba747..111e908 100644
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestPartitionPruning.java
+++ b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestPartitionPruning.java
@@ -71,7 +71,7 @@ import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
 
 @RunWith(Parameterized.class)
-public abstract class TestPartitionPruning {
+public class TestPartitionPruning {
 
   private static final Configuration CONF = new Configuration();
   private static final HadoopTables TABLES = new HadoopTables(CONF);
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestPartitionPruning24.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestPartitionPruning24.java
deleted file mode 100644
index 4b3889e..0000000
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestPartitionPruning24.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.iceberg.spark.source;
-
-public class TestPartitionPruning24 extends TestPartitionPruning {
-  public TestPartitionPruning24(String format, boolean vectorized) {
-    super(format, vectorized);
-  }
-}
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestPartitionValues.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestPartitionValues.java
index 3cee81e..0ac722c 100644
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestPartitionValues.java
+++ b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestPartitionValues.java
@@ -61,7 +61,7 @@ import static org.apache.iceberg.types.Types.NestedField.optional;
 import static org.apache.iceberg.types.Types.NestedField.required;
 
 @RunWith(Parameterized.class)
-public abstract class TestPartitionValues {
+public class TestPartitionValues {
   @Parameterized.Parameters(name = "format = {0}, vectorized = {1}")
   public static Object[][] parameters() {
     return new Object[][] {
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestPartitionValues24.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestPartitionValues24.java
deleted file mode 100644
index d5d891f..0000000
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestPartitionValues24.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.iceberg.spark.source;
-
-public class TestPartitionValues24 extends TestPartitionValues {
-  public TestPartitionValues24(String format, boolean vectorized) {
-    super(format, vectorized);
-  }
-}
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSnapshotSelection.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSnapshotSelection.java
index 8aadfb8..6da76b0 100644
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSnapshotSelection.java
+++ b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSnapshotSelection.java
@@ -44,7 +44,7 @@ import org.junit.rules.TemporaryFolder;
 
 import static org.apache.iceberg.types.Types.NestedField.optional;
 
-public abstract class TestSnapshotSelection {
+public class TestSnapshotSelection {
 
   private static final Configuration CONF = new Configuration();
   private static final Schema SCHEMA = new Schema(
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSnapshotSelection24.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSnapshotSelection24.java
deleted file mode 100644
index c003845..0000000
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSnapshotSelection24.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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.iceberg.spark.source;
-
-public class TestSnapshotSelection24 extends TestSnapshotSelection {
-}
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSparkBaseDataReader.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSparkBaseDataReader.java
index 8bae666..1260a26 100644
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSparkBaseDataReader.java
+++ b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSparkBaseDataReader.java
@@ -51,7 +51,7 @@ import org.junit.rules.TemporaryFolder;
 import static org.apache.iceberg.FileFormat.PARQUET;
 import static org.apache.iceberg.Files.localOutput;
 
-public abstract class TestSparkBaseDataReader {
+public class TestSparkBaseDataReader {
 
   @Rule
   public TemporaryFolder temp = new TemporaryFolder();
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSparkBaseDataReader24.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSparkBaseDataReader24.java
deleted file mode 100644
index 100c951..0000000
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSparkBaseDataReader24.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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.iceberg.spark.source;
-
-public class TestSparkBaseDataReader24 extends TestSparkBaseDataReader {
-}
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSparkDataFile.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSparkDataFile.java
index cffbab5..f6ca5f7 100644
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSparkDataFile.java
+++ b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSparkDataFile.java
@@ -65,7 +65,7 @@ import org.junit.rules.TemporaryFolder;
 import static org.apache.iceberg.types.Types.NestedField.optional;
 import static org.apache.iceberg.types.Types.NestedField.required;
 
-public abstract class TestSparkDataFile {
+public class TestSparkDataFile {
 
   private static final HadoopTables TABLES = new HadoopTables(new Configuration());
   private static final Schema SCHEMA = new Schema(
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSparkDataFile24.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSparkDataFile24.java
deleted file mode 100644
index f818301..0000000
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSparkDataFile24.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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.iceberg.spark.source;
-
-public class TestSparkDataFile24 extends TestSparkDataFile {
-}
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSparkDataWrite.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSparkDataWrite.java
index bc34974..5e99dac 100644
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSparkDataWrite.java
+++ b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSparkDataWrite.java
@@ -56,7 +56,7 @@ import static org.apache.iceberg.TableProperties.SPARK_WRITE_PARTITIONED_FANOUT_
 import static org.apache.iceberg.types.Types.NestedField.optional;
 
 @RunWith(Parameterized.class)
-public abstract class TestSparkDataWrite {
+public class TestSparkDataWrite {
   private static final Configuration CONF = new Configuration();
   private final FileFormat format;
   private static SparkSession spark = null;
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSparkDataWrite24.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSparkDataWrite24.java
deleted file mode 100644
index ce1896d..0000000
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSparkDataWrite24.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.iceberg.spark.source;
-
-public class TestSparkDataWrite24 extends TestSparkDataWrite {
-  public TestSparkDataWrite24(String format) {
-    super(format);
-  }
-}
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSparkReadProjection.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSparkReadProjection.java
index 2af2097..f42b48d 100644
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSparkReadProjection.java
+++ b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSparkReadProjection.java
@@ -56,7 +56,7 @@ import static org.apache.iceberg.types.Types.NestedField.optional;
 import static org.apache.iceberg.types.Types.NestedField.required;
 
 @RunWith(Parameterized.class)
-public abstract class TestSparkReadProjection extends TestReadProjection {
+public class TestSparkReadProjection extends TestReadProjection {
 
   private static SparkSession spark = null;
 
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSparkReadProjection24.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSparkReadProjection24.java
deleted file mode 100644
index bc79346..0000000
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSparkReadProjection24.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.iceberg.spark.source;
-
-public class TestSparkReadProjection24 extends TestSparkReadProjection {
-  public TestSparkReadProjection24(String format, boolean vectorized) {
-    super(format, vectorized);
-  }
-}
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSparkReaderDeletes.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSparkReaderDeletes.java
index 1306491..b7398b7 100644
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSparkReaderDeletes.java
+++ b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSparkReaderDeletes.java
@@ -62,7 +62,7 @@ import org.junit.Test;
 
 import static org.apache.hadoop.hive.conf.HiveConf.ConfVars.METASTOREURIS;
 
-public abstract class TestSparkReaderDeletes extends DeleteReadTests {
+public class TestSparkReaderDeletes extends DeleteReadTests {
 
   private static TestHiveMetastore metastore = null;
   protected static SparkSession spark = null;
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSparkReaderDeletes24.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSparkReaderDeletes24.java
deleted file mode 100644
index 5b13bff..0000000
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSparkReaderDeletes24.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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.iceberg.spark.source;
-
-public class TestSparkReaderDeletes24 extends TestSparkReaderDeletes {
-}
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSparkSchema.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSparkSchema.java
index a382201..d3c5cc4 100644
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSparkSchema.java
+++ b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSparkSchema.java
@@ -44,7 +44,7 @@ import org.junit.rules.TemporaryFolder;
 
 import static org.apache.iceberg.types.Types.NestedField.optional;
 
-public abstract class TestSparkSchema {
+public class TestSparkSchema {
 
   private static final Configuration CONF = new Configuration();
   private static final Schema SCHEMA = new Schema(
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSparkSchema24.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSparkSchema24.java
deleted file mode 100644
index ada3fcb..0000000
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestSparkSchema24.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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.iceberg.spark.source;
-
-public class TestSparkSchema24 extends TestSparkSchema {
-}
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestStructuredStreaming.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestStructuredStreaming.java
index a64145d..da13f65 100644
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestStructuredStreaming.java
+++ b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestStructuredStreaming.java
@@ -46,10 +46,11 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.junit.rules.TemporaryFolder;
+import scala.collection.JavaConversions;
 
 import static org.apache.iceberg.types.Types.NestedField.optional;
 
-public abstract class TestStructuredStreaming {
+public class TestStructuredStreaming {
 
   private static final Configuration CONF = new Configuration();
   private static final Schema SCHEMA = new Schema(
@@ -78,10 +79,6 @@ public abstract class TestStructuredStreaming {
     currentSpark.stop();
   }
 
-  protected abstract <T> MemoryStream<T> newMemoryStream(int id, SQLContext sqlContext, Encoder<T> encoder);
-
-  protected abstract <T> void send(List<T> records, MemoryStream<T> stream);
-
   @Test
   public void testStreamingWriteAppendMode() throws Exception {
     File parent = temp.newFolder("parquet");
@@ -296,4 +293,12 @@ public abstract class TestStructuredStreaming {
       }
     }
   }
+
+  private <T> MemoryStream<T> newMemoryStream(int id, SQLContext sqlContext, Encoder<T> encoder) {
+    return new MemoryStream<>(id, sqlContext, encoder);
+  }
+
+  private <T> void send(List<T> records, MemoryStream<T> stream) {
+    stream.addData(JavaConversions.asScalaBuffer(records));
+  }
 }
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestStructuredStreaming24.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestStructuredStreaming24.java
deleted file mode 100644
index c861502..0000000
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestStructuredStreaming24.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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.iceberg.spark.source;
-
-import java.util.List;
-import org.apache.spark.sql.Encoder;
-import org.apache.spark.sql.SQLContext;
-import org.apache.spark.sql.execution.streaming.MemoryStream;
-import scala.collection.JavaConversions;
-
-public class TestStructuredStreaming24 extends TestStructuredStreaming {
-  @Override
-  protected <T> MemoryStream<T> newMemoryStream(int id, SQLContext sqlContext, Encoder<T> encoder) {
-    return new MemoryStream<>(id, sqlContext, encoder);
-  }
-
-  @Override
-  protected <T> void send(List<T> records, MemoryStream<T> stream) {
-    stream.addData(JavaConversions.asScalaBuffer(records));
-  }
-}
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestTimestampWithoutZone.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestTimestampWithoutZone.java
index 984790d..20509ee 100644
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestTimestampWithoutZone.java
+++ b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestTimestampWithoutZone.java
@@ -67,7 +67,7 @@ import org.junit.runners.Parameterized;
 import static org.apache.iceberg.Files.localOutput;
 
 @RunWith(Parameterized.class)
-public abstract class TestTimestampWithoutZone extends SparkTestBase {
+public class TestTimestampWithoutZone extends SparkTestBase {
   private static final Configuration CONF = new Configuration();
   private static final HadoopTables TABLES = new HadoopTables(CONF);
 
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestTimestampWithoutZone24.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestTimestampWithoutZone24.java
deleted file mode 100644
index 84c7d1a..0000000
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestTimestampWithoutZone24.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.iceberg.spark.source;
-
-public class TestTimestampWithoutZone24 extends TestTimestampWithoutZone {
-  public TestTimestampWithoutZone24(String format, boolean vectorized) {
-    super(format, vectorized);
-  }
-}
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestWriteMetricsConfig.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestWriteMetricsConfig.java
index 9716987..7ed7103 100644
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestWriteMetricsConfig.java
+++ b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestWriteMetricsConfig.java
@@ -57,7 +57,7 @@ import static org.apache.iceberg.spark.SparkSchemaUtil.convert;
 import static org.apache.iceberg.types.Types.NestedField.optional;
 import static org.apache.iceberg.types.Types.NestedField.required;
 
-public abstract class TestWriteMetricsConfig {
+public class TestWriteMetricsConfig {
 
   private static final Configuration CONF = new Configuration();
   private static final Schema SIMPLE_SCHEMA = new Schema(
diff --git a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestWriteMetricsConfig24.java b/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestWriteMetricsConfig24.java
deleted file mode 100644
index 94aaf37..0000000
--- a/spark/v2.4/spark2/src/test/java/org/apache/iceberg/spark/source/TestWriteMetricsConfig24.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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.iceberg.spark.source;
-
-public class TestWriteMetricsConfig24 extends TestWriteMetricsConfig {
-}
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/TestScanTaskSerialization.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/TestScanTaskSerialization.java
index 9d10725..e234ee2 100644
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/TestScanTaskSerialization.java
+++ b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/TestScanTaskSerialization.java
@@ -52,7 +52,7 @@ import org.junit.rules.TemporaryFolder;
 
 import static org.apache.iceberg.types.Types.NestedField.optional;
 
-public abstract class TestScanTaskSerialization extends SparkTestBase {
+public class TestScanTaskSerialization extends SparkTestBase {
 
   private static final HadoopTables TABLES = new HadoopTables(new Configuration());
   private static final Schema SCHEMA = new Schema(
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/TestScanTaskSerialization3.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/TestScanTaskSerialization3.java
deleted file mode 100644
index 035aa49..0000000
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/TestScanTaskSerialization3.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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.iceberg;
-
-public class TestScanTaskSerialization3 extends TestScanTaskSerialization {
-}
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/actions/TestDeleteReachableFilesAction.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/actions/TestDeleteReachableFilesAction.java
index b0e783b..0539280 100644
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/actions/TestDeleteReachableFilesAction.java
+++ b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/actions/TestDeleteReachableFilesAction.java
@@ -42,6 +42,7 @@ import org.apache.iceberg.relocated.com.google.common.collect.Lists;
 import org.apache.iceberg.relocated.com.google.common.collect.Maps;
 import org.apache.iceberg.relocated.com.google.common.collect.Sets;
 import org.apache.iceberg.spark.SparkTestBase;
+import org.apache.iceberg.spark.actions.SparkActions;
 import org.apache.iceberg.types.Types;
 import org.junit.Assert;
 import org.junit.Before;
@@ -51,7 +52,7 @@ import org.junit.rules.TemporaryFolder;
 
 import static org.apache.iceberg.types.Types.NestedField.optional;
 
-public abstract class TestDeleteReachableFilesAction extends SparkTestBase {
+public class TestDeleteReachableFilesAction extends SparkTestBase {
   private static final HadoopTables TABLES = new HadoopTables(new Configuration());
   private static final Schema SCHEMA = new Schema(
       optional(1, "c1", Types.IntegerType.get()),
@@ -338,5 +339,7 @@ public abstract class TestDeleteReachableFilesAction extends SparkTestBase {
     return ((HasTableOperations) tbl).operations().current().metadataFileLocation();
   }
 
-  abstract ActionsProvider sparkActions();
+  private ActionsProvider sparkActions() {
+    return SparkActions.get();
+  }
 }
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/actions/TestExpireSnapshotsAction.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/actions/TestExpireSnapshotsAction.java
index 5729a04..292ced5 100644
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/actions/TestExpireSnapshotsAction.java
+++ b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/actions/TestExpireSnapshotsAction.java
@@ -59,7 +59,7 @@ import org.junit.rules.TemporaryFolder;
 
 import static org.apache.iceberg.types.Types.NestedField.optional;
 
-public abstract class TestExpireSnapshotsAction extends SparkTestBase {
+public class TestExpireSnapshotsAction extends SparkTestBase {
   private static final HadoopTables TABLES = new HadoopTables(new Configuration());
   private static final Schema SCHEMA = new Schema(
       optional(1, "c1", Types.IntegerType.get()),
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/actions/TestExpireSnapshotsAction3.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/actions/TestExpireSnapshotsAction3.java
deleted file mode 100644
index bd4aad1..0000000
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/actions/TestExpireSnapshotsAction3.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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.iceberg.actions;
-
-public class TestExpireSnapshotsAction3 extends TestExpireSnapshotsAction {
-}
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/actions/TestNewRewriteDataFilesAction3.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/actions/TestNewRewriteDataFilesAction3.java
deleted file mode 100644
index 19737f0..0000000
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/actions/TestNewRewriteDataFilesAction3.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.iceberg.actions;
-
-import java.util.Set;
-import org.apache.iceberg.Table;
-import org.apache.iceberg.relocated.com.google.common.collect.ImmutableSet;
-import org.apache.iceberg.spark.FileRewriteCoordinator;
-import org.apache.iceberg.spark.FileScanTaskSetManager;
-import org.apache.iceberg.spark.actions.SparkActions;
-import org.apache.iceberg.spark.actions.TestNewRewriteDataFilesAction;
-
-public class TestNewRewriteDataFilesAction3 extends TestNewRewriteDataFilesAction {
-  private final FileRewriteCoordinator coordinator = FileRewriteCoordinator.get();
-  private final FileScanTaskSetManager manager = FileScanTaskSetManager.get();
-
-  @Override
-  protected ActionsProvider actions() {
-    return SparkActions.get();
-  }
-
-  @Override
-  protected Set<String> cacheContents(Table table) {
-    return ImmutableSet.<String>builder()
-        .addAll(manager.fetchSetIDs(table))
-        .addAll(coordinator.fetchSetIDs(table))
-        .build();
-  }
-}
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/actions/TestRemoveFilesAction3.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/actions/TestRemoveFilesAction3.java
deleted file mode 100644
index 838741a..0000000
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/actions/TestRemoveFilesAction3.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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.iceberg.actions;
-
-import org.apache.iceberg.spark.actions.SparkActions;
-
-public class TestRemoveFilesAction3 extends TestDeleteReachableFilesAction {
-  @Override
-  ActionsProvider sparkActions() {
-    return SparkActions.get();
-  }
-}
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/actions/TestRewriteDataFilesAction.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/actions/TestRewriteDataFilesAction.java
index 7b541de..3545fa3 100644
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/actions/TestRewriteDataFilesAction.java
+++ b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/actions/TestRewriteDataFilesAction.java
@@ -52,7 +52,7 @@ import org.junit.rules.TemporaryFolder;
 
 import static org.apache.iceberg.types.Types.NestedField.optional;
 
-public abstract class TestRewriteDataFilesAction extends SparkTestBase {
+public class TestRewriteDataFilesAction extends SparkTestBase {
 
   private static final HadoopTables TABLES = new HadoopTables(new Configuration());
   private static final Schema SCHEMA = new Schema(
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/actions/TestRewriteDataFilesAction3.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/actions/TestRewriteDataFilesAction3.java
deleted file mode 100644
index ff81829..0000000
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/actions/TestRewriteDataFilesAction3.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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.iceberg.actions;
-
-public class TestRewriteDataFilesAction3 extends TestRewriteDataFilesAction {
-}
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/actions/TestRewriteManifestsAction.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/actions/TestRewriteManifestsAction.java
index b2fdaa6..e83f37d 100644
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/actions/TestRewriteManifestsAction.java
+++ b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/actions/TestRewriteManifestsAction.java
@@ -52,7 +52,7 @@ import org.junit.runners.Parameterized;
 import static org.apache.iceberg.types.Types.NestedField.optional;
 
 @RunWith(Parameterized.class)
-public abstract class TestRewriteManifestsAction extends SparkTestBase {
+public class TestRewriteManifestsAction extends SparkTestBase {
 
   private static final HadoopTables TABLES = new HadoopTables(new Configuration());
   private static final Schema SCHEMA = new Schema(
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/actions/TestRewriteManifestsAction3.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/actions/TestRewriteManifestsAction3.java
deleted file mode 100644
index 5d9376e..0000000
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/actions/TestRewriteManifestsAction3.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.iceberg.actions;
-
-public class TestRewriteManifestsAction3 extends TestRewriteManifestsAction {
-  public TestRewriteManifestsAction3(String snapshotIdInheritanceEnabled) {
-    super(snapshotIdInheritanceEnabled);
-  }
-}
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/actions/TestNewRewriteDataFilesAction.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/actions/TestNewRewriteDataFilesAction.java
index 21fa4a1..bd982dd 100644
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/actions/TestNewRewriteDataFilesAction.java
+++ b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/actions/TestNewRewriteDataFilesAction.java
@@ -56,6 +56,8 @@ import org.apache.iceberg.relocated.com.google.common.collect.Iterables;
 import org.apache.iceberg.relocated.com.google.common.collect.Lists;
 import org.apache.iceberg.relocated.com.google.common.collect.Maps;
 import org.apache.iceberg.relocated.com.google.common.collect.Streams;
+import org.apache.iceberg.spark.FileRewriteCoordinator;
+import org.apache.iceberg.spark.FileScanTaskSetManager;
 import org.apache.iceberg.spark.SparkTestBase;
 import org.apache.iceberg.spark.source.ThreeColumnRecord;
 import org.apache.iceberg.types.Comparators;
@@ -82,10 +84,7 @@ import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.spy;
 
-public abstract class TestNewRewriteDataFilesAction extends SparkTestBase {
-
-  protected abstract ActionsProvider actions();
-  protected abstract Set<String> cacheContents(Table table);
+public class TestNewRewriteDataFilesAction extends SparkTestBase {
 
   private static final HadoopTables TABLES = new HadoopTables(new Configuration());
   private static final Schema SCHEMA = new Schema(
@@ -97,6 +96,8 @@ public abstract class TestNewRewriteDataFilesAction extends SparkTestBase {
   @Rule
   public TemporaryFolder temp = new TemporaryFolder();
 
+  private final FileRewriteCoordinator coordinator = FileRewriteCoordinator.get();
+  private final FileScanTaskSetManager manager = FileScanTaskSetManager.get();
   private String tableLocation = null;
 
   @Before
@@ -990,6 +991,17 @@ public abstract class TestNewRewriteDataFilesAction extends SparkTestBase {
         .save(tableLocation);
   }
 
+  private ActionsProvider actions() {
+    return SparkActions.get();
+  }
+
+  private Set<String> cacheContents(Table table) {
+    return ImmutableSet.<String>builder()
+        .addAll(manager.fetchSetIDs(table))
+        .addAll(coordinator.fetchSetIDs(table))
+        .build();
+  }
+
   class GroupInfoMatcher implements ArgumentMatcher<RewriteFileGroup> {
     private final Set<Integer> groupIDs;
 
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestAvroScan.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestAvroScan.java
index bd498b2..4d2e122 100644
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestAvroScan.java
+++ b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestAvroScan.java
@@ -48,7 +48,7 @@ import org.junit.rules.TemporaryFolder;
 
 import static org.apache.iceberg.Files.localOutput;
 
-public abstract class TestAvroScan extends AvroDataTest {
+public class TestAvroScan extends AvroDataTest {
   private static final Configuration CONF = new Configuration();
 
   @Rule
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestAvroScan3.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestAvroScan3.java
deleted file mode 100644
index 9e31ed7..0000000
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestAvroScan3.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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.iceberg.spark.source;
-
-public class TestAvroScan3 extends TestAvroScan {
-}
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestDataFrameWrites.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestDataFrameWrites.java
index e103636..1391362 100644
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestDataFrameWrites.java
+++ b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestDataFrameWrites.java
@@ -73,7 +73,7 @@ import static org.apache.iceberg.spark.data.TestHelpers.assertEqualsSafe;
 import static org.apache.iceberg.spark.data.TestHelpers.assertEqualsUnsafe;
 
 @RunWith(Parameterized.class)
-public abstract class TestDataFrameWrites extends AvroDataTest {
+public class TestDataFrameWrites extends AvroDataTest {
   private static final Configuration CONF = new Configuration();
 
   private final String format;
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestDataFrameWrites3.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestDataFrameWrites3.java
deleted file mode 100644
index 098777d..0000000
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestDataFrameWrites3.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.iceberg.spark.source;
-
-public class TestDataFrameWrites3 extends TestDataFrameWrites {
-  public TestDataFrameWrites3(String format) {
-    super(format);
-  }
-}
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestDataSourceOptions.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestDataSourceOptions.java
index d81982b..7ffb94b 100644
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestDataSourceOptions.java
+++ b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestDataSourceOptions.java
@@ -56,7 +56,7 @@ import org.junit.rules.TemporaryFolder;
 
 import static org.apache.iceberg.types.Types.NestedField.optional;
 
-public abstract class TestDataSourceOptions {
+public class TestDataSourceOptions {
 
   private static final Configuration CONF = new Configuration();
   private static final Schema SCHEMA = new Schema(
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestDataSourceOptions3.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestDataSourceOptions3.java
deleted file mode 100644
index 8dbf08c..0000000
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestDataSourceOptions3.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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.iceberg.spark.source;
-
-public class TestDataSourceOptions3 extends TestDataSourceOptions {
-}
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestForwardCompatibility.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestForwardCompatibility.java
index 6ee7ee9..20e1352 100644
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestForwardCompatibility.java
+++ b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestForwardCompatibility.java
@@ -60,11 +60,13 @@ import org.junit.BeforeClass;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
+import scala.Option;
+import scala.collection.JavaConversions;
 
 import static org.apache.iceberg.Files.localInput;
 import static org.apache.iceberg.Files.localOutput;
 
-public abstract class TestForwardCompatibility {
+public class TestForwardCompatibility {
   private static final Configuration CONF = new Configuration();
 
   private static final Schema SCHEMA = new Schema(
@@ -95,10 +97,6 @@ public abstract class TestForwardCompatibility {
     currentSpark.stop();
   }
 
-  protected abstract <T> MemoryStream<T> newMemoryStream(int id, SQLContext sqlContext, Encoder<T> encoder);
-
-  protected abstract <T> void send(List<T> records, MemoryStream<T> stream);
-
   @Test
   public void testSparkWriteFailsUnknownTransform() throws IOException {
     File parent = temp.newFolder("avro");
@@ -208,4 +206,12 @@ public abstract class TestForwardCompatibility {
       TestHelpers.assertEqualsSafe(table.schema().asStruct(), expected.get(i), rows.get(i));
     }
   }
+
+  private <T> MemoryStream<T> newMemoryStream(int id, SQLContext sqlContext, Encoder<T> encoder) {
+    return new MemoryStream<>(id, sqlContext, Option.empty(), encoder);
+  }
+
+  private <T> void send(List<T> records, MemoryStream<T> stream) {
+    stream.addData(JavaConversions.asScalaBuffer(records));
+  }
 }
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestForwardCompatibility3.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestForwardCompatibility3.java
deleted file mode 100644
index 292010d..0000000
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestForwardCompatibility3.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.iceberg.spark.source;
-
-import java.util.List;
-import org.apache.spark.sql.Encoder;
-import org.apache.spark.sql.SQLContext;
-import org.apache.spark.sql.execution.streaming.MemoryStream;
-import scala.Option;
-import scala.collection.JavaConversions;
-
-public class TestForwardCompatibility3 extends TestForwardCompatibility {
-  @Override
-  protected <T> MemoryStream<T> newMemoryStream(int id, SQLContext sqlContext, Encoder<T> encoder) {
-    return new MemoryStream<>(id, sqlContext, Option.empty(), encoder);
-  }
-
-  @Override
-  protected <T> void send(List<T> records, MemoryStream<T> stream) {
-    stream.addData(JavaConversions.asScalaBuffer(records));
-  }
-}
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestIcebergSourceHadoopTables.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestIcebergSourceHadoopTables.java
index b869d7f..f1cfc7a 100644
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestIcebergSourceHadoopTables.java
+++ b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestIcebergSourceHadoopTables.java
@@ -28,7 +28,7 @@ import org.apache.iceberg.catalog.TableIdentifier;
 import org.apache.iceberg.hadoop.HadoopTables;
 import org.junit.Before;
 
-public abstract class TestIcebergSourceHadoopTables extends TestIcebergSourceTablesBase {
+public class TestIcebergSourceHadoopTables extends TestIcebergSourceTablesBase {
 
   private static final HadoopTables TABLES = new HadoopTables(new Configuration());
 
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestIcebergSourceHadoopTables3.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestIcebergSourceHadoopTables3.java
deleted file mode 100644
index 166a2bef..0000000
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestIcebergSourceHadoopTables3.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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.iceberg.spark.source;
-
-public class TestIcebergSourceHadoopTables3 extends TestIcebergSourceHadoopTables {
-}
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestIcebergSourceHiveTables.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestIcebergSourceHiveTables.java
index 70e920c..a51f9ee 100644
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestIcebergSourceHiveTables.java
+++ b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestIcebergSourceHiveTables.java
@@ -30,7 +30,7 @@ import org.apache.iceberg.catalog.TableIdentifier;
 import org.junit.After;
 import org.junit.BeforeClass;
 
-public abstract class TestIcebergSourceHiveTables extends TestIcebergSourceTablesBase {
+public class TestIcebergSourceHiveTables extends TestIcebergSourceTablesBase {
 
   private static TableIdentifier currentIdentifier;
 
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestIcebergSourceHiveTables3.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestIcebergSourceHiveTables3.java
deleted file mode 100644
index c69f3bb..0000000
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestIcebergSourceHiveTables3.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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.iceberg.spark.source;
-
-public class TestIcebergSourceHiveTables3 extends TestIcebergSourceHiveTables {
-}
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestIcebergSpark.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestIcebergSpark.java
index 14785d7..e83709a 100644
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestIcebergSpark.java
+++ b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestIcebergSpark.java
@@ -31,7 +31,7 @@ import org.junit.Assert;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
-public abstract class TestIcebergSpark {
+public class TestIcebergSpark {
 
   private static SparkSession spark = null;
 
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestIcebergSpark3.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestIcebergSpark3.java
deleted file mode 100644
index 3b143fd..0000000
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestIcebergSpark3.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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.iceberg.spark.source;
-
-public class TestIcebergSpark3 extends TestIcebergSpark {
-}
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestIdentityPartitionData.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestIdentityPartitionData.java
index 2e02a7c..e077983 100644
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestIdentityPartitionData.java
+++ b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestIdentityPartitionData.java
@@ -48,7 +48,7 @@ import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
 
 @RunWith(Parameterized.class)
-public abstract class TestIdentityPartitionData extends SparkTestBase {
+public class TestIdentityPartitionData extends SparkTestBase {
   private static final Configuration CONF = new Configuration();
   private static final HadoopTables TABLES = new HadoopTables(CONF);
 
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestIdentityPartitionData3.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestIdentityPartitionData3.java
deleted file mode 100644
index 3b90f61..0000000
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestIdentityPartitionData3.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.iceberg.spark.source;
-
-public class TestIdentityPartitionData3 extends TestIdentityPartitionData {
-  public TestIdentityPartitionData3(String format, boolean vectorized) {
-    super(format, vectorized);
-  }
-}
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestParquetScan.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestParquetScan.java
index 47fa9da..adfe8c7 100644
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestParquetScan.java
+++ b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestParquetScan.java
@@ -55,7 +55,7 @@ import org.junit.runners.Parameterized;
 import static org.apache.iceberg.Files.localOutput;
 
 @RunWith(Parameterized.class)
-public abstract class TestParquetScan extends AvroDataTest {
+public class TestParquetScan extends AvroDataTest {
   private static final Configuration CONF = new Configuration();
 
   private static SparkSession spark = null;
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestParquetScan3.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestParquetScan3.java
deleted file mode 100644
index ae78db9..0000000
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestParquetScan3.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.iceberg.spark.source;
-
-public class TestParquetScan3 extends TestParquetScan {
-  public TestParquetScan3(boolean vectorized) {
-    super(vectorized);
-  }
-}
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestPartitionPruning.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestPartitionPruning.java
index 3cba747..111e908 100644
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestPartitionPruning.java
+++ b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestPartitionPruning.java
@@ -71,7 +71,7 @@ import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
 
 @RunWith(Parameterized.class)
-public abstract class TestPartitionPruning {
+public class TestPartitionPruning {
 
   private static final Configuration CONF = new Configuration();
   private static final HadoopTables TABLES = new HadoopTables(CONF);
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestPartitionPruning3.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestPartitionPruning3.java
deleted file mode 100644
index 2d09c82..0000000
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestPartitionPruning3.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.iceberg.spark.source;
-
-public class TestPartitionPruning3 extends TestPartitionPruning {
-  public TestPartitionPruning3(String format, boolean vectorized) {
-    super(format, vectorized);
-  }
-}
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestPartitionValues.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestPartitionValues.java
index 3cee81e..0ac722c 100644
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestPartitionValues.java
+++ b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestPartitionValues.java
@@ -61,7 +61,7 @@ import static org.apache.iceberg.types.Types.NestedField.optional;
 import static org.apache.iceberg.types.Types.NestedField.required;
 
 @RunWith(Parameterized.class)
-public abstract class TestPartitionValues {
+public class TestPartitionValues {
   @Parameterized.Parameters(name = "format = {0}, vectorized = {1}")
   public static Object[][] parameters() {
     return new Object[][] {
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestPartitionValues3.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestPartitionValues3.java
deleted file mode 100644
index 9b42192..0000000
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestPartitionValues3.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.iceberg.spark.source;
-
-public class TestPartitionValues3 extends TestPartitionValues {
-  public TestPartitionValues3(String format, boolean vectorized) {
-    super(format, vectorized);
-  }
-}
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestSnapshotSelection.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestSnapshotSelection.java
index 8aadfb8..6da76b0 100644
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestSnapshotSelection.java
+++ b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestSnapshotSelection.java
@@ -44,7 +44,7 @@ import org.junit.rules.TemporaryFolder;
 
 import static org.apache.iceberg.types.Types.NestedField.optional;
 
-public abstract class TestSnapshotSelection {
+public class TestSnapshotSelection {
 
   private static final Configuration CONF = new Configuration();
   private static final Schema SCHEMA = new Schema(
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestSnapshotSelection3.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestSnapshotSelection3.java
deleted file mode 100644
index 4a08f84..0000000
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestSnapshotSelection3.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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.iceberg.spark.source;
-
-public class TestSnapshotSelection3 extends TestSnapshotSelection {
-}
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestSparkBaseDataReader.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestSparkBaseDataReader.java
index 8bae666..1260a26 100644
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestSparkBaseDataReader.java
+++ b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestSparkBaseDataReader.java
@@ -51,7 +51,7 @@ import org.junit.rules.TemporaryFolder;
 import static org.apache.iceberg.FileFormat.PARQUET;
 import static org.apache.iceberg.Files.localOutput;
 
-public abstract class TestSparkBaseDataReader {
+public class TestSparkBaseDataReader {
 
   @Rule
   public TemporaryFolder temp = new TemporaryFolder();
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestSparkBaseDataReader3.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestSparkBaseDataReader3.java
deleted file mode 100644
index 4322e34..0000000
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestSparkBaseDataReader3.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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.iceberg.spark.source;
-
-public class TestSparkBaseDataReader3 extends TestSparkBaseDataReader {
-}
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestSparkDataFile.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestSparkDataFile.java
index cffbab5..f6ca5f7 100644
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestSparkDataFile.java
+++ b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestSparkDataFile.java
@@ -65,7 +65,7 @@ import org.junit.rules.TemporaryFolder;
 import static org.apache.iceberg.types.Types.NestedField.optional;
 import static org.apache.iceberg.types.Types.NestedField.required;
 
-public abstract class TestSparkDataFile {
+public class TestSparkDataFile {
 
   private static final HadoopTables TABLES = new HadoopTables(new Configuration());
   private static final Schema SCHEMA = new Schema(
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestSparkDataFile3.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestSparkDataFile3.java
deleted file mode 100644
index e3bdcfc..0000000
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestSparkDataFile3.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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.iceberg.spark.source;
-
-public class TestSparkDataFile3 extends TestSparkDataFile {
-}
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestSparkDataWrite.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestSparkDataWrite.java
index bc34974..5e99dac 100644
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestSparkDataWrite.java
+++ b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestSparkDataWrite.java
@@ -56,7 +56,7 @@ import static org.apache.iceberg.TableProperties.SPARK_WRITE_PARTITIONED_FANOUT_
 import static org.apache.iceberg.types.Types.NestedField.optional;
 
 @RunWith(Parameterized.class)
-public abstract class TestSparkDataWrite {
+public class TestSparkDataWrite {
   private static final Configuration CONF = new Configuration();
   private final FileFormat format;
   private static SparkSession spark = null;
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestSparkDataWrite3.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestSparkDataWrite3.java
deleted file mode 100644
index 0ce6198..0000000
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestSparkDataWrite3.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.iceberg.spark.source;
-
-public class TestSparkDataWrite3 extends TestSparkDataWrite {
-  public TestSparkDataWrite3(String format) {
-    super(format);
-  }
-}
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestSparkReadProjection.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestSparkReadProjection.java
index 2af2097..f42b48d 100644
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestSparkReadProjection.java
+++ b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestSparkReadProjection.java
@@ -56,7 +56,7 @@ import static org.apache.iceberg.types.Types.NestedField.optional;
 import static org.apache.iceberg.types.Types.NestedField.required;
 
 @RunWith(Parameterized.class)
-public abstract class TestSparkReadProjection extends TestReadProjection {
+public class TestSparkReadProjection extends TestReadProjection {
 
   private static SparkSession spark = null;
 
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestSparkReadProjection3.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestSparkReadProjection3.java
deleted file mode 100644
index 5698214..0000000
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestSparkReadProjection3.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.iceberg.spark.source;
-
-public class TestSparkReadProjection3 extends TestSparkReadProjection {
-  public TestSparkReadProjection3(String format, boolean vectorized) {
-    super(format, vectorized);
-  }
-}
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestSparkReaderDeletes.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestSparkReaderDeletes.java
index 1306491..b7398b7 100644
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestSparkReaderDeletes.java
+++ b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestSparkReaderDeletes.java
@@ -62,7 +62,7 @@ import org.junit.Test;
 
 import static org.apache.hadoop.hive.conf.HiveConf.ConfVars.METASTOREURIS;
 
-public abstract class TestSparkReaderDeletes extends DeleteReadTests {
+public class TestSparkReaderDeletes extends DeleteReadTests {
 
   private static TestHiveMetastore metastore = null;
   protected static SparkSession spark = null;
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestSparkReaderDeletes3.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestSparkReaderDeletes3.java
deleted file mode 100644
index 82835d6..0000000
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestSparkReaderDeletes3.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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.iceberg.spark.source;
-
-public class TestSparkReaderDeletes3 extends TestSparkReaderDeletes {
-}
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestSparkSchema.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestSparkSchema.java
deleted file mode 100644
index a382201..0000000
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestSparkSchema.java
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * 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.iceberg.spark.source;
-
-import java.io.IOException;
-import java.util.List;
-import org.apache.hadoop.conf.Configuration;
-import org.apache.iceberg.AssertHelpers;
-import org.apache.iceberg.PartitionSpec;
-import org.apache.iceberg.Schema;
-import org.apache.iceberg.hadoop.HadoopTables;
-import org.apache.iceberg.relocated.com.google.common.collect.Lists;
-import org.apache.iceberg.types.Types;
-import org.apache.spark.sql.Dataset;
-import org.apache.spark.sql.Row;
-import org.apache.spark.sql.SparkSession;
-import org.apache.spark.sql.types.DataTypes;
-import org.apache.spark.sql.types.Metadata;
-import org.apache.spark.sql.types.StructField;
-import org.apache.spark.sql.types.StructType;
-import org.junit.AfterClass;
-import org.junit.Assert;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-
-import static org.apache.iceberg.types.Types.NestedField.optional;
-
-public abstract class TestSparkSchema {
-
-  private static final Configuration CONF = new Configuration();
-  private static final Schema SCHEMA = new Schema(
-      optional(1, "id", Types.IntegerType.get()),
-      optional(2, "data", Types.StringType.get())
-  );
-  private static SparkSession spark = null;
-
-  @Rule
-  public TemporaryFolder temp = new TemporaryFolder();
-
-  @BeforeClass
-  public static void startSpark() {
-    TestSparkSchema.spark = SparkSession.builder().master("local[2]").getOrCreate();
-  }
-
-  @AfterClass
-  public static void stopSpark() {
-    SparkSession currentSpark = TestSparkSchema.spark;
-    TestSparkSchema.spark = null;
-    currentSpark.stop();
-  }
-
-  @Test
-  public void testSparkReadSchemaIsHonored() throws IOException {
-    String tableLocation = temp.newFolder("iceberg-table").toString();
-
-    HadoopTables tables = new HadoopTables(CONF);
-    PartitionSpec spec = PartitionSpec.unpartitioned();
-    tables.create(SCHEMA, spec, null, tableLocation);
-
-    List<SimpleRecord> expectedRecords = Lists.newArrayList(
-        new SimpleRecord(1, "a")
-    );
-    Dataset<Row> originalDf = spark.createDataFrame(expectedRecords, SimpleRecord.class);
-    originalDf.select("id", "data").write()
-        .format("iceberg")
-        .mode("append")
-        .save(tableLocation);
-
-    StructType sparkReadSchema =
-        new StructType(
-            new StructField[] {
-                new StructField("id", DataTypes.IntegerType, true, Metadata.empty())
-            }
-        );
-
-    Dataset<Row> resultDf = spark.read()
-        .schema(sparkReadSchema)
-        .format("iceberg")
-        .load(tableLocation);
-
-    Row[] results = (Row[]) resultDf.collect();
-
-    Assert.assertEquals("Result size matches", 1, results.length);
-    Assert.assertEquals("Row length matches with sparkReadSchema", 1, results[0].length());
-    Assert.assertEquals("Row content matches data", 1, results[0].getInt(0));
-  }
-
-  @Test
-  public void testFailIfSparkReadSchemaIsOff() throws IOException {
-    String tableLocation = temp.newFolder("iceberg-table").toString();
-
-    HadoopTables tables = new HadoopTables(CONF);
-    PartitionSpec spec = PartitionSpec.unpartitioned();
-    tables.create(SCHEMA, spec, null, tableLocation);
-
-    List<SimpleRecord> expectedRecords = Lists.newArrayList(
-        new SimpleRecord(1, "a")
-    );
-    Dataset<Row> originalDf = spark.createDataFrame(expectedRecords, SimpleRecord.class);
-    originalDf.select("id", "data").write()
-        .format("iceberg")
-        .mode("append")
-        .save(tableLocation);
-
-    StructType sparkReadSchema =
-        new StructType(
-            new StructField[] {
-                new StructField("idd", DataTypes.IntegerType, true, Metadata.empty()) // wrong field name
-            }
-        );
-
-    AssertHelpers.assertThrows("Iceberg should not allow a projection that contain unknown fields",
-        java.lang.IllegalArgumentException.class, "Field idd not found in source schema",
-        () ->
-            spark.read()
-                .schema(sparkReadSchema)
-                .format("iceberg")
-                .load(tableLocation)
-    );
-  }
-
-  @Test
-  public void testSparkReadSchemaCombinedWithProjection() throws IOException {
-    String tableLocation = temp.newFolder("iceberg-table").toString();
-
-    HadoopTables tables = new HadoopTables(CONF);
-    PartitionSpec spec = PartitionSpec.unpartitioned();
-    tables.create(SCHEMA, spec, null, tableLocation);
-
-    List<SimpleRecord> expectedRecords = Lists.newArrayList(
-        new SimpleRecord(1, "a")
-    );
-    Dataset<Row> originalDf = spark.createDataFrame(expectedRecords, SimpleRecord.class);
-    originalDf.select("id", "data").write()
-        .format("iceberg")
-        .mode("append")
-        .save(tableLocation);
-
-    StructType sparkReadSchema =
-        new StructType(
-            new StructField[] {
-                new StructField("id", DataTypes.IntegerType, true, Metadata.empty()),
-                new StructField("data", DataTypes.StringType, true, Metadata.empty())
-            }
-        );
-
-    Dataset<Row> resultDf = spark.read()
-        .schema(sparkReadSchema)
-        .format("iceberg")
-        .load(tableLocation)
-        .select("id");
-
-    Row[] results = (Row[]) resultDf.collect();
-
-    Assert.assertEquals("Result size matches", 1, results.length);
-    Assert.assertEquals("Row length matches with sparkReadSchema", 1, results[0].length());
-    Assert.assertEquals("Row content matches data", 1, results[0].getInt(0));
-  }
-
-  @Test
-  public void testFailSparkReadSchemaCombinedWithProjectionWhenSchemaDoesNotContainProjection() throws IOException {
-    String tableLocation = temp.newFolder("iceberg-table").toString();
-
-    HadoopTables tables = new HadoopTables(CONF);
-    PartitionSpec spec = PartitionSpec.unpartitioned();
-    tables.create(SCHEMA, spec, null, tableLocation);
-
-    List<SimpleRecord> expectedRecords = Lists.newArrayList(
-        new SimpleRecord(1, "a")
-    );
-    Dataset<Row> originalDf = spark.createDataFrame(expectedRecords, SimpleRecord.class);
-    originalDf.select("id", "data").write()
-        .format("iceberg")
-        .mode("append")
-        .save(tableLocation);
-
-    StructType sparkReadSchema =
-        new StructType(
-            new StructField[] {
-                new StructField("data", DataTypes.StringType, true, Metadata.empty())
-            }
-        );
-
-    AssertHelpers.assertThrows("Spark should not allow a projection that is not included in the read schema",
-        org.apache.spark.sql.AnalysisException.class, "cannot resolve '`id`' given input columns: [data]",
-        () ->
-            spark.read()
-              .schema(sparkReadSchema)
-              .format("iceberg")
-              .load(tableLocation)
-              .select("id")
-    );
-  }
-}
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestStructuredStreaming.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestStructuredStreaming.java
index a64145d..4225747 100644
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestStructuredStreaming.java
+++ b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestStructuredStreaming.java
@@ -46,10 +46,12 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.junit.rules.TemporaryFolder;
+import scala.Option;
+import scala.collection.JavaConversions;
 
 import static org.apache.iceberg.types.Types.NestedField.optional;
 
-public abstract class TestStructuredStreaming {
+public class TestStructuredStreaming {
 
   private static final Configuration CONF = new Configuration();
   private static final Schema SCHEMA = new Schema(
@@ -78,10 +80,6 @@ public abstract class TestStructuredStreaming {
     currentSpark.stop();
   }
 
-  protected abstract <T> MemoryStream<T> newMemoryStream(int id, SQLContext sqlContext, Encoder<T> encoder);
-
-  protected abstract <T> void send(List<T> records, MemoryStream<T> stream);
-
   @Test
   public void testStreamingWriteAppendMode() throws Exception {
     File parent = temp.newFolder("parquet");
@@ -296,4 +294,12 @@ public abstract class TestStructuredStreaming {
       }
     }
   }
+
+  private <T> MemoryStream<T> newMemoryStream(int id, SQLContext sqlContext, Encoder<T> encoder) {
+    return new MemoryStream<>(id, sqlContext, Option.empty(), encoder);
+  }
+
+  private <T> void send(List<T> records, MemoryStream<T> stream) {
+    stream.addData(JavaConversions.asScalaBuffer(records));
+  }
 }
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestStructuredStreaming3.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestStructuredStreaming3.java
deleted file mode 100644
index 5062700..0000000
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestStructuredStreaming3.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.iceberg.spark.source;
-
-import java.util.List;
-import org.apache.spark.sql.Encoder;
-import org.apache.spark.sql.SQLContext;
-import org.apache.spark.sql.execution.streaming.MemoryStream;
-import scala.Option;
-import scala.collection.JavaConversions;
-
-public class TestStructuredStreaming3 extends TestStructuredStreaming {
-  @Override
-  protected <T> MemoryStream<T> newMemoryStream(int id, SQLContext sqlContext, Encoder<T> encoder) {
-    return new MemoryStream<>(id, sqlContext, Option.empty(), encoder);
-  }
-
-  @Override
-  protected <T> void send(List<T> records, MemoryStream<T> stream) {
-    stream.addData(JavaConversions.asScalaBuffer(records));
-  }
-}
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestTimestampWithoutZone.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestTimestampWithoutZone.java
index 984790d..20509ee 100644
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestTimestampWithoutZone.java
+++ b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestTimestampWithoutZone.java
@@ -67,7 +67,7 @@ import org.junit.runners.Parameterized;
 import static org.apache.iceberg.Files.localOutput;
 
 @RunWith(Parameterized.class)
-public abstract class TestTimestampWithoutZone extends SparkTestBase {
+public class TestTimestampWithoutZone extends SparkTestBase {
   private static final Configuration CONF = new Configuration();
   private static final HadoopTables TABLES = new HadoopTables(CONF);
 
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestTimestampWithoutZone3.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestTimestampWithoutZone3.java
deleted file mode 100644
index 4216aec..0000000
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestTimestampWithoutZone3.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.iceberg.spark.source;
-
-public class TestTimestampWithoutZone3 extends TestTimestampWithoutZone {
-  public TestTimestampWithoutZone3(String format, boolean vectorized) {
-    super(format, vectorized);
-  }
-}
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestWriteMetricsConfig.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestWriteMetricsConfig.java
index 9716987..7ed7103 100644
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestWriteMetricsConfig.java
+++ b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestWriteMetricsConfig.java
@@ -57,7 +57,7 @@ import static org.apache.iceberg.spark.SparkSchemaUtil.convert;
 import static org.apache.iceberg.types.Types.NestedField.optional;
 import static org.apache.iceberg.types.Types.NestedField.required;
 
-public abstract class TestWriteMetricsConfig {
+public class TestWriteMetricsConfig {
 
   private static final Configuration CONF = new Configuration();
   private static final Schema SIMPLE_SCHEMA = new Schema(
diff --git a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestWriteMetricsConfig3.java b/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestWriteMetricsConfig3.java
deleted file mode 100644
index 6132de2..0000000
--- a/spark/v3.0/spark3/src/test/java/org/apache/iceberg/spark/source/TestWriteMetricsConfig3.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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.iceberg.spark.source;
-
-public class TestWriteMetricsConfig3 extends TestWriteMetricsConfig {
-}