1 /******************************************************************************
2 * Copyright (c) 2016 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
8 *******************************************************************************/
10 package org
.eclipse
.tracecompass
.integration
.swtbot
.tests
.projectexplorer
;
12 import static org
.junit
.Assert
.assertTrue
;
15 import java
.io
.FileInputStream
;
16 import java
.io
.FileNotFoundException
;
17 import java
.io
.FileOutputStream
;
18 import java
.io
.IOException
;
19 import java
.io
.PrintWriter
;
20 import java
.util
.zip
.GZIPOutputStream
;
21 import java
.util
.zip
.ZipEntry
;
22 import java
.util
.zip
.ZipOutputStream
;
24 import org
.apache
.commons
.compress
.archivers
.tar
.TarArchiveEntry
;
25 import org
.apache
.commons
.compress
.archivers
.tar
.TarArchiveOutputStream
;
26 import org
.eclipse
.tracecompass
.ctf
.core
.tests
.shared
.LttngTraceGenerator
;
29 * Util class to create directory structures detailed in chapter 3 of the
32 * @author Matthew Khouzam
34 public class TestDirectoryStructureUtil
{
36 private static final String CUSTOM_TEXT_PARSER_CONTENT
= "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>"
37 + "<CustomTxtTraceDefinitionList>"
38 + "<Definition name=\"TmfGeneric\">"
39 + "<TimeStampOutputFormat>yyyy-MM-dd HH:mm:ss.SSS</TimeStampOutputFormat>"
40 + "<InputLine><Cardinality max=\"2147483647\" min=\"0\"/>"
41 + "<RegEx>\\s*\\[(\\d*\\.\\d*)\\]\\s*\\[TID=(\\d*)\\]\\s*\\[(SIG|CMP|EVT|REQ)\\]\\s*(.*)</RegEx>"
42 + "<InputData action=\"0\" format=\"ss.SSS\" name=\"Time Stamp\"/>"
43 + "<InputData action=\"0\" format=\"\" name=\"Thread ID\"/>"
44 + "<InputData action=\"0\" format=\"\" name=\"Type\"/>"
45 + "<InputData action=\"0\" format=\"\" name=\"Message\"/>"
46 + "</InputLine><OutputColumn name=\"Time Stamp\"/>"
47 + "<OutputColumn name=\"Thread ID\"/>"
48 + "<OutputColumn name=\"Type\"/>"
49 + "<OutputColumn name=\"Message\"/>"
51 + "</CustomTxtTraceDefinitionList>";
53 private static final String CUSTOM_XML_PARSER_CONTENT
= "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>"
54 + "<CustomXMLTraceDefinitionList><Definition name=\"Custom XML Log\">"
55 + "<TimeStampOutputFormat>yyyy-MM-dd HH:mm:ss.SSS</TimeStampOutputFormat>"
56 + "<InputElement name=\"Log\"><InputElement logentry=\"true\" name=\"Record\">"
57 + "<InputData action=\"0\" format=\"\" name=\"Ignore\"/>"
58 + "<Attribute name=\"number\"><InputData action=\"0\" format=\"\" name=\"Rec Num\"/>"
59 + "</Attribute><InputElement name=\"Time\">"
60 + "<InputData action=\"0\" format=\"'year:'yyyy | 'month:'MM | 'day:'dd | 'hour:'HH | 'minute:'mm | 'second:'ss\" name=\"Time Stamp\"/></InputElement>"
61 + "<InputElement name=\"Content\"><InputData action=\"0\" format=\"\" name=\"Message\"/></InputElement>"
62 + "</InputElement></InputElement><OutputColumn name=\"Time Stamp\"/>"
63 + "<OutputColumn name=\"Rec Num\"/><OutputColumn name=\"Message\"/>"
64 + "</Definition></CustomXMLTraceDefinitionList>";
66 private static final String CUSTOM_TEXT_LAST_LINE
= "[1371742192.049] [TID=001] [SIG] Sig=TmfEndSynchSignal Target=(end)\n";
67 private static final String CUSTOM_TEXT_CONTENT
= "[1371742192.034] [TID=001] [SIG] Sig=TmfStartSynchSignal Target=(start)\n" +
68 "[1371742192.048] [TID=001] [SIG] Sig=TmfStartSynchSignal Target=(end)\n" +
69 "[1371742192.048] [TID=001] [SIG] Sig=TmfStartSynchSignal Target=(start)\n" +
70 "[1371742192.048] [TID=001] [SIG] Sig=TmfStartSynchSignal Target=(end)\n" +
71 "[1371742192.048] [TID=001] [SIG] Sig=TmfTimestampFormatUpdateSignal Target=(start)\n" +
72 "[1371742192.048] [TID=001] [SIG] Sig=TmfTimestampFormatUpdateSignal Target=(end)\n" +
73 "[1371742192.049] [TID=001] [SIG] Sig=TmfTimestampFormatUpdateSignal Target=(start)\n" +
74 "[1371742192.049] [TID=001] [SIG] Sig=TmfTimestampFormatUpdateSignal Target=(end)\n" +
75 "[1371742192.049] [TID=001] [SIG] Sig=TmfEndSynchSignal Target=(start)\n" +
76 CUSTOM_TEXT_LAST_LINE
;
78 private static final String CUSTOM_XML_PARSER_LAST_LINE
= ""
79 + "<Record number = \"6\">" + "<Time>" + "<year> 2011 </year> <month> 10 </month> <day> 26 </day>" + "<hour> 22 </hour> <minute> 18 </minute> <second> 32 </second>" + "</Time>" + "<Content>" + "<Message>This is the message</Message>"
80 + "<Level>The Log Level</Level>" + "</Content>" + "</Record>";
81 private static final String CUSTOM_XML_CONTENT
= "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>"
82 + "<!DOCTYPE Log SYSTEM \"ExampleXMLLog.dtd\">\r\n\r\n<Log>" + "<LogCreated>" + "<LogName> Example XML Log </LogName>" + "<Time>" + "<year> 2011 </year> <month> 10 </month> <day> 26 </day>"
83 + "<hour> 22 </hour> <minute> 0 </minute> <second> 25 </second>" + "</Time>" + "</LogCreated>"
85 + "<Record number = \"1\">" + "<Time>" + "<year> 2011 </year> <month> 10 </month> <day> 26 </day>" + "<hour> 22 </hour> <minute> 1 </minute> <second> 20 </second>" + "</Time>" + "<Content>" + "<Message>This is the message</Message>"
86 + "<Level>The Log Level</Level>" + "</Content>" + "</Record>"
88 + "<Record number = \"2\">" + "<Time>" + "<year> 2011 </year> <month> 10 </month> <day> 26 </day>" + "<hour> 22 </hour> <minute> 2 </minute> <second> 11 </second>" + "</Time>" + "<Content>" + "<Message>This is the message</Message>"
89 + "<Level>The Log Level</Level>" + "" + "</Content>" + "</Record>"
91 + "<Record number = \"3\">" + "<Time>" + "<year> 2011 </year> <month> 10 </month> <day> 26 </day>" + "<hour> 22 </hour> <minute> 3 </minute> <second> 17 </second>" + "</Time>" + "<Content>"
92 + "<Message>This is the message</Message>" + "<Level>The Log Level</Level>" + "</Content>" + "</Record>"
94 + "<Record number = \"4\">" + "<Time>" + "<year> 2011 </year> <month> 10 </month> <day> 26 </day>" + "<hour> 22 </hour> <minute> 4 </minute> <second> 30 </second>" + "</Time>"
95 + "<Content>" + "<Message>This is the message</Message>" + "<Level>The Log Level</Level>" + "</Content>" + "</Record>"
97 + "<Record number = \"5\">" + "<Time>" + "<year> 2011 </year> <month> 10 </month> <day> 26 </day>" + "<hour> 22 </hour> <minute> 5 </minute> <second> 17 </second>" + "</Time>" + "<Content>" + "<Message>This is the message</Message>"
98 + "<Level>The Log Level</Level>" + "</Content>" + "</Record>"
99 + CUSTOM_XML_PARSER_LAST_LINE
;
101 private static final String UNRECOGNIZED_LOG_CONTENT
= "Hi mom!";
103 private TestDirectoryStructureUtil() {
108 * Generate a directory structure as follows
113 * │  ├── traces.zip
114 * │  └── traces.tar.gz
115 * ├── customParsers
116 * │  ├── ExampleCustomTxtParser.xml
117 * │  └── ExampleCustomXmlParser.xml
119 * ├── z-clashes
120 * │  ├── ExampleCustomTxt.log
121 * │  ├── ExampleCustomXml.xml
122 * │  ├── kernel-overlap-testing
123 * │  │  ├── stream
124 * │  │  └── metadata
125 * │  ├── simple_server-thread1
126 * │  │  ├── stream
127 * │  │  └── metadata
128 * │  ├── simple_server-thread2
129 * │  │  ├── stream
130 * │  │  └── metadata
131 * │  └── ust-overlap-testing
132 * │  ├── stream
133 * │  └── metadata
135 * ├── ExampleCustomTxt.log
136 * ├── ExampleCustomXml.xml
137 * ├── kernel-overlap-testing
138 * │  ├── stream
139 * │  └── metadata
140 * ├── simple_server-thread1
141 * │  ├── metadata
142 * │  └── stream
143 * ├── simple_server-thread2
144 * │  ├── metadata
145 * │  └── stream
146 * ├── unrecognized.log
147 * └── ust-overlap-testing
153 * the directory to use as the parent
154 * @return the structure detailed above
155 * @throws IOException
156 * out of space or permission problem
158 public static File
generateTraceStructure(File parentDir
) throws IOException
{
159 File parent
= (parentDir
== null) ? File
.createTempFile("Traces", "") : parentDir
;
160 if (!parent
.isDirectory()) {
164 File customParser
= createDir(parent
, "customParsers");
165 createFile(customParser
, "ExampleCustomTxtParser.xml", CUSTOM_TEXT_PARSER_CONTENT
);
166 createFile(customParser
, "ExampleCustomXmlParser.xml", CUSTOM_XML_PARSER_CONTENT
);
167 File importDir
= createDir(parent
, "import");
168 createDir(importDir
, "empty");
169 createFile(importDir
, "ExampleCustomTxt.log", CUSTOM_TEXT_CONTENT
);
170 createFile(importDir
, "ExampleCustomXml.xml", CUSTOM_XML_CONTENT
);
171 createFile(importDir
, "unrecognized.log", UNRECOGNIZED_LOG_CONTENT
);
172 // Using the z- prefix so that the traces in this folder are imported
173 // last by the import wizard
174 final String CLASHES_DIR_NAME
= "z-clashes";
175 File theClash
= createDir(importDir
, CLASHES_DIR_NAME
);
177 // We're making the clash version of each trace slightly different in content to help differentiate them
178 createFile(theClash
, "ExampleCustomTxt.log", CUSTOM_TEXT_CONTENT
+ CUSTOM_TEXT_LAST_LINE
);
179 createFile(theClash
, "ExampleCustomXml.xml", CUSTOM_XML_CONTENT
+ CUSTOM_XML_PARSER_LAST_LINE
);
181 LttngTraceGenerator kernelGenerator
= new LttngTraceGenerator(1000, 1000, 1);
182 LttngTraceGenerator ustGenerator
= new LttngTraceGenerator(1000, 1000, 1, false);
183 kernelGenerator
.writeTrace(new File(importDir
.getAbsolutePath() + File
.separator
+ "kernel-overlap-testing"));
184 ustGenerator
.writeTrace(new File(importDir
.getAbsolutePath() + File
.separator
+ "ust-overlap-testing"));
185 ustGenerator
.writeTrace(new File(importDir
.getAbsolutePath() + File
.separator
+ "simple_server-thread1"));
186 ustGenerator
.writeTrace(new File(importDir
.getAbsolutePath() + File
.separator
+ "simple_server-thread2"));
188 kernelGenerator
= new LttngTraceGenerator(1000, 1001, 1);
189 ustGenerator
= new LttngTraceGenerator(1000, 1001, 1, false);
190 kernelGenerator
.writeTrace(new File(importDir
.getAbsolutePath() + File
.separator
+ CLASHES_DIR_NAME
+ File
.separator
+ "kernel-overlap-testing"));
191 ustGenerator
.writeTrace(new File(importDir
.getAbsolutePath() + File
.separator
+ CLASHES_DIR_NAME
+ File
.separator
+ "ust-overlap-testing"));
192 ustGenerator
.writeTrace(new File(importDir
.getAbsolutePath() + File
.separator
+ CLASHES_DIR_NAME
+ File
.separator
+ "simple_server-thread1"));
193 ustGenerator
.writeTrace(new File(importDir
.getAbsolutePath() + File
.separator
+ CLASHES_DIR_NAME
+ File
.separator
+ "simple_server-thread2"));
195 assertTrue(parent
.listFiles().length
> 0);
197 File archivesDir
= createDir(parent
, "archives");
198 File zipFile
= new File(archivesDir
.getAbsolutePath() + File
.separator
+ "traces.zip");
199 try (ZipOutputStream zos
= new ZipOutputStream(new FileOutputStream(zipFile
))) {
200 addToArchive(zos
, importDir
, importDir
);
202 File targzFile
= new File(archivesDir
.getAbsolutePath() + File
.separator
+ "traces.tar.gz");
203 try (TarArchiveOutputStream tgzos
= new TarArchiveOutputStream(new GZIPOutputStream(new FileOutputStream(targzFile
)))) {
204 addToArchive(tgzos
, importDir
, importDir
);
209 private static File
createDir(File parent
, String name
) {
210 File child
= new File(parent
.getAbsolutePath() + File
.separator
+ name
);
215 private static File
createFile(File parent
, String name
, String content
) throws FileNotFoundException
{
216 File child
= new File(parent
.getAbsolutePath() + File
.separator
+ name
);
217 try (PrintWriter pw
= new PrintWriter(new FileOutputStream(child
))) {
223 private static void addToArchive(ZipOutputStream zos
, File dir
, File root
) throws IOException
{
224 byte[] buffer
= new byte[1024];
226 int index
= root
.getAbsolutePath().length();
227 for (File file
: dir
.listFiles()) {
228 String name
= file
.getAbsolutePath().substring(index
);
229 if (file
.isDirectory()) {
230 if (file
.listFiles().length
!= 0) {
231 addToArchive(zos
, file
, root
);
233 zos
.putNextEntry(new ZipEntry(name
+ File
.separator
));
237 try (FileInputStream fis
= new FileInputStream(file
)) {
238 zos
.putNextEntry(new ZipEntry(name
));
239 while ((length
= fis
.read(buffer
)) > 0) {
240 zos
.write(buffer
, 0, length
);
248 private static void addToArchive(TarArchiveOutputStream taos
, File dir
, File root
) throws IOException
{
249 byte[] buffer
= new byte[1024];
251 int index
= root
.getAbsolutePath().length();
252 for (File file
: dir
.listFiles()) {
253 String name
= file
.getAbsolutePath().substring(index
);
254 if (file
.isDirectory()) {
255 if (file
.listFiles().length
!= 0) {
256 addToArchive(taos
, file
, root
);
258 taos
.putArchiveEntry(new TarArchiveEntry(name
+ File
.separator
));
259 taos
.closeArchiveEntry();
262 try (FileInputStream fis
= new FileInputStream(file
)) {
263 TarArchiveEntry entry
= new TarArchiveEntry(name
);
264 entry
.setSize(file
.length());
265 taos
.putArchiveEntry(entry
);
266 while ((length
= fis
.read(buffer
)) > 0) {
267 taos
.write(buffer
, 0, length
);
269 taos
.closeArchiveEntry();