mirror of
https://github.com/apache/maven-mvnd.git
synced 2025-09-27 16:08:21 +00:00
Client: have just one event queue and one consuming thread #133
This commit is contained in:
@@ -17,6 +17,8 @@ package org.jboss.fuse.mvnd.client;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@@ -30,6 +32,7 @@ import org.jboss.fuse.mvnd.common.DaemonException.ConnectException;
|
||||
import org.jboss.fuse.mvnd.common.DaemonException.StaleAddressException;
|
||||
import org.jboss.fuse.mvnd.common.DaemonInfo;
|
||||
import org.jboss.fuse.mvnd.common.Message;
|
||||
import org.jboss.fuse.mvnd.common.Message.Prompt;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -85,19 +88,27 @@ public class DaemonClientConnection implements Closeable {
|
||||
}
|
||||
}
|
||||
|
||||
public Message receive() throws ConnectException, StaleAddressException {
|
||||
public List<Message> receive() throws ConnectException, StaleAddressException {
|
||||
while (true) {
|
||||
try {
|
||||
Message m = queue.poll(maxKeepAliveMs, TimeUnit.MILLISECONDS);
|
||||
final Message m = queue.poll(maxKeepAliveMs, TimeUnit.MILLISECONDS);
|
||||
{
|
||||
Exception e = exception.get();
|
||||
if (e != null) {
|
||||
throw e;
|
||||
} else if (m != null) {
|
||||
return m;
|
||||
} else {
|
||||
} else if (m == null) {
|
||||
throw new IOException("No message received within " + maxKeepAliveMs
|
||||
+ "ms, daemon may have crashed. You may want to check its status using mvnd --status");
|
||||
}
|
||||
}
|
||||
final List<Message> result = new ArrayList<>(4);
|
||||
result.add(m);
|
||||
queue.drainTo(result);
|
||||
Exception e = exception.get();
|
||||
if (e != null) {
|
||||
throw e;
|
||||
}
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
DaemonDiagnostics diag = new DaemonDiagnostics(daemon.getUid(), parameters);
|
||||
LOG.debug("Problem receiving message to the daemon. Performing 'on failure' operation...");
|
||||
@@ -119,6 +130,10 @@ public class DaemonClientConnection implements Closeable {
|
||||
if (m == null) {
|
||||
break;
|
||||
}
|
||||
if (m.getType() == Message.PROMPT) {
|
||||
final Prompt prompt = (Prompt) m;
|
||||
m = prompt.withCallback(response -> dispatch(prompt.response(response)));
|
||||
}
|
||||
queue.put(m);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
@@ -41,6 +41,7 @@ import org.jboss.fuse.mvnd.common.DaemonState;
|
||||
import org.jboss.fuse.mvnd.common.DaemonStopEvent;
|
||||
import org.jboss.fuse.mvnd.common.Environment;
|
||||
import org.jboss.fuse.mvnd.common.MavenDaemon;
|
||||
import org.jboss.fuse.mvnd.common.Message;
|
||||
import org.jboss.fuse.mvnd.common.Os;
|
||||
import org.jboss.fuse.mvnd.common.logging.ClientOutput;
|
||||
import org.slf4j.Logger;
|
||||
@@ -85,7 +86,7 @@ public class DaemonConnector {
|
||||
public DaemonClientConnection connect(ClientOutput output) {
|
||||
final DaemonCompatibilitySpec constraint = new DaemonCompatibilitySpec(
|
||||
parameters.javaHome(), parameters.getDaemonOpts());
|
||||
output.buildStatus("Looking up daemon...");
|
||||
output.accept(Message.buildStatus("Looking up daemon..."));
|
||||
Map<Boolean, List<DaemonInfo>> idleBusy = registry.getAll().stream()
|
||||
.collect(Collectors.groupingBy(di -> di.getState() == DaemonState.Idle));
|
||||
final Collection<DaemonInfo> idleDaemons = idleBusy.getOrDefault(true, Collections.emptyList());
|
||||
@@ -105,7 +106,7 @@ public class DaemonConnector {
|
||||
|
||||
// No compatible daemons available - start a new daemon
|
||||
String message = handleStopEvents(idleDaemons, busyDaemons);
|
||||
output.buildStatus(message);
|
||||
output.accept(Message.buildStatus(message));
|
||||
return startDaemon();
|
||||
}
|
||||
|
||||
|
@@ -28,10 +28,7 @@ import org.jboss.fuse.mvnd.common.DaemonInfo;
|
||||
import org.jboss.fuse.mvnd.common.DaemonRegistry;
|
||||
import org.jboss.fuse.mvnd.common.Environment;
|
||||
import org.jboss.fuse.mvnd.common.Message;
|
||||
import org.jboss.fuse.mvnd.common.Message.BuildEvent;
|
||||
import org.jboss.fuse.mvnd.common.Message.BuildException;
|
||||
import org.jboss.fuse.mvnd.common.Message.BuildMessage;
|
||||
import org.jboss.fuse.mvnd.common.Message.BuildStarted;
|
||||
import org.jboss.fuse.mvnd.common.OsUtils;
|
||||
import org.jboss.fuse.mvnd.common.logging.ClientOutput;
|
||||
import org.jboss.fuse.mvnd.common.logging.TerminalOutput;
|
||||
@@ -125,7 +122,7 @@ public class DefaultClient implements Client {
|
||||
+ "-" + buildProperties.getOsArch()
|
||||
+ nativeSuffix)
|
||||
.reset().toString();
|
||||
output.accept(null, v);
|
||||
output.accept(Message.log(v));
|
||||
// Print terminal information
|
||||
output.describeTerminal();
|
||||
/*
|
||||
@@ -138,20 +135,20 @@ public class DefaultClient implements Client {
|
||||
boolean status = args.remove("--status");
|
||||
if (status) {
|
||||
final String template = " %36s %7s %5s %7s %5s %23s %s";
|
||||
output.accept(null, String.format(template,
|
||||
"UUID", "PID", "Port", "Status", "RSS", "Last activity", "Java home"));
|
||||
output.accept(Message.log(String.format(template,
|
||||
"UUID", "PID", "Port", "Status", "RSS", "Last activity", "Java home")));
|
||||
for (DaemonInfo d : registry.getAll()) {
|
||||
if (ProcessHandle.of(d.getPid()).isEmpty()) {
|
||||
/* The process does not exist anymore - remove it from the registry */
|
||||
registry.remove(d.getUid());
|
||||
} else {
|
||||
output.accept(null, String.format(template,
|
||||
output.accept(Message.log(String.format(template,
|
||||
d.getUid(), d.getPid(), d.getAddress(), d.getState(),
|
||||
OsUtils.kbTohumanReadable(OsUtils.findProcessRssInKb(d.getPid())),
|
||||
LocalDateTime.ofInstant(
|
||||
Instant.ofEpochMilli(Math.max(d.getLastIdle(), d.getLastBusy())),
|
||||
ZoneId.systemDefault()),
|
||||
d.getJavaHome()));
|
||||
d.getJavaHome())));
|
||||
}
|
||||
}
|
||||
return new DefaultResult(argv, null);
|
||||
@@ -160,7 +157,7 @@ public class DefaultClient implements Client {
|
||||
if (stop) {
|
||||
DaemonInfo[] dis = registry.getAll().toArray(new DaemonInfo[0]);
|
||||
if (dis.length > 0) {
|
||||
output.accept(null, "Stopping " + dis.length + " running daemons");
|
||||
output.accept(Message.log("Stopping " + dis.length + " running daemons"));
|
||||
for (DaemonInfo di : dis) {
|
||||
try {
|
||||
ProcessHandle.of(di.getPid()).ifPresent(ProcessHandle::destroyForcibly);
|
||||
@@ -194,7 +191,7 @@ public class DefaultClient implements Client {
|
||||
|
||||
final DaemonConnector connector = new DaemonConnector(parameters, registry);
|
||||
try (DaemonClientConnection daemon = connector.connect(output)) {
|
||||
output.buildStatus("Connected to daemon");
|
||||
output.accept(Message.buildStatus("Connected to daemon"));
|
||||
|
||||
daemon.dispatch(new Message.BuildRequest(
|
||||
args,
|
||||
@@ -202,44 +199,28 @@ public class DefaultClient implements Client {
|
||||
parameters.multiModuleProjectDirectory().toString(),
|
||||
System.getenv()));
|
||||
|
||||
output.buildStatus("Build request sent");
|
||||
output.accept(Message.buildStatus("Build request sent"));
|
||||
|
||||
while (true) {
|
||||
Message m = daemon.receive();
|
||||
if (m instanceof BuildException) {
|
||||
final List<Message> messages = daemon.receive();
|
||||
for (int i = 0; i < messages.size(); i++) {
|
||||
Message m = messages.get(i);
|
||||
switch (m.getType()) {
|
||||
case Message.BUILD_EXCEPTION: {
|
||||
output.accept(messages.subList(0, i + 1));
|
||||
final BuildException e = (BuildException) m;
|
||||
output.error(e.getMessage(), e.getClassName(), e.getStackTrace());
|
||||
return new DefaultResult(argv,
|
||||
new Exception(e.getClassName() + ": " + e.getMessage() + "\n" + e.getStackTrace()));
|
||||
} else if (m instanceof BuildStarted) {
|
||||
final BuildStarted bs = (BuildStarted) m;
|
||||
output.startBuild(bs.getProjectId(), bs.getProjectCount(), bs.getMaxThreads());
|
||||
} else if (m instanceof BuildEvent) {
|
||||
BuildEvent be = (BuildEvent) m;
|
||||
switch (be.getType()) {
|
||||
case BuildStopped:
|
||||
}
|
||||
case Message.BUILD_STOPPED: {
|
||||
output.accept(messages.subList(0, i));
|
||||
return new DefaultResult(argv, null);
|
||||
case ProjectStarted:
|
||||
case MojoStarted:
|
||||
output.projectStateChanged(be.getProjectId(), be.getDisplay());
|
||||
break;
|
||||
case ProjectStopped:
|
||||
output.projectFinished(be.getProjectId());
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (m instanceof BuildMessage) {
|
||||
BuildMessage bm = (BuildMessage) m;
|
||||
output.accept(bm.getProjectId(), bm.getMessage());
|
||||
} else if (m == Message.KEEP_ALIVE_SINGLETON) {
|
||||
output.keepAlive();
|
||||
} else if (m instanceof Message.Display) {
|
||||
Message.Display d = (Message.Display) m;
|
||||
output.display(d.getProjectId(), d.getMessage());
|
||||
} else if (m instanceof Message.Prompt) {
|
||||
Message.Prompt p = (Message.Prompt) m;
|
||||
String response = output.prompt(p.getProjectId(), p.getMessage(), p.isPassword());
|
||||
daemon.dispatch(new Message.PromptResponse(p.getProjectId(), p.getUid(), response));
|
||||
}
|
||||
output.accept(messages);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -26,21 +26,34 @@ import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public abstract class Message {
|
||||
static final int BUILD_REQUEST = 0;
|
||||
static final int BUILD_EVENT = 1;
|
||||
static final int BUILD_MESSAGE = 2;
|
||||
static final int BUILD_EXCEPTION = 3;
|
||||
static final int KEEP_ALIVE = 4;
|
||||
static final int STOP = 5;
|
||||
static final int BUILD_STARTED = 6;
|
||||
static final int DISPLAY = 7;
|
||||
static final int PROMPT = 8;
|
||||
static final int PROMPT_RESPONSE = 9;
|
||||
public static final int BUILD_REQUEST = 0;
|
||||
public static final int BUILD_STARTED = 1;
|
||||
public static final int BUILD_STOPPED = 2;
|
||||
public static final int PROJECT_STARTED = 3;
|
||||
public static final int PROJECT_STOPPED = 4;
|
||||
public static final int MOJO_STARTED = 5;
|
||||
public static final int BUILD_MESSAGE = 6;
|
||||
public static final int BUILD_EXCEPTION = 7;
|
||||
public static final int KEEP_ALIVE = 8;
|
||||
public static final int STOP = 9;
|
||||
public static final int DISPLAY = 10;
|
||||
public static final int PROMPT = 11;
|
||||
public static final int PROMPT_RESPONSE = 12;
|
||||
public static final int BUILD_STATUS = 13;
|
||||
public static final int KEYBOARD_INPUT = 14;
|
||||
|
||||
public static final SimpleMessage KEEP_ALIVE_SINGLETON = new SimpleMessage(Message.KEEP_ALIVE, "KEEP_ALIVE");
|
||||
public static final SimpleMessage STOP_SINGLETON = new SimpleMessage(Message.STOP, "STOP");
|
||||
public static final SimpleMessage KEEP_ALIVE_SINGLETON = new SimpleMessage(KEEP_ALIVE);
|
||||
public static final SimpleMessage STOP_SINGLETON = new SimpleMessage(STOP);
|
||||
public static final SimpleMessage BUILD_STOPPED_SINGLETON = new SimpleMessage(BUILD_STOPPED);
|
||||
|
||||
final int type;
|
||||
|
||||
Message(int type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public static Message read(DataInputStream input) throws IOException {
|
||||
int type = input.read();
|
||||
@@ -52,8 +65,12 @@ public abstract class Message {
|
||||
return BuildRequest.read(input);
|
||||
case BUILD_STARTED:
|
||||
return BuildStarted.read(input);
|
||||
case BUILD_EVENT:
|
||||
return BuildEvent.read(input);
|
||||
case BUILD_STOPPED:
|
||||
return SimpleMessage.BUILD_STOPPED_SINGLETON;
|
||||
case PROJECT_STARTED:
|
||||
case PROJECT_STOPPED:
|
||||
case MOJO_STARTED:
|
||||
return BuildEvent.read(type, input);
|
||||
case BUILD_MESSAGE:
|
||||
return BuildMessage.read(input);
|
||||
case BUILD_EXCEPTION:
|
||||
@@ -68,6 +85,8 @@ public abstract class Message {
|
||||
return Prompt.read(input);
|
||||
case PROMPT_RESPONSE:
|
||||
return PromptResponse.read(input);
|
||||
case BUILD_STATUS:
|
||||
return StringMessage.read(BUILD_STATUS, input);
|
||||
}
|
||||
throw new IllegalStateException("Unexpected message type: " + type);
|
||||
}
|
||||
@@ -78,7 +97,9 @@ public abstract class Message {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public abstract void write(DataOutputStream output) throws IOException;
|
||||
public void write(DataOutputStream output) throws IOException {
|
||||
output.write(type);
|
||||
}
|
||||
|
||||
static void writeStringList(DataOutputStream output, List<String> value) throws IOException {
|
||||
output.writeInt(value.size());
|
||||
@@ -233,6 +254,7 @@ public abstract class Message {
|
||||
}
|
||||
|
||||
public BuildRequest(List<String> args, String workingDir, String projectDir, Map<String, String> env) {
|
||||
super(BUILD_REQUEST);
|
||||
this.args = args;
|
||||
this.workingDir = workingDir;
|
||||
this.projectDir = projectDir;
|
||||
@@ -266,7 +288,7 @@ public abstract class Message {
|
||||
|
||||
@Override
|
||||
public void write(DataOutputStream output) throws IOException {
|
||||
output.write(BUILD_REQUEST);
|
||||
super.write(output);
|
||||
writeStringList(output, args);
|
||||
writeUTF(output, workingDir);
|
||||
writeUTF(output, projectDir);
|
||||
@@ -297,6 +319,7 @@ public abstract class Message {
|
||||
}
|
||||
|
||||
public BuildException(String message, String className, String stackTrace) {
|
||||
super(BUILD_EXCEPTION);
|
||||
this.message = message;
|
||||
this.className = className;
|
||||
this.stackTrace = stackTrace;
|
||||
@@ -325,7 +348,7 @@ public abstract class Message {
|
||||
|
||||
@Override
|
||||
public void write(DataOutputStream output) throws IOException {
|
||||
output.write(BUILD_EXCEPTION);
|
||||
super.write(output);
|
||||
writeUTF(output, message);
|
||||
writeUTF(output, className);
|
||||
writeUTF(output, stackTrace);
|
||||
@@ -333,31 +356,21 @@ public abstract class Message {
|
||||
}
|
||||
|
||||
public static class BuildEvent extends Message {
|
||||
public enum Type {
|
||||
BuildStopped, ProjectStarted, ProjectStopped, MojoStarted
|
||||
}
|
||||
|
||||
final Type type;
|
||||
final String projectId;
|
||||
final String display;
|
||||
|
||||
public static Message read(DataInputStream input) throws IOException {
|
||||
BuildEvent.Type type = BuildEvent.Type.values()[input.read()];
|
||||
public static Message read(int type, DataInputStream input) throws IOException {
|
||||
String projectId = readUTF(input);
|
||||
String display = readUTF(input);
|
||||
return new BuildEvent(type, projectId, display);
|
||||
}
|
||||
|
||||
public BuildEvent(Type type, String projectId, String display) {
|
||||
this.type = type;
|
||||
public BuildEvent(int type, String projectId, String display) {
|
||||
super(type);
|
||||
this.projectId = projectId;
|
||||
this.display = display;
|
||||
}
|
||||
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getProjectId() {
|
||||
return projectId;
|
||||
}
|
||||
@@ -368,17 +381,28 @@ public abstract class Message {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BuildEvent{" +
|
||||
return mnemonic() + "{" +
|
||||
"projectId='" + projectId + '\'' +
|
||||
", type=" + type +
|
||||
", display='" + display + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
private String mnemonic() {
|
||||
switch (type) {
|
||||
case PROJECT_STARTED:
|
||||
return "ProjectStarted";
|
||||
case PROJECT_STOPPED:
|
||||
return "ProjectStopped";
|
||||
case MOJO_STARTED:
|
||||
return "MojoStarted";
|
||||
default:
|
||||
throw new IllegalStateException("Unexpected type " + type);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(DataOutputStream output) throws IOException {
|
||||
output.write(BUILD_EVENT);
|
||||
output.write(type.ordinal());
|
||||
super.write(output);
|
||||
writeUTF(output, projectId);
|
||||
writeUTF(output, display);
|
||||
}
|
||||
@@ -398,6 +422,7 @@ public abstract class Message {
|
||||
}
|
||||
|
||||
public BuildStarted(String projectId, int projectCount, int maxThreads) {
|
||||
super(BUILD_STARTED);
|
||||
this.projectId = projectId;
|
||||
this.projectCount = projectCount;
|
||||
this.maxThreads = maxThreads;
|
||||
@@ -417,16 +442,14 @@ public abstract class Message {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BuildEvent{" +
|
||||
"projectId='" + projectId + '\'' +
|
||||
", projectCount=" + projectCount +
|
||||
", maxThreads='" + maxThreads + '\'' +
|
||||
'}';
|
||||
return "BuildStarted{" +
|
||||
"projectId='" + projectId + "', projectCount=" + projectCount +
|
||||
", maxThreads='" + maxThreads + "'}";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(DataOutputStream output) throws IOException {
|
||||
output.write(BUILD_STARTED);
|
||||
super.write(output);
|
||||
writeUTF(output, projectId);
|
||||
output.writeInt(projectCount);
|
||||
output.writeInt(maxThreads);
|
||||
@@ -444,6 +467,7 @@ public abstract class Message {
|
||||
}
|
||||
|
||||
public BuildMessage(String projectId, String message) {
|
||||
super(BUILD_MESSAGE);
|
||||
this.projectId = projectId;
|
||||
this.message = message;
|
||||
}
|
||||
@@ -466,7 +490,7 @@ public abstract class Message {
|
||||
|
||||
@Override
|
||||
public void write(DataOutputStream output) throws IOException {
|
||||
output.write(BUILD_MESSAGE);
|
||||
super.write(output);
|
||||
writeUTF(output, projectId != null ? projectId : "");
|
||||
writeUTF(output, message);
|
||||
}
|
||||
@@ -474,28 +498,66 @@ public abstract class Message {
|
||||
|
||||
public static class SimpleMessage extends Message {
|
||||
|
||||
final int type;
|
||||
final String mnemonic;
|
||||
|
||||
/**
|
||||
* Use {@link #KEEP_ALIVE_SINGLETON}
|
||||
*
|
||||
* @param type
|
||||
*/
|
||||
private SimpleMessage(int type, String mnemonic) {
|
||||
this.type = type;
|
||||
this.mnemonic = mnemonic;
|
||||
private SimpleMessage(int type) {
|
||||
super(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return mnemonic;
|
||||
switch (type) {
|
||||
case KEEP_ALIVE:
|
||||
return "KeepAlive";
|
||||
case BUILD_STOPPED:
|
||||
return "BuildStopped";
|
||||
case STOP:
|
||||
return "Stop";
|
||||
default:
|
||||
throw new IllegalStateException("Unexpected type " + type);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class StringMessage extends Message {
|
||||
|
||||
final String payload;
|
||||
|
||||
public static StringMessage read(int type, DataInputStream input) throws IOException {
|
||||
String payload = readUTF(input);
|
||||
return new StringMessage(type, payload);
|
||||
}
|
||||
|
||||
private StringMessage(int type, String payload) {
|
||||
super(type);
|
||||
this.payload = payload;
|
||||
}
|
||||
|
||||
public String getPayload() {
|
||||
return payload;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(DataOutputStream output) throws IOException {
|
||||
output.write(type);
|
||||
super.write(output);
|
||||
writeUTF(output, payload);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return mnemonic() + "{payload='" + payload + "'}";
|
||||
}
|
||||
|
||||
private String mnemonic() {
|
||||
switch (type) {
|
||||
case BUILD_STATUS:
|
||||
return "BuildStatus";
|
||||
case Message.KEYBOARD_INPUT:
|
||||
return "KeyboardInput";
|
||||
default:
|
||||
throw new IllegalStateException("Unexpected type " + type);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Display extends Message {
|
||||
@@ -510,6 +572,7 @@ public abstract class Message {
|
||||
}
|
||||
|
||||
public Display(String projectId, String message) {
|
||||
super(DISPLAY);
|
||||
this.projectId = projectId;
|
||||
this.message = message;
|
||||
}
|
||||
@@ -532,7 +595,7 @@ public abstract class Message {
|
||||
|
||||
@Override
|
||||
public void write(DataOutputStream output) throws IOException {
|
||||
output.write(DISPLAY);
|
||||
super.write(output);
|
||||
writeUTF(output, projectId);
|
||||
writeUTF(output, message);
|
||||
}
|
||||
@@ -544,8 +607,9 @@ public abstract class Message {
|
||||
final String uid;
|
||||
final String message;
|
||||
final boolean password;
|
||||
final Consumer<String> callback;
|
||||
|
||||
public static Message read(DataInputStream input) throws IOException {
|
||||
public static Prompt read(DataInputStream input) throws IOException {
|
||||
String projectId = Message.readUTF(input);
|
||||
String uid = Message.readUTF(input);
|
||||
String message = Message.readUTF(input);
|
||||
@@ -554,10 +618,16 @@ public abstract class Message {
|
||||
}
|
||||
|
||||
public Prompt(String projectId, String uid, String message, boolean password) {
|
||||
this(projectId, uid, message, password, null);
|
||||
}
|
||||
|
||||
public Prompt(String projectId, String uid, String message, boolean password, Consumer<String> callback) {
|
||||
super(PROMPT);
|
||||
this.projectId = projectId;
|
||||
this.uid = uid;
|
||||
this.message = message;
|
||||
this.password = password;
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
public String getProjectId() {
|
||||
@@ -588,12 +658,25 @@ public abstract class Message {
|
||||
|
||||
@Override
|
||||
public void write(DataOutputStream output) throws IOException {
|
||||
output.write(PROMPT);
|
||||
super.write(output);
|
||||
writeUTF(output, projectId);
|
||||
writeUTF(output, uid);
|
||||
writeUTF(output, message);
|
||||
output.writeBoolean(password);
|
||||
}
|
||||
|
||||
public Prompt withCallback(Consumer<String> callback) {
|
||||
return new Prompt(projectId, uid, message, password, callback);
|
||||
}
|
||||
|
||||
public PromptResponse response(String message) {
|
||||
return new PromptResponse(projectId, uid, message);
|
||||
}
|
||||
|
||||
public Consumer<String> getCallback() {
|
||||
return callback;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class PromptResponse extends Message {
|
||||
@@ -610,6 +693,7 @@ public abstract class Message {
|
||||
}
|
||||
|
||||
public PromptResponse(String projectId, String uid, String message) {
|
||||
super(PROMPT_RESPONSE);
|
||||
this.projectId = projectId;
|
||||
this.uid = uid;
|
||||
this.message = message;
|
||||
@@ -638,11 +722,31 @@ public abstract class Message {
|
||||
|
||||
@Override
|
||||
public void write(DataOutputStream output) throws IOException {
|
||||
output.write(PROMPT_RESPONSE);
|
||||
super.write(output);
|
||||
writeUTF(output, projectId);
|
||||
writeUTF(output, uid);
|
||||
writeUTF(output, message);
|
||||
}
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public static StringMessage buildStatus(String payload) {
|
||||
return new StringMessage(BUILD_STATUS, payload);
|
||||
}
|
||||
|
||||
public static BuildMessage log(String message) {
|
||||
return new BuildMessage(null, message);
|
||||
}
|
||||
|
||||
public static BuildMessage log(String projectId, String message) {
|
||||
return new BuildMessage(projectId, message);
|
||||
}
|
||||
|
||||
public static StringMessage keyboardInput(char keyStroke) {
|
||||
return new StringMessage(KEYBOARD_INPUT, String.valueOf(keyStroke));
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -15,28 +15,16 @@
|
||||
*/
|
||||
package org.jboss.fuse.mvnd.common.logging;
|
||||
|
||||
import java.util.List;
|
||||
import org.jboss.fuse.mvnd.common.Message;
|
||||
|
||||
/**
|
||||
* A sink for various kinds of events sent by the daemon.
|
||||
*/
|
||||
public interface ClientOutput extends AutoCloseable {
|
||||
void accept(Message message);
|
||||
|
||||
void startBuild(String name, int projects, int cores);
|
||||
|
||||
void projectStateChanged(String projectId, String display);
|
||||
|
||||
void projectFinished(String projectId);
|
||||
|
||||
void accept(String projectId, String message);
|
||||
|
||||
void error(String message, String className, String stackTrace);
|
||||
|
||||
void keepAlive();
|
||||
|
||||
void buildStatus(String status);
|
||||
|
||||
void display(String projectId, String message);
|
||||
|
||||
String prompt(String projectId, String message, boolean password);
|
||||
void accept(List<Message> messages);
|
||||
|
||||
void describeTerminal();
|
||||
}
|
||||
|
@@ -27,16 +27,20 @@ import java.util.Collections;
|
||||
import java.util.Deque;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.LinkedBlockingDeque;
|
||||
import java.util.concurrent.SynchronousQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collector;
|
||||
import java.util.stream.Collectors;
|
||||
import org.jboss.fuse.mvnd.common.Message;
|
||||
import org.jboss.fuse.mvnd.common.Message.BuildEvent;
|
||||
import org.jboss.fuse.mvnd.common.Message.BuildException;
|
||||
import org.jboss.fuse.mvnd.common.Message.BuildMessage;
|
||||
import org.jboss.fuse.mvnd.common.Message.BuildStarted;
|
||||
import org.jboss.fuse.mvnd.common.Message.SimpleMessage;
|
||||
import org.jboss.fuse.mvnd.common.Message.StringMessage;
|
||||
import org.jline.terminal.Size;
|
||||
import org.jline.terminal.Terminal;
|
||||
import org.jline.terminal.TerminalBuilder;
|
||||
@@ -55,12 +59,10 @@ public class TerminalOutput implements ClientOutput {
|
||||
|
||||
public static final int CTRL_M = 'M' & 0x1f;
|
||||
|
||||
private final BlockingQueue<Event> queue;
|
||||
private final Terminal terminal;
|
||||
private final Display display;
|
||||
private final LinkedHashMap<String, Project> projects = new LinkedHashMap<>();
|
||||
private final ClientLog log;
|
||||
private final Thread worker;
|
||||
private final Thread reader;
|
||||
private volatile Exception exception;
|
||||
private volatile boolean closing;
|
||||
@@ -77,39 +79,6 @@ public class TerminalOutput implements ClientOutput {
|
||||
private String buildStatus; // read/written only by the displayLoop
|
||||
private boolean displayDone = false; // read/written only by the displayLoop
|
||||
|
||||
enum EventType {
|
||||
BUILD_STATUS,
|
||||
PROJECT_STATE,
|
||||
PROJECT_FINISHED,
|
||||
LOG,
|
||||
ERROR,
|
||||
END_OF_STREAM,
|
||||
INPUT,
|
||||
KEEP_ALIVE,
|
||||
DISPLAY,
|
||||
PROMPT,
|
||||
PROMPT_PASSWORD
|
||||
}
|
||||
|
||||
static class Event {
|
||||
public static final Event KEEP_ALIVE = new Event(EventType.KEEP_ALIVE, null, null);
|
||||
public final EventType type;
|
||||
public final String projectId;
|
||||
public final String message;
|
||||
public final SynchronousQueue<String> response;
|
||||
|
||||
public Event(EventType type, String projectId, String message) {
|
||||
this(type, projectId, message, null);
|
||||
}
|
||||
|
||||
public Event(EventType type, String projectId, String message, SynchronousQueue<String> response) {
|
||||
this.type = type;
|
||||
this.projectId = projectId;
|
||||
this.message = message;
|
||||
this.response = response;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link Project} is owned by the display loop thread and is accessed only from there. Therefore it does not need
|
||||
* to be immutable.
|
||||
@@ -126,193 +95,70 @@ public class TerminalOutput implements ClientOutput {
|
||||
|
||||
public TerminalOutput(Path logFile) throws IOException {
|
||||
this.start = System.currentTimeMillis();
|
||||
this.queue = new LinkedBlockingDeque<>();
|
||||
this.terminal = TerminalBuilder.terminal();
|
||||
terminal.enterRawMode();
|
||||
this.display = new Display(terminal, false);
|
||||
this.log = logFile == null ? new MessageCollector() : new FileLog(logFile);
|
||||
final Thread w = new Thread(this::displayLoop);
|
||||
w.start();
|
||||
this.worker = w;
|
||||
final Thread r = new Thread(this::readInputLoop);
|
||||
r.start();
|
||||
this.reader = r;
|
||||
}
|
||||
|
||||
public void startBuild(String name, int projects, int cores) {
|
||||
this.name = name;
|
||||
this.totalProjects = projects;
|
||||
this.maxThreads = cores;
|
||||
try {
|
||||
queue.put(Event.KEEP_ALIVE);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
public void projectStateChanged(String projectId, String task) {
|
||||
try {
|
||||
queue.put(new Event(EventType.PROJECT_STATE, projectId, task));
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
public void projectFinished(String projectId) {
|
||||
try {
|
||||
queue.put(new Event(EventType.PROJECT_FINISHED, projectId, null));
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
@Override
|
||||
public void accept(Message entry) {
|
||||
assert "main".equals(Thread.currentThread().getName());
|
||||
doAccept(entry);
|
||||
update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(String projectId, String message) {
|
||||
try {
|
||||
if (closing) {
|
||||
closed.await();
|
||||
System.err.println(message);
|
||||
} else {
|
||||
queue.put(new Event(EventType.LOG, projectId, message));
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
public void accept(List<Message> entries) {
|
||||
assert "main".equals(Thread.currentThread().getName());
|
||||
for (Message entry : entries) {
|
||||
doAccept(entry);
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(String message, String className, String stackTrace) {
|
||||
private void doAccept(Message entry) {
|
||||
switch (entry.getType()) {
|
||||
case Message.BUILD_STARTED: {
|
||||
BuildStarted bs = (BuildStarted) entry;
|
||||
this.name = bs.getProjectId();
|
||||
this.totalProjects = bs.getProjectCount();
|
||||
this.maxThreads = bs.getMaxThreads();
|
||||
break;
|
||||
}
|
||||
case Message.BUILD_EXCEPTION: {
|
||||
final BuildException e = (BuildException) entry;
|
||||
final String msg;
|
||||
if ("org.apache.commons.cli.UnrecognizedOptionException".equals(className)) {
|
||||
msg = "Unable to parse command line options: " + message;
|
||||
if ("org.apache.commons.cli.UnrecognizedOptionException".equals(e.getClassName())) {
|
||||
msg = "Unable to parse command line options: " + e.getMessage();
|
||||
} else {
|
||||
msg = className + ": " + message;
|
||||
msg = e.getClassName() + ": " + e.getMessage();
|
||||
}
|
||||
try {
|
||||
queue.put(new Event(EventType.ERROR, null, msg));
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keepAlive() {
|
||||
try {
|
||||
queue.put(Event.KEEP_ALIVE);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void buildStatus(String status) {
|
||||
try {
|
||||
queue.put(new Event(EventType.BUILD_STATUS, null, status));
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void display(String projectId, String message) {
|
||||
try {
|
||||
queue.put(new Event(EventType.DISPLAY, projectId, message));
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String prompt(String projectId, String message, boolean password) {
|
||||
String response = null;
|
||||
try {
|
||||
SynchronousQueue<String> sq = new SynchronousQueue<>();
|
||||
queue.put(new Event(password ? EventType.PROMPT_PASSWORD : EventType.PROMPT, projectId, message, sq));
|
||||
response = sq.take();
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void describeTerminal() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("Terminal: ").append(terminal != null ? terminal.getClass().getName() : null);
|
||||
if (terminal instanceof AbstractPosixTerminal) {
|
||||
sb.append(" with pty ").append(((AbstractPosixTerminal) terminal).getPty().getClass().getName());
|
||||
}
|
||||
this.accept(null, sb.toString());
|
||||
}
|
||||
|
||||
void readInputLoop() {
|
||||
try {
|
||||
while (!closing) {
|
||||
if (readInput.readLock().tryLock(10, TimeUnit.MILLISECONDS)) {
|
||||
int c = terminal.reader().read(10);
|
||||
if (c == -1) {
|
||||
break;
|
||||
}
|
||||
if (c == '+' || c == '-' || c == CTRL_L || c == CTRL_M) {
|
||||
queue.add(new Event(EventType.INPUT, null, Character.toString((char) c)));
|
||||
}
|
||||
readInput.readLock().unlock();
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
} catch (InterruptedIOException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
} catch (IOException e) {
|
||||
this.exception = e;
|
||||
}
|
||||
}
|
||||
|
||||
void displayLoop() {
|
||||
final List<Event> entries = new ArrayList<>();
|
||||
|
||||
while (true) {
|
||||
try {
|
||||
entries.add(queue.take());
|
||||
queue.drainTo(entries);
|
||||
for (Event entry : entries) {
|
||||
switch (entry.type) {
|
||||
case BUILD_STATUS: {
|
||||
this.buildStatus = entry.message;
|
||||
break;
|
||||
}
|
||||
case END_OF_STREAM: {
|
||||
projects.values().stream().flatMap(p -> p.log.stream()).forEach(log);
|
||||
clearDisplay();
|
||||
try {
|
||||
log.close();
|
||||
terminal.flush();
|
||||
return;
|
||||
} catch (IOException e1) {
|
||||
throw new RuntimeException(e1);
|
||||
}
|
||||
case LOG: {
|
||||
if (entry.projectId != null) {
|
||||
Project prj = projects.computeIfAbsent(entry.projectId, Project::new);
|
||||
prj.log.add(entry.message);
|
||||
} else {
|
||||
log.accept(entry.message);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ERROR: {
|
||||
projects.values().stream().flatMap(p -> p.log.stream()).forEach(log);
|
||||
clearDisplay();
|
||||
log.close();
|
||||
final AttributedStyle s = new AttributedStyle().bold().foreground(AttributedStyle.RED);
|
||||
new AttributedString(entry.message, s).println(terminal);
|
||||
new AttributedString(msg, s).println(terminal);
|
||||
terminal.flush();
|
||||
return;
|
||||
}
|
||||
case PROJECT_STATE: {
|
||||
Project prj = projects.computeIfAbsent(entry.projectId, Project::new);
|
||||
prj.status = entry.message;
|
||||
case Message.PROJECT_STARTED:
|
||||
case Message.MOJO_STARTED: {
|
||||
BuildEvent be = (BuildEvent) entry;
|
||||
Project prj = projects.computeIfAbsent(be.getProjectId(), Project::new);
|
||||
prj.status = be.getDisplay();
|
||||
break;
|
||||
}
|
||||
case PROJECT_FINISHED: {
|
||||
Project prj = projects.remove(entry.projectId);
|
||||
case Message.PROJECT_STOPPED: {
|
||||
BuildEvent be = (BuildEvent) entry;
|
||||
Project prj = projects.remove(be.getProjectId());
|
||||
if (prj != null) {
|
||||
prj.log.forEach(log);
|
||||
}
|
||||
@@ -320,8 +166,89 @@ public class TerminalOutput implements ClientOutput {
|
||||
displayDone();
|
||||
break;
|
||||
}
|
||||
case INPUT:
|
||||
switch (entry.message.charAt(0)) {
|
||||
case Message.BUILD_STATUS: {
|
||||
this.buildStatus = ((StringMessage) entry).getPayload();
|
||||
break;
|
||||
}
|
||||
case Message.BUILD_STOPPED: {
|
||||
projects.values().stream().flatMap(p -> p.log.stream()).forEach(log);
|
||||
clearDisplay();
|
||||
try {
|
||||
log.close();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
terminal.flush();
|
||||
}
|
||||
return;
|
||||
}
|
||||
case Message.KEEP_ALIVE: {
|
||||
break;
|
||||
}
|
||||
case Message.DISPLAY: {
|
||||
Message.Display d = (Message.Display) entry;
|
||||
display.update(Collections.emptyList(), 0);
|
||||
terminal.writer().printf("[%s] %s%n", d.getProjectId(), d.getMessage());
|
||||
break;
|
||||
}
|
||||
case Message.PROMPT: {
|
||||
Message.Prompt prompt = (Message.Prompt) entry;
|
||||
|
||||
readInput.writeLock().lock();
|
||||
try {
|
||||
display.update(Collections.emptyList(), 0);
|
||||
terminal.writer().printf("[%s] %s", prompt.getProjectId(), prompt.getMessage());
|
||||
terminal.flush();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
while (true) {
|
||||
int c = terminal.reader().read();
|
||||
if (c < 0) {
|
||||
break;
|
||||
} else if (c == '\n' || c == '\r') {
|
||||
prompt.getCallback().accept(sb.toString());
|
||||
terminal.writer().println();
|
||||
break;
|
||||
} else if (c == 127) {
|
||||
if (sb.length() > 0) {
|
||||
sb.setLength(sb.length() - 1);
|
||||
terminal.writer().write("\b \b");
|
||||
terminal.writer().flush();
|
||||
}
|
||||
} else {
|
||||
terminal.writer().print((char) c);
|
||||
terminal.writer().flush();
|
||||
sb.append((char) c);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
readInput.writeLock().unlock();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Message.BUILD_MESSAGE: {
|
||||
BuildMessage bm = (BuildMessage) entry;
|
||||
if (closing) {
|
||||
try {
|
||||
closed.await();
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
System.err.println(bm.getMessage());
|
||||
} else {
|
||||
if (bm.getProjectId() != null) {
|
||||
Project prj = projects.computeIfAbsent(bm.getProjectId(), Project::new);
|
||||
prj.log.add(bm.getMessage());
|
||||
} else {
|
||||
log.accept(bm.getMessage());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Message.KEYBOARD_INPUT:
|
||||
char keyStroke = ((StringMessage) entry).getPayload().charAt(0);
|
||||
switch (keyStroke) {
|
||||
case '+':
|
||||
linesPerProject = Math.min(10, linesPerProject + 1);
|
||||
break;
|
||||
@@ -337,61 +264,54 @@ public class TerminalOutput implements ClientOutput {
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case DISPLAY:
|
||||
display.update(Collections.emptyList(), 0);
|
||||
terminal.writer().printf("[%s] %s%n", entry.projectId, entry.message);
|
||||
break;
|
||||
case PROMPT:
|
||||
case PROMPT_PASSWORD: {
|
||||
readInput.writeLock().lock();
|
||||
try {
|
||||
display.update(Collections.emptyList(), 0);
|
||||
terminal.writer().printf("[%s] %s", entry.projectId, entry.message);
|
||||
terminal.flush();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void describeTerminal() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
while (true) {
|
||||
int c = terminal.reader().read();
|
||||
if (c < 0) {
|
||||
sb.append("Terminal: ").append(terminal != null ? terminal.getClass().getName() : null);
|
||||
if (terminal instanceof AbstractPosixTerminal) {
|
||||
sb.append(" with pty ").append(((AbstractPosixTerminal) terminal).getPty().getClass().getName());
|
||||
}
|
||||
this.accept(Message.log(sb.toString()));
|
||||
}
|
||||
|
||||
void readInputLoop() {
|
||||
try {
|
||||
while (!closing) {
|
||||
if (readInput.readLock().tryLock(10, TimeUnit.MILLISECONDS)) {
|
||||
int c = terminal.reader().read(10);
|
||||
if (c == -1) {
|
||||
break;
|
||||
} else if (c == '\n' || c == '\r') {
|
||||
entry.response.put(sb.toString());
|
||||
terminal.writer().println();
|
||||
break;
|
||||
} else if (c == 127) {
|
||||
if (sb.length() > 0) {
|
||||
sb.setLength(sb.length() - 1);
|
||||
terminal.writer().write("\b \b");
|
||||
terminal.writer().flush();
|
||||
}
|
||||
} else {
|
||||
terminal.writer().print((char) c);
|
||||
terminal.writer().flush();
|
||||
sb.append((char) c);
|
||||
if (c == '+' || c == '-' || c == CTRL_L || c == CTRL_M) {
|
||||
accept(Message.keyboardInput((char) c));
|
||||
}
|
||||
readInput.readLock().unlock();
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
readInput.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
entries.clear();
|
||||
update();
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
} catch (Exception e) {
|
||||
} catch (InterruptedIOException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
} catch (IOException e) {
|
||||
this.exception = e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void clearDisplay() {
|
||||
display.update(Collections.emptyList(), 0);
|
||||
}
|
||||
|
||||
private void displayDone() throws IOException {
|
||||
private void displayDone() {
|
||||
if (displayDone) {
|
||||
try {
|
||||
log.flush();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -399,8 +319,7 @@ public class TerminalOutput implements ClientOutput {
|
||||
public void close() throws Exception {
|
||||
closing = true;
|
||||
reader.interrupt();
|
||||
queue.put(new Event(EventType.END_OF_STREAM, null, null));
|
||||
worker.join();
|
||||
accept(SimpleMessage.BUILD_STOPPED_SINGLETON);
|
||||
reader.join();
|
||||
terminal.close();
|
||||
closed.countDown();
|
||||
@@ -456,11 +375,10 @@ public class TerminalOutput implements ClientOutput {
|
||||
}
|
||||
|
||||
private void addStatusLine(final List<AttributedString> lines, int dispLines, final int projectsCount) {
|
||||
if (name != null || buildStatus != null) {
|
||||
AttributedStringBuilder asb = new AttributedStringBuilder();
|
||||
StringBuilder statusLine = new StringBuilder(64);
|
||||
if (name == null) {
|
||||
statusLine.append(buildStatus != null ? buildStatus : "Looking up daemon...");
|
||||
} else {
|
||||
if (name != null) {
|
||||
asb.append("Building ");
|
||||
asb.style(AttributedStyle.BOLD);
|
||||
asb.append(name);
|
||||
@@ -477,6 +395,8 @@ public class TerminalOutput implements ClientOutput {
|
||||
statusLine.append(" progress: ").append(doneProjects).append('/').append(totalProjects).append(' ')
|
||||
.append(doneProjects * 100 / totalProjects).append('%');
|
||||
}
|
||||
} else if (buildStatus != null) {
|
||||
statusLine.append(buildStatus);
|
||||
}
|
||||
|
||||
statusLine.append(" time: ");
|
||||
@@ -490,6 +410,7 @@ public class TerminalOutput implements ClientOutput {
|
||||
asb.append(statusLine.toString());
|
||||
lines.add(asb.toAttributedString());
|
||||
}
|
||||
}
|
||||
|
||||
private void addProjectLine(final List<AttributedString> lines, Project prj) {
|
||||
String str = prj.status != null ? prj.status : ":" + prj.id + ":<unknown>";
|
||||
|
@@ -51,14 +51,10 @@ import org.jboss.fuse.mvnd.common.DaemonStopEvent;
|
||||
import org.jboss.fuse.mvnd.common.Environment;
|
||||
import org.jboss.fuse.mvnd.common.Message;
|
||||
import org.jboss.fuse.mvnd.common.Message.BuildEvent;
|
||||
import org.jboss.fuse.mvnd.common.Message.BuildEvent.Type;
|
||||
import org.jboss.fuse.mvnd.common.Message.BuildException;
|
||||
import org.jboss.fuse.mvnd.common.Message.BuildMessage;
|
||||
import org.jboss.fuse.mvnd.common.Message.BuildRequest;
|
||||
import org.jboss.fuse.mvnd.common.Message.BuildStarted;
|
||||
import org.jboss.fuse.mvnd.common.Message.Display;
|
||||
import org.jboss.fuse.mvnd.common.Message.Prompt;
|
||||
import org.jboss.fuse.mvnd.common.Message.PromptResponse;
|
||||
import org.jboss.fuse.mvnd.daemon.DaemonExpiration.DaemonExpirationResult;
|
||||
import org.jboss.fuse.mvnd.daemon.DaemonExpiration.DaemonExpirationStrategy;
|
||||
import org.jboss.fuse.mvnd.logging.smart.AbstractLoggingSpy;
|
||||
@@ -521,29 +517,32 @@ public class Server implements AutoCloseable, Runnable {
|
||||
}
|
||||
|
||||
int getClassOrder(Message m) {
|
||||
if (m instanceof BuildRequest) {
|
||||
switch (m.getType()) {
|
||||
case Message.BUILD_REQUEST:
|
||||
return 0;
|
||||
} else if (m instanceof BuildStarted) {
|
||||
case Message.BUILD_STARTED:
|
||||
return 1;
|
||||
} else if (m instanceof Prompt || m instanceof PromptResponse || m instanceof Display) {
|
||||
case Message.PROMPT:
|
||||
case Message.PROMPT_RESPONSE:
|
||||
case Message.DISPLAY:
|
||||
return 2;
|
||||
} else if (m instanceof BuildEvent && ((BuildEvent) m).getType() == Type.ProjectStarted) {
|
||||
case Message.PROJECT_STARTED:
|
||||
return 3;
|
||||
} else if (m instanceof BuildEvent && ((BuildEvent) m).getType() == Type.MojoStarted) {
|
||||
case Message.MOJO_STARTED:
|
||||
return 4;
|
||||
} else if (m instanceof BuildMessage) {
|
||||
case Message.BUILD_MESSAGE:
|
||||
return 50;
|
||||
} else if (m instanceof BuildEvent && ((BuildEvent) m).getType() == Type.ProjectStopped) {
|
||||
case Message.PROJECT_STOPPED:
|
||||
return 95;
|
||||
} else if (m instanceof BuildEvent && ((BuildEvent) m).getType() == Type.BuildStopped) {
|
||||
case Message.BUILD_STOPPED:
|
||||
return 96;
|
||||
} else if (m instanceof BuildException) {
|
||||
case Message.BUILD_EXCEPTION:
|
||||
return 97;
|
||||
} else if (m == Message.STOP_SINGLETON) {
|
||||
case Message.STOP:
|
||||
return 99;
|
||||
} else if (m == Message.KEEP_ALIVE_SINGLETON) {
|
||||
case Message.KEEP_ALIVE:
|
||||
return 100;
|
||||
} else {
|
||||
default:
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
@@ -598,7 +597,7 @@ public class Server implements AutoCloseable, Runnable {
|
||||
}
|
||||
|
||||
public void finish() throws Exception {
|
||||
queue.add(new BuildEvent(Type.BuildStopped, "", ""));
|
||||
queue.add(Message.BUILD_STOPPED_SINGLETON);
|
||||
queue.add(Message.STOP_SINGLETON);
|
||||
}
|
||||
|
||||
@@ -615,17 +614,17 @@ public class Server implements AutoCloseable, Runnable {
|
||||
|
||||
@Override
|
||||
protected void onStartProject(String projectId, String display) {
|
||||
sendEvent(Type.ProjectStarted, projectId, display);
|
||||
queue.add(new BuildEvent(Message.PROJECT_STARTED, projectId, display));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStopProject(String projectId, String display) {
|
||||
sendEvent(Type.ProjectStopped, projectId, display);
|
||||
queue.add(new BuildEvent(Message.PROJECT_STOPPED, projectId, display));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStartMojo(String projectId, String display) {
|
||||
sendEvent(Type.MojoStarted, projectId, display);
|
||||
queue.add(new BuildEvent(Message.MOJO_STARTED, projectId, display));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -633,9 +632,5 @@ public class Server implements AutoCloseable, Runnable {
|
||||
queue.add(new BuildMessage(projectId, message));
|
||||
}
|
||||
|
||||
private void sendEvent(Type type, String projectId, String display) {
|
||||
queue.add(new BuildEvent(type, projectId, display));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -17,6 +17,8 @@ package org.jboss.fuse.mvnd.logging.smart;
|
||||
|
||||
import java.io.IOError;
|
||||
import org.apache.maven.execution.MavenSession;
|
||||
import org.jboss.fuse.mvnd.common.Message;
|
||||
import org.jboss.fuse.mvnd.common.Message.BuildEvent;
|
||||
import org.jboss.fuse.mvnd.common.logging.TerminalOutput;
|
||||
|
||||
public class MavenLoggingSpy extends AbstractLoggingSpy {
|
||||
@@ -30,10 +32,10 @@ public class MavenLoggingSpy extends AbstractLoggingSpy {
|
||||
protected void onStartSession(MavenSession session) {
|
||||
try {
|
||||
output = new TerminalOutput(null);
|
||||
output.startBuild(
|
||||
output.accept(new Message.BuildStarted(
|
||||
session.getTopLevelProject().getName(),
|
||||
session.getAllProjects().size(),
|
||||
session.getRequest().getDegreeOfConcurrency());
|
||||
session.getRequest().getDegreeOfConcurrency()));
|
||||
} catch (Exception e) {
|
||||
throw new IOError(e);
|
||||
}
|
||||
@@ -51,30 +53,24 @@ public class MavenLoggingSpy extends AbstractLoggingSpy {
|
||||
@Override
|
||||
protected void onStartProject(String projectId, String display) {
|
||||
super.onStartProject(projectId, display);
|
||||
output.projectStateChanged(projectId, display);
|
||||
output.accept(new BuildEvent(Message.PROJECT_STARTED, projectId, display));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStopProject(String projectId, String display) {
|
||||
output.projectFinished(projectId);
|
||||
output.accept(new BuildEvent(Message.PROJECT_STOPPED, projectId, display));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStartMojo(String projectId, String display) {
|
||||
super.onStartMojo(projectId, display);
|
||||
output.projectStateChanged(projectId, display);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStopMojo(String projectId, String display) {
|
||||
output.projectStateChanged(projectId, ":" + projectId);
|
||||
super.onStopMojo(projectId, display);
|
||||
output.accept(new BuildEvent(Message.MOJO_STARTED, projectId, display));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onProjectLog(String projectId, String message) {
|
||||
super.onProjectLog(projectId, message);
|
||||
output.accept(projectId, message);
|
||||
output.accept(Message.log(projectId, message));
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -63,11 +63,6 @@
|
||||
<artifactId>junit-jupiter</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-model</artifactId>
|
||||
|
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 the original author or authors.
|
||||
*
|
||||
* Licensed 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.jboss.fuse.mvnd.assertj;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import org.assertj.core.api.Condition;
|
||||
|
||||
/**
|
||||
* An AssertJ {@link Condition} to assert that each item of a collection of expected items is equal to some item in
|
||||
* a list of strings exactly once in the order given by the expected items collection. The input list may contain other
|
||||
* non-matching items.
|
||||
*
|
||||
* @param <T> the type of the tested {@link List}.
|
||||
*/
|
||||
public class EqualsInOrderAmongOthers<T extends List<? extends String>> extends Condition<T> {
|
||||
|
||||
public EqualsInOrderAmongOthers(String... expectedItems) {
|
||||
this(Stream.of(expectedItems).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
public EqualsInOrderAmongOthers(final Collection<String> expectedItems) {
|
||||
super(
|
||||
messages -> messages.stream()
|
||||
/* map each message to the matching pattern or null of none matches */
|
||||
.map(m -> expectedItems.stream()
|
||||
.filter(expected -> expected.equals(m))
|
||||
.findFirst()
|
||||
.orElse(null))
|
||||
.filter(pat -> pat != null) /* remove null patterns */
|
||||
.collect(Collectors.toList())
|
||||
/* if the mapped patterns equal the input patterns then each pattern matched exactly once */
|
||||
.equals(expectedItems),
|
||||
"Match in order: " + expectedItems.stream().collect(Collectors.joining(", ")),
|
||||
expectedItems);
|
||||
}
|
||||
|
||||
}
|
@@ -22,6 +22,8 @@ import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import org.assertj.core.api.Condition;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* An AssertJ {@link Condition} to assert that each item of a collection of regular expressions matches some item in
|
||||
@@ -32,22 +34,36 @@ import org.assertj.core.api.Condition;
|
||||
*/
|
||||
public class MatchInOrderAmongOthers<T extends List<? extends String>> extends Condition<T> {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(MatchInOrderAmongOthers.class);
|
||||
|
||||
public MatchInOrderAmongOthers(String... expectedItems) {
|
||||
this(Stream.of(expectedItems).map(Pattern::compile).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
public MatchInOrderAmongOthers(final Collection<Pattern> patterns) {
|
||||
super(
|
||||
messages -> messages.stream()
|
||||
messages -> {
|
||||
final List<Pattern> matchingPatterns = messages.stream()
|
||||
/* map each message to the matching pattern or null of none matches */
|
||||
.map(m -> patterns.stream()
|
||||
.filter(pat -> pat.matcher(m).find())
|
||||
.findFirst()
|
||||
.orElse(null))
|
||||
.filter(Objects::nonNull) /* remove null patterns */
|
||||
.collect(Collectors.toList())
|
||||
.collect(Collectors.toList());
|
||||
final boolean result = matchingPatterns.equals(patterns);
|
||||
if (!result) {
|
||||
LOG.warn("Actually matched:\n"
|
||||
+ matchingPatterns.stream().map(p -> " " + p.pattern()).collect(Collectors.joining("\n")));
|
||||
LOG.warn("Did not match:\n"
|
||||
+ patterns.stream()
|
||||
.filter(p -> !matchingPatterns.contains(p))
|
||||
.map(p -> " " + p.pattern())
|
||||
.collect(Collectors.joining("\n")));
|
||||
}
|
||||
/* if the mapped patterns equal the input patterns then each pattern matched exactly once */
|
||||
.equals(patterns),
|
||||
return result;
|
||||
},
|
||||
"Match in order: " + patterns.stream().map(Pattern::pattern).collect(Collectors.joining(", ")),
|
||||
patterns);
|
||||
}
|
||||
|
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2019 the original author or authors.
|
||||
*
|
||||
* Licensed 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.jboss.fuse.mvnd.assertj;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.jboss.fuse.mvnd.common.Message;
|
||||
import org.jboss.fuse.mvnd.common.logging.ClientOutput;
|
||||
|
||||
public class TestClientOutput implements ClientOutput {
|
||||
private final List<Message> messages = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void close() throws Exception {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(Message message) {
|
||||
messages.add(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(List<Message> messages) {
|
||||
for (Message message : messages) {
|
||||
accept(message);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void describeTerminal() {
|
||||
accept(Message.log("Test terminal"));
|
||||
}
|
||||
|
||||
public List<Message> getMessages() {
|
||||
return messages;
|
||||
}
|
||||
|
||||
public void assertContainsMatchingSubsequence(String... patterns) {
|
||||
Assertions.assertThat(messagesToString()).is(new MatchInOrderAmongOthers<>(patterns));
|
||||
}
|
||||
|
||||
public List<String> messagesToString() {
|
||||
return messages.stream().map(m -> m.toString()).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
}
|
@@ -21,14 +21,13 @@ import java.nio.file.Path;
|
||||
import java.util.stream.Stream;
|
||||
import javax.inject.Inject;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.jboss.fuse.mvnd.assertj.TestClientOutput;
|
||||
import org.jboss.fuse.mvnd.client.Client;
|
||||
import org.jboss.fuse.mvnd.client.DaemonParameters;
|
||||
import org.jboss.fuse.mvnd.common.DaemonException;
|
||||
import org.jboss.fuse.mvnd.common.logging.ClientOutput;
|
||||
import org.jboss.fuse.mvnd.junit.MvndTest;
|
||||
import org.jboss.fuse.mvnd.junit.TestUtils;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
@@ -58,7 +57,7 @@ public class DaemonCrashTest {
|
||||
};
|
||||
Stream.of(installedJars).forEach(jar -> Assertions.assertThat(jar).doesNotExist());
|
||||
|
||||
final ClientOutput output = Mockito.mock(ClientOutput.class);
|
||||
final TestClientOutput output = new TestClientOutput();
|
||||
assertThrows(DaemonException.StaleAddressException.class,
|
||||
() -> client.execute(output, "clean", "install", "-e", "-Dmvnd.log.level=DEBUG").assertFailure());
|
||||
}
|
||||
|
@@ -18,14 +18,13 @@ package org.jboss.fuse.mvnd.it;
|
||||
import java.io.IOException;
|
||||
import javax.inject.Inject;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.jboss.fuse.mvnd.assertj.TestClientOutput;
|
||||
import org.jboss.fuse.mvnd.client.Client;
|
||||
import org.jboss.fuse.mvnd.client.DaemonParameters;
|
||||
import org.jboss.fuse.mvnd.common.DaemonInfo;
|
||||
import org.jboss.fuse.mvnd.common.logging.ClientOutput;
|
||||
import org.jboss.fuse.mvnd.junit.MvndNativeTest;
|
||||
import org.jboss.fuse.mvnd.junit.TestRegistry;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
@@ -46,7 +45,7 @@ public class ExtensionsNativeIT {
|
||||
registry.killAll();
|
||||
Assertions.assertThat(registry.getAll().size()).isEqualTo(0);
|
||||
|
||||
final ClientOutput o = Mockito.mock(ClientOutput.class);
|
||||
final TestClientOutput o = new TestClientOutput();
|
||||
client.execute(o, "-v").assertSuccess();
|
||||
Assertions.assertThat(registry.getAll().size()).isEqualTo(1);
|
||||
DaemonInfo daemon = registry.getAll().iterator().next();
|
||||
|
@@ -17,13 +17,14 @@ package org.jboss.fuse.mvnd.it;
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.inject.Inject;
|
||||
import org.jboss.fuse.mvnd.assertj.TestClientOutput;
|
||||
import org.jboss.fuse.mvnd.client.Client;
|
||||
import org.jboss.fuse.mvnd.client.DaemonParameters;
|
||||
import org.jboss.fuse.mvnd.common.logging.ClientOutput;
|
||||
import org.jboss.fuse.mvnd.common.Message;
|
||||
import org.jboss.fuse.mvnd.common.Message.Prompt;
|
||||
import org.jboss.fuse.mvnd.junit.MvndTest;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
@MvndTest(projectDir = "src/test/projects/single-module")
|
||||
public class InteractiveTest {
|
||||
@@ -39,9 +40,15 @@ public class InteractiveTest {
|
||||
final String version = MvndTestUtil.version(parameters.multiModuleProjectDirectory().resolve("pom.xml"));
|
||||
Assertions.assertEquals("0.0.1-SNAPSHOT", version);
|
||||
|
||||
final ClientOutput o = Mockito.mock(ClientOutput.class);
|
||||
Mockito.when(o.prompt("single-module", "Enter the new version to set 0.0.1-SNAPSHOT: ", false))
|
||||
.thenReturn("0.1.0-SNAPSHOT");
|
||||
final TestClientOutput o = new TestClientOutput() {
|
||||
@Override
|
||||
public void accept(Message m) {
|
||||
if (m instanceof Prompt) {
|
||||
((Prompt) m).getCallback().accept("0.1.0-SNAPSHOT");
|
||||
}
|
||||
super.accept(m);
|
||||
}
|
||||
};
|
||||
client.execute(o, "versions:set").assertSuccess();
|
||||
|
||||
final String newVersion = MvndTestUtil.version(parameters.multiModuleProjectDirectory().resolve("pom.xml"));
|
||||
|
@@ -23,12 +23,11 @@ import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.inject.Inject;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.jboss.fuse.mvnd.assertj.TestClientOutput;
|
||||
import org.jboss.fuse.mvnd.client.Client;
|
||||
import org.jboss.fuse.mvnd.client.DaemonParameters;
|
||||
import org.jboss.fuse.mvnd.common.logging.ClientOutput;
|
||||
import org.jboss.fuse.mvnd.junit.MvndNativeTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
@MvndNativeTest(projectDir = "src/test/projects/invoker")
|
||||
public class InvokerNativeIT {
|
||||
@@ -55,7 +54,7 @@ public class InvokerNativeIT {
|
||||
throw new RuntimeException("Could not delete " + helloPath);
|
||||
}
|
||||
|
||||
final ClientOutput output = Mockito.mock(ClientOutput.class);
|
||||
final TestClientOutput output = new TestClientOutput();
|
||||
client.execute(output, "clean", "verify", "-e", "-Dmvnd.log.level=DEBUG").assertSuccess();
|
||||
|
||||
Assertions.assertThat(helloPath).exists();
|
||||
|
@@ -22,13 +22,12 @@ import java.nio.file.Path;
|
||||
import java.util.stream.Stream;
|
||||
import javax.inject.Inject;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.jboss.fuse.mvnd.assertj.TestClientOutput;
|
||||
import org.jboss.fuse.mvnd.client.Client;
|
||||
import org.jboss.fuse.mvnd.client.DaemonParameters;
|
||||
import org.jboss.fuse.mvnd.common.logging.ClientOutput;
|
||||
import org.jboss.fuse.mvnd.junit.MvndNativeTest;
|
||||
import org.jboss.fuse.mvnd.junit.TestUtils;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
@MvndNativeTest(projectDir = "src/test/projects/module-and-plugin")
|
||||
public class ModuleAndPluginNativeIT {
|
||||
@@ -61,7 +60,7 @@ public class ModuleAndPluginNativeIT {
|
||||
|
||||
/* Build #1: with "Hello" output to target/hello.txt */
|
||||
{
|
||||
final ClientOutput output = Mockito.mock(ClientOutput.class);
|
||||
final TestClientOutput output = new TestClientOutput();
|
||||
client.execute(output, "clean", "install", "-e", "-Dmvnd.log.level=DEBUG", "-Dhello.property=Hello1")
|
||||
.assertSuccess();
|
||||
|
||||
@@ -78,7 +77,7 @@ public class ModuleAndPluginNativeIT {
|
||||
.resolve("plugin/src/main/java/org/jboss/fuse/mvnd/test/module/plugin/mojo/HelloMojo.java");
|
||||
TestUtils.replace(mojoPath, "\"Hello\".getBytes", "\"Hi\".getBytes");
|
||||
|
||||
final ClientOutput output = Mockito.mock(ClientOutput.class);
|
||||
final TestClientOutput output = new TestClientOutput();
|
||||
client.execute(output,
|
||||
"clean",
|
||||
"install", "-e", "-Dmvnd.log.level=DEBUG", "-Dhello.property=Hello2").assertSuccess();
|
||||
|
@@ -18,21 +18,22 @@ package org.jboss.fuse.mvnd.it;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import javax.inject.Inject;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.jboss.fuse.mvnd.assertj.EqualsInOrderAmongOthers;
|
||||
import org.jboss.fuse.mvnd.assertj.MatchInOrderAmongOthers;
|
||||
import org.jboss.fuse.mvnd.assertj.TestClientOutput;
|
||||
import org.jboss.fuse.mvnd.client.Client;
|
||||
import org.jboss.fuse.mvnd.client.DaemonParameters;
|
||||
import org.jboss.fuse.mvnd.common.logging.ClientOutput;
|
||||
import org.jboss.fuse.mvnd.common.Message;
|
||||
import org.jboss.fuse.mvnd.common.Message.BuildEvent;
|
||||
import org.jboss.fuse.mvnd.common.Message.BuildMessage;
|
||||
import org.jboss.fuse.mvnd.junit.MvndTest;
|
||||
import org.jboss.fuse.mvnd.junit.TestUtils;
|
||||
import org.junit.jupiter.api.Test;
|
||||
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,12 +70,16 @@ public class MultiModuleTest {
|
||||
};
|
||||
Stream.of(installedJars).forEach(jar -> Assertions.assertThat(jar).doesNotExist());
|
||||
|
||||
final ClientOutput output = Mockito.mock(ClientOutput.class);
|
||||
final TestClientOutput output = new TestClientOutput();
|
||||
client.execute(output, "clean", "install", "-e").assertSuccess();
|
||||
|
||||
final ArgumentCaptor<String> logMessage = ArgumentCaptor.forClass(String.class);
|
||||
Mockito.verify(output, Mockito.atLeast(1)).accept(any(), logMessage.capture());
|
||||
Assertions.assertThat(logMessage.getAllValues())
|
||||
{
|
||||
final List<String> filteredMessages = output.getMessages().stream()
|
||||
.filter(m -> m.getType() == Message.BUILD_MESSAGE)
|
||||
.map(m -> ((BuildMessage) m).getMessage())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
Assertions.assertThat(filteredMessages)
|
||||
.satisfiesAnyOf( /* Two orderings are possible */
|
||||
messages -> Assertions.assertThat(messages)
|
||||
.is(new MatchInOrderAmongOthers<>(
|
||||
@@ -87,26 +92,30 @@ public class MultiModuleTest {
|
||||
"SUCCESS build of project org.jboss.fuse.mvnd.test.multi-module:multi-module$",
|
||||
"SUCCESS build of project org.jboss.fuse.mvnd.test.multi-module:multi-module-api",
|
||||
"SUCCESS build of project org.jboss.fuse.mvnd.test.multi-module:multi-module-hi",
|
||||
"SUCCESS build of project org.jboss.fuse.mvnd.test.multi-module:multi-module-hello"))
|
||||
"SUCCESS build of project org.jboss.fuse.mvnd.test.multi-module:multi-module-hello")));
|
||||
}
|
||||
|
||||
);
|
||||
{
|
||||
final List<String> filteredMessages = output.getMessages().stream()
|
||||
.filter(m -> m.getType() == Message.PROJECT_STARTED)
|
||||
.map(m -> ((BuildEvent) m).getProjectId())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
final ArgumentCaptor<String> projectFinished = ArgumentCaptor.forClass(String.class);
|
||||
Mockito.verify(output, Mockito.atLeast(1)).projectFinished(projectFinished.capture());
|
||||
Assertions.assertThat(projectFinished.getAllValues())
|
||||
Assertions.assertThat(filteredMessages)
|
||||
.satisfiesAnyOf( /* Two orderings are possible */
|
||||
messages -> Assertions.assertThat(messages)
|
||||
.is(new EqualsInOrderAmongOthers<>(
|
||||
.isEqualTo(Arrays.asList(
|
||||
"multi-module",
|
||||
"multi-module-api",
|
||||
"multi-module-hello",
|
||||
"multi-module-hi")),
|
||||
messages -> Assertions.assertThat(messages)
|
||||
.is(new EqualsInOrderAmongOthers<>(
|
||||
.isEqualTo(Arrays.asList(
|
||||
"multi-module",
|
||||
"multi-module-api",
|
||||
"multi-module-hi",
|
||||
"multi-module-hello")));
|
||||
}
|
||||
|
||||
/* Make sure HelloTest and HiTest have created the files they were supposed to create */
|
||||
Stream.of(helloFilePaths).forEach(path -> Assertions.assertThat(path).exists());
|
||||
|
@@ -18,19 +18,19 @@ package org.jboss.fuse.mvnd.it;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.inject.Inject;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.jboss.fuse.mvnd.assertj.MatchInOrderAmongOthers;
|
||||
import org.jboss.fuse.mvnd.assertj.TestClientOutput;
|
||||
import org.jboss.fuse.mvnd.client.Client;
|
||||
import org.jboss.fuse.mvnd.client.DaemonParameters;
|
||||
import org.jboss.fuse.mvnd.common.logging.ClientOutput;
|
||||
import org.jboss.fuse.mvnd.common.Message;
|
||||
import org.jboss.fuse.mvnd.junit.MvndNativeTest;
|
||||
import org.jboss.fuse.mvnd.junit.TestUtils;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.InOrder;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
|
||||
@MvndNativeTest(projectDir = "src/test/projects/single-module")
|
||||
public class SingleModuleNativeIT {
|
||||
@@ -54,18 +54,23 @@ public class SingleModuleNativeIT {
|
||||
"org/jboss/fuse/mvnd/test/single-module/single-module/0.0.1-SNAPSHOT/single-module-0.0.1-SNAPSHOT.jar");
|
||||
Assertions.assertThat(installedJar).doesNotExist();
|
||||
|
||||
final ClientOutput o = Mockito.mock(ClientOutput.class);
|
||||
final TestClientOutput o = new TestClientOutput();
|
||||
client.execute(o, "clean", "install", "-e").assertSuccess();
|
||||
final Properties props = MvndTestUtil.properties(parameters.multiModuleProjectDirectory().resolve("pom.xml"));
|
||||
|
||||
final InOrder inOrder = Mockito.inOrder(o);
|
||||
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("BUILD SUCCESS"));
|
||||
final List<String> messages = o.getMessages().stream()
|
||||
.filter(m -> m.getType() != Message.MOJO_STARTED)
|
||||
.map(m -> m.toString())
|
||||
.collect(Collectors.toList());
|
||||
Assertions.assertThat(messages)
|
||||
.is(new MatchInOrderAmongOthers<>(
|
||||
"Building single-module",
|
||||
MvndTestUtil.plugin(props, "maven-clean-plugin") + ":clean",
|
||||
MvndTestUtil.plugin(props, "maven-compiler-plugin") + ":compile",
|
||||
MvndTestUtil.plugin(props, "maven-compiler-plugin") + ":testCompile",
|
||||
MvndTestUtil.plugin(props, "maven-surefire-plugin") + ":test",
|
||||
MvndTestUtil.plugin(props, "maven-install-plugin") + ":install",
|
||||
"BUILD SUCCESS"));
|
||||
|
||||
assertJVM(o, props);
|
||||
|
||||
@@ -76,7 +81,7 @@ public class SingleModuleNativeIT {
|
||||
|
||||
}
|
||||
|
||||
protected void assertJVM(ClientOutput o, Properties props) {
|
||||
/* implemented in the subclass*/
|
||||
protected void assertJVM(TestClientOutput o, Properties props) {
|
||||
/* implemented in the subclass */
|
||||
}
|
||||
}
|
||||
|
@@ -15,50 +15,41 @@
|
||||
*/
|
||||
package org.jboss.fuse.mvnd.it;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import org.jboss.fuse.mvnd.common.logging.ClientOutput;
|
||||
import java.util.stream.Collectors;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.jboss.fuse.mvnd.assertj.MatchInOrderAmongOthers;
|
||||
import org.jboss.fuse.mvnd.assertj.TestClientOutput;
|
||||
import org.jboss.fuse.mvnd.common.Message;
|
||||
import org.jboss.fuse.mvnd.junit.MvndTest;
|
||||
import org.mockito.InOrder;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
@MvndTest(projectDir = "src/test/projects/single-module")
|
||||
public class SingleModuleTest extends SingleModuleNativeIT {
|
||||
|
||||
protected void assertJVM(ClientOutput output, Properties props) {
|
||||
final InOrder inOrder = Mockito.inOrder(output);
|
||||
inOrder.verify(output).projectStateChanged(
|
||||
"single-module",
|
||||
":single-module");
|
||||
inOrder.verify(output).projectStateChanged(
|
||||
"single-module",
|
||||
":single-module:org.apache.maven.plugins:" + MvndTestUtil.plugin(props, "maven-clean-plugin")
|
||||
+ ":clean {execution: default-clean}");
|
||||
inOrder.verify(output).projectStateChanged(
|
||||
"single-module",
|
||||
":single-module:org.apache.maven.plugins:" + MvndTestUtil.plugin(props, "maven-resources-plugin")
|
||||
+ ":resources {execution: default-resources}");
|
||||
inOrder.verify(output).projectStateChanged(
|
||||
"single-module",
|
||||
":single-module:org.apache.maven.plugins:" + MvndTestUtil.plugin(props, "maven-compiler-plugin")
|
||||
+ ":compile {execution: default-compile}");
|
||||
inOrder.verify(output).projectStateChanged(
|
||||
"single-module",
|
||||
":single-module:org.apache.maven.plugins:" + MvndTestUtil.plugin(props, "maven-resources-plugin")
|
||||
+ ":testResources {execution: default-testResources}");
|
||||
inOrder.verify(output).projectStateChanged(
|
||||
"single-module",
|
||||
":single-module:org.apache.maven.plugins:" + MvndTestUtil.plugin(props, "maven-compiler-plugin")
|
||||
+ ":testCompile {execution: default-testCompile}");
|
||||
inOrder.verify(output).projectStateChanged(
|
||||
"single-module",
|
||||
":single-module:org.apache.maven.plugins:" + MvndTestUtil.plugin(props, "maven-surefire-plugin")
|
||||
+ ":test {execution: default-test}");
|
||||
inOrder.verify(output).projectStateChanged(
|
||||
"single-module",
|
||||
":single-module:org.apache.maven.plugins:" + MvndTestUtil.plugin(props, "maven-install-plugin")
|
||||
+ ":install {execution: default-install}");
|
||||
protected void assertJVM(TestClientOutput o, Properties props) {
|
||||
final List<String> filteredMessages = o.getMessages().stream()
|
||||
.filter(m -> m.getType() == Message.MOJO_STARTED)
|
||||
.map(m -> m.toString())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
Assertions.assertThat(filteredMessages)
|
||||
.is(new MatchInOrderAmongOthers<>(
|
||||
"\\Q:single-module:org.apache.maven.plugins:" + MvndTestUtil.plugin(props, "maven-clean-plugin")
|
||||
+ ":clean {execution: default-clean}\\E",
|
||||
"\\Q:single-module:org.apache.maven.plugins:" + MvndTestUtil.plugin(props, "maven-resources-plugin")
|
||||
+ ":resources {execution: default-resources}\\E",
|
||||
"\\Q:single-module:org.apache.maven.plugins:" + MvndTestUtil.plugin(props, "maven-compiler-plugin")
|
||||
+ ":compile {execution: default-compile}\\E",
|
||||
"\\Q:single-module:org.apache.maven.plugins:" + MvndTestUtil.plugin(props, "maven-resources-plugin")
|
||||
+ ":testResources {execution: default-testResources}\\E",
|
||||
"\\Q:single-module:org.apache.maven.plugins:" + MvndTestUtil.plugin(props, "maven-compiler-plugin")
|
||||
+ ":testCompile {execution: default-testCompile}\\E",
|
||||
"\\Q:single-module:org.apache.maven.plugins:" + MvndTestUtil.plugin(props, "maven-surefire-plugin")
|
||||
+ ":test {execution: default-test}\\E",
|
||||
"\\Q:single-module:org.apache.maven.plugins:" + MvndTestUtil.plugin(props, "maven-install-plugin")
|
||||
+ ":install {execution: default-install}\\E"));
|
||||
|
||||
inOrder.verify(output).projectFinished("single-module");
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -19,17 +19,12 @@ import java.io.IOException;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.inject.Inject;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.jboss.fuse.mvnd.assertj.MatchInOrderAmongOthers;
|
||||
import org.jboss.fuse.mvnd.assertj.TestClientOutput;
|
||||
import org.jboss.fuse.mvnd.client.Client;
|
||||
import org.jboss.fuse.mvnd.common.DaemonInfo;
|
||||
import org.jboss.fuse.mvnd.common.logging.ClientOutput;
|
||||
import org.jboss.fuse.mvnd.junit.MvndTest;
|
||||
import org.jboss.fuse.mvnd.junit.TestRegistry;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
|
||||
@MvndTest(projectDir = "src/test/projects/single-module")
|
||||
public class StopStatusTest {
|
||||
@@ -46,41 +41,36 @@ public class StopStatusTest {
|
||||
/* The registry should be empty before we run anything */
|
||||
Assertions.assertThat(registry.getAll()).isEmpty();
|
||||
|
||||
client.execute(Mockito.mock(ClientOutput.class), "clean").assertSuccess();
|
||||
client.execute(new TestClientOutput(), "clean").assertSuccess();
|
||||
/* There should be exactly one item in the registry after the first build */
|
||||
Assertions.assertThat(registry.getAll().size()).isEqualTo(1);
|
||||
|
||||
final DaemonInfo d = registry.getAll().get(0);
|
||||
{
|
||||
/* The output of --status must be consistent with the registry */
|
||||
final ClientOutput output = Mockito.mock(ClientOutput.class);
|
||||
final TestClientOutput output = new TestClientOutput();
|
||||
client.execute(output, "--status").assertSuccess();
|
||||
final ArgumentCaptor<String> logMessage = ArgumentCaptor.forClass(String.class);
|
||||
Mockito.verify(output, Mockito.atLeast(1)).accept(any(), logMessage.capture());
|
||||
Assertions.assertThat(logMessage.getAllValues())
|
||||
.is(new MatchInOrderAmongOthers<>(
|
||||
d.getUid() + " +" + d.getPid() + " +" + d.getAddress()));
|
||||
|
||||
output.assertContainsMatchingSubsequence(d.getUid() + " +" + d.getPid() + " +" + d.getAddress());
|
||||
}
|
||||
/* Wait, till the instance becomes idle */
|
||||
registry.awaitIdle(d.getUid());
|
||||
|
||||
client.execute(Mockito.mock(ClientOutput.class), "clean").assertSuccess();
|
||||
client.execute(new TestClientOutput(), "clean").assertSuccess();
|
||||
/* There should still be exactly one item in the registry after the second build */
|
||||
Assertions.assertThat(registry.getAll().size()).isEqualTo(1);
|
||||
|
||||
client.execute(Mockito.mock(ClientOutput.class), "--stop").assertSuccess();
|
||||
client.execute(new TestClientOutput(), "--stop").assertSuccess();
|
||||
/* No items in the registry after we have killed all daemons */
|
||||
Assertions.assertThat(registry.getAll()).isEmpty();
|
||||
|
||||
{
|
||||
/* After --stop, the output of --status may not contain the UID we have seen before */
|
||||
final ClientOutput output = Mockito.mock(ClientOutput.class);
|
||||
final TestClientOutput output = new TestClientOutput();
|
||||
client.execute(output, "--status").assertSuccess();
|
||||
final ArgumentCaptor<String> logMessage = ArgumentCaptor.forClass(String.class);
|
||||
Mockito.verify(output, Mockito.atLeast(1)).accept(any(), logMessage.capture());
|
||||
|
||||
Assertions.assertThat(
|
||||
logMessage.getAllValues().stream()
|
||||
output.messagesToString().stream()
|
||||
.filter(m -> m.contains(d.getUid()))
|
||||
.collect(Collectors.toList()))
|
||||
.isEmpty();
|
||||
|
@@ -20,16 +20,15 @@ import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import javax.inject.Inject;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.jboss.fuse.mvnd.assertj.TestClientOutput;
|
||||
import org.jboss.fuse.mvnd.client.Client;
|
||||
import org.jboss.fuse.mvnd.common.DaemonInfo;
|
||||
import org.jboss.fuse.mvnd.common.logging.ClientOutput;
|
||||
import org.jboss.fuse.mvnd.junit.ClientFactory;
|
||||
import org.jboss.fuse.mvnd.junit.MvndNativeTest;
|
||||
import org.jboss.fuse.mvnd.junit.TestParameters;
|
||||
import org.jboss.fuse.mvnd.junit.TestRegistry;
|
||||
import org.jboss.fuse.mvnd.junit.TestUtils;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
@MvndNativeTest(projectDir = "src/test/projects/upgrades-in-bom")
|
||||
public class UpgradesInBomNativeIT {
|
||||
@@ -48,7 +47,7 @@ public class UpgradesInBomNativeIT {
|
||||
/* Install the dependencies */
|
||||
for (String artifactDir : Arrays.asList("project/hello-0.0.1", "project/hello-0.0.2-SNAPSHOT")) {
|
||||
final Client cl = clientFactory.newClient(parameters.cd(parameters.getTestDir().resolve(artifactDir)));
|
||||
final ClientOutput output = Mockito.mock(ClientOutput.class);
|
||||
final TestClientOutput output = new TestClientOutput();
|
||||
cl.execute(output, "clean", "install", "-e").assertSuccess();
|
||||
registry.killAll();
|
||||
}
|
||||
@@ -58,7 +57,7 @@ public class UpgradesInBomNativeIT {
|
||||
final Path parentDir = parameters.getTestDir().resolve("project/parent");
|
||||
final Client cl = clientFactory.newClient(parameters.cd(parentDir));
|
||||
{
|
||||
final ClientOutput output = Mockito.mock(ClientOutput.class);
|
||||
final TestClientOutput output = new TestClientOutput();
|
||||
cl.execute(output, "clean", "install", "-e").assertSuccess();
|
||||
}
|
||||
Assertions.assertThat(registry.getAll().size()).isEqualTo(1);
|
||||
@@ -76,7 +75,7 @@ public class UpgradesInBomNativeIT {
|
||||
.resolve("module/src/main/java/org/jboss/fuse/mvnd/test/upgrades/bom/module/UseHello.java");
|
||||
TestUtils.replace(useHelloPath, "new Hello().sayHello()", "new Hello().sayWisdom()");
|
||||
{
|
||||
final ClientOutput output = Mockito.mock(ClientOutput.class);
|
||||
final TestClientOutput output = new TestClientOutput();
|
||||
cl.execute(output, "clean", "install", "-e").assertSuccess();
|
||||
}
|
||||
Assertions.assertThat(registry.getAll().size()).isEqualTo(1);
|
||||
|
@@ -17,18 +17,12 @@ package org.jboss.fuse.mvnd.it;
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.inject.Inject;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.jboss.fuse.mvnd.assertj.MatchInOrderAmongOthers;
|
||||
import org.jboss.fuse.mvnd.assertj.TestClientOutput;
|
||||
import org.jboss.fuse.mvnd.client.Client;
|
||||
import org.jboss.fuse.mvnd.client.DaemonParameters;
|
||||
import org.jboss.fuse.mvnd.common.logging.ClientOutput;
|
||||
import org.jboss.fuse.mvnd.junit.MvndNativeTest;
|
||||
import org.jboss.fuse.mvnd.junit.MvndTestExtension;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
|
||||
@MvndNativeTest(projectDir = MvndTestExtension.TEMP_EXTERNAL)
|
||||
public class VersionNativeIT {
|
||||
@@ -41,20 +35,16 @@ public class VersionNativeIT {
|
||||
|
||||
@Test
|
||||
void version() throws IOException, InterruptedException {
|
||||
final ClientOutput output = Mockito.mock(ClientOutput.class);
|
||||
final TestClientOutput output = new TestClientOutput();
|
||||
|
||||
client.execute(output, "-v").assertSuccess();
|
||||
|
||||
final ArgumentCaptor<String> logMessage = ArgumentCaptor.forClass(String.class);
|
||||
Mockito.verify(output, Mockito.atLeast(1)).accept(any(), logMessage.capture());
|
||||
|
||||
Assertions.assertThat(logMessage.getAllValues())
|
||||
.is(new MatchInOrderAmongOthers<>(
|
||||
output.assertContainsMatchingSubsequence(
|
||||
"\\QMaven Daemon "
|
||||
+ System.getProperty("project.version")
|
||||
+ "-" + System.getProperty("os.detected.name")
|
||||
+ "-" + System.getProperty("os.detected.arch")
|
||||
+ "\\E",
|
||||
"\\QMaven home: " + parameters.mvndHome() + "\\E"));
|
||||
"\\QMaven home: " + parameters.mvndHome() + "\\E");
|
||||
}
|
||||
}
|
||||
|
@@ -25,6 +25,7 @@ import org.jboss.fuse.mvnd.client.Client;
|
||||
import org.jboss.fuse.mvnd.client.DaemonParameters;
|
||||
import org.jboss.fuse.mvnd.client.ExecutionResult;
|
||||
import org.jboss.fuse.mvnd.common.Environment;
|
||||
import org.jboss.fuse.mvnd.common.Message;
|
||||
import org.jboss.fuse.mvnd.common.OsUtils.CommandProcess;
|
||||
import org.jboss.fuse.mvnd.common.logging.ClientOutput;
|
||||
|
||||
@@ -82,7 +83,7 @@ public class NativeTestClient implements Client {
|
||||
env.put("JAVA_HOME", System.getProperty("java.home"));
|
||||
}
|
||||
final String cmdString = String.join(" ", cmd);
|
||||
output.accept(null, "Executing " + cmdString);
|
||||
output.accept(Message.log("Executing " + cmdString));
|
||||
|
||||
final List<String> log = new ArrayList<>();
|
||||
final Consumer<String> loggingConsumer = s -> {
|
||||
@@ -91,7 +92,7 @@ public class NativeTestClient implements Client {
|
||||
}
|
||||
};
|
||||
try (CommandProcess process = new CommandProcess(builder.start(),
|
||||
loggingConsumer.andThen(s -> output.accept(null, s)))) {
|
||||
loggingConsumer.andThen(s -> output.accept(Message.log(s))))) {
|
||||
final int exitCode = process.waitFor(timeoutMs);
|
||||
return new Result(args, exitCode, log);
|
||||
} catch (IOException e) {
|
||||
|
32
integration-tests/src/test/resources/simplelogger.properties
Normal file
32
integration-tests/src/test/resources/simplelogger.properties
Normal file
@@ -0,0 +1,32 @@
|
||||
# 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.
|
||||
|
||||
org.slf4j.simpleLogger.defaultLogLevel=info
|
||||
org.slf4j.simpleLogger.showDateTime=false
|
||||
org.slf4j.simpleLogger.showThreadName=false
|
||||
org.slf4j.simpleLogger.showLogName=false
|
||||
org.slf4j.simpleLogger.logFile=System.out
|
||||
org.slf4j.simpleLogger.cacheOutputStream=true
|
||||
org.slf4j.simpleLogger.levelInBrackets=true
|
||||
org.slf4j.simpleLogger.log.Sisu=info
|
||||
org.slf4j.simpleLogger.warnLevelString=WARNING
|
||||
|
||||
# MNG-6181: mvn -X also prints all debug logging from HttpClient
|
||||
# Be aware that the shaded packages are used
|
||||
# org.apache.http -> org.apache.maven.wagon.providers.http.httpclient
|
||||
org.slf4j.simpleLogger.log.org.apache.maven.wagon.providers.http.httpclient=off
|
||||
org.slf4j.simpleLogger.log.org.apache.maven.wagon.providers.http.httpclient.wire=off
|
7
pom.xml
7
pom.xml
@@ -44,7 +44,6 @@
|
||||
<junit.jupiter.version>5.6.0</junit.jupiter.version>
|
||||
<logback.version>1.2.3</logback.version>
|
||||
<maven.version>3.6.3</maven.version>
|
||||
<mockito.version>3.3.3</mockito.version>
|
||||
<slf4j.version>1.7.29</slf4j.version>
|
||||
<takari-local-repository.version>0.11.2</takari-local-repository.version>
|
||||
|
||||
@@ -192,12 +191,6 @@
|
||||
<version>${jline.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<version>${mockito.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>log4j-over-slf4j</artifactId>
|
||||
|
Reference in New Issue
Block a user