| /****************************************************************************** |
| * Copyright (c) 2016, 2017 Ericsson |
| * |
| * All rights reserved. This program and the accompanying materials are |
| * made available under the terms of the Eclipse Public License 2.0 which |
| * accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| *******************************************************************************/ |
| |
| package org.eclipse.tracecompass.integration.swtbot.tests.projectexplorer; |
| |
| import static org.junit.Assert.assertTrue; |
| |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.FileNotFoundException; |
| import java.io.FileOutputStream; |
| import java.io.IOException; |
| import java.io.PrintWriter; |
| import java.util.zip.GZIPOutputStream; |
| import java.util.zip.ZipEntry; |
| import java.util.zip.ZipOutputStream; |
| |
| import org.apache.commons.compress.archivers.tar.TarArchiveEntry; |
| import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream; |
| import org.eclipse.tracecompass.ctf.core.tests.shared.LttngTraceGenerator; |
| |
| /** |
| * Util class to create directory structures detailed in chapter 3 of the |
| * projectView test |
| * |
| * @author Matthew Khouzam |
| */ |
| public class TestDirectoryStructureUtil { |
| |
| private static final String CUSTOM_TEXT_PARSER_CONTENT = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>" |
| + "<CustomTxtTraceDefinitionList>" |
| + "<Definition name=\"TmfGeneric\">" |
| + "<TimeStampOutputFormat>yyyy-MM-dd HH:mm:ss.SSS</TimeStampOutputFormat>" |
| + "<InputLine><Cardinality max=\"2147483647\" min=\"0\"/>" |
| + "<RegEx>\\s*\\[(\\d*\\.\\d*)\\]\\s*\\[TID=(\\d*)\\]\\s*\\[(SIG|CMP|EVT|REQ)\\]\\s*(.*)</RegEx>" |
| + "<InputData action=\"0\" format=\"ss.SSS\" name=\"Time Stamp\"/>" |
| + "<InputData action=\"0\" format=\"\" name=\"Thread ID\"/>" |
| + "<InputData action=\"0\" format=\"\" name=\"Type\"/>" |
| + "<InputData action=\"0\" format=\"\" name=\"Message\"/>" |
| + "</InputLine><OutputColumn name=\"Time Stamp\"/>" |
| + "<OutputColumn name=\"Thread ID\"/>" |
| + "<OutputColumn name=\"Type\"/>" |
| + "<OutputColumn name=\"Message\"/>" |
| + "</Definition>" |
| + "</CustomTxtTraceDefinitionList>"; |
| |
| private static final String CUSTOM_XML_PARSER_CONTENT = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>" |
| + "<CustomXMLTraceDefinitionList><Definition name=\"Custom XML Log\">" |
| + "<TimeStampOutputFormat>yyyy-MM-dd HH:mm:ss.SSS</TimeStampOutputFormat>" |
| + "<InputElement name=\"Log\"><InputElement logentry=\"true\" name=\"Record\">" |
| + "<InputData action=\"0\" format=\"\" name=\"Ignore\"/>" |
| + "<Attribute name=\"number\"><InputData action=\"0\" format=\"\" name=\"Rec Num\"/>" |
| + "</Attribute><InputElement name=\"Time\">" |
| + "<InputData action=\"0\" format=\"'year:'yyyy | 'month:'MM | 'day:'dd | 'hour:'HH | 'minute:'mm | 'second:'ss\" name=\"Time Stamp\"/></InputElement>" |
| + "<InputElement name=\"Content\"><InputData action=\"0\" format=\"\" name=\"Message\"/></InputElement>" |
| + "</InputElement></InputElement><OutputColumn name=\"Time Stamp\"/>" |
| + "<OutputColumn name=\"Rec Num\"/><OutputColumn name=\"Message\"/>" |
| + "</Definition></CustomXMLTraceDefinitionList>"; |
| |
| private static final String CUSTOM_TEXT_LAST_LINE = "[1371742192.049] [TID=001] [SIG] Sig=TmfEndSynchSignal Target=(end)\n"; |
| private static final String CUSTOM_TEXT_CONTENT = "[1371742192.034] [TID=001] [SIG] Sig=TmfStartSynchSignal Target=(start)\n" + |
| "[1371742192.048] [TID=001] [SIG] Sig=TmfStartSynchSignal Target=(end)\n" + |
| "[1371742192.048] [TID=001] [SIG] Sig=TmfStartSynchSignal Target=(start)\n" + |
| "[1371742192.048] [TID=001] [SIG] Sig=TmfStartSynchSignal Target=(end)\n" + |
| "[1371742192.048] [TID=001] [SIG] Sig=TmfTimestampFormatUpdateSignal Target=(start)\n" + |
| "[1371742192.048] [TID=001] [SIG] Sig=TmfTimestampFormatUpdateSignal Target=(end)\n" + |
| "[1371742192.049] [TID=001] [SIG] Sig=TmfTimestampFormatUpdateSignal Target=(start)\n" + |
| "[1371742192.049] [TID=001] [SIG] Sig=TmfTimestampFormatUpdateSignal Target=(end)\n" + |
| "[1371742192.049] [TID=001] [SIG] Sig=TmfEndSynchSignal Target=(start)\n" + |
| CUSTOM_TEXT_LAST_LINE; |
| |
| private static final String CUSTOM_XML_PARSER_LAST_LINE = "" |
| + "<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>" |
| + "<Level>The Log Level</Level>" + "</Content>" + "</Record>"; |
| private static final String CUSTOM_XML_CONTENT = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>" |
| + "<!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>" |
| + "<hour> 22 </hour> <minute> 0 </minute> <second> 25 </second>" + "</Time>" + "</LogCreated>" |
| + "" |
| + "<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>" |
| + "<Level>The Log Level</Level>" + "</Content>" + "</Record>" |
| + "" |
| + "<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>" |
| + "<Level>The Log Level</Level>" + "" + "</Content>" + "</Record>" |
| + "" |
| + "<Record number = \"3\">" + "<Time>" + "<year> 2011 </year> <month> 10 </month> <day> 26 </day>" + "<hour> 22 </hour> <minute> 3 </minute> <second> 17 </second>" + "</Time>" + "<Content>" |
| + "<Message>This is the message</Message>" + "<Level>The Log Level</Level>" + "</Content>" + "</Record>" |
| + "" |
| + "<Record number = \"4\">" + "<Time>" + "<year> 2011 </year> <month> 10 </month> <day> 26 </day>" + "<hour> 22 </hour> <minute> 4 </minute> <second> 30 </second>" + "</Time>" |
| + "<Content>" + "<Message>This is the message</Message>" + "<Level>The Log Level</Level>" + "</Content>" + "</Record>" |
| + "" |
| + "<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>" |
| + "<Level>The Log Level</Level>" + "</Content>" + "</Record>" |
| + CUSTOM_XML_PARSER_LAST_LINE; |
| |
| private static final String UNRECOGNIZED_LOG_CONTENT = "Hi mom!"; |
| |
| private TestDirectoryStructureUtil() { |
| // do nothing |
| } |
| |
| /** |
| * Generate a directory structure as follows |
| * |
| * <pre> |
| * parentDir |
| * ├── archives |
| * │ ├── traces.zip |
| * │ └── traces.tar.gz |
| * ├── customParsers |
| * │ ├── ExampleCustomTxtParser.xml |
| * │ └── ExampleCustomXmlParser.xml |
| * └── import |
| * ├── z-clashes |
| * │ ├── ExampleCustomTxt.log |
| * │ ├── ExampleCustomXml.xml |
| * │ ├── kernel-overlap-testing |
| * │ │ ├── channel0 |
| * │ │ └── metadata |
| * │ ├── simple_server-thread1 |
| * │ │ ├── channel0 |
| * │ │ └── metadata |
| * │ ├── simple_server-thread2 |
| * │ │ ├── channel0 |
| * │ │ └── metadata |
| * │ └── ust-overlap-testing |
| * │ ├── channel0 |
| * │ └── metadata |
| * ├── empty |
| * ├── ExampleCustomTxt.log |
| * ├── ExampleCustomXml.xml |
| * ├── kernel-overlap-testing |
| * │ ├── channel0 |
| * │ └── metadata |
| * ├── simple_server-thread1 |
| * │ ├── channel0 |
| * │ └── metadata |
| * ├── simple_server-thread2 |
| * │ ├── channel0 |
| * │ └── metadata |
| * ├── unrecognized.log |
| * └── ust-overlap-testing |
| * ├── channel0 |
| * └── metadata |
| * </pre> |
| * |
| * @param parentDir |
| * the directory to use as the parent |
| * @return the structure detailed above |
| * @throws IOException |
| * out of space or permission problem |
| */ |
| public static File generateTraceStructure(File parentDir) throws IOException { |
| File parent = (parentDir == null) ? File.createTempFile("Traces", "") : parentDir; |
| if (!parent.isDirectory()) { |
| parent.delete(); |
| parent.mkdir(); |
| } |
| File customParser = createDir(parent, "customParsers"); |
| createFile(customParser, "ExampleCustomTxtParser.xml", CUSTOM_TEXT_PARSER_CONTENT); |
| createFile(customParser, "ExampleCustomXmlParser.xml", CUSTOM_XML_PARSER_CONTENT); |
| File importDir = createDir(parent, "import"); |
| createDir(importDir, "empty"); |
| createFile(importDir, "ExampleCustomTxt.log", CUSTOM_TEXT_CONTENT); |
| createFile(importDir, "ExampleCustomXml.xml", CUSTOM_XML_CONTENT); |
| createFile(importDir, "unrecognized.log", UNRECOGNIZED_LOG_CONTENT); |
| // Using the z- prefix so that the traces in this folder are imported |
| // last by the import wizard |
| final String CLASHES_DIR_NAME = "z-clashes"; |
| File theClash = createDir(importDir, CLASHES_DIR_NAME); |
| |
| // We're making the clash version of each trace slightly different in content to help differentiate them |
| createFile(theClash, "ExampleCustomTxt.log", CUSTOM_TEXT_CONTENT + CUSTOM_TEXT_LAST_LINE); |
| createFile(theClash, "ExampleCustomXml.xml", CUSTOM_XML_CONTENT + CUSTOM_XML_PARSER_LAST_LINE); |
| |
| LttngTraceGenerator kernelGenerator = new LttngTraceGenerator(1000, 1000, 1); |
| LttngTraceGenerator ustGenerator = new LttngTraceGenerator(1000, 1000, 1, false); |
| kernelGenerator.writeTrace(new File(importDir.getAbsolutePath() + File.separator + "kernel-overlap-testing")); |
| ustGenerator.writeTrace(new File(importDir.getAbsolutePath() + File.separator + "ust-overlap-testing")); |
| ustGenerator.writeTrace(new File(importDir.getAbsolutePath() + File.separator + "simple_server-thread1")); |
| ustGenerator.writeTrace(new File(importDir.getAbsolutePath() + File.separator + "simple_server-thread2")); |
| |
| kernelGenerator = new LttngTraceGenerator(1001, 1001, 1); |
| ustGenerator = new LttngTraceGenerator(1001, 1001, 1, false); |
| kernelGenerator.writeTrace(new File(importDir.getAbsolutePath() + File.separator + CLASHES_DIR_NAME + File.separator + "kernel-overlap-testing")); |
| ustGenerator.writeTrace(new File(importDir.getAbsolutePath() + File.separator + CLASHES_DIR_NAME + File.separator + "ust-overlap-testing")); |
| ustGenerator.writeTrace(new File(importDir.getAbsolutePath() + File.separator + CLASHES_DIR_NAME + File.separator + "simple_server-thread1")); |
| ustGenerator.writeTrace(new File(importDir.getAbsolutePath() + File.separator + CLASHES_DIR_NAME + File.separator + "simple_server-thread2")); |
| |
| assertTrue(parent.listFiles().length > 0); |
| |
| File archivesDir = createDir(parent, "archives"); |
| File zipFile = new File(archivesDir.getAbsolutePath() + File.separator + "traces.zip"); |
| try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFile))) { |
| addToArchive(zos, importDir, importDir); |
| } |
| File targzFile = new File(archivesDir.getAbsolutePath() + File.separator + "traces.tar.gz"); |
| try (TarArchiveOutputStream tgzos = new TarArchiveOutputStream(new GZIPOutputStream(new FileOutputStream(targzFile)))) { |
| addToArchive(tgzos, importDir, importDir); |
| } |
| return parent; |
| } |
| |
| private static File createDir(File parent, String name) { |
| File child = new File(parent.getAbsolutePath() + File.separator + name); |
| child.mkdir(); |
| return child; |
| } |
| |
| private static File createFile(File parent, String name, String content) throws FileNotFoundException { |
| File child = new File(parent.getAbsolutePath() + File.separator + name); |
| try (PrintWriter pw = new PrintWriter(new FileOutputStream(child))) { |
| pw.write(content); |
| } |
| return child; |
| } |
| |
| private static void addToArchive(ZipOutputStream zos, File dir, File root) throws IOException { |
| byte[] buffer = new byte[1024]; |
| int length; |
| int index = root.getAbsolutePath().length(); |
| for (File file : dir.listFiles()) { |
| String name = file.getAbsolutePath().substring(index); |
| if (file.isDirectory()) { |
| if (file.listFiles().length != 0) { |
| addToArchive(zos, file, root); |
| } else { |
| zos.putNextEntry(new ZipEntry(name + File.separator)); |
| zos.closeEntry(); |
| } |
| } else { |
| try (FileInputStream fis = new FileInputStream(file)) { |
| zos.putNextEntry(new ZipEntry(name)); |
| while ((length = fis.read(buffer)) > 0) { |
| zos.write(buffer, 0, length); |
| } |
| zos.closeEntry(); |
| } |
| } |
| } |
| } |
| |
| private static void addToArchive(TarArchiveOutputStream taos, File dir, File root) throws IOException { |
| byte[] buffer = new byte[1024]; |
| int length; |
| int index = root.getAbsolutePath().length(); |
| for (File file : dir.listFiles()) { |
| String name = file.getAbsolutePath().substring(index); |
| if (file.isDirectory()) { |
| if (file.listFiles().length != 0) { |
| addToArchive(taos, file, root); |
| } else { |
| taos.putArchiveEntry(new TarArchiveEntry(name + File.separator)); |
| taos.closeArchiveEntry(); |
| } |
| } else { |
| try (FileInputStream fis = new FileInputStream(file)) { |
| TarArchiveEntry entry = new TarArchiveEntry(name); |
| entry.setSize(file.length()); |
| taos.putArchiveEntry(entry); |
| while ((length = fis.read(buffer)) > 0) { |
| taos.write(buffer, 0, length); |
| } |
| taos.closeArchiveEntry(); |
| } |
| } |
| } |
| } |
| } |