Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions dsl/camel-jbang/camel-jbang-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,12 @@
<version>${wiremock-version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>${mockito-version}</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* 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;

import org.apache.camel.dsl.jbang.core.common.CamelCommandHelper;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;

class CamelCommandHelperTest {

@Test
void testStartingState() {
// Phase <= 4 maps to Starting
assertEquals("Starting", CamelCommandHelper.extractState(0));
assertEquals("Starting", CamelCommandHelper.extractState(1));
assertEquals("Starting", CamelCommandHelper.extractState(4));
}

@Test
void testRunningState() {
assertEquals("Running", CamelCommandHelper.extractState(5));
}

@Test
void testSuspendingState() {
assertEquals("Suspending", CamelCommandHelper.extractState(6));
}

@Test
void testSuspendedState() {
assertEquals("Suspended", CamelCommandHelper.extractState(7));
}

@Test
void testTerminatingState() {
assertEquals("Terminating", CamelCommandHelper.extractState(8));
}

@Test
void testTerminatedState() {
assertEquals("Terminated", CamelCommandHelper.extractState(9));
}

@Test
void testUnknownPhaseFallsToTerminated() {
// Any phase beyond 9 defaults to Terminated — prevents NPE during display
assertEquals("Terminated", CamelCommandHelper.extractState(99));
assertEquals("Terminated", CamelCommandHelper.extractState(Integer.MAX_VALUE));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* 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.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;

class CamelSourceActionTest {

@Test
void testNullReturnsNull() {
assertNull(CamelSourceAction.extractSourceName(null));
}

@Test
void testPlainFilenameUnchanged() {
assertEquals("MyRoute.yaml", CamelSourceAction.extractSourceName("MyRoute.yaml"));
}

@Test
void testSchemeAndPathStripsSchemeAndDirectory() {
// "file:/some/path/MyRoute.yaml" -> strip scheme -> "/some/path/MyRoute.yaml" -> strip path -> "MyRoute.yaml"
assertEquals("MyRoute.yaml", CamelSourceAction.extractSourceName("file:/some/path/MyRoute.yaml"));
}

@Test
void testClasspathSchemeStripsScheme() {
assertEquals("routes.xml", CamelSourceAction.extractSourceName("classpath:routes.xml"));
}

@Test
void testSingleColonTreatedAsScheme() {
// Only one colon: treated as scheme separator, not line number.
// "MyRoute.java:42" -> substring after ':' = "42" -> stripPath("42") = "42"
assertEquals("42", CamelSourceAction.extractSourceName("MyRoute.java:42"));
}

@Test
void testSchemeWithLineNumberStripsSchemeAndLineNumber() {
// Two colons: stripSourceLocationLineNumber removes ":10" -> "file:/path/MyRoute.yaml"
// then strip scheme and path -> "MyRoute.yaml"
assertEquals("MyRoute.yaml", CamelSourceAction.extractSourceName("file:/path/MyRoute.yaml:10"));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
/*
* 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.nio.file.Path;
import java.util.Collections;
import java.util.List;

import org.apache.camel.dsl.jbang.core.commands.CamelCommandBaseTestSupport;
import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
import org.apache.camel.dsl.jbang.core.common.CommandLineHelper;
import org.apache.camel.util.json.JsonArray;
import org.apache.camel.util.json.JsonObject;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

class CamelStartupRecorderActionTest extends CamelCommandBaseTestSupport {

@BeforeEach
@Override
public void setup() throws Exception {
super.setup();
CommandLineHelper.useHomeDir("target");
}

@Test
void testDisplaysStepsFromOutput() throws Exception {
JsonObject mockOutput = buildStartupOutput(
step(1, 0, 0, "MyRoute", "Route", "Build route", 150),
step(2, 1, 1, null, "From", "timer:tick", 50),
step(3, 1, 1, null, "To", "log:info", 30));

TestableStartupRecorder command = new TestableStartupRecorder(
new CamelJBangMain().withPrinter(printer), mockOutput);

int exit = command.doWatchCall();

assertEquals(0, exit);
String output = printer.getOutput();
assertTrue(output.contains("Route"), "Should show step type Route");
assertTrue(output.contains("From"), "Should show step type From");
assertTrue(output.contains("Build route"), "Should show step description");
}

@Test
void testStepWithNameShowsParentheses() throws Exception {
JsonObject mockOutput = buildStartupOutput(
step(1, 0, 0, "myRoute", "Route", "Configure route", 100));

TestableStartupRecorder command = new TestableStartupRecorder(
new CamelJBangMain().withPrinter(printer), mockOutput);

int exit = command.doWatchCall();

assertEquals(0, exit);
// When a step has a name, it appears as "description(name)"
assertTrue(printer.getOutput().contains("Configure route(myRoute)"),
"Name should be appended in parentheses");
}

@Test
void testSortByDuration() throws Exception {
JsonObject mockOutput = buildStartupOutput(
step(1, 0, 0, null, "Route", "FastStep", 10),
step(2, 0, 0, null, "Route", "SlowStep", 500),
step(3, 0, 0, null, "Route", "MidStep", 200));

TestableStartupRecorder command = new TestableStartupRecorder(
new CamelJBangMain().withPrinter(printer), mockOutput);
command.sort = "duration";

int exit = command.doWatchCall();

assertEquals(0, exit);
String output = printer.getOutput();
int fastPos = output.indexOf("FastStep");
int midPos = output.indexOf("MidStep");
int slowPos = output.indexOf("SlowStep");
// Ascending duration: FastStep (10ms) before MidStep (200ms) before SlowStep (500ms)
assertTrue(fastPos < midPos && midPos < slowPos,
"Sort by duration ascending: fastest step must appear first");
}

@Test
void testSortByDurationDescending() throws Exception {
JsonObject mockOutput = buildStartupOutput(
step(1, 0, 0, null, "Route", "FastStep", 10),
step(2, 0, 0, null, "Route", "SlowStep", 500));

TestableStartupRecorder command = new TestableStartupRecorder(
new CamelJBangMain().withPrinter(printer), mockOutput);
command.sort = "-duration";

int exit = command.doWatchCall();

assertEquals(0, exit);
String output = printer.getOutput();
int slowPos = output.indexOf("SlowStep");
int fastPos = output.indexOf("FastStep");
assertTrue(slowPos < fastPos, "Descending duration: slowest step must appear first");
}

@Test
void testZeroDurationDisplayedAsEmpty() throws Exception {
JsonObject mockOutput = buildStartupOutput(
step(1, 0, 0, null, "Route", "ZeroDurationStep", 0));

TestableStartupRecorder command = new TestableStartupRecorder(
new CamelJBangMain().withPrinter(printer), mockOutput);

int exit = command.doWatchCall();

assertEquals(0, exit);
// Zero duration is rendered as empty string, not "0" — verify step name still appears
assertTrue(printer.getOutput().contains("ZeroDurationStep"));
}

@Test
void testEmptyOutputWhenNoPidFound() throws Exception {
// No pids returned — command should return error code 1
TestableStartupRecorder command = new TestableStartupRecorder(
new CamelJBangMain().withPrinter(printer), null) {
@Override
List<Long> findPids(String name) {
return List.of();
}
};

int exit = command.doWatchCall();

assertEquals(1, exit, "Should return error when no pids found");
}

private static JsonObject buildStartupOutput(JsonObject... steps) {
JsonArray arr = new JsonArray();
Collections.addAll(arr, steps);
JsonObject jo = new JsonObject();
jo.put("steps", arr);
return jo;
}

private static JsonObject step(
int id, int parentId, int level, String name, String type, String description,
long duration) {
JsonObject step = new JsonObject();
step.put("id", id);
step.put("parentId", parentId);
step.put("level", level);
step.put("name", name);
step.put("type", type);
step.put("description", description);
step.put("duration", duration);
return step;
}

/**
* Test subclass that bypasses process discovery and output file waiting so the rendering logic can be tested
* against a pre-built JSON response.
*/
private static class TestableStartupRecorder extends CamelStartupRecorderAction {
private final JsonObject mockOutput;

TestableStartupRecorder(CamelJBangMain main, JsonObject mockOutput) {
super(main);
this.mockOutput = mockOutput;
}

@Override
List<Long> findPids(String name) {
return List.of(12345L);
}

@Override
protected JsonObject waitForOutputFile(Path outputFile) {
return mockOutput;
}
}
}
Loading