This is an automated email from the ASF dual-hosted git repository.
exceptionfactory pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi.git
The following commit(s) were added to refs/heads/main by this push:
new 8fd6a98438f NIFI-16388 Fixed unit tests to clean up HSQLDB temporary
files (#11761)
8fd6a98438f is described below
commit 8fd6a98438ff11cea0a09ba740ecbb959d765304
Author: dan-s1 <[email protected]>
AuthorDate: Wed Oct 28 15:34:23 2026 -0400
NIFI-16388 Fixed unit tests to clean up HSQLDB temporary files (#11761)
Signed-off-by: David Handermann <[email protected]>
---
.../nifi/util/db/AbstractConnectionTest.java | 15 +-
.../java/org/apache/nifi/dbcp/DBCPServiceTest.java | 52 +++++--
.../record/sink/db/DatabaseRecordSinkTest.java | 159 ++++++++++++---------
3 files changed, 149 insertions(+), 77 deletions(-)
diff --git
a/nifi-extension-bundles/nifi-extension-utils/nifi-database-utils/src/test/java/org/apache/nifi/util/db/AbstractConnectionTest.java
b/nifi-extension-bundles/nifi-extension-utils/nifi-database-utils/src/test/java/org/apache/nifi/util/db/AbstractConnectionTest.java
index d76bfe4dd92..2fa4b897d16 100644
---
a/nifi-extension-bundles/nifi-extension-utils/nifi-database-utils/src/test/java/org/apache/nifi/util/db/AbstractConnectionTest.java
+++
b/nifi-extension-bundles/nifi-extension-utils/nifi-database-utils/src/test/java/org/apache/nifi/util/db/AbstractConnectionTest.java
@@ -16,6 +16,7 @@
*/
package org.apache.nifi.util.db;
+import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.io.TempDir;
@@ -23,10 +24,11 @@ import java.nio.file.Path;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
+import java.sql.Statement;
abstract class AbstractConnectionTest {
private static final String DRIVER_CLASS = "org.hsqldb.jdbc.JDBCDriver";
- private static final String CONNECTION_URL_FORMAT = "jdbc:hsqldb:file:%s";
+ private static final String CONNECTION_URL_FORMAT =
"jdbc:hsqldb:file:%s/nifi";
private static String connectionUrl;
@@ -37,7 +39,16 @@ abstract class AbstractConnectionTest {
} catch (final ClassNotFoundException e) {
throw new IllegalStateException("Driver Class [%s] not
found".formatted(DRIVER_CLASS), e);
}
- connectionUrl = CONNECTION_URL_FORMAT.formatted(tempDir);
+ connectionUrl =
CONNECTION_URL_FORMAT.formatted(tempDir.toAbsolutePath());
+ }
+
+ @AfterAll
+ public static void shutdownDatabase() throws SQLException {
+ try (Connection conn = DriverManager.getConnection(connectionUrl);
+ Statement stmt = conn.createStatement()) {
+ // Engine shutdown closes all connections regardless of status
+ stmt.execute("SHUTDOWN");
+ }
}
/**
diff --git
a/nifi-extension-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/test/java/org/apache/nifi/dbcp/DBCPServiceTest.java
b/nifi-extension-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/test/java/org/apache/nifi/dbcp/DBCPServiceTest.java
index 440ce95d38b..5f5260997c7 100644
---
a/nifi-extension-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/test/java/org/apache/nifi/dbcp/DBCPServiceTest.java
+++
b/nifi-extension-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/test/java/org/apache/nifi/dbcp/DBCPServiceTest.java
@@ -30,6 +30,8 @@ import org.apache.nifi.util.NoOpProcessor;
import org.apache.nifi.util.PropertyMigrationResult;
import org.apache.nifi.util.TestRunner;
import org.apache.nifi.util.TestRunners;
+import org.hsqldb.jdbc.JDBCDriver;
+import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
@@ -38,6 +40,7 @@ import org.opentest4j.AssertionFailedError;
import java.io.File;
import java.net.URISyntaxException;
import java.net.URL;
+import java.nio.file.Files;
import java.nio.file.Path;
import java.sql.Connection;
import java.sql.DriverManager;
@@ -48,6 +51,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
+import java.util.Properties;
import java.util.Set;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -63,25 +67,54 @@ public class DBCPServiceTest {
private static final String NON_JDBC_URL =
"http://localhost:3306/database";
private static final String DRIVER_CLASS = "org.hsqldb.jdbc.JDBCDriver";
- private static final String CONNECTION_URL_FORMAT = "jdbc:hsqldb:file:%s";
+ private static final String CONNECTION_URL_FORMAT =
"jdbc:hsqldb:file:%s/nifi";
+ private static final String DATABASE_PROPERTIES = "nifi.properties";
+ private static final String USERNAME = String.class.getSimpleName();
+ private static final String PASSWORD = String.class.getName();
private TestRunner runner;
private DBCPConnectionPool service;
+ private String connectionUrl;
+
+ private Path databasePath;
+
@BeforeEach
public void setService(@TempDir final Path tempDir) throws
InitializationException {
service = new DBCPConnectionPool();
runner = TestRunners.newTestRunner(NoOpProcessor.class);
runner.addControllerService(SERVICE_ID, service);
- final String url = CONNECTION_URL_FORMAT.formatted(tempDir);
- runner.setProperty(service, DBCPProperties.DATABASE_URL, url);
- runner.setProperty(service, DBCPProperties.DB_USER,
String.class.getSimpleName());
- runner.setProperty(service, DBCPProperties.DB_PASSWORD,
String.class.getName());
+ databasePath = tempDir.toAbsolutePath();
+ connectionUrl = CONNECTION_URL_FORMAT.formatted(databasePath);
+ runner.setProperty(service, DBCPProperties.DATABASE_URL,
connectionUrl);
+ runner.setProperty(service, DBCPProperties.DB_USER, USERNAME);
+ runner.setProperty(service, DBCPProperties.DB_PASSWORD, PASSWORD);
runner.setProperty(service, DBCPProperties.DB_DRIVERNAME,
DRIVER_CLASS);
}
+ @AfterEach
+ public void shutdownDatabase() throws Exception {
+ runner.shutdown();
+
+ // Attempt shutdown only when database files found
+ final Path propertiesFile = databasePath.resolve(DATABASE_PROPERTIES);
+ if (Files.exists(propertiesFile)) {
+ final Properties properties = new Properties();
+ properties.setProperty("user", USERNAME);
+ properties.setProperty("password", PASSWORD);
+
+ // Connect with JDBCDriver to avoid DriverManager deregistration.
+ try (Connection connection = new
JDBCDriver().connect(connectionUrl, properties)) {
+ try (final Statement statement = connection.createStatement())
{
+ // Engine shutdown closes all connections regardless of
status
+ statement.execute("SHUTDOWN");
+ }
+ }
+ }
+ }
+
@Test
public void testConnectionUrlInvalid() {
runner.assertValid(service);
@@ -204,15 +237,16 @@ public class DBCPServiceTest {
}
@Test
- public void testGetConnectionMaxTotalConnectionsExceeded() {
+ public void testGetConnectionMaxTotalConnectionsExceeded() throws
SQLException {
runner.setProperty(service, DBCPProperties.MAX_TOTAL_CONNECTIONS, "1");
runner.setProperty(service, DBCPProperties.MAX_WAIT_TIME, "1 ms");
runner.enableControllerService(service);
runner.assertValid(service);
- final Connection connection = service.getConnection();
- assertNotNull(connection);
- assertThrows(ProcessException.class, service::getConnection);
+ try (Connection connection = service.getConnection()) {
+ assertNotNull(connection);
+ assertThrows(ProcessException.class, service::getConnection);
+ }
}
@Test
diff --git
a/nifi-extension-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/test/java/org/apache/nifi/record/sink/db/DatabaseRecordSinkTest.java
b/nifi-extension-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/test/java/org/apache/nifi/record/sink/db/DatabaseRecordSinkTest.java
index 8dff9805d57..261e296d0a8 100644
---
a/nifi-extension-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/test/java/org/apache/nifi/record/sink/db/DatabaseRecordSinkTest.java
+++
b/nifi-extension-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/test/java/org/apache/nifi/record/sink/db/DatabaseRecordSinkTest.java
@@ -44,11 +44,14 @@ import org.apache.nifi.util.NoOpProcessor;
import org.apache.nifi.util.PropertyMigrationResult;
import org.apache.nifi.util.TestRunner;
import org.apache.nifi.util.TestRunners;
+import org.hsqldb.jdbc.JDBCDriver;
+import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import java.io.IOException;
+import java.nio.file.Files;
import java.nio.file.Path;
import java.sql.Connection;
import java.sql.ResultSet;
@@ -59,6 +62,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Properties;
import java.util.UUID;
import static org.apache.nifi.dbcp.utils.DBCPProperties.DATABASE_URL;
@@ -90,89 +94,114 @@ public class DatabaseRecordSinkTest {
private static final String SERVICE_ID =
DBCPConnectionPool.class.getName();
private static final String DRIVER_CLASS = "org.hsqldb.jdbc.JDBCDriver";
- private static final String CONNECTION_URL_FORMAT = "jdbc:hsqldb:file:%s";
+ private static final String CONNECTION_URL_FORMAT =
"jdbc:hsqldb:file:%s/nifi";
+ private static final String DATABASE_PROPERTIES = "nifi.properties";
+ private static final String USERNAME = String.class.getSimpleName();
+ private static final String PASSWORD = String.class.getName();
+ private Path databasePath;
private String connectionUrl;
private DBCPConnectionPool dbcpService;
+ private TestRunner runner;
@BeforeEach
public void setService(@TempDir final Path tempDir) throws
InitializationException {
dbcpService = new DBCPConnectionPool();
- TestRunner runner = TestRunners.newTestRunner(NoOpProcessor.class);
+ runner = TestRunners.newTestRunner(NoOpProcessor.class);
runner.addControllerService(SERVICE_ID, dbcpService);
- connectionUrl = CONNECTION_URL_FORMAT.formatted(tempDir);
+ databasePath = tempDir.toAbsolutePath();
+ connectionUrl = CONNECTION_URL_FORMAT.formatted(databasePath);
runner.setProperty(dbcpService, DATABASE_URL, connectionUrl);
- runner.setProperty(dbcpService, DB_USER, String.class.getSimpleName());
- runner.setProperty(dbcpService, DB_PASSWORD, String.class.getName());
runner.setProperty(dbcpService, DB_DRIVERNAME, DRIVER_CLASS);
}
+ @AfterEach
+ public void shutdownDatabase() throws SQLException {
+ runner.shutdown();
+ dbcpService.shutdown();
+
+ // Attempt shutdown only when database files found
+ final Path propertiesFile = databasePath.resolve(DATABASE_PROPERTIES);
+ if (Files.exists(propertiesFile)) {
+ final Properties properties = new Properties();
+ properties.setProperty("user", USERNAME);
+ properties.setProperty("password", PASSWORD);
+
+ try (Connection connection = new
JDBCDriver().connect(connectionUrl, properties)) {
+ try (final Statement statement = connection.createStatement())
{
+ // Engine shutdown closes all connections regardless of
status
+ statement.execute("SHUTDOWN");
+ }
+ }
+ }
+ }
+
@Test
void testRecordFormat() throws IOException, InitializationException,
SQLException {
final DatabaseRecordSink task = initTask("TESTTABLE");
// Create the table
- final Connection con = dbcpService.getConnection();
- final Statement stmt = con.createStatement();
- try (stmt) {
+ try (Connection con = dbcpService.getConnection();
+ Statement stmt = con.createStatement()) {
try {
stmt.execute("drop table TESTTABLE");
} catch (final SQLException ignored) {
// Ignore, usually due to Derby not having DROP TABLE IF EXISTS
}
stmt.executeUpdate("CREATE TABLE testTable (field1 integer, field2
varchar(20))");
- }
-
- final List<RecordField> recordFields = Arrays.asList(
- new RecordField("field1", RecordFieldType.INT.getDataType()),
- new RecordField("field2", RecordFieldType.STRING.getDataType())
- );
- final RecordSchema recordSchema = new SimpleRecordSchema(recordFields);
-
- final Map<String, Object> row1 = new HashMap<>();
- row1.put("field1", 15);
- row1.put("field2", "Hello");
- final Map<String, Object> row2 = new HashMap<>();
- row2.put("field1", 6);
- row2.put("field2", "World!");
-
- final RecordSet recordSet = new ListRecordSet(recordSchema,
Arrays.asList(
- new MapRecord(recordSchema, row1),
- new MapRecord(recordSchema, row2)
- ));
-
- final WriteResult writeResult = task.sendData(recordSet,
Collections.singletonMap("a", "Hello"), true);
- assertNotNull(writeResult);
- assertEquals(2, writeResult.getRecordCount());
- assertEquals("Hello", writeResult.getAttributes().get("a"));
-
- final Statement st = con.createStatement();
- final ResultSet resultSet = st.executeQuery("select * from testTable");
- assertTrue(resultSet.next());
-
- Object f1 = resultSet.getObject(1);
- assertNotNull(f1);
- assertInstanceOf(Integer.class, f1);
- assertEquals(15, f1);
- Object f2 = resultSet.getObject(2);
- assertNotNull(f2);
- assertInstanceOf(String.class, f2);
- assertEquals("Hello", f2);
-
- assertTrue(resultSet.next());
-
- f1 = resultSet.getObject(1);
- assertNotNull(f1);
- assertInstanceOf(Integer.class, f1);
- assertEquals(6, f1);
- f2 = resultSet.getObject(2);
- assertNotNull(f2);
- assertInstanceOf(String.class, f2);
- assertEquals("World!", f2);
-
- assertFalse(resultSet.next());
+ final List<RecordField> recordFields = Arrays.asList(
+ new RecordField("field1",
RecordFieldType.INT.getDataType()),
+ new RecordField("field2",
RecordFieldType.STRING.getDataType())
+ );
+ final RecordSchema recordSchema = new
SimpleRecordSchema(recordFields);
+
+ final Map<String, Object> row1 = new HashMap<>();
+ row1.put("field1", 15);
+ row1.put("field2", "Hello");
+
+ final Map<String, Object> row2 = new HashMap<>();
+ row2.put("field1", 6);
+ row2.put("field2", "World!");
+
+ final RecordSet recordSet = new ListRecordSet(recordSchema,
Arrays.asList(
+ new MapRecord(recordSchema, row1),
+ new MapRecord(recordSchema, row2)
+ ));
+
+ final WriteResult writeResult = task.sendData(recordSet,
Collections.singletonMap("a", "Hello"), true);
+ assertNotNull(writeResult);
+ assertEquals(2, writeResult.getRecordCount());
+ assertEquals("Hello", writeResult.getAttributes().get("a"));
+
+ final Statement st = con.createStatement();
+ final ResultSet resultSet = st.executeQuery("select * from
testTable");
+ assertTrue(resultSet.next());
+
+ Object f1 = resultSet.getObject(1);
+ assertNotNull(f1);
+ assertInstanceOf(Integer.class, f1);
+ assertEquals(15, f1);
+ Object f2 = resultSet.getObject(2);
+ assertNotNull(f2);
+ assertInstanceOf(String.class, f2);
+ assertEquals("Hello", f2);
+
+ assertTrue(resultSet.next());
+
+ f1 = resultSet.getObject(1);
+ assertNotNull(f1);
+ assertInstanceOf(Integer.class, f1);
+ assertEquals(6, f1);
+ f2 = resultSet.getObject(2);
+ assertNotNull(f2);
+ assertInstanceOf(String.class, f2);
+ assertEquals("World!", f2);
+
+ assertFalse(resultSet.next());
+ resultSet.close();
+ }
}
@Test
@@ -199,9 +228,8 @@ public class DatabaseRecordSinkTest {
final DatabaseRecordSink task = initTask("TESTTABLE");
// Create the table
- final Connection con = dbcpService.getConnection();
- final Statement stmt = con.createStatement();
- try (stmt) {
+ try (Connection con = dbcpService.getConnection();
+ Statement stmt = con.createStatement()) {
try {
stmt.execute("drop table TESTTABLE");
} catch (final SQLException ignored) {
@@ -231,9 +259,8 @@ public class DatabaseRecordSinkTest {
final DatabaseRecordSink task = initTask("TESTTABLE");
// Create the table
- final Connection con = dbcpService.getConnection();
- final Statement stmt = con.createStatement();
- try (stmt) {
+ try (Connection con = dbcpService.getConnection();
+ Statement stmt = con.createStatement()) {
try {
stmt.execute("drop table TESTTABLE");
} catch (final SQLException ignored) {
@@ -311,8 +338,8 @@ public class DatabaseRecordSinkTest {
final StateManager dbStateManager = new MockStateManager(dbcpService);
when(dbContext.getProperty(DATABASE_URL)).thenReturn(new
MockPropertyValue(connectionUrl));
- when(dbContext.getProperty(DB_USER)).thenReturn(new
MockPropertyValue(null));
- when(dbContext.getProperty(DB_PASSWORD)).thenReturn(new
MockPropertyValue(null));
+ when(dbContext.getProperty(DB_USER)).thenReturn(new
MockPropertyValue(USERNAME));
+ when(dbContext.getProperty(DB_PASSWORD)).thenReturn(new
MockPropertyValue(PASSWORD));
when(dbContext.getProperty(DB_DRIVERNAME)).thenReturn(new
MockPropertyValue(DRIVER_CLASS));
when(dbContext.getProperty(DB_DRIVER_LOCATION)).thenReturn(new
MockPropertyValue(""));
when(dbContext.getProperty(MAX_TOTAL_CONNECTIONS)).thenReturn(new
MockPropertyValue("2"));