1 /*
2  * Copyright (C) 2019 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 package com.android.tradefed.cluster;
17 
18 import com.android.annotations.VisibleForTesting;
19 import com.android.tradefed.log.LogUtil.CLog;
20 import java.util.ArrayList;
21 import java.util.Collections;
22 import java.util.HashMap;
23 import java.util.List;
24 import java.util.Map;
25 import org.json.JSONArray;
26 import org.json.JSONException;
27 import org.json.JSONObject;
28 
29 /** A class to model a TestEnvironment message returned by TFC API. */
30 public class TestEnvironment {
31 
32     final Map<String, String> mEnvVars = new HashMap<>();
33     final List<String> mSetupScripts = new ArrayList<>();
34     final List<String> mOutputFilePatterns = new ArrayList<>();
35     String mOutputFileUploadUrl = null;
36     boolean mUseSubprocessReporting = false;
37     long mOutputIdleTimeout = 0L;
38     final List<String> mJvmOptions = new ArrayList<>();
39     final Map<String, String> mJavaProperties = new HashMap<>();
40     String mContextFilePattern = null;
41     private final List<String> mExtraContextFiles = new ArrayList<>();
42     String mRetryCommandLine = null;
43     String mLogLevel = null;
44     final List<TradefedConfigObject> mTradefedConfigObjects = new ArrayList<>();
45 
46     /**
47      * Adds an environment variable.
48      *
49      * @param name a variable name.
50      * @param value a variable value.
51      */
addEnvVar(final String name, final String value)52     public void addEnvVar(final String name, final String value) {
53         mEnvVars.put(name, value);
54     }
55 
56     /**
57      * Returns a {@link Map} object containing all env vars.
58      *
59      * @return unmodifiable map of all env vars.
60      */
getEnvVars()61     public Map<String, String> getEnvVars() {
62         return Collections.unmodifiableMap(mEnvVars);
63     }
64 
65     /**
66      * Adds a setup script command.
67      *
68      * @param s a setup script command.
69      */
addSetupScripts(final String s)70     public void addSetupScripts(final String s) {
71         mSetupScripts.add(s);
72     }
73 
74     /**
75      * Returns a list of setup script commands.
76      *
77      * @return unmodifiable list of commands
78      */
getSetupScripts()79     public List<String> getSetupScripts() {
80         return Collections.unmodifiableList(mSetupScripts);
81     }
82 
83     /**
84      * Adds an output file pattern.
85      *
86      * @param s a file pattern.
87      */
addOutputFilePattern(final String s)88     public void addOutputFilePattern(final String s) {
89         mOutputFilePatterns.add(s);
90     }
91 
92     /**
93      * Returns a list of output file patterns.
94      *
95      * @return unmodifiable list of file patterns.
96      */
getOutputFilePatterns()97     public List<String> getOutputFilePatterns() {
98         return Collections.unmodifiableList(mOutputFilePatterns);
99     }
100 
101     /**
102      * Sets an output file upload URL.
103      *
104      * @param s a URL.
105      */
setOutputFileUploadUrl(final String s)106     public void setOutputFileUploadUrl(final String s) {
107         mOutputFileUploadUrl = s;
108     }
109 
110     /**
111      * Returns an output file upload URL.
112      *
113      * @return a URL.
114      */
getOutputFileUploadUrl()115     public String getOutputFileUploadUrl() {
116         return mOutputFileUploadUrl;
117     }
118 
119     /**
120      * Returns whether to use subprocess reporting.
121      *
122      * @return a boolean.
123      */
useSubprocessReporting()124     public boolean useSubprocessReporting() {
125         return mUseSubprocessReporting;
126     }
127 
setUseSubprocessReporting(boolean f)128     public void setUseSubprocessReporting(boolean f) {
129         mUseSubprocessReporting = f;
130     }
131 
132     /** @return maximum millis to wait for an idle subprocess */
getOutputIdleTimeout()133     public long getOutputIdleTimeout() {
134         return mOutputIdleTimeout;
135     }
136 
setOutputIdleTimeout(long outputIdleTimeout)137     public void setOutputIdleTimeout(long outputIdleTimeout) {
138         mOutputIdleTimeout = outputIdleTimeout;
139     }
140 
141     /**
142      * Adds a JVM option.
143      *
144      * @param s a JVM option.
145      */
addJvmOption(final String s)146     public void addJvmOption(final String s) {
147         mJvmOptions.add(s);
148     }
149 
150     /**
151      * Returns a list of JVM options.
152      *
153      * @return unmodifiable list of options
154      */
getJvmOptions()155     public List<String> getJvmOptions() {
156         return Collections.unmodifiableList(mJvmOptions);
157     }
158 
159     /**
160      * Adds a java property.
161      *
162      * @param name a property name.
163      * @param value a property value.
164      */
addJavaProperty(final String name, final String value)165     public void addJavaProperty(final String name, final String value) {
166         mJavaProperties.put(name, value);
167     }
168 
169     /**
170      * Returns a {@link Map} object containing all Java properties.
171      *
172      * @return unmodifiable map of all runner properties.
173      */
getJavaProperties()174     public Map<String, String> getJavaProperties() {
175         return Collections.unmodifiableMap(mJavaProperties);
176     }
177 
getContextFilePattern()178     public String getContextFilePattern() {
179         return mContextFilePattern;
180     }
181 
182     /** Adds a file path to append to the context file. */
addExtraContextFile(String path)183     public void addExtraContextFile(String path) {
184         mExtraContextFiles.add(path);
185     }
186 
187     /** @return list of additional file paths to append to context file */
getExtraContextFiles()188     public List<String> getExtraContextFiles() {
189         return Collections.unmodifiableList(mExtraContextFiles);
190     }
191 
getRetryCommandLine()192     public String getRetryCommandLine() {
193         return mRetryCommandLine;
194     }
195 
getLogLevel()196     public String getLogLevel() {
197         return mLogLevel;
198     }
199 
getTradefedConfigObjects()200     public List<TradefedConfigObject> getTradefedConfigObjects() {
201         return Collections.unmodifiableList(mTradefedConfigObjects);
202     }
203 
204     /**
205      * Adds a {@link TradefedConfigObject}.
206      *
207      * @param obj a {@link TradefedConfigObject}.
208      */
209     @VisibleForTesting
addTradefedConfigObject(TradefedConfigObject obj)210     void addTradefedConfigObject(TradefedConfigObject obj) {
211         mTradefedConfigObjects.add(obj);
212     }
213 
fromJson(JSONObject json)214     public static TestEnvironment fromJson(JSONObject json) throws JSONException {
215         TestEnvironment obj = new TestEnvironment();
216         final JSONArray envVars = json.optJSONArray("env_vars");
217         if (envVars != null) {
218             for (int i = 0; i < envVars.length(); i++) {
219                 final JSONObject envVar = envVars.getJSONObject(i);
220                 obj.addEnvVar(envVar.getString("key"), envVar.getString("value"));
221             }
222         } else {
223             CLog.w("env_vars is null");
224         }
225         JSONArray jvmOptions = json.optJSONArray("jvm_options");
226         if (jvmOptions != null) {
227             for (int i = 0; i < jvmOptions.length(); i++) {
228                 obj.addJvmOption(jvmOptions.getString(i));
229             }
230         } else {
231             CLog.w("jvm_options is null");
232         }
233         final JSONArray javaProperties = json.optJSONArray("java_properties");
234         if (javaProperties != null) {
235             for (int i = 0; i < javaProperties.length(); i++) {
236                 final JSONObject javaProperty = javaProperties.getJSONObject(i);
237                 obj.addJavaProperty(javaProperty.getString("key"), javaProperty.getString("value"));
238             }
239         } else {
240             CLog.w("java_properties is null");
241         }
242         final JSONArray scripts = json.optJSONArray("setup_scripts");
243         if (scripts != null) {
244             for (int i = 0; i < scripts.length(); i++) {
245                 obj.addSetupScripts(scripts.getString(i));
246             }
247         } else {
248             CLog.w("setup_scripts is null");
249         }
250         final JSONArray patterns = json.optJSONArray("output_file_patterns");
251         if (patterns != null) {
252             for (int i = 0; i < patterns.length(); i++) {
253                 obj.addOutputFilePattern(patterns.getString(i));
254             }
255         } else {
256             CLog.w("output_file_patterns is null");
257         }
258         final String url = json.optString("output_file_upload_url");
259         if (url != null) {
260             obj.setOutputFileUploadUrl(url);
261         } else {
262             CLog.w("output_file_upload_url is null");
263         }
264         obj.mUseSubprocessReporting = json.optBoolean("use_subprocess_reporting");
265         obj.mOutputIdleTimeout = json.optLong("output_idle_timeout_millis", 0L);
266         obj.mContextFilePattern = json.optString("context_file_pattern");
267         JSONArray extraContextFiles = json.optJSONArray("extra_context_files");
268         if (extraContextFiles != null) {
269             for (int i = 0; i < extraContextFiles.length(); i++) {
270                 obj.addExtraContextFile(extraContextFiles.getString(i));
271             }
272         } else {
273             CLog.w("extra_context_files is null");
274         }
275         obj.mRetryCommandLine = json.optString("retry_command_line");
276         obj.mLogLevel = json.optString("log_level");
277         final JSONArray arr = json.optJSONArray("tradefed_config_objects");
278         if (arr != null) {
279             obj.mTradefedConfigObjects.addAll(TradefedConfigObject.fromJsonArray(arr));
280         }
281         return obj;
282     }
283 }
284