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

hansva pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/hop.git


The following commit(s) were added to refs/heads/main by this push:
     new 9f499d2d9b harden unit tests, fixes #7578 (#7579)
9f499d2d9b is described below

commit 9f499d2d9b9ef2f3f438021be59fdc85ff2b76ec
Author: Hans Van Akelyen <[email protected]>
AuthorDate: Mon Jul 20 10:57:43 2026 +0200

    harden unit tests, fixes #7578 (#7579)
---
 .../metadata/SerializableMetadataProviderTest.java    |  5 +++--
 .../refactor/MetadataReferenceFinderTest.java         |  5 +++--
 .../org/apache/hop/pipeline/PipelineMetaTest.java     | 10 +++-------
 .../hop/pipeline/TransformWithMappingMetaTest.java    | 14 ++------------
 .../engines/remote/RemotePipelineEngineTest.java      | 10 +++-------
 .../hop/pipeline/transform/TransformOptionTest.java   | 10 ++--------
 .../java/org/apache/hop/workflow/WorkflowTest.java    |  5 +++--
 .../loadsave/WorkflowActionLoadSaveTestSupport.java   | 10 +++-------
 .../workflow/engine/WorkflowEngineFactoryTest.java    | 19 ++++++++++++-------
 .../hop/www/RegisterPipelineServletLogFileTest.java   | 10 +++-------
 .../org/apache/hop/ui/testing/SwtBotTestBase.java     |  4 ++++
 11 files changed, 41 insertions(+), 61 deletions(-)

diff --git 
a/engine/src/test/java/org/apache/hop/core/metadata/SerializableMetadataProviderTest.java
 
b/engine/src/test/java/org/apache/hop/core/metadata/SerializableMetadataProviderTest.java
index 0b6f9c6f70..3f03658013 100644
--- 
a/engine/src/test/java/org/apache/hop/core/metadata/SerializableMetadataProviderTest.java
+++ 
b/engine/src/test/java/org/apache/hop/core/metadata/SerializableMetadataProviderTest.java
@@ -20,19 +20,20 @@ package org.apache.hop.core.metadata;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 
-import org.apache.hop.core.HopEnvironment;
 import org.apache.hop.core.util.TestUtil;
+import org.apache.hop.junit.rules.RestoreHopEngineEnvironmentExtension;
 import org.apache.hop.metadata.api.IHopMetadataSerializer;
 import org.apache.hop.metadata.serializer.memory.MemoryMetadataProvider;
 import org.apache.hop.server.HopServerMeta;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
 
+@ExtendWith(RestoreHopEngineEnvironmentExtension.class)
 class SerializableMetadataProviderTest {
 
   @BeforeEach
   void before() throws Exception {
-    HopEnvironment.init();
     TestUtil.registerTestPluginTypes();
   }
 
diff --git 
a/engine/src/test/java/org/apache/hop/metadata/refactor/MetadataReferenceFinderTest.java
 
b/engine/src/test/java/org/apache/hop/metadata/refactor/MetadataReferenceFinderTest.java
index 6de500691f..3c850bb4ff 100644
--- 
a/engine/src/test/java/org/apache/hop/metadata/refactor/MetadataReferenceFinderTest.java
+++ 
b/engine/src/test/java/org/apache/hop/metadata/refactor/MetadataReferenceFinderTest.java
@@ -26,13 +26,14 @@ import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.Collections;
 import java.util.List;
-import org.apache.hop.core.HopEnvironment;
 import org.apache.hop.core.variables.Variables;
+import org.apache.hop.junit.rules.RestoreHopEngineEnvironmentExtension;
 import org.apache.hop.metadata.serializer.memory.MemoryMetadataProvider;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
 
 /**
  * Unit tests for {@link MetadataReferenceFinder}.
@@ -46,6 +47,7 @@ import org.junit.jupiter.api.Test;
  * <p>The tests here focus on guard conditions (null/empty inputs) and 
behaviors that are
  * independent of plugin registration.
  */
+@ExtendWith(RestoreHopEngineEnvironmentExtension.class)
 class MetadataReferenceFinderTest {
 
   private static MemoryMetadataProvider provider;
@@ -54,7 +56,6 @@ class MetadataReferenceFinderTest {
 
   @BeforeAll
   static void setupEnvironment() throws Exception {
-    HopEnvironment.init();
     provider = new MemoryMetadataProvider();
   }
 
diff --git a/engine/src/test/java/org/apache/hop/pipeline/PipelineMetaTest.java 
b/engine/src/test/java/org/apache/hop/pipeline/PipelineMetaTest.java
index 85a68b264a..1ee4349d05 100644
--- a/engine/src/test/java/org/apache/hop/pipeline/PipelineMetaTest.java
+++ b/engine/src/test/java/org/apache/hop/pipeline/PipelineMetaTest.java
@@ -42,7 +42,6 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import org.apache.hop.core.Const;
-import org.apache.hop.core.HopEnvironment;
 import org.apache.hop.core.IProgressMonitor;
 import org.apache.hop.core.NotePadMeta;
 import org.apache.hop.core.annotations.Transform;
@@ -59,6 +58,7 @@ import org.apache.hop.core.row.value.ValueMetaString;
 import org.apache.hop.core.variables.IVariables;
 import org.apache.hop.core.variables.Variables;
 import org.apache.hop.core.xml.XmlHandler;
+import org.apache.hop.junit.rules.RestoreHopEngineEnvironmentExtension;
 import org.apache.hop.metadata.api.IHopMetadataProvider;
 import org.apache.hop.metadata.api.IHopMetadataSerializer;
 import org.apache.hop.metadata.serializer.memory.MemoryMetadataProvider;
@@ -72,23 +72,19 @@ import org.apache.hop.pipeline.transform.TransformMeta;
 import org.apache.hop.pipeline.transform.TransformPartitioningMeta;
 import org.apache.hop.pipeline.transform.transforms.FakeMeta;
 import org.apache.hop.pipeline.transforms.dummy.DummyMeta;
-import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.Mockito;
 import org.mockito.stubbing.Answer;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
 
 /** Unit test for {@link PipelineMeta} */
+@ExtendWith(RestoreHopEngineEnvironmentExtension.class)
 class PipelineMetaTest {
   public static final String TRANSFORM_NAME = "Any transform name";
 
-  @BeforeAll
-  static void initHop() throws Exception {
-    HopEnvironment.init();
-  }
-
   private PipelineMeta pipelineMeta;
   private IVariables variables;
   private IHopMetadataProvider metadataProvider;
diff --git 
a/engine/src/test/java/org/apache/hop/pipeline/TransformWithMappingMetaTest.java
 
b/engine/src/test/java/org/apache/hop/pipeline/TransformWithMappingMetaTest.java
index 8358f3102c..e1fedc061d 100644
--- 
a/engine/src/test/java/org/apache/hop/pipeline/TransformWithMappingMetaTest.java
+++ 
b/engine/src/test/java/org/apache/hop/pipeline/TransformWithMappingMetaTest.java
@@ -23,32 +23,22 @@ import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 import org.apache.hop.core.Const;
-import org.apache.hop.core.HopEnvironment;
 import org.apache.hop.core.logging.LoggingObject;
 import org.apache.hop.core.variables.IVariables;
 import org.apache.hop.core.variables.Variables;
+import org.apache.hop.junit.rules.RestoreHopEngineEnvironmentExtension;
 import org.apache.hop.pipeline.engines.local.LocalPipelineEngine;
-import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.Mock;
 import org.mockito.junit.jupiter.MockitoExtension;
 
+@ExtendWith(RestoreHopEngineEnvironmentExtension.class)
 @ExtendWith(MockitoExtension.class)
 class TransformWithMappingMetaTest {
 
   @Mock PipelineMeta pipelineMeta;
 
-  @BeforeEach
-  void setupBefore() throws Exception {
-    // Without initialization of the Hop Environment, the load of the pipeline 
fails
-    // when run in Windows (saying it cannot find the Database plugin ID for 
Oracle). Digging into
-    // it I discovered that it's during the read of the shared objects xml 
which doesn't reference
-    // Oracle
-    // at all. Initializing the environment fixed everything.
-    HopEnvironment.init();
-  }
-
   @Test
   void activateParamsTest() throws Exception {
     String childParam = "childParam";
diff --git 
a/engine/src/test/java/org/apache/hop/pipeline/engines/remote/RemotePipelineEngineTest.java
 
b/engine/src/test/java/org/apache/hop/pipeline/engines/remote/RemotePipelineEngineTest.java
index 0bc094afe2..a0ed6f326d 100644
--- 
a/engine/src/test/java/org/apache/hop/pipeline/engines/remote/RemotePipelineEngineTest.java
+++ 
b/engine/src/test/java/org/apache/hop/pipeline/engines/remote/RemotePipelineEngineTest.java
@@ -21,31 +21,27 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.util.ArrayList;
-import org.apache.hop.core.HopEnvironment;
 import org.apache.hop.core.exception.HopException;
 import org.apache.hop.core.logging.LogLevel;
+import org.apache.hop.junit.rules.RestoreHopEngineEnvironmentExtension;
 import org.apache.hop.metadata.api.IHopMetadataProvider;
 import org.apache.hop.metadata.serializer.memory.MemoryMetadataProvider;
 import org.apache.hop.pipeline.PipelineMeta;
 import org.apache.hop.pipeline.config.PipelineRunConfiguration;
 import org.apache.hop.pipeline.engines.local.LocalPipelineRunConfiguration;
-import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
 
 /**
  * The run configuration a remote run configuration hands the pipeline to is 
used on the server.
  * When that leads back to a remote run configuration the pipeline keeps being 
handed on and
  * registered again and again. See issue #4086.
  */
+@ExtendWith(RestoreHopEngineEnvironmentExtension.class)
 class RemotePipelineEngineTest {
 
   private static final String SERVER_NAME = "a-server";
 
-  @BeforeAll
-  static void setUpBeforeClass() throws HopException {
-    HopEnvironment.init();
-  }
-
   /** A remote run configuration that names itself never reaches a server that 
would run it. */
   @Test
   void runConfigurationThatRefersToItselfIsRejected() throws Exception {
diff --git 
a/engine/src/test/java/org/apache/hop/pipeline/transform/TransformOptionTest.java
 
b/engine/src/test/java/org/apache/hop/pipeline/transform/TransformOptionTest.java
index c5747b6766..dd8f200ab2 100644
--- 
a/engine/src/test/java/org/apache/hop/pipeline/transform/TransformOptionTest.java
+++ 
b/engine/src/test/java/org/apache/hop/pipeline/transform/TransformOptionTest.java
@@ -24,27 +24,21 @@ import static org.mockito.Mockito.when;
 
 import java.util.ArrayList;
 import java.util.List;
-import org.apache.hop.core.HopEnvironment;
 import org.apache.hop.core.ICheckResult;
-import org.apache.hop.core.exception.HopException;
 import org.apache.hop.core.variables.IVariables;
-import org.junit.jupiter.api.BeforeAll;
+import org.apache.hop.junit.rules.RestoreHopEngineEnvironmentExtension;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.Mock;
 import org.mockito.junit.jupiter.MockitoExtension;
 
+@ExtendWith(RestoreHopEngineEnvironmentExtension.class)
 @ExtendWith(MockitoExtension.class)
 class TransformOptionTest {
   @Mock TransformMeta transformMeta;
   @Mock IVariables variables;
 
-  @BeforeAll
-  static void setUpBeforeClass() throws HopException {
-    HopEnvironment.init();
-  }
-
   @BeforeEach
   void setup() {
     when(variables.resolve(anyString()))
diff --git a/engine/src/test/java/org/apache/hop/workflow/WorkflowTest.java 
b/engine/src/test/java/org/apache/hop/workflow/WorkflowTest.java
index 1fae0e3faa..3b1a49aaff 100644
--- a/engine/src/test/java/org/apache/hop/workflow/WorkflowTest.java
+++ b/engine/src/test/java/org/apache/hop/workflow/WorkflowTest.java
@@ -23,7 +23,6 @@ import static org.mockito.Mockito.mock;
 
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
-import org.apache.hop.core.HopEnvironment;
 import org.apache.hop.core.Result;
 import org.apache.hop.core.annotations.Action;
 import org.apache.hop.core.exception.HopException;
@@ -33,6 +32,7 @@ import org.apache.hop.core.logging.HopLogStore;
 import org.apache.hop.core.logging.LogLevel;
 import org.apache.hop.core.plugins.ActionPluginType;
 import org.apache.hop.core.plugins.PluginRegistry;
+import org.apache.hop.junit.rules.RestoreHopEngineEnvironmentExtension;
 import org.apache.hop.workflow.action.ActionBase;
 import org.apache.hop.workflow.action.ActionMeta;
 import org.apache.hop.workflow.action.IAction;
@@ -43,7 +43,9 @@ import 
org.apache.hop.workflow.engines.local.LocalWorkflowEngine;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
 
+@ExtendWith(RestoreHopEngineEnvironmentExtension.class)
 class WorkflowTest {
 
   int count = 10000;
@@ -141,7 +143,6 @@ class WorkflowTest {
 
   @BeforeAll
   static void beforeClass() throws HopException, HopPluginException {
-    HopEnvironment.init();
     PluginRegistry.getInstance()
         .registerPluginClass(
             ActionBlockingForWorkflowStopTest.class.getName(),
diff --git 
a/engine/src/test/java/org/apache/hop/workflow/action/loadsave/WorkflowActionLoadSaveTestSupport.java
 
b/engine/src/test/java/org/apache/hop/workflow/action/loadsave/WorkflowActionLoadSaveTestSupport.java
index 3f54526769..d80da6a0a8 100644
--- 
a/engine/src/test/java/org/apache/hop/workflow/action/loadsave/WorkflowActionLoadSaveTestSupport.java
+++ 
b/engine/src/test/java/org/apache/hop/workflow/action/loadsave/WorkflowActionLoadSaveTestSupport.java
@@ -21,23 +21,19 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import org.apache.hop.core.HopEnvironment;
 import org.apache.hop.core.exception.HopException;
+import org.apache.hop.junit.rules.RestoreHopEngineEnvironmentExtension;
 import 
org.apache.hop.pipeline.transforms.loadsave.validator.IFieldLoadSaveValidator;
 import org.apache.hop.workflow.action.IAction;
-import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
 
+@ExtendWith(RestoreHopEngineEnvironmentExtension.class)
 public abstract class WorkflowActionLoadSaveTestSupport<T extends IAction> {
 
   protected LoadSaveTester<T> tester;
 
-  @BeforeAll
-  static void setUpBeforeClass() throws HopException {
-    HopEnvironment.init();
-  }
-
   @BeforeEach
   void setUp() throws Exception {
     List<String> attributes = listAttributes();
diff --git 
a/engine/src/test/java/org/apache/hop/workflow/engine/WorkflowEngineFactoryTest.java
 
b/engine/src/test/java/org/apache/hop/workflow/engine/WorkflowEngineFactoryTest.java
index fbc52080af..c21beffb60 100644
--- 
a/engine/src/test/java/org/apache/hop/workflow/engine/WorkflowEngineFactoryTest.java
+++ 
b/engine/src/test/java/org/apache/hop/workflow/engine/WorkflowEngineFactoryTest.java
@@ -21,12 +21,12 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertInstanceOf;
 import static org.junit.jupiter.api.Assertions.assertSame;
 
-import org.apache.hop.core.HopEnvironment;
 import org.apache.hop.core.exception.HopException;
 import org.apache.hop.core.logging.LogLevel;
 import org.apache.hop.core.logging.LoggingObjectType;
 import org.apache.hop.core.logging.SimpleLoggingObject;
 import org.apache.hop.core.variables.Variables;
+import org.apache.hop.junit.rules.RestoreHopEngineEnvironmentExtension;
 import org.apache.hop.metadata.serializer.memory.MemoryMetadataProvider;
 import org.apache.hop.workflow.WorkflowMeta;
 import org.apache.hop.workflow.config.IWorkflowEngineRunConfiguration;
@@ -35,16 +35,21 @@ import 
org.apache.hop.workflow.engines.local.LocalWorkflowEngine;
 import org.apache.hop.workflow.engines.local.LocalWorkflowRunConfiguration;
 import org.apache.hop.workflow.engines.remote.RemoteWorkflowEngine;
 import org.apache.hop.workflow.engines.remote.RemoteWorkflowRunConfiguration;
-import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
 
+/**
+ * Uses {@link RestoreHopEngineEnvironmentExtension} rather than a plain {@code
+ * HopEnvironment.init()} in a {@code @BeforeAll}. The bare init is a no-op 
when a previous test
+ * already flipped {@code HopEnvironment.initialized} to true, and a base 
{@code
+ * RestoreHopEnvironmentExtension} test running in between wipes the 
PluginRegistry without nulling
+ * that flag. That combination left the workflow engine plugins 
("Local"/"Remote") unregistered and
+ * made this class fail depending on test execution order. The engine 
extension forces a full reset
+ * + re-init, so the registry is always populated here.
+ */
+@ExtendWith(RestoreHopEngineEnvironmentExtension.class)
 class WorkflowEngineFactoryTest {
 
-  @BeforeAll
-  static void setUpBeforeClass() throws HopException {
-    HopEnvironment.init();
-  }
-
   /**
    * The parent logging object is how the log level is pushed down into the 
engine. A workflow that
    * runs on a server needs it as much as one that runs locally, or the server 
ends up logging at
diff --git 
a/engine/src/test/java/org/apache/hop/www/RegisterPipelineServletLogFileTest.java
 
b/engine/src/test/java/org/apache/hop/www/RegisterPipelineServletLogFileTest.java
index 7e3a25bc5d..1df7ec40a3 100644
--- 
a/engine/src/test/java/org/apache/hop/www/RegisterPipelineServletLogFileTest.java
+++ 
b/engine/src/test/java/org/apache/hop/www/RegisterPipelineServletLogFileTest.java
@@ -23,11 +23,11 @@ import static 
org.junit.jupiter.api.Assertions.assertNotNull;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.ArrayList;
-import org.apache.hop.core.HopEnvironment;
 import org.apache.hop.core.exception.HopException;
 import org.apache.hop.core.logging.LoggingRegistry;
 import org.apache.hop.core.metadata.SerializableMetadataProvider;
 import org.apache.hop.core.variables.Variables;
+import org.apache.hop.junit.rules.RestoreHopEngineEnvironmentExtension;
 import org.apache.hop.metadata.serializer.memory.MemoryMetadataProvider;
 import org.apache.hop.metadata.serializer.multi.MultiMetadataProvider;
 import org.apache.hop.pipeline.PipelineConfiguration;
@@ -37,25 +37,21 @@ import 
org.apache.hop.pipeline.config.PipelineRunConfiguration;
 import org.apache.hop.pipeline.engine.IPipelineEngine;
 import org.apache.hop.pipeline.engines.local.LocalPipelineRunConfiguration;
 import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
 
 /**
  * Registering a pipeline with a log file used to fail with a 
NullPointerException, because the
  * logging object of the servlet had no log channel to hang the log file 
writer on. See issue #4677.
  */
+@ExtendWith(RestoreHopEngineEnvironmentExtension.class)
 class RegisterPipelineServletLogFileTest {
 
   private static final String RUN_CONFIGURATION_NAME = "local";
 
   private Path logFile;
 
-  @BeforeAll
-  static void setUpBeforeClass() throws HopException {
-    HopEnvironment.init();
-  }
-
   @BeforeEach
   void setUp() throws Exception {
     logFile = Files.createTempFile("register-pipeline-servlet", ".log");
diff --git a/ui/src/test/java/org/apache/hop/ui/testing/SwtBotTestBase.java 
b/ui/src/test/java/org/apache/hop/ui/testing/SwtBotTestBase.java
index c535e9eeba..5fdc60d357 100644
--- a/ui/src/test/java/org/apache/hop/ui/testing/SwtBotTestBase.java
+++ b/ui/src/test/java/org/apache/hop/ui/testing/SwtBotTestBase.java
@@ -60,6 +60,10 @@ public abstract class SwtBotTestBase {
         GraphicsEnvironment.isHeadless(),
         "No display available (headless); skipping SWTBot UI tests. Run on a 
desktop or under Xvfb.");
     // Registers the transform/plugin metadata (e.g. the Abort transform) the 
dialogs look up.
+    // reset() first so we always get a full re-registration: a bare init() is 
a no-op when an
+    // earlier test already flipped HopEnvironment.initialized, and a test 
that wiped the
+    // PluginRegistry in the meantime would otherwise leave the dialogs 
without their plugins.
+    HopEnvironment.reset();
     HopEnvironment.init();
     keepAuditStateOutOfSourceTree();
     ensureDisplay();

Reply via email to