Skip to main content
aboutsummaryrefslogblamecommitdiffstats
blob: ab34a752609405c18e12b00ee13b1477e3449a7f (plain) (tree)
1
2
3
4
5
6
7
8
                                                                                
                                                                                     




                                                                                 
                                                      











































                                                                                 
                                                                           































































































































































































































































































































































































                                                                                                                                                                                                          
                                                                          











                                                                                                         
                                                                                  





                                                                
                                        



                                                                                                                     
                                                        






























































































































































































































                                                                                                                                                                                          
/*******************************************************************************
 * Copyright (c) 2011, 2014 Wind River Systems, Inc. and others. 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
 *
 * Contributors:
 * Wind River Systems - initial API and implementation
 *******************************************************************************/
package org.eclipse.tcf.te.tests;

import java.io.IOException;
import java.lang.reflect.Field;
import java.net.URL;
import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Properties;

import junit.framework.AssertionFailedError;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestListener;
import junit.framework.TestResult;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.swt.widgets.Display;
import org.eclipse.tcf.te.runtime.interfaces.IConditionTester;
import org.eclipse.tcf.te.runtime.utils.Host;
import org.eclipse.tcf.te.tests.activator.UIPlugin;
import org.eclipse.tcf.te.tests.interfaces.IConfigurationProperties;
import org.eclipse.tcf.te.ui.views.interfaces.IUIConstants;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IViewReference;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.WorkbenchException;
import org.osgi.framework.Bundle;

/**
 * Core test case implementation.
 */
public class CoreTestCase extends TestCase {
	// Internal property id to store if or if not the views zoom action
	// got changed before executing the test case.
	private final static String VIEW_ZOOM_STATE_CHANGED = "viewZoomStateChanged"; //$NON-NLS-1$

	// The test configuration
	private final Properties configuration = new Properties();

	// The internal test listener.
	private final TestListener listener = new InternalTestListener();

	/**
	 * Listens to the test executions and logs the failures.
	 */
	private class InternalTestListener implements TestListener {

		/**
		 * Constructor.
		 */
		public InternalTestListener() {
		}

		/* (non-Javadoc)
		 * @see junit.framework.TestListener#startTest(junit.framework.Test)
		 */
		@Override
		public void startTest(Test test) {
		}

		/* (non-Javadoc)
		 * @see junit.framework.TestListener#addError(junit.framework.Test, java.lang.Throwable)
		 */
		@Override
		public synchronized void addError(Test test, Throwable error) {
			if (test != null && error != null) {
				// Log the error to the error log.
				IStatus status = new Status(IStatus.ERROR,
				                            UIPlugin.getUniqueIdentifier(),
				                            1,
				                            "Test case '" + test + "' failed with error. Possible cause: " + error.getLocalizedMessage(), //$NON-NLS-1$ //$NON-NLS-2$
				                            error
				                           );
				UIPlugin.getDefault().getLog().log(status);
			}
		}

		/* (non-Javadoc)
		 * @see junit.framework.TestListener#addFailure(junit.framework.Test, junit.framework.AssertionFailedError)
		 */
		@Override
		public synchronized void addFailure(Test test, AssertionFailedError failure) {
			if (test != null && failure != null) {
				// Log the failure to the error log.
				IStatus status = new Status(IStatus.ERROR,
											UIPlugin.getUniqueIdentifier(),
				                            1,
				                            "Test case '" + test + "' failed. Failure: " + failure.getLocalizedMessage(), //$NON-NLS-1$ //$NON-NLS-2$
				                            failure
				                           );
				UIPlugin.getDefault().getLog().log(status);
			}
		}

		/* (non-Javadoc)
		 * @see junit.framework.TestListener#endTest(junit.framework.Test)
		 */
		@Override
		public void endTest(Test test) {
			// nothing to do on end test
		}
	}

	/**
	 * Constructor.
	 */
	public CoreTestCase() {
		this(null);
	}

	/**
	 * Constructor.
	 *
	 * @param name The test name.
	 */
	public CoreTestCase(String name) {
		super(name);

		// Setup the test case configuration. Clear out the old configuration.
		configuration.clear();
		initialize();
	}

	/**
	 * Initialize the test configuration.
	 * <p>
	 * Clients may overwrite this method to modify the base configuration.
	 */
	protected void initialize() {
		Assert.isNotNull(configuration);

		setProperty(VIEW_ZOOM_STATE_CHANGED, false);
		setProperty(IConfigurationProperties.MAXIMIZE_VIEW, false);

		setProperty(IConfigurationProperties.TARGET_PERSPECTIVE, "org.eclipse.tcf.te.ui.perspective"); //$NON-NLS-1$
		setProperty(IConfigurationProperties.TARGET_VIEW, IUIConstants.ID_EXPLORER);
	}

	/**
	 * Sets a boolean configuration property.
	 *
	 * @param key The property key. Must not be <code>null</code>!
	 * @param value The property value.
	 */
	protected final void setProperty(String key, boolean value) {
		Assert.isNotNull(key);
		setProperty(key, value ? Boolean.TRUE.toString() : Boolean.FALSE.toString());
	}

	/**
	 * Checks if a boolean configuration property has been set to the
	 * given property value.
	 *
	 * @param key The property key. Must not be <code>null</code>!
	 * @param value The property value.
	 *
	 * @return <code>True</code> if the property values match, <code>false</code> if not.
	 */
	protected final boolean isProperty(String key, boolean value) {
		Assert.isNotNull(key);
		return (value ? Boolean.TRUE : Boolean.FALSE).equals(Boolean.valueOf(configuration.getProperty(key, "false"))); //$NON-NLS-1$
	}

	/**
	 * Sets a string configuration property.
	 * <p>
	 * If the value is <code>null</code>, the configuration property
	 * will be removed.
	 *
	 * @param key The property key. Must not be <code>null</code>!
	 * @param value The property value.
	 */
	protected final void setProperty(String key, String value) {
		Assert.isNotNull(key);
		if (value != null) configuration.setProperty(key, value);
		else configuration.remove(key);
	}

	/**
	 * Checks if a string configuration property has been set to the given property
	 * value (case insensitive).
	 * <p>
	 * If the value is <code>null</code>, the method returns <code>true</code> if
	 * the configuration property cannot be found.
	 *
	 * @param key The property key. Must not be <code>null</code>!
	 * @param value The property value.
	 *
	 * @return <code>True</code> if the property values match, <code>false</code> if not.
	 */
	protected final boolean isProperty(String key, String value) {
		Assert.isNotNull(key);
		return value != null ? value.equalsIgnoreCase(configuration.getProperty(key)) : !configuration.containsKey(key);
	}

	/**
	 * Returns the value of a string configuration property.
	 *
	 * @param key The property key. Must not be <code>null</code>!
	 * @return The property value or <code>null</code> if not set.
	 */
	protected final String getProperty(String key) {
		Assert.isNotNull(key);
		return configuration.getProperty(key, null);
	}

	/* (non-Javadoc)
	 * @see junit.framework.TestCase#run(junit.framework.TestResult)
	 */
	@Override
	public void run(TestResult result) {
		if (result != null) result.addListener(listener);
		super.run(result);
		if (result != null) result.removeListener(listener);
	}

	/* (non-Javadoc)
	 * @see junit.framework.TestCase#runBare()
	 */
	@Override
	public void runBare() throws Throwable {
		long start = printStart(getName());

		boolean toggleInteractiveMode = Host.isInteractive();
	    if (toggleInteractiveMode) {
	    	System.setProperty("NOINTERACTIVE", "true"); //$NON-NLS-1$ //$NON-NLS-2$
	    	try {
	    		Field f = Host.class.getDeclaredField("isInteractive"); //$NON-NLS-1$
	    		f.setAccessible(true);
	    		f.set(null, null);
	    	}
	    	catch (Exception e) { /* ignored on purpose */ }
	    }

		try {
			super.runBare();
		} finally {
			if (toggleInteractiveMode) {
		    	System.setProperty("NOINTERACTIVE", "false"); //$NON-NLS-1$ //$NON-NLS-2$
		    	try {
		    		Field f = Host.class.getDeclaredField("isInteractive"); //$NON-NLS-1$
		    		f.setAccessible(true);
		    		f.set(null, null);
		    	}
		    	catch (Exception e) { /* ignored on purpose */ }
			}

			printEnd(getName(), start);
		}
	}

	// Local date format presenting long date and time format.
	private final DateFormat DATE_FORMAT = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, Locale.getDefault());

	/**
	 * Prints out the test start time.
	 *
	 * @param name The name. Must not be <code>null</code>.
	 * @return The start time in milliseconds.
	 */
	protected long printStart(String name) {
		Assert.isNotNull(name);
		long startTime = System.currentTimeMillis();
		System.out.println("\n=== " + name + " started at: " + DATE_FORMAT.format(new Date(startTime))); //$NON-NLS-1$ //$NON-NLS-2$
		return startTime;
	}

	/**
	 * Prints out the test end time together with the test duration in milliseconds.
	 *
	 * @param name The name. Must not be <code>null</code>.
	 * @param startTime The start time in milliseconds.
	 */
	protected void printEnd(String name, long startTime) {
		Assert.isNotNull(name);
		long endTime = System.currentTimeMillis();
		long duration = endTime - startTime;
		System.out.println("=== " + name + " finished at: " + DATE_FORMAT.format(new Date(endTime)) + " (duration: " + duration + " ms)"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
	}

	/**
	 * Prints out the given message.
	 *
	 * @param message The message. Must not be <code>null</code>.
	 */
	protected void printMessage(String message) {
		Assert.isNotNull(message);
		System.out.println(message);
	}

	/**
	 * Prints out the given debug message.
	 * <p>
	 * Debug messages are printed only if the platform is in debug mode.
	 *
	 * @param message The message. Must not be <code>null</code>.
	 */
	protected void printDebugMessage(String message) {
		Assert.isNotNull(message);
		if (Platform.inDebugMode()) System.out.println(message);
	}

	/* (non-Javadoc)
	 * @see junit.framework.TestCase#setUp()
	 */
	@Override
	protected void setUp() throws Exception {
		super.setUp();

		// View handling must run in the UI thread
		if (Display.findDisplay(Thread.currentThread()) == null) {
			PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() {
				@Override
				public void run() {
					maximizeView();
				}
			});
		} else {
			maximizeView();
		}
	}

	/* (non-Javadoc)
	 * @see junit.framework.TestCase#tearDown()
	 */
	@Override
	protected void tearDown() throws Exception {
		// View handling must run in the UI thread
		if (Display.findDisplay(Thread.currentThread()) == null) {
			PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() {
				@Override
				public void run() {
					restoreView();
				}
			});
		} else {
			restoreView();
		}

		flushEventQueue();
		super.tearDown();
	}

	/**
	 * Flush the display event queue.
	 * <p>
	 * Unhandled exceptions in the event loop event are caught as follows:
	 * In case multiple events from the event loop throw exceptions these are printed
	 * to stdout. The first exception found in the event loop is thrown to the caller.
	 *
	 * @throws Exception in case an unhandled event loop exception was found.
	 */
	protected void flushEventQueue() throws Exception {
		Display display = Display.getCurrent();
		if (display!=null) {
			//on the dispatch thread already
			Exception eventLoopException = null;
			while(!display.isDisposed()) {
				//loop until event queue is flushed
				try {
					if (!display.readAndDispatch()) {
						break;
					}
				} catch(Exception e) {
					if (eventLoopException==null) {
						eventLoopException = e;
					} else {
						System.out.println("Multiple unhandled event loop exceptions:"); //$NON-NLS-1$
						e.printStackTrace();
					}
				}
			}
			if (eventLoopException!=null) {
				throw eventLoopException;
			}
		} else {
			//calling from background thread
			final Exception[] ex = new Exception[1];
			display = Display.getDefault();
			display.syncExec(new Runnable() {
				@Override
				public void run() {
					try {
						flushEventQueue();
					} catch(Exception e) {
						ex[0] = e;
					}
				}
			});
			if (ex[0]!=null) throw ex[0];
		}
	}

	/**
	 * Bring the main view to front.
	 * <p>
	 * If the property {@link IConfigurationProperties#MAXIMIZE_VIEW} is set, the
	 * view will be maximized.
	 * <p>
	 * A possibly open Eclipse Intro View will be hidden automatically.
	 */
	protected void maximizeView() {
		Assert.isNotNull(Display.findDisplay(Thread.currentThread()), "Illegal Thread Access"); //$NON-NLS-1$

		final String perspectiveId = getProperty(IConfigurationProperties.TARGET_PERSPECTIVE);
		assertNotNull("Invalid null-value for test case perspective id!", perspectiveId); //$NON-NLS-1$
		final String viewId = getProperty(IConfigurationProperties.TARGET_VIEW);
		assertNotNull("Invalid null-value for test case view id!", perspectiveId); //$NON-NLS-1$

		// Find the Eclipse Intro page and hide it.
		hideView("org.eclipse.ui.internal.introview", perspectiveId); //$NON-NLS-1$

		// Show the main view
		setProperty(VIEW_ZOOM_STATE_CHANGED, false);
		IViewPart part = showView(viewId, perspectiveId);
		assertNotNull("Main view is not available!", part); //$NON-NLS-1$

		// Get the view reference for setting the maximized action
		IViewReference reference = findView(viewId, perspectiveId);
		assertNotNull("Failed to lookup view reference for main view!", reference); //$NON-NLS-1$
		if (reference.getPage().getPartState(reference) != IWorkbenchPage.STATE_MAXIMIZED
				&& isProperty(IConfigurationProperties.MAXIMIZE_VIEW, true)) {
			reference.getPage().toggleZoom(reference);
			setProperty(VIEW_ZOOM_STATE_CHANGED, true);
		} else if (reference.getPage().getPartState(reference) == IWorkbenchPage.STATE_MAXIMIZED
				&& isProperty(IConfigurationProperties.MAXIMIZE_VIEW, false)) {
			reference.getPage().toggleZoom(reference);
			setProperty(VIEW_ZOOM_STATE_CHANGED, true);
		}

		// Give the UI a chance to repaint if the view zoom action changed
		if (isProperty(VIEW_ZOOM_STATE_CHANGED, true)) {
			waitAndDispatch(1000);
		}
	}

	/**
	 * Restore the main view action.
	 */
	protected void restoreView() {
		Assert.isNotNull(Display.findDisplay(Thread.currentThread()), "Illegal Thread Access"); //$NON-NLS-1$

		// restore the original view zoom action
		if (isProperty(VIEW_ZOOM_STATE_CHANGED, true)) {
			final String perspectiveId = getProperty(IConfigurationProperties.TARGET_PERSPECTIVE);
			assertNotNull("Invalid null-value for test case perspective id!", perspectiveId); //$NON-NLS-1$
			final String viewId = getProperty(IConfigurationProperties.TARGET_VIEW);
			assertNotNull("Invalid null-value for test case view id!", perspectiveId); //$NON-NLS-1$

			IViewReference reference = findView(viewId, perspectiveId);
			assertNotNull("Failed to lookup view reference for RSE Remote Systems View!", reference); //$NON-NLS-1$
			if (reference.getPage().getPartState(reference) == IWorkbenchPage.STATE_MAXIMIZED
					&& isProperty(IConfigurationProperties.MAXIMIZE_VIEW, true)) {
				reference.getPage().toggleZoom(reference);
			} else if (reference.getPage().getPartState(reference) != IWorkbenchPage.STATE_MAXIMIZED
					&& isProperty(IConfigurationProperties.MAXIMIZE_VIEW, false)) {
				reference.getPage().toggleZoom(reference);
			}
			setProperty(VIEW_ZOOM_STATE_CHANGED, false);
		}
	}

	/**
	 * Lookup the view reference for the given view and perspective id's.
	 *
	 * @param viewId The view id. Must not be <code>null</code>.
	 * @param perspectiveId The perspective id. Must not be <code>null</code>.
	 *
	 * @return The view reference instance to the view or <code>null</code> if not available.
	 */
	public final IViewReference findView(String viewId, String perspectiveId) {
		Assert.isNotNull(Display.findDisplay(Thread.currentThread()), "Illegal Thread Access"); //$NON-NLS-1$
		Assert.isNotNull(viewId);
		Assert.isNotNull(perspectiveId);

		IWorkbench workbench = PlatformUI.getWorkbench();
		assertNotNull("Failed to query current workbench instance!", workbench); //$NON-NLS-1$
		IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
		assertNotNull("Failed to query currently active workbench window!", window); //$NON-NLS-1$

		try {
			workbench.showPerspective(perspectiveId, window);
		} catch (WorkbenchException e) {
			IStatus status = new Status(IStatus.ERROR, UIPlugin.getUniqueIdentifier(),
										"Failed to switch to requested perspective (id = " + perspectiveId + ")!", e); //$NON-NLS-1$ //$NON-NLS-2$
			UIPlugin.getDefault().getLog().log(status);
		}

		IWorkbenchPage page = window.getActivePage();
		assertNotNull("Failed to query currently active workbench page!", page); //$NON-NLS-1$

		return page.findViewReference(viewId);
	}

	/**
	 * Shows the view.
	 *
	 * @param viewId The view id. Must not be <code>null</code>.
	 * @param perspectiveId The perspective id. Must not be <code>null</code>.
	 *
	 * @return The view part instance to the view or <code>null</code> if it cannot be shown.
	 */
	public final IViewPart showView(String viewId, String perspectiveId) {
		Assert.isNotNull(Display.findDisplay(Thread.currentThread()), "Illegal Thread Access"); //$NON-NLS-1$
		Assert.isNotNull(viewId);
		Assert.isNotNull(perspectiveId);

		IWorkbench workbench = PlatformUI.getWorkbench();
		assertNotNull("Failed to query current workbench instance!", workbench); //$NON-NLS-1$
		IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
		assertNotNull("Failed to query currently active workbench window!", window); //$NON-NLS-1$

		try {
			workbench.showPerspective(perspectiveId, window);
		} catch (WorkbenchException e) {
			IStatus status = new Status(IStatus.ERROR, UIPlugin.getUniqueIdentifier(),
										"Failed to switch to requested perspective (id = " + perspectiveId + ")!", e); //$NON-NLS-1$ //$NON-NLS-2$
			UIPlugin.getDefault().getLog().log(status);
		}

		IWorkbenchPage page = window.getActivePage();
		assertNotNull("Failed to query currently active workbench page!", page); //$NON-NLS-1$

		IViewPart part = null;
		try {
			part = page.showView(viewId);
		} catch (PartInitException e) {
			IStatus status = new Status(IStatus.ERROR, UIPlugin.getUniqueIdentifier(),
										"Failed to switch to requested perspective (id = " + perspectiveId + ")!", e); //$NON-NLS-1$ //$NON-NLS-2$
			UIPlugin.getDefault().getLog().log(status);
		}

		return part;
	}

	/**
	 * Hides the view.
	 *
	 * @param viewId The view id. Must not be <code>null</code>.
	 * @param perspectiveId The perspective id. Must not be <code>null</code>.
	 */
	public final void hideView(String viewId, String perspectiveId) {
		Assert.isNotNull(Display.findDisplay(Thread.currentThread()), "Illegal Thread Access"); //$NON-NLS-1$
		Assert.isNotNull(viewId);
		Assert.isNotNull(perspectiveId);

		IViewReference viewReference = findView(viewId, perspectiveId);
		if (viewReference != null) {
			PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().hideView(viewReference);
			waitAndDispatch(1000);
		}
	}

	/**
	 * Convenience method to call {@link #waitAndDispatch(long, null)}.
	 *
	 * @param timeout The timeout in milliseconds. Must be larger than 0.
	 *
	 * @return <code>True</code> if the method returned because of the timeout, <code>false</code> if the
	 *         method returned because of the condition became true.
	 */
	public boolean waitAndDispatch(long timeout) {
		Assert.isTrue(timeout > 0);
		return waitAndDispatch(timeout, null);
	}

	/**
	 * Method does not return until either the timeout has been exceeded or
	 * the interrupt condition is fulfilled. If the method called in a UI thread,
	 * the method keeps the UI thread dispatching running. If called in a
	 * non-UI thread, the method uses {@link Thread#sleep(long)}.
	 * <p>
	 * If a timeout of 0 milliseconds is specified, the method waits until the
	 * given interrupt condition is fulfilled.
	 *
	 * @param timeout The timeout in milliseconds. Must be larger or equals than 0.
	 * @param condition The condition to test. Must not be <code>null</code> if the timeout is 0.
	 *
	 * @return <code>True</code> if the method returned because of the timeout, <code>false</code> if the
	 *         method returned because of the condition became true.
	 */
	public boolean waitAndDispatch(long timeout, IConditionTester condition) {
		Assert.isTrue(timeout >= 0);
		if (timeout == 0) Assert.isNotNull(condition);

		boolean isTimedOut= false;
		if (timeout >= 0) {
			long start = System.currentTimeMillis();
			final Display display = Display.findDisplay(Thread.currentThread());
			if (display != null) {
				long current = System.currentTimeMillis();
				while (timeout == 0 || (current - start) < timeout && !display.isDisposed()) {
					if (condition != null && condition.isConditionFulfilled()) break;
					if (!display.readAndDispatch()) display.sleep();
					current = System.currentTimeMillis();
				}
				isTimedOut = (current - start) >= timeout && timeout > 0;
			} else {
				long current = System.currentTimeMillis();
				while (timeout == 0 || (current - start) < timeout) {
					if (condition != null && condition.isConditionFulfilled()) break;
					try { Thread.sleep(50); } catch (InterruptedException e) { /* ignored on purpose */ }
					current = System.currentTimeMillis();
				}
				isTimedOut = (current - start) >= timeout && timeout > 0;
			}
		}
		if (condition != null) condition.cleanup();

		return isTimedOut;
	}

	/**
	 * Calculates the absolute path to load additional data from.
	 * <p>
	 * The returned path is calculated as follow:<br>
	 * <ul>
	 *     <li>Add org.eclipse.tcf.te.tests bundle location</li>
	 *     <li>Add &quot;data&quot;</li>
	 *     <li>Add the given relative path</li>
	 *     <li>If &quot;hostSpecific&quot; is true, add &quot;Platform.getOS()&quot;</li>
	 *     <li>If &quot;archSpecific&quot; is true, add &quot;Platform.getOSArch()&quot;</li>
	 * </ul>
	 * <p>
	 * The calculated path must be a readable directory, otherwise the method will
	 * return <code>null</code>.
	 *
	 * @param path The relative path segment to append. Must not be <code>null</code>.
	 * @param hostSpecific Specify <code>true</code> to include {@link Platform#getOS()}, <code>false</code> if not.
	 * @param archSpecific Specify <code>true</code> to include {@link Platform#getOSArch()}, <code>false</code> if not.
	 *
	 * @return The absolute path to the data location or <code>null</code>.
	 */
	protected final IPath getDataLocation(String path, boolean hostSpecific, boolean archSpecific) {
		Assert.isNotNull(path);
		IPath root = null;

		Bundle bundle = getTestBundle();
		if (bundle != null) {
			IPath relative = new Path ("data").append(path); //$NON-NLS-1$
			if (hostSpecific) relative = relative.append(Platform.getOS());
			if (archSpecific) relative = relative.append(Platform.getOSArch());

			URL url = FileLocator.find(bundle, relative, null);
			if (url != null) {
				try {
					root = new Path(FileLocator.resolve(url).getFile());
					if (!root.toFile().isDirectory() || !root.toFile().canRead()) {
						root = null;
					}
				} catch (IOException e) { /* ignored on purpose */ }
			}
		}

		return root;
	}

	/**
	 * Returns the test bundle.
	 *
	 * @return The test bundle.
	 */
	protected Bundle getTestBundle() {
		return UIPlugin.getDefault().getBundle();
	}
}

Back to the top