Add copyright header to all source files
[lttng-ust-java-tests.git] / src / test / java / org / lttng / ust / agent / utils / LttngSession.java
1 /*
2 * Copyright (C) 2015, EfficiOS Inc., Alexandre Montplaisir <alexmonthy@efficios.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 package org.lttng.ust.agent.utils;
20
21 import java.io.IOException;
22 import java.lang.ProcessBuilder.Redirect;
23 import java.nio.file.FileVisitResult;
24 import java.nio.file.Files;
25 import java.nio.file.Path;
26 import java.nio.file.Paths;
27 import java.nio.file.SimpleFileVisitor;
28 import java.nio.file.attribute.BasicFileAttributes;
29 import java.util.Arrays;
30 import java.util.List;
31 import java.util.UUID;
32 import java.util.stream.Collectors;
33
34 public class LttngSession implements AutoCloseable {
35
36 public enum Domain {
37 JUL("-j"),
38 LOG4J("-l");
39
40 private final String flag;
41
42 private Domain(String flag) {
43 this.flag = flag;
44 }
45
46 public String flag() {
47 return flag;
48 }
49 }
50
51 private final String sessionName;
52 private final Domain domain;
53
54 private volatile boolean channelCreated = false;
55
56 public LttngSession(String sessionName, Domain domain) {
57 if (sessionName != null) {
58 this.sessionName = sessionName;
59 } else {
60 this.sessionName = UUID.randomUUID().toString();
61 }
62 this.domain = domain;
63
64 /* Create the session in LTTng */
65 executeCommand(Arrays.asList("lttng", "create", this.sessionName));
66 }
67
68 @Override
69 public void close() {
70 /* Destroy the session */
71 executeCommand(Arrays.asList("lttng", "destroy", sessionName));
72 // FIXME also delete the trace we generated ?
73 }
74
75 // ------------------------------------------------------------------------
76 // Public methods
77 // ------------------------------------------------------------------------
78
79 /**
80 * Enable all events in the given session (enable-event -a)
81 *
82 * @return If the command executed successfully (return code = 0).
83 */
84 public boolean enableAllEvents() {
85 channelCreated = true;
86 return executeCommand(Arrays.asList(
87 "lttng", "enable-event", domain.flag(), "-a", "-s", sessionName));
88 }
89
90 /**
91 * Enable individual event(s).
92 *
93 * @param enabledEvents
94 * The list of events to enable. Should not be null or empty
95 * @return If the command executed successfully (return code = 0).
96 */
97 public boolean enableEvents(String... enabledEvents) {
98 if (enabledEvents == null || enabledEvents.length == 0) {
99 throw new IllegalArgumentException();
100 }
101 channelCreated = true;
102 return executeCommand(Arrays.asList(
103 "lttng", "enable-event", domain.flag(),
104 Arrays.stream(enabledEvents).collect(Collectors.joining(",")),
105 "-s", sessionName));
106 }
107
108 /**
109 * Send a disable-event command. Used to disable events that were previously
110 * enabled.
111 *
112 * @param disabledEvents
113 * The list of disabled events. Should not be null or empty
114 * @return If the command executed successfully (return code = 0).
115 */
116 public boolean disableEvents(String... disabledEvents) {
117 if (disabledEvents == null || disabledEvents.length == 0) {
118 throw new IllegalArgumentException();
119 }
120 return executeCommand(Arrays.asList(
121 "lttng", "disable-event", domain.flag(),
122 Arrays.stream(disabledEvents).collect(Collectors.joining(",")),
123 "-s", sessionName));
124 }
125
126 public boolean start() {
127 /*
128 * We have to enable a channel for 'lttng start' to work. However, we
129 * cannot enable a channel directly, see
130 * https://bugs.lttng.org/issues/894 . Instead we will enable an event
131 * we know does not exist
132 */
133 if (!channelCreated) {
134 enableEvents("non-event");
135 }
136 return executeCommand(Arrays.asList("lttng", "start", sessionName));
137 }
138
139 /**
140 * Stop the tracing session
141 *
142 * @return If the command executed successfully (return code = 0).
143 */
144 public boolean stop() {
145 return executeCommand(Arrays.asList("lttng", "stop", sessionName));
146 }
147
148 /**
149 * Issue a "lttng view" command on the session, and returns its output. This
150 * effectively returns the current content of the trace in text form.
151 *
152 * @return The output of Babeltrace on the session's current trace
153 */
154 public List<String> view() {
155 return MiscTestUtils.getOutputFromCommand(Arrays.asList("lttng", "view", sessionName));
156 }
157
158 /**
159 * Utility method to destroy all existing sessions. Useful when first
160 * setting up a test to make sure no existing session interferes.
161 */
162 public static void destroyAllSessions() {
163 executeCommand(Arrays.asList("lttng", "destroy", "-a"));
164 }
165
166 /**
167 * Outside of the scope of lttng-tools, but this utility method can be used
168 * to delete all traces currently under ~/lttng-traces/. This can be used by
169 * tests to cleanup a trace they have created.
170 *
171 * @return True if the command completes successfully, false if there was an
172 * error.
173 */
174 public static boolean deleteAllTracee() {
175 String tracesDir = new String(System.getProperty("user.home") + "/lttng-traces/");
176 return deleteDirectory(Paths.get(tracesDir));
177 }
178
179 // ------------------------------------------------------------------------
180 // Private helper methods
181 // ------------------------------------------------------------------------
182
183 private static boolean deleteDirectory(Path directory) {
184 try {
185 Files.walkFileTree(directory, new SimpleFileVisitor<Path>() {
186 @Override
187 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
188 Files.delete(file);
189 return FileVisitResult.CONTINUE;
190 }
191
192 @Override
193 public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
194 Files.delete(dir);
195 return FileVisitResult.CONTINUE;
196 }
197 });
198 } catch (IOException e) {
199 /* At least we tried... */
200 return false;
201 }
202 return true;
203 }
204
205 /**
206 * Just to test the environment / stdout are working correctly
207 */
208 public static void main(String[] args) {
209 List<String> command = Arrays.asList("ls", "-l");
210 executeCommand(command);
211 }
212
213 private static boolean executeCommand(List<String> command) {
214 try {
215 ProcessBuilder builder = new ProcessBuilder(command);
216 builder.redirectErrorStream(true);
217 builder.redirectOutput(Redirect.INHERIT);
218
219 Process p = builder.start();
220 int ret = p.waitFor();
221 return (ret == 0);
222
223 } catch (IOException | InterruptedException e) {
224 return false;
225 }
226 }
227 }
This page took 0.034453 seconds and 4 git commands to generate.