• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.tradefed.util;
18 
19 import com.android.tradefed.build.IBuildInfo;
20 import com.android.tradefed.build.IDeviceBuildInfo;
21 import com.android.tradefed.log.LogUtil.CLog;
22 
23 import com.google.common.annotations.VisibleForTesting;
24 
25 import java.io.File;
26 import java.util.ArrayList;
27 import java.util.Arrays;
28 import java.util.HashMap;
29 import java.util.List;
30 import java.util.Map;
31 
32 
33 /** Utility class for making system calls. */
34 public class SystemUtil {
35 
36     @VisibleForTesting static SystemUtil singleton = new SystemUtil();
37 
38     // Environment variables for the test cases directory in target out directory and host out
39     // directory.
40     public enum EnvVariable {
41         ANDROID_TARGET_OUT_TESTCASES,
42         ANDROID_HOST_OUT_TESTCASES,
43     }
44 
45     private static final String HOST_TESTCASES = "host/testcases";
46     private static final String TARGET_TESTCASES = "target/testcases";
47 
48     /** Keep track of the mapping of the variables to the subpath it takes in the tests dir. */
49     public static final Map<EnvVariable, String> ENV_VARIABLE_PATHS_IN_TESTS_DIR = new HashMap<>();
50 
51     static {
ENV_VARIABLE_PATHS_IN_TESTS_DIR.put( EnvVariable.ANDROID_TARGET_OUT_TESTCASES, TARGET_TESTCASES)52         ENV_VARIABLE_PATHS_IN_TESTS_DIR.put(
53                 EnvVariable.ANDROID_TARGET_OUT_TESTCASES, TARGET_TESTCASES);
ENV_VARIABLE_PATHS_IN_TESTS_DIR.put(EnvVariable.ANDROID_HOST_OUT_TESTCASES, HOST_TESTCASES)54         ENV_VARIABLE_PATHS_IN_TESTS_DIR.put(EnvVariable.ANDROID_HOST_OUT_TESTCASES, HOST_TESTCASES);
55     }
56 
57     static final String ENV_ANDROID_PRODUCT_OUT = "ANDROID_PRODUCT_OUT";
58 
59 
60     /**
61      * Get the value of an environment variable.
62      *
63      * <p>The wrapper function is created for mock in unit test.
64      *
65      * @param name the name of the environment variable.
66      * @return {@link String} value of the given environment variable.
67      */
68     @VisibleForTesting
getEnv(String name)69     String getEnv(String name) {
70         return System.getenv(name);
71     }
72 
73     /** Get a list of {@link File} pointing to tests directories external to Tradefed. */
getExternalTestCasesDirs()74     public static List<File> getExternalTestCasesDirs() {
75         List<File> testCasesDirs = new ArrayList<File>();
76         // TODO(b/36782030): Support running both HOST and TARGET tests.
77         List<String> testCasesDirNames =
78                 // List order matters. ConfigurationFactory caller uses first dir with test config.
79                 Arrays.asList(
80                         singleton.getEnv(EnvVariable.ANDROID_TARGET_OUT_TESTCASES.name()),
81                         singleton.getEnv(EnvVariable.ANDROID_HOST_OUT_TESTCASES.name()));
82         for (String testCasesDirName : testCasesDirNames) {
83             if (testCasesDirName != null) {
84                 File dir = new File(testCasesDirName);
85                 if (dir.exists() && dir.isDirectory()) {
86                     CLog.d("Found test case dir: %s", testCasesDirName);
87                     testCasesDirs.add(dir);
88                 } else {
89                     CLog.w(
90                             "Path %s for test cases directory does not exist or it's not a "
91                                     + "directory.",
92                             testCasesDirName);
93                 }
94             }
95         }
96         return testCasesDirs;
97     }
98 
99     /**
100      * Get the file associated with the env. variable.
101      *
102      * @param envVariable ANDROID_TARGET_OUT_TESTCASES or ANDROID_HOST_OUT_TESTCASES
103      * @return The directory associated.
104      */
getExternalTestCasesDir(EnvVariable envVariable)105     public static File getExternalTestCasesDir(EnvVariable envVariable) {
106         String var = System.getenv(envVariable.name());
107         if (var == null) {
108             return null;
109         }
110         File dir = new File(var);
111         if (dir.exists() && dir.isDirectory()) {
112             CLog.d("Found test case dir: %s for %s.", dir.getAbsolutePath(), envVariable.name());
113             return dir;
114         }
115         return null;
116     }
117 
118     /**
119      * Get a list of {@link File} of the test cases directories
120      *
121      * @param buildInfo the build artifact information. Set it to null if build info is not
122      *     available or there is no need to get test cases directories from build info.
123      * @return a list of {@link File} of directories of the test cases folder of build output, based
124      *     on the value of environment variables and the given build info.
125      */
getTestCasesDirs(IBuildInfo buildInfo)126     public static List<File> getTestCasesDirs(IBuildInfo buildInfo) {
127         List<File> testCasesDirs = new ArrayList<File>();
128         testCasesDirs.addAll(getExternalTestCasesDirs());
129 
130         // TODO: Remove this logic after Versioned TF V2 is implemented, in which staging build
131         // artifact will be done by the parent process, and the test cases dirs will be set by
132         // environment variables.
133         // Add tests dir from build info.
134         if (buildInfo instanceof IDeviceBuildInfo) {
135             IDeviceBuildInfo deviceBuildInfo = (IDeviceBuildInfo) buildInfo;
136             File testsDir = deviceBuildInfo.getTestsDir();
137             // Add all possible paths to the testcases directory list.
138             if (testsDir != null) {
139                 testCasesDirs.addAll(
140                         Arrays.asList(
141                                 testsDir,
142                                 FileUtil.getFileForPath(testsDir, HOST_TESTCASES),
143                                 FileUtil.getFileForPath(testsDir, TARGET_TESTCASES)));
144             }
145         }
146 
147         return testCasesDirs;
148     }
149 
150     /**
151      * Gets the product specific output dir from an Android build tree. Typically this location
152      * contains images for various device partitions, bootloader, radio and so on.
153      *
154      * <p>Note: the method does not guarantee that this path exists.
155      *
156      * @return the location of the output dir or <code>null</code> if the current build is not
157      */
getProductOutputDir()158     public static File getProductOutputDir() {
159         String path = singleton.getEnv(ENV_ANDROID_PRODUCT_OUT);
160         if (path == null) {
161             return null;
162         } else {
163             return new File(path);
164         }
165     }
166 }
167