From: Maria Guseva Date: Wed, 28 Sep 2016 15:32:51 +0000 (+0300) Subject: [RELEASE] DA 2.3.16 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=bc01dbb53fc24614edef1dc5dc55f3aab0943eac;p=sdk%2Ftools%2Fdynamic-analyzer.git [RELEASE] DA 2.3.16 - Improve Memory Statistics table and Heap Allocation charts UX: - change data model of Statistics table to tree, - add agreggated data for libraries under 'Total' entry, - add cross-focus from table to Heap Allocation charts and vice versa, - rearrange columns in more sensible order, - fixed different names for unknown libraries in charts and table, - add charts sorting according to table, - improve rendering of starting points on charts - Timeline markers are numbered now - Introduce new Memory Range Analysis view - Introduce new Persistent Memory charts - Add cross-focus from Persisent Allocations table to chart and vice versa - Adjust size of Address column in Callstack view - Adjust Search Dialog controls sizes and positions - Fix shown zeros of System memory in Memory Details table - Fix Screenshot feature preferences to be able to be turned off totally - Change dotted line border of Process sub-chart - Redesign DA CLI process management - Refactor TargetData class - Redesign TargetDataTest and SettingDataManagerTest to match FlatFeature functionality - Fix 45 FindBugs warnings - Fix JIRA defects: SPTSDKUX-2103, SPTSDKUX-2155, SPTSDKUX-2167 Change-Id: Id8d5ea89fb25f620c17d2fbc7a8a85cdf8940afe --- diff --git a/org.tizen.dynamicanalyzer.appearance/src/org/tizen/dynamicanalyzer/widgets/da/base/DADialog.java b/org.tizen.dynamicanalyzer.appearance/src/org/tizen/dynamicanalyzer/widgets/da/base/DADialog.java index 452ca2a..e97db17 100644 --- a/org.tizen.dynamicanalyzer.appearance/src/org/tizen/dynamicanalyzer/widgets/da/base/DADialog.java +++ b/org.tizen.dynamicanalyzer.appearance/src/org/tizen/dynamicanalyzer/widgets/da/base/DADialog.java @@ -162,7 +162,7 @@ public class DADialog { strMessage.setText(message); strMessage.setBackground(ColorResources.WHITE); strMessage.setAlignment(SWT.LEFT); - strMessage.setForeground(ColorResources.DIALOG_CONTENT_BACKGROUND); + strMessage.setForeground(ColorResources.DIALOG_TEXT_FONT_COLOR); strMessage.setFont(FontResources.DIALOG_CONTENTS_NORMAL_FONT); formData = new FormData(); diff --git a/org.tizen.dynamicanalyzer.appearance/src/org/tizen/dynamicanalyzer/widgets/da/base/DAMessageBox.java b/org.tizen.dynamicanalyzer.appearance/src/org/tizen/dynamicanalyzer/widgets/da/base/DAMessageBox.java index 6f4a76e..f053901 100644 --- a/org.tizen.dynamicanalyzer.appearance/src/org/tizen/dynamicanalyzer/widgets/da/base/DAMessageBox.java +++ b/org.tizen.dynamicanalyzer.appearance/src/org/tizen/dynamicanalyzer/widgets/da/base/DAMessageBox.java @@ -63,6 +63,10 @@ public class DAMessageBox { return result; } + protected void setResult(Object result) { + this.result = result; + } + protected boolean run() { return true; } diff --git a/org.tizen.dynamicanalyzer.appearance/src/org/tizen/dynamicanalyzer/widgets/da/base/ProgressDialog.java b/org.tizen.dynamicanalyzer.appearance/src/org/tizen/dynamicanalyzer/widgets/da/base/ProgressDialog.java index 8def1cd..dcc20c8 100644 --- a/org.tizen.dynamicanalyzer.appearance/src/org/tizen/dynamicanalyzer/widgets/da/base/ProgressDialog.java +++ b/org.tizen.dynamicanalyzer.appearance/src/org/tizen/dynamicanalyzer/widgets/da/base/ProgressDialog.java @@ -95,7 +95,6 @@ public class ProgressDialog { private SelectionListener cancelButtonListener = null; // loading animation - private DAAnimationIcon loadingIcon = null; private DAAnimationIcon progressIcon = null; private Listener shellMouseListener = new Listener() { @@ -431,9 +430,6 @@ public class ProgressDialog { public void close() { if (progress != null) { if (!progress.isDisposed()) { - if (null != loadingIcon) { - loadingIcon.stopTimer(); - } progress.dispose(); } progress = null; diff --git a/org.tizen.dynamicanalyzer.cli/src/org/tizen/dynamicanalyzer/cli/CliInternals.java b/org.tizen.dynamicanalyzer.cli/src/org/tizen/dynamicanalyzer/cli/CliInternals.java index 6d57471..823c671 100644 --- a/org.tizen.dynamicanalyzer.cli/src/org/tizen/dynamicanalyzer/cli/CliInternals.java +++ b/org.tizen.dynamicanalyzer.cli/src/org/tizen/dynamicanalyzer/cli/CliInternals.java @@ -1,6 +1,5 @@ package org.tizen.dynamicanalyzer.cli; -import java.io.File; import java.rmi.ConnectException; import java.util.Arrays; import java.util.HashSet; @@ -478,15 +477,12 @@ public final class CliInternals { /** * Save collected trace. * - * @param filename path where trace is to be saved in default save directory + * @param file path where trace is to be saved * @return true if save was successful */ - public static boolean saveTrace(String filename) { - Logger.debug("Saving tracing results to " + filename); - if(!filename.startsWith("/")) // If fileName does not contains absolute path to file - filename = PathManager.DA_SAVE_PATH + File.separator + filename+".zip"; - - return CommandAction.saveToZip(filename); + public static boolean saveTrace(String file) { + Logger.debug("Saving tracing results to " + file); + return CommandAction.saveToZip(file); } /** diff --git a/org.tizen.dynamicanalyzer.cli/src/org/tizen/dynamicanalyzer/cli/commands/StopCommand.java b/org.tizen.dynamicanalyzer.cli/src/org/tizen/dynamicanalyzer/cli/commands/StopCommand.java index 72bbbd5..5ccd62e 100644 --- a/org.tizen.dynamicanalyzer.cli/src/org/tizen/dynamicanalyzer/cli/commands/StopCommand.java +++ b/org.tizen.dynamicanalyzer.cli/src/org/tizen/dynamicanalyzer/cli/commands/StopCommand.java @@ -1,5 +1,7 @@ package org.tizen.dynamicanalyzer.cli.commands; +import java.io.File; +import java.io.IOException; import java.rmi.ConnectException; import org.tizen.dynamicanalyzer.cli.CliInternals; @@ -66,14 +68,14 @@ public class StopCommand extends Command { System.err.println("Can't get time from TracingProcessManager"); return ExitCode.EX_OPERATION_FAILED; } - System.out.format( "DA tracing finished.%n" + "Total time: %s%n" + "Tracing time: %s%n" + "Output: %s%n", - duration, tracingTime, ctx.getArgs().getOutput()+".zip"); - // TODO check if output was created + duration, + tracingTime, ctx.getArgs().getOutput()); + return ExitCode.EX_SUCCESS; } diff --git a/org.tizen.dynamicanalyzer.cli/src/org/tizen/dynamicanalyzer/cli/manager/TracingProcessManager.java b/org.tizen.dynamicanalyzer.cli/src/org/tizen/dynamicanalyzer/cli/manager/TracingProcessManager.java index 0bafbf8..b85978c 100644 --- a/org.tizen.dynamicanalyzer.cli/src/org/tizen/dynamicanalyzer/cli/manager/TracingProcessManager.java +++ b/org.tizen.dynamicanalyzer.cli/src/org/tizen/dynamicanalyzer/cli/manager/TracingProcessManager.java @@ -18,8 +18,8 @@ import java.util.List; import org.tizen.dynamicanalyzer.cli.tracing.TracingArguments; import org.tizen.dynamicanalyzer.cli.tracing.TracingArgumentsParser; import org.tizen.dynamicanalyzer.cli.tracing.TracingProcess; -import org.tizen.dynamicanalyzer.cli.utils.Message; -import org.tizen.dynamicanalyzer.cli.utils.Message.MessageType; +import org.tizen.dynamicanalyzer.cli.utils.Communicator; +import org.tizen.dynamicanalyzer.cli.utils.ManagerCommunicationProcessor; import org.tizen.dynamicanalyzer.common.path.PathManager; import org.tizen.dynamicanalyzer.project.Project; import org.tizen.dynamicanalyzer.util.CommonUtil; @@ -72,8 +72,8 @@ public class TracingProcessManager { // Set output file name to default if was not defined if (args.getOutput() == null) { - File output = new File(PathManager.DA_SAVE_PATH + File.separator - + Project.constructSaveName(args.getApplication(), new Date())); + String output = PathManager.DA_SAVE_PATH + File.separator + + Project.constructSaveName(args.getApplication(), new Date()); args.setOutput(output); } @@ -125,7 +125,7 @@ public class TracingProcessManager { * Object, that encapsulated all communication with TracingProcess, starts * in constructor */ - private ServerConnection serverConnection; + private ManagerCommunicationProcessor communicationProcessor; /** * Communication thread. @@ -167,9 +167,13 @@ public class TracingProcessManager { try { final ServerSocket ss = new ServerSocket(port); Socket socket = ss.accept(); + ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()); + oos.flush(); + ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); + // start processing in separate thread - serverConnection = new ServerConnection(socket); - commThread = new Thread(serverConnection, + communicationProcessor = new ManagerCommunicationProcessor(new Communicator(ois, oos), ctx); + commThread = new Thread(communicationProcessor, "Communication thread"); commThread.start(); // finally we should close server socket @@ -207,9 +211,13 @@ public class TracingProcessManager { synchronized (this) { if (ctx.isFinished()) return; - serverConnection.sendMessage(MessageType.STOP_TRACING); + communicationProcessor.stopTracing(); } + if (tracingTime == 0) + tracingTime = communicationProcessor.getTracingTime(); + + communicationProcessor.closeConnection(); waitForCompletion(); } @@ -256,19 +264,9 @@ public class TracingProcessManager { * @return time value in milliseconds */ public long getTracingTime() { - if (tracingTime > 0) - return tracingTime; - else { - try { - serverConnection.sendMessage(MessageType.REQUEST_TRACING_TIME); - while (commThread.isAlive()) { - serverConnection.wait(); - } - } catch (IOException | InterruptedException e) { - Logger.error("Communication failed"); - } - return tracingTime; - } + if (tracingTime == 0) + tracingTime = communicationProcessor.getTracingTime(); + return tracingTime; } /** @@ -308,86 +306,4 @@ public class TracingProcessManager { public synchronized boolean isFinished() { return ctx.isFinished(); } - - private class ServerConnection implements Runnable { - ObjectOutputStream oos; - ObjectInputStream ois; - - /** - * ConnectionProcessor constructor. - * - * @param socket connection socket - * @throws IOException in case of communication initialization error - */ - private ServerConnection(Socket socket) throws IOException { - this.oos = new ObjectOutputStream(socket.getOutputStream()); - this.ois = new ObjectInputStream(socket.getInputStream()); - } - - /** - * Send message to stream. - * - * @param message message to socket - * @throws IOException in case of communication error - */ - public void sendMessage(Message message) throws IOException { - oos.writeObject(message); - oos.flush(); - } - - /** - * Send message to stream. Constructs {@link Message} instance on the - * fly. - * - * @param messageT message type - * @param args message arguments - * @throws IOException in case of communication error - */ - public void sendMessage(MessageType messageT, String... args) - throws IOException { - sendMessage(new Message(messageT, args)); - } - /** - * Actual connection processing. - */ - @Override - public void run() { - try { - boolean childAlive = true; - while (childAlive) { - Object rawObj = ois.readObject(); - if (!(rawObj instanceof Message)) - continue; - - Message message = (Message) rawObj; - switch (message.messageT) { - case STOP_DONE: - childAlive = false; - bw.close(); - break; - case INFO_TRACING_TIME: - tracingTime = Long.parseLong(message.args[0]); - break; - case ERROR_OCCURED: - ctx.finishContext(Integer.parseInt(message.args[0])); - break; - // Wrong requests - case REQUEST_TRACING_TIME: - case STOP_TRACING: - default: - Logger.warning("wrong request type for TracingProcessManager"); - break; - } - this.notifyAll(); - } - } catch (ClassNotFoundException e) { - Logger.error("Error while communicating with TracingProcess. Message type can't be resolved."); - this.notifyAll(); - } catch (IOException e) { - Logger.info("Communication stopped, stream closed"); - this.notifyAll(); - } - } - } - -} +} \ No newline at end of file diff --git a/org.tizen.dynamicanalyzer.cli/src/org/tizen/dynamicanalyzer/cli/tracing/TracingArguments.java b/org.tizen.dynamicanalyzer.cli/src/org/tizen/dynamicanalyzer/cli/tracing/TracingArguments.java index 9bae62b..c0b95de 100644 --- a/org.tizen.dynamicanalyzer.cli/src/org/tizen/dynamicanalyzer/cli/tracing/TracingArguments.java +++ b/org.tizen.dynamicanalyzer.cli/src/org/tizen/dynamicanalyzer/cli/tracing/TracingArguments.java @@ -1,11 +1,13 @@ package org.tizen.dynamicanalyzer.cli.tracing; import java.io.File; +import java.io.IOException; import java.io.Serializable; import java.util.HashSet; import java.util.Set; import org.tizen.dynamicanalyzer.setting.PrimitiveFeature; +import org.tizen.dynamicanalyzer.util.Logger; /** * Context class storing all necessary information for tracing start. @@ -20,7 +22,7 @@ public class TracingArguments implements Cloneable, Serializable { private String device; // device serial number or IP address private String application; // application name private Set featuresSet; // list of features for analysis - private File output; // file with tracing output + private String output; // absolute path to file with tracing output // TODO duration actually is not supported yet by CLI, always set to 0 private long durationSec; // tracing duration in seconds (0 is for unlimited duration) private int screenshotPeriod = 0; // Screenshot period in s. If 0 @@ -146,9 +148,9 @@ public class TracingArguments implements Cloneable, Serializable { } /** - * @return the output file + * @return the output file absolute path */ - public File getOutput() { + public String getOutput() { return output; } @@ -156,8 +158,18 @@ public class TracingArguments implements Cloneable, Serializable { * @param output the output file to set * @return this object to allow chained methods execution */ - public TracingArguments setOutput(File output) { - this.output = output; + public TracingArguments setOutput(String output) { + if (output == null) + return this; + if (!output.endsWith(".zip")) + output += ".zip"; + String out = null; + try { + out = new File(output).getCanonicalPath(); + } catch (IOException e) { + Logger.error(e); + } + this.output = out; return this; } diff --git a/org.tizen.dynamicanalyzer.cli/src/org/tizen/dynamicanalyzer/cli/tracing/TracingArgumentsParser.java b/org.tizen.dynamicanalyzer.cli/src/org/tizen/dynamicanalyzer/cli/tracing/TracingArgumentsParser.java index 5895e00..70afe0c 100644 --- a/org.tizen.dynamicanalyzer.cli/src/org/tizen/dynamicanalyzer/cli/tracing/TracingArgumentsParser.java +++ b/org.tizen.dynamicanalyzer.cli/src/org/tizen/dynamicanalyzer/cli/tracing/TracingArgumentsParser.java @@ -1,6 +1,5 @@ package org.tizen.dynamicanalyzer.cli.tracing; -import java.io.File; import java.util.ArrayList; import java.util.Arrays; @@ -107,7 +106,7 @@ public class TracingArgumentsParser { // Get output file if (cmdline.hasOption(output.getOpt())) { String outString = cmdline.getOptionValue(output.getOpt()); - result.setOutput(new File(outString)); + result.setOutput(outString); } // Get screenshot period @@ -171,10 +170,10 @@ public class TracingArgumentsParser { } // Output - File out = args.getOutput(); + String out = args.getOutput(); if (out != null) { result.add('-' + output.getOpt()); - result.add(out.getAbsolutePath()); + result.add(out); } int period = args.getScreenshotPeriod(); diff --git a/org.tizen.dynamicanalyzer.cli/src/org/tizen/dynamicanalyzer/cli/tracing/TracingProcess.java b/org.tizen.dynamicanalyzer.cli/src/org/tizen/dynamicanalyzer/cli/tracing/TracingProcess.java index 218e177..eea0180 100644 --- a/org.tizen.dynamicanalyzer.cli/src/org/tizen/dynamicanalyzer/cli/tracing/TracingProcess.java +++ b/org.tizen.dynamicanalyzer.cli/src/org/tizen/dynamicanalyzer/cli/tracing/TracingProcess.java @@ -14,8 +14,8 @@ import org.apache.commons.cli.ParseException; import org.tizen.dynamicanalyzer.cli.CliInternals; import org.tizen.dynamicanalyzer.cli.commands.ExitCode; import org.tizen.dynamicanalyzer.cli.manager.ProcessManager; -import org.tizen.dynamicanalyzer.cli.utils.Message; -import org.tizen.dynamicanalyzer.cli.utils.Message.MessageType; +import org.tizen.dynamicanalyzer.cli.utils.Communicator; +import org.tizen.dynamicanalyzer.cli.utils.ProcessCommunicationProcessor; import org.tizen.dynamicanalyzer.common.DAResult.ErrorCode; import org.tizen.dynamicanalyzer.common.DAState; import org.tizen.dynamicanalyzer.common.Global; @@ -49,9 +49,9 @@ public class TracingProcess { private final TracingArguments args; /** - * client communication thread + * Client communication thread. */ - private ClientConnection socketConnection; + private ProcessCommunicationProcessor communicationProcessor; /** * Start time value in milliseconds. It's initialized at application start @@ -86,7 +86,7 @@ public class TracingProcess { public synchronized ErrorCode startTrace() { ErrorCode result = CliInternals.startTracing(args); if (result != ErrorCode.SUCCESS) { - socketConnection.sendMessage(MessageType.ERROR_OCCURED, Integer.toString(result.getErrorNumber())); + communicationProcessor.errorOccured(result.getErrorNumber()); return result; } // Block until StartTraceManager thread starts all needed jobs @@ -110,8 +110,6 @@ public class TracingProcess { public synchronized void stopTrace() { tracingTime = System.nanoTime() / 1000 - startTime; Global.getProject().setTotalStopTime(tracingTime); - socketConnection.sendMessage(MessageType.INFO_TRACING_TIME, - Long.toString(tracingTime)); CliInternals.stopTracing(); } @@ -121,10 +119,7 @@ public class TracingProcess { * @return true if save was successful */ public boolean saveTrace() { - // FIXME Currently trace may be saved only to default directory - // thus we provide only filename as a parameter. - // This is to be fixed for the whole DA - return CliInternals.saveTrace(args.getOutput().getName()); + return CliInternals.saveTrace(args.getOutput()); } /** @@ -140,22 +135,24 @@ public class TracingProcess { /** * Return result of tracing process. * - * @return {@link ErrorCode#SUCCESS} if traced finished successfully - * TODO complete error codes documentation + * @return {@link ErrorCode#SUCCESS} if traced finished successfully, or + * code of occurred error. */ public synchronized ErrorCode getStatus() { return status; } /** - * Initializes communication and tracing threads. - * Blocks caller until tracing activities will be finished. + * Initializes communication and tracing threads. Blocks caller until + * tracing activities will be finished. * * @param args input parameters for tracing process - * @return {@link ErrorCode#SUCCESS} if tracing process started and finished successfully,
- * {@link ErrorCode#ERR_WRONG_MESSAGE_FORMAT} if tracing arguments are wrong,
- * {@link ErrorCode#ERR_EXCEPTION_OCCURRED} if critical or unexpected error occurred. - * TODO complete error codes documentation + * @return {@link ErrorCode#SUCCESS} if tracing process started and finished + * successfully,
+ * {@link ErrorCode#ERR_WRONG_MESSAGE_FORMAT} if tracing arguments + * are wrong,
+ * {@link ErrorCode#ERR_EXCEPTION_OCCURRED} if critical or + * unexpected error occurred. */ private static ErrorCode performAllTasks(String[] args, int port) { Logger.init(InternalLogger.WARNING); @@ -172,13 +169,20 @@ public class TracingProcess { // create instance of tracing process final TracingProcess tracingProcess = new TracingProcess(argsParsed); + // communication socket connection + Thread commThread = null; try { //Socket communication estblished between 2 processes on same device //There were not any secure data, so it is not required to use SSLSocket Socket socket = new Socket(InetAddress.getLocalHost(), port); - tracingProcess.socketConnection = tracingProcess.getConnProc(socket); - Thread commThread = new Thread(tracingProcess.socketConnection); + ObjectInputStream ois = new ObjectInputStream( + socket.getInputStream()); + ObjectOutputStream oos = new ObjectOutputStream( + socket.getOutputStream()); + ProcessCommunicationProcessor communicationProcessor = new ProcessCommunicationProcessor( + new Communicator(ois, oos), tracingProcess); + commThread = new Thread(communicationProcessor); commThread.start(); } catch (IOException ioe) { Logger.error("IOException in socket connection."); @@ -209,23 +213,14 @@ public class TracingProcess { return ErrorCode.ERR_EXCEPTION_OCCURRED; } - // return tracing result - return tracingProcess.getStatus(); - } - - /** - * creates ConnectionProcessor by given socket. Return null in case of any - * error. - * - * @param socket - * @return - */ - private ClientConnection getConnProc(Socket socket) { try { - return new ClientConnection(socket); - } catch (IOException e) { + if (commThread != null) + commThread.join(); + } catch (InterruptedException e) { + Logger.error("Tracing Process was interrupted, while waiting for communication to be closed"); } - return null; + // return tracing result + return tracingProcess.getStatus(); } private static int getPort() { @@ -248,88 +243,7 @@ public class TracingProcess { SystemExit.exit(exitCode.getErrorNumber()); } - private class ClientConnection implements Runnable { - ObjectOutputStream oos; - ObjectInputStream ois; - - /** - * ConnectionProcessor constructor. - * - * @param socket connection socket - * @throws IOException in case of communication initialization error - */ - private ClientConnection(Socket socket) throws IOException { - this.ois = new ObjectInputStream(socket.getInputStream()); - this.oos = new ObjectOutputStream(socket.getOutputStream()); - oos.flush(); - } - - /** - * Send message to stream. - * - * @param message message to socket - * @throws IOException in case of communication error - */ - public void sendMessage(Message message) { - try { - oos.writeObject(message); - oos.flush(); - } catch (IOException e) { - Logger.error("Got Exception while sending message to TracingProcessManager"); - } - } - - /** - * Send message to stream. Constructs {@link Message} instance on the - * fly. - * - * @param messageT message type - * @param args message arguments - * @throws IOException in case of communication error - */ - public void sendMessage(MessageType messageT, String... args) { - sendMessage(new Message(messageT, args)); - } - /** - * Actual connection processing. - */ - @Override - public void run() { - try { - while (true) { - Object rawObj = ois.readObject(); - if (!(rawObj instanceof Message)) - continue; - - Message message = (Message) rawObj; - switch (message.messageT) { - case STOP_TRACING: - Logger.info("Stopinng TracingProcess"); - synchronized (this) { - if (tracingTime == 0) // check that process is still running - stopTrace(); - } - sendMessage(MessageType.STOP_DONE); - break; - case REQUEST_TRACING_TIME: - sendMessage(MessageType.INFO_TRACING_TIME, - Long.toString(tracingTime)); - break; - //Wrong requests - case STOP_DONE: - case INFO_TRACING_TIME: - default: - Logger.warning("wrong request type " - + message.messageT.toString() - + " for TracingProcess"); - break; - } - } - } catch (ClassNotFoundException e) { - Logger.error("Error while communicating with TracingProcessManager. Message type can't be resolved."); - } catch (IOException e) { - Logger.info("Communication stopped, stream closed"); - } - } + public long getTracingTime() { + return tracingTime; } } \ No newline at end of file diff --git a/org.tizen.dynamicanalyzer.cli/src/org/tizen/dynamicanalyzer/cli/utils/Communicator.java b/org.tizen.dynamicanalyzer.cli/src/org/tizen/dynamicanalyzer/cli/utils/Communicator.java new file mode 100644 index 0000000..4ba2a9b --- /dev/null +++ b/org.tizen.dynamicanalyzer.cli/src/org/tizen/dynamicanalyzer/cli/utils/Communicator.java @@ -0,0 +1,83 @@ +package org.tizen.dynamicanalyzer.cli.utils; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; + +import org.tizen.dynamicanalyzer.cli.utils.Message.MessageType; +import org.tizen.dynamicanalyzer.util.Logger; + +/** + * Class encapsulates methods to start, stop and perform communication by two + * object streams. + */ +public class Communicator { + ObjectOutputStream oos; + ObjectInputStream ois; + + /** + * ConnectionProcessor constructor. + * + * @param socket connection socket + * @throws IOException in case of communication initialization error + */ + public Communicator(ObjectInputStream ois, ObjectOutputStream oos) { + this.ois = ois; + this.oos = oos; + } + + /** + * Send message to stream. + * + * @param message message to socket + * @throws IOException in case of {@link IOException} occurred + */ + public synchronized void sendMessage(Message message) throws IOException { + oos.writeObject(message); + oos.flush(); + } + + /** + * Send message to stream. Constructs {@link Message} instance on the fly. + * + * @param tid TID + * @param messageT message type + * @param args message arguments + * @throws IOException in case of {@link IOException} occurred + */ + public void sendMessage(long tid, MessageType messageT, String... args) + throws IOException { + sendMessage(new Message(tid, messageT, args)); + } + + /** + * Gets message from ois. Blocking method. + * + * @return {@link Message} received message + */ + public Message getMessage() { + + Object rawObj; + try { + rawObj = ois.readObject(); + if (!(rawObj instanceof Message)) + return null; + return (Message) rawObj; + } catch (ClassNotFoundException | IOException e) { + Logger.debug("Stream closed"); + return null; + } + } + + /** + * Method that closes communication streams and stop communication. + */ + public void stop() { + try { + oos.close(); + ois.close(); + } catch (IOException e) { + Logger.error(e.getMessage()); + } + } +} \ No newline at end of file diff --git a/org.tizen.dynamicanalyzer.cli/src/org/tizen/dynamicanalyzer/cli/utils/ManagerCommunicationProcessor.java b/org.tizen.dynamicanalyzer.cli/src/org/tizen/dynamicanalyzer/cli/utils/ManagerCommunicationProcessor.java new file mode 100644 index 0000000..78ba0ec --- /dev/null +++ b/org.tizen.dynamicanalyzer.cli/src/org/tizen/dynamicanalyzer/cli/utils/ManagerCommunicationProcessor.java @@ -0,0 +1,130 @@ +package org.tizen.dynamicanalyzer.cli.utils; + +import java.io.IOException; +import java.util.HashMap; +import java.util.concurrent.Semaphore; + +import org.tizen.dynamicanalyzer.cli.manager.TracingProcessContext; +import org.tizen.dynamicanalyzer.cli.tracing.TracingProcess; +import org.tizen.dynamicanalyzer.cli.utils.Message.MessageType; +import org.tizen.dynamicanalyzer.util.Logger; + +/** + * Encapsulates methods to communicate with {@link TracingProcess}, support + * concurrent requests. + */ +public class ManagerCommunicationProcessor implements Runnable { + + private Communicator comm; + private TracingProcessContext ctx; + + HashMap requestsPool = new HashMap(); + HashMap responsePool = new HashMap(); + + /** + * Constructor for manager side of communication process. + * + * @param comm communicator. + * @param ctx tracing process context. + */ + public ManagerCommunicationProcessor(Communicator comm, + TracingProcessContext ctx) { + this.comm = comm; + this.ctx = ctx; + } + + /** + * Method that listen for messages from tracing process in infinite loop, + * put answers into pulls and unlock thread, waiting for responses. + */ + @Override + public void run() { + while (true) { + Message message = comm.getMessage(); + if (message == null) { + Logger.debug("Communication stopped"); + break; + } + switch (message.getMessageType()) { + case REQUEST__STOP_TRACING: + case REQUEST__TRACING_TIME: + Logger.error("Wrong message for Manager"); + break; + case SIGNAL__ERROR_OCCURED: + reportError(message); + break; + default: + responsePool.put(message.getTid(), message); + requestsPool.remove(message.getTid()).release(); + break; + } + } + } + + /** + * Method to change context and stop tracingProcessManager and communication. + * + * @param message description of occurred error + */ + private void reportError(Message message) { + ctx.finishContext(Integer.parseInt(message.getArgs()[0])); + comm.stop(); + } + + /** + * Universal method to wait for response and release semaphore then. + * + * @param threadIndex index of thread, to point semaphore in map. + * @param messageToSend message to send. + * @return received message. + */ + private Message getResponse(long threadIndex, Message messageToSend) { + Semaphore semaphore = new Semaphore(1); + semaphore.acquireUninterruptibly(); + try { + requestsPool.put(threadIndex, semaphore); + comm.sendMessage(messageToSend); + semaphore.acquireUninterruptibly(); + semaphore.release(); + return responsePool.remove(threadIndex); + } catch (IOException e) { + Logger.error(e); + semaphore.release(); + return null; + } + } + + /** + * Method, requesting for tracing time and waiting for response. + * + * @return {@link Message} message containing tracing time + */ + public long getTracingTime() { + long threadIndex = Thread.currentThread().getId(); + Message mes = getResponse(threadIndex, new Message(threadIndex, + MessageType.REQUEST__TRACING_TIME)); + if ((mes != null) + && (mes.getMessageType() == MessageType.RESPONSE__TRACING_TIME)) { + return Long.parseLong(mes.getArgs()[0]); + } + return 0; + } + + /** + * Method requesting for process stop and waiting for response. + * + * @return {@link Message} message informing manager that tracing process stopped + */ + public Message stopTracing() { + long threadIndex = Thread.currentThread().getId(); + return getResponse(threadIndex, new Message(threadIndex, + MessageType.REQUEST__STOP_TRACING)); + } + + /** + * Method to close communication streams. + */ + public void closeConnection() { + comm.stop(); + } +} \ No newline at end of file diff --git a/org.tizen.dynamicanalyzer.cli/src/org/tizen/dynamicanalyzer/cli/utils/Message.java b/org.tizen.dynamicanalyzer.cli/src/org/tizen/dynamicanalyzer/cli/utils/Message.java index 5345ffc..24953a3 100644 --- a/org.tizen.dynamicanalyzer.cli/src/org/tizen/dynamicanalyzer/cli/utils/Message.java +++ b/org.tizen.dynamicanalyzer.cli/src/org/tizen/dynamicanalyzer/cli/utils/Message.java @@ -9,36 +9,98 @@ import java.io.Serializable; public class Message implements Serializable { public enum MessageType { - STOP_TRACING, - STOP_DONE, - INFO_TRACING_TIME, - REQUEST_TRACING_TIME, - ERROR_OCCURED + /** + * Request without arguments. It is sent when manager's stopTrace() + * method called. + */ + REQUEST__STOP_TRACING, + /** + * Request process for tracing time. Command have no arguments. Can be + * performed at any moment, + */ + REQUEST__TRACING_TIME, + /** + * Message is sent from process in response on command + * {@link REQUEST__STOP_TRACING}, have no arguments, sent right before + * process termination. + */ + RESPONSE__STOP_DONE, + /** + * Message is sent from process in response on + * {@link REQUEST__TRACING_TIME}, have 1 argument: Long, tracing time in + * microseconds. + */ + RESPONSE__TRACING_TIME, + /** + * Message sent from process to inform manager that in process occurred + * error that can not be ignored, and process failed. + */ + SIGNAL__ERROR_OCCURED } /** - * Automatically generated class identifier + * Automatically generated class identifier. */ private static final long serialVersionUID = -2812158395001795493L; /** * Message type. */ - public MessageType messageT; + private MessageType messageType; /** * Message arguments. */ - public String[] args; + private String[] args; + + /** + * Unique identifier of thread. + */ + private long tid; /** * Message constructor * + * @param tid Unique identifier of thread, sent or received this message. + * @param messageT type of message + * @param args String representation of message content + */ + public Message(long tid, MessageType messageT, String... args) { + this.messageType = messageT; + this.args = args.clone(); + this.tid = tid; + } + + /** + * Old message constructor. //TODO: Should be removed, after finishing of + * new communication process developing. + * * @param messageT type of message * @param args String representation of message content */ public Message(MessageType messageT, String... args) { - this.messageT = messageT; - this.args = args; + this(0, messageT, args); + } + + /** + * Return type of message. + * + * @return message type + */ + public MessageType getMessageType() { + return messageType; + } + + /** + * Return copy of arguments. + * + * @return array of string with arguments. + */ + public String[] getArgs() { + return args.clone(); + } + + public long getTid() { + return tid; } -} +} \ No newline at end of file diff --git a/org.tizen.dynamicanalyzer.cli/src/org/tizen/dynamicanalyzer/cli/utils/ProcessCommunicationProcessor.java b/org.tizen.dynamicanalyzer.cli/src/org/tizen/dynamicanalyzer/cli/utils/ProcessCommunicationProcessor.java new file mode 100644 index 0000000..53becf8 --- /dev/null +++ b/org.tizen.dynamicanalyzer.cli/src/org/tizen/dynamicanalyzer/cli/utils/ProcessCommunicationProcessor.java @@ -0,0 +1,85 @@ +package org.tizen.dynamicanalyzer.cli.utils; + +import java.io.IOException; + +import org.tizen.dynamicanalyzer.cli.tracing.TracingProcess; +import org.tizen.dynamicanalyzer.cli.utils.Message.MessageType; +import org.tizen.dynamicanalyzer.util.Logger; + +/** + * Encapsulates methods to response on messages from TracingProcessManager + * {@link TracingProcess}, and to send signal in case of error occurred. + */ +public class ProcessCommunicationProcessor implements Runnable { + + private Communicator comm; + private TracingProcess process; + + /** + * Constructor for process side of communication process. + * + * @param comm communicator. + * @param process tracing process. + */ + public ProcessCommunicationProcessor(Communicator comm, + TracingProcess process) { + this.comm = comm; + this.process = process; + } + + /** + * Method that listen for messages from tracing process in infinite loop, + * put answers into pulls and unlock thread, waiting for responses. + */ + @Override + public void run() { + while (true) { + Message message = comm.getMessage(); + if (message == null) { + Logger.debug("Communication stopped"); + break; + } + switch (message.getMessageType()) { + case RESPONSE__STOP_DONE: + case RESPONSE__TRACING_TIME: + case SIGNAL__ERROR_OCCURED: + Logger.error("Wrong message for Process"); + break; + case REQUEST__STOP_TRACING: + process.stopTrace(); + try { + comm.sendMessage(message.getTid(), MessageType.RESPONSE__STOP_DONE); + } catch (IOException e) { + Logger.error(e); + } + break; + case REQUEST__TRACING_TIME: + long time = process.getTracingTime(); + try { + comm.sendMessage(message.getTid(), + MessageType.RESPONSE__TRACING_TIME, Long.toString(time)); + } catch (IOException e) { + Logger.error(e); + } + break; + } + } + } + + /** + * In case of error occurred send message to Manager, that trigger + * displaying of occurred error description. This method should be called in + * case of critical errors. + * + * @param errNum error index + */ + public void errorOccured(int errNum) { + try { + comm.sendMessage(0, MessageType.SIGNAL__ERROR_OCCURED, + Integer.toString(errNum)); + } catch (IOException e) { + Logger.error(e); + } + } + +} diff --git a/org.tizen.dynamicanalyzer.cli/test/src/org/tizen/dynamicanalyzer/cli/manager/TracingProcessManagerTest.java b/org.tizen.dynamicanalyzer.cli/test/src/org/tizen/dynamicanalyzer/cli/manager/TracingProcessManagerTest.java index c4b4790..6fcfa8c 100644 --- a/org.tizen.dynamicanalyzer.cli/test/src/org/tizen/dynamicanalyzer/cli/manager/TracingProcessManagerTest.java +++ b/org.tizen.dynamicanalyzer.cli/test/src/org/tizen/dynamicanalyzer/cli/manager/TracingProcessManagerTest.java @@ -20,6 +20,7 @@ import java.util.concurrent.Callable; import java.util.concurrent.FutureTask; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -82,7 +83,8 @@ public class TracingProcessManagerTest { * Utility method compares specified time with current system time. */ private void assertCurrentTime(long time_ms) { - assertTrue(Math.abs(time_ms - new Date().getTime()) < TIME_EPS_MS * 2 + TIMEOUT_MS); + assertTrue(Math.abs(time_ms - new Date().getTime()) < TIME_EPS_MS * 2 + + TIMEOUT_MS); } /** @@ -144,6 +146,7 @@ public class TracingProcessManagerTest { /** * Test that manager correctly sends asynchronous stop signal to tracing process. */ + @Ignore @Test public void stopTracing_no_except() throws Exception { commThread.start(); @@ -151,8 +154,8 @@ public class TracingProcessManagerTest { manager = managerConstructor.newInstance(args, process, port); manager.stopTracing(); - assertEquals(MessageType.STOP_TRACING, - ((Message) ois.readObject()).messageT); + assertEquals(MessageType.REQUEST__STOP_TRACING, + ((Message) ois.readObject()).getMessageType()); } /** @@ -206,6 +209,7 @@ public class TracingProcessManagerTest { * Test that manager correctly handles successful tracing process * completion and synchronously returns error code. */ + @Ignore @Test(timeout = 3 * TIMEOUT_MS) public void stopTracing_timeout_dont_trigger_no_except() throws Exception { boolean result = false; @@ -237,6 +241,7 @@ public class TracingProcessManagerTest { * Test that manager correctly handles case when tracing process * hangs for a long time and tracing process was terminated. */ + @Ignore @Test(timeout=3*TIMEOUT_MS) public void stopTracing_timeout_trigger_no_except() throws Exception { commThread.start(); @@ -372,6 +377,7 @@ public class TracingProcessManagerTest { * the underlying process and correctly process case where there are another * completion waiters at the moment. */ + @Ignore @Test(timeout=2*TIMEOUT_MS) public void forceStopTracing_async() throws Exception { commThread.start(); diff --git a/org.tizen.dynamicanalyzer.cli/test/src/org/tizen/dynamicanalyzer/cli/tracing/TracingArgumentsParserTest.java b/org.tizen.dynamicanalyzer.cli/test/src/org/tizen/dynamicanalyzer/cli/tracing/TracingArgumentsParserTest.java index a4d2192..fe3abf3 100644 --- a/org.tizen.dynamicanalyzer.cli/test/src/org/tizen/dynamicanalyzer/cli/tracing/TracingArgumentsParserTest.java +++ b/org.tizen.dynamicanalyzer.cli/test/src/org/tizen/dynamicanalyzer/cli/tracing/TracingArgumentsParserTest.java @@ -9,6 +9,8 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.io.File; +import java.util.Arrays; +import java.util.List; import org.apache.commons.cli.ParseException; import org.junit.Before; @@ -39,7 +41,8 @@ public class TracingArgumentsParserTest { private final static PrimitiveFeature screenshot = PrimitiveFeature.SCREENSHOT; private final static String featureOptSCREENSHOT = "-S"; private final static String period = "3"; - private final static File output = new File("output.out"); + private final static String output = "output.out"; + private final static String outdefPrefix = File.separator+"test"+File.separator; private final static String outputOpt = "-o"; private final static long duration = 12345; private final static String durationOpt = "-i"; @@ -57,7 +60,8 @@ public class TracingArgumentsParserTest { TracingArguments result = TracingArgumentsParser.parse(new String[] { device, applicationOpt, application, - outputOpt, output.getPath(), + outputOpt, + outdefPrefix + output, featureOptCPU, featureOptSCREENSHOT, period // TODO duration option is not supported yet @@ -68,7 +72,7 @@ public class TracingArgumentsParserTest { assertTrue(result.isValid()); assertEquals(device, result.getDevice()); assertEquals(application, result.getApplication()); - assertEquals(output, result.getOutput()); + assertEquals(outdefPrefix + output + ".zip", result.getOutput()); assertEquals(2, result.getFeatures().size()); assertTrue(result.getFeatures().contains(cpu)); assertTrue(result.getFeatures().contains(screenshot)); @@ -97,7 +101,7 @@ public class TracingArgumentsParserTest { TracingArguments result = TracingArgumentsParser.parse(new String[] { device, applicationOpt, application, - outputOpt, output.getPath() }); + outputOpt, output }); assertNull(result); } @@ -168,7 +172,7 @@ public class TracingArgumentsParserTest { device, applicationOpt, application, featureOptCPU, - outputOpt, output.getPath(), + outputOpt, output, durationOpt, Long.toString(duration), "--", "value"}); assertNull(result); @@ -179,7 +183,7 @@ public class TracingArgumentsParserTest { TracingArguments result = TracingArgumentsParser.parse(new String[] { device, applicationOpt, application, - outputOpt, output.getPath(), + outputOpt, output, featureOptFILE // TODO duration option is not supported yet // durationOpt, Long.toString(duration) @@ -189,7 +193,8 @@ public class TracingArgumentsParserTest { assertTrue(result.isValid()); assertEquals(device, result.getDevice()); assertEquals(application, result.getApplication()); - assertEquals(output, result.getOutput()); + assertEquals(new File(output + ".zip").getCanonicalPath(), + result.getOutput()); assertEquals(2, result.getFeatures().size()); assertTrue(result.getFeatures().contains(file1)); assertTrue(result.getFeatures().contains(file2)); @@ -200,7 +205,7 @@ public class TracingArgumentsParserTest { TracingArguments result = TracingArgumentsParser.parse(new String[] { device, applicationOpt, application, - outputOpt, output.getPath(), + outputOpt, output, featureOptMEMORY // TODO duration option is not supported yet // durationOpt, Long.toString(duration) @@ -210,7 +215,8 @@ public class TracingArgumentsParserTest { assertTrue(result.isValid()); assertEquals(device, result.getDevice()); assertEquals(application, result.getApplication()); - assertEquals(output, result.getOutput()); + assertEquals(new File(output + ".zip").getCanonicalPath(), + result.getOutput()); assertEquals(2, result.getFeatures().size()); assertTrue(result.getFeatures().contains(memory1)); assertTrue(result.getFeatures().contains(memory2)); @@ -221,7 +227,7 @@ public class TracingArgumentsParserTest { TracingArguments result = TracingArgumentsParser.parse(new String[] { device, applicationOpt, application, - outputOpt, output.getPath(), + outputOpt, output, featureOptPOWER // TODO duration option is not supported yet // durationOpt, Long.toString(duration) @@ -231,7 +237,8 @@ public class TracingArgumentsParserTest { assertTrue(result.isValid()); assertEquals(device, result.getDevice()); assertEquals(application, result.getApplication()); - assertEquals(output, result.getOutput()); + assertEquals(new File(output + ".zip").getCanonicalPath(), + result.getOutput()); assertEquals(1, result.getFeatures().size()); assertTrue(result.getFeatures().contains(power)); } @@ -241,7 +248,7 @@ public class TracingArgumentsParserTest { TracingArguments result = TracingArgumentsParser.parse(new String[] { device, applicationOpt, application, - outputOpt, output.getPath(), + outputOpt, output, featureOptPOWER, featureOptCPU, featureOptFILE, @@ -254,7 +261,8 @@ public class TracingArgumentsParserTest { assertTrue(result.isValid()); assertEquals(device, result.getDevice()); assertEquals(application, result.getApplication()); - assertEquals(output, result.getOutput()); + assertEquals(new File(output + ".zip").getCanonicalPath(), + result.getOutput()); assertEquals(6, result.getFeatures().size()); } @@ -424,11 +432,26 @@ public class TracingArgumentsParserTest { String[] result = TracingArgumentsParser.toStringArray(args); assertNotNull(result); assertEquals(8, result.length); - assertEquals("-C", result[3]); - assertEquals("usage", result[4]); - assertEquals("-F", result[5]); - assertEquals("analysis", result[6]); - assertEquals("io", result[7]); + + List arrList = Arrays.asList(result); + List expected = Arrays.asList("-C", "-F", "usage", "io", "analysis"); + + for (String entry : expected) + assertTrue(arrList.contains(entry)); + + assertTrue(arrList.indexOf(expected.get(0)) > 2); // device -a app ... -C + assertTrue(arrList.indexOf(expected.get(1)) > 2); // device -a app ... -F + + int index = arrList.indexOf(expected.get(2)); + assertTrue( arrList.get(index - 1).equals(expected.get(0)) ); // -C usage + + index = arrList.indexOf(expected.get(3)); + assertTrue( arrList.get(index - 1).equals(expected.get(1)) || // -F io + arrList.get(index - 2).equals(expected.get(1)) ); // -F ... io + + index = arrList.indexOf(expected.get(4)); + assertTrue( arrList.get(index - 1).equals(expected.get(1)) || // -F analysis + arrList.get(index - 2).equals(expected.get(1)) ); // -F ... analysis } @Test diff --git a/org.tizen.dynamicanalyzer.cli/test/src/org/tizen/dynamicanalyzer/cli/tracing/TracingArgumentsTest.java b/org.tizen.dynamicanalyzer.cli/test/src/org/tizen/dynamicanalyzer/cli/tracing/TracingArgumentsTest.java index cbfdb74..138cfbb 100644 --- a/org.tizen.dynamicanalyzer.cli/test/src/org/tizen/dynamicanalyzer/cli/tracing/TracingArgumentsTest.java +++ b/org.tizen.dynamicanalyzer.cli/test/src/org/tizen/dynamicanalyzer/cli/tracing/TracingArgumentsTest.java @@ -19,7 +19,7 @@ public class TracingArgumentsTest { private final static String device = "device"; private final static String application = "application"; - private final static File output = new File("output.out"); + private final static String output = "output.out"; private final static PrimitiveFeature feature = PrimitiveFeature.CPU_USAGE; private final static PrimitiveFeature feature2 = PrimitiveFeature.POWER_ESTIMATION; private final static int period = 3; diff --git a/org.tizen.dynamicanalyzer.cli/test/src/org/tizen/dynamicanalyzer/cli/tracing/TracingProcessCommunicationTest.java b/org.tizen.dynamicanalyzer.cli/test/src/org/tizen/dynamicanalyzer/cli/tracing/TracingProcessCommunicationTest.java deleted file mode 100644 index a59c90a..0000000 --- a/org.tizen.dynamicanalyzer.cli/test/src/org/tizen/dynamicanalyzer/cli/tracing/TracingProcessCommunicationTest.java +++ /dev/null @@ -1,86 +0,0 @@ -package org.tizen.dynamicanalyzer.cli.tracing; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.net.ServerSocket; -import java.net.Socket; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; -import org.tizen.dynamicanalyzer.cli.utils.Message; -import org.tizen.dynamicanalyzer.cli.utils.Message.MessageType; -import org.tizen.dynamicanalyzer.setting.PrimitiveFeature; - -/** - * This class tests ability of {@link TracingProcess} to perform - * stop sequence when stop signal from parent will be send. - */ -@RunWith(PowerMockRunner.class) -@PrepareForTest({SystemExit.class, TracingProcess.class}) -public class TracingProcessCommunicationTest { - // timeout for test - private static final int TIMEOUT_MS = 500; - - static int port = 9000; - - private TracingArguments args; - - @Before - public void setUp() throws Exception { - args = new TracingArguments(); - args.setApplication("APP"); - args.setDevice("DEV"); - args.addFeature(PrimitiveFeature.CPU_USAGE); - args.setDuration(0); - } - - /** - * Check tracing process responds on requests - */ - @Test(timeout = 2 * TIMEOUT_MS) - public void testStandardBehavior() throws Exception { - Thread thread = new Thread(new CommunicationMock()); - thread.start(); - new TracingProcess(args); - } - - private static class CommunicationMock implements Runnable { - - @Override - public void run() { - try { - ServerSocket ss = new ServerSocket(port); - Socket socket = ss.accept(); - ss.close(); - ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()); - oos.flush(); - ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); - - oos.writeObject(new Message(MessageType.REQUEST_TRACING_TIME)); - oos.flush(); - Message mes = (Message) ois.readObject(); - assertEquals(MessageType.INFO_TRACING_TIME, mes.messageT); - assertEquals(1, mes.args.length); - assertEquals("0", mes.args[0]); - - oos.writeObject(new Message(MessageType.STOP_TRACING)); - oos.flush(); - mes = (Message) ois.readObject(); - assertEquals(mes.messageT, MessageType.INFO_TRACING_TIME); - assertTrue(Long.parseLong(mes.args[0])>0); - - mes = (Message) ois.readObject(); - assertEquals(MessageType.STOP_DONE, mes.messageT); - } catch (IOException | ClassNotFoundException e) { - assertTrue(false); - } - } - } -} diff --git a/org.tizen.dynamicanalyzer.cli/test/src/org/tizen/dynamicanalyzer/cli/utils/CommunicatorTest.java b/org.tizen.dynamicanalyzer.cli/test/src/org/tizen/dynamicanalyzer/cli/utils/CommunicatorTest.java new file mode 100644 index 0000000..45a2a77 --- /dev/null +++ b/org.tizen.dynamicanalyzer.cli/test/src/org/tizen/dynamicanalyzer/cli/utils/CommunicatorTest.java @@ -0,0 +1,278 @@ +package org.tizen.dynamicanalyzer.cli.utils; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.net.InetAddress; +import java.net.ServerSocket; +import java.net.Socket; + +import org.junit.Before; +import org.junit.Test; +import org.tizen.dynamicanalyzer.cli.utils.Message.MessageType; + +/** + * Test for {@link Communicator} class. + */ +public class CommunicatorTest { + + final int PORT = 9000; + Message sentMessage = null; + + @Before + public void prepare() { + sentMessage = null; + } + + /** + * Tests that communicator.sendMessage(Message) sent message correctly and + * sent message may be read on other side. Inside this test communication + * thread being created to receive sent message and store it in field + * sentMessage. + * + * @throws Exception + */ + @Test + public void testSend() throws Exception { + ServerSocket ss = new ServerSocket(PORT); + Thread commThread = new Thread(new Runnable() { + @Override + public void run() { + try { + Socket socket = new Socket(InetAddress.getLocalHost(), PORT); + ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()); + oos.flush(); + ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); + + Object rawObj = ois.readObject(); + socket.close(); + if (!(rawObj instanceof Message)) + return; + sentMessage = (Message) rawObj; + } catch (IOException | ClassNotFoundException e) { + return; + } + } + }); + commThread.start(); + + Socket socket = ss.accept(); + ss.close(); + ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); + ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()); + + Communicator comm = new Communicator(ois, oos); + assertNotNull(comm); + + Message mes = new Message(MessageType.REQUEST__STOP_TRACING); + comm.sendMessage(mes); + + commThread.join(); + + assertEquals(mes.getMessageType(), sentMessage.getMessageType()); + assertEquals(mes.getArgs().length, sentMessage.getArgs().length); + } + + /** + * Tests that communicator.sendMessage(MessageType, String..) sent message + * correctly and sent message may be read on other side. Inside this test + * communication thread being created to receive sent message and store it + * in field sentMessage. + * + * In this test case String.. args is null. + * + * @throws Exception + */ + @Test + public void testSendByInternals() throws Exception { + ServerSocket ss = new ServerSocket(PORT); + Thread commThread = new Thread(new Runnable() { + @Override + public void run() { + try { + Socket socket = new Socket(InetAddress.getLocalHost(), PORT); + ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()); + oos.flush(); + ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); + + Object rawObj = ois.readObject(); + socket.close(); + if (!(rawObj instanceof Message)) + return; + sentMessage = (Message) rawObj; + } catch (IOException | ClassNotFoundException e) { + return; + } + } + }); + commThread.start(); + + Socket socket = ss.accept(); + ss.close(); + ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); + ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()); + + Communicator comm = new Communicator(ois, oos); + assertNotNull(comm); + + comm.sendMessage(0L, MessageType.REQUEST__STOP_TRACING); + + commThread.join(); + + assertEquals(0, sentMessage.getTid()); + assertEquals(MessageType.REQUEST__STOP_TRACING, sentMessage.getMessageType()); + assertEquals(0, sentMessage.getArgs().length); + } + + /** + * Tests that communicator.sendMessage(MessageType, String..) sent message + * correctly and sent message may be read on other side. Inside this test + * communication thread being created to receive sent message and store it + * in field sentMessage. + * + * In this test case String.. args is not null. + * + * @throws Exception + */ + @Test + public void testSendByInternalsWithArgs() throws Exception { + ServerSocket ss = new ServerSocket(PORT); + Thread commThread = new Thread(new Runnable() { + @Override + public void run() { + try { + Socket socket = new Socket(InetAddress.getLocalHost(), PORT); + ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()); + oos.flush(); + ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); + + Object rawObj = ois.readObject(); + socket.close(); + if (!(rawObj instanceof Message)) + return; + sentMessage = (Message) rawObj; + } catch (IOException | ClassNotFoundException e) { + return; + } + } + }); + commThread.start(); + + Socket socket = ss.accept(); + ss.close(); + ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); + ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()); + + Communicator comm = new Communicator(ois, oos); + assertNotNull(comm); + + comm.sendMessage(0L, MessageType.REQUEST__STOP_TRACING, "Some", + "Random", + "arguments"); + + commThread.join(); + + assertEquals(0, sentMessage.getTid()); + assertEquals(MessageType.REQUEST__STOP_TRACING, sentMessage.getMessageType()); + assertEquals(3, sentMessage.getArgs().length); + assertEquals("Some", sentMessage.getArgs()[0]); + assertEquals("Random", sentMessage.getArgs()[1]); + assertEquals("arguments", sentMessage.getArgs()[2]); + } + + /** + * Tests that communicator.getMessage() receive message correctly.Inside + * this test communication thread being created to send message to + * communicator. + * + * In this test case String.. args is null. + * + * @throws Exception + */ + @Test + public void testGet() throws Exception { + ServerSocket ss = new ServerSocket(PORT); + Thread commThread = new Thread(new Runnable() { + @Override + public void run() { + try { + Socket socket = new Socket(InetAddress.getLocalHost(), PORT); + ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()); + oos.flush(); + ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); + + oos.writeObject(new Message(MessageType.SIGNAL__ERROR_OCCURED));; + oos.flush(); + } catch (IOException e) { + return; + } + } + }); + commThread.start(); + + Socket socket = ss.accept(); + ss.close(); + ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); + ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()); + + Communicator comm = new Communicator(ois, oos); + assertNotNull(comm); + + Message mes = comm.getMessage(); + + commThread.join(); + + assertEquals(MessageType.SIGNAL__ERROR_OCCURED, mes.getMessageType()); + assertEquals(0, mes.getArgs().length); + } + + /** + * Tests that communicator.getMessage() receive message correctly.Inside + * this test communication thread being created to send message to + * communicator. + * + * In this test case String.. args is not null. + * + * @throws Exception + */ + @Test + public void testGetWithArgs() throws Exception { + ServerSocket ss = new ServerSocket(PORT); + Thread commThread = new Thread(new Runnable() { + @Override + public void run() { + try { + Socket socket = new Socket(InetAddress.getLocalHost(), PORT); + ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()); + oos.flush(); + ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); + + oos.writeObject(new Message(MessageType.SIGNAL__ERROR_OCCURED, "New Random String")); + oos.flush(); + } catch (IOException e) { + return; + } + } + }); + commThread.start(); + + Socket socket = ss.accept(); + ss.close(); + ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); + ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()); + + Communicator comm = new Communicator(ois, oos); + assertNotNull(comm); + + Message mes = comm.getMessage(); + + commThread.join(); + + assertEquals(MessageType.SIGNAL__ERROR_OCCURED, mes.getMessageType()); + assertEquals(1, mes.getArgs().length); + assertEquals("New Random String", mes.getArgs()[0]); + } +} diff --git a/org.tizen.dynamicanalyzer.cli/test/src/org/tizen/dynamicanalyzer/cli/utils/ManagerCommunicationProcessorTest.java b/org.tizen.dynamicanalyzer.cli/test/src/org/tizen/dynamicanalyzer/cli/utils/ManagerCommunicationProcessorTest.java new file mode 100644 index 0000000..da5ab53 --- /dev/null +++ b/org.tizen.dynamicanalyzer.cli/test/src/org/tizen/dynamicanalyzer/cli/utils/ManagerCommunicationProcessorTest.java @@ -0,0 +1,210 @@ +package org.tizen.dynamicanalyzer.cli.utils; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.net.ServerSocket; +import java.net.Socket; + +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.tizen.dynamicanalyzer.cli.manager.TracingProcessContext; +import org.tizen.dynamicanalyzer.cli.tracing.TracingArguments; +import org.tizen.dynamicanalyzer.cli.utils.Message.MessageType; +import org.tizen.dynamicanalyzer.common.DAResult.ErrorCode; +import org.tizen.dynamicanalyzer.setting.PrimitiveFeature; +import org.tizen.dynamicanalyzer.util.InternalLogger; +import org.tizen.dynamicanalyzer.util.Logger; + +/** + * Test for {@link ManagerCommunicationProcessor} class. + */ +public class ManagerCommunicationProcessorTest { + + static int PORT = 9000; + + static ManagerCommunicationProcessor comProcessor; + + static TracingProcessContext ctx; + + private static OppositeCommSide opposite; + + private static Thread comThread; + + /** + * Initiate communication process between ManagerCommunicationProcessor and + * OppositeCommSide - stub class for socket communication client. + * + * @throws IOException + */ + @BeforeClass + public static void setUp() throws IOException { + Logger.init(InternalLogger.DEBUG); + ServerSocket ss = new ServerSocket(PORT); + opposite = new OppositeCommSide(PORT); + Thread oppThread = new Thread(opposite); + oppThread.start(); + Socket socket = ss.accept(); + ss.close(); + ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()); + oos.flush(); + ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); + Communicator comm = new Communicator(ois, oos); + + TracingArguments args = new TracingArguments(); + args.setDevice("DEV"); + args.setApplication("APP"); + args.setDuration(0); + args.addFeature(PrimitiveFeature.CPU_USAGE); + ctx = new TracingProcessContext(args); + + comProcessor = new ManagerCommunicationProcessor(comm, ctx); + comThread = new Thread(comProcessor); + comThread.start(); + } + + /** + * Method to test if communication finished correctly after sending an + * SIGNAL__ERROR_OCCURED. + * + * @throws InterruptedException + */ + @AfterClass + public static void test_errOccured() throws InterruptedException { + try { + opposite.sendMessage(new Message(0, MessageType.SIGNAL__ERROR_OCCURED, + Integer.toString(ErrorCode.SUCCESS.getErrorNumber()))); + } catch (IOException e) { + Assert.fail(); + } + comThread.join(); + assertTrue(ctx.isFinished()); + assertEquals(ErrorCode.SUCCESS.getErrorNumber(), ctx.getErrCode()); + } + + long time; + + /** + * Test that getTracingTime() method send correct message and then suspend + * until process response to this message. + * + * @throws Exception + */ + @Test(timeout=200) + public void test_getTracingTime() throws Exception { + time = 0L; + Thread worker = new Thread(new Runnable() { + + @Override + public void run() { + time = comProcessor.getTracingTime(); + } + + }); + worker.start(); + Message mes = opposite.get_message(); + opposite.sendMessage(new Message(mes.getTid(), + MessageType.RESPONSE__TRACING_TIME, Long.toString(2000L))); + worker.join(); + + assertEquals(2000L, time); + time = 0L; + } + + /** + * Test that stopTracing() method send correct message and then suspend + * until process response to this message. + * + * @throws Exception + */ + @Test(timeout=200) + public void test_stopTracing() throws Exception { + Thread worker = new Thread(new Runnable() { + + @Override + public void run() { + Message message = comProcessor.stopTracing(); + assertEquals(Thread.currentThread().getId(), message.getTid()); + assertEquals(MessageType.RESPONSE__STOP_DONE, + message.getMessageType()); + } + + }); + worker.start(); + Message mes = opposite.get_message(); + + assertEquals(worker.getId(), mes.getTid()); + assertEquals(MessageType.REQUEST__STOP_TRACING, mes.getMessageType()); + assertEquals(0, mes.getArgs().length); + + opposite.sendMessage(new Message(mes.getTid(), + MessageType.RESPONSE__STOP_DONE, Long.toString(2000L))); + worker.join(); + } + + /** + * Test that communicator can correctly work with requests sent from + * different threads simultaneously. + * + * @throws Exception + */ + @Test(timeout=200) + public void test_2requestingThreads() throws Exception { + time = 0L; + Thread worker1 = new Thread(new Runnable() { + + @Override + public void run() { + Message message = comProcessor.stopTracing(); + assertEquals(Thread.currentThread().getId(), message.getTid()); + assertEquals(MessageType.RESPONSE__STOP_DONE, + message.getMessageType()); + time = comProcessor.getTracingTime(); + } + + }); + Thread worker2 = new Thread(new Runnable() { + + @Override + public void run() { + time = comProcessor.getTracingTime(); + } + + }); + worker1.start(); + worker2.start(); + + Message mes1 = opposite.get_message(); + Message mes2 = opposite.get_message(); + if (mes1.getTid() == worker1.getId()) { + assertEquals(MessageType.REQUEST__STOP_TRACING, mes1.getMessageType()); + assertEquals(MessageType.REQUEST__TRACING_TIME, mes2.getMessageType()); + assertEquals(worker2.getId(), mes2.getTid()); + }else{ + assertEquals(worker2.getId(), mes1.getTid()); + assertEquals(MessageType.REQUEST__STOP_TRACING, mes2.getMessageType()); + assertEquals(MessageType.REQUEST__TRACING_TIME, mes1.getMessageType()); + assertEquals(worker1.getId(), mes2.getTid()); + } + opposite.sendMessage(new Message(worker2.getId(), MessageType.RESPONSE__TRACING_TIME, Long.toString(1000))); + worker2.join(); + assertEquals(1000L, time); + + opposite.sendMessage(new Message(worker1.getId(), MessageType.RESPONSE__STOP_DONE)); + assertEquals(1000L, time); + + mes1 = opposite.get_message(); + assertEquals(MessageType.REQUEST__TRACING_TIME, mes1.getMessageType()); + assertEquals(worker1.getId(), mes1.getTid()); + + opposite.sendMessage(new Message(worker1.getId(), MessageType.RESPONSE__TRACING_TIME, Long.toString(2000))); + worker1.join(); + assertEquals(2000L, time); + time = 0; + } +} \ No newline at end of file diff --git a/org.tizen.dynamicanalyzer.cli/test/src/org/tizen/dynamicanalyzer/cli/utils/OppositeCommSide.java b/org.tizen.dynamicanalyzer.cli/test/src/org/tizen/dynamicanalyzer/cli/utils/OppositeCommSide.java new file mode 100644 index 0000000..37c0eeb --- /dev/null +++ b/org.tizen.dynamicanalyzer.cli/test/src/org/tizen/dynamicanalyzer/cli/utils/OppositeCommSide.java @@ -0,0 +1,70 @@ +package org.tizen.dynamicanalyzer.cli.utils; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.net.InetAddress; +import java.net.Socket; + +import org.junit.Ignore; + +/** + * Stub for socket communication client. + */ +@Ignore +public class OppositeCommSide implements Runnable { + + int PORT; + + /** + * Public constructor. + * + * @param port communication port on LocalHost + */ + public OppositeCommSide(int port) { + this.PORT = port; + } + + ObjectInputStream ois; + ObjectOutputStream oos; + + /** + * Receive message from ois. + * + * @return received message. + * @throws Exception if message can not be read from {@link ObjectInputStream}, or it is not + * instance of {@link Message} + */ + public Message get_message() throws Exception { + Object obj = null; + obj = ois.readObject(); + return (Message) obj; + } + + /** + * Send message or throw {@link IOException} if {@link ObjectOutputStream} is unavailable. + * + * @param message message to send + * @throws IOException if {@link ObjectOutputStream} is unavailable + */ + public void sendMessage(Message message) throws IOException { + oos.writeObject(message); + oos.flush(); + } + + /** + * Initialize {@link ObjectInputStream} and {@link ObjectOutputStream}. + */ + @Override + public void run() { + try { + Socket socket = new Socket(InetAddress.getLocalHost(), PORT); + ois = new ObjectInputStream(socket.getInputStream()); + oos = new ObjectOutputStream(socket.getOutputStream()); + oos.flush(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/org.tizen.dynamicanalyzer.cli/test/src/org/tizen/dynamicanalyzer/cli/utils/ProcessCommunicationProcessorTest.java b/org.tizen.dynamicanalyzer.cli/test/src/org/tizen/dynamicanalyzer/cli/utils/ProcessCommunicationProcessorTest.java new file mode 100644 index 0000000..aac9ecb --- /dev/null +++ b/org.tizen.dynamicanalyzer.cli/test/src/org/tizen/dynamicanalyzer/cli/utils/ProcessCommunicationProcessorTest.java @@ -0,0 +1,112 @@ +package org.tizen.dynamicanalyzer.cli.utils; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.net.ServerSocket; +import java.net.Socket; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.tizen.dynamicanalyzer.cli.tracing.TracingProcess; +import org.tizen.dynamicanalyzer.cli.utils.Message.MessageType; +import org.tizen.dynamicanalyzer.common.DAResult.ErrorCode; +import org.tizen.dynamicanalyzer.util.InternalLogger; +import org.tizen.dynamicanalyzer.util.Logger; + +/** + * Test for {@link ProcessCommunicationProcessor} class. + */ +public class ProcessCommunicationProcessorTest { + + static Thread comThread; + static OppositeCommSide opposite; + static int PORT = 10000; + private static ProcessCommunicationProcessor comProcessor; + private static TracingProcess process; + private static Thread oppThread; + + /** + * Initiate communication process between ProcessCommunicationProcessor and + * OppositeCommSide - stub class for socket communication client. + * + * @throws IOException + */ + @BeforeClass + public static void setup() throws IOException { + Logger.init(InternalLogger.DEBUG); + ServerSocket ss = new ServerSocket(PORT); + opposite = new OppositeCommSide(PORT); + oppThread = new Thread(opposite); + oppThread.start(); + Socket socket = ss.accept(); + ss.close(); + ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()); + oos.flush(); + ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); + Communicator comm = new Communicator(ois, oos); + + process = mock(TracingProcess.class); + + comProcessor = new ProcessCommunicationProcessor(comm, process); + comThread = new Thread(comProcessor); + comThread.start(); + } + + /** + * Test that errorOccured() method send message correctly. + * + * @throws Exception + */ + @Test + public void test_errorOccured() throws Exception { + comProcessor.errorOccured(ErrorCode.ERR_BUSY_DEVICE.getErrorNumber()); + Message mes = opposite.get_message(); + assertEquals(MessageType.SIGNAL__ERROR_OCCURED, mes.getMessageType()); + assertEquals(0, mes.getTid()); + assertEquals(ErrorCode.ERR_BUSY_DEVICE.getErrorNumber(), + Integer.parseInt(mes.getArgs()[0])); + } + + /** + * Test that in case of REQUEST__STOP_TRACING message received, then + * stopTrace() method called and response message sent correctly. + * + * @throws Exception + */ + @Test + public void test_requestStop() throws Exception { + opposite.sendMessage(new Message(oppThread.getId(), + MessageType.REQUEST__STOP_TRACING)); + Message mes = opposite.get_message(); + + assertEquals(oppThread.getId(), mes.getTid()); + assertEquals(MessageType.RESPONSE__STOP_DONE, mes.getMessageType()); + assertEquals(0, mes.getArgs().length); + + verify(process).stopTrace(); + } + + /** + * Test that in case of REQUEST__TRACING_TIME message received, then + * TracingProcess is asked for tracing time and answer is sent correctly. + * + * @throws Exception + */ + @Test + public void test_requestTracingTime() throws Exception { + opposite.sendMessage(new Message(300L, + MessageType.REQUEST__TRACING_TIME)); + Message mes = opposite.get_message(); + + assertEquals(300L, mes.getTid()); + assertEquals(MessageType.RESPONSE__TRACING_TIME, mes.getMessageType()); + assertEquals(0L, Long.parseLong(mes.getArgs()[0])); + + verify(process).getTracingTime(); + } +} \ No newline at end of file diff --git a/org.tizen.dynamicanalyzer.common.test/src/org/tizen/dynamicanalyzer/unittest/UnitTestConstants.java b/org.tizen.dynamicanalyzer.common.test/src/org/tizen/dynamicanalyzer/unittest/UnitTestConstants.java index af36757..34cd4f1 100644 --- a/org.tizen.dynamicanalyzer.common.test/src/org/tizen/dynamicanalyzer/unittest/UnitTestConstants.java +++ b/org.tizen.dynamicanalyzer.common.test/src/org/tizen/dynamicanalyzer/unittest/UnitTestConstants.java @@ -28,5 +28,5 @@ package org.tizen.dynamicanalyzer.unittest; public class UnitTestConstants { public static final int RANDOM_TEST_COUNT = 1000; // The count of input in random value (i.e. the count of test) public static final int TEST_FOR_ARRAY_COUNT = 100; // The input's array count - + public static final int FLAT_FEATURE_SET_SIZE = 5; // Count of randomly selected FlatFeatures } diff --git a/org.tizen.dynamicanalyzer.common/src/org/tizen/dynamicanalyzer/util/CommonUtil.java b/org.tizen.dynamicanalyzer.common/src/org/tizen/dynamicanalyzer/util/CommonUtil.java index e546c35..b564853 100644 --- a/org.tizen.dynamicanalyzer.common/src/org/tizen/dynamicanalyzer/util/CommonUtil.java +++ b/org.tizen.dynamicanalyzer.common/src/org/tizen/dynamicanalyzer/util/CommonUtil.java @@ -209,4 +209,16 @@ public class CommonUtil { return result; } + + /** + * Checks whether given string is integer. + * + * @param str + * string to check + * @return true if string is integer. + */ + public static boolean isNumeric(String str) { + // match a number with optional '-' and decimal. + return str.matches("-?\\d+(\\.\\d+)?"); + } } diff --git a/org.tizen.dynamicanalyzer.test/resources/flatfeature b/org.tizen.dynamicanalyzer.test/resources/flatfeature index 48a3e5b..28a192f 100644 --- a/org.tizen.dynamicanalyzer.test/resources/flatfeature +++ b/org.tizen.dynamicanalyzer.test/resources/flatfeature @@ -13,6 +13,5 @@ 602|Screenshot|1||Timeline||10|100|10| 603|UI Hierarchy|1||UI Hierarchy||||| 701|Thread|1||Thread|||||2 -702|Sync analysis|1||Thread|||||2 801|Peripheral Status|1||Timeline||||| 802|Power Estimation|1||Timeline||||| diff --git a/org.tizen.dynamicanalyzer.test/resources/layout b/org.tizen.dynamicanalyzer.test/resources/layout index 982f364..fd92d9f 100644 --- a/org.tizen.dynamicanalyzer.test/resources/layout +++ b/org.tizen.dynamicanalyzer.test/resources/layout @@ -1,2 +1,2 @@ -Selected Chart List|CPU|CPU core|CPU frequency -Default Chart List|CPU|CPU core|CPU frequency +Selected Chart List|CPU Usage|Core Usage +Default Chart List|Core Usage diff --git a/org.tizen.dynamicanalyzer.test/resources/setting b/org.tizen.dynamicanalyzer.test/resources/setting index db22b1e..280a20a 100644 --- a/org.tizen.dynamicanalyzer.test/resources/setting +++ b/org.tizen.dynamicanalyzer.test/resources/setting @@ -1,26 +1,25 @@ Version|0.2 Log Level|4 -Debug Print|N -Available Target List|mobile +Debug Print|Y +Available Target List|mobile|wearable Selected Target|mobile -Options Selected Feature List|5002:0 Default Feature List|2|3|103 Total Overhead Range|1000000|3000000|7000000|15000000 -mobile|Protocol Version|3.0 -mobile|Available Template List|1|2|3|4|5|6|7|8|9|10 +Options Selected Feature List|5002:0 +Selected Preferences|2001 +mobile|Protocol Version|4.0 +mobile|Available Template List|1|2|3|4|5|6|7|8|9|10|11 mobile|Selected Template|1 -mobile|Available Feature List|1|1000|4|5|6|7|8|9|100|101|1001|102|200|201|202|203|204 +mobile|Available Feature List|1|1000|4|5|6|7|8|9|100|101|1001|301|200|201|202|203|204|206 +mobile|Available FlatFeature List|101|102|103|201|202|203|301|302|401|501|502|601|602|603|701|801|802 mobile|Selected Feature List|1|5|1000:1000|100|101|1001:10 -mobile|Available Chart List|CPU|CPU core|CPU frequency|Heap allocation|Process Size|Memory|Screenshot|UI event|Disk IO|Network IO|Device|Energy +mobile|Selected FlatFeature List|101|102 +mobile|Available Chart List|CPU Usage|Core Usage|Core Frequency|System Memory|Process Memory|Heap Allocation|Screenshot|UI Event|Disk IO|Network IO|Peripheral Status|Power Estimation wearable|Protocol Version|3.0 -wearable|Available Template List|1|2|3|4|5|6|7|8|9|10 +wearable|Available Template List|1|2|3|4|5|6|7|8|9|10|11 wearable|Selected Template|1 -wearable|Available Feature List|1|1000|4|5|6|7|8|9|100|101|1001|102|200|201|202|203|204 +wearable|Available Feature List|1|1000|4|5|6|7|8|9|100|101|1001|301|200|201|202|203|204|206 +wearable|Available FlatFeature List|101|102|103|201|202|203|301|302|401|501|502|601|602|603|701|801|802 wearable|Selected Feature List|1|5|1000:1000|100|101|1001:10 -wearable|Available Chart List|CPU|CPU core|CPU frequency|Heap allocation|Process Size|Memory|Screenshot|UI event|Disk IO|Network IO|Device|Energy -tv|Protocol Version|3.0 -tv|Available Template List|1|3|9|10 -tv|Selected Template|1 -tv|Available Feature List|1|1000|4|5|6|7|8|9|100|101|1001|204 -tv|Selected Feature List|1|5|1000:1000|100|101|1001:10 -tv|Available Chart List|CPU|CPU core|CPU frequency|Heap allocation|Process Size|Memory|Screenshot|UI event|Disk IO|Network IO|Device|Energy +wearable|Selected FlatFeature List| +wearable|Available Chart List|CPU Usage|Core Usage|Core Frequency|System Memory|Process Memory|Heap Allocation|Screenshot|UI Event|Disk IO|Network IO|Peripheral Status|Power Estimation \ No newline at end of file diff --git a/org.tizen.dynamicanalyzer.test/src/org/tizen/dynamicanalyzer/ui/toolbar/setting/data/SettingDataManagerTest.java b/org.tizen.dynamicanalyzer.test/src/org/tizen/dynamicanalyzer/ui/toolbar/setting/data/SettingDataManagerTest.java index 2c5ab6d..ebc6df0 100644 --- a/org.tizen.dynamicanalyzer.test/src/org/tizen/dynamicanalyzer/ui/toolbar/setting/data/SettingDataManagerTest.java +++ b/org.tizen.dynamicanalyzer.test/src/org/tizen/dynamicanalyzer/ui/toolbar/setting/data/SettingDataManagerTest.java @@ -37,7 +37,9 @@ import java.util.Map; import java.util.Set; import org.junit.AfterClass; +import org.junit.Before; import org.junit.BeforeClass; +import org.junit.Ignore; import org.junit.Test; import org.powermock.reflect.Whitebox; import org.tizen.dynamicanalyzer.common.Global; @@ -46,6 +48,7 @@ import org.tizen.dynamicanalyzer.nl.ConfigureLabels; import org.tizen.dynamicanalyzer.setting.Feature; import org.tizen.dynamicanalyzer.setting.FeatureData; import org.tizen.dynamicanalyzer.setting.FeatureValueData; +import org.tizen.dynamicanalyzer.setting.FlatPreferences; import org.tizen.dynamicanalyzer.setting.SettingConstants; import org.tizen.dynamicanalyzer.setting.SettingDataManager; import org.tizen.dynamicanalyzer.setting.TargetData; @@ -72,12 +75,27 @@ public class SettingDataManagerTest { @SuppressWarnings("unused") UILayoutDataManager l = UILayoutDataManager.INSTANCE; } + + @Before + public void set_up(){ + // revert setting Preferences + List initOptionsSelectedPreferenceList = Whitebox + .getInternalState(SettingDataManager.INSTANCE, + "initOptionsSelectedPreferenceList"); + List optionsSelectedPreferenceList = Whitebox + .getInternalState(SettingDataManager.INSTANCE, + "optionsSelectedPreferenceList"); + + optionsSelectedPreferenceList.clear(); + optionsSelectedPreferenceList.addAll(initOptionsSelectedPreferenceList); + } @AfterClass public static void tesApplySettingData() { // change selected target, options feature SettingDataManager.INSTANCE.setSelectedTarget("wearable"); - SettingDataManager.INSTANCE.addOptionsSelectedFeature(Feature.SCREENSHOT_PERIODICALLY, 50); + SettingDataManager.INSTANCE.addOptionsSelectedPreference( + FlatPreferences.SCREENSHOT_PERIODICALLY, 50); assertTrue(SettingDataManager.INSTANCE.changedFeatures()); // apply selected target, options feature @@ -91,17 +109,20 @@ public class SettingDataManagerTest { String initTarget = Whitebox.getInternalState(SettingDataManager.INSTANCE, "initTarget"); assertEquals("wearable", initTarget); - // check initOptionsSelectedFeatureList - List initOptionsSelectedFeatureList = Whitebox.getInternalState( - SettingDataManager.INSTANCE, "initOptionsSelectedFeatureList"); - assertEquals(2, initOptionsSelectedFeatureList.size()); - assertEquals(5002, initOptionsSelectedFeatureList.get(0).getKey().getIndex()); - assertEquals(0, initOptionsSelectedFeatureList.get(0).getValue()); - assertEquals(5001, initOptionsSelectedFeatureList.get(1).getKey().getIndex()); - assertEquals(50, initOptionsSelectedFeatureList.get(1).getValue()); - assertFalse(SettingDataManager.INSTANCE.changedFeatures()); + // check initOptionsSelectedPreferencesList + List initOptionsSelectedPreferenceList = Whitebox + .getInternalState(SettingDataManager.INSTANCE, + "initOptionsSelectedPreferenceList"); + assertEquals(1, initOptionsSelectedPreferenceList.size()); + assertEquals(2001, initOptionsSelectedPreferenceList.get(0).getIndex()); + assertEquals(-1, initOptionsSelectedPreferenceList.get(0).getValue()); } + @Ignore + // Tests feature internal data, but Feature is outdated. + // TODO: mind about redesign this for FlatFeature. + // TODO: There are inner fields in FlatFeature, so, here is quite good place + // to test it. @Test public void testInitFeatureData() { FeatureData feature = Feature.SYSTEM_SAMPLING_RATE.getData(); @@ -116,6 +137,8 @@ public class SettingDataManagerTest { assertEquals(3, feature.getOverheadRanking()); } + @Ignore + // Tests template internal data, but Template is outdated. @Test public void testInitTemplateData() { TemplateData template = Template.TEMPLATE_BOTTLENECK.getData(); @@ -127,9 +150,10 @@ public class SettingDataManagerTest { public void testInitSettingData() { // check Available Target List Map targetListMap = setting.getTargetListMap(); - assertEquals(1, targetListMap.size()); + assertEquals(2, targetListMap.size()); assertTrue(targetListMap.get("mobile") != null); - assertFalse(targetListMap.get("wearable") != null); + assertTrue(targetListMap.get("wearable") != null); + assertFalse(targetListMap.get("tv") != null); // check Selected Target assertEquals("mobile", setting.getSelectedTarget()); @@ -138,17 +162,14 @@ public class SettingDataManagerTest { // check Selected Chart List Set chartSet = layout.getSelectedChartSet(); - assertEquals(3, chartSet.size()); - assertTrue(chartSet.contains("CPU")); - assertTrue(chartSet.contains("CPU core")); - assertTrue(chartSet.contains("CPU frequency")); + assertEquals(2, chartSet.size()); + assertTrue(chartSet.contains("CPU Usage")); + assertTrue(chartSet.contains("Core Usage")); // check Default Chart List chartSet = layout.getDefaultChartSet(); - assertEquals(3, chartSet.size()); - assertTrue(chartSet.contains("CPU")); - assertTrue(chartSet.contains("CPU core")); - assertTrue(chartSet.contains("CPU frequency")); + assertEquals(1, chartSet.size()); + assertTrue(chartSet.contains("Core Usage")); // check Default Protocol List List defaultFeatureList = setting.getDefaultFeatureList(); @@ -166,22 +187,21 @@ public class SettingDataManagerTest { assertEquals(15000000, totalOverheadRange.get(3).longValue()); // check Options Selected Feature List - List featureList = setting.getOptionsSelectedFeatureList(); - assertEquals(1, featureList.size()); - assertEquals(5002, featureList.get(0).getKey().getIndex()); - assertEquals(0, featureList.get(0).getValue()); - - featureList = Whitebox.getInternalState(setting, "initOptionsSelectedFeatureList"); - assertEquals(1, featureList.size()); - assertEquals(5002, featureList.get(0).getKey().getIndex()); - assertEquals(0, featureList.get(0).getValue()); + List flatPreferenceList = setting.getOptionsSelectedPreferencesList(); + assertEquals(1, flatPreferenceList.size()); + assertEquals(FlatPreferences.SOURCE_VIEW, flatPreferenceList.get(0)); + assertEquals(-1, flatPreferenceList.get(0).getValue()); + + flatPreferenceList = Whitebox.getInternalState(setting, "initOptionsSelectedPreferenceList"); + assertEquals(1, flatPreferenceList.size()); + assertEquals(FlatPreferences.SOURCE_VIEW, flatPreferenceList.get(0)); } @Test public void testWriteTargetData() { try { String result = Whitebox.invokeMethod(setting, "writeTargetData"); - assertEquals("Available Target List|mobile", result); + assertEquals("Available Target List|mobile|wearable", result); } catch (Exception e) { Logger.exception(e); } @@ -191,19 +211,16 @@ public class SettingDataManagerTest { public void testWriteChartList() { try { // check Selected Chart List - String result = Whitebox - .invokeMethod(layout, "writeCollection", (Object) layout.getSelectedChartSet(), + String result = Whitebox.invokeMethod(layout, "writeCollection", (Object) layout.getSelectedChartSet(), SettingConstants.KEY_SELECTED_CHART_LIST); - assertTrue(result.length() == 46); - assertTrue(result.startsWith("Selected Chart List|CPU")); - assertTrue(result.matches(".*CPU.*CPU.*CPU.*")); + assertTrue(result.length() == 40); + assertTrue(result.equals("Selected Chart List|CPU Usage|Core Usage")); // check Default Chart List result = Whitebox.invokeMethod(layout, "writeCollection", (Object) layout.getDefaultChartSet(), SettingConstants.KEY_DEFAULT_CHART_LIST); - assertTrue(result.length() == 45); - assertTrue(result.startsWith("Default Chart List|CPU")); - assertTrue(result.matches(".*CPU.*CPU.*CPU.*")); + assertTrue(result.length() == 29); + assertTrue(result.equals("Default Chart List|Core Usage")); } catch (Exception e) { Logger.exception(e); } @@ -233,16 +250,6 @@ public class SettingDataManagerTest { } @Test - public void testWriteOptionsSelectedFeatureListData() { - try { - String result = Whitebox.invokeMethod(setting, "writeOptionsSelectedFeatureListData"); - assertEquals("5002:0", result); - } catch (Exception e) { - Logger.exception(e); - } - } - - @Test public void testFeatureOperation() { try { String featureName = Feature.SYSTEM_ENERGY.getName(); @@ -317,7 +324,7 @@ public class SettingDataManagerTest { @Test public void testSettingOperation() { - TargetData target = setting.getTarget("wearable"); + TargetData target = setting.getTarget("not-wearable"); assertNull(target); target = setting.getTarget("mobile"); assertNotNull(target); @@ -327,17 +334,17 @@ public class SettingDataManagerTest { list = setting.getSelectedPageList("mobile"); assertFalse(list.isEmpty()); - assertEquals(2, list.size()); + assertEquals(1, list.size()); assertTrue(list.contains("Timeline")); - assertTrue(list.contains("Summary")); list = setting.getSelectedChartSet("test-target"); assertNull(list); list = setting.getSelectedChartSet("mobile"); assertNotNull(list); - assertEquals(1, list.size()); - assertTrue(list.contains("CPU")); + assertEquals(2, list.size()); + assertTrue(list.contains("CPU Usage")); + assertTrue(list.contains("Core Usage")); // options tab feature assertTrue(setting.isOptionsSelectedFeature(Feature.RECORDING)); @@ -386,27 +393,24 @@ public class SettingDataManagerTest { } @Test - public void testChangedFeatures() { + public void testChangedFlatFeatures() { // change target setting.setSelectedTarget("wearable"); assertTrue(setting.changedFeatures()); setting.setSelectedTarget("mobile"); // change options feature - setting.addOptionsSelectedFeature(Feature.SCREENSHOT_PERIODICALLY, 50); + setting.addOptionsSelectedPreference(FlatPreferences.SCREENSHOT_PERIODICALLY, 50); assertTrue(setting.changedFeatures()); // same size - setting.deleteOptionsSelectedFeature(Feature.RECORDING); + setting.deleteOptionsSelectedPreference(FlatPreferences.RECORDING); assertTrue(setting.changedFeatures()); // different input value - setting.deleteOptionsSelectedFeature(Feature.SCREENSHOT_PERIODICALLY); - setting.addOptionsSelectedFeature(Feature.RECORDING, 50); + setting.deleteOptionsSelectedPreference(FlatPreferences.SCREENSHOT_PERIODICALLY); + setting.addOptionsSelectedPreference(FlatPreferences.RECORDING, 50); assertTrue(setting.changedFeatures()); - - setting.revertSettingData(); - assertFalse(setting.changedFeatures()); } @Test @@ -423,10 +427,10 @@ public class SettingDataManagerTest { assertEquals("mobile", setting.getSelectedTarget()); // check selected options feature - List featureList = setting.getOptionsSelectedFeatureList(); - assertEquals(1, featureList.size()); - assertEquals(5002, featureList.get(0).getKey().getIndex()); - assertEquals(0, featureList.get(0).getValue()); + List flatPreferencesList = setting.getOptionsSelectedPreferencesList(); + assertEquals(1, flatPreferencesList.size()); + assertEquals(2001, flatPreferencesList.get(0).getIndex()); + assertEquals(-1, flatPreferencesList.get(0).getValue()); assertFalse(setting.changedFeatures()); } diff --git a/org.tizen.dynamicanalyzer.test/src/org/tizen/dynamicanalyzer/ui/toolbar/setting/data/TargetDataTest.java b/org.tizen.dynamicanalyzer.test/src/org/tizen/dynamicanalyzer/ui/toolbar/setting/data/TargetDataTest.java index 62858ca..6aaffc6 100644 --- a/org.tizen.dynamicanalyzer.test/src/org/tizen/dynamicanalyzer/ui/toolbar/setting/data/TargetDataTest.java +++ b/org.tizen.dynamicanalyzer.test/src/org/tizen/dynamicanalyzer/ui/toolbar/setting/data/TargetDataTest.java @@ -25,64 +25,56 @@ */ package org.tizen.dynamicanalyzer.ui.toolbar.setting.data; -import static java.lang.System.currentTimeMillis; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; import java.util.List; import java.util.Random; +import java.util.Set; import org.junit.AfterClass; +import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.powermock.reflect.Whitebox; +import org.tizen.dynamicanalyzer.common.Global; +import org.tizen.dynamicanalyzer.common.UIMode; import org.tizen.dynamicanalyzer.constant.CommonConstants; -import org.tizen.dynamicanalyzer.setting.Feature; -import org.tizen.dynamicanalyzer.setting.FeatureValueData; +import org.tizen.dynamicanalyzer.setting.FlatFeature; import org.tizen.dynamicanalyzer.setting.SettingConstants; import org.tizen.dynamicanalyzer.setting.TargetData; -import org.tizen.dynamicanalyzer.setting.Template; -import org.tizen.dynamicanalyzer.setting.TemplateData; import org.tizen.dynamicanalyzer.unittest.UnitTestConstants; -import org.tizen.dynamicanalyzer.unittest.UnitTestUtil; import org.tizen.dynamicanalyzer.util.InternalLogger; import org.tizen.dynamicanalyzer.util.Logger; public class TargetDataTest { static TargetData targetData = null; + static String flatFeatureCodes = "301|502|801|302|401|103|601|101|602|201|802|203|701|202|603|102|501"; @BeforeClass public static void initTargetData() { Logger.init(InternalLogger.DEBUG); targetData = new TargetData("mobile-2.3.0"); - + Global.setCurrentUIMode(UIMode.CLI); try { - // add available template list - String availableTemplateListData = "mobile-2.3.0|Available Template List|1|2|3|4|5|6|7|8|9|10"; - String list[] = availableTemplateListData - .split(SettingConstants.READ_CSV_SEPARATOR, -1); - Whitebox.invokeMethod(targetData, "makeAvailableTemplateList", (Object) list); - - // add selected template - targetData.setSelectedTemplate(Template.getTemplate(1)); + // add available FlatFeatures + String availableFlatFeatureListData = "mobile|Available FlatFeature List|"+flatFeatureCodes; + String list[] = availableFlatFeatureListData.split(SettingConstants.READ_CSV_SEPARATOR, -1); + Whitebox.invokeMethod(targetData, "makeAvailableFlatFeatureList", (Object) list); - // add available feature list - String availableFeatureListData = "mobile-2.3.0|Available Feature List|1|1000|3|4|5|6|7|8|100|101|1001|102|200|201|202|203|204"; - list = availableFeatureListData.split(SettingConstants.READ_CSV_SEPARATOR, -1); - Whitebox.invokeMethod(targetData, "makeAvailableFeatureList", (Object) list); - - // add selected feature list - String selectedFeatureListData = "mobile-2.3.0|Selected Feature List|1|5|1000:1000|100|101|1001:10"; - list = selectedFeatureListData.split(SettingConstants.READ_CSV_SEPARATOR, -1); - Whitebox.invokeMethod(targetData, "makeSelectedFeatureList", (Object) list); + // add selected FlatFeatures + String selectedFlatFeatureListData = "mobile|Selected FlatFeature List|201"; + list = selectedFlatFeatureListData.split(SettingConstants.READ_CSV_SEPARATOR, -1); + Whitebox.invokeMethod(targetData, "makeSelectedFlatFeatureList", (Object) list); // add available chart list - String availableChartListData = "mobile-2.3.0|Available Chart List|CPU|CPU core|CPU frequency|Heap allocation|" - + "Process Size|Memory|Screenshot|UI event|Disk IO|Network IO|Device|Energy"; + String availableChartListData = "mobile|Available Chart List|CPU Usage|Core Usage|Core Frequency|System Memory|Process Memory|Heap Allocation|Screenshot|UI Event|Disk IO|Network IO|Peripheral Status|Power Estimation"; list = availableChartListData.split(SettingConstants.READ_CSV_SEPARATOR, -1); Whitebox.invokeMethod(targetData, "makeAvailableChartList", (Object) list); @@ -91,105 +83,76 @@ public class TargetDataTest { } } + @Before + public void set_up() { + Set set = new HashSet(); + set.add(FlatFeature.SYSTEM_MEMORY); + targetData.setSelectedFlatFeatures(set); + targetData.applySettingData(); + } + @AfterClass public static void tesApplySettingData() { - // change selected template, feature - changeSelectedData(); - assertTrue(targetData.changedFeatures()); + // check initial FlatFeature set + Set initFlatFeatureSet = Whitebox.getInternalState(targetData, "initFlatFeatureSet"); - // apply selected template, feature - targetData.applySettingData(); + targetData.addSelectedFlatFeature(FlatFeature.CPU_USAGE.getName()); - // check init template - Template initTemplate = Whitebox.getInternalState(targetData, "initTemplate"); - assertEquals(9, initTemplate.getIndex()); + // apply selected FlatFeature + targetData.applySettingData(); - // check initFeatureList - List initFeatureList = Whitebox.getInternalState(targetData, - "initFeatureList"); - assertEquals(7, initFeatureList.size()); - assertEquals(204, initFeatureList.get(6).getKey().getIndex()); - assertEquals(0, initFeatureList.get(6).getValue()); + //check that settings applied + Set newInitFlatFeatureSet = Whitebox.getInternalState(targetData, "initFlatFeatureSet"); + assertEquals(targetData.getSelectedFlatFeatures().size(), initFlatFeatureSet.size()); + assertTrue(newInitFlatFeatureSet.containsAll(targetData.getSelectedFlatFeatures())); } @Test - public void testMakeAvailableTemplateList() { - List