Skip to content

[FLINK-27939][hive] Migrate unit tests to JUnit 5#39

Open
jlalwani-amazon wants to merge 8 commits into
apache:mainfrom
jlalwani-amazon:flink-27939-junit5-migration
Open

[FLINK-27939][hive] Migrate unit tests to JUnit 5#39
jlalwani-amazon wants to merge 8 commits into
apache:mainfrom
jlalwani-amazon:flink-27939-junit5-migration

Conversation

@jlalwani-amazon
Copy link
Copy Markdown

@jlalwani-amazon jlalwani-amazon commented Apr 27, 2026

What is the purpose of the change

Complete JUnit 5 migration for all 32 test files in flink-connector-hive (FLINK-27939).

JIRA: FLINK-27939

Brief change log

Batch 1 (7 files): Simple import swaps for HiveModuleFactoryTest, HiveTableUtilTest, HiveGenericUDAFTest, HiveGenericUDTFTest, HiveSimpleUDFTest, HiveGenericUDFTest, HiveASTParserTest

Batch 2 (7 files): Simple import swaps + parameterized test migration for PartitionMonitorTest, HiveConfUtilsTest, HiveOutputFormatFactoryTest, HiveDeserializeExceptionTest (@RunWith(Parameterized.class)@ParameterizedTest @MethodSource), ContinuousHiveSplitEnumeratorTest, HiveInputFormatPartitionReaderITCase, HivePartitionFetcherTest

Batch 3 (6 files): Lifecycle annotations for HiveDynamicTableFactoryTest, HiveLookupJoinITCase, HiveSourceITCase, HiveDialectQueryPlanTest, HiveCatalogTest, HiveTableSourceITCase. @BeforeClass@BeforeAll, @AfterClass@AfterAll, @Before@BeforeEach, @After@AfterEach, @Test(timeout=N)@Test @Timeout.

Batch 4 (7 files): TemporaryFolder migration for HiveModuleTest, HiveSourceFileEnumeratorTest, HivePartitionUtilsTest, HiveCatalogUdfITCase, HiveCatalogITCase, HiveDialectITCase, TableEnvHiveConnectorITCase. @Rule TemporaryFolder@TempDir Path, @ClassRule static TemporaryFolder@TempDir static Path.

Batch 5 (4 files): Complex migrations for HiveCatalogDataTypeTest (ExpectedExceptionassertThatThrownBy), HiveCatalogFactoryTest (TestExecutorResourceTestExecutorExtension, ExpectedExceptionassertThatThrownBy), HiveDialectQueryITCase (ComparisonFailureAssertionFailedError), HiveDialectAggITCase (removed unused TemporaryFolder).

Batch 6: Migrate FlinkEmbeddedHiveRunner (JUnit 4 BlockJUnit4ClassRunner) to FlinkEmbeddedHiveRunnerExtension (JUnit 5 BeforeAllCallback/AfterAllCallback). Replicates annotation processing for @HiveSQL, @HiveResource, @HiveProperties, @HiveSetupScript, @HiveRunnerSetup. Delete old FlinkEmbeddedHiveRunner.java and FlinkStandaloneHiveRunner.java (dead code). Add @Isolated to HiveRunnerITCase to avoid Derby metastore contention with other IT tests.

Review fixes: Address reviewer feedback on assertion style and test organization.

Verifying this change

CI passed on fork: https://github.com/jlalwani-amazon/flink-connector-hive/actions

Does this pull request potentially affect one of the following parts?

  • Dependencies: no (junit-jupiter already a transitive dependency)
  • The public API: no
  • The serializers: no
  • The runtime per-record code paths: no
  • Anything that affects deployment or recovery: no

@jlalwani-amazon jlalwani-amazon marked this pull request as draft April 27, 2026 21:21
@jlalwani-amazon jlalwani-amazon marked this pull request as ready for review April 27, 2026 21:26
@jlalwani-amazon jlalwani-amazon changed the title [FLINK-27939][hive] Migrate simple unit tests to JUnit 5 [FLINK-27939][hive] Migrate unit tests to JUnit 5 Apr 27, 2026
@jlalwani-amazon jlalwani-amazon force-pushed the flink-27939-junit5-migration branch from 44b0025 to 63ca36e Compare April 27, 2026 22:15
@jlalwani-amazon jlalwani-amazon marked this pull request as draft April 27, 2026 22:22
@jlalwani-amazon jlalwani-amazon force-pushed the flink-27939-junit5-migration branch from 63ca36e to 5c8cefb Compare April 27, 2026 22:47
@jlalwani-amazon jlalwani-amazon marked this pull request as ready for review April 27, 2026 22:55
@jlalwani-amazon jlalwani-amazon force-pushed the flink-27939-junit5-migration branch 3 times, most recently from 46e7d55 to 4409a6e Compare May 8, 2026 23:43
Comment thread pom.xml Outdated
Comment on lines +381 to +414
<dependency>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
<version>1.4.01</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.2.4</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty</artifactId>
<version>3.10.6.Final</version>
</dependency>
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>3.3.7</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.6</version>
</dependency>
<dependency>
<groupId>org.codehaus.jettison</groupId>
<artifactId>jettison</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need such old dependencies?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are dependency convergence pins that were based on dependencies pulled from 1.20.3. SInce, main is on 2.0-preview now, we will need to update these dependencies. We will push tha change shortly

@snuyanzin
Copy link
Copy Markdown
Contributor

in Apache Flink we should follow linear history
any merge commit is a blocker

@jlalwani-amazon
Copy link
Copy Markdown
Author

Thanks for flagging — I'll rebase to get a linear history. Will push the fix shortly.

Migrate 7 test files with no Rules/ClassRule/lifecycle methods:
- HiveModuleFactoryTest
- HiveTableUtilTest
- HiveGenericUDAFTest
- HiveGenericUDTFTest
- HiveSimpleUDFTest
- HiveGenericUDFTest
- HiveASTParserTest

Changes: org.junit.Test -> org.junit.jupiter.api.Test,
org.junit.Assume -> org.junit.jupiter.api.Assumptions
Migrate 7 more test files with no Rules/ClassRule/lifecycle methods:
- PartitionMonitorTest
- HiveConfUtilsTest
- HiveOutputFormatFactoryTest
- HiveDeserializeExceptionTest (includes Parameterized -> ParameterizedTest)
- ContinuousHiveSplitEnumeratorTest
- HiveInputFormatPartitionReaderITCase
- HivePartitionFetcherTest
@jlalwani-amazon jlalwani-amazon force-pushed the flink-27939-junit5-migration branch from 44662c3 to 76ca022 Compare May 11, 2026 17:16

private void loadAnnotatedSetupScripts(Class testClass, HiveShellBuilder hiveShellBuilder) {
private void loadAnnotatedSetupScripts(
final Class<?> testClass, HiveShellBuilder hiveShellBuilder) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we align on style: either all args are final or none of them, however not mixed
here and in other places

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed final on all parameters ro be consistent

Comment thread flink-connector-hive/pom.xml Outdated
<hiverunner.version>4.0.0</hiverunner.version>
<reflections.version>0.9.8</reflections.version>
<!-- Allow tests to run on Java 17+ where Hive uses deep reflection on java.base internals -->
<flink.surefire.baseArgLine>-XX:+UseG1GC -Xms256m --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED --add-opens java.base/java.nio=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens java.base/java.time=ALL-UNNAMED --add-exports java.security.jgss/sun.security.krb5=ALL-UNNAMED</flink.surefire.baseArgLine>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of putting everything in one heap can we also put a comment for each flag: what test requires it?
similar things we have in flink main repo

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was a mistake. We don't need Java 17 for Junit5. This change got carried over from some Hive4 work I was doing. Rolling it back

* setup
*/
public class HiveCatalogUdfITCase extends AbstractTestBaseJUnit4 {
public class HiveCatalogUdfITCase extends AbstractTestBase {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we still need to have junit5 tests public?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed public from all tests except HiveGenericUDTFTest because HiveDialectITCase uses it


@AfterClass
@AfterAll
public static void closeCatalog() {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we still need method marked with junit5's BeforeAll, AfterAll, Test public?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed public from all JUnit annotated methods

@jlalwani-amazon jlalwani-amazon force-pushed the flink-27939-junit5-migration branch 4 times, most recently from ed0aa00 to d2ba23a Compare May 11, 2026 23:22
Migrate 6 test files using @BeforeClass/@AfterClass/@Before/@after:
- HiveDynamicTableFactoryTest
- HiveLookupJoinITCase
- HiveSourceITCase
- HiveDialectQueryPlanTest
- HiveCatalogTest
- HiveTableSourceITCase

@BeforeClass -> @BeforeAll, @afterclass -> @afterall,
@before -> @beforeeach, @after -> @AfterEach,
@test(timeout=N) -> @test @timeout
…atch 4)

Migrate 7 test files using @Rule/@ClassRule TemporaryFolder:
- HiveModuleTest
- HiveSourceFileEnumeratorTest
- HivePartitionUtilsTest
- HiveCatalogUdfITCase
- HiveCatalogITCase
- HiveDialectITCase
- TableEnvHiveConnectorITCase

@rule TemporaryFolder -> @tempdir Path,
@ClassRule static TemporaryFolder -> @tempdir static Path,
LegacyRowResource -> manual before()/after() in lifecycle methods
Migrate 4 test files with complex JUnit 4 features:
- HiveCatalogDataTypeTest (ExpectedException -> assertThatThrownBy)
- HiveCatalogFactoryTest (TestExecutorResource -> TestExecutorExtension,
  ExpectedException -> assertThatThrownBy, TemporaryFolder -> @tempdir)
- HiveDialectQueryITCase (ClassRule TemporaryFolder -> @tempdir,
  ComparisonFailure -> AssertionFailedError)
- HiveDialectAggITCase (removed unused TemporaryFolder)

HiveRunnerITCase kept on JUnit 4 vintage — FlinkEmbeddedHiveRunner
extends BlockJUnit4ClassRunner with no JUnit 5 equivalent.
…ion (batch 6)

- Convert FlinkEmbeddedHiveRunner to FlinkEmbeddedHiveRunnerExtension
- Remove FlinkStandaloneHiveRunner (unused)
- Remove public from test classes and JUnit 5 annotated methods
- Remove mixed final/non-final parameter style
- Add per-flag comments to flink.surefire.baseArgLine
@jlalwani-amazon jlalwani-amazon force-pushed the flink-27939-junit5-migration branch from d2ba23a to 312468a Compare May 11, 2026 23:27
@jlalwani-amazon
Copy link
Copy Markdown
Author

Ready for re-review. Verified that the PR build passes on my github account


/** Test for {@link HiveCatalog} created by {@link HiveCatalogFactory}. */
public class HiveCatalogFactoryTest extends TestLogger {
class HiveCatalogFactoryTest {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this drops junit4's logger however doesn't add anything from junit5

I guess we should use @ExtendWith(TestLoggerExtension.class)
like for instance in ImmutableByteArrayWrapperTest of main repo

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that because TestLoggerExtension is in the META-INF/services file, the extension will auto-register. However, to be consistent with main repo and other tests, I am adding the declarative registration in next commit

// test partition location
tableEnv.executeSql("create table tbl2 (x int) partitioned by (p string)");
location = tempFolder.newFolder(",");
location = Files.createDirectories(tempFolder.resolve(",")).toFile();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we have such line in multiple places.
Should we extract it in a util method and reuse in a shorter manner?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! Fixing in next commit

@jlalwani-amazon jlalwani-amazon force-pushed the flink-27939-junit5-migration branch from d7be91e to d91a2f2 Compare May 12, 2026 15:05
- Add @ExtendWith(TestLoggerExtension.class) to HiveCatalogFactoryTest
  to replace dropped TestLogger base class
- Extract createSubDir helper in TableEnvHiveConnectorITCase to reduce
  repetition of Files.createDirectories(tempFolder.resolve(...)).toFile()
@jlalwani-amazon jlalwani-amazon force-pushed the flink-27939-junit5-migration branch from d91a2f2 to 081544f Compare May 12, 2026 15:32
@jlalwani-amazon
Copy link
Copy Markdown
Author

Both comments addressed. Ready for re-review

Comment on lines +48 to +49
Files.createDirectories(temporaryFolder.resolve("testHiveTablePartitionSerDe"))
.toFile();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

didn't we mention it in prev review iteration?

Comment on lines +88 to +97
LOGGER.info("Tearing down {}", context.getDisplayName());
try {
container.tearDown();
} catch (Throwable e) {
LOGGER.warn("Tear down failed: " + e.getMessage(), e);
}
}
if (temporaryFolder != null) {
temporaryFolder.delete();
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does it mean in case of exception nobody will drop the folder?

why can't we use @tempdir?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tempdir doesn't work on Extesitons. It tried is and I get this

java.lang.NullPointerException
      at FlinkEmbeddedHiveServerContext.newFolder(FlinkEmbeddedHiveServerContext.java:217)
      at FlinkEmbeddedHiveServerContext.createAndSetFolderProperty(FlinkEmbeddedHiveServerContext.java:243)
      at FlinkEmbeddedHiveServerContext.configureFileSystem(FlinkEmbeddedHiveServerContext.java:203)
      at FlinkEmbeddedHiveServerContext.init(FlinkEmbeddedHiveServerContext.java:86)
      at FlinkEmbeddedHiveRunnerExtension.createHiveServerContainer(FlinkEmbeddedHiveRunnerExtension.java:106)
      at FlinkEmbeddedHiveRunnerExtension.beforeAll(FlinkEmbeddedHiveRunnerExtension.java:81)

See https://stackoverflow.com/questions/54647577/how-to-use-tempdir-in-extensions

Also, afterAll is called even if there is an exception in the test. We are catching exception fro container.tearDown. So, the folder should get deleted even if there is exception in container shutdown

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, but then we are mixing junit4 and junit5 in this extension , aren't we?

public void testCreateTableWithConstraints() throws Exception {
Assume.assumeTrue(HiveVersionTestUtil.HIVE_310_OR_LATER);
void testCreateTableWithConstraints() throws Exception {
Assumptions.assumeTrue(HiveVersionTestUtil.HIVE_310_OR_LATER);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assumptions and Assertions should be in static import

Copy link
Copy Markdown
Author

@jlalwani-amazon jlalwani-amazon May 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok. I tried to keep the same convention as existing code. I'll fix in next commit.

Do we have any other coding conventions besides checkstyle that I should be aware about?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we use static imports everywhere? or only for Assumptions and Assertions. HiveTestUtils has static methods that are not being imported staticly. I'm not changing those static imports

String sinkPath = new File(tempFolder.newFolder(), "csv-order-sink").toURI().toString();
String sinkPath =
new File(
Files.createDirectories(tempFolder.resolve("csvSink")).toFile(),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems to be not addressed here and in other places

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pulling this code into a util method won't reduce the code too much. Because we will need to do something like FilesUtil.createSubDir(tempFolder, "csvSink") instead of Files.createDirectories(tempFolder.resolve("csvSink")).toFile().

Alternatively, we can pull the tempdir into a extension, but it seems overkill for one line of code.

I'll pull the createSubDir into a common util class in next commit

@snuyanzin
Copy link
Copy Markdown
Contributor

@jlalwani-amazon ai slop doesn't handle properly PR description

what is the reason to have this in description

Commit 3 - Java 17+ compatibility: Add --add-opens JVM flags to flink.surefire.baseArgLine (test-scoped only). Fixes 61 pre-existing test errors on Java 17+ caused by Hive's deep reflection on java.base internals.

if there is no change about it?

Please correct all other points as well

@jlalwani-amazon jlalwani-amazon force-pushed the flink-27939-junit5-migration branch 5 times, most recently from 246bee5 to 3b1d2e9 Compare May 14, 2026 17:06
…atic imports

- Extract HiveTestUtils.createTempSubDir() to deduplicate
  Files.createDirectories(tempFolder.resolve(...)).toFile() pattern
- Use static import for Assumptions.assumeTrue in HiveDialectITCase
- Remove private createSubDir helper from TableEnvHiveConnectorITCase
@jlalwani-amazon jlalwani-amazon force-pushed the flink-27939-junit5-migration branch from 3b1d2e9 to 05d0442 Compare May 14, 2026 17:10

private static final Logger LOGGER = LoggerFactory.getLogger(FlinkEmbeddedHiveRunner.class);
private HiveShellContainer container;
private TemporaryFolder temporaryFolder;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably missed in previous iteration
if it is junit5 extension why do we use junit4's class here?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants