This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new 459355c5865e CAMEL-23688: camel-jbang - add unit tests for
action-writer CLI commands
459355c5865e is described below
commit 459355c5865e1bfa2c91ee069c7ab62d37815e11
Author: Adriano Machado <[email protected]>
AuthorDate: Mon Jun 22 16:49:53 2026 -0400
CAMEL-23688: camel-jbang - add unit tests for action-writer CLI commands
Adds unit test coverage for the fire-and-forget action commands in
camel-jbang-core: start/stop/suspend/resume-route, start/stop-group,
reload, reset-stats, enable/disable-processor. Includes a shared
ActionCommandTestSupport base and tests that verify exact JSON action
payloads and no-match behavior.
Closes #24188
Co-Authored-By: Claude Opus 4.8 <[email protected]>
---
.../commands/action/ActionCommandTestSupport.java | 144 +++++++++++++++++++++
.../action/CamelProcessorDisableActionTest.java | 62 +++++++++
.../action/CamelProcessorEnableActionTest.java | 62 +++++++++
.../commands/action/CamelReloadActionTest.java | 59 +++++++++
.../commands/action/CamelResetStatsActionTest.java | 59 +++++++++
.../action/CamelRouteGroupStartActionTest.java | 64 +++++++++
.../action/CamelRouteGroupStopActionTest.java | 64 +++++++++
.../action/CamelRouteResumeActionTest.java | 62 +++++++++
.../commands/action/CamelRouteStartActionTest.java | 78 +++++++++++
.../commands/action/CamelRouteStopActionTest.java | 62 +++++++++
.../action/CamelRouteSuspendActionTest.java | 62 +++++++++
11 files changed, 778 insertions(+)
diff --git
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/action/ActionCommandTestSupport.java
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/action/ActionCommandTestSupport.java
new file mode 100644
index 000000000000..9a31d872dd30
--- /dev/null
+++
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/action/ActionCommandTestSupport.java
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.dsl.jbang.core.commands.action;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.time.Instant;
+import java.util.Comparator;
+import java.util.Optional;
+import java.util.stream.Stream;
+
+import org.apache.camel.dsl.jbang.core.commands.CamelCommand;
+import org.apache.camel.dsl.jbang.core.commands.CamelCommandBaseTestSupport;
+import org.apache.camel.dsl.jbang.core.common.CommandLineHelper;
+import org.apache.camel.util.json.JsonObject;
+import org.apache.camel.util.json.Jsoner;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.mockito.MockedStatic;
+
+import static org.mockito.Mockito.lenient;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.mockStatic;
+import static org.mockito.Mockito.when;
+
+/**
+ * Base class for action command tests. Handles file system setup, status file
writing and ProcessHandle mock creation
+ * for use with Mockito's mockStatic. Mirrors the proven {@code
ProcessCommandTestSupport} (in the {@code process} test
+ * package) and adds helpers for the action/output file round trip that action
commands use.
+ */
+abstract class ActionCommandTestSupport extends CamelCommandBaseTestSupport {
+
+ static final long TEST_PID = 12345L;
+ static final long CURRENT_PID = 99999L;
+
+ @BeforeEach
+ @Override
+ public void setup() throws Exception {
+ super.setup();
+ CommandLineHelper.useHomeDir("target/test-action");
+ Files.createDirectories(CommandLineHelper.getCamelDir());
+ }
+
+ @AfterEach
+ public void cleanup() throws Exception {
+ Path camelDir = CommandLineHelper.getCamelDir();
+ if (Files.exists(camelDir)) {
+ try (Stream<Path> walk = Files.walk(camelDir)) {
+ walk.sorted(Comparator.reverseOrder()).forEach(p -> {
+ try {
+ Files.deleteIfExists(p);
+ } catch (IOException e) {
+ // best effort cleanup
+ }
+ });
+ }
+ }
+ }
+
+ /**
+ * Writes a minimal status file so {@code findPids} can resolve the given
pid by its Camel context name.
+ */
+ protected static void writeStatusFile(long pid, String contextName) throws
Exception {
+ JsonObject context = new JsonObject();
+ context.put("name", contextName);
+
+ JsonObject root = new JsonObject();
+ root.put("context", context);
+ writeStatusFile(pid, root);
+ }
+
+ protected static void writeStatusFile(long pid, JsonObject root) throws
Exception {
+ Path f = CommandLineHelper.getCamelDir().resolve(pid + "-status.json");
+ Files.writeString(f, root.toJson());
+ }
+
+ /**
+ * Reads back the action file an action command wrote for the given pid.
+ *
+ * @return the deserialized action JSON, or {@code null} if no action file
exists
+ */
+ protected static JsonObject readActionFile(long pid) throws Exception {
+ Path f = CommandLineHelper.getCamelDir().resolve(pid + "-action.json");
+ if (!Files.exists(f)) {
+ return null;
+ }
+ return (JsonObject) Jsoner.deserialize(Files.readString(f));
+ }
+
+ /**
+ * Runs the command with ProcessHandle mocked so a single test process
(TEST_PID) is discoverable and the current
+ * process is a distinct pid. Returns the exit code; any action/output
files the command wrote persist on disk and
+ * can be asserted after this returns.
+ */
+ protected static int callWithSingleProcess(CamelCommand command) throws
Exception {
+ try (MockedStatic<ProcessHandle> mocked =
mockStatic(ProcessHandle.class)) {
+ ProcessHandle ph = mockProcessHandle(TEST_PID);
+ ProcessHandle current = mockCurrentHandle();
+ mocked.when(ProcessHandle::current).thenReturn(current);
+ mocked.when(ProcessHandle::allProcesses).thenAnswer(inv ->
Stream.of(ph));
+ return command.doCall();
+ }
+ }
+
+ /**
+ * Creates a mock ProcessHandle for the test process. Info is
pre-configured with empty commandLine and a fixed
+ * start instant so extractName falls through to context.name.
+ */
+ protected static ProcessHandle mockProcessHandle(long pid) {
+ ProcessHandle ph = mock(ProcessHandle.class);
+ ProcessHandle.Info info = mock(ProcessHandle.Info.class);
+ when(ph.pid()).thenReturn(pid);
+ when(ph.info()).thenReturn(info);
+ when(info.commandLine()).thenReturn(Optional.empty());
+ // lenient: only read when a status file is matched
+
lenient().when(info.startInstant()).thenReturn(Optional.of(Instant.now().minusSeconds(60)));
+ return ph;
+ }
+
+ /**
+ * Creates a mock for ProcessHandle.current(): a distinct process so the
"skip current" filter in findPids does not
+ * exclude the test handle.
+ */
+ protected static ProcessHandle mockCurrentHandle() {
+ ProcessHandle current = mock(ProcessHandle.class);
+ when(current.pid()).thenReturn(CURRENT_PID);
+ return current;
+ }
+}
diff --git
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/action/CamelProcessorDisableActionTest.java
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/action/CamelProcessorDisableActionTest.java
new file mode 100644
index 000000000000..b76c4ea6bda3
--- /dev/null
+++
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/action/CamelProcessorDisableActionTest.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.dsl.jbang.core.commands.action;
+
+import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
+import org.apache.camel.util.json.JsonObject;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+@ExtendWith(MockitoExtension.class)
+class CamelProcessorDisableActionTest extends ActionCommandTestSupport {
+
+ @Test
+ void testWritesDisableProcessorActionForMatchingName() throws Exception {
+ writeStatusFile(TEST_PID, "myApp");
+
+ CamelProcessorDisableAction command = new
CamelProcessorDisableAction(new CamelJBangMain().withPrinter(printer));
+ command.name = "myApp";
+ command.id = "myProcessor";
+
+ int exit = callWithSingleProcess(command);
+
+ assertEquals(0, exit);
+ JsonObject action = readActionFile(TEST_PID);
+ assertNotNull(action, "action file should be written for the matched
process");
+ assertEquals("processor", action.getString("action"));
+ assertEquals("disable", action.getString("command"));
+ assertEquals("myProcessor", action.getString("id"));
+ }
+
+ @Test
+ void testNoActionWhenNameDoesNotMatch() throws Exception {
+ writeStatusFile(TEST_PID, "myApp");
+
+ CamelProcessorDisableAction command = new
CamelProcessorDisableAction(new CamelJBangMain().withPrinter(printer));
+ command.name = "doesNotExist";
+
+ int exit = callWithSingleProcess(command);
+
+ assertEquals(0, exit);
+ assertNull(readActionFile(TEST_PID), "no action file should be written
when no process matches");
+ }
+}
diff --git
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/action/CamelProcessorEnableActionTest.java
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/action/CamelProcessorEnableActionTest.java
new file mode 100644
index 000000000000..baee9db35730
--- /dev/null
+++
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/action/CamelProcessorEnableActionTest.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.dsl.jbang.core.commands.action;
+
+import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
+import org.apache.camel.util.json.JsonObject;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+@ExtendWith(MockitoExtension.class)
+class CamelProcessorEnableActionTest extends ActionCommandTestSupport {
+
+ @Test
+ void testWritesEnableProcessorActionForMatchingName() throws Exception {
+ writeStatusFile(TEST_PID, "myApp");
+
+ CamelProcessorEnableAction command = new
CamelProcessorEnableAction(new CamelJBangMain().withPrinter(printer));
+ command.name = "myApp";
+ command.id = "myProcessor";
+
+ int exit = callWithSingleProcess(command);
+
+ assertEquals(0, exit);
+ JsonObject action = readActionFile(TEST_PID);
+ assertNotNull(action, "action file should be written for the matched
process");
+ assertEquals("processor", action.getString("action"));
+ assertEquals("enable", action.getString("command"));
+ assertEquals("myProcessor", action.getString("id"));
+ }
+
+ @Test
+ void testNoActionWhenNameDoesNotMatch() throws Exception {
+ writeStatusFile(TEST_PID, "myApp");
+
+ CamelProcessorEnableAction command = new
CamelProcessorEnableAction(new CamelJBangMain().withPrinter(printer));
+ command.name = "doesNotExist";
+
+ int exit = callWithSingleProcess(command);
+
+ assertEquals(0, exit);
+ assertNull(readActionFile(TEST_PID), "no action file should be written
when no process matches");
+ }
+}
diff --git
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/action/CamelReloadActionTest.java
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/action/CamelReloadActionTest.java
new file mode 100644
index 000000000000..e430b21e36ae
--- /dev/null
+++
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/action/CamelReloadActionTest.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.dsl.jbang.core.commands.action;
+
+import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
+import org.apache.camel.util.json.JsonObject;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+@ExtendWith(MockitoExtension.class)
+class CamelReloadActionTest extends ActionCommandTestSupport {
+
+ @Test
+ void testWritesReloadActionForMatchingName() throws Exception {
+ writeStatusFile(TEST_PID, "myApp");
+
+ CamelReloadAction command = new CamelReloadAction(new
CamelJBangMain().withPrinter(printer));
+ command.name = "myApp";
+
+ int exit = callWithSingleProcess(command);
+
+ assertEquals(0, exit);
+ JsonObject action = readActionFile(TEST_PID);
+ assertNotNull(action, "action file should be written for the matched
process");
+ assertEquals("reload", action.getString("action"));
+ }
+
+ @Test
+ void testNoActionWhenNameDoesNotMatch() throws Exception {
+ writeStatusFile(TEST_PID, "myApp");
+
+ CamelReloadAction command = new CamelReloadAction(new
CamelJBangMain().withPrinter(printer));
+ command.name = "doesNotExist";
+
+ int exit = callWithSingleProcess(command);
+
+ assertEquals(0, exit);
+ assertNull(readActionFile(TEST_PID), "no action file should be written
when no process matches");
+ }
+}
diff --git
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/action/CamelResetStatsActionTest.java
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/action/CamelResetStatsActionTest.java
new file mode 100644
index 000000000000..cde244e20c7e
--- /dev/null
+++
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/action/CamelResetStatsActionTest.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.dsl.jbang.core.commands.action;
+
+import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
+import org.apache.camel.util.json.JsonObject;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+@ExtendWith(MockitoExtension.class)
+class CamelResetStatsActionTest extends ActionCommandTestSupport {
+
+ @Test
+ void testWritesResetStatsActionForMatchingName() throws Exception {
+ writeStatusFile(TEST_PID, "myApp");
+
+ CamelResetStatsAction command = new CamelResetStatsAction(new
CamelJBangMain().withPrinter(printer));
+ command.name = "myApp";
+
+ int exit = callWithSingleProcess(command);
+
+ assertEquals(0, exit);
+ JsonObject action = readActionFile(TEST_PID);
+ assertNotNull(action, "action file should be written for the matched
process");
+ assertEquals("reset-stats", action.getString("action"));
+ }
+
+ @Test
+ void testNoActionWhenNameDoesNotMatch() throws Exception {
+ writeStatusFile(TEST_PID, "myApp");
+
+ CamelResetStatsAction command = new CamelResetStatsAction(new
CamelJBangMain().withPrinter(printer));
+ command.name = "doesNotExist";
+
+ int exit = callWithSingleProcess(command);
+
+ assertEquals(0, exit);
+ assertNull(readActionFile(TEST_PID), "no action file should be written
when no process matches");
+ }
+}
diff --git
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/action/CamelRouteGroupStartActionTest.java
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/action/CamelRouteGroupStartActionTest.java
new file mode 100644
index 000000000000..73e64dfd11c3
--- /dev/null
+++
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/action/CamelRouteGroupStartActionTest.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.dsl.jbang.core.commands.action;
+
+import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
+import org.apache.camel.util.json.JsonObject;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+@ExtendWith(MockitoExtension.class)
+class CamelRouteGroupStartActionTest extends ActionCommandTestSupport {
+
+ @Test
+ void testWritesStartGroupActionForMatchingName() throws Exception {
+ writeStatusFile(TEST_PID, "myApp");
+
+ CamelRouteGroupStartAction command = new
CamelRouteGroupStartAction(new CamelJBangMain().withPrinter(printer));
+ command.name = "myApp";
+ command.id = "myGroup";
+
+ int exit = callWithSingleProcess(command);
+
+ assertEquals(0, exit);
+ JsonObject action = readActionFile(TEST_PID);
+ assertNotNull(action, "action file should be written for the matched
process");
+ assertEquals("route", action.getString("action"));
+ assertEquals("start", action.getString("command"));
+ assertEquals("myGroup", action.getString("id"));
+ // group flag distinguishes a group action from a single-route action
+ assertEquals(Boolean.TRUE, action.getBoolean("group"));
+ }
+
+ @Test
+ void testNoActionWhenNameDoesNotMatch() throws Exception {
+ writeStatusFile(TEST_PID, "myApp");
+
+ CamelRouteGroupStartAction command = new
CamelRouteGroupStartAction(new CamelJBangMain().withPrinter(printer));
+ command.name = "doesNotExist";
+
+ int exit = callWithSingleProcess(command);
+
+ assertEquals(0, exit);
+ assertNull(readActionFile(TEST_PID), "no action file should be written
when no process matches");
+ }
+}
diff --git
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/action/CamelRouteGroupStopActionTest.java
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/action/CamelRouteGroupStopActionTest.java
new file mode 100644
index 000000000000..74d1f5e85aed
--- /dev/null
+++
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/action/CamelRouteGroupStopActionTest.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.dsl.jbang.core.commands.action;
+
+import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
+import org.apache.camel.util.json.JsonObject;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+@ExtendWith(MockitoExtension.class)
+class CamelRouteGroupStopActionTest extends ActionCommandTestSupport {
+
+ @Test
+ void testWritesStopGroupActionForMatchingName() throws Exception {
+ writeStatusFile(TEST_PID, "myApp");
+
+ CamelRouteGroupStopAction command = new CamelRouteGroupStopAction(new
CamelJBangMain().withPrinter(printer));
+ command.name = "myApp";
+ command.id = "myGroup";
+
+ int exit = callWithSingleProcess(command);
+
+ assertEquals(0, exit);
+ JsonObject action = readActionFile(TEST_PID);
+ assertNotNull(action, "action file should be written for the matched
process");
+ assertEquals("route", action.getString("action"));
+ assertEquals("stop", action.getString("command"));
+ assertEquals("myGroup", action.getString("id"));
+ // group flag distinguishes a group action from a single-route action
+ assertEquals(Boolean.TRUE, action.getBoolean("group"));
+ }
+
+ @Test
+ void testNoActionWhenNameDoesNotMatch() throws Exception {
+ writeStatusFile(TEST_PID, "myApp");
+
+ CamelRouteGroupStopAction command = new CamelRouteGroupStopAction(new
CamelJBangMain().withPrinter(printer));
+ command.name = "doesNotExist";
+
+ int exit = callWithSingleProcess(command);
+
+ assertEquals(0, exit);
+ assertNull(readActionFile(TEST_PID), "no action file should be written
when no process matches");
+ }
+}
diff --git
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/action/CamelRouteResumeActionTest.java
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/action/CamelRouteResumeActionTest.java
new file mode 100644
index 000000000000..483d627bd979
--- /dev/null
+++
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/action/CamelRouteResumeActionTest.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.dsl.jbang.core.commands.action;
+
+import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
+import org.apache.camel.util.json.JsonObject;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+@ExtendWith(MockitoExtension.class)
+class CamelRouteResumeActionTest extends ActionCommandTestSupport {
+
+ @Test
+ void testWritesResumeActionForMatchingName() throws Exception {
+ writeStatusFile(TEST_PID, "myApp");
+
+ CamelRouteResumeAction command = new CamelRouteResumeAction(new
CamelJBangMain().withPrinter(printer));
+ command.name = "myApp";
+ command.id = "myRoute";
+
+ int exit = callWithSingleProcess(command);
+
+ assertEquals(0, exit);
+ JsonObject action = readActionFile(TEST_PID);
+ assertNotNull(action, "action file should be written for the matched
process");
+ assertEquals("route", action.getString("action"));
+ assertEquals("resume", action.getString("command"));
+ assertEquals("myRoute", action.getString("id"));
+ }
+
+ @Test
+ void testNoActionWhenNameDoesNotMatch() throws Exception {
+ writeStatusFile(TEST_PID, "myApp");
+
+ CamelRouteResumeAction command = new CamelRouteResumeAction(new
CamelJBangMain().withPrinter(printer));
+ command.name = "doesNotExist";
+
+ int exit = callWithSingleProcess(command);
+
+ assertEquals(0, exit);
+ assertNull(readActionFile(TEST_PID), "no action file should be written
when no process matches");
+ }
+}
diff --git
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/action/CamelRouteStartActionTest.java
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/action/CamelRouteStartActionTest.java
new file mode 100644
index 000000000000..562dafd0714b
--- /dev/null
+++
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/action/CamelRouteStartActionTest.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.dsl.jbang.core.commands.action;
+
+import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
+import org.apache.camel.util.json.JsonObject;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+@ExtendWith(MockitoExtension.class)
+class CamelRouteStartActionTest extends ActionCommandTestSupport {
+
+ @Test
+ void testWritesStartActionForMatchingName() throws Exception {
+ writeStatusFile(TEST_PID, "myApp");
+
+ CamelRouteStartAction command = new CamelRouteStartAction(new
CamelJBangMain().withPrinter(printer));
+ command.name = "myApp";
+ command.id = "myRoute";
+
+ int exit = callWithSingleProcess(command);
+
+ assertEquals(0, exit);
+ JsonObject action = readActionFile(TEST_PID);
+ assertNotNull(action, "action file should be written for the matched
process");
+ assertEquals("route", action.getString("action"));
+ assertEquals("start", action.getString("command"));
+ assertEquals("myRoute", action.getString("id"));
+ }
+
+ @Test
+ void testDefaultIdMatchesAllRoutes() throws Exception {
+ writeStatusFile(TEST_PID, "myApp");
+
+ // default id is "*" (all routes)
+ CamelRouteStartAction command = new CamelRouteStartAction(new
CamelJBangMain().withPrinter(printer));
+ command.name = "myApp";
+
+ int exit = callWithSingleProcess(command);
+
+ assertEquals(0, exit);
+ JsonObject action = readActionFile(TEST_PID);
+ assertNotNull(action);
+ assertEquals("*", action.getString("id"));
+ }
+
+ @Test
+ void testNoActionWhenNameDoesNotMatch() throws Exception {
+ writeStatusFile(TEST_PID, "myApp");
+
+ CamelRouteStartAction command = new CamelRouteStartAction(new
CamelJBangMain().withPrinter(printer));
+ command.name = "doesNotExist";
+
+ int exit = callWithSingleProcess(command);
+
+ assertEquals(0, exit);
+ assertNull(readActionFile(TEST_PID), "no action file should be written
when no process matches");
+ }
+}
diff --git
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/action/CamelRouteStopActionTest.java
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/action/CamelRouteStopActionTest.java
new file mode 100644
index 000000000000..482f92d0191c
--- /dev/null
+++
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/action/CamelRouteStopActionTest.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.dsl.jbang.core.commands.action;
+
+import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
+import org.apache.camel.util.json.JsonObject;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+@ExtendWith(MockitoExtension.class)
+class CamelRouteStopActionTest extends ActionCommandTestSupport {
+
+ @Test
+ void testWritesStopActionForMatchingName() throws Exception {
+ writeStatusFile(TEST_PID, "myApp");
+
+ CamelRouteStopAction command = new CamelRouteStopAction(new
CamelJBangMain().withPrinter(printer));
+ command.name = "myApp";
+ command.id = "myRoute";
+
+ int exit = callWithSingleProcess(command);
+
+ assertEquals(0, exit);
+ JsonObject action = readActionFile(TEST_PID);
+ assertNotNull(action, "action file should be written for the matched
process");
+ assertEquals("route", action.getString("action"));
+ assertEquals("stop", action.getString("command"));
+ assertEquals("myRoute", action.getString("id"));
+ }
+
+ @Test
+ void testNoActionWhenNameDoesNotMatch() throws Exception {
+ writeStatusFile(TEST_PID, "myApp");
+
+ CamelRouteStopAction command = new CamelRouteStopAction(new
CamelJBangMain().withPrinter(printer));
+ command.name = "doesNotExist";
+
+ int exit = callWithSingleProcess(command);
+
+ assertEquals(0, exit);
+ assertNull(readActionFile(TEST_PID), "no action file should be written
when no process matches");
+ }
+}
diff --git
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/action/CamelRouteSuspendActionTest.java
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/action/CamelRouteSuspendActionTest.java
new file mode 100644
index 000000000000..839169b4e96b
--- /dev/null
+++
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/action/CamelRouteSuspendActionTest.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.dsl.jbang.core.commands.action;
+
+import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
+import org.apache.camel.util.json.JsonObject;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+@ExtendWith(MockitoExtension.class)
+class CamelRouteSuspendActionTest extends ActionCommandTestSupport {
+
+ @Test
+ void testWritesSuspendActionForMatchingName() throws Exception {
+ writeStatusFile(TEST_PID, "myApp");
+
+ CamelRouteSuspendAction command = new CamelRouteSuspendAction(new
CamelJBangMain().withPrinter(printer));
+ command.name = "myApp";
+ command.id = "myRoute";
+
+ int exit = callWithSingleProcess(command);
+
+ assertEquals(0, exit);
+ JsonObject action = readActionFile(TEST_PID);
+ assertNotNull(action, "action file should be written for the matched
process");
+ assertEquals("route", action.getString("action"));
+ assertEquals("suspend", action.getString("command"));
+ assertEquals("myRoute", action.getString("id"));
+ }
+
+ @Test
+ void testNoActionWhenNameDoesNotMatch() throws Exception {
+ writeStatusFile(TEST_PID, "myApp");
+
+ CamelRouteSuspendAction command = new CamelRouteSuspendAction(new
CamelJBangMain().withPrinter(printer));
+ command.name = "doesNotExist";
+
+ int exit = callWithSingleProcess(command);
+
+ assertEquals(0, exit);
+ assertNull(readActionFile(TEST_PID), "no action file should be written
when no process matches");
+ }
+}