diff --git a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/tests/CodanTestCase.java b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/tests/CodanTestCase.java
index e833eb9d6f2..d6989fe3746 100644
--- a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/tests/CodanTestCase.java
+++ b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/tests/CodanTestCase.java
@@ -27,6 +27,7 @@ import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.testplugin.CProjectHelper;
import org.eclipse.cdt.core.testplugin.util.BaseTestCase;
+import org.eclipse.cdt.core.testplugin.util.ModelJoiner;
import org.eclipse.cdt.core.testplugin.util.TestSourceReader;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
diff --git a/core/org.eclipse.cdt.core.tests/.settings/.api_filters b/core/org.eclipse.cdt.core.tests/.settings/.api_filters
new file mode 100644
index 00000000000..cc8fdc94773
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/.settings/.api_filters
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/core/org.eclipse.cdt.core.tests/META-INF/MANIFEST.MF b/core/org.eclipse.cdt.core.tests/META-INF/MANIFEST.MF
index b63891271a3..3d3b4e2e0b7 100644
--- a/core/org.eclipse.cdt.core.tests/META-INF/MANIFEST.MF
+++ b/core/org.eclipse.cdt.core.tests/META-INF/MANIFEST.MF
@@ -48,3 +48,4 @@ Bundle-Vendor: %providerName
Bundle-RequiredExecutionEnvironment: JavaSE-11
Automatic-Module-Name: org.eclipse.cdt.core.tests
Bundle-Localization: plugin
+Import-Package: org.junit.jupiter.api;version="5.7.0"
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/TeamSharedIndexTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/TeamSharedIndexTest.java
index 1bcdecaf8b3..4c7486907f5 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/TeamSharedIndexTest.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/TeamSharedIndexTest.java
@@ -29,6 +29,7 @@ import org.eclipse.cdt.core.index.IndexFilter;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.testplugin.CProjectHelper;
+import org.eclipse.cdt.core.testplugin.util.ModelJoiner;
import org.eclipse.cdt.core.testplugin.util.TestSourceReader;
import org.eclipse.cdt.internal.core.pdom.indexer.IndexerPreferences;
import org.eclipse.core.resources.IFile;
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/ChangeConfigurationTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/ChangeConfigurationTests.java
index 86d90490a8d..8f6b1dab75c 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/ChangeConfigurationTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/ChangeConfigurationTests.java
@@ -31,6 +31,7 @@ import org.eclipse.cdt.core.settings.model.ICSettingEntry;
import org.eclipse.cdt.core.settings.model.util.CDataUtil;
import org.eclipse.cdt.core.testplugin.CProjectHelper;
import org.eclipse.cdt.core.testplugin.CTestPlugin;
+import org.eclipse.cdt.core.testplugin.util.ModelJoiner;
import org.eclipse.cdt.core.testplugin.util.TestSourceReader;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/PDOMTestBase.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/PDOMTestBase.java
index 9bb0fe1f6d7..5d4f6a97937 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/PDOMTestBase.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/PDOMTestBase.java
@@ -38,6 +38,7 @@ import org.eclipse.cdt.core.parser.tests.VisibilityAsserts;
import org.eclipse.cdt.core.testplugin.CProjectHelper;
import org.eclipse.cdt.core.testplugin.CTestPlugin;
import org.eclipse.cdt.core.testplugin.util.BaseTestCase;
+import org.eclipse.cdt.core.testplugin.util.ModelJoiner;
import org.eclipse.cdt.core.testplugin.util.TestSourceReader;
import org.eclipse.cdt.internal.core.index.IIndexFragment;
import org.eclipse.cdt.internal.core.pdom.PDOM;
diff --git a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/BaseTestCase.java b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/BaseTestCase.java
index 172d940df91..c6efc350e43 100644
--- a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/BaseTestCase.java
+++ b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/BaseTestCase.java
@@ -20,36 +20,21 @@ import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayDeque;
-import java.util.ArrayList;
-import java.util.Collections;
import java.util.Deque;
import java.util.HashSet;
-import java.util.List;
import java.util.Set;
-import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.index.IIndex;
-import org.eclipse.cdt.core.model.CoreModel;
-import org.eclipse.cdt.core.model.ElementChangedEvent;
import org.eclipse.cdt.core.model.ICProject;
-import org.eclipse.cdt.core.model.IElementChangedListener;
import org.eclipse.cdt.core.testplugin.ResourceHelper;
import org.eclipse.cdt.core.testplugin.TestScannerProvider;
-import org.eclipse.cdt.internal.core.CCoreInternals;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNameBase;
import org.eclipse.cdt.internal.core.pdom.CModelListener;
import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IResourceStatus;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.ILogListener;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.jobs.Job;
import junit.framework.AssertionFailedError;
import junit.framework.Test;
@@ -58,29 +43,33 @@ import junit.framework.TestFailure;
import junit.framework.TestResult;
import junit.framework.TestSuite;
+/**
+ * @deprecated Please migrate tests away from JUnit3 style to JUnit5 style by using {@link BaseTestCase5}
+ * as base class.
+ */
+@Deprecated
public abstract class BaseTestCase extends TestCase {
- private static final String DEFAULT_INDEXER_TIMEOUT_SEC = "10";
- private static final String INDEXER_TIMEOUT_PROPERTY = "indexer.timeout";
+ private static final String DEFAULT_INDEXER_TIMEOUT_SEC = BaseTestCase5.DEFAULT_INDEXER_TIMEOUT_SEC;
+ private static final String INDEXER_TIMEOUT_PROPERTY = BaseTestCase5.INDEXER_TIMEOUT_PROPERTY;
/**
* Indexer timeout used by tests. To avoid this timeout expiring during debugging add
* -Dindexer.timeout=some_large_number to VM arguments of the test launch configuration.
*/
- protected static final int INDEXER_TIMEOUT_SEC = Integer
- .parseInt(System.getProperty(INDEXER_TIMEOUT_PROPERTY, DEFAULT_INDEXER_TIMEOUT_SEC));
- protected static final int INDEXER_TIMEOUT_MILLISEC = INDEXER_TIMEOUT_SEC * 1000;
+ protected static final int INDEXER_TIMEOUT_SEC = BaseTestCase5.INDEXER_TIMEOUT_SEC;
+ protected static final int INDEXER_TIMEOUT_MILLISEC = BaseTestCase5.INDEXER_TIMEOUT_MILLISEC;
/**
* The GCC version to emulate when running tests.
* We emulate the latest version whose extensions we support.
*/
- protected static final int GCC_MAJOR_VERSION_FOR_TESTS = 10;
- protected static final int GCC_MINOR_VERSION_FOR_TESTS = 1;
+ protected static final int GCC_MAJOR_VERSION_FOR_TESTS = BaseTestCase5.GCC_MAJOR_VERSION_FOR_TESTS;
+ protected static final int GCC_MINOR_VERSION_FOR_TESTS = BaseTestCase5.GCC_MINOR_VERSION_FOR_TESTS;
/**
* This provides the systems new line separator. Use this if you do String comparisons in tests
* instead of hard coding '\n' or '\r\n' respectively.
*/
- protected static final String NL = System.getProperty("line.separator");
+ protected static final String NL = BaseTestCase5.NL;
private boolean fExpectFailure;
private int fBugNumber;
@@ -187,74 +176,13 @@ public abstract class BaseTestCase extends TestCase {
@Override
public void runBare() throws Throwable {
- final List statusLog = Collections.synchronizedList(new ArrayList());
- ILogListener logListener = new ILogListener() {
- @Override
- public void logging(IStatus status, String plugin) {
- if (!status.isOK() && status.getSeverity() != IStatus.INFO) {
- switch (status.getCode()) {
- case IResourceStatus.NOT_FOUND_LOCAL:
- case IResourceStatus.NO_LOCATION_LOCAL:
- case IResourceStatus.FAILED_READ_LOCAL:
- case IResourceStatus.RESOURCE_NOT_LOCAL:
- // Logged by the resources plugin.
- return;
- }
- statusLog.add(status);
- }
- }
- };
- final CCorePlugin corePlugin = CCorePlugin.getDefault();
- if (corePlugin != null) { // Iff we don't run as a JUnit Plugin Test.
- corePlugin.getLog().addLogListener(logListener);
- }
-
- Throwable testThrowable = null;
+ LogMonitoring monitoring = new LogMonitoring();
+ monitoring.start();
try {
- try {
- super.runBare();
- } catch (Throwable e) {
- testThrowable = e;
- }
-
- if (statusLog.size() != fExpectedLoggedNonOK) {
- StringBuilder msg = new StringBuilder("Expected number (").append(fExpectedLoggedNonOK).append(") of ");
- msg.append("Non-OK status objects in log differs from actual (").append(statusLog.size())
- .append(").\n");
- Throwable cause = null;
- if (!statusLog.isEmpty()) {
- synchronized (statusLog) {
- for (IStatus status : statusLog) {
- IStatus[] ss = { status };
- ss = status instanceof MultiStatus ? ((MultiStatus) status).getChildren() : ss;
- for (IStatus s : ss) {
- msg.append('\t').append(s.getMessage()).append(' ');
-
- Throwable t = s.getException();
- cause = cause != null ? cause : t;
- if (t != null) {
- msg.append(
- t.getMessage() != null ? t.getMessage() : t.getClass().getCanonicalName());
- }
-
- msg.append("\n");
- }
- }
- }
- }
- cause = cause != null ? cause : testThrowable;
- AssertionFailedError afe = new AssertionFailedError(msg.toString());
- afe.initCause(cause);
- throw afe;
- }
+ super.runBare();
} finally {
- if (corePlugin != null) {
- corePlugin.getLog().removeLogListener(logListener);
- }
+ monitoring.stop(fExpectedLoggedNonOK);
}
-
- if (testThrowable != null)
- throw testThrowable;
}
@Override
@@ -302,97 +230,29 @@ public abstract class BaseTestCase extends TestCase {
fExpectedLoggedNonOK = count;
}
- /**
- * Some test steps need synchronizing against a CModel event. This class
- * is a very basic means of doing that.
- */
- static protected class ModelJoiner implements IElementChangedListener {
- private final boolean[] changed = new boolean[1];
-
- public ModelJoiner() {
- CoreModel.getDefault().addElementChangedListener(this);
- }
-
- public void clear() {
- synchronized (changed) {
- changed[0] = false;
- changed.notifyAll();
- }
- }
-
- public void join() throws CoreException {
- try {
- synchronized (changed) {
- while (!changed[0]) {
- changed.wait();
- }
- }
- } catch (InterruptedException e) {
- throw new CoreException(CCorePlugin.createStatus("Interrupted", e));
- }
- }
-
- public void dispose() {
- CoreModel.getDefault().removeElementChangedListener(this);
- }
-
- @Override
- public void elementChanged(ElementChangedEvent event) {
- // Only respond to post change events
- if (event.getType() != ElementChangedEvent.POST_CHANGE)
- return;
-
- synchronized (changed) {
- changed[0] = true;
- changed.notifyAll();
- }
- }
- }
-
public static void waitForIndexer(ICProject project) throws InterruptedException {
- Job.getJobManager().join(ResourcesPlugin.FAMILY_AUTO_REFRESH, null);
- assertTrue(CCoreInternals.getPDOMManager().joinIndexer(INDEXER_TIMEOUT_SEC * 1000, npm()));
+ BaseTestCase5.waitForIndexer(project);
}
public static void waitUntilFileIsIndexed(IIndex index, IFile file) throws Exception {
- TestSourceReader.waitUntilFileIsIndexed(index, file, INDEXER_TIMEOUT_SEC * 1000);
+ BaseTestCase5.waitUntilFileIsIndexed(index, file);
}
- // Assertion helpers
+ // Assertion helpers (redirected to the common implementation)
protected static T assertInstance(Object o, Class clazz, Class... cs) {
- assertNotNull("Expected object of " + clazz.getName() + " but got a null value", o);
- assertTrue("Expected " + clazz.getName() + " but got " + o.getClass().getName(), clazz.isInstance(o));
- for (Class c : cs) {
- assertNotNull("Expected object of " + c.getName() + " but got a null value", o);
- assertTrue("Expected " + c.getName() + " but got " + o.getClass().getName(), c.isInstance(o));
- }
- return clazz.cast(o);
+ return BaseTestCase5.assertInstance(o, clazz, cs);
}
protected static void assertValue(IValue value, long expectedValue) {
- assertNotNull(value);
- assertTrue(value.numberValue() instanceof Long);
- assertEquals(expectedValue, value.numberValue().longValue());
+ BaseTestCase5.assertValue(value, expectedValue);
}
protected static void assertVariableValue(IVariable var, long expectedValue) {
- assertValue(var.getInitialValue(), expectedValue);
+ BaseTestCase5.assertVariableValue(var, expectedValue);
}
protected static String formatForPrinting(IASTName name) {
- String signature = name.getRawSignature();
- boolean saved = CPPASTNameBase.sAllowNameComputation;
- CPPASTNameBase.sAllowNameComputation = true;
- try {
- String nameStr = name.toString();
- if (signature.replace(" ", "").equals(nameStr.replace(" ", "")))
- return signature;
- return nameStr + " in " + signature;
- } catch (Throwable e) {
- return signature;
- } finally {
- CPPASTNameBase.sAllowNameComputation = saved;
- }
+ return BaseTestCase5.formatForPrinting(name);
}
}
diff --git a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/BaseTestCase5.java b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/BaseTestCase5.java
new file mode 100644
index 00000000000..8f9c529924f
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/BaseTestCase5.java
@@ -0,0 +1,284 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2020 Wind River Systems, Inc. and others.
+ *
+ * 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:
+ * Markus Schorn - initial API and implementation
+ * Andrew Ferguson (Symbian)
+ * Sergey Prigogin (Google)
+ *******************************************************************************/
+package org.eclipse.cdt.core.testplugin.util;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayDeque;
+import java.util.Deque;
+
+import org.eclipse.cdt.core.dom.ast.IASTName;
+import org.eclipse.cdt.core.dom.ast.IValue;
+import org.eclipse.cdt.core.dom.ast.IVariable;
+import org.eclipse.cdt.core.index.IIndex;
+import org.eclipse.cdt.core.model.ICProject;
+import org.eclipse.cdt.core.testplugin.ResourceHelper;
+import org.eclipse.cdt.core.testplugin.TestScannerProvider;
+import org.eclipse.cdt.internal.core.CCoreInternals;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNameBase;
+import org.eclipse.cdt.internal.core.pdom.CModelListener;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.jobs.Job;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.TestInfo;
+
+import junit.framework.TestResult;
+
+/**
+ * BaseTestCase for JUnit5.
+ */
+public abstract class BaseTestCase5 {
+ protected static final String DEFAULT_INDEXER_TIMEOUT_SEC = "10";
+ protected static final String INDEXER_TIMEOUT_PROPERTY = "indexer.timeout";
+ /**
+ * Indexer timeout used by tests. To avoid this timeout expiring during debugging add
+ * -Dindexer.timeout=some_large_number to VM arguments of the test launch configuration.
+ */
+ protected static final int INDEXER_TIMEOUT_SEC = Integer
+ .parseInt(System.getProperty(INDEXER_TIMEOUT_PROPERTY, DEFAULT_INDEXER_TIMEOUT_SEC));
+ protected static final int INDEXER_TIMEOUT_MILLISEC = INDEXER_TIMEOUT_SEC * 1000;
+
+ /**
+ * The GCC version to emulate when running tests.
+ * We emulate the latest version whose extensions we support.
+ */
+ protected static final int GCC_MAJOR_VERSION_FOR_TESTS = 10;
+ protected static final int GCC_MINOR_VERSION_FOR_TESTS = 1;
+
+ /**
+ * This provides the systems new line separator. Use this if you do String comparisons in tests
+ * instead of hard coding '\n' or '\r\n' respectively.
+ */
+ protected static final String NL = System.getProperty("line.separator");
+
+ private boolean fExpectFailure;
+ private int fBugNumber;
+ private int fExpectedLoggedNonOK;
+ private Deque filesToDeleteOnTearDown = new ArrayDeque<>();
+ private TestInfo testInfo;
+
+ LogMonitoring logMonitoring = new LogMonitoring();
+
+ /**
+ * Backwards support for JUnit3 style test that had a getName. This is not 100% the same, but close
+ * enough for the general use case of getName.
+ */
+ public String getName() {
+ return testInfo.getDisplayName();
+ }
+
+ public static NullProgressMonitor npm() {
+ return new NullProgressMonitor();
+ }
+
+ @BeforeEach
+ protected void setupBase(TestInfo testInfo) throws Exception {
+ this.testInfo = testInfo;
+
+ logMonitoring.start();
+
+ CPPASTNameBase.sAllowRecursionBindings = false;
+ CPPASTNameBase.sAllowNameComputation = false;
+ CModelListener.sSuppressUpdateOfLastRecentlyUsed = true;
+ }
+
+ @AfterEach
+ protected void tearDownBase() throws Exception {
+ for (File file; (file = filesToDeleteOnTearDown.pollLast()) != null;) {
+ file.delete();
+ }
+ ResourceHelper.cleanUp(getName());
+ TestScannerProvider.clear();
+
+ logMonitoring.stop(fExpectedLoggedNonOK);
+ }
+
+ protected void deleteOnTearDown(File file) {
+ filesToDeleteOnTearDown.add(file);
+ }
+
+ protected File createTempFile(String prefix, String suffix) throws IOException {
+ File file = File.createTempFile(prefix, suffix);
+ filesToDeleteOnTearDown.add(file);
+ return file;
+ }
+
+ protected File nonExistentTempFile(String prefix, String suffix) {
+ File file = new File(System.getProperty("java.io.tmpdir"), prefix + System.currentTimeMillis() + suffix);
+ filesToDeleteOnTearDown.add(file);
+ return file;
+ }
+
+ /**
+ * The last value passed to this method in the body of a testXXX method
+ * will be used to determine whether or not the presence of non-OK status objects
+ * in the log should fail the test. If the logged number of non-OK status objects
+ * differs from the last value passed, the test is failed. If this method is not called
+ * at all, the expected number defaults to zero.
+ * @param count the expected number of logged error and warning messages
+ */
+ public void setExpectedNumberOfLoggedNonOKStatusObjects(int count) {
+ fExpectedLoggedNonOK = count;
+ }
+
+ public static void waitForIndexer(ICProject project) throws InterruptedException {
+ Job.getJobManager().join(ResourcesPlugin.FAMILY_AUTO_REFRESH, null);
+ assertTrue(CCoreInternals.getPDOMManager().joinIndexer(INDEXER_TIMEOUT_SEC * 1000, npm()));
+ }
+
+ public static void waitUntilFileIsIndexed(IIndex index, IFile file) throws Exception {
+ TestSourceReader.waitUntilFileIsIndexed(index, file, INDEXER_TIMEOUT_SEC * 1000);
+ }
+
+ // Assertion helpers
+
+ /**
+ * Asserts that the file does exist and prints a niceish error message if not.
+ */
+ public static void assertExists(File f) {
+ assertTrue(f.exists(), "File " + f + " does not exist");
+ }
+
+ /**
+ * Asserts that the resource does exist and prints a niceish error message if not.
+ */
+ public static void assertExists(IResource f) {
+ assertTrue(f.exists(), "Resource " + f + " does not exist");
+ }
+
+ /**
+ * Asserts that the file does exist and prints a niceish error message if not.
+ */
+ public static void assertNotExists(File f) {
+ assertFalse(f.exists(), "File " + f + " should not exist");
+ }
+
+ /**
+ * Asserts that the Resource does exist and prints a niceish error message if not.
+ */
+ public static void assertNotExists(IResource f) {
+ assertFalse(f.exists(), "Resource " + f + " should not exist");
+ }
+
+ public static T assertInstance(Object o, Class clazz, Class... cs) {
+ assertNotNull(o, "Expected object of " + clazz.getName() + " but got a null value");
+ assertTrue(clazz.isInstance(o), "Expected " + clazz.getName() + " but got " + o.getClass().getName());
+ for (Class c : cs) {
+ assertNotNull(o, "Expected object of " + c.getName() + " but got a null value");
+ assertTrue(c.isInstance(o), "Expected " + c.getName() + " but got " + o.getClass().getName());
+ }
+ return clazz.cast(o);
+ }
+
+ public static void assertValue(IValue value, long expectedValue) {
+ assertNotNull(value);
+ assertTrue(value.numberValue() instanceof Long);
+ assertEquals(expectedValue, value.numberValue().longValue());
+ }
+
+ public static void assertVariableValue(IVariable var, long expectedValue) {
+ assertValue(var.getInitialValue(), expectedValue);
+ }
+
+ public static String formatForPrinting(IASTName name) {
+ String signature = name.getRawSignature();
+ boolean saved = CPPASTNameBase.sAllowNameComputation;
+ CPPASTNameBase.sAllowNameComputation = true;
+ try {
+ String nameStr = name.toString();
+ if (signature.replace(" ", "").equals(nameStr.replace(" ", "")))
+ return signature;
+ return nameStr + " in " + signature;
+ } catch (Throwable e) {
+ return signature;
+ } finally {
+ CPPASTNameBase.sAllowNameComputation = saved;
+ }
+ }
+
+ // These methods help migrate from JUnit3 to JUnit5 version by providing errors as early as possible
+ // in the migration cycle
+
+ public BaseTestCase5() {
+ // This constructor is expected to be called
+ }
+
+ /**
+ * This JUnit3 style constructor is not supported.
+ */
+ private BaseTestCase5(String name) {
+ fail("Test not migrated properly to JUnit5 yet.");
+ }
+
+ /**
+ * This method is declared as final to help transition to JUnit5 to ensure that
+ * accidental override of the method is not left in subclasses when migrating.
+ */
+ final protected void setUp() {
+ fail("Test not migrated properly to JUnit5 yet.");
+ }
+
+ /**
+ * This method is declared as final to help transition to JUnit5 to ensure that
+ * accidental override of the method is not left in subclasses when migrating.
+ */
+ final protected void tearDown() {
+ fail("Test not migrated properly to JUnit5 yet.");
+ }
+
+ /**
+ * This method is declared as final to help transition to JUnit5 to ensure that
+ * accidental override of the method is not left in subclasses when migrating.
+ */
+ final protected void runBare() {
+ fail("Test not migrated properly to JUnit5 yet.");
+ }
+
+ /**
+ * This method is declared as final to help transition to JUnit5 to ensure that
+ * accidental override of the method is not left in subclasses when migrating.
+ */
+ final protected void run(TestResult result) {
+ fail("Test not migrated properly to JUnit5 yet.");
+ }
+
+ /**
+ * This method is declared as final to help transition to JUnit5 to ensure that
+ * accidental override of the method is not left in subclasses when migrating.
+ */
+ final protected void runTest() throws Throwable {
+ fail("Test not migrated properly to JUnit5 yet.");
+ }
+
+ /**
+ * Setting expected failures in this way is not support with the BaseTestCase5. If this
+ * is functionality that is needed, please find a new way to do it.
+ */
+ public void setExpectFailure(int bugNumber) {
+ fail("Test not migrated properly to JUnit5 yet.");
+ }
+
+}
diff --git a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/LogMonitoring.java b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/LogMonitoring.java
new file mode 100644
index 00000000000..88b630230d3
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/LogMonitoring.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2020 Wind River Systems, Inc. and others.
+ *
+ * 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.cdt.core.testplugin.util;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.core.resources.IResourceStatus;
+import org.eclipse.core.runtime.ILogListener;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+
+import junit.framework.AssertionFailedError;
+
+class LogMonitoring {
+
+ private List statusLog;
+
+ private ILogListener logListener;
+
+ private CCorePlugin corePlugin;
+
+ void start() {
+ statusLog = Collections.synchronizedList(new ArrayList());
+ logListener = new ILogListener() {
+ @Override
+ public void logging(IStatus status, String plugin) {
+ if (!status.isOK() && status.getSeverity() != IStatus.INFO) {
+ switch (status.getCode()) {
+ case IResourceStatus.NOT_FOUND_LOCAL:
+ case IResourceStatus.NO_LOCATION_LOCAL:
+ case IResourceStatus.FAILED_READ_LOCAL:
+ case IResourceStatus.RESOURCE_NOT_LOCAL:
+ // Logged by the resources plugin.
+ return;
+ }
+ statusLog.add(status);
+ }
+ }
+ };
+ corePlugin = CCorePlugin.getDefault();
+ if (corePlugin != null) { // Iff we don't run as a JUnit Plugin Test.
+ corePlugin.getLog().addLogListener(logListener);
+ }
+
+ }
+
+ void stop(int expectedLoggedNonOK) {
+ if (statusLog.size() != expectedLoggedNonOK) {
+ StringBuilder msg = new StringBuilder("Expected number (").append(expectedLoggedNonOK).append(") of ");
+ msg.append("Non-OK status objects in log differs from actual (").append(statusLog.size()).append(").\n");
+ Throwable cause = null;
+ if (!statusLog.isEmpty()) {
+ synchronized (statusLog) {
+ for (IStatus status : statusLog) {
+ IStatus[] ss = { status };
+ ss = status instanceof MultiStatus ? ((MultiStatus) status).getChildren() : ss;
+ for (IStatus s : ss) {
+ msg.append('\t').append(s.getMessage()).append(' ');
+
+ Throwable t = s.getException();
+ cause = cause != null ? cause : t;
+ if (t != null) {
+ msg.append(t.getMessage() != null ? t.getMessage() : t.getClass().getCanonicalName());
+ }
+
+ msg.append("\n");
+ }
+ }
+ }
+ }
+ AssertionFailedError afe = new AssertionFailedError(msg.toString());
+ afe.initCause(cause);
+ throw afe;
+ }
+ if (corePlugin != null) {
+ corePlugin.getLog().removeLogListener(logListener);
+ }
+ }
+}
\ No newline at end of file
diff --git a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/ModelJoiner.java b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/ModelJoiner.java
new file mode 100644
index 00000000000..189544d6bae
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/ModelJoiner.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2016 Wind River Systems, Inc. and others.
+ *
+ * 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:
+ * Markus Schorn - initial API and implementation
+ * Andrew Ferguson (Symbian)
+ * Sergey Prigogin (Google)
+ *******************************************************************************/
+package org.eclipse.cdt.core.testplugin.util;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.model.CoreModel;
+import org.eclipse.cdt.core.model.ElementChangedEvent;
+import org.eclipse.cdt.core.model.IElementChangedListener;
+import org.eclipse.core.runtime.CoreException;
+
+/**
+ * Some test steps need synchronizing against a CModel event. This class
+ * is a very basic means of doing that.
+ */
+public class ModelJoiner implements IElementChangedListener {
+ private final boolean[] changed = new boolean[1];
+
+ public ModelJoiner() {
+ CoreModel.getDefault().addElementChangedListener(this);
+ }
+
+ public void clear() {
+ synchronized (changed) {
+ changed[0] = false;
+ changed.notifyAll();
+ }
+ }
+
+ public void join() throws CoreException {
+ try {
+ synchronized (changed) {
+ while (!changed[0]) {
+ changed.wait();
+ }
+ }
+ } catch (InterruptedException e) {
+ throw new CoreException(CCorePlugin.createStatus("Interrupted", e));
+ }
+ }
+
+ public void dispose() {
+ CoreModel.getDefault().removeElementChangedListener(this);
+ }
+
+ @Override
+ public void elementChanged(ElementChangedEvent event) {
+ // Only respond to post change events
+ if (event.getType() != ElementChangedEvent.POST_CHANGE)
+ return;
+
+ synchronized (changed) {
+ changed[0] = true;
+ changed.notifyAll();
+ }
+ }
+}
\ No newline at end of file
diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/UITestCaseWithProject.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/UITestCaseWithProject.java
index e2b01844a5c..15db270316e 100644
--- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/UITestCaseWithProject.java
+++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/UITestCaseWithProject.java
@@ -27,6 +27,7 @@ import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.testplugin.CProjectHelper;
import org.eclipse.cdt.core.testplugin.FileManager;
+import org.eclipse.cdt.core.testplugin.util.ModelJoiner;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;