blob: 8651894a57f887e9b33dc61709f3c61602f53f3c [file] [log] [blame]
/*
* Copyright (C) 2010 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.sdkmanager;
import com.android.SdkConstants;
import com.android.sdklib.IAndroidTarget;
import com.android.sdklib.SdkManager;
import com.android.sdklib.SdkManagerTestCase;
import com.android.sdklib.internal.avd.AvdInfo;
import com.android.sdklib.internal.repository.CanceledByUserException;
import com.android.sdklib.internal.repository.DownloadCache;
import com.android.sdklib.internal.repository.DownloadCache.Strategy;
import com.android.sdklib.internal.repository.NullTaskMonitor;
import com.android.sdklib.repository.SdkAddonConstants;
import com.android.sdklib.repository.SdkRepoConstants;
import com.android.utils.Pair;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Set;
import java.util.TreeSet;
import junit.framework.AssertionFailedError;
public class MainTest extends SdkManagerTestCase {
private IAndroidTarget mTarget;
private File mAvdFolder;
@Override
public void setUp() throws Exception {
super.setUp();
mTarget = getSdkManager().getTargets()[0];
mAvdFolder = AvdInfo.getDefaultAvdFolder(getAvdManager(), getName());
}
@Override
public void tearDown() throws Exception {
super.tearDown();
}
public void testDisplayEmptyAvdList() {
Main main = new Main();
main.setLogger(getLog());
getLog().clear();
main.displayAvdList(getAvdManager());
assertEquals("[P Available Android Virtual Devices:\n]", getLog().toString());
}
public void testDisplayAvdListOfOneNonSnapshot() {
Main main = new Main();
main.setLogger(getLog());
getAvdManager().createAvd(
mAvdFolder,
this.getName(),
mTarget,
SdkConstants.ABI_ARMEABI,
null, // skinName
null, // sdName
null, // properties
false, // createSnapshot
false, // removePrevious
false, // editExisting
getLog());
getLog().clear();
main.displayAvdList(getAvdManager());
assertEquals(
"[P Available Android Virtual Devices:\n"
+ ", P Name: " + this.getName() + "\n"
+ ", P Path: " + mAvdFolder + "\n"
+ ", P Target: Android 0.0 (API level 0)\n"
+ ", P ABI: armeabi\n"
+ ", P Skin: HVGA\n"
+ "]",
getLog().toString());
}
public void testDisplayAvdListOfOneSnapshot() {
Main main = new Main();
main.setLogger(getLog());
getAvdManager().createAvd(
mAvdFolder,
this.getName(),
mTarget,
SdkConstants.ABI_ARMEABI,
null, // skinName
null, // sdName
null, // properties
true, // createSnapshot
false, // removePrevious
false, // editExisting
getLog());
getLog().clear();
main.displayAvdList(getAvdManager());
assertEquals(
"[P Available Android Virtual Devices:\n"
+ ", P Name: " + this.getName() + "\n"
+ ", P Path: " + mAvdFolder + "\n"
+ ", P Target: Android 0.0 (API level 0)\n"
+ ", P ABI: armeabi\n"
+ ", P Skin: HVGA\n"
+ ", P Snapshot: true\n"
+ "]",
getLog().toString());
}
public void testDisplayTargetList() {
Main main = new Main();
main.setLogger(getLog());
main.setSdkManager(getSdkManager());
getLog().clear();
main.displayTargetList();
assertEquals(
"[P Available Android targets:\n" +
", P ----------\n" +
", P id: 1 or \"android-0\"\n" +
", P Name: Android 0.0\n" +
", P Type: Platform\n" +
", P API level: 0\n" +
", P Revision: 1\n" +
", P Skins: , P \n" +
", P ABIs : , P armeabi, P \n" +
"]",
getLog().toString());
}
public void testDisplayAbiList() {
Main main = new Main();
main.setLogger(getLog());
main.setSdkManager(getSdkManager());
getLog().clear();
main.displayAbiList(mTarget, "message");
assertEquals(
"[P message, P armeabi, P \n" +
"]",
getLog().toString());
}
public void testDisplaySkinList() {
Main main = new Main();
main.setLogger(getLog());
main.setSdkManager(getSdkManager());
getLog().clear();
main.displaySkinList(mTarget, "message");
assertEquals(
"[P message, P \n" +
"]",
getLog().toString());
}
public void testSdkManagerHasChanged() throws IOException {
try {
Main main = new Main();
main.setLogger(getLog());
SdkManager sdkman = getSdkManager();
main.setSdkManager(sdkman);
getLog().clear();
assertFalse(sdkman.hasChanged(getLog()));
getLog().clear();
File addonsDir = new File(sdkman.getLocation(), SdkConstants.FD_ADDONS);
assertTrue(addonsDir.isDirectory());
FileWriter readme = new FileWriter(new File(addonsDir, "android.txt"));
readme.write("test\n");
readme.close();
// Adding a file doesn't alter sdk.hasChanged
assertFalse(sdkman.hasChanged(getLog()));
getLog().clear();
sdkman.reloadSdk(getLog());
assertFalse(sdkman.hasChanged(getLog()));
getLog().clear();
File fakeAddon = new File(addonsDir, "google-addon");
fakeAddon.mkdirs();
File sourceProps = new File(fakeAddon, SdkConstants.FN_SOURCE_PROP);
FileWriter propsWriter = new FileWriter(sourceProps);
propsWriter.write("revision=7\n");
propsWriter.close();
// Adding a directory does alter sdk.hasChanged even if not a real add-on
assertTrue(sdkman.hasChanged(getLog()));
getLog().clear();
// Once reloaded, sdk.hasChanged will be reset
sdkman.reloadSdk(getLog());
assertFalse(sdkman.hasChanged(getLog()));
getLog().clear();
// Changing the source.properties file alters sdk.hasChanged
propsWriter = new FileWriter(sourceProps);
propsWriter.write("revision=8\n");
propsWriter.close();
assertTrue(sdkman.hasChanged(getLog()));
getLog().clear();
// Once reloaded, sdk.hasChanged will be reset
sdkman.reloadSdk(getLog());
assertFalse(sdkman.hasChanged(getLog()));
getLog().clear();
} catch (AssertionFailedError e) {
String s = e.getMessage();
if (s != null) {
s += "\n";
} else {
s = "";
}
s += "Log:" + getLog().toString();
AssertionFailedError e2 = new AssertionFailedError(s);
e2.initCause(e);
throw e2;
}
}
public void testCheckFilterValues() {
// These are the values we expect checkFilterValues() to match.
String[] expectedValues = {
"platform",
"system-image",
"tool",
"platform-tool",
"doc",
"sample",
"add-on",
"extra",
"source"
};
Set<String> expectedSet = new TreeSet<String>(Arrays.asList(expectedValues));
// First check the values are actually defined in the proper arrays
// in the Sdk*Constants.NODES
for (String node : SdkRepoConstants.NODES) {
assertTrue(
String.format(
"Error: value '%1$s' from SdkRepoConstants.NODES should be used in unit-test",
node),
expectedSet.contains(node));
}
for (String node : SdkAddonConstants.NODES) {
assertTrue(
String.format(
"Error: value '%1$s' from SdkAddonConstants.NODES should be used in unit-test",
node),
expectedSet.contains(node));
}
// Now check none of these values are NOT present in the NODES arrays
for (String node : SdkRepoConstants.NODES) {
expectedSet.remove(node);
}
for (String node : SdkAddonConstants.NODES) {
expectedSet.remove(node);
}
assertTrue(
String.format(
"Error: values %1$s are missing from Sdk[Repo|Addons]Constants.NODES",
Arrays.toString(expectedSet.toArray())),
expectedSet.isEmpty());
// We're done with expectedSet now
expectedSet = null;
// Finally check that checkFilterValues accepts all these values, one by one.
Main main = new Main();
main.setLogger(getLog());
for (int step = 0; step < 3; step++) {
for (String value : expectedValues) {
switch(step) {
// step 0: use value as-is
case 1:
// add some whitespace before and after
value = " " + value + " ";
break;
case 2:
// same with some empty arguments that should get ignored
value = " ," + value + " , ";
break;
}
Pair<String, ArrayList<String>> result = main.checkFilterValues(value);
assertNull(
String.format("Expected error to be null for value '%1$s', got: %2$s",
value, result.getFirst()),
result.getFirst());
assertEquals(
String.format("[%1$s]", value.replace(',', ' ').trim()),
Arrays.toString(result.getSecond().toArray()));
}
}
}
public void testLocalFileDownload() throws IOException, CanceledByUserException {
Main main = new Main();
main.setLogger(getLog());
SdkManager sdkman = getSdkManager();
main.setSdkManager(sdkman);
getLog().clear();
IAndroidTarget target = sdkman.getTargets()[0];
File sourceProps = new File(target.getLocation(), SdkConstants.FN_SOURCE_PROP);
assertTrue(sourceProps.isFile());
String urlStr = getFileUrl(sourceProps);
assertTrue(urlStr.startsWith("file:///"));
DownloadCache cache = new DownloadCache(Strategy.DIRECT);
NullTaskMonitor monitor = new NullTaskMonitor(getLog());
Pair<InputStream, Integer> result = cache.openDirectUrl(urlStr, monitor);
assertNotNull(result);
assertEquals(200, result.getSecond().intValue());
int len = (int) sourceProps.length();
byte[] buf = new byte[len];
FileInputStream is = new FileInputStream(sourceProps);
is.read(buf);
is.close();
String expected = new String(buf, "UTF-8");
buf = new byte[len];
result.getFirst().read(buf);
result.getFirst().close();
String actual = new String(buf, "UTF-8");
assertEquals(expected, actual);
}
private String getFileUrl(File file) throws IOException {
// Note: to create a file:// URL, one would typically use something like
// f.toURI().toURL().toString(). However this generates a broken path on
// Windows, namely "C:\\foo" is converted to "file:/C:/foo" instead of
// "file:///C:/foo" (i.e. there should be 3 / after "file:"). So we'll
// do the correct thing manually.
String path = file.getCanonicalPath();
if (File.separatorChar != '/') {
path = path.replace(File.separatorChar, '/');
}
// A file:// should start with 3 // (2 for file:// and 1 to make it an absolute
// path. On Windows that should look like file:///C:/. Linux/Mac will already
// have that leading / in their path so we need to compensate for windows.
if (!path.startsWith("/")) {
path = "/" + path;
}
// For some reason the URL class doesn't add the mandatory "//" after
// the "file:" protocol name, so it has to be hacked into the path.
URL url = new URL("file", null, "//" + path); //$NON-NLS-1$ //$NON-NLS-2$
String result = url.toString();
return result;
}
}