diff options
5 files changed, 222 insertions, 17 deletions
diff --git a/bundles/org.eclipse.equinox.p2.tests.ui/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.tests.ui/META-INF/MANIFEST.MF index 6a2296558..8998c0484 100644 --- a/bundles/org.eclipse.equinox.p2.tests.ui/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.equinox.p2.tests.ui/META-INF/MANIFEST.MF @@ -2,14 +2,14 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.equinox.p2.tests.ui -Bundle-Version: 1.2.400.qualifier +Bundle-Version: 1.2.500.qualifier Bundle-Vendor: %providerName Bundle-Localization: plugin Require-Bundle: org.eclipse.core.runtime;bundle-version="3.4.100", org.eclipse.ui;bundle-version="3.6.0", org.eclipse.equinox.p2.metadata;bundle-version="1.0.0", org.eclipse.equinox.p2.metadata.repository;bundle-version="1.0.100", - org.eclipse.equinox.p2.ui;bundle-version="1.0.100", + org.eclipse.equinox.p2.ui;bundle-version="2.6.0", org.eclipse.core.tests.harness;bundle-version="3.4.0", org.eclipse.equinox.p2.core;bundle-version="1.0.100", org.eclipse.equinox.p2.engine;bundle-version="1.0.100", diff --git a/bundles/org.eclipse.equinox.p2.tests.ui/pom.xml b/bundles/org.eclipse.equinox.p2.tests.ui/pom.xml index 7ac570209..1aeb1fb6c 100644 --- a/bundles/org.eclipse.equinox.p2.tests.ui/pom.xml +++ b/bundles/org.eclipse.equinox.p2.tests.ui/pom.xml @@ -21,7 +21,7 @@ <groupId>org.eclipse.equinox</groupId> <artifactId>org.eclipse.equinox.p2.tests.ui</artifactId> - <version>1.2.400-SNAPSHOT</version> + <version>1.2.500-SNAPSHOT</version> <packaging>eclipse-test-plugin</packaging> <properties> diff --git a/bundles/org.eclipse.equinox.p2.tests.ui/src/org/eclipse/equinox/p2/tests/ui/dialogs/AllTests.java b/bundles/org.eclipse.equinox.p2.tests.ui/src/org/eclipse/equinox/p2/tests/ui/dialogs/AllTests.java index fc5afecde..116f1df1e 100644 --- a/bundles/org.eclipse.equinox.p2.tests.ui/src/org/eclipse/equinox/p2/tests/ui/dialogs/AllTests.java +++ b/bundles/org.eclipse.equinox.p2.tests.ui/src/org/eclipse/equinox/p2/tests/ui/dialogs/AllTests.java @@ -22,7 +22,8 @@ import org.junit.runners.Suite; @RunWith(Suite.class) @Suite.SuiteClasses({ InstallWizardTest.class, InstalledSoftwarePageTest.class, InstallWithRemediationTest.class, InstallationHistoryPageTest.class, UpdateWizardTest.class, UninstallWizardTest.class, - RepositoryManipulationPageTest.class, IUPropertyPagesTest.class, PreferencePagesTest.class }) + RepositoryManipulationPageTest.class, IUPropertyPagesTest.class, PreferencePagesTest.class, + EECompatibilityTest.class }) public class AllTests { // test suite } diff --git a/bundles/org.eclipse.equinox.p2.tests.ui/src/org/eclipse/equinox/p2/tests/ui/dialogs/EECompatibilityTest.java b/bundles/org.eclipse.equinox.p2.tests.ui/src/org/eclipse/equinox/p2/tests/ui/dialogs/EECompatibilityTest.java new file mode 100644 index 000000000..e0e8e44f0 --- /dev/null +++ b/bundles/org.eclipse.equinox.p2.tests.ui/src/org/eclipse/equinox/p2/tests/ui/dialogs/EECompatibilityTest.java @@ -0,0 +1,166 @@ +/******************************************************************************* + * Copyright (c) 2020 Red Hat 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.equinox.p2.tests.ui.dialogs; + +import static org.junit.Assume.assumeTrue; + +import java.util.Arrays; +import java.util.Collections; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.equinox.internal.p2.metadata.ProvidedCapability; +import org.eclipse.equinox.internal.p2.ui.ProvUI; +import org.eclipse.equinox.internal.p2.ui.dialogs.*; +import org.eclipse.equinox.p2.engine.IProfile; +import org.eclipse.equinox.p2.metadata.*; +import org.eclipse.equinox.p2.metadata.MetadataFactory.InstallableUnitDescription; +import org.eclipse.equinox.p2.operations.InstallOperation; +import org.eclipse.swt.widgets.Shell; +import org.junit.*; +import org.junit.runner.RunWith; +import org.junit.runners.BlockJUnit4ClassRunner; + +@RunWith(BlockJUnit4ClassRunner.class) +public class EECompatibilityTest extends WizardTest { + + private static final int latestKnownJavaVersion = 14; + + private final class ProvisioningWizardDialogExtension extends ProvisioningWizardDialog { + private ProvisioningWizardDialogExtension(Shell parent, ProvisioningOperationWizard wizard) { + super(parent, wizard); + } + + @Override + public void nextPressed() { + super.nextPressed(); + } + } + + private boolean previewCheckJREValue = false; + private IInstallableUnit iuRequiringTooRecentEE; + + @Before + @Override + public void setUp() throws Exception { + super.setUp(); + addAJREJavaSEUnit(getProfile(TESTPROFILE)); + previewCheckJREValue = getPolicy().getCheckAgainstCurrentExecutionEnvironment(); + getPolicy().setCheckAgainstCurrentExecutionEnvironment(true); + this.iuRequiringTooRecentEE = iuRequiringTooRecentEE(); + assumeTrue("Tests are skipped on latest known Java version", Integer + .parseInt(System.getProperty("java.version").split("\\.")[0].split("-")[0]) < latestKnownJavaVersion); + } + + @After + @Override + public void tearDown() throws Exception { + super.tearDown(); + getPolicy().setCheckAgainstCurrentExecutionEnvironment(previewCheckJREValue); + } + + @Test + public void testSingleIUPreventInstallation() { + PreselectedIUInstallWizard wizard = new PreselectedIUInstallWizard(getProvisioningUI(), null, + Collections.singletonList(iuRequiringTooRecentEE), null); + wizard.setBypassLicensePage(true); + ProvisioningWizardDialogExtension dialog = new ProvisioningWizardDialogExtension(ProvUI.getDefaultParentShell(), + wizard); + dialog.setBlockOnOpen(false); + dialog.open(); + dialog.nextPressed(); + IResolutionErrorReportingPage page = (IResolutionErrorReportingPage) dialog.getCurrentPage(); + page.getMessage(); + assertFalse(wizard.canFinish()); + } + + @Test + @Ignore(value = "This test is not relevant as it doesn't build an interesting remediation. Feel free to improve!") + public void testEEIssueSkipsRemediation() { + IInstallableUnit unsatisfiableUnit = unsatisfiableUnit(); + IInstallableUnit unsatisfiedFeature = createFeature(unsatisfiableUnit); + createTestMetdataRepository(new IInstallableUnit[] { unsatisfiableUnit, unsatisfiedFeature }); + IInstallableUnit[] units = new IInstallableUnit[] { iuRequiringTooRecentEE, createFeature(unsatisfiedFeature) }; + PreselectedIUInstallWizard wizard = new PreselectedIUInstallWizard(getProvisioningUI(), null, + Arrays.asList(units), null); + wizard.setBypassLicensePage(true); + ProvisioningWizardDialogExtension dialog = new ProvisioningWizardDialogExtension(ProvUI.getDefaultParentShell(), + wizard); + dialog.setBlockOnOpen(false); + dialog.open(); + dialog.nextPressed(); // to remediation page + assertTrue(dialog.getCurrentPage() instanceof RemediationPage); + // Here, we'd like to have remediation pre-selecting "Keep my installation the + // same and modify the items being installed to be compatible" and keeping the + // iuRequiringTooRecentEE as part of the plan. + // but this is not happening with current test scenario, so test it ignored so + // far. + assertFalse(wizard.canFinish()); + dialog.nextPressed(); + assertFalse(wizard.canFinish()); + dialog.close(); + } + + private IInstallableUnit unsatisfiableUnit() { + InstallableUnitDescription desc = new InstallableUnitDescription(); + desc.setId("unsatisfiable-unit"); //$NON-NLS-1$ + desc.setVersion(Version.create("0.0.1")); + desc.addProvidedCapabilities(Collections.singletonList( + new ProvidedCapability(IInstallableUnit.NAMESPACE_IU_ID, desc.getId(), desc.getVersion()))); + desc.addRequirements(Collections.singletonList(MetadataFactory.createRequirement( + IInstallableUnit.NAMESPACE_IU_ID, "blah", VersionRange.create("1.0.0"), null, false, true))); + return MetadataFactory.createInstallableUnit(desc); + } + + private static IInstallableUnit iuRequiringTooRecentEE() { + InstallableUnitDescription desc = new InstallableUnitDescription(); + desc.setId("dummyIU"); //$NON-NLS-1$ + desc.setVersion(Version.create("0.0.1")); + desc.addProvidedCapabilities(Collections.singletonList( + new ProvidedCapability(IInstallableUnit.NAMESPACE_IU_ID, desc.getId(), desc.getVersion()))); + desc.addRequirements(Collections.singletonList(MetadataFactory.createRequirement("osgi.ee", "JavaSE", + VersionRange.create(latestKnownJavaVersion + ".0.0"), null, false, true))); + return MetadataFactory.createInstallableUnit(desc); + } + + private static IInstallableUnit createFeature(IInstallableUnit... included) { + InstallableUnitDescription iu = new MetadataFactory.InstallableUnitDescription(); + iu.setId("dummyFeatureIncluding" + + Stream.of(included).map(IInstallableUnit::getId).collect(Collectors.joining()) + ".feature.group"); + iu.setVersion(Version.create("0.0.1")); + iu.addProvidedCapabilities(Collections.singleton(MetadataFactory + .createProvidedCapability(IInstallableUnit.NAMESPACE_IU_ID, iu.getId(), iu.getVersion()))); + iu.addRequirements(Stream.of(included) + .map(unit -> MetadataFactory.createRequirement(IInstallableUnit.NAMESPACE_IU_ID, unit.getId(), + new VersionRange(unit.getVersion(), true, iu.getVersion(), true), null, false, false)) + .collect(Collectors.toList())); + iu.setProperty(InstallableUnitDescription.PROP_TYPE_GROUP, Boolean.TRUE.toString()); + return MetadataFactory.createInstallableUnit(iu); + } + + private void addAJREJavaSEUnit(IProfile profile) { + InstallOperation installOperation = new InstallOperation(getSession(), + Collections.singletonList(aJREJavaSE(latestKnownJavaVersion))); + installOperation.setProfileId(TESTPROFILE); + installOperation.resolveModal(new NullProgressMonitor()); + installOperation.getProvisioningJob(new NullProgressMonitor()).run(new NullProgressMonitor()); + } + + private IInstallableUnit aJREJavaSE(int javaSEVersion) { + InstallableUnitDescription desc = new InstallableUnitDescription(); + desc.setId("a.jre.javase"); //$NON-NLS-1$ + desc.setVersion(Version.create(javaSEVersion + ".0.0")); + desc.addProvidedCapabilities(Arrays.asList(new ProvidedCapability[] { + new ProvidedCapability(IInstallableUnit.NAMESPACE_IU_ID, desc.getId(), desc.getVersion()), + new ProvidedCapability("osgi.ee", "JavaSE", desc.getVersion()) })); + return MetadataFactory.createInstallableUnit(desc); + } +} diff --git a/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/dialogs/ProvisioningOperationWizard.java b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/dialogs/ProvisioningOperationWizard.java index cc2c36789..71479559e 100644 --- a/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/dialogs/ProvisioningOperationWizard.java +++ b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/dialogs/ProvisioningOperationWizard.java @@ -18,6 +18,7 @@ package org.eclipse.equinox.internal.p2.ui.dialogs; import java.lang.reflect.InvocationTargetException; import java.util.HashSet; +import java.util.stream.Stream; import org.eclipse.core.runtime.*; import org.eclipse.core.runtime.jobs.*; import org.eclipse.equinox.internal.p2.ui.*; @@ -69,12 +70,6 @@ public abstract class ProvisioningOperationWizard extends Wizard { setNeedsProgressMonitor(true); if (operation != null) { provisioningContext = operation.getProvisioningContext(); - if (operation.hasResolved() && getPolicy().getCheckAgainstCurrentExecutionEnvironment()) { - this.localJRECheckPlan = ProvUI.toCompabilityWithCurrentJREProvisioningPlan(operation, null); - if (!localJRECheckPlan.getStatus().isOK()) { - couldNotResolveStatus = localJRECheckPlan.getStatus(); - } - } } } @@ -136,6 +131,13 @@ public abstract class ProvisioningOperationWizard extends Wizard { getContainer().run(true, true, monitor -> { remediationOperation.setCurrentRemedy(remediationPage.getRemediationGroup().getCurrentRemedy()); remediationOperation.resolveModal(monitor); + if (getPolicy().getCheckAgainstCurrentExecutionEnvironment()) { + this.localJRECheckPlan = ProvUI + .toCompabilityWithCurrentJREProvisioningPlan(remediationOperation, monitor); + if (!compatibleWithCurrentEE()) { + couldNotResolveStatus = localJRECheckPlan.getStatus(); + } + } }); } catch (InterruptedException e) { // Nothing to report if thread was interrupted @@ -147,6 +149,9 @@ public abstract class ProvisioningOperationWizard extends Wizard { initializeResolutionModelElements(ElementUtils.requestToElement( ((RemediationOperation) operation).getCurrentRemedy(), !(this instanceof UpdateWizard))); planChanged(); + if (getPolicy().getCheckAgainstCurrentExecutionEnvironment() && !compatibleWithCurrentEE()) { + return errorPage; + } return resolutionPage; } else if (page == mainPage || page == errorPage) { ISelectableIUsPage currentPage = (ISelectableIUsPage) page; @@ -160,8 +165,8 @@ public abstract class ProvisioningOperationWizard extends Wizard { initializeResolutionModelElements(planSelections); } IStatus status = operation.getResolutionResult(); - if (status.getSeverity() != IStatus.ERROR && localJRECheckPlan != null - && !localJRECheckPlan.getStatus().isOK()) { + if (getPolicy().getCheckAgainstCurrentExecutionEnvironment() && !compatibleWithCurrentEE()) { + // skip remediation for EE compatibility issues return errorPage; } if (status == null || status.getSeverity() == IStatus.ERROR) { @@ -189,6 +194,40 @@ public abstract class ProvisioningOperationWizard extends Wizard { return super.getNextPage(page); } + private boolean compatibleWithCurrentEE() { + if (operation == null || !getPolicy().getCheckAgainstCurrentExecutionEnvironment()) { + return true; + } + if (localJRECheckPlan == null) { + try { + getContainer().run(true, true, monitor -> { + if (!operation.hasResolved()) { + operation.resolveModal(monitor); + } + if (operation.hasResolved()) { + this.localJRECheckPlan = ProvUI.toCompabilityWithCurrentJREProvisioningPlan(operation, null); + if (!compatibleWithCurrentEE()) { + couldNotResolveStatus = localJRECheckPlan.getStatus(); + } + } + }); + } catch (InvocationTargetException | InterruptedException e) { + return false; + } + } + IStatus currentEEPlanStatus = localJRECheckPlan.getStatus(); + if (currentEEPlanStatus.getSeverity() != IStatus.ERROR) { + return true; + } + return Stream.of(currentEEPlanStatus).filter(status -> status.getSeverity() == IStatus.ERROR) + .flatMap(status -> status.isMultiStatus() ? Stream.of(status.getChildren()) : Stream.of(status)) + .filter(status -> status.getSeverity() == IStatus.ERROR) + .flatMap(status -> status.isMultiStatus() ? Stream.of(status.getChildren()) : Stream.of(status)) + .filter(status -> status.getSeverity() == IStatus.ERROR) + .flatMap(status -> status.isMultiStatus() ? Stream.of(status.getChildren()) : Stream.of(status)) + .map(IStatus::getMessage).noneMatch(message -> message.contains("osgi.ee")); //$NON-NLS-1$ + } + /** * The selections that drive the provisioning operation have changed. We might * need to change the completion state of the resolution page. @@ -300,7 +339,7 @@ public abstract class ProvisioningOperationWizard extends Wizard { operation.resolveModal(monitor); if (getPolicy().getCheckAgainstCurrentExecutionEnvironment()) { this.localJRECheckPlan = ProvUI.toCompabilityWithCurrentJREProvisioningPlan(operation, monitor); - if (!localJRECheckPlan.getStatus().isOK()) { + if (!compatibleWithCurrentEE()) { couldNotResolveStatus = localJRECheckPlan.getStatus(); } } @@ -348,10 +387,9 @@ public abstract class ProvisioningOperationWizard extends Wizard { if (statusOverridesOperation()) return couldNotResolveStatus; if (operation != null && operation.getResolutionResult() != null) { - if (!operation.getResolutionResult().isOK() || localJRECheckPlan == null - || localJRECheckPlan.getStatus().isOK()) { + if (!operation.getResolutionResult().isOK() || localJRECheckPlan == null || compatibleWithCurrentEE()) { return operation.getResolutionResult(); - } else if (localJRECheckPlan != null) { + } else if (!compatibleWithCurrentEE()) { return localJRECheckPlan.getStatus(); } } @@ -460,7 +498,7 @@ public abstract class ProvisioningOperationWizard extends Wizard { public boolean statusOverridesOperation() { return operation != null && operation.getResolutionResult() != null && operation.getResolutionResult().getSeverity() < IStatus.ERROR - && (localJRECheckPlan != null && !localJRECheckPlan.getStatus().isOK()); + && (localJRECheckPlan != null && !compatibleWithCurrentEE()); } public void setRelaxedResolution(boolean value) { |