Bug 479450 - fix new race-condition in FeatureBasedLaunchTest
Change-Id: I6b91e49707f9edd79c2d00672c0016e425444a21
Signed-off-by: Hannes Wellmann <wellmann.hannes1@gmx.net>
Reviewed-on: https://git.eclipse.org/r/c/pde/eclipse.pde.ui/+/192067
Tested-by: Andrey Loskutov <loskutov@gmx.de>
Tested-by: PDE Bot <pde-bot@eclipse.org>
Reviewed-by: Andrey Loskutov <loskutov@gmx.de>
diff --git a/ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/ui/tests/launcher/FeatureBasedLaunchTest.java b/ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/ui/tests/launcher/FeatureBasedLaunchTest.java
index 1d65cea..5662fa6 100644
--- a/ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/ui/tests/launcher/FeatureBasedLaunchTest.java
+++ b/ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/ui/tests/launcher/FeatureBasedLaunchTest.java
@@ -29,7 +29,6 @@
import java.util.stream.Collectors;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
-import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.*;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.pde.core.plugin.IMatchRules;
@@ -1308,12 +1307,12 @@
}
private static void createFeatureProject(String id, String version, CoreConsumer<IFeature> featureSetup)
- throws Throwable {
+ throws Exception {
createFeature(id, version, id + "_" + version.replace('.', '_'), featureSetup);
}
private static IFeature createFeature(String id, String version, String projectName,
- CoreConsumer<IFeature> featureSetup) throws Throwable {
+ CoreConsumer<IFeature> featureSetup) throws Exception {
FeatureData featureData = new FeatureData();
featureData.id = id;
featureData.version = version;
@@ -1334,30 +1333,29 @@
}
};
operation.run(new NullProgressMonitor());
+
+ flushPendingResourceChangeEvents(project);
+
FeatureModelManager featureModelManager = PDECore.getDefault().getFeatureModelManager();
return featureModelManager.getFeatureModel(project).getFeature();
}
- // Created Feature-projects get reloaded shortly after their creation, in
- // the end of the auto-build job (due to some pending resource-changed
- // events). In the beginning of the reload the feature model is reset and
- // all fields become null/0. So if the model is read inbetween the model
- // state could be inconsistent. This creates a race condition, which
- // occasionally leads to test-failure. All my attempts to consume all
- // resource-change events immediately to resolve the race-condition failed.
- // I also tried to await the World-Changed event fired on a FeatureModel
- // once it was reloaded but then the test spent most of its runtime waiting.
- // Blocking all other operations was the simplest and fastest solution.
- @BeforeClass
- public static void acquireWorkspaceRuleToAvoidFeatureReloadByAutobuild() {
- IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
- Job.getJobManager().beginRule(root, null);
- }
-
- @AfterClass
- public static void releaseWorkspaceRule() {
- IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
- Job.getJobManager().endRule(root);
+ private static void flushPendingResourceChangeEvents(IProject project) throws CoreException {
+ // The create-feature operation above creates/modifies the feature.xml,
+ // but not all resource-change-events generated by the operation are
+ // handled when the operation exists. If these change-events are not
+ // handled now they are handled asynchronously by the Autobuild-job. The
+ // problem is that the Feature-model is reset/reload while processing
+ // the changes (which first sets all fields to null/zero and then
+ // re-reads them), but the reload is NOT guarded by corresponding locks.
+ // So if this happens asynchronously and the model is read inbetween the model
+ // state could be inconsistent, which occasionally leads to
+ // test-failure. Furthermore the feature-models are only added to the
+ // FeatureModelManager while processing the resource-changes.
+ // Consequently it has to be ensured that all pending resource change
+ // events are properly processed now and in this thread:
+ // -> Building the project ensures this
+ ResourcesPlugin.getWorkspace().run(m -> project.build(IncrementalProjectBuilder.FULL_BUILD, null), null);
}
private static void addRequiredPlugin(IFeature feature, String id, String version, int matchRule)