From 0ce39707cdd6ea838e9df69a44471122d984a355 Mon Sep 17 00:00:00 2001 From: Guillaume Nodet Date: Fri, 2 Oct 2020 08:27:20 +0200 Subject: [PATCH] Provide smarter output on the client, fixes #77 All events are directly forwarded to the client. The client is now responsible for ordering them per project and displaying them if needed. A thread is now started to read the terminal input with support for '+' to display one more line per project, '-' to display one line less, and 'Ctrl+L' to redraw the display which could become messed if the build messages are a bit unusual (this may require a better fix though). --- .../jboss/fuse/mvnd/client/ClientOutput.java | 155 ++++++++++++++---- .../jboss/fuse/mvnd/client/DefaultClient.java | 14 +- common/pom.xml | 5 + .../org/jboss/fuse/mvnd/common/Message.java | 12 +- .../org/jboss/fuse/mvnd/daemon/Server.java | 44 +++-- .../logging/smart/AbstractLoggingSpy.java | 82 ++++----- .../mvnd/logging/smart/MavenLoggingSpy.java | 37 ++++- .../mvnd/assertj/MatchInOrderAmongOthers.java | 3 +- .../jboss/fuse/mvnd/it/MultiModuleTest.java | 4 +- .../fuse/mvnd/it/SingleModuleNativeIT.java | 18 +- .../jboss/fuse/mvnd/it/StopStatusTest.java | 6 +- .../jboss/fuse/mvnd/it/VersionNativeIT.java | 4 +- .../fuse/mvnd/junit/NativeTestClient.java | 10 +- 13 files changed, 259 insertions(+), 135 deletions(-) diff --git a/client/src/main/java/org/jboss/fuse/mvnd/client/ClientOutput.java b/client/src/main/java/org/jboss/fuse/mvnd/client/ClientOutput.java index ceb0d5c18..ce5d2c737 100644 --- a/client/src/main/java/org/jboss/fuse/mvnd/client/ClientOutput.java +++ b/client/src/main/java/org/jboss/fuse/mvnd/client/ClientOutput.java @@ -16,17 +16,15 @@ package org.jboss.fuse.mvnd.client; import java.io.IOException; +import java.io.InterruptedIOException; import java.io.Writer; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; -import java.util.AbstractMap; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; -import java.util.Map; -import java.util.Map.Entry; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingDeque; import java.util.function.Consumer; @@ -43,24 +41,50 @@ /** * A sink for various kinds of events sent by the daemon. */ -public interface ClientOutput extends AutoCloseable, Consumer { +public interface ClientOutput extends AutoCloseable { + + int CTRL_L = 'L' & 0x1f; public void projectStateChanged(String projectId, String display); public void projectFinished(String projectId); - /** Receive a log message */ - public void accept(String message); + public void accept(String projectId, String message); public void error(BuildException m); + enum EventType { + PROJECT_STATUS, + LOG, + ERROR, + END_OF_STREAM, + INPUT + } + + class Event { + public final EventType type; + public final String projectId; + public final String message; + + public Event(EventType type, String projectId, String message) { + this.type = type; + this.projectId = projectId; + this.message = message; + } + } + + class Project { + String status; + final List log = new ArrayList<>(); + } + /** * A terminal {@link ClientOutput} based on JLine. */ static class TerminalOutput implements ClientOutput { private static final Logger LOGGER = LoggerFactory.getLogger(TerminalOutput.class); private final TerminalUpdater updater; - private final BlockingQueue> queue; + private final BlockingQueue queue; public TerminalOutput(Path logFile) throws IOException { this.queue = new LinkedBlockingDeque<>(); @@ -69,7 +93,7 @@ public TerminalOutput(Path logFile) throws IOException { public void projectStateChanged(String projectId, String task) { try { - queue.put(new AbstractMap.SimpleImmutableEntry<>(projectId, task)); + queue.put(new Event(EventType.PROJECT_STATUS, projectId, task)); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } @@ -77,16 +101,16 @@ public void projectStateChanged(String projectId, String task) { public void projectFinished(String projectId) { try { - queue.put(new AbstractMap.SimpleImmutableEntry<>(projectId, null)); + queue.put(new Event(EventType.PROJECT_STATUS, projectId, null)); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } @Override - public void accept(String message) { + public void accept(String projectId, String message) { try { - queue.put(new AbstractMap.SimpleImmutableEntry<>(TerminalUpdater.LOG, message)); + queue.put(new Event(EventType.LOG, projectId, message)); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } @@ -106,27 +130,28 @@ public void error(BuildException error) { msg = error.getClassName() + ": " + error.getMessage(); } try { - queue.put(new AbstractMap.SimpleImmutableEntry<>(TerminalUpdater.ERROR, msg)); + queue.put(new Event(EventType.ERROR, null, msg)); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } static class TerminalUpdater implements AutoCloseable { - private static final String LOG = ""; - private static final String ERROR = ""; - private static final String END_OF_STREAM = ""; - private final BlockingQueue> queue; + private final BlockingQueue queue; private final Terminal terminal; private final Display display; - private final LinkedHashMap projects = new LinkedHashMap<>(); + private final LinkedHashMap projects = new LinkedHashMap<>(); private final Log log; private final Thread worker; + private final Thread reader; private volatile Exception exception; + private volatile boolean closing; + private int linesPerProject = 0; - public TerminalUpdater(BlockingQueue> queue, Path logFile) throws IOException { + public TerminalUpdater(BlockingQueue queue, Path logFile) throws IOException { super(); this.terminal = TerminalBuilder.terminal(); + terminal.enterRawMode(); this.display = new Display(terminal, false); this.log = logFile == null ? new ClientOutput.Log.MessageCollector(terminal) : new ClientOutput.Log.FileLog(logFile); @@ -134,37 +159,88 @@ public TerminalUpdater(BlockingQueue> queue, Path logFile) final Thread w = new Thread(this::run); w.start(); this.worker = w; + final Thread r = new Thread(this::read); + r.start(); + this.reader = r; + } + + void read() { + try { + while (!closing) { + int c = terminal.reader().read(10); + if (c == -1) { + break; + } + if (c == '+' || c == '-' || c == CTRL_L) { + queue.add(new Event(EventType.INPUT, null, Character.toString(c))); + } + } + } catch (InterruptedIOException e) { + Thread.currentThread().interrupt(); + } catch (IOException e) { + this.exception = e; + } } void run() { - final List> entries = new ArrayList<>(); + final List entries = new ArrayList<>(); while (true) { try { entries.add(queue.take()); queue.drainTo(entries); - for (Entry entry : entries) { - final String key = entry.getKey(); - final String value = entry.getValue(); - if (key == END_OF_STREAM) { + for (Event entry : entries) { + switch (entry.type) { + case END_OF_STREAM: { + projects.values().stream().flatMap(p -> p.log.stream()).forEach(log); display.update(Collections.emptyList(), 0); LOGGER.debug("Done receiving, printing log"); log.close(); LOGGER.debug("Done !"); terminal.flush(); return; - } else if (key == LOG) { - log.accept(value); - } else if (key == ERROR) { + } + case LOG: { + if (entry.projectId != null) { + Project prj = projects.computeIfAbsent(entry.projectId, p -> new Project()); + prj.log.add(entry.message); + } else { + log.accept(entry.message); + } + break; + } + case ERROR: { + projects.values().stream().flatMap(p -> p.log.stream()).forEach(log); display.update(Collections.emptyList(), 0); final AttributedStyle s = new AttributedStyle().bold().foreground(AttributedStyle.RED); - terminal.writer().println(new AttributedString(value, s).toAnsi()); + terminal.writer().println(new AttributedString(entry.message, s).toAnsi()); terminal.flush(); return; - } else if (value == null) { - projects.remove(key); - } else { - projects.put(key, value); + } + case PROJECT_STATUS: + if (entry.message != null) { + Project prj = projects.computeIfAbsent(entry.projectId, p -> new Project()); + prj.status = entry.message; + } else { + Project prj = projects.remove(entry.projectId); + if (prj != null) { + prj.log.forEach(log); + } + } + break; + case INPUT: + switch (entry.message.charAt(0)) { + case '+': + linesPerProject = Math.min(10, linesPerProject + 1); + break; + case '-': + linesPerProject = Math.max(0, linesPerProject - 1); + break; + case CTRL_L: + display.reset(); + break; + } + break; } } entries.clear(); @@ -179,8 +255,12 @@ void run() { @Override public void close() throws Exception { - queue.put(new AbstractMap.SimpleImmutableEntry<>(END_OF_STREAM, null)); + closing = true; + reader.interrupt(); + queue.put(new Event(EventType.END_OF_STREAM, null, null)); worker.join(); + reader.join(); + terminal.close(); if (exception != null) { throw exception; } @@ -197,15 +277,22 @@ private void update() { } final int displayableProjectCount = rows - 1; final int skipRows = projects.size() > displayableProjectCount ? projects.size() - displayableProjectCount : 0; + final int remRows = displayableProjectCount > projects.size() ? displayableProjectCount - projects.size() : 0; final List lines = new ArrayList<>(projects.size() - skipRows); final int lineMaxLength = size.getColumns(); int i = 0; + int j = 0; lines.add(new AttributedString("Building..." + (skipRows > 0 ? " (" + skipRows + " more)" : ""))); - for (String line : projects.values()) { + for (Project prj : projects.values()) { if (i < skipRows) { i++; } else { - lines.add(shortenIfNeeded(AttributedString.fromAnsi(line), lineMaxLength)); + lines.add(shortenIfNeeded(AttributedString.fromAnsi(prj.status), lineMaxLength)); + for (String line : prj.log.subList(Math.max(0, prj.log.size() - linesPerProject), prj.log.size())) { + if (j++ < remRows) { + lines.add(shortenIfNeeded(AttributedString.fromAnsi(" " + line), lineMaxLength)); + } + } } } display.update(lines, -1); diff --git a/client/src/main/java/org/jboss/fuse/mvnd/client/DefaultClient.java b/client/src/main/java/org/jboss/fuse/mvnd/client/DefaultClient.java index cd222639e..92ca7d62e 100644 --- a/client/src/main/java/org/jboss/fuse/mvnd/client/DefaultClient.java +++ b/client/src/main/java/org/jboss/fuse/mvnd/client/DefaultClient.java @@ -128,7 +128,7 @@ public ExecutionResult execute(ClientOutput output, List argv) { + "-" + buildProperties.getOsArch() + nativeSuffix) .reset().toString(); - output.accept(v); + output.accept(null, v); /* * Do not return, rather pass -v to the server so that the client module does not need to depend on any * Maven artifacts @@ -140,9 +140,9 @@ public ExecutionResult execute(ClientOutput output, List argv) { try (DaemonRegistry registry = new DaemonRegistry(layout.registry())) { boolean status = args.remove("--status"); if (status) { - output.accept(String.format(" %36s %7s %5s %7s %s", + output.accept(null, String.format(" %36s %7s %5s %7s %s", "UUID", "PID", "Port", "Status", "Last activity")); - registry.getAll().forEach(d -> output.accept(String.format(" %36s %7s %5s %7s %s", + registry.getAll().forEach(d -> output.accept(null, String.format(" %36s %7s %5s %7s %s", d.getUid(), d.getPid(), d.getAddress(), d.getState(), LocalDateTime.ofInstant( Instant.ofEpochMilli(Math.max(d.getLastIdle(), d.getLastBusy())), @@ -153,7 +153,7 @@ public ExecutionResult execute(ClientOutput output, List argv) { if (stop) { DaemonInfo[] dis = registry.getAll().toArray(new DaemonInfo[0]); if (dis.length > 0) { - output.accept("Stopping " + dis.length + " running daemons"); + output.accept(null, "Stopping " + dis.length + " running daemons"); for (DaemonInfo di : dis) { try { ProcessHandle.of(di.getPid()).ifPresent(ProcessHandle::destroyForcibly); @@ -204,15 +204,19 @@ public ExecutionResult execute(ClientOutput output, List argv) { return new DefaultResult(argv, null); case ProjectStarted: case MojoStarted: + output.projectStateChanged(be.getProjectId(), be.getDisplay()); + break; case MojoStopped: output.projectStateChanged(be.getProjectId(), be.getDisplay()); + output.projectStateChanged(be.getProjectId(), ":" + be.getProjectId()); break; case ProjectStopped: output.projectFinished(be.getProjectId()); + break; } } else if (m instanceof BuildMessage) { BuildMessage bm = (BuildMessage) m; - output.accept(bm.getMessage()); + output.accept(bm.getProjectId(), bm.getMessage()); } } } diff --git a/common/pom.xml b/common/pom.xml index 00d4819cd..b038632ed 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -51,6 +51,11 @@ junit-jupiter test + + org.slf4j + slf4j-simple + test + diff --git a/common/src/main/java/org/jboss/fuse/mvnd/common/Message.java b/common/src/main/java/org/jboss/fuse/mvnd/common/Message.java index 07b003192..419ea46df 100644 --- a/common/src/main/java/org/jboss/fuse/mvnd/common/Message.java +++ b/common/src/main/java/org/jboss/fuse/mvnd/common/Message.java @@ -146,9 +146,11 @@ public String toString() { } public static class BuildMessage extends Message { + final String projectId; final String message; - public BuildMessage(String message) { + public BuildMessage(String projectId, String message) { + this.projectId = projectId; this.message = message; } @@ -156,6 +158,10 @@ public String getMessage() { return message; } + public String getProjectId() { + return projectId; + } + @Override public String toString() { return "BuildMessage{" + @@ -236,11 +242,13 @@ private void writeBuildEvent(DataOutputStream output, BuildEvent value) throws I } private BuildMessage readBuildMessage(DataInputStream input) throws IOException { + String projectId = readUTF(input); String message = readUTF(input); - return new BuildMessage(message); + return new BuildMessage(projectId.isEmpty() ? null : projectId, message); } private void writeBuildMessage(DataOutputStream output, BuildMessage value) throws IOException { + writeUTF(output, value.projectId != null ? value.projectId : ""); writeUTF(output, value.message); } diff --git a/daemon/src/main/java/org/jboss/fuse/mvnd/daemon/Server.java b/daemon/src/main/java/org/jboss/fuse/mvnd/daemon/Server.java index a81452728..63d0d44a9 100644 --- a/daemon/src/main/java/org/jboss/fuse/mvnd/daemon/Server.java +++ b/daemon/src/main/java/org/jboss/fuse/mvnd/daemon/Server.java @@ -514,7 +514,6 @@ public void init(Context context) throws Exception { @Override public void close() throws Exception { - sendBuildMessages(); super.close(); } @@ -529,43 +528,38 @@ public void fail(Throwable t) throws Exception { } @Override - protected void onStartProject(ProjectBuild project) { - super.onStartProject(project); - sendEvent(Type.ProjectStarted, project); + protected void onStartProject(String projectId, String display) { + super.onStartProject(projectId, display); + sendEvent(Type.ProjectStarted, projectId, display); } @Override - protected void onStopProject(ProjectBuild project) { - sendEvent(Type.ProjectStopped, project); - super.onStopProject(project); + protected void onStopProject(String projectId, String display) { + sendEvent(Type.ProjectStopped, projectId, display); + super.onStopProject(projectId, display); } @Override - protected void onStartMojo(ProjectBuild project) { - super.onStartMojo(project); - sendEvent(Type.MojoStarted, project); + protected void onStartMojo(String projectId, String display) { + super.onStartMojo(projectId, display); + sendEvent(Type.MojoStarted, projectId, display); } @Override - protected void onStopMojo(ProjectBuild project) { - sendEvent(Type.MojoStopped, project); - super.onStopMojo(project); + protected void onStopMojo(String projectId, String display) { + sendEvent(Type.MojoStopped, projectId, display); + super.onStopMojo(projectId, display); } - private void sendEvent(Type type, ProjectBuild project) { - String projectId = project.projectId(); - String disp = project.toDisplay().toAnsi(256, false); - queue.add(new BuildEvent(type, projectId, disp)); - sendBuildMessages(); + @Override + protected void onProjectLog(String projectId, String message) { + queue.add(new BuildMessage(projectId, message)); + super.onProjectLog(projectId, message); } - private synchronized void sendBuildMessages() { - if (events != null) { - events.stream() - .map(s -> s.endsWith("\n") ? s.substring(0, s.length() - 1) : s) - .map(BuildMessage::new).forEachOrdered(queue::add); - events.clear(); - } + private void sendEvent(Type type, String projectId, String display) { + queue.add(new BuildEvent(type, projectId, display)); } + } } diff --git a/daemon/src/main/java/org/jboss/fuse/mvnd/logging/smart/AbstractLoggingSpy.java b/daemon/src/main/java/org/jboss/fuse/mvnd/logging/smart/AbstractLoggingSpy.java index 40d3d69dd..6d3277ef0 100644 --- a/daemon/src/main/java/org/jboss/fuse/mvnd/logging/smart/AbstractLoggingSpy.java +++ b/daemon/src/main/java/org/jboss/fuse/mvnd/logging/smart/AbstractLoggingSpy.java @@ -15,14 +15,13 @@ */ package org.jboss.fuse.mvnd.logging.smart; -import java.util.ArrayList; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import org.apache.maven.eventspy.AbstractEventSpy; import org.apache.maven.execution.ExecutionEvent; import org.apache.maven.plugin.MojoExecution; import org.apache.maven.project.MavenProject; +import org.jboss.fuse.mvnd.common.Message; import org.jline.utils.AttributedString; import org.slf4j.MDC; @@ -44,17 +43,14 @@ public static void instance(AbstractLoggingSpy instance) { } protected Map projects; - protected List events; + protected List events; @Override public synchronized void init(Context context) throws Exception { - projects = new LinkedHashMap<>(); - events = new ArrayList<>(); } @Override public synchronized void close() throws Exception { - events = null; projects = null; } @@ -97,73 +93,67 @@ protected void notifySessionStart(ExecutionEvent event) { protected void notifySessionFinish(ExecutionEvent event) { } - protected synchronized void notifyProjectBuildStart(ExecutionEvent event) { - ProjectBuild pb = new ProjectBuild(); - pb.project = event.getProject(); - pb.execution = event.getMojoExecution(); - pb.events = new ArrayList<>(); - projects.putIfAbsent(event.getProject().getId(), pb); - onStartProject(pb); + protected void notifyProjectBuildStart(ExecutionEvent event) { + onStartProject(getProjectId(event), getProjectDisplay(event)); } - protected void onStartProject(ProjectBuild project) { - MDC.put(KEY_PROJECT_ID, project.project.getId()); - update(); + protected void notifyProjectBuildFinish(ExecutionEvent event) throws Exception { + onStopProject(getProjectId(event), getProjectDisplay(event)); } - protected synchronized void notifyProjectBuildFinish(ExecutionEvent event) throws Exception { - ProjectBuild pb = projects.remove(event.getProject().getId()); - if (pb != null) { - events.addAll(pb.events); - onStopProject(pb); - } + protected void notifyMojoExecutionStart(ExecutionEvent event) { + onStartMojo(getProjectId(event), getProjectDisplay(event)); + } + + protected void notifyMojoExecutionFinish(ExecutionEvent event) { + onStopMojo(getProjectId(event), getProjectDisplay(event)); } - protected void onStopProject(ProjectBuild project) { + protected void onStartProject(String projectId, String display) { + MDC.put(KEY_PROJECT_ID, projectId); update(); - MDC.remove(KEY_PROJECT_ID); } - protected synchronized void notifyMojoExecutionStart(ExecutionEvent event) { - ProjectBuild pb = projects.get(event.getProject().getId()); - if (pb != null) { - pb.execution = event.getMojoExecution(); - onStartMojo(pb); - } + protected void onStopProject(String projectId, String display) { + update(); + MDC.remove(KEY_PROJECT_ID); } - protected void onStartMojo(ProjectBuild project) { + protected void onStartMojo(String projectId, String display) { update(); } - protected synchronized void notifyMojoExecutionFinish(ExecutionEvent event) { - ProjectBuild pb = projects.get(event.getProject().getId()); - if (pb != null) { - pb.execution = null; - onStopMojo(pb); - } + protected void onStopMojo(String projectId, String display) { + update(); } - protected void onStopMojo(ProjectBuild project) { + protected void onProjectLog(String projectId, String message) { update(); } protected void update() { } - public synchronized void append(String projectId, String event) { - ProjectBuild project = projectId != null ? projects.get(projectId) : null; - if (project != null) { - project.events.add(event); - } else { - events.add(event); - } + private String getProjectId(ExecutionEvent event) { + return event.getProject().getArtifactId(); + } + + private String getProjectDisplay(ExecutionEvent event) { + String projectId = getProjectId(event); + String disp = event.getMojoExecution() != null + ? ":" + projectId + ":" + event.getMojoExecution().toString() + : ":" + projectId; + return disp; + } + + public void append(String projectId, String event) { + String msg = event.endsWith("\n") ? event.substring(0, event.length() - 1) : event; + onProjectLog(projectId, msg); } protected static class ProjectBuild { MavenProject project; volatile MojoExecution execution; - List events; @Override public String toString() { diff --git a/daemon/src/main/java/org/jboss/fuse/mvnd/logging/smart/MavenLoggingSpy.java b/daemon/src/main/java/org/jboss/fuse/mvnd/logging/smart/MavenLoggingSpy.java index 3483fe10f..1298e6fad 100644 --- a/daemon/src/main/java/org/jboss/fuse/mvnd/logging/smart/MavenLoggingSpy.java +++ b/daemon/src/main/java/org/jboss/fuse/mvnd/logging/smart/MavenLoggingSpy.java @@ -17,7 +17,9 @@ import java.util.ArrayList; import java.util.Collections; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import org.jline.terminal.Size; import org.jline.terminal.Terminal; import org.jline.terminal.TerminalBuilder; @@ -26,6 +28,7 @@ public class MavenLoggingSpy extends AbstractLoggingSpy { + private Map projects = new LinkedHashMap<>(); private Terminal terminal; private Display display; @@ -45,9 +48,9 @@ public void init(Context context) throws Exception { @Override public void close() throws Exception { display.update(Collections.emptyList(), 0); - for (String event : events) { - terminal.writer().print(event); - } + // for (String event : events) { + // terminal.writer().print(event); + // } terminal.flush(); terminal.close(); terminal = null; @@ -55,13 +58,37 @@ public void close() throws Exception { super.close(); } + @Override + protected void onStartProject(String projectId, String display) { + projects.put(projectId, display); + super.onStartProject(projectId, display); + } + + @Override + protected void onStopProject(String projectId, String display) { + projects.remove(projectId); + super.onStopProject(projectId, display); + } + + @Override + protected void onStartMojo(String projectId, String display) { + projects.put(projectId, display); + super.onStartMojo(projectId, display); + } + + @Override + protected void onStopMojo(String projectId, String display) { + projects.put(projectId, display); + super.onStopMojo(projectId, display); + } + protected void update() { Size size = terminal.getSize(); display.resize(size.getRows(), size.getColumns()); List lines = new ArrayList<>(); lines.add(new AttributedString("Building...")); - for (ProjectBuild build : projects.values()) { - lines.add(build.toDisplay()); + for (String build : projects.values()) { + lines.add(new AttributedString(build)); } display.update(lines, -1); } diff --git a/integration-tests/src/test/java/org/jboss/fuse/mvnd/assertj/MatchInOrderAmongOthers.java b/integration-tests/src/test/java/org/jboss/fuse/mvnd/assertj/MatchInOrderAmongOthers.java index ed8d1254b..39d4c8c05 100644 --- a/integration-tests/src/test/java/org/jboss/fuse/mvnd/assertj/MatchInOrderAmongOthers.java +++ b/integration-tests/src/test/java/org/jboss/fuse/mvnd/assertj/MatchInOrderAmongOthers.java @@ -17,6 +17,7 @@ import java.util.Collection; import java.util.List; +import java.util.Objects; import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -43,7 +44,7 @@ public MatchInOrderAmongOthers(final Collection patterns) { .filter(pat -> pat.matcher(m).find()) .findFirst() .orElse(null)) - .filter(pat -> pat != null) /* remove null patterns */ + .filter(Objects::nonNull) /* remove null patterns */ .collect(Collectors.toList()) /* if the mapped patterns equal the input patterns then each pattern matched exactly once */ .equals(patterns), diff --git a/integration-tests/src/test/java/org/jboss/fuse/mvnd/it/MultiModuleTest.java b/integration-tests/src/test/java/org/jboss/fuse/mvnd/it/MultiModuleTest.java index e94273759..d4b5bd9db 100644 --- a/integration-tests/src/test/java/org/jboss/fuse/mvnd/it/MultiModuleTest.java +++ b/integration-tests/src/test/java/org/jboss/fuse/mvnd/it/MultiModuleTest.java @@ -32,6 +32,8 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mockito; +import static org.mockito.ArgumentMatchers.any; + @MvndTest(projectDir = "src/test/projects/multi-module") public class MultiModuleTest { @@ -69,7 +71,7 @@ void cleanInstall() throws IOException, InterruptedException { client.execute(output, "clean", "install", "-e").assertSuccess(); final ArgumentCaptor logMessage = ArgumentCaptor.forClass(String.class); - Mockito.verify(output, Mockito.atLeast(1)).accept(logMessage.capture()); + Mockito.verify(output, Mockito.atLeast(1)).accept(any(), logMessage.capture()); Assertions.assertThat(logMessage.getAllValues()) .satisfiesAnyOf( /* Two orderings are possible */ messages -> Assertions.assertThat(messages) diff --git a/integration-tests/src/test/java/org/jboss/fuse/mvnd/it/SingleModuleNativeIT.java b/integration-tests/src/test/java/org/jboss/fuse/mvnd/it/SingleModuleNativeIT.java index 3e7d578c7..86942ae64 100644 --- a/integration-tests/src/test/java/org/jboss/fuse/mvnd/it/SingleModuleNativeIT.java +++ b/integration-tests/src/test/java/org/jboss/fuse/mvnd/it/SingleModuleNativeIT.java @@ -30,6 +30,8 @@ import org.mockito.InOrder; import org.mockito.Mockito; +import static org.mockito.ArgumentMatchers.any; + @MvndNativeTest(projectDir = "src/test/projects/single-module") public class SingleModuleNativeIT { @@ -57,14 +59,14 @@ void cleanInstall() throws IOException, InterruptedException { final Properties props = MvndTestUtil.properties(layout.multiModuleProjectDirectory().resolve("pom.xml")); final InOrder inOrder = Mockito.inOrder(o); - inOrder.verify(o).accept(Mockito.contains("Building single-module")); - inOrder.verify(o).accept(Mockito.contains(MvndTestUtil.plugin(props, "maven-clean-plugin") + ":clean")); - inOrder.verify(o).accept(Mockito.contains(MvndTestUtil.plugin(props, "maven-compiler-plugin") + ":compile")); - inOrder.verify(o).accept(Mockito.contains(MvndTestUtil.plugin(props, "maven-compiler-plugin") + ":testCompile")); - inOrder.verify(o).accept(Mockito.contains(MvndTestUtil.plugin(props, "maven-surefire-plugin") + ":test")); - inOrder.verify(o).accept(Mockito.contains(MvndTestUtil.plugin(props, "maven-install-plugin") + ":install")); - inOrder.verify(o) - .accept(Mockito.contains("SUCCESS build of project org.jboss.fuse.mvnd.test.single-module:single-module")); + inOrder.verify(o).accept(any(), Mockito.contains("Building single-module")); + inOrder.verify(o).accept(any(), Mockito.contains(MvndTestUtil.plugin(props, "maven-clean-plugin") + ":clean")); + inOrder.verify(o).accept(any(), Mockito.contains(MvndTestUtil.plugin(props, "maven-compiler-plugin") + ":compile")); + inOrder.verify(o).accept(any(), Mockito.contains(MvndTestUtil.plugin(props, "maven-compiler-plugin") + ":testCompile")); + inOrder.verify(o).accept(any(), Mockito.contains(MvndTestUtil.plugin(props, "maven-surefire-plugin") + ":test")); + inOrder.verify(o).accept(any(), Mockito.contains(MvndTestUtil.plugin(props, "maven-install-plugin") + ":install")); + inOrder.verify(o).accept(any(), + Mockito.contains("SUCCESS build of project org.jboss.fuse.mvnd.test.single-module:single-module")); assertJVM(o, props); diff --git a/integration-tests/src/test/java/org/jboss/fuse/mvnd/it/StopStatusTest.java b/integration-tests/src/test/java/org/jboss/fuse/mvnd/it/StopStatusTest.java index d6332079d..8cd430739 100644 --- a/integration-tests/src/test/java/org/jboss/fuse/mvnd/it/StopStatusTest.java +++ b/integration-tests/src/test/java/org/jboss/fuse/mvnd/it/StopStatusTest.java @@ -29,6 +29,8 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mockito; +import static org.mockito.ArgumentMatchers.any; + @MvndTest(projectDir = "src/test/projects/single-module") public class StopStatusTest { @@ -54,7 +56,7 @@ void stopStatus() throws IOException, InterruptedException { final ClientOutput output = Mockito.mock(ClientOutput.class); client.execute(output, "--status").assertSuccess(); final ArgumentCaptor logMessage = ArgumentCaptor.forClass(String.class); - Mockito.verify(output, Mockito.atLeast(1)).accept(logMessage.capture()); + Mockito.verify(output, Mockito.atLeast(1)).accept(any(), logMessage.capture()); Assertions.assertThat(logMessage.getAllValues()) .is(new MatchInOrderAmongOthers<>( d.getUid() + " +" + d.getPid() + " +" + d.getAddress())); @@ -76,7 +78,7 @@ void stopStatus() throws IOException, InterruptedException { final ClientOutput output = Mockito.mock(ClientOutput.class); client.execute(output, "--status").assertSuccess(); final ArgumentCaptor logMessage = ArgumentCaptor.forClass(String.class); - Mockito.verify(output, Mockito.atLeast(1)).accept(logMessage.capture()); + Mockito.verify(output, Mockito.atLeast(1)).accept(any(), logMessage.capture()); Assertions.assertThat( logMessage.getAllValues().stream() .filter(m -> m.contains(d.getUid())) diff --git a/integration-tests/src/test/java/org/jboss/fuse/mvnd/it/VersionNativeIT.java b/integration-tests/src/test/java/org/jboss/fuse/mvnd/it/VersionNativeIT.java index acebfed7a..92aef608d 100644 --- a/integration-tests/src/test/java/org/jboss/fuse/mvnd/it/VersionNativeIT.java +++ b/integration-tests/src/test/java/org/jboss/fuse/mvnd/it/VersionNativeIT.java @@ -28,6 +28,8 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mockito; +import static org.mockito.ArgumentMatchers.any; + @MvndNativeTest(projectDir = MvndTestExtension.TEMP_EXTERNAL) public class VersionNativeIT { @@ -44,7 +46,7 @@ void version() throws IOException, InterruptedException { client.execute(output, "-v").assertSuccess(); final ArgumentCaptor logMessage = ArgumentCaptor.forClass(String.class); - Mockito.verify(output, Mockito.atLeast(1)).accept(logMessage.capture()); + Mockito.verify(output, Mockito.atLeast(1)).accept(any(), logMessage.capture()); Assertions.assertThat(logMessage.getAllValues()) .is(new MatchInOrderAmongOthers<>( diff --git a/integration-tests/src/test/java/org/jboss/fuse/mvnd/junit/NativeTestClient.java b/integration-tests/src/test/java/org/jboss/fuse/mvnd/junit/NativeTestClient.java index c88cb2074..6604182cd 100644 --- a/integration-tests/src/test/java/org/jboss/fuse/mvnd/junit/NativeTestClient.java +++ b/integration-tests/src/test/java/org/jboss/fuse/mvnd/junit/NativeTestClient.java @@ -56,7 +56,7 @@ public NativeTestClient(ClientLayout layout, Path mvndNativeExecutablePath, long public ExecutionResult execute(ClientOutput output, List args) throws InterruptedException { final List cmd = new ArrayList(args.size() + 1); cmd.add(mvndNativeExecutablePath.toString()); - args.stream().forEach(cmd::add); + cmd.addAll(args); if (!Environment.MVND_PROPERTIES_PATH.hasCommandLineProperty(args)) { cmd.add(Environment.MVND_PROPERTIES_PATH.asCommandLineProperty(layout.getMvndPropertiesPath().toString())); } @@ -74,9 +74,9 @@ public ExecutionResult execute(ClientOutput output, List args) throws In if (!Environment.JAVA_HOME.hasCommandLineProperty(args)) { env.put("JAVA_HOME", System.getProperty("java.home")); } - final String cmdString = cmd.stream().collect(Collectors.joining(" ")); - output.accept("Executing " + cmdString); - try (CommandProcess process = new CommandProcess(builder.start(), cmd, output)) { + final String cmdString = String.join(" ", cmd); + output.accept(null, "Executing " + cmdString); + try (CommandProcess process = new CommandProcess(builder.start(), cmd, s -> output.accept(null, s))) { return process.waitFor(timeoutMs); } catch (IOException e) { throw new RuntimeException("Could not execute: " + cmdString, e); @@ -120,7 +120,7 @@ public Result assertSuccess() { } sb.append("\n--- stderr+stdout start ---"); synchronized (log) { - log.stream().forEach(s -> sb.append('\n').append(s)); + log.forEach(s -> sb.append('\n').append(s)); } sb.append("\n--- stderr+stdout end ---"); throw new AssertionError(sb);