blob: d1cdcc0ffd0d00049117880e61c76a20d7e3287e [file] [log] [blame]
/*
* Copyright (C) 2017 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.tradefed.util;
import com.android.tradefed.build.IBuildInfo;
import com.android.tradefed.build.IDeviceBuildInfo;
import com.android.tradefed.log.LogUtil.CLog;
import com.google.common.annotations.VisibleForTesting;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/** Utility class for making system calls. */
public class SystemUtil {
@VisibleForTesting static SystemUtil singleton = new SystemUtil();
// Environment variables for the test cases directory in target out directory and host out
// directory.
public enum EnvVariable {
ANDROID_TARGET_OUT_TESTCASES,
ANDROID_HOST_OUT_TESTCASES,
}
public static final String REMOTE_VM_VARIABLE = "REMOTE_VM_ENV";
private static final String HOST_TESTCASES = "host/testcases";
private static final String TARGET_TESTCASES = "target/testcases";
/** Keep track of the mapping of the variables to the subpath it takes in the tests dir. */
public static final Map<EnvVariable, String> ENV_VARIABLE_PATHS_IN_TESTS_DIR = new HashMap<>();
static {
ENV_VARIABLE_PATHS_IN_TESTS_DIR.put(
EnvVariable.ANDROID_TARGET_OUT_TESTCASES, TARGET_TESTCASES);
ENV_VARIABLE_PATHS_IN_TESTS_DIR.put(EnvVariable.ANDROID_HOST_OUT_TESTCASES, HOST_TESTCASES);
}
static final String ENV_ANDROID_PRODUCT_OUT = "ANDROID_PRODUCT_OUT";
/**
* Get the value of an environment variable.
*
* <p>The wrapper function is created for mock in unit test.
*
* @param name the name of the environment variable.
* @return {@link String} value of the given environment variable.
*/
@VisibleForTesting
String getEnv(String name) {
return System.getenv(name);
}
/** Get a list of {@link File} pointing to tests directories external to Tradefed. */
public static List<File> getExternalTestCasesDirs() {
List<File> testCasesDirs = new ArrayList<File>();
// TODO(b/36782030): Support running both HOST and TARGET tests.
List<String> testCasesDirNames =
// List order matters. ConfigurationFactory caller uses first dir with test config.
Arrays.asList(
singleton.getEnv(EnvVariable.ANDROID_TARGET_OUT_TESTCASES.name()),
singleton.getEnv(EnvVariable.ANDROID_HOST_OUT_TESTCASES.name()));
for (String testCasesDirName : testCasesDirNames) {
if (testCasesDirName != null) {
File dir = new File(testCasesDirName);
if (dir.exists() && dir.isDirectory()) {
CLog.d("Found test case dir: %s", testCasesDirName);
testCasesDirs.add(dir);
} else {
CLog.w(
"Path %s for test cases directory does not exist or it's not a "
+ "directory.",
testCasesDirName);
}
}
}
return testCasesDirs;
}
/**
* Get the file associated with the env. variable.
*
* @param envVariable ANDROID_TARGET_OUT_TESTCASES or ANDROID_HOST_OUT_TESTCASES
* @return The directory associated.
*/
public static File getExternalTestCasesDir(EnvVariable envVariable) {
String var = System.getenv(envVariable.name());
if (var == null) {
return null;
}
File dir = new File(var);
if (dir.exists() && dir.isDirectory()) {
CLog.d("Found test case dir: %s for %s.", dir.getAbsolutePath(), envVariable.name());
return dir;
}
return null;
}
/**
* Get a list of {@link File} of the test cases directories
*
* @param buildInfo the build artifact information. Set it to null if build info is not
* available or there is no need to get test cases directories from build info.
* @return a list of {@link File} of directories of the test cases folder of build output, based
* on the value of environment variables and the given build info.
*/
public static List<File> getTestCasesDirs(IBuildInfo buildInfo) {
List<File> testCasesDirs = new ArrayList<File>();
testCasesDirs.addAll(getExternalTestCasesDirs());
// TODO: Remove this logic after Versioned TF V2 is implemented, in which staging build
// artifact will be done by the parent process, and the test cases dirs will be set by
// environment variables.
// Add tests dir from build info.
if (buildInfo instanceof IDeviceBuildInfo) {
IDeviceBuildInfo deviceBuildInfo = (IDeviceBuildInfo) buildInfo;
File testsDir = deviceBuildInfo.getTestsDir();
// Add all possible paths to the testcases directory list.
if (testsDir != null) {
testCasesDirs.addAll(
Arrays.asList(
testsDir,
FileUtil.getFileForPath(testsDir, HOST_TESTCASES),
FileUtil.getFileForPath(testsDir, TARGET_TESTCASES)));
}
}
return testCasesDirs;
}
/**
* Gets the product specific output dir from an Android build tree. Typically this location
* contains images for various device partitions, bootloader, radio and so on.
*
* <p>Note: the method does not guarantee that this path exists.
*
* @return the location of the output dir or <code>null</code> if the current build is not
*/
public static File getProductOutputDir() {
String path = singleton.getEnv(ENV_ANDROID_PRODUCT_OUT);
if (path == null) {
return null;
} else {
return new File(path);
}
}
/** Return true if we are currently running in a remote environment. */
public static boolean isRemoteEnvironment() {
if ("1".equals(System.getenv(REMOTE_VM_VARIABLE))) {
return true;
}
return false;
}
/** Returns the path to the Java binary that current test harness is running in */
public static File getRunningJavaBinaryPath() {
String javaHome = System.getProperty("java.home");
if (javaHome == null) {
throw new RuntimeException("System property \"java.home\" is not set.");
}
// this only works on *nix systems, but it's not like we officially support any others
File javaBinary = new File(String.format("%s/bin/java", javaHome));
if (!javaBinary.exists()) {
throw new RuntimeException(
String.format("Computed Java binary path %s does not exist", javaBinary));
}
return javaBinary;
}
}