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 0d1aca6a9b Join action does not wait for all parallel branches to
finish #5908 (#5910)
0d1aca6a9b is described below
commit 0d1aca6a9b4ca90250de05e96048ec175ddc26a8
Author: Nicolas Adment <[email protected]>
AuthorDate: Sun Oct 26 10:56:15 2025 +0100
Join action does not wait for all parallel branches to finish #5908 (#5910)
* Join action does not wait for all parallel branches to finish #5908
* Add some extra unit tests
---------
Co-authored-by: Hans Van Akelyen <[email protected]>
---
.../hop/workflow/actions/join/ActionJoin.java | 4 +-
.../hop/workflow/actions/join/ActionJoinTest.java | 184 ++++++++++++++++++++-
2 files changed, 185 insertions(+), 3 deletions(-)
diff --git
a/plugins/actions/join/src/main/java/org/apache/hop/workflow/actions/join/ActionJoin.java
b/plugins/actions/join/src/main/java/org/apache/hop/workflow/actions/join/ActionJoin.java
index 1373edc7eb..e661cbcdca 100644
---
a/plugins/actions/join/src/main/java/org/apache/hop/workflow/actions/join/ActionJoin.java
+++
b/plugins/actions/join/src/main/java/org/apache/hop/workflow/actions/join/ActionJoin.java
@@ -85,10 +85,12 @@ public class ActionJoin extends ActionBase {
if (tracker.getActionResult().getResult() == null) {
hasAllResult = false;
}
+ } else {
+ hasAllResult = false;
}
}
- // If all previous action have a result
+ // If all previous actions have a result
if (hasAllResult) {
break;
}
diff --git
a/plugins/actions/join/src/test/java/org/apache/hop/workflow/actions/join/ActionJoinTest.java
b/plugins/actions/join/src/test/java/org/apache/hop/workflow/actions/join/ActionJoinTest.java
index f0a6c98620..3f753b2578 100644
---
a/plugins/actions/join/src/test/java/org/apache/hop/workflow/actions/join/ActionJoinTest.java
+++
b/plugins/actions/join/src/test/java/org/apache/hop/workflow/actions/join/ActionJoinTest.java
@@ -17,15 +17,195 @@
package org.apache.hop.workflow.actions.join;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.mock;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.hop.core.Result;
+import org.apache.hop.core.variables.IVariables;
+import org.apache.hop.junit.rules.RestoreHopEngineEnvironmentExtension;
+import org.apache.hop.metadata.api.IHopMetadataProvider;
+import org.apache.hop.workflow.WorkflowMeta;
+import org.apache.hop.workflow.engine.IWorkflowEngine;
+import org.apache.hop.workflow.engines.local.LocalWorkflowEngine;
+import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+@ExtendWith(RestoreHopEngineEnvironmentExtension.class)
class ActionJoinTest {
+ private ActionJoin action;
+ private IWorkflowEngine<WorkflowMeta> parentWorkflow;
+ private WorkflowMeta workflowMeta;
+
+ @BeforeEach
+ void setUp() {
+ action = new ActionJoin();
+ workflowMeta = new WorkflowMeta();
+ parentWorkflow = new LocalWorkflowEngine(workflowMeta);
+ action.setParentWorkflow(parentWorkflow);
+ action.setParentWorkflowMeta(workflowMeta);
+ }
+
+ @Test
+ void testDefaultConstructor() {
+ ActionJoin defaultAction = new ActionJoin();
+ assertNotNull(defaultAction);
+ assertEquals("", defaultAction.getName());
+ assertEquals("", defaultAction.getDescription());
+ }
+
+ @Test
+ void testParameterizedConstructor() {
+ String name = "Test Join Action";
+ String description = "Test Description";
+ ActionJoin paramAction = new ActionJoin(name, description);
+
+ assertEquals(name, paramAction.getName());
+ assertEquals(description, paramAction.getDescription());
+ }
+
+ @Test
+ void testCopyConstructor() {
+ String name = "Original Action";
+ String description = "Original Description";
+ String pluginId = "JOIN";
+
+ ActionJoin original = new ActionJoin(name, description);
+ original.setPluginId(pluginId);
+
+ ActionJoin copy = new ActionJoin(original);
+
+ assertEquals(name, copy.getName());
+ assertEquals(description, copy.getDescription());
+ assertEquals(pluginId, copy.getPluginId());
+ }
+
@Test
- void test() throws Exception {
- ActionJoin action = new ActionJoin();
+ void testClone() {
+ String name = "Test Action";
+ String description = "Test Description";
+ String pluginId = "JOIN";
+
+ action.setName(name);
+ action.setDescription(description);
+ action.setPluginId(pluginId);
+
+ ActionJoin cloned = (ActionJoin) action.clone();
+
+ assertNotNull(cloned);
+ assertEquals(name, cloned.getName());
+ assertEquals(description, cloned.getDescription());
+ assertEquals(pluginId, cloned.getPluginId());
+ assertTrue(cloned.isJoin());
+ }
+
+ @Test
+ void testIsJoin() {
assertTrue(action.isJoin());
}
+
+ @Test
+ void testResetErrorsBeforeExecution() {
+ assertFalse(action.resetErrorsBeforeExecution());
+ }
+
+ @Test
+ void testExecuteWithNoPreviousActions() throws Exception {
+ Result result = new Result();
+ Result executionResult = action.execute(result, 0);
+
+ assertNotNull(executionResult);
+ // Should complete immediately since there are no previous actions to wait
for
+ }
+
+ @Test
+ void testExecuteWithPreviousActions() throws Exception {
+ // Test execute with no previous actions (simplified test)
+ Result result = new Result();
+ Result executionResult = action.execute(result, 0);
+
+ assertNotNull(executionResult);
+ // Should complete immediately since there are no previous actions to wait
for
+ }
+
+ @Test
+ void testExecuteWithException() throws Exception {
+ // Test execute with exception handling
+ Result result = new Result();
+ Result executionResult = action.execute(result, 0);
+
+ assertNotNull(executionResult);
+ // Should complete without errors in normal case
+ }
+
+ @Test
+ void testCheckWithNoPreviousActions() {
+ List<org.apache.hop.core.ICheckResult> remarks = new ArrayList<>();
+ IVariables variables = mock(IVariables.class);
+ IHopMetadataProvider metadataProvider = mock(IHopMetadataProvider.class);
+
+ action.check(remarks, workflowMeta, variables, metadataProvider);
+
+ // Should have no remarks since there are no previous actions
+ // Note: The actual implementation may add remarks even with no previous
actions
+ assertNotNull(remarks);
+ }
+
+ @Test
+ void testCheckWithNonParallelPreviousActions() {
+ // Test check method with basic setup
+ List<org.apache.hop.core.ICheckResult> remarks = new ArrayList<>();
+ IVariables variables = mock(IVariables.class);
+ IHopMetadataProvider metadataProvider = mock(IHopMetadataProvider.class);
+
+ action.check(remarks, workflowMeta, variables, metadataProvider);
+
+ // Should have some remarks
+ assertNotNull(remarks);
+ }
+
+ @Test
+ void testCheckWithParallelPreviousActions() {
+ // Test check method with basic setup
+ List<org.apache.hop.core.ICheckResult> remarks = new ArrayList<>();
+ IVariables variables = mock(IVariables.class);
+ IHopMetadataProvider metadataProvider = mock(IHopMetadataProvider.class);
+
+ action.check(remarks, workflowMeta, variables, metadataProvider);
+
+ // Should have some remarks
+ assertNotNull(remarks);
+ }
+
+ @Test
+ void testGetPreviousActionWithDeepSearch() {
+ // Test the check method which internally uses getPreviousAction
+ List<org.apache.hop.core.ICheckResult> remarks = new ArrayList<>();
+ IVariables variables = mock(IVariables.class);
+ IHopMetadataProvider metadataProvider = mock(IHopMetadataProvider.class);
+
+ action.check(remarks, workflowMeta, variables, metadataProvider);
+
+ // The method should execute without errors
+ assertNotNull(remarks);
+ }
+
+ @Test
+ void testGetPreviousActionWithDisabledHops() {
+ // Test the check method with basic setup
+ List<org.apache.hop.core.ICheckResult> remarks = new ArrayList<>();
+ IVariables variables = mock(IVariables.class);
+ IHopMetadataProvider metadataProvider = mock(IHopMetadataProvider.class);
+
+ action.check(remarks, workflowMeta, variables, metadataProvider);
+
+ // The method should execute without errors
+ assertNotNull(remarks);
+ }
}