blob: ab45785e7a7202c0a8d09c0c2031f481d20c9a80 [file] [log] [blame]
/*
* 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.
*/
/*
Note: this file is duplicated from tools/base/sdklib/src/tests.
The version of sdkmanager-tests in sdk.git does no longer have
access to sdklib-tests.
FIXME: if this generic enough, move it to test-utils.
*/
package com.android.sdklib;
import com.android.SdkConstants;
import com.android.prefs.AndroidLocation;
import com.android.prefs.AndroidLocation.AndroidLocationException;
import com.android.sdklib.internal.avd.AvdManager;
import com.android.sdklib.io.FileOp;
import com.android.sdklib.mock.MockLog;
import com.android.sdklib.repository.PkgProps;
import com.android.utils.ILogger;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import junit.framework.TestCase;
/**
* Test case that allocates a temporary SDK, a temporary AVD base folder
* with an SdkManager and an AvdManager that points to them.
*/
public class SdkManagerTestCase extends TestCase {
private File mFakeSdk;
private MockLog mLog;
private SdkManager mSdkManager;
private TmpAvdManager mAvdManager;
/** Returns the {@link MockLog} for this test case. */
public MockLog getLog() {
return mLog;
}
/** Returns the {@link SdkManager} for this test case. */
public SdkManager getSdkManager() {
return mSdkManager;
}
/** Returns the {@link AvdManager} for this test case. */
public TmpAvdManager getAvdManager() {
return mAvdManager;
}
/**
* Sets up a {@link MockLog}, a fake SDK in a temporary directory
* and an AVD Manager pointing to an initially-empty AVD directory.
*/
@Override
public void setUp() throws Exception {
mLog = new MockLog();
mFakeSdk = makeFakeSdk();
mSdkManager = SdkManager.createManager(mFakeSdk.getAbsolutePath(), mLog);
assertNotNull("SdkManager location was invalid", mSdkManager);
mAvdManager = new TmpAvdManager(mSdkManager, mLog);
}
/**
* Removes the temporary SDK and AVD directories.
*/
@Override
public void tearDown() throws Exception {
deleteDir(mFakeSdk);
}
/**
* A empty test method to placate the JUnit test runner, which doesn't
* like TestCase classes with no test methods.
*/
public void testPlaceholder() {
}
/**
* An {@link AvdManager} that uses a temporary directory
* located <em>inside</em> the SDK directory for testing.
* The AVD list should be initially empty.
*/
protected static class TmpAvdManager extends AvdManager {
/*
* Implementation detail:
* - When the super.AvdManager constructor is invoked, it will invoke
* the buildAvdFilesList() to fill the initial AVD list, which will in
* turn call getBaseAvdFolder().
* - That's why mTmpAvdRoot is initialized in getAvdRoot() rather than
* in the constructor, since we can't initialize fields before the super()
* call.
*/
/**
* AVD Root, initialized "lazily" when the AVD root is first requested.
*/
private File mTmpAvdRoot;
public TmpAvdManager(SdkManager sdkManager, ILogger log) throws AndroidLocationException {
super(sdkManager, log);
}
@Override
public String getBaseAvdFolder() throws AndroidLocationException {
if (mTmpAvdRoot == null) {
mTmpAvdRoot = new File(getSdkManager().getLocation(), "tmp_avds");
mTmpAvdRoot.mkdirs();
}
return mTmpAvdRoot.getAbsolutePath();
}
}
/**
* Build enough of a skeleton SDK to make the tests pass.
* <p/>
* Ideally this wouldn't touch the file system but the current
* structure of the SdkManager and AvdManager makes this difficult.
*
* @return Path to the temporary SDK root
* @throws IOException
*/
private File makeFakeSdk() throws IOException {
// First we create a temp file to "reserve" the temp directory name we want to use.
File sdkDir = File.createTempFile(
this.getClass().getSimpleName() + '_' + this.getName(), null);
// Then erase the file and make the directory
sdkDir.delete();
sdkDir.mkdirs();
AndroidLocation.resetFolder();
File addonsDir = new File(sdkDir, SdkConstants.FD_ADDONS);
addonsDir.mkdir();
File toolsDir = new File(sdkDir, SdkConstants.OS_SDK_TOOLS_FOLDER);
toolsDir.mkdir();
new File(toolsDir, SdkConstants.androidCmdName()).createNewFile();
new File(toolsDir, SdkConstants.FN_EMULATOR).createNewFile();
// TODO makePlatformTools with at least a source props
File toolsLibEmuDir = new File(sdkDir, SdkConstants.OS_SDK_TOOLS_LIB_FOLDER + "emulator");
toolsLibEmuDir.mkdirs();
new File(toolsLibEmuDir, "snapshots.img").createNewFile();
File platformsDir = new File(sdkDir, SdkConstants.FD_PLATFORMS);
// Creating a fake target here on down
File targetDir = makeFakeTargetInternal(platformsDir);
File imagesDir = new File(targetDir, "images");
makeFakeSysImgInternal(imagesDir, SdkConstants.ABI_ARMEABI);
makeFakeSkinInternal(targetDir);
makeFakeSourceInternal(sdkDir);
return sdkDir;
}
/**
* Creates the system image folder and places a fake userdata.img in it.
*
* @param systemImage A system image with a valid location.
* @throws IOException if the file fails to be created.
*/
protected void makeSystemImageFolder(ISystemImage systemImage) throws IOException {
File imagesDir = systemImage.getLocation();
imagesDir.mkdirs();
makeFakeSysImgInternal(imagesDir, systemImage.getAbiType());
}
//----
/** Utility used by {@link #makeFakeSdk()} to create a fake target with API 0, rev 0. */
private File makeFakeTargetInternal(File platformsDir) throws IOException {
File targetDir = new File(platformsDir, "v0_0");
targetDir.mkdirs();
new File(targetDir, SdkConstants.FN_FRAMEWORK_LIBRARY).createNewFile();
new File(targetDir, SdkConstants.FN_FRAMEWORK_AIDL).createNewFile();
File sourceProp = new File(targetDir, SdkConstants.FN_SOURCE_PROP);
sourceProp.createNewFile();
FileWriter out = new FileWriter(sourceProp);
out.write(PkgProps.LAYOUTLIB_API + "=5\n");
out.write(PkgProps.LAYOUTLIB_REV + "=2\n");
out.close();
File buildProp = new File(targetDir, SdkConstants.FN_BUILD_PROP);
out = new FileWriter(buildProp);
out.write(SdkManager.PROP_VERSION_RELEASE + "=0.0\n");
out.write(SdkManager.PROP_VERSION_SDK + "=0\n");
out.write(SdkManager.PROP_VERSION_CODENAME + "=REL\n");
out.close();
return targetDir;
}
/** Utility to create a fake sys image in the given folder. */
private void makeFakeSysImgInternal(File imagesDir, String abiType) throws IOException {
imagesDir.mkdirs();
new File(imagesDir, "userdata.img").createNewFile();
File sourceProp = new File(imagesDir, SdkConstants.FN_SOURCE_PROP);
sourceProp.createNewFile();
FileWriter out = new FileWriter(sourceProp);
out.write(PkgProps.VERSION_API_LEVEL + "=0\n");
out.write(PkgProps.SYS_IMG_ABI + "=" + abiType + "\n");
out.close();
}
/** Utility to make a fake skin for the given target */
private void makeFakeSkinInternal(File targetDir) {
FileOp.append(targetDir, "skins", "HVGA").mkdirs();
}
/** Utility to create a fake source with a few files in the given sdk folder. */
private void makeFakeSourceInternal(File sdkDir) throws IOException {
File sourcesDir = FileOp.append(sdkDir, SdkConstants.FD_PKG_SOURCES, "android-0");
sourcesDir.mkdirs();
File sourceProp = new File(sourcesDir, SdkConstants.FN_SOURCE_PROP);
sourceProp.createNewFile();
FileWriter out = new FileWriter(sourceProp);
out.write(PkgProps.VERSION_API_LEVEL + "=0\n");
out.close();
File dir1 = FileOp.append(sourcesDir, "src", "com", "android");
dir1.mkdirs();
FileOp.append(dir1, "File1.java").createNewFile();
FileOp.append(dir1, "File2.java").createNewFile();
FileOp.append(sourcesDir, "res", "values").mkdirs();
FileOp.append(sourcesDir, "res", "values", "styles.xml").createNewFile();
}
/**
* Recursive delete directory. Mostly for fake SDKs.
*
* @param root directory to delete
*/
private void deleteDir(File root) {
if (root.exists()) {
for (File file : root.listFiles()) {
if (file.isDirectory()) {
deleteDir(file);
} else {
file.delete();
}
}
root.delete();
}
}
}