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"));

Reply via email to