1 /**********************************************************************
2 * Copyright (c) 2012, 2015 Ericsson
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * Bernd Hufmann - Initial API and implementation
11 * Markus Schorn - Bug 448058: Use org.eclipse.remote in favor of RSE
12 **********************************************************************/
13 package org
.eclipse
.tracecompass
.internal
.lttng2
.control
.stubs
.shells
;
15 import static org
.eclipse
.tracecompass
.common
.core
.NonNullUtils
.checkNotNull
;
17 import java
.io
.BufferedReader
;
18 import java
.io
.DataInputStream
;
19 import java
.io
.FileInputStream
;
20 import java
.io
.IOException
;
21 import java
.io
.InputStreamReader
;
22 import java
.util
.ArrayList
;
23 import java
.util
.Collection
;
24 import java
.util
.HashMap
;
25 import java
.util
.Iterator
;
26 import java
.util
.List
;
28 import java
.util
.regex
.Matcher
;
29 import java
.util
.regex
.Pattern
;
31 import org
.eclipse
.core
.commands
.ExecutionException
;
32 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
33 import org
.eclipse
.tracecompass
.tmf
.remote
.core
.shell
.ICommandInput
;
34 import org
.eclipse
.tracecompass
.tmf
.remote
.core
.shell
.ICommandResult
;
36 @SuppressWarnings("javadoc")
37 public class LTTngToolsFileShell
extends TestCommandShell
{
39 // ------------------------------------------------------------------------
41 // ------------------------------------------------------------------------
42 private final static String SCENARIO_KEY
= "<SCENARIO>";
43 private final static String SCENARIO_END_KEY
= "</SCENARIO>";
44 private final static String INPUT_KEY
= "<COMMAND_INPUT>";
45 private final static String INPUT_END_KEY
= "</COMMAND_INPUT>";
46 private final static String RESULT_KEY
= "<COMMAND_RESULT>";
47 private final static String OUTPUT_KEY
= "<COMMAND_OUTPUT>";
48 private final static String OUTPUT_END_KEY
= "</COMMAND_OUTPUT>";
49 private final static String ERROR_OUTPUT_KEY
= "<COMMAND_ERROR_OUTPUT>";
50 private final static String ERROR_OUTPUT_END_KEY
= "</COMMAND_ERROR_OUTPUT>";
51 private final static String COMMENT_KEY
= "#.*";
53 private final static Pattern LTTNG_LIST_SESSION_PATTERN
= Pattern
.compile("lttng\\s+list\\s+(.+)");
54 private final static String LTTNG_LIST_PROVIDER_PATTERN
= "lttng\\s+list\\s+(-u|-k)";
56 // ------------------------------------------------------------------------
58 // ------------------------------------------------------------------------
59 private String fScenariofile
;
60 private String fScenario
;
62 private final Map
<String
, Map
<String
, ICommandResult
>> fScenarioMap
= new HashMap
<>();
63 private final Map
<String
, Integer
> fSessionNameMap
= new HashMap
<>();
66 * Parse a scenario file with the format:
72 * <COMMAND_INPUT>
74 * </COMMAND_INPUT>
76 * <COMMAND_RESULT>
78 * </COMMAND_RESULT>
80 * <COMMAND_OUTPUT>
82 * <COMMAND_ERROR_OUTPUT>
84 * </COMMAND_ERROR_OUTPUT>
85 * </COMMAND_OUTPUT>
89 * Where: ScenarioName - is the scenario name
90 * Command - the command line string
91 * CommandResult - the result integer of the command (0 for success, 1 for failure)
92 * CommandOutput - the command output string (multi-line possible)
93 * CommandErrorOutput - the command error output string (multi-line possible)
95 * Note: 1) There can be many scenarios per file
96 * 2) There can be many (Command-CommandResult-CommandOutput) triples per scenario
97 * 3) Lines starting with # will be ignored (comments)
100 * @param scenariofile - path to scenario file
102 public synchronized void loadScenarioFile(String scenariofile
) {
103 fScenariofile
= scenariofile
;
106 Collection
<Map
<String
, ICommandResult
>> values
= fScenarioMap
.values();
107 for (Iterator
<Map
<String
, ICommandResult
>> iterator
= values
.iterator(); iterator
.hasNext();) {
108 Map
<String
, ICommandResult
> map
= iterator
.next();
111 fScenarioMap
.clear();
116 try (FileInputStream fstream
= new FileInputStream(fScenariofile
);
117 DataInputStream in
= new DataInputStream(fstream
);
118 BufferedReader br
= new BufferedReader(new InputStreamReader(in
));) {
121 // Read File Line by Line
123 // Temporary map for generating instance numbers for lttng list
124 // <session> commands.
125 // The numbers are per scenario.
126 Map
<String
, Integer
> tmpSessionNameMap
= new HashMap
<>();
127 while ((strLine
= br
.readLine()) != null) {
130 if (isComment(strLine
)) {
134 if (SCENARIO_KEY
.equals(strLine
)) {
138 strLine
= br
.readLine();
139 while (isComment(strLine
)) {
140 strLine
= br
.readLine();
143 String scenario
= strLine
;
144 Map
<String
, ICommandResult
> commandMap
= new HashMap
<>();
145 fScenarioMap
.put(scenario
, commandMap
);
146 List
<String
> output
= null;
147 List
<String
> errorOutput
= null;
149 boolean inOutput
= false;
150 boolean inErrorOutput
= false;
152 tmpSessionNameMap
.clear();
153 while ((strLine
= br
.readLine()) != null) {
155 if (isComment(strLine
)) {
159 if (SCENARIO_END_KEY
.equals(strLine
)) {
160 // Scenario is finished
163 if (INPUT_KEY
.equals(strLine
)) {
164 strLine
= br
.readLine();
166 while (isComment(strLine
)) {
167 strLine
= br
.readLine();
172 // Handle instances of 'lttng list
174 Matcher matcher
= LTTNG_LIST_SESSION_PATTERN
.matcher(strLine
);
175 if (matcher
.matches() && !input
.matches(LTTNG_LIST_PROVIDER_PATTERN
)) {
176 String sessionName
= matcher
.group(1).trim();
177 Integer i
= tmpSessionNameMap
.get(sessionName
);
183 tmpSessionNameMap
.put(sessionName
, i
);
184 input
+= String
.valueOf(i
);
186 } else if (INPUT_END_KEY
.equals(strLine
)) {
187 // Initialize output array
188 output
= new ArrayList
<>();
189 errorOutput
= new ArrayList
<>();
190 } else if (RESULT_KEY
.equals(strLine
)) {
191 strLine
= br
.readLine();
193 while (isComment(strLine
)) {
194 strLine
= br
.readLine();
197 result
= Integer
.parseInt(strLine
);
198 } else if (OUTPUT_END_KEY
.equals(strLine
)) {
199 // Save output/result in command map
200 if (output
!= null && errorOutput
!= null) {
201 commandMap
.put(input
, new CommandResultStub(result
,
202 checkNotNull(output
.toArray(new String
[output
.size()])),
203 checkNotNull(errorOutput
.toArray(new String
[errorOutput
.size()]))));
206 } else if (OUTPUT_KEY
.equals(strLine
)) {
207 // first line of output
209 } else if (ERROR_OUTPUT_KEY
.equals(strLine
)) {
210 // first line of output
211 inErrorOutput
= true;
212 } else if (ERROR_OUTPUT_END_KEY
.equals(strLine
)) {
213 inErrorOutput
= false;
214 } else if (inOutput
) {
215 while (isComment(strLine
)) {
216 strLine
= br
.readLine();
218 // lines of output/error output
219 if (errorOutput
!= null && inErrorOutput
) {
220 errorOutput
.add(strLine
);
221 } else if (output
!= null) {
226 // if (RESULT_END_KEY.equals(strLine)) {
232 } catch (IOException e
) {
237 // Set the scenario to consider in executeCommand()
238 public synchronized void setScenario(String scenario
) {
239 fScenario
= scenario
;
240 fSessionNameMap
.clear();
241 if (!fScenarioMap
.containsKey(fScenario
)) {
242 throw new IllegalArgumentException();
247 public synchronized ICommandResult
executeCommand(ICommandInput command
, IProgressMonitor monitor
) throws ExecutionException
{
248 Map
<String
, ICommandResult
> commands
= fScenarioMap
.get(fScenario
);
249 String commandLine
= command
.toString();
250 String fullCommand
= commandLine
;
252 Matcher matcher
= LTTNG_LIST_SESSION_PATTERN
.matcher(commandLine
);
253 if (matcher
.matches() && !commandLine
.matches(LTTNG_LIST_PROVIDER_PATTERN
)) {
254 String sessionName
= matcher
.group(1).trim();
255 Integer i
= fSessionNameMap
.get(sessionName
);
261 fSessionNameMap
.put(sessionName
, i
);
262 fullCommand
+= String
.valueOf(i
);
265 if (commands
.containsKey(fullCommand
)) {
266 return checkNotNull(commands
.get(fullCommand
));
269 String
[] output
= new String
[1];
270 output
[0] = String
.valueOf("Command not found");
271 CommandResultStub result
= new CommandResultStub(1, output
, output
);
275 // ------------------------------------------------------------------------
277 // ------------------------------------------------------------------------
279 private static boolean isComment(String line
) {
281 throw new RuntimeException("line is null");
283 return line
.matches(COMMENT_KEY
);