summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPascal Rapicault (Ericsson)2013-02-14 16:18:26 (EST)
committerPascal Rapicault2013-02-14 16:18:26 (EST)
commit9e096dc6c118e0af8ac81ae8a0e9398397557368 (patch)
tree7428fdd732761ddc51aa5e5263ac6da8fdec7b84
parent4d94af97f0fbf679496a68be657684c297994aa3 (diff)
downloadrt.equinox.p2-9e096dc6c118e0af8ac81ae8a0e9398397557368.zip
rt.equinox.p2-9e096dc6c118e0af8ac81ae8a0e9398397557368.tar.gz
rt.equinox.p2-9e096dc6c118e0af8ac81ae8a0e9398397557368.tar.bz2
Improve logic to detect whether migration is needed
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/META-INF/MANIFEST.MF3
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/sharedinstall/NeedsMigration.java127
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.sdk.scheduler/src/org/eclipse/equinox/internal/p2/ui/sdk/scheduler/AutomaticUpdateScheduler.java32
3 files changed, 153 insertions, 9 deletions
diff --git a/bundles/org.eclipse.equinox.p2.tests/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.tests/META-INF/MANIFEST.MF
index bfd8881..224ab09 100644
--- a/bundles/org.eclipse.equinox.p2.tests/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.p2.tests/META-INF/MANIFEST.MF
@@ -53,7 +53,8 @@ Require-Bundle: org.eclipse.equinox.frameworkadmin,
org.apache.ant;bundle-version="1.7.1",
org.eclipse.equinox.p2.transport.ecf;bundle-version="1.0.0",
org.eclipse.equinox.p2.publisher.eclipse;bundle-version="1.0.0",
- org.eclipse.equinox.p2.operations;bundle-version="2.1.0"
+ org.eclipse.equinox.p2.operations;bundle-version="2.1.0",
+ org.eclipse.equinox.p2.ui.sdk.scheduler
Eclipse-RegisterBuddy: org.eclipse.equinox.p2.artifact.repository
Bundle-RequiredExecutionEnvironment: J2SE-1.5,
J2SE-1.4
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/sharedinstall/NeedsMigration.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/sharedinstall/NeedsMigration.java
new file mode 100644
index 0000000..cf9859f
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/sharedinstall/NeedsMigration.java
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Ericsson AB 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:
+ * Ericsson AB - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.p2.tests.sharedinstall;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import org.eclipse.equinox.internal.p2.ui.sdk.scheduler.AutomaticUpdateScheduler;
+import org.eclipse.equinox.p2.engine.IEngine;
+import org.eclipse.equinox.p2.engine.IProfile;
+import org.eclipse.equinox.p2.metadata.IInstallableUnit;
+import org.eclipse.equinox.p2.planner.IPlanner;
+import org.eclipse.equinox.p2.tests.*;
+
+public class NeedsMigration extends AbstractProvisioningTest {
+ @IUDescription(content = "package: sdk \n" + "singleton: true\n" + "version: 1 \n")
+ public IInstallableUnit sdk1;
+
+ @IUDescription(content = "package: sdk \n" + "singleton: true\n" + "version: 2 \n")
+ public IInstallableUnit sdk2;
+
+ @IUDescription(content = "package: egit \n" + "singleton: true\n" + "version: 1 \n")
+ public IInstallableUnit egit1;
+
+ @IUDescription(content = "package: egit \n" + "singleton: true\n" + "version: 2 \n")
+ public IInstallableUnit egit2;
+
+ @IUDescription(content = "package: cdt \n" + "singleton: true\n" + "version: 1 \n")
+ public IInstallableUnit cdt1;
+
+ @IUDescription(content = "package: eppPackage \n" + "singleton: true\n" + "version: 1 \n" + "depends: sdk = 1, egit =1")
+ public IInstallableUnit eppPackage;
+
+ private IPlanner planner;
+ private IEngine engine;
+ private AutomaticUpdateScheduler scheduler;
+ private Method needsMigrationMethod;
+
+ @Override
+ protected void setUp() throws Exception {
+ IULoader.loadIUs(this);
+ planner = createPlanner();
+ engine = createEngine();
+ scheduler = new AutomaticUpdateScheduler();
+ createTestMetdataRepository(new IInstallableUnit[] {sdk1, sdk2, egit1, egit2, cdt1, eppPackage});
+ needsMigrationMethod = scheduler.getClass().getDeclaredMethod("needsMigration", IProfile.class, IProfile.class);
+ needsMigrationMethod.setAccessible(true);
+ }
+
+ public void testEmptyUserProfile() {
+ IProfile previousUserProfile = createProfile("previous" + getName());
+ IProfile currentBaseProfile = createProfile("current" + getName());
+ assertOK(install(currentBaseProfile, new IInstallableUnit[] {sdk1}, true, planner, engine));
+
+ //The user version and the base version are the same
+ assertFalse(needsMigration(previousUserProfile, currentBaseProfile));
+ }
+
+ public void testSameVersions() {
+ IProfile previousUserProfile = createProfile("previous" + getName());
+ IProfile currentBaseProfile = createProfile("current" + getName());
+ assertOK(install(previousUserProfile, new IInstallableUnit[] {sdk1}, true, planner, engine));
+ assertOK(install(currentBaseProfile, new IInstallableUnit[] {sdk1}, true, planner, engine));
+
+ //The user version and the base version are the same
+ assertFalse(needsMigration(previousUserProfile, currentBaseProfile));
+ }
+
+ public void testDifferentVersions() {
+ IProfile previousUserProfile = createProfile("previous" + getName());
+ IProfile currentBaseProfile = createProfile("current" + getName());
+ assertOK(installAsRoots(previousUserProfile, new IInstallableUnit[] {sdk1}, true, planner, engine));
+ assertOK(installAsRoots(currentBaseProfile, new IInstallableUnit[] {sdk2}, true, planner, engine));
+
+ //The user version is older than the base version
+ assertFalse(needsMigration(previousUserProfile, currentBaseProfile));
+ }
+
+ public void testUserProfileNewerThanBaseVersion() {
+ IProfile previousUserProfile = createProfile("previous" + getName());
+ IProfile currentBaseProfile = createProfile("current" + getName());
+ assertOK(installAsRoots(previousUserProfile, new IInstallableUnit[] {sdk2, egit2}, true, planner, engine));
+ assertOK(installAsRoots(currentBaseProfile, new IInstallableUnit[] {sdk2, egit1}, true, planner, engine));
+
+ //The user version is higher than what the base has
+ assertTrue(needsMigration(previousUserProfile, currentBaseProfile));
+ }
+
+ public void testBaseEncompassWhatUserHas() {
+ IProfile previousUserProfile = createProfile("previous" + getName());
+ IProfile currentBaseProfile = createProfile("current" + getName());
+ assertOK(installAsRoots(previousUserProfile, new IInstallableUnit[] {sdk1, egit1}, true, planner, engine));
+ assertOK(installAsRoots(currentBaseProfile, new IInstallableUnit[] {eppPackage}, true, planner, engine));
+
+ //All the elements that are in the user profile are included in the base
+ assertFalse(needsMigration(previousUserProfile, currentBaseProfile));
+ }
+
+ public void testBaseEncompassSomePartsOfWhatUserHas() {
+ IProfile previousUserProfile = createProfile("previous" + getName());
+ IProfile currentBaseProfile = createProfile("current" + getName());
+ assertOK(installAsRoots(previousUserProfile, new IInstallableUnit[] {sdk1, egit1, cdt1}, true, planner, engine));
+ assertOK(installAsRoots(currentBaseProfile, new IInstallableUnit[] {eppPackage}, true, planner, engine));
+
+ //Not all the elements that are in the user profile are included in the base
+ assertTrue(needsMigration(previousUserProfile, currentBaseProfile));
+ }
+
+ private boolean needsMigration(IProfile previousUserProfile, IProfile currentBaseProfile) {
+ try {
+ return (Boolean) needsMigrationMethod.invoke(scheduler, previousUserProfile, currentBaseProfile);
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException(e);
+ } catch (IllegalArgumentException e) {
+ throw new RuntimeException(e);
+ } catch (InvocationTargetException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.ui.sdk.scheduler/src/org/eclipse/equinox/internal/p2/ui/sdk/scheduler/AutomaticUpdateScheduler.java b/bundles/org.eclipse.equinox.p2.ui.sdk.scheduler/src/org/eclipse/equinox/internal/p2/ui/sdk/scheduler/AutomaticUpdateScheduler.java
index 2183d5b..9bdc282 100644
--- a/bundles/org.eclipse.equinox.p2.ui.sdk.scheduler/src/org/eclipse/equinox/internal/p2/ui/sdk/scheduler/AutomaticUpdateScheduler.java
+++ b/bundles/org.eclipse.equinox.p2.ui.sdk.scheduler/src/org/eclipse/equinox/internal/p2/ui/sdk/scheduler/AutomaticUpdateScheduler.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008, 2011 IBM Corporation and others.
+ * Copyright (c) 2008, 2013 IBM Corporation 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
@@ -12,17 +12,18 @@
*******************************************************************************/
package org.eclipse.equinox.internal.p2.ui.sdk.scheduler;
-import org.eclipse.equinox.internal.p2.ui.sdk.scheduler.migration.AbstractPage_c;
-import org.eclipse.equinox.internal.p2.ui.sdk.scheduler.migration.ImportFromInstallationWizard_c;
-
import com.ibm.icu.util.Calendar;
import com.ibm.icu.util.ULocale;
+import java.util.Iterator;
import java.util.Set;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.preferences.ConfigurationScope;
import org.eclipse.core.runtime.preferences.IScopeContext;
import org.eclipse.equinox.internal.p2.core.helpers.ServiceHelper;
import org.eclipse.equinox.internal.p2.garbagecollector.GarbageCollector;
+import org.eclipse.equinox.internal.p2.metadata.query.UpdateQuery;
+import org.eclipse.equinox.internal.p2.ui.sdk.scheduler.migration.AbstractPage_c;
+import org.eclipse.equinox.internal.p2.ui.sdk.scheduler.migration.ImportFromInstallationWizard_c;
import org.eclipse.equinox.internal.provisional.p2.updatechecker.*;
import org.eclipse.equinox.p2.core.IProvisioningAgent;
import org.eclipse.equinox.p2.engine.IProfile;
@@ -31,6 +32,7 @@ import org.eclipse.equinox.p2.engine.query.IUProfilePropertyQuery;
import org.eclipse.equinox.p2.engine.query.UserVisibleRootQuery;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
import org.eclipse.equinox.p2.query.IQuery;
+import org.eclipse.equinox.p2.query.QueryUtil;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.swt.widgets.Display;
@@ -119,7 +121,7 @@ public class AutomaticUpdateScheduler implements IStartup {
final IProfile previousProfile = findProfileBeforeReset(registry, currentProfile);
if (previousProfile != null && currentProfile != null) {
- if (isCurrentProfileLacksUnitsFromPrevious(previousProfile, currentProfile)) {
+ if (needsMigration(previousProfile, currentProfile)) {
if (remindMeLater) {
openMigrationWizard(previousProfile);
}
@@ -133,13 +135,27 @@ public class AutomaticUpdateScheduler implements IStartup {
* @param currentProfile is the current profile used by eclipse.
* @return true if set difference between previousProfile units and currentProfile units not empty, otherwise false
*/
- private boolean isCurrentProfileLacksUnitsFromPrevious(IProfile previousProfile, IProfile currentProfile) {
-
+ private boolean needsMigration(IProfile previousProfile, IProfile currentProfile) {
+ //First, try the case of inclusion
Set<IInstallableUnit> previousProfileUnits = previousProfile.query(new UserVisibleRootQuery(), null).toSet();
Set<IInstallableUnit> currentProfileUnits = currentProfile.available(new UserVisibleRootQuery(), null).toSet();
previousProfileUnits.removeAll(currentProfileUnits);
- return !previousProfileUnits.isEmpty();
+ //For the IUs left in the previous profile, look for those that could be in the base but not as roots
+ Iterator<IInstallableUnit> previousProfileIterator = previousProfileUnits.iterator();
+ while (previousProfileIterator.hasNext()) {
+ if (!currentProfile.available(QueryUtil.createIUQuery(previousProfileIterator.next()), null).isEmpty())
+ previousProfileIterator.remove();
+ }
+
+ //For the IUs left in the previous profile, look for those that could be available in the root but as higher versions (they could be root or not)
+ previousProfileIterator = previousProfileUnits.iterator();
+ while (previousProfileIterator.hasNext()) {
+ if (!currentProfile.available(new UpdateQuery(previousProfileIterator.next()), null).isEmpty())
+ previousProfileIterator.remove();
+ }
+
+ return !previousProfileUnits.isEmpty();
}
private void openMigrationWizard(final IProfile inputProfile) {