3e10bd5ef813ef9e84c3b892ae31ff4dd266dfc8
[lttng-ust-java-tests.git] / src / org / lttng / ust / agent / utils / LttngSessionControl.java
1 package org.lttng.ust.agent.utils;
2
3 import java.io.IOException;
4 import java.lang.ProcessBuilder.Redirect;
5 import java.nio.file.FileVisitResult;
6 import java.nio.file.Files;
7 import java.nio.file.Path;
8 import java.nio.file.Paths;
9 import java.nio.file.SimpleFileVisitor;
10 import java.nio.file.attribute.BasicFileAttributes;
11 import java.util.ArrayList;
12 import java.util.Arrays;
13 import java.util.List;
14 import java.util.stream.Collectors;
15
16 public final class LttngSessionControl {
17
18 private LttngSessionControl() {}
19
20 public enum Domain {
21 JUL("-j"),
22 LOG4J("-l");
23
24 private final String flag;
25
26 private Domain(String flag) {
27 this.flag = flag;
28 }
29
30 public String flag() {
31 return flag;
32 }
33 }
34
35 // ------------------------------------------------------------------------
36 // Public utility methods
37 // ------------------------------------------------------------------------
38
39 /**
40 * Setup a LTTng session by enabling certain events (or none).
41 *
42 * @param sessionName
43 * The name of the session to create. May be null to use the
44 * default one from lttng-tools.
45 * @param domain
46 * The tracing domain
47 * @param enabledEvents
48 * The list of events to enable. May be null or empty, to not
49 * enable any events.
50 * @return If the command executed successfully (return code = 0).
51 */
52 public static boolean setupSession(String sessionName, Domain domain, String... enabledEvents) {
53 String[] createCommand = (sessionName == null ?
54 new String[] { "lttng", "create" } :
55 new String[] { "lttng", "create", sessionName}
56 );
57
58 String eventsToEnable = (enabledEvents == null || enabledEvents.length == 0 ?
59 /*
60 * We have to enable a channel for 'lttng start' to work.
61 * However, we cannot enable a channel directly, see
62 * https://bugs.lttng.org/issues/894 . Instead we will enable an
63 * event we know does not exist
64 */
65 "non-event" :
66 Arrays.stream(enabledEvents).collect(Collectors.joining(","))
67 );
68
69 return executeCommands(new String[][] {
70 createCommand,
71 { "lttng", "enable-event", domain.flag(), eventsToEnable},
72 { "lttng", "start" }
73 });
74 }
75
76 /**
77 * Setup a LTTng session with all events enabled (lttng enable-event -a).
78 *
79 * @param sessionName
80 * The name of the session to create. May be null to use the
81 * default one from lttng-tools.
82 * @param domain
83 * The tracing domain
84 * @return If the command executed successfully (return code = 0).
85 */
86 public static boolean setupSessionAllEvents(String sessionName, Domain domain) {
87 String[] createCommand = (sessionName == null ?
88 new String[] { "lttng", "create" } :
89 new String[] { "lttng", "create", sessionName}
90 );
91
92 return executeCommands(new String[][] {
93 createCommand,
94 { "lttng", "enable-event", domain.flag(), "-a" },
95 { "lttng", "start" }
96 });
97 }
98
99 /**
100 * Send a separate enable-event command.
101 *
102 * @param sessionName
103 * Name of the session in which to enable events. Use null for
104 * current session.
105 * @param domain
106 * The tracing domain
107 * @param enabledEvents
108 * The list of events to enable. Should not be null or empty
109 * @return If the command executed successfully (return code = 0).
110 */
111 public static boolean enableEvents(String sessionName, Domain domain, String... enabledEvents) {
112 if (enabledEvents == null || enabledEvents.length == 0) {
113 throw new IllegalArgumentException();
114 }
115 List<String> command = new ArrayList<String>();
116 command.add("lttng");
117 command.add("enable-event");
118 command.add(domain.flag());
119 command.add(Arrays.stream(enabledEvents).collect(Collectors.joining(",")));
120 if (sessionName != null) {
121 command.add("-s");
122 command.add(sessionName);
123 }
124 return executeCommand(command.toArray(new String[0]));
125 }
126
127 /**
128 * Send a disable-event command. Used to disable events that were previously
129 * enabled.
130 *
131 * @param sessionName
132 * Name of the session in which to disable events. Use null for
133 * current session.
134 * @param domain
135 * The tracing domain
136 * @param disabledEvents
137 * The list of disabled events. Should not be null or empty
138 * @return If the command executed successfully (return code = 0).
139 */
140 public static boolean disableEvents(String sessionName, Domain domain, String... disabledEvents) {
141 if (disabledEvents == null || disabledEvents.length == 0) {
142 throw new IllegalArgumentException();
143 }
144 List<String> command = new ArrayList<String>();
145 command.add("lttng");
146 command.add("disable-event");
147 command.add(domain.flag());
148 command.add(Arrays.stream(disabledEvents).collect(Collectors.joining(",")));
149 if (sessionName != null) {
150 command.add("-s");
151 command.add(sessionName);
152 }
153 return executeCommand(command.toArray(new String[0]));
154 }
155
156 /**
157 * Stop the current tracing session
158 *
159 * @param sessionName
160 * The name of the session to stop. Use null for the current
161 * session.
162 * @return If the command executed successfully (return code = 0).
163 */
164 public static boolean stopSession(String sessionName) {
165 List<String> command = new ArrayList<String>();
166 command.add("lttng");
167 command.add("stop");
168 if (sessionName != null) {
169 command.add(sessionName);
170 }
171 return executeCommand(command.toArray(new String[0]));
172 }
173
174 /**
175 * Issue a "lttng view" command on the provided session, and returns its
176 * output. This effectively returns the current content of the trace in text
177 * form.
178 *
179 * @param sessionName
180 * The name of the session to print. Use null for the current
181 * session.
182 * @return The output of Babeltrace on the session's current trace
183 */
184 public static List<String> viewSession(String sessionName) {
185 List<String> command = new ArrayList<String>();
186 command.add("lttng");
187 command.add("view");
188 if (sessionName != null) {
189 command.add(sessionName);
190 }
191 return getOutputFromCommand(command.toArray(new String[0]));
192 }
193
194 /**
195 * Destroy the current tracing session
196 *
197 * @param sessionName
198 * The name of the session to destroy. Use null for the current
199 * session.
200 * @return If the command executed successfully (return code = 0).
201 */
202 public static boolean destroySession(String sessionName) {
203 List<String> command = new ArrayList<String>();
204 command.add("lttng");
205 command.add("destroy");
206 if (sessionName != null) {
207 command.add(sessionName);
208 }
209 return executeCommand(command.toArray(new String[0]));
210 }
211
212 /**
213 * Try destroying the given tracing session, fail silently if there is no
214 * session.
215 *
216 * @param sessionName
217 * The name of the session to destroy. Use null for the current
218 * session.
219 */
220 public static void tryDestroySession(String sessionName) {
221 getOutputFromCommand(false, new String[] { "lttng", "destroy" });
222 }
223
224 /**
225 * Outside of the scope of lttng-tools, but this utility method can be used
226 * to delete all traces currently under ~/lttng-traces/. This can be used by
227 * tests to cleanup a trace they have created.
228 *
229 * @return True if the command completes successfully, false if there was an
230 * error.
231 */
232 public static boolean deleteAllTracee() {
233 String tracesDir = new String(System.getProperty("user.home") + "/lttng-traces/");
234 return deleteDirectory(Paths.get(tracesDir));
235 }
236
237 private static boolean deleteDirectory(Path directory) {
238 try {
239 Files.walkFileTree(directory, new SimpleFileVisitor<Path>() {
240 @Override
241 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
242 Files.delete(file);
243 return FileVisitResult.CONTINUE;
244 }
245
246 @Override
247 public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
248 Files.delete(dir);
249 return FileVisitResult.CONTINUE;
250 }
251 });
252 } catch (IOException e) {
253 /* At least we tried... */
254 return false;
255 }
256 return true;
257 }
258
259 // ------------------------------------------------------------------------
260 // Private helper methods
261 // ------------------------------------------------------------------------
262
263 private static boolean executeCommands(String [][] commands) {
264 for (String[] command : commands) {
265 if (executeCommand(command) == false) {
266 return false;
267 }
268 }
269 return true;
270 }
271
272 /**
273 * Just to test the environment / stdout are working correctly
274 */
275 public static void main(String[] args) {
276 executeCommand(new String[] {"ls", "-l"});
277 }
278
279 private static boolean executeCommand(String[] command) {
280 try {
281 ProcessBuilder builder = new ProcessBuilder(command);
282 builder.redirectErrorStream(true);
283 builder.redirectOutput(Redirect.INHERIT);
284
285 Process p = builder.start();
286 int ret = p.waitFor();
287 return (ret == 0);
288
289 } catch (IOException | InterruptedException e) {
290 return false;
291 }
292 }
293
294 private static List<String> getOutputFromCommand(String[] command) {
295 return getOutputFromCommand(true, command);
296 }
297
298 private static List<String> getOutputFromCommand(boolean print, String[] command) {
299 try {
300 Path tempFile = Files.createTempFile("test-output", null);
301
302 ProcessBuilder builder = new ProcessBuilder(command);
303 builder.redirectErrorStream(true);
304 builder.redirectOutput(Redirect.to(tempFile.toFile()));
305
306 Process p = builder.start();
307 p.waitFor();
308
309 List<String> lines = Files.readAllLines(tempFile);
310 Files.delete(tempFile);
311
312 if (print) {
313 /* Also print the output to the console */
314 lines.stream().forEach(s -> System.out.println(s));
315 }
316
317 return lines;
318
319 } catch (IOException | InterruptedException e) {
320 return null;
321 }
322 }
323 }
This page took 0.035292 seconds and 3 git commands to generate.