diff options
-rw-r--r-- | sdkmanager/app/tests/com/android/sdkmanager/AvdManagerTest.java | 1 | ||||
-rw-r--r-- | sdkmanager/app/tests/com/android/sdkmanager/MainTest.java | 1 | ||||
-rwxr-xr-x | sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/Archive.java | 6 | ||||
-rwxr-xr-x | sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/Package.java | 13 | ||||
-rwxr-xr-x | sdkmanager/libs/sdklib/tests/com/android/sdklib/internal/repository/MockEmptySdkManager.java | 2 | ||||
-rw-r--r-- | sdkmanager/libs/sdklib/tests/com/android/sdklib/mock/MockLog.java (renamed from sdkmanager/app/tests/com/android/sdkmanager/MockLog.java) | 7 | ||||
-rw-r--r-- | sdkmanager/libs/sdkuilib/.classpath | 23 | ||||
-rw-r--r-- | sdkmanager/libs/sdkuilib/.project | 34 | ||||
-rw-r--r-- | sdkmanager/libs/sdkuilib/src/Android.mk | 1 | ||||
-rwxr-xr-x | sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterData.java | 32 | ||||
-rwxr-xr-x | sdkmanager/libs/sdkuilib/tests/com/android/sdkuilib/internal/repository/UpdaterDataTest.java | 256 |
11 files changed, 337 insertions, 39 deletions
diff --git a/sdkmanager/app/tests/com/android/sdkmanager/AvdManagerTest.java b/sdkmanager/app/tests/com/android/sdkmanager/AvdManagerTest.java index bb1ba75..4ae107c 100644 --- a/sdkmanager/app/tests/com/android/sdkmanager/AvdManagerTest.java +++ b/sdkmanager/app/tests/com/android/sdkmanager/AvdManagerTest.java @@ -23,6 +23,7 @@ import com.android.sdklib.SdkManager; import com.android.sdklib.internal.avd.AvdManager; import com.android.sdklib.internal.project.ProjectProperties; import com.android.sdklib.io.FileWrapper; +import com.android.sdklib.mock.MockLog; import java.io.File; import java.util.Map; diff --git a/sdkmanager/app/tests/com/android/sdkmanager/MainTest.java b/sdkmanager/app/tests/com/android/sdkmanager/MainTest.java index f6e3bbe..29516e3 100644 --- a/sdkmanager/app/tests/com/android/sdkmanager/MainTest.java +++ b/sdkmanager/app/tests/com/android/sdkmanager/MainTest.java @@ -22,6 +22,7 @@ import static java.io.File.createTempFile; import com.android.sdklib.IAndroidTarget; import com.android.sdklib.SdkManager; import com.android.sdklib.internal.avd.AvdManager; +import com.android.sdklib.mock.MockLog; import java.io.File; diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/Archive.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/Archive.java index ce3372c..96d5cf5 100755 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/Archive.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/Archive.java @@ -16,6 +16,9 @@ package com.android.sdklib.internal.repository;
+import com.android.annotations.VisibleForTesting;
+import com.android.annotations.VisibleForTesting.Visibility;
+
import java.io.File;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
@@ -200,7 +203,8 @@ public class Archive implements IDescription, Comparable<Archive> { * Creates a new local archive.
* Uses the properties from props first, if possible. Props can be null.
*/
- Archive(Package pkg, Properties props, Os os, Arch arch, String localOsPath) {
+ @VisibleForTesting(visibility=Visibility.PACKAGE)
+ protected Archive(Package pkg, Properties props, Os os, Arch arch, String localOsPath) {
mPackage = pkg;
mOs = props == null ? os : Os.valueOf( props.getProperty(PROP_OS, os.toString()));
diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/Package.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/Package.java index 3e9f9d6..58be3c9 100755 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/Package.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/Package.java @@ -16,6 +16,8 @@ package com.android.sdklib.internal.repository;
+import com.android.annotations.VisibleForTesting;
+import com.android.annotations.VisibleForTesting.Visibility;
import com.android.sdklib.AndroidVersion;
import com.android.sdklib.SdkManager;
import com.android.sdklib.internal.repository.Archive.Arch;
@@ -150,7 +152,16 @@ public abstract class Package implements IDescription, Comparable<Package> { mSource = source;
mArchives = new Archive[1];
- mArchives[0] = new Archive(this,
+ mArchives[0] = createLocalArchive(props, archiveOs, archiveArch, archiveOsPath);
+ }
+
+ @VisibleForTesting(visibility=Visibility.PRIVATE)
+ protected Archive createLocalArchive(
+ Properties props,
+ Os archiveOs,
+ Arch archiveArch,
+ String archiveOsPath) {
+ return new Archive(this,
props,
archiveOs,
archiveArch,
diff --git a/sdkmanager/libs/sdklib/tests/com/android/sdklib/internal/repository/MockEmptySdkManager.java b/sdkmanager/libs/sdklib/tests/com/android/sdklib/internal/repository/MockEmptySdkManager.java index 455841a..f66734b 100755 --- a/sdkmanager/libs/sdklib/tests/com/android/sdklib/internal/repository/MockEmptySdkManager.java +++ b/sdkmanager/libs/sdklib/tests/com/android/sdklib/internal/repository/MockEmptySdkManager.java @@ -22,7 +22,7 @@ import com.android.sdklib.SdkManager; /**
* An invalid SDK Manager, just good enough to avoid passing a null reference.
*/
-class MockEmptySdkManager extends SdkManager {
+public class MockEmptySdkManager extends SdkManager {
public MockEmptySdkManager(String osSdkPath) {
super(osSdkPath);
setTargets(new IAndroidTarget[0]);
diff --git a/sdkmanager/app/tests/com/android/sdkmanager/MockLog.java b/sdkmanager/libs/sdklib/tests/com/android/sdklib/mock/MockLog.java index 7925709..3ef0140 100644 --- a/sdkmanager/app/tests/com/android/sdkmanager/MockLog.java +++ b/sdkmanager/libs/sdklib/tests/com/android/sdklib/mock/MockLog.java @@ -14,13 +14,18 @@ * limitations under the License. */ -package com.android.sdkmanager; +package com.android.sdklib.mock; import com.android.sdklib.ISdkLog; import java.util.ArrayList; import java.util.Formatter; +/** + * An instance of {@link ISdkLog} that captures all messages to an internal list. + * Messages can be retrieved later using {@link #toString()}. + * Useful for unit-tests. + */ public class MockLog implements ISdkLog { private ArrayList<String> mMessages = new ArrayList<String>(); diff --git a/sdkmanager/libs/sdkuilib/.classpath b/sdkmanager/libs/sdkuilib/.classpath index 73592c4..b62b292 100644 --- a/sdkmanager/libs/sdkuilib/.classpath +++ b/sdkmanager/libs/sdkuilib/.classpath @@ -1,11 +1,12 @@ -<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
- <classpathentry kind="src" path="src"/>
- <classpathentry kind="src" path="tests"/>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
- <classpathentry exported="true" kind="con" path="org.eclipse.jdt.USER_LIBRARY/ANDROID_SWT"/>
- <classpathentry combineaccessrules="false" kind="src" path="/SdkLib"/>
- <classpathentry combineaccessrules="false" kind="src" path="/AndroidPrefs"/>
- <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/>
- <classpathentry kind="output" path="bin"/>
-</classpath>
+<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="src"/> + <classpathentry kind="src" path="tests"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> + <classpathentry exported="true" kind="con" path="org.eclipse.jdt.USER_LIBRARY/ANDROID_SWT"/> + <classpathentry combineaccessrules="false" kind="src" path="/SdkLib"/> + <classpathentry combineaccessrules="false" kind="src" path="/AndroidPrefs"/> + <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/> + <classpathentry combineaccessrules="false" kind="src" path="/common"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/sdkmanager/libs/sdkuilib/.project b/sdkmanager/libs/sdkuilib/.project index da430c8..0fc6a73 100644 --- a/sdkmanager/libs/sdkuilib/.project +++ b/sdkmanager/libs/sdkuilib/.project @@ -1,17 +1,17 @@ -<?xml version="1.0" encoding="UTF-8"?> -<projectDescription> - <name>SdkUiLib</name> - <comment></comment> - <projects> - </projects> - <buildSpec> - <buildCommand> - <name>org.eclipse.jdt.core.javabuilder</name> - <arguments> - </arguments> - </buildCommand> - </buildSpec> - <natures> - <nature>org.eclipse.jdt.core.javanature</nature> - </natures> -</projectDescription> +<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>SdkUiLib</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/sdkmanager/libs/sdkuilib/src/Android.mk b/sdkmanager/libs/sdkuilib/src/Android.mk index 970c122..9aceba1 100644 --- a/sdkmanager/libs/sdkuilib/src/Android.mk +++ b/sdkmanager/libs/sdkuilib/src/Android.mk @@ -8,6 +8,7 @@ LOCAL_JAVA_RESOURCE_DIRS := . LOCAL_JAVA_LIBRARIES := \ sdklib \ + common \ androidprefs \ swt \ org.eclipse.jface_3.4.2.M20090107-0800 \ diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterData.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterData.java index 82e7adb..85fa0d6 100755 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterData.java +++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterData.java @@ -16,6 +16,8 @@ package com.android.sdkuilib.internal.repository;
+import com.android.annotations.VisibleForTesting;
+import com.android.annotations.VisibleForTesting.Visibility;
import com.android.prefs.AndroidLocation.AndroidLocationException;
import com.android.sdklib.ISdkLog;
import com.android.sdklib.SdkConstants;
@@ -226,8 +228,9 @@ class UpdaterData implements IUpdaterData { /**
* Initializes the {@link SdkManager} and the {@link AvdManager}.
*/
- private void initSdk() {
- mSdkManager = SdkManager.createManager(mOsSdkRoot, mSdkLog);
+ @VisibleForTesting(visibility=Visibility.PRIVATE)
+ protected void initSdk() {
+ setSdkManager(SdkManager.createManager(mOsSdkRoot, mSdkLog));
try {
mAvdManager = null; // remove the old one if needed.
mAvdManager = new AvdManager(mSdkManager, mSdkLog);
@@ -247,6 +250,11 @@ class UpdaterData implements IUpdaterData { broadcastOnSdkReload();
}
+ @VisibleForTesting(visibility=Visibility.PRIVATE)
+ protected void setSdkManager(SdkManager sdkManager) {
+ mSdkManager = sdkManager;
+ }
+
/**
* Reloads the SDK content (targets).
* <p/>
@@ -372,9 +380,10 @@ class UpdaterData implements IUpdaterData { * Install the list of given {@link Archive}s. This is invoked by the user selecting some
* packages in the remote page and then clicking "install selected".
*
- * @param result The archives to install. Incompatible ones will be skipped.
+ * @param archives The archives to install. Incompatible ones will be skipped.
*/
- public void installArchives(final Collection<ArchiveInfo> result) {
+ @VisibleForTesting(visibility=Visibility.PRIVATE)
+ protected void installArchives(final Collection<ArchiveInfo> archives) {
if (mTaskFactory == null) {
throw new IllegalArgumentException("Task Factory is null");
}
@@ -385,7 +394,7 @@ class UpdaterData implements IUpdaterData { public void run(ITaskMonitor monitor) {
final int progressPerArchive = 2 * ArchiveInstaller.NUM_MONITOR_INC;
- monitor.setProgressMax(result.size() * progressPerArchive);
+ monitor.setProgressMax(archives.size() * progressPerArchive);
monitor.setDescription("Preparing to install archives");
boolean installedAddon = false;
@@ -402,7 +411,7 @@ class UpdaterData implements IUpdaterData { }
int numInstalled = 0;
- nextArchive: for (ArchiveInfo ai : result) {
+ nextArchive: for (ArchiveInfo ai : archives) {
Archive archive = ai.getNewArchive();
if (archive == null) {
// This is not supposed to happen.
@@ -443,7 +452,7 @@ class UpdaterData implements IUpdaterData { broadcastPreInstallHook();
}
- ArchiveInstaller installer = new ArchiveInstaller();
+ ArchiveInstaller installer = createArchiveInstaler();
if (installer.install(archive,
mOsSdkRoot,
forceHttp,
@@ -978,4 +987,13 @@ class UpdaterData implements IUpdaterData { }
}
+ /**
+ * Internal helper to return a new {@link ArchiveInstaller}.
+ * This allows us to override the installer for unit-testing.
+ */
+ @VisibleForTesting(visibility=Visibility.PRIVATE)
+ protected ArchiveInstaller createArchiveInstaler() {
+ return new ArchiveInstaller();
+ }
+
}
diff --git a/sdkmanager/libs/sdkuilib/tests/com/android/sdkuilib/internal/repository/UpdaterDataTest.java b/sdkmanager/libs/sdkuilib/tests/com/android/sdkuilib/internal/repository/UpdaterDataTest.java new file mode 100755 index 0000000..cf0f912 --- /dev/null +++ b/sdkmanager/libs/sdkuilib/tests/com/android/sdkuilib/internal/repository/UpdaterDataTest.java @@ -0,0 +1,256 @@ +/* + * Copyright (C) 2011 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.repository.Archive; +import com.android.sdklib.internal.repository.ArchiveInstaller; +import com.android.sdklib.internal.repository.ITask; +import com.android.sdklib.internal.repository.ITaskFactory; +import com.android.sdklib.internal.repository.ITaskMonitor; +import com.android.sdklib.internal.repository.MockEmptySdkManager; +import com.android.sdklib.internal.repository.Package; +import com.android.sdklib.internal.repository.SdkSource; +import com.android.sdklib.internal.repository.Archive.Arch; +import com.android.sdklib.internal.repository.Archive.Os; +import com.android.sdklib.mock.MockLog; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Properties; + +import junit.framework.TestCase; + +public class UpdaterDataTest extends TestCase { + + private MockUpdaterData m; + + @Override + protected void setUp() throws Exception { + super.setUp(); + m = new MockUpdaterData(); + assertEquals("[]", Arrays.toString(m.getInstalled())); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + } + + /** + * Tests the case where we have nothing to install. + */ + public void testInstallArchives_None() { + m._installArchives(new ArrayList<ArchiveInfo>()); + assertEquals("[]", Arrays.toString(m.getInstalled())); + } + + + /** + * Tests the case where there's a simple dependency, in the right order + * (e.g. install A1 then A2 that depends on A1). + */ + public void testInstallArchives_SimpleDependency() { + + ArrayList<ArchiveInfo> archives = new ArrayList<ArchiveInfo>(); + + Archive a1 = new MockEmptyPackage("a1").getLocalArchive(); + ArchiveInfo ai1 = new ArchiveInfo(a1, null, null); + + Archive a2 = new MockEmptyPackage("a2").getLocalArchive(); + ArchiveInfo ai2 = new ArchiveInfo(a2, null, new ArchiveInfo[] { ai1 } ); + + archives.add(ai1); + archives.add(ai2); + + m._installArchives(archives); + assertEquals("[a1, a2]", Arrays.toString(m.getInstalled())); + } + + /** + * Tests the case where there's a simple dependency, in the wrong order + * (e.g. install A2 then A1 which A2 depends on) + */ + public void testInstallArchives_ReverseDependency() { + + ArrayList<ArchiveInfo> archives = new ArrayList<ArchiveInfo>(); + + Archive a1 = new MockEmptyPackage("a1").getLocalArchive(); + ArchiveInfo ai1 = new ArchiveInfo(a1, null, null); + + Archive a2 = new MockEmptyPackage("a2").getLocalArchive(); + ArchiveInfo ai2 = new ArchiveInfo(a2, null, new ArchiveInfo[] { ai1 } ); + + archives.add(ai2); + archives.add(ai1); + + m._installArchives(archives); + // TODO fix bug 14393: a2 is not installed because a1 has not been installed yet. + assertEquals("[a1]", Arrays.toString(m.getInstalled())); + } + + // --- + + + /** A mock UpdaterData that simply records what would have been installed. */ + private static class MockUpdaterData extends UpdaterData { + + private final List<Archive> mInstalled = new ArrayList<Archive>(); + + public MockUpdaterData() { + super("/tmp/SDK", new MockLog()); + + setTaskFactory(new MockTaskFactory()); + } + + /** Gives access to the internal {@link #installArchives(Collection)}. */ + public void _installArchives(Collection<ArchiveInfo> result) { + installArchives(result); + } + + public Archive[] getInstalled() { + return mInstalled.toArray(new Archive[mInstalled.size()]); + } + + @Override + protected void initSdk() { + setSdkManager(new MockEmptySdkManager("/tmp/SDK")); + } + + @Override + public void reloadSdk() { + // bypass original implementation + } + + /** Returns a mock installer that simply records what would have been installed. */ + @Override + protected ArchiveInstaller createArchiveInstaler() { + return new ArchiveInstaller() { + @Override + public boolean install( + Archive archive, + String osSdkRoot, + boolean forceHttp, + SdkManager sdkManager, + ITaskMonitor monitor) { + mInstalled.add(archive); + return true; + } + }; + } + } + + private static class MockTaskFactory implements ITaskFactory { + public void start(String title, ITask task) { + new MockTask(task); + } + } + + private static class MockTask implements ITaskMonitor { + public MockTask(ITask task) { + task.run(this); + } + + public ITaskMonitor createSubMonitor(int tickCount) { + return this; + } + + public boolean displayPrompt(String title, String message) { + return false; + } + + public int getProgress() { + return 0; + } + + public void incProgress(int delta) { + // ignore + } + + public boolean isCancelRequested() { + return false; + } + + public void setDescription(String descriptionFormat, Object... args) { + // ignore + } + + public void setProgressMax(int max) { + // ignore + } + + public void setResult(String resultFormat, Object... args) { + // ignore + } + } + + private static class MockEmptyPackage extends Package { + private final String mTestHandle; + + public MockEmptyPackage(String testHandle) { + super( + null /*source*/, + null /*props*/, + 0 /*revision*/, + null /*license*/, + null /*description*/, + null /*descUrl*/, + Os.ANY /*archiveOs*/, + Arch.ANY /*archiveArch*/, + null /*archiveOsPath*/ + ); + mTestHandle = testHandle; + } + + @Override + protected Archive createLocalArchive( + Properties props, + Os archiveOs, + Arch archiveArch, + String archiveOsPath) { + return new Archive(this, props, archiveOs, archiveArch, archiveOsPath) { + @Override + public String toString() { + return mTestHandle; + } + }; + } + + public Archive getLocalArchive() { + return getArchives()[0]; + } + + @Override + public File getInstallFolder(String osSdkRoot, SdkManager sdkManager) { + return null; + } + + @Override + public String getShortDescription() { + return this.getClass().getSimpleName(); + } + + @Override + public boolean sameItemAs(Package pkg) { + return false; + } + + } +} |