Skip to content

Commit

Permalink
fix: Introduce descendant process id verification in Camel JBang
Browse files Browse the repository at this point in the history
  • Loading branch information
christophd committed Dec 20, 2024
1 parent bdae2d8 commit 218246b
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ public class ProcessAndOutput {

private BufferedReader reader;

private String app;
/** Application name that should be present in process command, used to retrieve pid of descendant processes */
private String app = "jbang";

ProcessAndOutput(Process process) {
this(process, "");
Expand Down Expand Up @@ -146,7 +147,16 @@ private void readChunk() {
* @return
*/
public Long getProcessId() {
return getProcessId(app);
return process.pid();
}

/**
* Retrieve a descendant process if any and return its pid.
* Uses the app name stored in this instance to filter descendant process commands.
* @return
*/
public Long getDescendantPid() {
return getDescendantPid(app);
}

/**
Expand All @@ -156,14 +166,15 @@ public Long getProcessId() {
*
* @return
*/
public Long getProcessId(String app) {

public Long getDescendantPid(String app) {
try {
if (app != null && isUnix()) {
if (isUnix()) {
// wait for descendant process to be available
await().atMost(5000L, TimeUnit.MILLISECONDS)
.until(() -> process.descendants().findAny().isPresent());
return process.descendants()
.peek(p -> LOG.info(String.format("Found descendant process (pid:%d) for process '%d'", p.pid(), getProcessId())))
.peek(p -> LOG.info(p.info().commandLine().orElse("no command line")))
.filter(p -> p.info().commandLine().orElse("").contains(app))
.findFirst()
.map(ProcessHandle::pid)
Expand All @@ -178,17 +189,6 @@ public Long getProcessId(String app) {
}
}

/**
* Get the process id of the parent process.
* Typically, we need the JBang command process id.
*
* @return
*/
public Long getParentProcessId() {
return process.pid();
}


private static boolean isUnix() {
String os = System.getProperty("os.name").toLowerCase();
return os.contains("nix") || os.contains("nux") || os.contains("aix");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ public void doExecute(TestContext context) {
verifyProcessIsAlive(pao, name);

pao.setApp(integrationToRun.getFileName().toString());
Long pid = pao.getParentProcessId();
Long pid = pao.getProcessId();

context.setVariable(name + ":pid", pid);
context.setVariable(name + ":process:" + pid, pao);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,14 +139,18 @@ private Long verifyRouteStatus(String name, String phase, TestContext context) {
throw new CitrusRuntimeException(String.format("Failed to verify Camel integration '%s' - exit code %s", name, pao.getProcess().exitValue()));
}

// Verify that current processId is the same as the one saved in test context
Long appPid = pao.getProcessId();
if (!Objects.equals(pid, appPid)) {
// seems like there is another pid (descendant process) that should be verified
if (findProcessAndVerifyStatus(appPid, name, phase)) {
return appPid;
// Check if there is a descendant process for the process saved in test context
Long descendantPid = pao.getDescendantPid();
if (!Objects.equals(pid, descendantPid)) {
// seems like there is descendant pid that should be verified, too
if (findProcessAndVerifyStatus(descendantPid, name, phase)) {
return descendantPid;
}
} else {
logger.info(String.format("No descendant process for pid %d", pid));
}
} else {
logger.info(String.format("No process for %s:process:%d stored in text context", name, pid));
}
}

Expand Down Expand Up @@ -177,6 +181,8 @@ private boolean findProcessAndVerifyStatus(Long pid, String name, String phase)
}
}

logger.info(String.format("Camel integration '%s' (pid:%d) not in state '%s'", name, pid, phase));

return false;
}

Expand Down

0 comments on commit 218246b

Please sign in to comment.