blob: cd4e272f564cad735518edecd4f4ee7f9487d695 [file] [log] [blame]
/******************************************************************************
* Copyright (c) 2017, 2018 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
*
* Contributors:
* Patrick Tasse - Initial API and implementation
*******************************************************************************/
package org.eclipse.tracecompass.integration.swtbot.tests.projectexplorer;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.io.IOException;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.commons.io.FileUtils;
import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.Logger;
import org.apache.log4j.SimpleLayout;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner;
import org.eclipse.swtbot.swt.finder.utils.SWTBotPreferences;
import org.eclipse.swtbot.swt.finder.waits.Conditions;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotShell;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectRegistry;
import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.ConditionHelpers;
import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.SWTBotUtils;
import org.eclipse.tracecompass.tmf.ui.swtbot.tests.wizards.SWTBotImportWizardUtils;
import org.eclipse.tracecompass.tmf.ui.tests.shared.WaitUtils;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.MethodSorters;
/**
* SWTBot test for testing Project Explorer Refresh action
*/
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@RunWith(SWTBotJunit4ClassRunner.class)
public class ProjectExplorerRefreshTest {
private static final String TRACE_PROJECT_NAME = "test";
private static final String C_PROJECT_NAME = "c-project";
/** The Log4j logger instance. */
private static final Logger fLogger = Logger.getRootLogger();
private static final long DISK_ACCESS_TIMEOUT = 120000L;
private static final File TEST_TRACES_PATH = new File(new Path(TmfTraceManager.getTemporaryDirPath()).append("testtraces").toOSString());
private static final File TEST_FILE_KERNEL = new File(getPath("import/kernel-overlap-testing"));
private static final File TEST_FILE_KERNEL_CLASH = new File(getPath("import/z-clashes/kernel-overlap-testing"));
private static final File TEST_FILE_UST = new File(getPath("import/ust-overlap-testing"));
private static SWTWorkbenchBot fBot;
private static File fTracesFolder = null;
private static File fCProjectFolder = null;
private static String getPath(String relativePath) {
return new Path(TEST_TRACES_PATH.getAbsolutePath()).append(relativePath).toOSString();
}
/**
* Test Class setup
*
* @throws Exception
* on error
*/
@BeforeClass
public static void init() throws Exception {
TestDirectoryStructureUtil.generateTraceStructure(TEST_TRACES_PATH);
SWTBotUtils.initialize();
/* Set up for SWTBot */
SWTBotPreferences.TIMEOUT = 20000; /* 20 second timeout */
SWTBotPreferences.KEYBOARD_LAYOUT = "EN_US";
fLogger.removeAllAppenders();
fLogger.addAppender(new ConsoleAppender(new SimpleLayout(), ConsoleAppender.SYSTEM_OUT));
fBot = new SWTWorkbenchBot();
/* Finish waiting for eclipse to load */
WaitUtils.waitForJobs();
SWTBotUtils.createProject(TRACE_PROJECT_NAME);
IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(TRACE_PROJECT_NAME);
fTracesFolder = new File(Objects.requireNonNull(TmfProjectRegistry.getProject(project, true).getTracesFolder()).getResource().getLocation().toOSString());
createCProject(C_PROJECT_NAME);
setTracingNature(C_PROJECT_NAME);
IProject cProject = ResourcesPlugin.getWorkspace().getRoot().getProject(C_PROJECT_NAME);
fCProjectFolder = cProject.getLocation().toFile();
}
/**
* Test class tear down method.
*/
@AfterClass
public static void tearDown() {
SWTBotUtils.deleteProject(TRACE_PROJECT_NAME, fBot);
SWTBotUtils.deleteProject(C_PROJECT_NAME, fBot);
fLogger.removeAllAppenders();
}
/**
* Test tear down method.
*/
@After
public void afterTest() {
SWTBotUtils.closeSecondaryShells(fBot);
}
/**
* Test Refresh after adding a trace on the file system.
*
* @throws IOException if an exception occurs
*/
@Test
public void test16_01RefreshTraceAdded() throws IOException {
FileUtils.copyDirectory(TEST_FILE_KERNEL, FileUtils.getFile(fTracesFolder, TEST_FILE_KERNEL.getName()));
FileUtils.copyDirectory(TEST_FILE_UST, FileUtils.getFile(fTracesFolder, TEST_FILE_UST.getName()));
SWTBotTreeItem tracesFolder = SWTBotUtils.selectTracesFolder(fBot, TRACE_PROJECT_NAME);
assertEquals(0, tracesFolder.getItems().length);
refresh(() -> tracesFolder.contextMenu().menu("Refresh").click());
SWTBotTreeItem kernelTrace = SWTBotUtils.getTraceProjectItem(fBot, tracesFolder, TEST_FILE_KERNEL.getName());
kernelTrace.contextMenu().menu("Select Trace Type...", "Common Trace Format", "Linux Kernel Trace").click();
SWTBotTreeItem ustTrace = SWTBotUtils.getTraceProjectItem(fBot, tracesFolder, TEST_FILE_UST.getName());
ustTrace.contextMenu().menu("Select Trace Type...", "Common Trace Format", "LTTng UST Trace").click();
}
/**
* Test Refresh after modifying trace content while trace is opened.
*
* @throws IOException if an exception occurs
*/
@Test
public void test16_02RefreshOpenedTraceContentModified() throws IOException {
SWTBotTreeItem tracesFolder = SWTBotUtils.selectTracesFolder(fBot, TRACE_PROJECT_NAME);
SWTBotTreeItem kernelTrace = SWTBotUtils.getTraceProjectItem(fBot, tracesFolder, TEST_FILE_KERNEL.getName());
kernelTrace.contextMenu().menu("Open").click();
SWTBotUtils.activateEditor(fBot, TEST_FILE_KERNEL.getName());
tracesFolder.contextMenu().menu("Open As Experiment...", "Generic Experiment").click();
SWTBotUtils.activateEditor(fBot, "Experiment");
SWTBotTreeItem project = SWTBotUtils.selectProject(fBot, TRACE_PROJECT_NAME);
SWTBotTreeItem experiment = SWTBotUtils.getTraceProjectItem(fBot, project, "Experiments", "Experiment");
FileUtils.copyDirectory(TEST_FILE_KERNEL_CLASH, FileUtils.getFile(fTracesFolder, TEST_FILE_KERNEL.getName()), false);
// false -> last modified times are copied file time stamps
assertTrue(kernelTrace.contextMenu().menuItems().contains("Delete Supplementary Files..."));
assertTrue(experiment.contextMenu().menuItems().contains("Delete Supplementary Files..."));
refresh(() -> tracesFolder.contextMenu().menu("Refresh").click());
SWTBotShell shell = fBot.shell("Trace Changed");
shell.bot().button("No").click();
assertTrue(kernelTrace.contextMenu().menuItems().contains("Delete Supplementary Files..."));
assertTrue(experiment.contextMenu().menuItems().contains("Delete Supplementary Files..."));
SWTBotUtils.activateEditor(fBot, TEST_FILE_KERNEL.getName());
SWTBotUtils.activateEditor(fBot, "Experiment");
FileUtils.copyDirectory(TEST_FILE_KERNEL, FileUtils.getFile(fTracesFolder, TEST_FILE_KERNEL.getName()), true);
// true -> last modified times are original file time stamps
assertTrue(kernelTrace.contextMenu().menuItems().contains("Delete Supplementary Files..."));
refresh(() -> tracesFolder.contextMenu().menu("Refresh").click());
shell = fBot.shell("Trace Changed");
shell.bot().button("Yes").click();
SWTBotUtils.waitUntil(treeItem -> !treeItem.contextMenu().menuItems().contains("Delete Supplementary Files..."),
kernelTrace, "Supplementary Files did not get deleted");
assertEquals(0, fBot.editors().size());
}
/**
* Test Refresh after modifying trace content while trace is closed.
*
* @throws IOException if an exception occurs
*/
@Test
public void test16_03RefreshClosedTraceContentModified() throws IOException {
SWTBotTreeItem tracesFolder = SWTBotUtils.selectTracesFolder(fBot, TRACE_PROJECT_NAME);
SWTBotTreeItem kernelTrace = SWTBotUtils.getTraceProjectItem(fBot, tracesFolder, TEST_FILE_KERNEL.getName());
SWTBotTreeItem ustTrace = SWTBotUtils.getTraceProjectItem(fBot, tracesFolder, TEST_FILE_UST.getName());
kernelTrace.contextMenu().menu("Select Trace Type...", "Common Trace Format", "Linux Kernel Trace").click();
kernelTrace.contextMenu().menu("Open").click();
SWTBotUtils.activateEditor(fBot, TEST_FILE_KERNEL.getName()).close();
tracesFolder.contextMenu().menu("Open As Experiment...", "Generic Experiment").click();
SWTBotUtils.activateEditor(fBot, "Experiment").close();
SWTBotTreeItem project = SWTBotUtils.selectProject(fBot, TRACE_PROJECT_NAME);
SWTBotTreeItem experiment = SWTBotUtils.getTraceProjectItem(fBot, project, "Experiments", "Experiment");
FileUtils.touch(FileUtils.getFile(fTracesFolder, TEST_FILE_KERNEL.getName(), "channel1"));
FileUtils.deleteQuietly(FileUtils.getFile(fTracesFolder, TEST_FILE_UST.getName(), "channel0"));
assertTrue(kernelTrace.contextMenu().menuItems().contains("Delete Supplementary Files..."));
assertTrue(ustTrace.contextMenu().menuItems().contains("Delete Supplementary Files..."));
assertTrue(experiment.contextMenu().menuItems().contains("Delete Supplementary Files..."));
refresh(() -> tracesFolder.contextMenu().menu("Refresh").click());
SWTBotUtils.waitUntil(treeItem -> !treeItem.contextMenu().menuItems().contains("Delete Supplementary Files..."),
kernelTrace, "Supplementary Files did not get deleted");
SWTBotUtils.waitUntil(treeItem -> !treeItem.contextMenu().menuItems().contains("Delete Supplementary Files..."),
ustTrace, "Supplementary Files did not get deleted");
SWTBotUtils.waitUntil(treeItem -> !treeItem.contextMenu().menuItems().contains("Delete Supplementary Files..."),
experiment, "Supplementary Files did not get deleted");
}
/**
* Test Refresh after deleting a trace on the file system.
*
* @throws IOException if an exception occurs
*/
@Test
public void test16_04RefreshTraceDeleted() throws IOException {
SWTBotTreeItem tracesFolder = SWTBotUtils.selectTracesFolder(fBot, TRACE_PROJECT_NAME);
assertEquals(2, tracesFolder.getItems().length);
SWTBotUtils.getTraceProjectItem(fBot, tracesFolder, TEST_FILE_KERNEL.getName());
SWTBotUtils.getTraceProjectItem(fBot, tracesFolder, TEST_FILE_UST.getName());
FileUtils.deleteDirectory(FileUtils.getFile(fTracesFolder, TEST_FILE_UST.getName()));
refresh(() -> fBot.menu().menu("File", "Refresh").click());
assertEquals(1, tracesFolder.getItems().length);
SWTBotUtils.getTraceProjectItem(fBot, tracesFolder, TEST_FILE_KERNEL.getName());
}
/**
* Test refresh after deleting a trace in a c-project
*
* @throws IOException
* if an exception occurs
*/
@Test
public void test16_05CProjectRefreshTraceDeleted() throws IOException {
// Copy traces inside the c-project
FileUtils.copyDirectory(TEST_FILE_KERNEL, FileUtils.getFile(fCProjectFolder, TEST_FILE_KERNEL.getName()));
FileUtils.copyDirectory(TEST_FILE_UST, FileUtils.getFile(fCProjectFolder, TEST_FILE_UST.getName()));
SWTBotTreeItem project = SWTBotUtils.selectProject(fBot, C_PROJECT_NAME);
refresh(() -> project.contextMenu().menu("Refresh").click());
// Import traces in Trace Compass sub project as links
SWTBotTreeItem tracesFolder = SWTBotUtils.getTraceProjectItem(fBot, project, "Trace Compass", "Traces");
tracesFolder.contextMenu().menu("Import...").click();
SWTBotImportWizardUtils.selectImportFromDirectory(fBot, fCProjectFolder.getAbsolutePath());
SWTBotImportWizardUtils.selectFolder(fBot, true, C_PROJECT_NAME, TEST_FILE_KERNEL.getName());
SWTBotImportWizardUtils.selectFolder(fBot, true, C_PROJECT_NAME, TEST_FILE_UST.getName());
SWTBotShell shell = fBot.shell("Trace Import");
shell.bot().button("Finish").click();
fBot.waitUntil(Conditions.shellCloses(shell), DISK_ACCESS_TIMEOUT);
WaitUtils.waitForJobs();
// Be sure that the two traces are imported
tracesFolder.expand();
fBot.waitUntil(ConditionHelpers.treeItemCount(tracesFolder, 2));
// Create an experiment
tracesFolder.contextMenu().menu("Open As Experiment...", "Generic Experiment").click();
SWTBotUtils.activateEditor(fBot, "Experiment").close();
SWTBotTreeItem experiment = SWTBotUtils.getTraceProjectItem(fBot, project, "Trace Compass", "Experiments", "Experiment");
experiment.expand();
fBot.waitUntil(ConditionHelpers.treeItemCount(experiment, 5));
// Delete one trace from the c-project and verify that the trace is not in Trace Compass anymore
FileUtils.deleteDirectory(FileUtils.getFile(fCProjectFolder, TEST_FILE_UST.getName()));
refresh(() -> project.contextMenu().menu("Refresh").click());
fBot.waitUntil(ConditionHelpers.treeItemCount(tracesFolder, 1));
// Make sure that the experiment is still there and the trace is not there
fBot.waitUntil(ConditionHelpers.treeItemCount(experiment, 4));
// Delete the remaining trace from the c-project and verify that the trace is not in Trace Compass anymore
FileUtils.deleteDirectory(FileUtils.getFile(fCProjectFolder, TEST_FILE_KERNEL.getName()));
refresh(() -> project.contextMenu().menu("Refresh").click());
fBot.waitUntil(ConditionHelpers.treeItemCount(tracesFolder, 0));
// Experiments folder should be empty at this point
SWTBotTreeItem experimentsFolder = SWTBotUtils.getTraceProjectItem(fBot, project, "Trace Compass", "Experiments");
experimentsFolder.expand();
fBot.waitUntil(ConditionHelpers.treeItemCount(experimentsFolder, 0));
}
private static void createCProject(String projectName) throws CoreException {
IProgressMonitor monitor = new NullProgressMonitor();
IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
project.create(monitor);
project.open(monitor);
IProjectDescription description = project.getDescription();
description.setNatureIds(new String[] { "org.eclipse.cdt.core.cnature" });
project.setDescription(description, monitor);
project.open(monitor);
}
private static void setTracingNature(String projectName) {
SWTBotTreeItem projectItem = SWTBotUtils.selectProject(fBot, projectName);
projectItem.contextMenu().menu("Configure", "Configure or convert to Tracing Project").click();
WaitUtils.waitForJobs();
}
private static void refresh(Runnable runnable) {
AtomicBoolean resourceChanged = new AtomicBoolean();
IResourceChangeListener listener = event -> {
resourceChanged.set(true);
};
try {
ResourcesPlugin.getWorkspace().addResourceChangeListener(listener);
SWTBotUtils.waitUntil(refresh -> {
refresh.run();
return resourceChanged.get();
}, runnable, "Resource change event not received");
} finally {
ResourcesPlugin.getWorkspace().removeResourceChangeListener(listener);
}
}
}