From ce38196f8e47fa3b48805b36eaca55716c0af79c Mon Sep 17 00:00:00 2001 From: Raphael Moll Date: Wed, 14 Nov 2012 13:59:45 -0800 Subject: SDK Manager: handle platform-tools preview + final. One issue is that when there was only one instance of platform-tools possible, the computeUpdates() code would pick the first one. But now there can be 2 of them (preview, non-preview) and thus we need to pick up the higher one even if it's not the first choice. Same issue with tools: if a platform depends on tools and there are none installed, we need to pick the highest version of the available preview or final package that satisfies the dependency. Note that in both cases the issue does not arise if there's already a tools or platform-tools installed. Change-Id: I61db2881274dafa32c5c303c0b3569fc336b8e92 --- .../internal/repository/SdkUpdaterLogic.java | 128 ++++-- .../internal/repository/SdkUpdaterLogicTest.java | 495 +++++++++++++++++++++ .../internal/repository/UpdaterLogicTest.java | 366 --------------- 3 files changed, 580 insertions(+), 409 deletions(-) create mode 100755 sdkmanager/libs/sdkuilib/tests/com/android/sdkuilib/internal/repository/SdkUpdaterLogicTest.java delete mode 100755 sdkmanager/libs/sdkuilib/tests/com/android/sdkuilib/internal/repository/UpdaterLogicTest.java (limited to 'sdkmanager/libs/sdkuilib') diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/SdkUpdaterLogic.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/SdkUpdaterLogic.java index da71115..25e6553 100755 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/SdkUpdaterLogic.java +++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/SdkUpdaterLogic.java @@ -738,25 +738,34 @@ class SdkUpdaterLogic { // Finally nothing matched, so let's look at all available remote packages fetchRemotePackages(remotePkgs, remoteSources); + FullRevision localRev = rev; + Archive localArch = null; for (Package p : remotePkgs) { if (p instanceof ToolPackage) { - if (((ToolPackage) p).getRevision().compareTo(rev) >= 0) { + FullRevision r = ((ToolPackage) p).getRevision(); + if (r.compareTo(localRev) >= 0) { // It's not already in the list of things to install, so add the // first compatible archive we can find. for (Archive a : p.getArchives()) { if (a.isCompatible()) { - return insertArchive(a, - outArchives, - selectedArchives, - remotePkgs, - remoteSources, - localArchives, - true /*automated*/); + localRev = r; + localArch = a; + break; } } } } } + if (localArch != null) { + return insertArchive(localArch, + outArchives, + selectedArchives, + remotePkgs, + remoteSources, + localArchives, + true /*automated*/); + + } // We end up here if nothing matches. We don't have a good platform to match. // We need to indicate this extra depends on a missing platform archive @@ -782,6 +791,7 @@ class SdkUpdaterLogic { // This is the requirement to match. FullRevision rev = pkg.getMinPlatformToolsRevision(); boolean findMax = false; + int compareThreshold = 0; ArchiveInfo aiMax = null; Archive aMax = null; @@ -793,6 +803,9 @@ class SdkUpdaterLogic { // So instead we parse all the existing and remote packages and try to find // the max available revision and we'll use it. findMax = true; + // When findMax is false, we want r.compareTo(rev) >= 0. + // When findMax is true, we want r.compareTo(rev) > 0 (so >= 1). + compareThreshold = 1; } // First look in locally installed packages. @@ -802,10 +815,10 @@ class SdkUpdaterLogic { Package p = a.getParentPackage(); if (p instanceof PlatformToolPackage) { FullRevision r = ((PlatformToolPackage) p).getRevision(); - if (findMax && r.compareTo(rev) > 0) { + if (findMax && r.compareTo(rev) > compareThreshold) { rev = r; aiMax = ai; - } else if (!findMax && r.compareTo(rev) >= 0) { + } else if (!findMax && r.compareTo(rev) >= compareThreshold) { // We found one already installed. return null; } @@ -813,6 +826,9 @@ class SdkUpdaterLogic { } } + // Because of previews, we can have more than 1 choice, so get the local max. + FullRevision localRev = rev; + ArchiveInfo localAiMax = null; // Look in archives already scheduled for install for (ArchiveInfo ai : outArchives) { Archive a = ai.getNewArchive(); @@ -820,43 +836,61 @@ class SdkUpdaterLogic { Package p = a.getParentPackage(); if (p instanceof PlatformToolPackage) { FullRevision r = ((PlatformToolPackage) p).getRevision(); - if (findMax && r.compareTo(rev) > 0) { - rev = r; - aiMax = ai; - } else if (!findMax && r.compareTo(rev) >= 0) { - // The dependency is already scheduled for install, nothing else to do. - return ai; + if (r.compareTo(localRev) >= compareThreshold) { + localRev = r; + localAiMax = ai; } } } } + if (localAiMax != null) { + if (findMax) { + rev = localRev; + aiMax = localAiMax; + } else { + // The dependency is already scheduled for install, nothing else to do. + return localAiMax; + } + } + // Otherwise look in the selected archives. + localRev = rev; + Archive localAMax = null; if (selectedArchives != null) { for (Archive a : selectedArchives) { Package p = a.getParentPackage(); if (p instanceof PlatformToolPackage) { FullRevision r = ((PlatformToolPackage) p).getRevision(); - if (findMax && r.compareTo(rev) > 0) { - rev = r; - aiMax = null; - aMax = a; - } else if (!findMax && r.compareTo(rev) >= 0) { - // It's not already in the list of things to install, so add it now - return insertArchive(a, - outArchives, - selectedArchives, - remotePkgs, - remoteSources, - localArchives, - true /*automated*/); + if (r.compareTo(localRev) >= compareThreshold) { + localRev = r; + localAiMax = null; + localAMax = a; } } } + if (localAMax != null) { + if (findMax) { + rev = localRev; + aiMax = null; + aMax = localAMax; + } else { + // It's not already in the list of things to install, so add it now + return insertArchive(localAMax, + outArchives, + selectedArchives, + remotePkgs, + remoteSources, + localArchives, + true /*automated*/); + } + } } // Finally nothing matched, so let's look at all available remote packages fetchRemotePackages(remotePkgs, remoteSources); + localRev = rev; + localAMax = null; for (Package p : remotePkgs) { if (p instanceof PlatformToolPackage) { FullRevision r = ((PlatformToolPackage) p).getRevision(); @@ -864,26 +898,34 @@ class SdkUpdaterLogic { // Make sure there's at least one valid archive here for (Archive a : p.getArchives()) { if (a.isCompatible()) { - if (findMax && r.compareTo(rev) > 0) { - rev = r; - aiMax = null; - aMax = a; - } else if (!findMax && r.compareTo(rev) >= 0) { - // It's not already in the list of things to install, so add the - // first compatible archive we can find. - return insertArchive(a, - outArchives, - selectedArchives, - remotePkgs, - remoteSources, - localArchives, - true /*automated*/); + if (r.compareTo(localRev) >= compareThreshold) { + localRev = r; + localAiMax = null; + localAMax = a; + break; } } } } } } + if (localAMax != null) { + if (findMax) { + rev = localRev; + aiMax = null; + aMax = localAMax; + } else { + // It's not already in the list of things to install, so add the + // first compatible archive we can find. + return insertArchive(localAMax, + outArchives, + selectedArchives, + remotePkgs, + remoteSources, + localArchives, + true /*automated*/); + } + } if (findMax) { if (aMax != null) { diff --git a/sdkmanager/libs/sdkuilib/tests/com/android/sdkuilib/internal/repository/SdkUpdaterLogicTest.java b/sdkmanager/libs/sdkuilib/tests/com/android/sdkuilib/internal/repository/SdkUpdaterLogicTest.java new file mode 100755 index 0000000..6a93914 --- /dev/null +++ b/sdkmanager/libs/sdkuilib/tests/com/android/sdkuilib/internal/repository/SdkUpdaterLogicTest.java @@ -0,0 +1,495 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.sdkuilib.internal.repository; + +import com.android.sdklib.SdkManager; +import com.android.sdklib.internal.avd.AvdManager; +import com.android.sdklib.internal.repository.DownloadCache; +import com.android.sdklib.internal.repository.ITaskFactory; +import com.android.sdklib.internal.repository.archives.Archive; +import com.android.sdklib.internal.repository.packages.FullRevision; +import com.android.sdklib.internal.repository.packages.MockAddonPackage; +import com.android.sdklib.internal.repository.packages.MockBrokenPackage; +import com.android.sdklib.internal.repository.packages.MockPlatformPackage; +import com.android.sdklib.internal.repository.packages.MockPlatformToolPackage; +import com.android.sdklib.internal.repository.packages.MockToolPackage; +import com.android.sdklib.internal.repository.packages.Package; +import com.android.sdklib.internal.repository.sources.SdkSource; +import com.android.sdklib.internal.repository.sources.SdkSources; +import com.android.sdkuilib.internal.repository.icons.ImageFactory; +import com.android.utils.ILogger; + +import org.eclipse.swt.widgets.Shell; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +import junit.framework.TestCase; + +public class SdkUpdaterLogicTest extends TestCase { + + private static class NullUpdaterData implements IUpdaterData { + + @Override + public AvdManager getAvdManager() { + return null; + } + + @Override + public ImageFactory getImageFactory() { + return null; + } + + @Override + public ILogger getSdkLog() { + return null; + } + + @Override + public DownloadCache getDownloadCache() { + return null; + } + + @Override + public SdkManager getSdkManager() { + return null; + } + + @Override + public SettingsController getSettingsController() { + return null; + } + + @Override + public ITaskFactory getTaskFactory() { + return null; + } + + @Override + public Shell getWindowShell() { + return null; + } + + } + + private static class MockSdkUpdaterLogic extends SdkUpdaterLogic { + private final Package[] mRemotePackages; + + public MockSdkUpdaterLogic(IUpdaterData updaterData, Package[] remotePackages) { + super(updaterData); + mRemotePackages = remotePackages; + } + + @Override + protected void fetchRemotePackages(Collection remotePkgs, + SdkSource[] remoteSources) { + // Ignore remoteSources and instead uses the remotePackages list given to the + // constructor. + if (mRemotePackages != null) { + remotePkgs.addAll(Arrays.asList(mRemotePackages)); + } + } + } + + /** + * Addon packages depend on a base platform package. + * This test checks that UpdaterLogic.findPlatformToolsDependency(...) + * can find the base platform for a given addon. + */ + public void testFindAddonDependency() { + MockSdkUpdaterLogic mul = new MockSdkUpdaterLogic(new NullUpdaterData(), null); + + MockPlatformPackage p1 = new MockPlatformPackage(1, 1); + MockPlatformPackage p2 = new MockPlatformPackage(2, 1); + + MockAddonPackage a1 = new MockAddonPackage(p1, 1); + MockAddonPackage a2 = new MockAddonPackage(p2, 2); + + ArrayList out = new ArrayList(); + ArrayList selected = new ArrayList(); + ArrayList remote = new ArrayList(); + + // a2 depends on p2, which is not in the locals + Package[] localPkgs = { p1, a1 }; + ArchiveInfo[] locals = mul.createLocalArchives(localPkgs); + + SdkSource[] sources = null; + + // a2 now depends on a "fake" archive info with no newArchive that wraps the missing + // underlying platform. + ArchiveInfo fai = mul.findPlatformDependency(a2, out, selected, remote, sources, locals); + assertNotNull(fai); + assertNull(fai.getNewArchive()); + assertTrue(fai.isRejected()); + assertEquals(0, out.size()); + + // p2 is now selected, and should be scheduled for install in out + Archive p2_archive = p2.getArchives()[0]; + selected.add(p2_archive); + ArchiveInfo ai2 = mul.findPlatformDependency(a2, out, selected, remote, sources, locals); + assertNotNull(ai2); + assertSame(p2_archive, ai2.getNewArchive()); + assertEquals(1, out.size()); + assertSame(p2_archive, out.get(0).getNewArchive()); + } + + /** + * Broken add-on packages require an exact platform package to be present or installed. + * This tests checks that findExactApiLevelDependency() can find a base + * platform package for a given broken add-on package. + */ + public void testFindExactApiLevelDependency() { + MockSdkUpdaterLogic mul = new MockSdkUpdaterLogic(new NullUpdaterData(), null); + + MockPlatformPackage p1 = new MockPlatformPackage(1, 1); + MockPlatformPackage p2 = new MockPlatformPackage(2, 1); + + MockBrokenPackage a1 = new MockBrokenPackage(0, 1); + MockBrokenPackage a2 = new MockBrokenPackage(0, 2); + + ArrayList out = new ArrayList(); + ArrayList selected = new ArrayList(); + ArrayList remote = new ArrayList(); + + // a2 depends on p2, which is not in the locals + Package[] localPkgs = { p1, a1 }; + ArchiveInfo[] locals = mul.createLocalArchives(localPkgs); + + SdkSource[] sources = null; + + // a1 depends on p1, which can be found in the locals. p1 is already "installed" + // so we donn't need to suggest it as a dependency to solve any problem. + ArchiveInfo found = mul.findExactApiLevelDependency( + a1, out, selected, remote, sources, locals); + assertNull(found); + + // a2 now depends on a "fake" archive info with no newArchive that wraps the missing + // underlying platform. + found = mul.findExactApiLevelDependency(a2, out, selected, remote, sources, locals); + assertNotNull(found); + assertNull(found.getNewArchive()); + assertTrue(found.isRejected()); + assertEquals(0, out.size()); + + // p2 is now selected, and should be scheduled for install in out + Archive p2_archive = p2.getArchives()[0]; + selected.add(p2_archive); + found = mul.findExactApiLevelDependency(a2, out, selected, remote, sources, locals); + assertNotNull(found); + assertSame(p2_archive, found.getNewArchive()); + assertEquals(1, out.size()); + assertSame(p2_archive, out.get(0).getNewArchive()); + } + + /** + * Platform packages depend on a tool package. + * This tests checks that UpdaterLogic.findToolsDependency() can find a base + * tool package for a given platform package. + */ + public void testFindPlatformDependency() { + MockSdkUpdaterLogic mul = new MockSdkUpdaterLogic(new NullUpdaterData(), null); + + MockPlatformToolPackage pt1 = new MockPlatformToolPackage(1); + + MockToolPackage t1 = new MockToolPackage(1, 1); + MockToolPackage t2 = new MockToolPackage(2, 1); + + MockPlatformPackage p2 = new MockPlatformPackage(2, 1, 2); + + ArrayList out = new ArrayList(); + ArrayList selected = new ArrayList(); + ArrayList remote = new ArrayList(); + + // p2 depends on t2, which is not locally installed + Package[] localPkgs = { t1, pt1 }; + ArchiveInfo[] locals = mul.createLocalArchives(localPkgs); + + SdkSource[] sources = null; + + // p2 now depends on a "fake" archive info with no newArchive that wraps the missing + // underlying tool + ArchiveInfo fai = mul.findToolsDependency(p2, out, selected, remote, sources, locals); + assertNotNull(fai); + assertNull(fai.getNewArchive()); + assertTrue(fai.isRejected()); + assertEquals(0, out.size()); + + // t2 is now selected and can be used as a dependency + Archive t2_archive = t2.getArchives()[0]; + selected.add(t2_archive); + ArchiveInfo ai2 = mul.findToolsDependency(p2, out, selected, remote, sources, locals); + assertNotNull(ai2); + assertSame(t2_archive, ai2.getNewArchive()); + assertEquals(1, out.size()); + assertSame(t2_archive, out.get(0).getNewArchive()); + } + + /** + * Tool packages require a platform-tool package to be present or installed. + * This tests checks that UpdaterLogic.findPlatformToolsDependency() can find a base + * platform-tool package for a given tool package. + */ + public void testFindPlatformToolDependency() { + MockSdkUpdaterLogic mul = new MockSdkUpdaterLogic(new NullUpdaterData(), null); + + MockPlatformToolPackage t1 = new MockPlatformToolPackage(1); + MockPlatformToolPackage t2 = new MockPlatformToolPackage(2); + + MockToolPackage p2 = new MockToolPackage(2, 2); + + ArrayList out = new ArrayList(); + ArrayList selected = new ArrayList(); + ArrayList remote = new ArrayList(); + + // p2 depends on t2, which is not locally installed + Package[] localPkgs = { t1 }; + ArchiveInfo[] locals = mul.createLocalArchives(localPkgs); + + SdkSource[] sources = null; + + // p2 now depends on a "fake" archive info with no newArchive that wraps the missing + // underlying tool + ArchiveInfo fai = mul.findPlatformToolsDependency( + p2, out, selected, remote, sources, locals); + assertNotNull(fai); + assertNull(fai.getNewArchive()); + assertTrue(fai.isRejected()); + assertEquals(0, out.size()); + + // t2 is now selected and can be used as a dependency + Archive t2_archive = t2.getArchives()[0]; + selected.add(t2_archive); + ArchiveInfo ai2 = mul.findPlatformToolsDependency( + p2, out, selected, remote, sources, locals); + assertNotNull(ai2); + assertSame(t2_archive, ai2.getNewArchive()); + assertEquals(1, out.size()); + assertSame(t2_archive, out.get(0).getNewArchive()); + } + + public void testComputeRevisionUpdate() { + // Scenario: + // - user has tools rev 7 installed + plat-tools rev 1 installed + // - server has tools rev 8, depending on plat-tools rev 2 + // - server has tools rev 9, depending on plat-tools rev 3 + // - server has platform 9 that requires min-tools-rev 9 + // + // If we do an update all, we want to the installer to pick up: + // - the new platform 9 + // - the tools rev 9 (required by platform 9) + // - the plat-tools rev 3 (required by tools rev 9) + + final MockPlatformToolPackage pt1 = new MockPlatformToolPackage(1); + final MockPlatformToolPackage pt2 = new MockPlatformToolPackage(2); + final MockPlatformToolPackage pt3 = new MockPlatformToolPackage(3); + + final MockToolPackage t7 = new MockToolPackage(7, 1 /*min-plat-tools*/); + final MockToolPackage t8 = new MockToolPackage(8, 2 /*min-plat-tools*/); + final MockToolPackage t9 = new MockToolPackage(9, 3 /*min-plat-tools*/); + + final MockPlatformPackage p9 = new MockPlatformPackage(9, 1, 9 /*min-tools*/); + + // Note: the mock updater logic gets the remotes packages from the array given + // here and bypasses the source (to avoid fetching any actual URLs) + MockSdkUpdaterLogic mul = new MockSdkUpdaterLogic(new NullUpdaterData(), + new Package[] { t8, pt2, t9, pt3, p9 }); + + SdkSources sources = new SdkSources(); + Package[] localPkgs = { t7, pt1 }; + + List selected = mul.computeUpdates( + null /*selectedArchives*/, + sources, + localPkgs, + false /*includeObsoletes*/); + + assertEquals( + "[Android SDK Platform-tools, revision 3, " + + "Android SDK Tools, revision 9]", + Arrays.toString(selected.toArray())); + + mul.addNewPlatforms( + selected, + sources, + localPkgs, + false /*includeObsoletes*/); + + assertEquals( + "[Android SDK Platform-tools, revision 3, " + + "Android SDK Tools, revision 9, " + + "SDK Platform Android android-9, API 9, revision 1]", + Arrays.toString(selected.toArray())); + + // Now try again but reverse the order of the remote package list. + + mul = new MockSdkUpdaterLogic(new NullUpdaterData(), + new Package[] { p9, t9, pt3, t8, pt2 }); + + selected = mul.computeUpdates( + null /*selectedArchives*/, + sources, + localPkgs, + false /*includeObsoletes*/); + + assertEquals( + "[Android SDK Platform-tools, revision 3, " + + "Android SDK Tools, revision 9]", + Arrays.toString(selected.toArray())); + + mul.addNewPlatforms( + selected, + sources, + localPkgs, + false /*includeObsoletes*/); + + assertEquals( + "[Android SDK Platform-tools, revision 3, " + + "Android SDK Tools, revision 9, " + + "SDK Platform Android android-9, API 9, revision 1]", + Arrays.toString(selected.toArray())); + } + + public void testComputeRevisionUpdate2() { + // Scenario: + // - user has tools rev 2 installed and NO platform-tools + // - server has platform tools 1 rc 1 (a preview) and 2. + // - server has platform 2 that requires min-tools 2 that requires min-plat-tools 1rc1. + // + // One issue is that when there was only one instance of platform-tools possible, + // the computeUpdates() code would pick the first one. But now there can be 2 of + // them (preview, non-preview) and thus we need to pick up the higher one even if + // it's not the first choice. + + final MockPlatformToolPackage pt1rc = new MockPlatformToolPackage( + null, + new FullRevision(1, 0, 0, 1)); + final MockPlatformToolPackage pt2 = new MockPlatformToolPackage(2); + + // Tools rev 2 requires at least plat-tools 1rc1 + final MockToolPackage t2 = new MockToolPackage(null, + new FullRevision(2), // tools rev + new FullRevision(1, 0, 0, 1)); // min-pt-rev + + final MockPlatformPackage p2 = new MockPlatformPackage(2, 1, 2 /*min-tools*/); + + // Note: the mock updater logic gets the remotes packages from the array given + // here and bypasses the source (to avoid fetching any actual URLs) + // Remote available packages include both plat-tools 1rc1 and 2. + // + // Order DOES matter: the issue is that computeUpdates was selecting the first platform + // tools (so 1rc1) and ignoring the newer revision 2 because originally there could be + // only one platform-tool definition. Now with previews we can have 2 and we need to + // select the higher one even if it's not the first choice. + MockSdkUpdaterLogic mul = new MockSdkUpdaterLogic(new NullUpdaterData(), + new Package[] { t2, pt1rc, pt2, p2 }); + + // Local packages only have tools 2. + SdkSources sources = new SdkSources(); + Package[] localPkgs = { t2 }; + List selectedArchives = Arrays.asList( p2.getArchives() ); + + List selected = mul.computeUpdates( + selectedArchives, + sources, + localPkgs, + false /*includeObsoletes*/); + + assertEquals( + "[SDK Platform Android android-2, API 2, revision 1, " + + "Android SDK Platform-tools, revision 2]", + Arrays.toString(selected.toArray())); + + mul.addNewPlatforms( + selected, + sources, + localPkgs, + false /*includeObsoletes*/); + + assertEquals( + "[SDK Platform Android android-2, API 2, revision 1, " + + "Android SDK Platform-tools, revision 2]", + Arrays.toString(selected.toArray())); + } + + public void testComputeRevisionUpdate3() { + // Scenario: + // - user has tools rev 2 installed and NO platform-tools + // - server has platform tools 1 rc 1 (a preview) and 2. + // - server has platform 2 that requires min-tools 2 that requires min-plat-tools 1rc1. + // + // One issue is that when there was only one instance of tools possible, + // the computeUpdates() code would pick the first one. But now there can be 2 of + // them (preview, non-preview) and thus we need to pick up the higher one even if + // it's not the first choice. + + final MockPlatformToolPackage pt1rc = new MockPlatformToolPackage( + null, + new FullRevision(1, 0, 0, 1)); + final MockPlatformToolPackage pt2 = new MockPlatformToolPackage(2); + + // Tools rev 1rc1 requires plat-tools 1rc1, and tools 2 requires plat-tools 2. + final MockToolPackage t1rc = new MockToolPackage(null, + new FullRevision(1, 0, 0, 1), // tools rev + new FullRevision(1, 0, 0, 1)); // min-pt-rev + final MockToolPackage t2 = new MockToolPackage(null, 2, 2); + + // Platform depends on min-tools 1rc1, so any of tools 1rc1 or 2 would satisfy. + final MockPlatformPackage p2 = new MockPlatformPackage(2, 1, new FullRevision(1, 0, 0, 1)); + + // Note: the mock updater logic gets the remotes packages from the array given + // here and bypasses the source (to avoid fetching any actual URLs) + // Remote available packages include both plat-tools 1rc1 and 2. + // + // Order DOES matter: the issue is that computeUpdates was selecting the first tools (1rc1) + // and ignoring the newer revision 2 because originally there could be only one tool + // definition. Now with previews we can have 2 and we need to select the higher version + // available even if it's not the first choice. + MockSdkUpdaterLogic mul = new MockSdkUpdaterLogic(new NullUpdaterData(), + new Package[] { t1rc, pt1rc, t2, pt2, p2 }); + + // Local packages only have tools 2. + SdkSources sources = new SdkSources(); + Package[] localPkgs = { }; + List selectedArchives = Arrays.asList( p2.getArchives() ); + + List selected = mul.computeUpdates( + selectedArchives, + sources, + localPkgs, + false /*includeObsoletes*/); + + assertEquals( + "[Android SDK Platform-tools, revision 2, " + + "Android SDK Tools, revision 2, " + + "SDK Platform Android android-2, API 2, revision 1]", + Arrays.toString(selected.toArray())); + + mul.addNewPlatforms( + selected, + sources, + localPkgs, + false /*includeObsoletes*/); + + assertEquals( + "[Android SDK Platform-tools, revision 2, " + + "Android SDK Tools, revision 2, " + + "SDK Platform Android android-2, API 2, revision 1]", + Arrays.toString(selected.toArray())); + } +} diff --git a/sdkmanager/libs/sdkuilib/tests/com/android/sdkuilib/internal/repository/UpdaterLogicTest.java b/sdkmanager/libs/sdkuilib/tests/com/android/sdkuilib/internal/repository/UpdaterLogicTest.java deleted file mode 100755 index 7918885..0000000 --- a/sdkmanager/libs/sdkuilib/tests/com/android/sdkuilib/internal/repository/UpdaterLogicTest.java +++ /dev/null @@ -1,366 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.repository; - -import com.android.sdklib.SdkManager; -import com.android.sdklib.internal.avd.AvdManager; -import com.android.sdklib.internal.repository.DownloadCache; -import com.android.sdklib.internal.repository.ITaskFactory; -import com.android.sdklib.internal.repository.archives.Archive; -import com.android.sdklib.internal.repository.packages.MockAddonPackage; -import com.android.sdklib.internal.repository.packages.MockBrokenPackage; -import com.android.sdklib.internal.repository.packages.MockPlatformPackage; -import com.android.sdklib.internal.repository.packages.MockPlatformToolPackage; -import com.android.sdklib.internal.repository.packages.MockToolPackage; -import com.android.sdklib.internal.repository.packages.Package; -import com.android.sdklib.internal.repository.sources.SdkSource; -import com.android.sdklib.internal.repository.sources.SdkSources; -import com.android.sdkuilib.internal.repository.icons.ImageFactory; -import com.android.utils.ILogger; - -import org.eclipse.swt.widgets.Shell; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; - -import junit.framework.TestCase; - -public class UpdaterLogicTest extends TestCase { - - private static class NullUpdaterData implements IUpdaterData { - - @Override - public AvdManager getAvdManager() { - return null; - } - - @Override - public ImageFactory getImageFactory() { - return null; - } - - @Override - public ILogger getSdkLog() { - return null; - } - - @Override - public DownloadCache getDownloadCache() { - return null; - } - - @Override - public SdkManager getSdkManager() { - return null; - } - - @Override - public SettingsController getSettingsController() { - return null; - } - - @Override - public ITaskFactory getTaskFactory() { - return null; - } - - @Override - public Shell getWindowShell() { - return null; - } - - } - - private static class MockUpdaterLogic extends SdkUpdaterLogic { - private final Package[] mRemotePackages; - - public MockUpdaterLogic(IUpdaterData updaterData, Package[] remotePackages) { - super(updaterData); - mRemotePackages = remotePackages; - } - - @Override - protected void fetchRemotePackages(Collection remotePkgs, - SdkSource[] remoteSources) { - // Ignore remoteSources and instead uses the remotePackages list given to the - // constructor. - if (mRemotePackages != null) { - remotePkgs.addAll(Arrays.asList(mRemotePackages)); - } - } - } - - /** - * Addon packages depend on a base platform package. - * This test checks that UpdaterLogic.findPlatformToolsDependency(...) - * can find the base platform for a given addon. - */ - public void testFindAddonDependency() { - MockUpdaterLogic mul = new MockUpdaterLogic(new NullUpdaterData(), null); - - MockPlatformPackage p1 = new MockPlatformPackage(1, 1); - MockPlatformPackage p2 = new MockPlatformPackage(2, 1); - - MockAddonPackage a1 = new MockAddonPackage(p1, 1); - MockAddonPackage a2 = new MockAddonPackage(p2, 2); - - ArrayList out = new ArrayList(); - ArrayList selected = new ArrayList(); - ArrayList remote = new ArrayList(); - - // a2 depends on p2, which is not in the locals - Package[] localPkgs = { p1, a1 }; - ArchiveInfo[] locals = mul.createLocalArchives(localPkgs); - - SdkSource[] sources = null; - - // a2 now depends on a "fake" archive info with no newArchive that wraps the missing - // underlying platform. - ArchiveInfo fai = mul.findPlatformDependency(a2, out, selected, remote, sources, locals); - assertNotNull(fai); - assertNull(fai.getNewArchive()); - assertTrue(fai.isRejected()); - assertEquals(0, out.size()); - - // p2 is now selected, and should be scheduled for install in out - Archive p2_archive = p2.getArchives()[0]; - selected.add(p2_archive); - ArchiveInfo ai2 = mul.findPlatformDependency(a2, out, selected, remote, sources, locals); - assertNotNull(ai2); - assertSame(p2_archive, ai2.getNewArchive()); - assertEquals(1, out.size()); - assertSame(p2_archive, out.get(0).getNewArchive()); - } - - /** - * Broken add-on packages require an exact platform package to be present or installed. - * This tests checks that findExactApiLevelDependency() can find a base - * platform package for a given broken add-on package. - */ - public void testFindExactApiLevelDependency() { - MockUpdaterLogic mul = new MockUpdaterLogic(new NullUpdaterData(), null); - - MockPlatformPackage p1 = new MockPlatformPackage(1, 1); - MockPlatformPackage p2 = new MockPlatformPackage(2, 1); - - MockBrokenPackage a1 = new MockBrokenPackage(0, 1); - MockBrokenPackage a2 = new MockBrokenPackage(0, 2); - - ArrayList out = new ArrayList(); - ArrayList selected = new ArrayList(); - ArrayList remote = new ArrayList(); - - // a2 depends on p2, which is not in the locals - Package[] localPkgs = { p1, a1 }; - ArchiveInfo[] locals = mul.createLocalArchives(localPkgs); - - SdkSource[] sources = null; - - // a1 depends on p1, which can be found in the locals. p1 is already "installed" - // so we donn't need to suggest it as a dependency to solve any problem. - ArchiveInfo found = mul.findExactApiLevelDependency( - a1, out, selected, remote, sources, locals); - assertNull(found); - - // a2 now depends on a "fake" archive info with no newArchive that wraps the missing - // underlying platform. - found = mul.findExactApiLevelDependency(a2, out, selected, remote, sources, locals); - assertNotNull(found); - assertNull(found.getNewArchive()); - assertTrue(found.isRejected()); - assertEquals(0, out.size()); - - // p2 is now selected, and should be scheduled for install in out - Archive p2_archive = p2.getArchives()[0]; - selected.add(p2_archive); - found = mul.findExactApiLevelDependency(a2, out, selected, remote, sources, locals); - assertNotNull(found); - assertSame(p2_archive, found.getNewArchive()); - assertEquals(1, out.size()); - assertSame(p2_archive, out.get(0).getNewArchive()); - } - - /** - * Platform packages depend on a tool package. - * This tests checks that UpdaterLogic.findToolsDependency() can find a base - * tool package for a given platform package. - */ - public void testFindPlatformDependency() { - MockUpdaterLogic mul = new MockUpdaterLogic(new NullUpdaterData(), null); - - MockPlatformToolPackage pt1 = new MockPlatformToolPackage(1); - - MockToolPackage t1 = new MockToolPackage(1, 1); - MockToolPackage t2 = new MockToolPackage(2, 1); - - MockPlatformPackage p2 = new MockPlatformPackage(2, 1, 2); - - ArrayList out = new ArrayList(); - ArrayList selected = new ArrayList(); - ArrayList remote = new ArrayList(); - - // p2 depends on t2, which is not locally installed - Package[] localPkgs = { t1, pt1 }; - ArchiveInfo[] locals = mul.createLocalArchives(localPkgs); - - SdkSource[] sources = null; - - // p2 now depends on a "fake" archive info with no newArchive that wraps the missing - // underlying tool - ArchiveInfo fai = mul.findToolsDependency(p2, out, selected, remote, sources, locals); - assertNotNull(fai); - assertNull(fai.getNewArchive()); - assertTrue(fai.isRejected()); - assertEquals(0, out.size()); - - // t2 is now selected and can be used as a dependency - Archive t2_archive = t2.getArchives()[0]; - selected.add(t2_archive); - ArchiveInfo ai2 = mul.findToolsDependency(p2, out, selected, remote, sources, locals); - assertNotNull(ai2); - assertSame(t2_archive, ai2.getNewArchive()); - assertEquals(1, out.size()); - assertSame(t2_archive, out.get(0).getNewArchive()); - } - - /** - * Tool packages require a platform-tool package to be present or installed. - * This tests checks that UpdaterLogic.findPlatformToolsDependency() can find a base - * platform-tool package for a given tool package. - */ - public void testFindPlatformToolDependency() { - MockUpdaterLogic mul = new MockUpdaterLogic(new NullUpdaterData(), null); - - MockPlatformToolPackage t1 = new MockPlatformToolPackage(1); - MockPlatformToolPackage t2 = new MockPlatformToolPackage(2); - - MockToolPackage p2 = new MockToolPackage(2, 2); - - ArrayList out = new ArrayList(); - ArrayList selected = new ArrayList(); - ArrayList remote = new ArrayList(); - - // p2 depends on t2, which is not locally installed - Package[] localPkgs = { t1 }; - ArchiveInfo[] locals = mul.createLocalArchives(localPkgs); - - SdkSource[] sources = null; - - // p2 now depends on a "fake" archive info with no newArchive that wraps the missing - // underlying tool - ArchiveInfo fai = mul.findPlatformToolsDependency( - p2, out, selected, remote, sources, locals); - assertNotNull(fai); - assertNull(fai.getNewArchive()); - assertTrue(fai.isRejected()); - assertEquals(0, out.size()); - - // t2 is now selected and can be used as a dependency - Archive t2_archive = t2.getArchives()[0]; - selected.add(t2_archive); - ArchiveInfo ai2 = mul.findPlatformToolsDependency( - p2, out, selected, remote, sources, locals); - assertNotNull(ai2); - assertSame(t2_archive, ai2.getNewArchive()); - assertEquals(1, out.size()); - assertSame(t2_archive, out.get(0).getNewArchive()); - } - - public void testComputeRevisionUpdate() { - // Scenario: - // - user has tools rev 7 installed + plat-tools rev 1 installed - // - server has tools rev 8, depending on plat-tools rev 2 - // - server has tools rev 9, depending on plat-tools rev 3 - // - server has platform 9 that requires min-tools-rev 9 - // - // If we do an update all, we want to the installer to pick up: - // - the new platform 9 - // - the tools rev 9 (required by platform 9) - // - the plat-tools rev 3 (required by tools rev 9) - - final MockPlatformToolPackage pt1 = new MockPlatformToolPackage(1); - final MockPlatformToolPackage pt2 = new MockPlatformToolPackage(2); - final MockPlatformToolPackage pt3 = new MockPlatformToolPackage(3); - - final MockToolPackage t7 = new MockToolPackage(7, 1 /*min-plat-tools*/); - final MockToolPackage t8 = new MockToolPackage(8, 2 /*min-plat-tools*/); - final MockToolPackage t9 = new MockToolPackage(9, 3 /*min-plat-tools*/); - - final MockPlatformPackage p9 = new MockPlatformPackage(9, 1, 9 /*min-tools*/); - - // Note: the mock updater logic gets the remotes packages from the array given - // here and bypasses the source (to avoid fetching any actual URLs) - MockUpdaterLogic mul = new MockUpdaterLogic(new NullUpdaterData(), - new Package[] { t8, pt2, t9, pt3, p9 }); - - SdkSources sources = new SdkSources(); - Package[] localPkgs = { t7, pt1 }; - - List selected = mul.computeUpdates( - null /*selectedArchives*/, - sources, - localPkgs, - false /*includeObsoletes*/); - - assertEquals( - "[Android SDK Platform-tools, revision 3, " + - "Android SDK Tools, revision 9]", - Arrays.toString(selected.toArray())); - - mul.addNewPlatforms( - selected, - sources, - localPkgs, - false /*includeObsoletes*/); - - assertEquals( - "[Android SDK Platform-tools, revision 3, " + - "Android SDK Tools, revision 9, " + - "SDK Platform Android android-9, API 9, revision 1]", - Arrays.toString(selected.toArray())); - - // Now try again but reverse the order of the remote package list. - - mul = new MockUpdaterLogic(new NullUpdaterData(), - new Package[] { p9, t9, pt3, t8, pt2 }); - - selected = mul.computeUpdates( - null /*selectedArchives*/, - sources, - localPkgs, - false /*includeObsoletes*/); - - assertEquals( - "[Android SDK Platform-tools, revision 3, " + - "Android SDK Tools, revision 9]", - Arrays.toString(selected.toArray())); - - mul.addNewPlatforms( - selected, - sources, - localPkgs, - false /*includeObsoletes*/); - - assertEquals( - "[Android SDK Platform-tools, revision 3, " + - "Android SDK Tools, revision 9, " + - "SDK Platform Android android-9, API 9, revision 1]", - Arrays.toString(selected.toArray())); - } -} -- cgit v1.1