/*******************************************************************************
* Copyright (c) 2016 Ericsson
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v1.0 which
* accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.tracecompass.tmf.ui.swtbot.tests.viewers.events;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
import static org.junit.Assume.assumeTrue;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.Logger;
import org.apache.log4j.SimpleLayout;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.swt.SWT;
import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotEditor;
import org.eclipse.swtbot.swt.finder.SWTBot;
import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner;
import org.eclipse.swtbot.swt.finder.keyboard.Keyboard;
import org.eclipse.swtbot.swt.finder.keyboard.KeyboardFactory;
import org.eclipse.swtbot.swt.finder.keyboard.Keystrokes;
import org.eclipse.swtbot.swt.finder.utils.SWTBotPreferences;
import org.eclipse.swtbot.swt.finder.waits.Conditions;
import org.eclipse.swtbot.swt.finder.waits.ICondition;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotTable;
import org.eclipse.tracecompass.tmf.core.tests.TmfCoreTestPlugin;
import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
import org.eclipse.tracecompass.tmf.ui.dialog.TmfFileDialogFactory;
import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.SWTBotUtils;
import org.eclipse.tracecompass.tmf.ui.tests.shared.WaitUtils;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import com.google.common.collect.ImmutableList;
/**
* SWTBot test for testing export to tsv.
*/
@RunWith(SWTBotJunit4ClassRunner.class)
@NonNullByDefault
public class ExportToTsvTest {
private static final class FileLargerThanZeroCondition implements ICondition {
private File fFile;
public FileLargerThanZeroCondition(File file) {
fFile = file;
}
@Override
public boolean test() throws Exception {
return fFile.length() >= 1;
}
@Override
public void init(@Nullable SWTBot bot) {
// nothing
}
@Override
public String getFailureMessage() {
return "File is still of length 0 : " + fFile.getAbsolutePath();
}
}
private static final String HEADER_TEXT = "Timestamp\tHost\tLogger\tFile\tLine\tMessage";
private static final String EVENT1_TEXT = "01:01:01.000 000 000\tHostA\tLoggerA\tSourceFile\t4\tMessage A";
private static final String EVENT2_TEXT = "02:02:02.000 000 000\tHostB\tLoggerB\tSourceFile\t5\tMessage B";
private static final String EVENT3_TEXT = "03:03:03.000 000 000\tHostC\tLoggerC\tSourceFile\t6\tMessage C";
@SuppressWarnings("null")
private static final Keyboard KEYBOARD = KeyboardFactory.getSWTKeyboard();
private static final String TRACE_PROJECT_NAME = "test";
private static final String TRACE_NAME = "syslog_collapse";
private static final String TRACE_PATH = "testfiles/" + TRACE_NAME;
private static final String TRACE_TYPE = "org.eclipse.linuxtools.tmf.tests.stubs.trace.text.testsyslog";
private static final String EXPORT_TO_TSV = "Export To Text...";
private static final int TIMEOUT = 2000; /* 20 second timeout */
private @Nullable static File fTestFile = null;
private static SWTWorkbenchBot fBot = new SWTWorkbenchBot();
private @Nullable SWTBotEditor fEditorBot;
private @Nullable String fAbsolutePath;
/** The Log4j logger instance. */
@SuppressWarnings("null")
private static final Logger fLogger = Logger.getRootLogger();
/**
* Test Class setup
*/
@BeforeClass
public static void beforeClass() {
SWTBotUtils.initialize();
/* set up test trace */
URL location = FileLocator.find(TmfCoreTestPlugin.getDefault().getBundle(), new Path(TRACE_PATH), null);
URI uri;
try {
uri = FileLocator.toFileURL(location).toURI();
fTestFile = new File(uri);
} catch (URISyntaxException | IOException e) {
fail(e.getMessage());
}
File testFile = fTestFile;
assertNotNull(testFile);
assumeTrue(testFile.exists());
/* Set up for swtbot */
SWTBotPreferences.TIMEOUT = TIMEOUT;
SWTBotPreferences.KEYBOARD_LAYOUT = "EN_US";
fLogger.removeAllAppenders();
fLogger.addAppender(new ConsoleAppender(new SimpleLayout(), ConsoleAppender.SYSTEM_OUT));
fBot = new SWTWorkbenchBot();
/* Close welcome view */
SWTBotUtils.closeView("Welcome", fBot);
/* Switch perspectives */
SWTBotUtils.switchToTracingPerspective();
/* Finish waiting for eclipse to load */
WaitUtils.waitForJobs();
SWTBotUtils.createProject(TRACE_PROJECT_NAME);
}
/**
* Test class tear down method.
*/
@AfterClass
public static void afterClass() {
SWTBotUtils.deleteProject(TRACE_PROJECT_NAME, fBot);
fLogger.removeAllAppenders();
}
/**
* Before Test
*/
@Before
public void before() {
File testFile = fTestFile;
assertNotNull(testFile);
SWTBotUtils.openTrace(TRACE_PROJECT_NAME, testFile.getAbsolutePath(), TRACE_TYPE);
fEditorBot = SWTBotUtils.activateEditor(fBot, testFile.getName());
fAbsolutePath = TmfTraceManager.getTemporaryDirPath() + File.separator + "exportToTsvTest.tsv";
TmfFileDialogFactory.setOverrideFiles(fAbsolutePath);
}
/**
* After Test
*/
@After
public void after() {
fBot.closeAllEditors();
}
/**
* Test export a single selection
*
* @throws IOException
* File not found or such
*/
@Test
public void testExportSingleSelection() throws IOException {
assumeTrue(!isAffectedByBug486302());
SWTBotEditor editorBot = fEditorBot;
assertNotNull(editorBot);
final SWTBotTable tableBot = editorBot.bot().table();
tableBot.getTableItem(0).click(3);
KEYBOARD.typeText("LoggerA");
KEYBOARD.pressShortcut(Keystrokes.CTRL, Keystrokes.CR);
fBot.waitUntil(Conditions.tableHasRows(tableBot, 4), 5000);
tableBot.contextMenu(EXPORT_TO_TSV).click();
assertTsvContentsEquals(ImmutableList.of(HEADER_TEXT, EVENT1_TEXT));
}
/**
* Test export multiple selection
*
* @throws IOException
* File not found or such
*/
@Test
public void testExportMultipleSelection() throws IOException {
assumeTrue(!isAffectedByBug486302());
SWTBotEditor editorBot = fEditorBot;
assertNotNull(editorBot);
final SWTBotTable tableBot = editorBot.bot().table();
tableBot.getTableItem(0).click(3);
KEYBOARD.typeText("LoggerA|LoggerB|LoggerC");
KEYBOARD.pressShortcut(Keystrokes.CTRL, Keystrokes.CR);
fBot.waitUntil(Conditions.tableHasRows(tableBot, 6), 5000);
tableBot.contextMenu(EXPORT_TO_TSV).click();
assertTsvContentsEquals(ImmutableList.of(HEADER_TEXT, EVENT1_TEXT, EVENT2_TEXT, EVENT3_TEXT));
}
/**
* Returns whether or not the running Eclipse is affected by Bug 486302. The
* bug is present in Eclipse 4.5.2 and earlier running GTK3.
*/
private static boolean isAffectedByBug486302() {
String property = System.getProperty("org.eclipse.swt.internal.gtk.version");
if (property != null) {
@NonNull
String @NonNull [] versionSegments = property.split("\\.");
if (versionSegments.length > 0) {
return SWT.getVersion() <= 4530 && versionSegments[0].equals("3");
}
}
return false;
}
/**
* Test full export
*
* @throws IOException
* File not found or such
*/
@Test
public void testExportNoSelection() throws IOException {
SWTBotEditor editorBot = fEditorBot;
assertNotNull(editorBot);
final SWTBotTable tableBot = editorBot.bot().table();
tableBot.getTableItem(1).click();
KEYBOARD.pressShortcut(Keystrokes.SHIFT, Keystrokes.UP);
tableBot.contextMenu(EXPORT_TO_TSV).click();
File file = new File(fAbsolutePath);
fBot.waitUntil(new FileLargerThanZeroCondition(file));
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
long lines = br.lines().count();
assertEquals("Both reads", 23, lines);
} finally {
new File(fAbsolutePath).delete();
}
}
private void assertTsvContentsEquals(final List<String> expected) throws FileNotFoundException, IOException {
File file = new File(fAbsolutePath);
fBot.waitUntil(new FileLargerThanZeroCondition(file));
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
List<String> lines = br.lines().collect(Collectors.toList());
assertEquals("Both reads", expected, lines);
} finally {
file.delete();
}
}
}