├── .classpath
├── .gitignore
├── .project
├── .settings
└── org.eclipse.jdt.core.prefs
├── README.md
├── docs
├── how_to_develop.md
├── how_to_use_in_mac.md
├── how_to_use_in_windows.md
└── troubleshoot.md
├── libs
├── chimpchat-22.2.0.jar
├── commons-compress-1.8.1.jar
├── ddmlib-prebuilt.jar
├── gson-2.2.4.jar
├── guava-17.0.jar
├── hosttestlib.jar
├── imagedraw.jar
├── javalib-deviceinfo.jar
├── javalib-deviceutil.jar
├── jline-0.9.9.jar
├── kxml2-2.3.0.jar
└── tradefederation.jar
├── res
├── config
│ └── cts.xml
└── report
│ ├── bootstrap.css
│ ├── index.xsl
│ ├── result.xsl
│ └── trace.xsl
└── src
└── com
└── android
└── cts
└── tradefed
├── build
├── CtsBuildHelper.java
└── CtsBuildProvider.java
├── command
└── CtsConsole.java
├── device
├── DeviceInfoCollector.java
├── DeviceNetWorkListener.java
├── DeviceUnlock.java
└── MonkeyActivityListener.java
├── result
├── AbstractXmlPullParser.java
├── CrashAnalyzer.java
├── CtsTestStatus.java
├── CtsXmlResultReporter.java
├── DeviceInfoResult.java
├── ITestResultRepo.java
├── ITestSummary.java
├── IssueReporter.java
├── MonkeyReporter.java
├── MultipartForm.java
├── PlanCreator.java
├── PtsHostStore.java
├── PtsReportUtil.java
├── ResultReporter.java
├── Test.java
├── TestCase.java
├── TestPackageResult.java
├── TestResultRepo.java
├── TestResults.java
├── TestSuite.java
├── TestSummaryXml.java
├── TimeUtil.java
└── monkey
│ ├── DragTag.java
│ ├── EventTag.java
│ ├── KeyTag.java
│ ├── MonkeyTestTag.java
│ ├── MotionTag.java
│ ├── TapTag.java
│ └── TouchTag.java
├── targetprep
├── CtsRootDeviceSetup.java
└── SettingsToggler.java
├── test
└── Test.java
└── testtype
├── AccessibilityServiceTestRunner.java
├── AccessibilityTestRunner.java
├── CtsTest.java
├── DisplayTestRunner.java
├── GeeTest.java
├── GeeTestResultParser.java
├── ITestPackageDef.java
├── ITestPackageRepo.java
├── ITestPlan.java
├── InstrumentationApkTest.java
├── JarHostTest.java
├── MonkeyTest.java
├── ResultFilter.java
├── TestFilter.java
├── TestPackageDef.java
├── TestPackageRepo.java
├── TestPackageXmlParser.java
├── TestPlan.java
├── TestTimeoutException.java
├── UiAutomatorJarTest.java
├── VMHostTest.java
├── WrappedGTest.java
├── WrappedGTestResultParser.java
└── monkey
├── Monkey.java
├── MonkeyDragEvent.java
├── MonkeyEvent.java
├── MonkeyEventQueue.java
├── MonkeyEventSource.java
├── MonkeyKeyEvent.java
├── MonkeyMotionEvent.java
├── MonkeySourceRandom.java
├── MonkeyTapEvent.java
└── Rectangle.java
/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
null
if it could not be found
48 | */
49 | static CtsTestStatus getStatus(String value) {
50 | for (CtsTestStatus status : CtsTestStatus.values()) {
51 | if (value.compareToIgnoreCase(status.getValue()) == 0) {
52 | return status;
53 | }
54 | }
55 | return null;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/result/ITestResultRepo.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 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.cts.tradefed.result;
17 |
18 | import java.io.File;
19 | import java.util.List;
20 |
21 | /**
22 | * Repository for CTS results.
23 | */
24 | public interface ITestResultRepo {
25 |
26 | /**
27 | * @return the list of {@link ITestSummary}s. The index of the {@link ITestSummary} in the
28 | * list is its session id
29 | */
30 | public Listnull if the result with that session id
37 | * cannot be retrieved
38 | */
39 | public TestResults getResult(int sessionId);
40 |
41 | /**
42 | * Get the report directory for given result
43 | * @param sessionId
44 | * @return
45 | */
46 | public File getReportDir(int sessionId);
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/result/ITestSummary.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 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.cts.tradefed.result;
17 |
18 | /**
19 | * Interface for a single CTS result summary.
20 | */
21 | public interface ITestSummary {
22 |
23 | /**
24 | * @return the session id
25 | */
26 | int getId();
27 |
28 | /**
29 | * @return the starting timestamp, also known as result directory name
30 | */
31 | String getTimestamp();
32 |
33 | /**
34 | * @return the num of not executed tests
35 | */
36 | int getNumIncomplete();
37 |
38 | /**
39 | * @return the number of failed tests
40 | */
41 | int getNumFailed();
42 |
43 | /**
44 | * @return the number of passed tests
45 | */
46 | int getNumPassed();
47 |
48 | /**
49 | * @return the test plan associated with result
50 | */
51 | String getTestPlan();
52 |
53 | /**
54 | * Return the user-friendly displayed start time stored in result XML.
55 | *
56 | * Expected format: {@link TimeUtil#getTimestamp()}
57 | */
58 | String getStartTime();
59 |
60 | /**
61 | * @return a comma separated list of device serials associated with result
62 | */
63 | String getDeviceSerials();
64 |
65 | }
66 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/result/IssueReporter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 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.cts.tradefed.result;
18 |
19 | import com.android.ddmlib.testrunner.TestIdentifier;
20 | import com.android.tradefed.build.IBuildInfo;
21 | import com.android.tradefed.config.Option;
22 | import com.android.tradefed.log.LogUtil.CLog;
23 | import com.android.tradefed.result.ITestInvocationListener;
24 | import com.android.tradefed.result.InputStreamSource;
25 | import com.android.tradefed.result.LogDataType;
26 | import com.android.tradefed.result.TestSummary;
27 |
28 | import java.io.ByteArrayOutputStream;
29 | import java.io.IOException;
30 | import java.io.InputStream;
31 | import java.util.Map;
32 | import java.util.concurrent.Callable;
33 | import java.util.concurrent.ExecutorService;
34 | import java.util.concurrent.Executors;
35 | import java.util.concurrent.TimeUnit;
36 | import java.util.zip.GZIPOutputStream;
37 |
38 | /**
39 | * Class that sends a HTTP POST multipart/form-data request containing details
40 | * about a test failure.
41 | */
42 | public class IssueReporter implements ITestInvocationListener {
43 |
44 | private static final int BUGREPORT_SIZE = 500 * 1024;
45 |
46 | private static final String PRODUCT_NAME_KEY = "buildName";
47 | private static final String BUILD_TYPE_KEY = "build_type";
48 | private static final String BUILD_ID_KEY = "buildID";
49 |
50 | @Option(name = "issue-server", description = "Server url to post test failures to.")
51 | private String mServerUrl;
52 |
53 | private final ExecutorService mReporterService = Executors.newCachedThreadPool();
54 |
55 | private Issue mCurrentIssue;
56 | private String mBuildId;
57 | private String mBuildType;
58 | private String mProductName;
59 |
60 | @Override
61 | public void testFailed(TestFailure status, TestIdentifier test, String trace) {
62 | mCurrentIssue = new Issue();
63 | mCurrentIssue.mTestName = test.toString();
64 | mCurrentIssue.mStackTrace = trace;
65 | }
66 |
67 | @Override
68 | public void testLog(String dataName, LogDataType dataType, InputStreamSource dataStream) {
69 | if (dataName.startsWith("bug-")) {
70 | try {
71 | setBugReport(dataStream);
72 | } catch (IOException e) {
73 | CLog.e(e);
74 | }
75 | }
76 | }
77 |
78 | /**
79 | * Set the bug report for the current test failure. GZip it to save space.
80 | * This is only called when the --bugreport option is enabled.
81 | */
82 | private void setBugReport(InputStreamSource dataStream) throws IOException {
83 | if (mCurrentIssue != null) {
84 | // Only one bug report can be stored at a time and they are gzipped to
85 | // about 0.5 MB so there shoudn't be any memory leak bringing down CTS.
86 | InputStream input = null;
87 | try {
88 | input = dataStream.createInputStream();
89 | mCurrentIssue.mBugReport = getBytes(input, BUGREPORT_SIZE);
90 | } finally {
91 | if (input != null) {
92 | input.close();
93 | }
94 | }
95 | } else {
96 | CLog.e("setBugReport is getting called on an empty issue...");
97 | }
98 | }
99 |
100 | /**
101 | * @param input that will be gzipped and returne as a byte array
102 | * @param size of the output expected
103 | * @return the byte array with the input's data
104 | * @throws IOException
105 | */
106 | static byte[] getBytes(InputStream input, int size) throws IOException {
107 | ByteArrayOutputStream byteOutput = new ByteArrayOutputStream(size);
108 | GZIPOutputStream gzipOutput = new GZIPOutputStream(byteOutput);
109 | for (byte[] buffer = new byte[1024]; ; ) {
110 | int numRead = input.read(buffer);
111 | if (numRead < 0) {
112 | break;
113 | }
114 | gzipOutput.write(buffer, 0, numRead);
115 | }
116 | gzipOutput.close();
117 | return byteOutput.toByteArray();
118 | }
119 |
120 | @Override
121 | public void testEnded(TestIdentifier test, Map testMetrics) {
122 | if (mCurrentIssue != null) {
123 | mReporterService.submit(mCurrentIssue);
124 | mCurrentIssue = null;
125 | }
126 | }
127 |
128 | @Override
129 | public void testRunEnded(long elapsedTime, Map runMetrics) {
130 | setDeviceMetrics(runMetrics);
131 | }
132 |
133 | /** Set device information. Populated once when the device info app runs. */
134 | private void setDeviceMetrics(Map metrics) {
135 | if (metrics.containsKey(BUILD_ID_KEY)) {
136 | mBuildId = metrics.get(BUILD_ID_KEY);
137 | }
138 | if (metrics.containsKey(BUILD_TYPE_KEY)) {
139 | mBuildType = metrics.get(BUILD_TYPE_KEY);
140 | }
141 | if (metrics.containsKey(PRODUCT_NAME_KEY)) {
142 | mProductName = metrics.get(PRODUCT_NAME_KEY);
143 | }
144 | }
145 |
146 | @Override
147 | public void invocationEnded(long elapsedTime) {
148 | try {
149 | mReporterService.shutdown();
150 | if (!mReporterService.awaitTermination(1, TimeUnit.MINUTES)) {
151 | CLog.i("Some issues could not be reported...");
152 | }
153 | } catch (InterruptedException e) {
154 | CLog.e(e);
155 | }
156 | }
157 |
158 | class Issue implements Callable {
159 |
160 | private String mTestName;
161 | private String mStackTrace;
162 | private byte[] mBugReport;
163 |
164 | @Override
165 | public Void call() throws Exception {
166 | if (isEmpty(mServerUrl)
167 | || isEmpty(mBuildId)
168 | || isEmpty(mBuildType)
169 | || isEmpty(mProductName)
170 | || isEmpty(mTestName)
171 | || isEmpty(mStackTrace)) {
172 | return null;
173 | }
174 |
175 | new MultipartForm(mServerUrl)
176 | .addFormValue("productName", mProductName)
177 | .addFormValue("buildType", mBuildType)
178 | .addFormValue("buildId", mBuildId)
179 | .addFormValue("testName", mTestName)
180 | .addFormValue("stackTrace", mStackTrace)
181 | .addFormFile("bugReport", "bugreport.txt.gz", mBugReport)
182 | .submit();
183 |
184 | return null;
185 | }
186 |
187 | private boolean isEmpty(String value) {
188 | return value == null || value.trim().isEmpty();
189 | }
190 | }
191 |
192 | @Override
193 | public void invocationStarted(IBuildInfo buildInfo) {
194 | }
195 |
196 | @Override
197 | public void testRunStarted(String name, int numTests) {
198 | }
199 |
200 | @Override
201 | public void testStarted(TestIdentifier test) {
202 | }
203 |
204 | @Override
205 | public void testRunFailed(String arg0) {
206 | }
207 |
208 | @Override
209 | public void testRunStopped(long elapsedTime) {
210 | }
211 |
212 | @Override
213 | public void invocationFailed(Throwable cause) {
214 | }
215 |
216 | @Override
217 | public TestSummary getSummary() {
218 | return null;
219 | }
220 | }
221 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/result/MultipartForm.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 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.cts.tradefed.result;
18 |
19 | import java.io.ByteArrayOutputStream;
20 | import java.io.IOException;
21 | import java.io.InputStream;
22 | import java.io.OutputStream;
23 | import java.io.OutputStreamWriter;
24 | import java.io.PrintWriter;
25 | import java.net.HttpURLConnection;
26 | import java.net.URL;
27 | import java.util.HashMap;
28 | import java.util.Map;
29 |
30 | /** MultipartForm builds a multipart form and submits it. */
31 | class MultipartForm {
32 |
33 | private static final String FORM_DATA_BOUNDARY = "C75I55u3R3p0r73r";
34 |
35 | private final String mServerUrl;
36 |
37 | private final Map mFormValues = new HashMap();
38 |
39 | private String mName;
40 | private String mFileName;
41 | private byte[] mData;
42 |
43 | public MultipartForm(String serverUrl) {
44 | mServerUrl = serverUrl;
45 | }
46 |
47 | public MultipartForm addFormValue(String name, String value) {
48 | mFormValues.put(name, value);
49 | return this;
50 | }
51 |
52 | public MultipartForm addFormFile(String name, String fileName, byte[] data) {
53 | mName = name;
54 | mFileName = fileName;
55 | mData = data;
56 | return this;
57 | }
58 |
59 | public void submit() throws IOException {
60 | String redirectUrl = submitForm(mServerUrl);
61 | if (redirectUrl != null) {
62 | submitForm(redirectUrl);
63 | }
64 | }
65 |
66 | /**
67 | * @param serverUrl to post the data to
68 | * @return a url if the server redirected to another url
69 | * @throws IOException
70 | */
71 | private String submitForm(String serverUrl) throws IOException {
72 | HttpURLConnection connection = null;
73 | try {
74 | URL url = new URL(serverUrl);
75 | connection = (HttpURLConnection) url.openConnection();
76 | connection.setInstanceFollowRedirects(false);
77 | connection.setRequestMethod("POST");
78 | connection.setDoOutput(true);
79 | connection.setRequestProperty("Content-Type",
80 | "multipart/form-data; boundary=" + FORM_DATA_BOUNDARY);
81 |
82 | byte[] body = getContentBody();
83 | connection.setRequestProperty("Content-Length", Integer.toString(body.length));
84 |
85 | OutputStream output = connection.getOutputStream();
86 | try {
87 | output.write(body);
88 | } finally {
89 | output.close();
90 | }
91 |
92 | // Open the stream to get a response. Otherwise request will be cancelled.
93 | InputStream input = connection.getInputStream();
94 | input.close();
95 |
96 | if (connection.getResponseCode() == 302) {
97 | return connection.getHeaderField("Location");
98 | }
99 | } finally {
100 | if (connection != null) {
101 | connection.disconnect();
102 | }
103 | }
104 |
105 | return null;
106 | }
107 |
108 | private byte[] getContentBody() throws IOException {
109 | ByteArrayOutputStream byteOutput = new ByteArrayOutputStream();
110 | PrintWriter writer = new PrintWriter(new OutputStreamWriter(byteOutput));
111 | writer.println();
112 |
113 | for (Map.Entry formValue : mFormValues.entrySet()) {
114 | writeFormField(writer, formValue.getKey(), formValue.getValue());
115 | }
116 |
117 | if (mData != null) {
118 | writeFormFileHeader(writer, mName, mFileName);
119 | writer.flush(); // Must flush here before writing to the byte stream!
120 | byteOutput.write(mData);
121 | writer.println();
122 | }
123 | writer.append("--").append(FORM_DATA_BOUNDARY).println("--");
124 | writer.flush();
125 | writer.close();
126 | return byteOutput.toByteArray();
127 | }
128 |
129 | private void writeFormField(PrintWriter writer, String name, String value) {
130 | writer.append("--").println(FORM_DATA_BOUNDARY);
131 | writer.append("Content-Disposition: form-data; name=\"").append(name).println("\"");
132 | writer.println();
133 | writer.println(value);
134 | }
135 |
136 | private void writeFormFileHeader(PrintWriter writer, String name, String fileName) {
137 | writer.append("--").println(FORM_DATA_BOUNDARY);
138 | writer.append("Content-Disposition: form-data; name=\"").append(name);
139 | writer.append("\"; filename=\"").append(fileName).println("\"");
140 | writer.println("Content-Type: application/x-gzip");
141 | writer.println("Content-Transfer-Encoding: binary");
142 | writer.println();
143 | }
144 | }
145 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/result/PlanCreator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 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.cts.tradefed.result;
17 |
18 | import com.android.cts.tradefed.build.CtsBuildHelper;
19 | import com.android.cts.tradefed.testtype.CtsTest;
20 | import com.android.cts.tradefed.testtype.ITestPackageDef;
21 | import com.android.cts.tradefed.testtype.ITestPackageRepo;
22 | import com.android.cts.tradefed.testtype.ITestPlan;
23 | import com.android.cts.tradefed.testtype.TestPackageRepo;
24 | import com.android.cts.tradefed.testtype.TestPlan;
25 | import com.android.ddmlib.Log;
26 | import com.android.ddmlib.Log.LogLevel;
27 | import com.android.ddmlib.testrunner.TestIdentifier;
28 | import com.android.tradefed.config.ConfigurationException;
29 | import com.android.tradefed.config.Option;
30 | import com.android.tradefed.config.Option.Importance;
31 | import com.android.tradefed.log.LogUtil.CLog;
32 |
33 | import java.io.BufferedOutputStream;
34 | import java.io.File;
35 | import java.io.FileNotFoundException;
36 | import java.io.FileOutputStream;
37 | import java.io.IOException;
38 | import java.util.Collection;
39 | import java.util.LinkedHashSet;
40 |
41 | /**
42 | * Class for creating test plans from CTS result XML.
43 | */
44 | public class PlanCreator {
45 |
46 | @Option (name = "plan", shortName = 'p', description = "the name of the plan to create",
47 | importance=Importance.IF_UNSET)
48 | private String mPlanName = null;
49 |
50 | @Option (name = "session", shortName = 's', description = "the session id to derive from",
51 | importance=Importance.IF_UNSET)
52 | private Integer mSessionId = null;
53 |
54 | @Option (name = "result", shortName = 'r',
55 | description = "the result type to filter. One of pass, fail, notExecuted.",
56 | importance=Importance.IF_UNSET)
57 | private String mResultFilterString = null;
58 |
59 | @Option(name = CtsTest.RUN_KNOWN_FAILURES_OPTION)
60 | private boolean mIncludeKnownFailures = false;
61 |
62 | private CtsTestStatus mResultFilter = null;
63 | private TestResults mResult = null;
64 |
65 | private File mPlanFile;
66 |
67 | /**
68 | * Create an empty {@link PlanCreator}.
69 | *
70 | * All {@link Option} fields must be populated via
71 | * {@link com.android.tradefed.config.ArgsOptionParser}
72 | */
73 | public PlanCreator() {
74 | }
75 |
76 | /**
77 | * Create a {@link PlanCreator} using the specified option values.
78 | */
79 | public PlanCreator(String planName, int session, CtsTestStatus result) {
80 | mPlanName = planName;
81 | mSessionId = session;
82 | mResultFilterString = result.getValue();
83 | }
84 |
85 | /**
86 | * Create and serialize a test plan derived from a result.
87 | *
88 | * {@link Option} values must all be set before this is called.
89 | * @throws ConfigurationException
90 | */
91 | public void createAndSerializeDerivedPlan(CtsBuildHelper build) throws ConfigurationException {
92 | ITestPlan derivedPlan = createDerivedPlan(build);
93 | if (derivedPlan != null) {
94 | try {
95 | derivedPlan.serialize(new BufferedOutputStream(new FileOutputStream(mPlanFile)));
96 | } catch (IOException e) {
97 | Log.logAndDisplay(LogLevel.ERROR, "", String.format("Failed to create plan file %s",
98 | mPlanName));
99 | CLog.e(e);
100 | }
101 | }
102 | }
103 |
104 | /**
105 | * Create a test plan derived from a result.
106 | *
107 | * {@link Option} values must all be set before this is called.
108 | *
109 | * @param build
110 | * @return test plan
111 | * @throws ConfigurationException
112 | */
113 | public ITestPlan createDerivedPlan(CtsBuildHelper build) throws ConfigurationException {
114 | checkFields(build);
115 | ITestPackageRepo pkgDefRepo = new TestPackageRepo(build.getTestCasesDir(),
116 | mIncludeKnownFailures);
117 | ITestPlan derivedPlan = new TestPlan(mPlanName);
118 | for (TestPackageResult pkg : mResult.getPackages()) {
119 | Collection filteredTests = pkg.getTestsWithStatus(mResultFilter);
120 | if (!filteredTests.isEmpty()) {
121 | String pkgUri = pkg.getAppPackageName();
122 | ITestPackageDef pkgDef = pkgDefRepo.getTestPackage(pkgUri);
123 | if (pkgDef != null) {
124 | Collection excludedTests = new LinkedHashSet(
125 | pkgDef.getTests());
126 | excludedTests.removeAll(filteredTests);
127 | derivedPlan.addPackage(pkgUri);
128 | derivedPlan.addExcludedTests(pkgUri, excludedTests);
129 | } else {
130 | CLog.e("Could not find package %s in repository", pkgUri);
131 | }
132 | }
133 | }
134 | return derivedPlan;
135 | }
136 |
137 | /**
138 | * Check that all {@Option}s have been populated with valid values.
139 | * @param build
140 | * @throws ConfigurationException if any option has an invalid value
141 | */
142 | private void checkFields(CtsBuildHelper build) throws ConfigurationException {
143 | if (mSessionId == null) {
144 | throw new ConfigurationException("Missing --session argument");
145 | }
146 | ITestResultRepo repo = new TestResultRepo(build.getResultsDir());
147 | mResult = repo.getResult(mSessionId);
148 | if (mResult == null) {
149 | throw new ConfigurationException(String.format("Could not find session with id %d",
150 | mSessionId));
151 | }
152 | if (mResultFilterString == null) {
153 | throw new ConfigurationException("Missing --result argument");
154 | }
155 | mResultFilter = CtsTestStatus.getStatus(mResultFilterString);
156 | if (mResultFilter == null) {
157 | throw new ConfigurationException(
158 | "Invalid result argument. Expected one of pass,fail,notExecuted");
159 | }
160 | if (mPlanName == null) {
161 | throw new ConfigurationException("Missing --plan argument");
162 | }
163 | try {
164 | mPlanFile = build.getTestPlanFile(mPlanName);
165 | if (mPlanFile.exists()) {
166 | throw new ConfigurationException(String.format("Test plan %s already exists",
167 | mPlanName));
168 | }
169 | } catch (FileNotFoundException e) {
170 | throw new ConfigurationException("Could not find plans directory");
171 | }
172 | }
173 | }
174 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/result/PtsHostStore.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2013 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.cts.tradefed.result;
17 |
18 | import com.android.ddmlib.testrunner.TestIdentifier;
19 | import com.android.tradefed.device.ITestDevice;
20 |
21 | import java.util.concurrent.ConcurrentHashMap;
22 |
23 | /**
24 | * Utility class for storing Pts Results.
25 | * This is necessary for host tests where test metrics cannot be passed.
26 | */
27 | public class PtsHostStore {
28 |
29 | // needs concurrent verion as there can be multiple client accessing this.
30 | // But there is no additional protection for the same key as that should not happen.
31 | private static final ConcurrentHashMap mMap =
32 | new ConcurrentHashMap();
33 |
34 | /**
35 | * Stores PTS result. Existing result with the same key will be replaced.
36 | * Note that key is generated in the form of device_serial#class#method name.
37 | * So there should be no concurrent test for the same (serial, class, method).
38 | * @param device
39 | * @param test
40 | * @param result PTS result string
41 | */
42 | public static void storePtsResult(String deviceSerial, String classMethodName, String result) {
43 | mMap.put(generateTestKey(deviceSerial, classMethodName), result);
44 | }
45 |
46 | /**
47 | * retrieves a PTS result for the given condition and remove it from the internal
48 | * storage. If there is no result for the given condition, it will return null.
49 | */
50 | public static String removePtsResult(String deviceSerial, TestIdentifier test) {
51 | return mMap.remove(generateTestKey(deviceSerial, test));
52 | }
53 |
54 | /**
55 | * return test key in the form of device_serial#class_name#method_name
56 | */
57 | private static String generateTestKey(String deviceSerial, TestIdentifier test) {
58 | return String.format("%s#%s", deviceSerial, test.toString());
59 |
60 | }
61 |
62 | /**
63 | * return test key in the form of device_serial#class_name#method_name
64 | */
65 | private static String generateTestKey(String deviceSerial, String classMethodName) {
66 | return String.format("%s#%s", deviceSerial, classMethodName);
67 |
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/result/PtsReportUtil.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2013 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.cts.tradefed.result;
17 |
18 | import com.android.ddmlib.testrunner.TestIdentifier;
19 | import com.android.tradefed.device.ITestDevice;
20 |
21 | import java.util.Map;
22 | import java.util.concurrent.ConcurrentHashMap;
23 |
24 | /**
25 | * Static utility class for handling Pts Results.
26 | */
27 | public class PtsReportUtil {
28 | private static final String PTS_RESULT_KEY = "PTS_RESULT";
29 |
30 | /**
31 | * Utility method to extract PTS result from test metrics
32 | * @param testMetrics
33 | * @return result or null if not found
34 | */
35 | public static String getPtsResultFromMetrics(Map testMetrics) {
36 | for (Map.Entry entry: testMetrics.entrySet()) {
37 | if (PTS_RESULT_KEY.equals(entry.getKey())) {
38 | return entry.getValue();
39 | }
40 | }
41 | return null;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/result/ResultReporter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 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.cts.tradefed.result;
18 |
19 | import java.io.File;
20 | import java.io.FileInputStream;
21 | import java.io.IOException;
22 | import java.io.InputStream;
23 |
24 | /**
25 | * Class that sends a HTTP POST multipart/form-data request containing
26 | * the test result XML.
27 | */
28 | class ResultReporter {
29 |
30 | private static final int RESULT_XML_BYTES = 500 * 1024;
31 |
32 | private final String mServerUrl;
33 | private final String mSuiteName;
34 |
35 | ResultReporter(String serverUrl, String suiteName) {
36 | mServerUrl = serverUrl;
37 | mSuiteName = suiteName;
38 | }
39 |
40 | public void reportResult(File reportFile) throws IOException {
41 | if (isEmpty(mServerUrl)) {
42 | return;
43 | }
44 |
45 | InputStream input = new FileInputStream(reportFile);
46 | try {
47 | byte[] data = IssueReporter.getBytes(input, RESULT_XML_BYTES);
48 | new MultipartForm(mServerUrl)
49 | .addFormValue("suite", mSuiteName)
50 | .addFormFile("resultXml", "testResult.xml.gz", data)
51 | .submit();
52 | } finally {
53 | input.close();
54 | }
55 | }
56 |
57 | private boolean isEmpty(String value) {
58 | return value == null || value.trim().isEmpty();
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/result/TestCase.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 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.cts.tradefed.result;
17 |
18 | import com.android.ddmlib.testrunner.TestIdentifier;
19 | import com.android.tradefed.util.ArrayUtil;
20 |
21 | import org.kxml2.io.KXmlSerializer;
22 | import org.xmlpull.v1.XmlPullParser;
23 | import org.xmlpull.v1.XmlPullParserException;
24 |
25 | import java.io.IOException;
26 | import java.util.Collection;
27 | import java.util.Deque;
28 | import java.util.LinkedHashMap;
29 | import java.util.Map;
30 |
31 | /**
32 | * Data structure that represents a "TestCase" XML element and its children.
33 | */
34 | class TestCase extends AbstractXmlPullParser {
35 |
36 | static final String TAG = "TestCase";
37 |
38 | private String mName;
39 |
40 | Map mChildTestMap = new LinkedHashMap();
41 |
42 | /**
43 | * Create a {@link TestCase}
44 | *
45 | * @param testCaseName
46 | */
47 | public TestCase(String testCaseName) {
48 | setName(testCaseName);
49 | }
50 |
51 | public TestCase() {
52 | }
53 |
54 | public void setName(String name) {
55 | mName = name;
56 | }
57 |
58 | public String getName() {
59 | return mName;
60 | }
61 |
62 | /**
63 | * Gets the child tests
64 | */
65 | public Collection getTests() {
66 | return mChildTestMap.values();
67 | }
68 |
69 | /**
70 | * @param testName
71 | * @param insertIfMissing
72 | * @return
73 | */
74 | public Test findTest(String testName, boolean insertIfMissing) {
75 | Test t = mChildTestMap.get(testName);
76 | if (t == null && insertIfMissing) {
77 | t = new Test(testName);
78 | mChildTestMap.put(t.getName(), t);
79 | }
80 | return t;
81 | }
82 |
83 | /**
84 | * Serialize this object and all its contents to XML.
85 | *
86 | * @param serializer
87 | * @throws IOException
88 | */
89 | public void serialize(KXmlSerializer serializer) throws IOException {
90 | serializer.startTag(CtsXmlResultReporter.ns, TAG);
91 | serializer.attribute(CtsXmlResultReporter.ns, "name", getName());
92 | // unused
93 | serializer.attribute(CtsXmlResultReporter.ns, "priority", "");
94 | for (Test t : mChildTestMap.values()) {
95 | t.serialize(serializer);
96 | }
97 | serializer.endTag(CtsXmlResultReporter.ns, TAG);
98 | }
99 |
100 | /**
101 | * Populates this class with test case result data parsed from XML.
102 | *
103 | * @param parser
104 | * the {@link XmlPullParser}. Expected to be pointing at start of
105 | * a TestCase tag
106 | */
107 | @Override
108 | public void parse(XmlPullParser parser) throws XmlPullParserException,
109 | IOException {
110 | if (!parser.getName().equals(TAG)) {
111 | throw new XmlPullParserException(String.format(
112 | "invalid XML: Expected %s tag but received %s", TAG,
113 | parser.getName()));
114 | }
115 | setName(getAttribute(parser, "name"));
116 | int eventType = parser.next();
117 | while (eventType != XmlPullParser.END_DOCUMENT) {
118 | if (eventType == XmlPullParser.START_TAG
119 | && parser.getName().equals(Test.TAG)) {
120 | Test test = new Test();
121 | test.parse(parser);
122 | mChildTestMap.put(test.getName(), test);
123 | } else if (eventType == XmlPullParser.END_TAG
124 | && parser.getName().equals(TAG)) {
125 | return;
126 | }
127 | eventType = parser.next();
128 | }
129 | }
130 |
131 | /**
132 | * Adds tests contained in this result that have the given
133 | * resultFilter.
134 | *
135 | * @param tests
136 | * the {@link Collection} of {@link TestIdentifier}s to add to
137 | * @param parentSuiteNames
138 | * a {@link Deque} of parent suite names. Used to construct the
139 | * full class name of the test
140 | * @param resultFilter
141 | * the {@link CtsTestStatus} to filter by
142 | */
143 | void addTestsWithStatus(Collection tests,
144 | Deque parentSuiteNames, CtsTestStatus resultFilter) {
145 | if (getName() != null) {
146 | parentSuiteNames.addLast(getName());
147 | }
148 | String fullClassName = ArrayUtil.join(".", parentSuiteNames);
149 | for (Test test : mChildTestMap.values()) {
150 | if (resultFilter.equals(test.getResult())) {
151 | tests.add(new TestIdentifier(fullClassName, test.getName()));
152 | }
153 | }
154 | if (getName() != null) {
155 | parentSuiteNames.removeLast();
156 | }
157 | }
158 |
159 | /**
160 | * Count the number of tests in this {@link TestCase} with given status.
161 | *
162 | * @param status
163 | * @return the test count
164 | */
165 | public int countTests(CtsTestStatus status) {
166 | int total = 0;
167 | for (Test test : mChildTestMap.values()) {
168 | if (test.getResult().equals(status)) {
169 | total++;
170 | }
171 | }
172 | return total;
173 | }
174 | }
175 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/result/TestResultRepo.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 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.cts.tradefed.result;
17 |
18 | import com.android.tradefed.log.LogUtil.CLog;
19 | import com.android.tradefed.util.xml.AbstractXmlParser.ParseException;
20 |
21 | import java.io.BufferedReader;
22 | import java.io.File;
23 | import java.io.FileFilter;
24 | import java.io.FileNotFoundException;
25 | import java.io.FileReader;
26 | import java.util.ArrayList;
27 | import java.util.Collections;
28 | import java.util.Comparator;
29 | import java.util.List;
30 |
31 | /**
32 | * An implementation of {@link ITestResultsRepo}.
33 | */
34 | public class TestResultRepo implements ITestResultRepo {
35 |
36 | /**
37 | * ordered list of result directories. the index of each file is its session id.
38 | */
39 | private List mResultDirs;
40 |
41 | /**
42 | * Create a {@link TestResultRepo} from a directory of results
43 | *
44 | * @param testResultsDir the parent directory of results
45 | */
46 | public TestResultRepo(File testResultsDir) {
47 | mResultDirs = new ArrayList();
48 | File[] resultArray = testResultsDir.listFiles(new ResultDirFilter());
49 | if (resultArray != null) {
50 | List resultList = new ArrayList();
51 | Collections.addAll(resultList, resultArray);
52 | Collections.sort(resultList, new FileComparator());
53 | for (int i=0; i < resultList.size(); i++) {
54 | File resultFile = new File(resultList.get(i),
55 | CtsXmlResultReporter.TEST_RESULT_FILE_NAME);
56 | if (resultFile.exists()) {
57 | mResultDirs.add(resultList.get(i));
58 | }
59 | }
60 | }
61 | }
62 |
63 | @Override
64 | public File getReportDir(int sessionId) {
65 | return mResultDirs.get(sessionId);
66 | }
67 |
68 | private ITestSummary parseSummary(int id, File resultDir) {
69 | TestSummaryXml result = new TestSummaryXml(id, resultDir.getName());
70 | try {
71 | result.parse(new BufferedReader(new FileReader(new File(resultDir,
72 | CtsXmlResultReporter.TEST_RESULT_FILE_NAME))));
73 | return result;
74 | } catch (ParseException e) {
75 | CLog.e(e);
76 | } catch (FileNotFoundException e) {
77 | // should never happen, since we check for file existence above. Barf the stack trace
78 | CLog.e(e);
79 | }
80 | return result;
81 | }
82 |
83 | /**
84 | * {@inheritDoc}
85 | */
86 | @Override
87 | public List getSummaries() {
88 | // parsing the summary data should be relatively quick, so just parse it every time
89 | // rather than caching it
90 | List summaries = new ArrayList(mResultDirs.size());
91 | for (int i = 0; i < mResultDirs.size(); i++) {
92 | summaries.add(parseSummary(i, mResultDirs.get(i)));
93 | }
94 | return summaries;
95 | }
96 |
97 | /**
98 | * {@inheritDoc}
99 | */
100 | @Override
101 | public TestResults getResult(int sessionId) {
102 | // TODO: consider caching the results in future
103 | if (mResultDirs.size() <= sessionId) {
104 | CLog.e("Session id %d does not exist", sessionId);
105 | return null;
106 | }
107 | try {
108 | TestResults results = new TestResults();
109 | File resultFile = new File(mResultDirs.get(sessionId),
110 | CtsXmlResultReporter.TEST_RESULT_FILE_NAME);
111 | results.parse(new BufferedReader(new FileReader(resultFile)));
112 | return results;
113 | } catch (FileNotFoundException e) {
114 | CLog.e("Could not find result file for session %d", sessionId);
115 | } catch (ParseException e) {
116 | CLog.e("Failed to parse result file for session %d", sessionId);
117 | }
118 | return null;
119 | }
120 |
121 | private class ResultDirFilter implements FileFilter {
122 |
123 | /**
124 | * {@inheritDoc}
125 | */
126 | @Override
127 | public boolean accept(File file) {
128 | return file.isDirectory();
129 | }
130 | }
131 |
132 | /**
133 | * A {@link Comparator} that compares {@link File}s by name.
134 | */
135 | private class FileComparator implements Comparator {
136 |
137 | /**
138 | * {@inheritDoc}
139 | */
140 | @Override
141 | public int compare(File file0, File file1) {
142 | return file0.getName().compareTo(file1.getName());
143 | }
144 | }
145 | }
146 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/result/TestSummaryXml.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 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.cts.tradefed.result;
17 |
18 | import com.android.tradefed.util.xml.AbstractXmlParser.ParseException;
19 |
20 | import org.xmlpull.v1.XmlPullParser;
21 | import org.xmlpull.v1.XmlPullParserException;
22 |
23 | import android.tests.getinfo.DeviceInfoConstants;
24 |
25 | import java.io.FileNotFoundException;
26 | import java.io.IOException;
27 |
28 | /**
29 | * A {@link ITestSummary} that parses summary data from the CTS result XML.
30 | */
31 | public class TestSummaryXml extends AbstractXmlPullParser implements ITestSummary {
32 |
33 | private final int mId;
34 | private final String mTimestamp;
35 | private int mNumFailed = 0;
36 | private int mNumNotExecuted = 0;
37 | private int mNumPassed = 0;
38 | private String mPlan = "NA";
39 | private String mStartTime = "unknown";
40 | private String mDeviceSerials = "unknown";
41 |
42 | /**
43 | * @param id
44 | * @param resultFile
45 | * @throws ParseException
46 | * @throws FileNotFoundException
47 | */
48 | public TestSummaryXml(int id, String timestamp) {
49 | mId = id;
50 | mTimestamp = timestamp;
51 | }
52 |
53 | /**
54 | * {@inheritDoc}
55 | */
56 | @Override
57 | public int getId() {
58 | return mId;
59 | }
60 |
61 | /**
62 | * {@inheritDoc}
63 | */
64 | @Override
65 | public String getTimestamp() {
66 | return mTimestamp;
67 | }
68 |
69 | /**
70 | * {@inheritDoc}
71 | */
72 | @Override
73 | public int getNumIncomplete() {
74 | return mNumNotExecuted;
75 | }
76 |
77 | /**
78 | * {@inheritDoc}
79 | */
80 | @Override
81 | public int getNumFailed() {
82 | return mNumFailed;
83 | }
84 |
85 | /**
86 | * {@inheritDoc}
87 | */
88 | @Override
89 | public int getNumPassed() {
90 | return mNumPassed;
91 | }
92 |
93 | /**
94 | * {@inheritDoc}
95 | */
96 | @Override
97 | public String getTestPlan() {
98 | return mPlan ;
99 | }
100 |
101 |
102 | @Override
103 | public
104 | void parse(XmlPullParser parser) throws XmlPullParserException, IOException {
105 | int eventType = parser.getEventType();
106 | while (eventType != XmlPullParser.END_DOCUMENT) {
107 | if (eventType == XmlPullParser.START_TAG && parser.getName().equals(
108 | CtsXmlResultReporter.RESULT_TAG)) {
109 | mPlan = getAttribute(parser, CtsXmlResultReporter.PLAN_ATTR);
110 | mStartTime = getAttribute(parser, CtsXmlResultReporter.STARTTIME_ATTR);
111 | } else if (eventType == XmlPullParser.START_TAG && parser.getName().equals(
112 | DeviceInfoResult.BUILD_TAG)) {
113 | mDeviceSerials = getAttribute(parser, DeviceInfoConstants.SERIAL_NUMBER);
114 | } else if (eventType == XmlPullParser.START_TAG && parser.getName().equals(
115 | TestResults.SUMMARY_TAG)) {
116 | mNumFailed = parseIntAttr(parser, TestResults.FAILED_ATTR) +
117 | parseIntAttr(parser, TestResults.TIMEOUT_ATTR);
118 | mNumNotExecuted = parseIntAttr(parser, TestResults.NOT_EXECUTED_ATTR);
119 | mNumPassed = parseIntAttr(parser, TestResults.PASS_ATTR);
120 | // abort after parsing Summary, which should be the last tag
121 | return;
122 | }
123 | eventType = parser.next();
124 | }
125 | throw new XmlPullParserException("Could not find Summary tag");
126 | }
127 |
128 | /**
129 | * {@inheritDoc}
130 | */
131 | @Override
132 | public String getStartTime() {
133 | return mStartTime;
134 | }
135 |
136 | /**
137 | * {@inheritDoc}
138 | */
139 | @Override
140 | public String getDeviceSerials() {
141 | return mDeviceSerials;
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/result/TimeUtil.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 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.cts.tradefed.result;
17 |
18 | import java.text.SimpleDateFormat;
19 | import java.util.Date;
20 | import java.util.concurrent.TimeUnit;
21 |
22 | /**
23 | * Utility class for formatting times as strings.
24 | */
25 | class TimeUtil {
26 |
27 | /**
28 | * Return a prettified version of the given elapsed time
29 | * @return
30 | */
31 | static String formatElapsedTime(long elapsedTimeMs) {
32 | long seconds = TimeUnit.MILLISECONDS.toSeconds(elapsedTimeMs) % 60;
33 | long minutes = TimeUnit.MILLISECONDS.toMinutes(elapsedTimeMs) % 60;
34 | long hours = TimeUnit.MILLISECONDS.toHours(elapsedTimeMs);
35 | StringBuilder time = new StringBuilder();
36 | if (hours > 0) {
37 | time.append(hours);
38 | time.append("h ");
39 | }
40 | if (minutes > 0) {
41 | time.append(minutes);
42 | time.append("m ");
43 | }
44 | time.append(seconds);
45 | time.append("s");
46 |
47 | return time.toString();
48 | }
49 |
50 | /**
51 | * Return the current timestamp as a {@link String} suitable for displaying.
52 | *
53 | * Example: Fri Aug 20 15:13:03 PDT 2010
54 | */
55 | static String getTimestamp() {
56 | return getTimestamp(System.currentTimeMillis());
57 | }
58 |
59 | /**
60 | * Return the given time as a {@link String} suitable for displaying.
61 | *
62 | * Example: Fri Aug 20 15:13:03 PDT 2010
63 | *
64 | * @param time the epoch time in ms since midnight Jan 1, 1970
65 | */
66 | static String getTimestamp(long time) {
67 | SimpleDateFormat dateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");
68 | return dateFormat.format(new Date(time));
69 | }
70 |
71 | /**
72 | * Return the current timestamp in a compressed format, used to uniquely identify results.
73 | *
74 | * Example: 2010.08.16_11.42.12
75 | */
76 | static String getResultTimestamp() {
77 | SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd_HH.mm.ss");
78 | return dateFormat.format(new Date());
79 | }
80 | private final static SimpleDateFormat TIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
81 | private final static SimpleDateFormat TIME_FORMAT_MSEC = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
82 | private final static SimpleDateFormat FILE_TIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
83 |
84 | // only static methods, don't allow construction
85 | private TimeUtil() {
86 | }
87 |
88 |
89 |
90 | /**
91 | * Return a readable formatted version of the given epoch time.
92 | *
93 | * @param epochTime the epoch time in milliseconds
94 | * @return a user readable string
95 | */
96 | public static String formatTimeStamp(long epochTime) {
97 | return TIME_FORMAT.format(new Date(epochTime));
98 | }
99 |
100 |
101 | public static String formatTimeStampMsec(long epochTime) {
102 | return TIME_FORMAT_MSEC.format(new Date(epochTime));
103 | }
104 |
105 | public static String getTimestampMsec() {
106 | return formatTimeStampMsec(System.currentTimeMillis());
107 | }
108 |
109 | public static String formatTimeForFile(long epochTime) {
110 | return FILE_TIME_FORMAT.format(new Date(epochTime));
111 | }
112 |
113 | public static String getTimestampForFile() {
114 | return formatTimeForFile(System.currentTimeMillis());
115 | }
116 |
117 |
118 | }
119 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/result/monkey/DragTag.java:
--------------------------------------------------------------------------------
1 | package com.android.cts.tradefed.result.monkey;
2 |
3 | import java.awt.Point;
4 | import java.io.IOException;
5 | import java.util.LinkedList;
6 | import java.util.List;
7 |
8 | import org.kxml2.io.KXmlSerializer;
9 | import org.xmlpull.v1.XmlPullParser;
10 | import org.xmlpull.v1.XmlPullParserException;
11 |
12 | import com.android.cts.tradefed.result.CtsXmlResultReporter;
13 |
14 | public class DragTag extends EventTag {
15 |
16 | public static final String DIRECTION_UP = "up";
17 | public static final String DIRECTION_DOWN = "down";
18 | public static final String DIRECTION_MOVE = "move";
19 |
20 | public List getTouches() {
21 | return touches;
22 | }
23 |
24 | public DragTag() {
25 | setType(EVENT_TYPE_DRAG);
26 | }
27 |
28 | private List touches = new LinkedList();
29 |
30 | @Override
31 | public void serialize(KXmlSerializer serializer, int index,int count)
32 | throws IOException {
33 | setIndex(index);
34 | setPos(count - 1 - index);
35 | // TODO Auto-generated method stub
36 | serializer.startTag(CtsXmlResultReporter.ns, EVENT_TAG);
37 | serializer.attribute(CtsXmlResultReporter.ns, INDEX_ATTR, getIndex()
38 | + "");
39 | serializer.attribute(CtsXmlResultReporter.ns, TYPE_ATTR, getType());
40 | serializer.attribute(CtsXmlResultReporter.ns, TIME_ATTR, getTime());
41 | serializer.attribute(CtsXmlResultReporter.ns, IMAGE_ATTR, getImage());
42 | serializer.attribute(CtsXmlResultReporter.ns, LOG_ATTR, getLog());
43 | serializer.attribute(CtsXmlResultReporter.ns, POS_ATTR, getPos() + "");
44 | for (TouchTag touchTag : touches) {
45 | touchTag.serialize(serializer);
46 | }
47 | serializer.endTag(CtsXmlResultReporter.ns, EVENT_TAG);
48 | }
49 |
50 | public void addTouchTag(TouchTag touchTag) {
51 | touches.add(touchTag);
52 | }
53 |
54 | public void addTouchUp(Point point) {
55 | TouchTag tag = new TouchTag();
56 | tag.setDirection(DIRECTION_UP);
57 | setXY(point, tag);
58 | }
59 |
60 | public void addTouchMove(Point point) {
61 | TouchTag tag = new TouchTag();
62 | tag.setDirection(DIRECTION_MOVE);
63 | setXY(point, tag);
64 | }
65 |
66 | public void addTouchDown(Point point) {
67 | TouchTag tag = new TouchTag();
68 | tag.setDirection(DIRECTION_DOWN);
69 | setXY(point, tag);
70 | }
71 |
72 | private void setXY(Point point, TouchTag tag) {
73 | tag.setX(point.x);
74 | tag.setY(point.y);
75 | touches.add(tag);
76 | }
77 |
78 | @Override
79 | public void parse(XmlPullParser parser) throws XmlPullParserException,
80 | IOException {
81 | if (!parser.getName().equals(EVENT_TAG)) {
82 | throw new XmlPullParserException(String.format(
83 | "invalid XML: Expected %s tag but received %s", EVENT_TAG,
84 | parser.getName()));
85 | }
86 | setIndex(Integer.parseInt(getAttribute(parser, INDEX_ATTR)));
87 | setImage(getAttribute(parser, IMAGE_ATTR));
88 | setLog(getAttribute(parser, LOG_ATTR));
89 | int eventType = parser.getEventType();
90 | while (eventType != XmlPullParser.END_DOCUMENT) {
91 | if (eventType == XmlPullParser.START_TAG
92 | && parser.getName().equals(TouchTag.TOUCH_TAG)) {
93 | TouchTag touchTag = new TouchTag();
94 | touchTag.parse(parser);
95 | touches.add(touchTag);
96 | } else if (eventType == XmlPullParser.END_TAG
97 | && parser.getName().equals(EVENT_TAG)) {
98 | return;
99 | }
100 |
101 | eventType = parser.next();
102 | }
103 | }
104 |
105 |
106 | }
107 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/result/monkey/EventTag.java:
--------------------------------------------------------------------------------
1 | package com.android.cts.tradefed.result.monkey;
2 |
3 | import java.io.IOException;
4 | import java.util.LinkedList;
5 | import java.util.List;
6 |
7 | import org.kxml2.io.KXmlSerializer;
8 |
9 | import com.android.cts.tradefed.result.AbstractXmlPullParser;
10 |
11 | public abstract class EventTag extends AbstractXmlPullParser {
12 | public String getTime() {
13 | return time;
14 | }
15 |
16 | public void setTime(String time) {
17 | this.time = time;
18 | }
19 |
20 | public int getPos() {
21 | return pos;
22 | }
23 |
24 | public void setPos(int pos) {
25 | this.pos = pos;
26 | }
27 |
28 | protected static final String EVENT_TAG = "Event";
29 | protected static final String INDEX_ATTR = "index";
30 | protected static final String TYPE_ATTR = "type";
31 | protected static final String TIME_ATTR = "time";
32 | protected static final String IMAGE_ATTR = "image";
33 | protected static final String LOG_ATTR = "log";
34 | protected static final String POS_ATTR = "pos";
35 |
36 | public static final String EVENT_TYPE_DRAG = "drag";
37 | public static final String EVENT_TYPE_TAP = "tap";
38 | public static final String EVENT_TYPE_KEY = "key";
39 | private int index = 0;
40 | private String type = "NA";
41 | private String time = "NA";
42 | private String image = "ss";
43 | private String log = "NA";
44 | private int pos = 0;
45 |
46 |
47 | public int getIndex() {
48 | return index;
49 | }
50 |
51 | /*
52 | * (non-Javadoc)
53 | *
54 | * @see com.android.cts.tradefed.result.monkey.Event#setIndex(int)
55 | */
56 | public void setIndex(int index) {
57 | this.index = index;
58 | }
59 |
60 | /*
61 | * (non-Javadoc)
62 | *
63 | * @see com.android.cts.tradefed.result.monkey.Event#getType()
64 | */
65 | public String getType() {
66 | return type;
67 | }
68 |
69 | /*
70 | * (non-Javadoc)
71 | *
72 | * @see
73 | * com.android.cts.tradefed.result.monkey.Event#setType(java.lang.String)
74 | */
75 |
76 | public void setType(String type) {
77 | this.type = type;
78 | }
79 |
80 | /*
81 | * (non-Javadoc)
82 | *
83 | * @see com.android.cts.tradefed.result.monkey.Event#getImage()
84 | */
85 |
86 | public String getImage() {
87 | return image;
88 | }
89 |
90 | /*
91 | * (non-Javadoc)
92 | *
93 | * @see
94 | * com.android.cts.tradefed.result.monkey.Event#setImage(java.lang.String)
95 | */
96 |
97 | public void setImage(String image) {
98 | this.image = image;
99 | }
100 |
101 | /*
102 | * (non-Javadoc)
103 | *
104 | * @see com.android.cts.tradefed.result.monkey.Event#getLog()
105 | */
106 |
107 | public String getLog() {
108 | return log;
109 | }
110 |
111 | /*
112 | * (non-Javadoc)
113 | *
114 | * @see
115 | * com.android.cts.tradefed.result.monkey.Event#setLog(java.lang.String)
116 | */
117 |
118 | public void setLog(String log) {
119 | this.log = log;
120 | }
121 |
122 | /*
123 | * (non-Javadoc)
124 | *
125 | * @see com.android.cts.tradefed.result.monkey.Event#serialize(org.kxml2.io.
126 | * KXmlSerializer, int)
127 | */
128 |
129 | public abstract void serialize(KXmlSerializer serializer, int index,int count)
130 | throws IOException;
131 |
132 | }
133 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/result/monkey/KeyTag.java:
--------------------------------------------------------------------------------
1 | package com.android.cts.tradefed.result.monkey;
2 |
3 | import java.io.IOException;
4 |
5 | import org.kxml2.io.KXmlSerializer;
6 | import org.xmlpull.v1.XmlPullParser;
7 | import org.xmlpull.v1.XmlPullParserException;
8 |
9 | import sun.awt.SunHints.Value;
10 |
11 | import com.android.cts.tradefed.result.CtsXmlResultReporter;
12 |
13 | public class KeyTag extends EventTag {
14 |
15 | private static final String VALUE_ATTR = "value";
16 |
17 | private String value = "NA";
18 |
19 | public KeyTag() {
20 | setType(EVENT_TYPE_KEY);
21 | }
22 |
23 | public String getValue() {
24 | return value;
25 | }
26 |
27 | public void setValue(String value) {
28 | this.value = value;
29 | }
30 |
31 | @Override
32 | public void serialize(KXmlSerializer serializer, int index, int count)
33 | throws IOException {
34 | setIndex(index);
35 | setPos(count - 1 - index);
36 | serializer.startTag(CtsXmlResultReporter.ns, EVENT_TAG);
37 | serializer.attribute(CtsXmlResultReporter.ns, INDEX_ATTR, getIndex()
38 | + "");
39 | serializer.attribute(CtsXmlResultReporter.ns, TYPE_ATTR, getType());
40 |
41 | serializer.attribute(CtsXmlResultReporter.ns, VALUE_ATTR, getValue());
42 | serializer.attribute(CtsXmlResultReporter.ns, TIME_ATTR, getTime());
43 | serializer.attribute(CtsXmlResultReporter.ns, IMAGE_ATTR, getImage());
44 | serializer.attribute(CtsXmlResultReporter.ns, LOG_ATTR, getLog());
45 | serializer.attribute(CtsXmlResultReporter.ns, POS_ATTR, getPos() + "");
46 | serializer.endTag(CtsXmlResultReporter.ns, EVENT_TAG);
47 |
48 | }
49 |
50 | @Override
51 | public void parse(XmlPullParser parser) throws XmlPullParserException,
52 | IOException {
53 | if (!parser.getName().equals(EVENT_TAG)) {
54 | throw new XmlPullParserException(String.format(
55 | "invalid XML: Expected %s tag but received %s", EVENT_TAG,
56 | parser.getName()));
57 | }
58 | setValue(getAttribute(parser, VALUE_ATTR));
59 | setIndex(Integer.parseInt(getAttribute(parser, INDEX_ATTR)));
60 | setImage(getAttribute(parser, IMAGE_ATTR));
61 | setLog(getAttribute(parser, LOG_ATTR));
62 | }
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/result/monkey/MonkeyTestTag.java:
--------------------------------------------------------------------------------
1 | package com.android.cts.tradefed.result.monkey;
2 |
3 | import java.io.IOException;
4 | import java.util.LinkedList;
5 | import java.util.List;
6 |
7 | import org.kxml2.io.KXmlSerializer;
8 | import org.xmlpull.v1.XmlPullParser;
9 | import org.xmlpull.v1.XmlPullParserException;
10 |
11 | import com.android.cts.tradefed.result.AbstractXmlPullParser;
12 | import com.android.cts.tradefed.result.CtsXmlResultReporter;
13 |
14 | public class MonkeyTestTag extends AbstractXmlPullParser {
15 |
16 | public String getFinalLog() {
17 | return finalLog;
18 | }
19 |
20 | public void setFinalLog(String finalLog) {
21 | this.finalLog = finalLog;
22 | }
23 |
24 | public String getFinalPng() {
25 | return finalPng;
26 | }
27 |
28 | public void setFinalPng(String finalPng) {
29 | this.finalPng = finalPng;
30 | }
31 |
32 | public int getCount() {
33 | return count;
34 | }
35 |
36 | public void setCount(int count) {
37 | this.count = count;
38 | }
39 |
40 | public String getApplication() {
41 | return application;
42 | }
43 |
44 | public void setApplication(String application) {
45 | this.application = application;
46 | }
47 |
48 | public String getResult() {
49 | return result;
50 | }
51 |
52 | public void setResult(String result) {
53 | this.result = result;
54 | }
55 |
56 | public List getEvents() {
57 | return events;
58 | }
59 |
60 | public void setEvents(List events) {
61 | this.events = events;
62 | }
63 |
64 | private static final String MONKEY_TEST_TAG = "MonkeyTest";
65 | private static final String APPLICATION_ATTR = "application";
66 | private static final String RESULT_ATTR = "result";
67 | private static final String EVENT_COUNT_ATTR = "count";
68 | private static final String FINALPNG_ATT = "final";
69 | private static final String FINALLOG_ATT = "log";
70 | private List events = new LinkedList();
71 | private EventTag currentTag = null;
72 |
73 | private String application = "NA";
74 | private String result = "NA";
75 | private int count = 0;
76 | private String finalPng = "NA";
77 | private String finalLog = "NA";
78 |
79 | public void addEvent(EventTag event) {
80 | events.add(event);
81 | currentTag = event;
82 | }
83 |
84 | public void serialize(KXmlSerializer serializer) throws IOException {
85 | serializer.startTag(CtsXmlResultReporter.ns, MONKEY_TEST_TAG);
86 | serializer.attribute(CtsXmlResultReporter.ns, APPLICATION_ATTR,
87 | getApplication());
88 | serializer.attribute(CtsXmlResultReporter.ns, EVENT_COUNT_ATTR,
89 | getCount() + "");
90 | serializer.attribute(CtsXmlResultReporter.ns, RESULT_ATTR, getResult());
91 | serializer.attribute(CtsXmlResultReporter.ns, FINALPNG_ATT,
92 | getFinalPng());
93 | serializer.attribute(CtsXmlResultReporter.ns, FINALLOG_ATT,
94 | getFinalLog());
95 | for (int i = events.size() - 1; i >= 0; i--) {
96 | events.get(i).serialize(serializer, i, count);
97 | }
98 | serializer.endTag(CtsXmlResultReporter.ns, MONKEY_TEST_TAG);
99 | }
100 |
101 | public EventTag getCurrentTag() {
102 | return currentTag;
103 | }
104 |
105 | public void setCurrentTag(EventTag currentTag) {
106 | this.currentTag = currentTag;
107 | }
108 |
109 | @Override
110 | public void parse(XmlPullParser parser) throws XmlPullParserException,
111 | IOException {
112 | int eventType = parser.getEventType();
113 | while (eventType != XmlPullParser.END_DOCUMENT) {
114 | if (eventType == XmlPullParser.START_TAG
115 | && parser.getName().equals(EventTag.EVENT_TAG)) {
116 | String type = getAttribute(parser, EventTag.TYPE_ATTR);
117 | if (EventTag.EVENT_TYPE_DRAG.equals(type)) {
118 | DragTag dragTag = new DragTag();
119 | dragTag.parse(parser);
120 | events.add(dragTag);
121 | } else if (EventTag.EVENT_TYPE_KEY.equals(type)) {
122 | KeyTag keyTag = new KeyTag();
123 | keyTag.parse(parser);
124 | events.add(keyTag);
125 | } else if (EventTag.EVENT_TYPE_TAP.equals(type)) {
126 | TapTag tapTag = new TapTag();
127 | tapTag.parse(parser);
128 | events.add(tapTag);
129 | }
130 | if (events.size() >= 50)
131 | return;
132 | }
133 | eventType = parser.next();
134 | }
135 |
136 | }
137 |
138 | }
139 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/result/monkey/MotionTag.java:
--------------------------------------------------------------------------------
1 | package com.android.cts.tradefed.result.monkey;
2 |
3 | import java.awt.Point;
4 | import java.io.IOException;
5 | import java.util.LinkedList;
6 | import java.util.List;
7 |
8 | import org.kxml2.io.KXmlSerializer;
9 | import org.xmlpull.v1.XmlPullParser;
10 | import org.xmlpull.v1.XmlPullParserException;
11 |
12 | import com.android.cts.tradefed.result.CtsXmlResultReporter;
13 |
14 | public class MotionTag extends EventTag {
15 |
16 | public static final String DIRECTION_UP = "up";
17 | public static final String DIRECTION_DOWN = "down";
18 | public static final String DIRECTION_MOVE = "move";
19 |
20 | public List getTouches() {
21 | return touches;
22 | }
23 |
24 | public MotionTag() {
25 | setType(EVENT_TYPE_DRAG);
26 | }
27 |
28 | private List touches = new LinkedList();
29 |
30 | @Override
31 | public void serialize(KXmlSerializer serializer, int index,int count)
32 | throws IOException {
33 | setIndex(index);
34 | setPos(count - 1 - index);
35 | // TODO Auto-generated method stub
36 | serializer.startTag(CtsXmlResultReporter.ns, EVENT_TAG);
37 | serializer.attribute(CtsXmlResultReporter.ns, INDEX_ATTR, getIndex()
38 | + "");
39 | serializer.attribute(CtsXmlResultReporter.ns, TYPE_ATTR, getType());
40 | serializer.attribute(CtsXmlResultReporter.ns, IMAGE_ATTR, getImage());
41 | serializer.attribute(CtsXmlResultReporter.ns, LOG_ATTR, getLog());
42 | serializer.attribute(CtsXmlResultReporter.ns, POS_ATTR, getPos() + "");
43 | for (TouchTag touchTag : touches) {
44 | touchTag.serialize(serializer);
45 | }
46 | serializer.endTag(CtsXmlResultReporter.ns, EVENT_TAG);
47 | }
48 |
49 | public void addTouchTag(TouchTag touchTag) {
50 | touches.add(touchTag);
51 | }
52 |
53 | public void addTouchUp(Point point) {
54 | TouchTag tag = new TouchTag();
55 | tag.setDirection(DIRECTION_UP);
56 | setXY(point, tag);
57 | }
58 |
59 | public void addTouchMove(Point point) {
60 | TouchTag tag = new TouchTag();
61 | tag.setDirection(DIRECTION_MOVE);
62 | setXY(point, tag);
63 | }
64 |
65 | public void addTouchDown(Point point) {
66 | TouchTag tag = new TouchTag();
67 | tag.setDirection(DIRECTION_DOWN);
68 | setXY(point, tag);
69 | }
70 |
71 | private void setXY(Point point, TouchTag tag) {
72 | tag.setX(point.x);
73 | tag.setY(point.y);
74 | touches.add(tag);
75 | }
76 |
77 | @Override
78 | public void parse(XmlPullParser parser) throws XmlPullParserException,
79 | IOException {
80 | if (!parser.getName().equals(EVENT_TAG)) {
81 | throw new XmlPullParserException(String.format(
82 | "invalid XML: Expected %s tag but received %s", EVENT_TAG,
83 | parser.getName()));
84 | }
85 | setIndex(Integer.parseInt(getAttribute(parser, INDEX_ATTR)));
86 | setImage(getAttribute(parser, IMAGE_ATTR));
87 | setLog(getAttribute(parser, LOG_ATTR));
88 | int eventType = parser.getEventType();
89 | while (eventType != XmlPullParser.END_DOCUMENT) {
90 | if (eventType == XmlPullParser.START_TAG
91 | && parser.getName().equals(TouchTag.TOUCH_TAG)) {
92 | TouchTag touchTag = new TouchTag();
93 | touchTag.parse(parser);
94 | touches.add(touchTag);
95 | } else if (eventType == XmlPullParser.END_TAG
96 | && parser.getName().equals(EVENT_TAG)) {
97 | return;
98 | }
99 |
100 | eventType = parser.next();
101 | }
102 | }
103 |
104 |
105 | }
106 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/result/monkey/TapTag.java:
--------------------------------------------------------------------------------
1 | package com.android.cts.tradefed.result.monkey;
2 |
3 | import java.io.IOException;
4 |
5 | import org.kxml2.io.KXmlSerializer;
6 | import org.xmlpull.v1.XmlPullParser;
7 | import org.xmlpull.v1.XmlPullParserException;
8 |
9 | import com.android.cts.tradefed.result.CtsXmlResultReporter;
10 |
11 | public class TapTag extends EventTag {
12 |
13 | public TapTag() {
14 | setType(EVENT_TYPE_TAP);
15 | }
16 |
17 | public float getX() {
18 | return x;
19 | }
20 |
21 | public void setX(float x) {
22 | this.x = x;
23 | }
24 |
25 | public float getY() {
26 | return y;
27 | }
28 |
29 | public void setY(float y) {
30 | this.y = y;
31 | }
32 |
33 | private static final String X_ATTR = "x";
34 | private static final String Y_ATTR = "y";
35 |
36 | private float x = 0;
37 | private float y = 0;
38 |
39 | @Override
40 | public void serialize(KXmlSerializer serializer, int index, int count)
41 | throws IOException {
42 | setIndex(index);
43 | setPos(count - 1 - index);
44 | // TODO Auto-generated method stub
45 | serializer.startTag(CtsXmlResultReporter.ns, EVENT_TAG);
46 | serializer.attribute(CtsXmlResultReporter.ns, INDEX_ATTR, getIndex()
47 | + "");
48 | serializer.attribute(CtsXmlResultReporter.ns, TYPE_ATTR, getType());
49 |
50 | serializer.attribute(CtsXmlResultReporter.ns, X_ATTR, getX() + "");
51 | serializer.attribute(CtsXmlResultReporter.ns, Y_ATTR, getY() + "");
52 | serializer.attribute(CtsXmlResultReporter.ns, TIME_ATTR, getTime());
53 | serializer.attribute(CtsXmlResultReporter.ns, IMAGE_ATTR, getImage());
54 | serializer.attribute(CtsXmlResultReporter.ns, LOG_ATTR, getLog());
55 | serializer.attribute(CtsXmlResultReporter.ns, POS_ATTR, getPos() + "");
56 | serializer.endTag(CtsXmlResultReporter.ns, EVENT_TAG);
57 |
58 | }
59 |
60 | @Override
61 | public void parse(XmlPullParser parser) throws XmlPullParserException,
62 | IOException {
63 | if (!parser.getName().equals(EVENT_TAG)) {
64 | throw new XmlPullParserException(String.format(
65 | "invalid XML: Expected %s tag but received %s", EVENT_TAG,
66 | parser.getName()));
67 | }
68 | setIndex(Integer.parseInt(getAttribute(parser, INDEX_ATTR)));
69 | setImage(getAttribute(parser, IMAGE_ATTR));
70 | setLog(getAttribute(parser, LOG_ATTR));
71 | setX(Float.parseFloat(getAttribute(parser, X_ATTR)));
72 | setY(Float.parseFloat(getAttribute(parser, Y_ATTR)));
73 | }
74 |
75 | }
76 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/result/monkey/TouchTag.java:
--------------------------------------------------------------------------------
1 | package com.android.cts.tradefed.result.monkey;
2 |
3 | import java.io.IOException;
4 |
5 | import org.kxml2.io.KXmlSerializer;
6 | import org.xmlpull.v1.XmlPullParser;
7 | import org.xmlpull.v1.XmlPullParserException;
8 |
9 | import com.android.cts.tradefed.result.AbstractXmlPullParser;
10 | import com.android.cts.tradefed.result.CtsXmlResultReporter;
11 |
12 | public class TouchTag extends AbstractXmlPullParser {
13 | public static final String TOUCH_TAG = "Touch";
14 | private static final String DIRECTION_ATTR = "direction";
15 | private static final String X_ATTR = "x";
16 | private static final String Y_ATTR = "y";
17 | private String direction = "NA";
18 | private int x = 0;
19 | private int y = 0;
20 |
21 | public String getDirection() {
22 | return direction;
23 | }
24 |
25 | public void setDirection(String direction) {
26 | this.direction = direction;
27 | }
28 |
29 | public int getX() {
30 | return x;
31 | }
32 |
33 | public void setX(int x) {
34 | this.x = x;
35 | }
36 |
37 | public int getY() {
38 | return y;
39 | }
40 |
41 | public void setY(int y) {
42 | this.y = y;
43 | }
44 |
45 | public void serialize(KXmlSerializer serializer) throws IOException {
46 | serializer.startTag(CtsXmlResultReporter.ns, TOUCH_TAG);
47 | serializer.attribute(CtsXmlResultReporter.ns, DIRECTION_ATTR,
48 | getDirection());
49 | serializer.attribute(CtsXmlResultReporter.ns, X_ATTR, getX() + "");
50 | serializer.attribute(CtsXmlResultReporter.ns, Y_ATTR, getY() + "");
51 | serializer.endTag(CtsXmlResultReporter.ns, TOUCH_TAG);
52 |
53 | }
54 |
55 | @Override
56 | public void parse(XmlPullParser parser) throws XmlPullParserException,
57 | IOException {
58 | if (!parser.getName().equals(TOUCH_TAG)) {
59 | throw new XmlPullParserException(String.format(
60 | "invalid XML: Expected %s tag but received %s", TOUCH_TAG,
61 | parser.getName()));
62 | }
63 |
64 | setDirection(getAttribute(parser, DIRECTION_ATTR));
65 | setX(Integer.parseInt(getAttribute(parser, X_ATTR)));
66 | setY(Integer.parseInt(getAttribute(parser, Y_ATTR)));
67 | }
68 |
69 | }
70 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/targetprep/CtsRootDeviceSetup.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2010 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.cts.tradefed.targetprep;
17 |
18 | import com.android.cts.tradefed.build.CtsBuildHelper;
19 | import com.android.tradefed.build.IBuildInfo;
20 | import com.android.tradefed.build.IFolderBuildInfo;
21 | import com.android.tradefed.device.DeviceNotAvailableException;
22 | import com.android.tradefed.device.ITestDevice;
23 | import com.android.tradefed.log.LogUtil.CLog;
24 | import com.android.tradefed.targetprep.DeviceSetup;
25 | import com.android.tradefed.targetprep.ITargetPreparer;
26 | import com.android.tradefed.targetprep.TargetSetupError;
27 |
28 | import java.io.FileNotFoundException;
29 |
30 | /**
31 | * A {@link ITargetPreparer} that attempts to automatically perform the CTS-specific manual steps
32 | * for setting up a device for CTS testing.
33 | *
34 | * This class is NOT intended for 'official' CTS runs against a production device as the steps
35 | * performed by this class require a debug build (aka 'adb root' must succeed).
36 | *
37 | * This class currently performs the 'Allow mock locations' and 'accessibililty setup' steps
38 | * documented in the CTS user manual. It is intended to be used in conjunction with
39 | * a {@link DeviceSetup} which will enable the 'Stay Awake' setting and verify that external
40 | * storage is present.
41 | */
42 | public class CtsRootDeviceSetup implements ITargetPreparer {
43 |
44 | private static final String DEVICE_ADMIN_APK_FILE_NAME = "CtsDeviceAdmin.apk";
45 |
46 | /**
47 | * {@inheritDoc}
48 | */
49 | @Override
50 | public void setUp(ITestDevice device, IBuildInfo buildInfo) throws TargetSetupError,
51 | DeviceNotAvailableException {
52 | if (!(buildInfo instanceof IFolderBuildInfo)) {
53 | throw new IllegalArgumentException("Provided buildInfo is not a IFolderBuildInfo");
54 | }
55 | CLog.i("Setting up %s to run CTS tests", device.getSerialNumber());
56 |
57 | IFolderBuildInfo ctsBuild = (IFolderBuildInfo)buildInfo;
58 | try {
59 | CtsBuildHelper buildHelper = new CtsBuildHelper(ctsBuild.getRootDir());
60 |
61 | if (!device.enableAdbRoot()) {
62 | throw new TargetSetupError(String.format(
63 | "Failed to set root on device %s.", device.getSerialNumber()));
64 | }
65 |
66 | // perform CTS setup steps that only work if adb is root
67 | SettingsToggler.setSecureInt(device, "mock_location", 1);
68 | enableDeviceAdmin(device, buildHelper);
69 | // This is chrome specific setting to disable the first screen.
70 | // For other browser, it will not do anything.
71 | device.executeShellCommand(
72 | "echo \"chrome --disable-fre\" > /data/local/chrome-command-line");
73 | // end root setup steps
74 | } catch (FileNotFoundException e) {
75 | throw new TargetSetupError("Invalid CTS installation", e);
76 | }
77 | }
78 |
79 | private void enableDeviceAdmin(ITestDevice device, CtsBuildHelper ctsBuild)
80 | throws DeviceNotAvailableException, TargetSetupError, FileNotFoundException {
81 | String errorCode = device.installPackage(ctsBuild.getTestApp(DEVICE_ADMIN_APK_FILE_NAME),
82 | true);
83 | if (errorCode != null) {
84 | // TODO: retry ?
85 | throw new TargetSetupError(String.format(
86 | "Failed to install %s on device %s. Reason: %s",
87 | DEVICE_ADMIN_APK_FILE_NAME, device.getSerialNumber(), errorCode));
88 | }
89 | // TODO: enable device admin Settings
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/targetprep/SettingsToggler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2012 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.cts.tradefed.targetprep;
17 |
18 | import com.android.tradefed.device.DeviceNotAvailableException;
19 | import com.android.tradefed.device.ITestDevice;
20 |
21 | /**
22 | * {@link SettingsToggler} sets settings by using the "adb shell content" command.
23 | */
24 | public class SettingsToggler {
25 | private static final String GROUP_SECURE = "secure";
26 | private static final String GROUP_GLOBAL = "global";
27 |
28 | /** Sets a setting by deleting and then inserting the string value. */
29 | public static void setString(ITestDevice device, String group, String name, String value)
30 | throws DeviceNotAvailableException {
31 | deleteSetting(device, group, name);
32 | device.executeShellCommand(
33 | "content insert"
34 | + " --uri content://settings/" + group
35 | + " --bind name:s:" + name
36 | + " --bind value:s:" + value);
37 | }
38 |
39 | /** Sets a secure setting by deleting and then inserting the string value. */
40 | public static void setSecureString(ITestDevice device, String name, String value)
41 | throws DeviceNotAvailableException {
42 | setString(device, GROUP_SECURE, name, value);
43 | }
44 |
45 | /** Sets a global setting by deleting and then inserting the string value. */
46 | public static void setGlobalString(ITestDevice device, String name, String value)
47 | throws DeviceNotAvailableException {
48 | setString(device, GROUP_GLOBAL, name, value);
49 | }
50 |
51 | /** Sets a setting by deleting and then inserting the int value. */
52 | public static void setInt(ITestDevice device, String group, String name, int value)
53 | throws DeviceNotAvailableException {
54 | deleteSetting(device, group, name);
55 | device.executeShellCommand(
56 | "content insert"
57 | + " --uri content://settings/" + group
58 | + " --bind name:s:" + name
59 | + " --bind value:i:" + value);
60 | }
61 |
62 | /** Sets a secure setting by deleting and then inserting the int value. */
63 | public static void setSecureInt(ITestDevice device, String name, int value)
64 | throws DeviceNotAvailableException {
65 | setInt(device, GROUP_SECURE, name, value);
66 | }
67 |
68 | /** Sets a global setting by deleting and then inserting the int value. */
69 | public static void setGlobalInt(ITestDevice device, String name, int value)
70 | throws DeviceNotAvailableException {
71 | setInt(device, GROUP_GLOBAL, name, value);
72 | }
73 |
74 | public static void updateString(ITestDevice device, String group, String name, String value)
75 | throws DeviceNotAvailableException {
76 | device.executeShellCommand(
77 | "content update"
78 | + " --uri content://settings/" + group
79 | + " --bind value:s:" + value
80 | + " --where \"name='" + name + "'\"");
81 | }
82 |
83 | public static void updateSecureString(ITestDevice device, String name, String value)
84 | throws DeviceNotAvailableException {
85 | updateString(device, GROUP_SECURE, name, value);
86 | }
87 |
88 | public static void updateGlobalString(ITestDevice device, String name, String value)
89 | throws DeviceNotAvailableException {
90 | updateString(device, GROUP_GLOBAL, name, value);
91 | }
92 |
93 | public static void updateInt(ITestDevice device, String group, String name, int value)
94 | throws DeviceNotAvailableException {
95 | device.executeShellCommand(
96 | "content update"
97 | + " --uri content://settings/" + group
98 | + " --bind value:i:" + value
99 | + " --where \"name='" + name + "'\"");
100 | }
101 |
102 | public static void updateSecureInt(ITestDevice device, String name, int value)
103 | throws DeviceNotAvailableException {
104 | updateInt(device, GROUP_SECURE, name, value);
105 | }
106 |
107 | public static void updateGlobalInt(ITestDevice device, String name, int value)
108 | throws DeviceNotAvailableException {
109 | updateInt(device, GROUP_GLOBAL, name, value);
110 | }
111 |
112 | private static void deleteSetting(ITestDevice device, String group, String name)
113 | throws DeviceNotAvailableException {
114 | device.executeShellCommand(
115 | "content delete"
116 | + " --uri content://settings/" + group
117 | + " --where \"name='" + name + "'\"");
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/test/Test.java:
--------------------------------------------------------------------------------
1 | package com.android.cts.tradefed.test;
2 |
3 | import java.awt.Color;
4 | import java.awt.Font;
5 | import java.io.File;
6 | import java.io.IOException;
7 |
8 | import pl.vgtworld.imagedraw.processing.ImageProcessing;
9 |
10 | import com.android.cts.tradefed.result.MonkeyReporter;
11 |
12 | import junit.framework.TestCase;
13 |
14 | public class Test extends TestCase {
15 |
16 | public void test_MonkeyReporter() throws IOException {
17 |
18 | MonkeyReporter reporter = new MonkeyReporter(
19 | new File(
20 | "/Users/wuxian/Downloads/android-cts/repository/results/2015.05.27_18.23.30/testResult.xml"), null);
21 | reporter.drawImage();
22 | // reporter.createReporter();
23 | // reporter.transferToHtml("/Users/wuxian/Downloads/android-cts/repository/results/2015.05.27_10.56.35/report/index.xsl",
24 | // "/Users/wuxian/Downloads/android-cts/repository/results/2015.05.27_10.56.35/testResult.xml",
25 | // "/Users/wuxian/Downloads/android-cts/repository/results/2015.05.27_10.56.35/report/index.html");
26 | // reporter.transferToHtml("/Users/wuxian/Downloads/android-cts/repository/results/2015.05.27_10.56.35/report/result.xsl",
27 | // "/Users/wuxian/Downloads/android-cts/repository/results/2015.05.27_10.56.35/testResult.xml",
28 | // "/Users/wuxian/Downloads/android-cts/repository/results/2015.05.27_10.56.35/report/result.html");
29 | }
30 |
31 | public void test_MonkeyReporter1() {
32 |
33 | MonkeyReporter reporter = new MonkeyReporter(
34 | new File(
35 | "/Users/wuxian/Downloads/android-cts/repository/results/2015.05.26_11.14.34/testResult.xml"),
36 | new File("/Users/wuxian/Desktop/index"), null);
37 | }
38 |
39 | public void test_File() throws IOException {
40 | ImageProcessing image = new ImageProcessing();
41 | File imageFile = new File("/Users/wuxian/Desktop/123.png");
42 | image.open(imageFile);
43 | image.drawText("Helloworld1", Color.RED, new Font("SansSerif",
44 | Font.BOLD, 40), 0, 50);
45 | image.save(imageFile);
46 | }
47 |
48 | public void test_math() {
49 | int count = (int)Float.parseFloat("48.0");
50 | System.out.println(count);
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/testtype/AccessibilityServiceTestRunner.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2012 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.cts.tradefed.testtype;
18 |
19 | import com.android.cts.tradefed.build.CtsBuildHelper;
20 | import com.android.tradefed.build.IBuildInfo;
21 | import com.android.tradefed.device.DeviceNotAvailableException;
22 | import com.android.tradefed.result.ITestInvocationListener;
23 | import com.android.tradefed.util.FileUtil;
24 |
25 | import junit.framework.TestCase;
26 |
27 | import java.io.File;
28 |
29 | /**
30 | * Running the accessibility tests requires modification of secure
31 | * settings. Secure settings cannot be changed from device CTS tests
32 | * since system signature permission is required. Such settings can
33 | * be modified by the shell user, so a host side test is used for
34 | * installing a package with a delegating accessibility service, enabling
35 | * this service, running these tests, disabling the service, and removing
36 | * the delegating accessibility service package.
37 | *
38 | * @deprecated This class is not required in current CTS builds. Still
39 | * maintained so cts-tradefed can run against older CTS builds that still
40 | * require this class.
41 | */
42 | public class AccessibilityServiceTestRunner extends InstrumentationApkTest {
43 |
44 | private static final String DELEGATING_ACCESSIBLITY_SERVICE_PACKAGE_NAME =
45 | "android.accessibilityservice.delegate";
46 |
47 | private static final String DELEGATING_ACCESSIBLITY_SERVICE_NAME =
48 | "android.accessibilityservice.delegate.DelegatingAccessibilityService";
49 |
50 | private static final String DELEGATING_ACCESSIBLITY_SERVICE_APK =
51 | "CtsDelegatingAccessibilityService.apk";
52 |
53 | private CtsBuildHelper mCtsBuild;
54 |
55 | @Override
56 | public void setBuild(IBuildInfo build) {
57 | super.setBuild(build);
58 | mCtsBuild = CtsBuildHelper.createBuildHelper(build);
59 | }
60 |
61 | @Override
62 | public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
63 | beforeTest();
64 | super.run(listener);
65 | afterTest();
66 | }
67 |
68 | private void beforeTest() throws DeviceNotAvailableException {
69 | installApkAndAssert(DELEGATING_ACCESSIBLITY_SERVICE_APK);
70 | enableAccessibilityAndDelegatingService();
71 | }
72 |
73 | private void afterTest() throws DeviceNotAvailableException {
74 | AccessibilityTestRunner.disableAccessibilityAndServices(getDevice());
75 | uninstallAndAssert(DELEGATING_ACCESSIBLITY_SERVICE_PACKAGE_NAME);
76 | }
77 |
78 | private void installApkAndAssert(String apkName) throws DeviceNotAvailableException {
79 | File file = FileUtil.getFileForPath(mCtsBuild.getTestCasesDir(), apkName);
80 | String errorMessage = getDevice().installPackage(file, true);
81 | TestCase.assertNull("Error installing: " + apkName, errorMessage);
82 | }
83 |
84 | private void uninstallAndAssert(String packageName) throws DeviceNotAvailableException {
85 | String errorMessage = getDevice().uninstallPackage(packageName);
86 | TestCase.assertNull("Error uninstalling: " + packageName, errorMessage);
87 | }
88 |
89 | private void enableAccessibilityAndDelegatingService() throws DeviceNotAvailableException {
90 | String componentName = DELEGATING_ACCESSIBLITY_SERVICE_PACKAGE_NAME + "/"
91 | + DELEGATING_ACCESSIBLITY_SERVICE_NAME;
92 | AccessibilityTestRunner.enableAccessibilityAndServices(getDevice(),
93 | componentName);
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/testtype/AccessibilityTestRunner.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2012 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.cts.tradefed.testtype;
18 |
19 | import com.android.cts.tradefed.build.CtsBuildHelper;
20 | import com.android.cts.tradefed.targetprep.SettingsToggler;
21 | import com.android.tradefed.build.IBuildInfo;
22 | import com.android.tradefed.device.DeviceNotAvailableException;
23 | import com.android.tradefed.device.ITestDevice;
24 | import com.android.tradefed.result.ITestInvocationListener;
25 | import com.android.tradefed.util.FileUtil;
26 |
27 | import junit.framework.TestCase;
28 |
29 | import java.io.File;
30 |
31 | /**
32 | * Running the accessibility tests requires modification of secure
33 | * settings. Secure settings cannot be changed from device CTS tests
34 | * since system signature permission is required. Such settings can
35 | * be modified by the shell user, so a host side test is used for
36 | * installing a package with some accessibility services, enabling
37 | * these services, running the tests, disabling the services, and removing
38 | * the accessibility services package.
39 | */
40 | public class AccessibilityTestRunner extends InstrumentationApkTest {
41 |
42 | private static final String SOME_ACCESSIBLITY_SERVICES_PACKAGE_NAME =
43 | "android.view.accessibility.services";
44 |
45 | private static final String SPEAKING_ACCESSIBLITY_SERVICE_NAME =
46 | "android.view.accessibility.services.SpeakingAccessibilityService";
47 |
48 | private static final String VIBRATING_ACCESSIBLITY_SERVICE_NAME =
49 | "android.view.accessibility.services.VibratingAccessibilityService";
50 |
51 | private static final String SOME_ACCESSIBLITY_SERVICES_APK =
52 | "CtsSomeAccessibilityServices.apk";
53 |
54 | private CtsBuildHelper mCtsBuild;
55 |
56 | @Override
57 | public void setBuild(IBuildInfo build) {
58 | super.setBuild(build);
59 | mCtsBuild = CtsBuildHelper.createBuildHelper(build);
60 | }
61 |
62 | @Override
63 | public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
64 | beforeTest();
65 | super.run(listener);
66 | afterTest();
67 | }
68 |
69 | private void beforeTest() throws DeviceNotAvailableException {
70 | installApkAndAssert(SOME_ACCESSIBLITY_SERVICES_APK);
71 | enableAccessibilityAndServices();
72 | }
73 |
74 | private void afterTest() throws DeviceNotAvailableException {
75 | disableAccessibilityAndServices(getDevice());
76 | uninstallAndAssert(SOME_ACCESSIBLITY_SERVICES_PACKAGE_NAME);
77 | }
78 |
79 | private void installApkAndAssert(String apkName) throws DeviceNotAvailableException {
80 | File file = FileUtil.getFileForPath(mCtsBuild.getTestCasesDir(), apkName);
81 | String errorMessage = getDevice().installPackage(file, true);
82 | TestCase.assertNull("Error installing: " + apkName, errorMessage);
83 | }
84 |
85 | private void uninstallAndAssert(String packageName) throws DeviceNotAvailableException {
86 | String errorMessage = getDevice().uninstallPackage(packageName);
87 | TestCase.assertNull("Error uninstalling: " + packageName, errorMessage);
88 | }
89 |
90 | private void enableAccessibilityAndServices() throws DeviceNotAvailableException {
91 | String enabledServicesValue =
92 | SOME_ACCESSIBLITY_SERVICES_PACKAGE_NAME + "/" + SPEAKING_ACCESSIBLITY_SERVICE_NAME
93 | + ":"
94 | + SOME_ACCESSIBLITY_SERVICES_PACKAGE_NAME + "/" + VIBRATING_ACCESSIBLITY_SERVICE_NAME;
95 | enableAccessibilityAndServices(getDevice(), enabledServicesValue);
96 | }
97 |
98 | static void enableAccessibilityAndServices(ITestDevice device, String value)
99 | throws DeviceNotAvailableException {
100 | SettingsToggler.setSecureString(device, "enabled_accessibility_services", value);
101 | SettingsToggler.setSecureString(device,
102 | "touch_exploration_granted_accessibility_services", value);
103 | SettingsToggler.setSecureInt(device, "accessibility_enabled", 1);
104 | }
105 |
106 | static void disableAccessibilityAndServices(ITestDevice device)
107 | throws DeviceNotAvailableException {
108 | SettingsToggler.updateSecureString(device, "enabled_accessibility_services", "");
109 | SettingsToggler.updateSecureString(device,
110 | "touch_exploration_granted_accessibility_services", "");
111 | SettingsToggler.updateSecureInt(device, "accessibility_enabled", 0);
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/testtype/DisplayTestRunner.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2012 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.cts.tradefed.testtype;
18 |
19 | import com.android.cts.tradefed.targetprep.SettingsToggler;
20 | import com.android.tradefed.device.DeviceNotAvailableException;
21 | import com.android.tradefed.result.ITestInvocationListener;
22 |
23 | /**
24 | * Running the display tests requires modification of secure settings to create an overlay display.
25 | * Secure settings cannot be changed from device CTS tests since system signature permission is
26 | * required. Such settings can be modified by the shell user, so a host side test is used.
27 | */
28 | public class DisplayTestRunner extends InstrumentationApkTest {
29 | private static final String OVERLAY_DISPLAY_DEVICES_SETTING_NAME = "overlay_display_devices";
30 |
31 | // Use a non-standard pattern, must match values in tests/tests/display/.../DisplayTest.java
32 | private static final String OVERLAY_DISPLAY_DEVICES_SETTING_VALUE = "1281x721/214";
33 |
34 | @Override
35 | public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
36 | // CLog.e("run: About to enable overlay display.");
37 | SettingsToggler.setGlobalString(getDevice(), OVERLAY_DISPLAY_DEVICES_SETTING_NAME,
38 | OVERLAY_DISPLAY_DEVICES_SETTING_VALUE);
39 |
40 | super.run(listener);
41 |
42 | // Tear down overlay display.
43 | // CLog.e("run: About to disable overlay display.");
44 | SettingsToggler.setGlobalString(getDevice(), OVERLAY_DISPLAY_DEVICES_SETTING_NAME,
45 | "");
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/testtype/GeeTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 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.cts.tradefed.testtype;
18 |
19 | import com.android.cts.tradefed.build.CtsBuildHelper;
20 | import com.android.ddmlib.testrunner.ITestRunListener;
21 | import com.android.tradefed.build.IBuildInfo;
22 | import com.android.tradefed.device.DeviceNotAvailableException;
23 | import com.android.tradefed.device.ITestDevice;
24 | import com.android.tradefed.log.LogUtil.CLog;
25 | import com.android.tradefed.result.ITestInvocationListener;
26 | import com.android.tradefed.testtype.IBuildReceiver;
27 | import com.android.tradefed.testtype.IDeviceTest;
28 | import com.android.tradefed.testtype.IRemoteTest;
29 |
30 | import java.io.File;
31 |
32 | /**
33 | * Test runner for native gTests.
34 | *
35 | * TODO: This is similar to Tradefed's existing GTest, but it doesn't confirm
36 | * each directory segment exists using ddmlib's file service. This was
37 | * a problem since /data is not visible on a user build, but it is
38 | * executable. It's also a lot more verbose when it comes to errors.
39 | */
40 | public class GeeTest implements IBuildReceiver, IDeviceTest, IRemoteTest {
41 |
42 | private static final String NATIVE_TESTS_DIRECTORY = "/data/local/tmp/cts-native-tests";
43 |
44 | private int mMaxTestTimeMs = 1 * 60 * 1000;
45 |
46 | private CtsBuildHelper mCtsBuild;
47 | private ITestDevice mDevice;
48 |
49 | private final String mPackageName;
50 | private final String mExeName;
51 |
52 | public GeeTest(String packageName, String exeName) {
53 | mPackageName = packageName;
54 | mExeName = exeName;
55 | }
56 |
57 | @Override
58 | public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
59 | if (installTest()) {
60 | runTest(listener);
61 | } else {
62 | CLog.e("Failed to install native tests");
63 | }
64 | }
65 |
66 | private boolean installTest() throws DeviceNotAvailableException {
67 | if (!createRemoteDir(NATIVE_TESTS_DIRECTORY)) {
68 | CLog.e("Could not create directory for native tests: " + NATIVE_TESTS_DIRECTORY);
69 | return false;
70 | }
71 |
72 | File nativeExe = new File(mCtsBuild.getTestCasesDir(), mExeName);
73 | if (!nativeExe.exists()) {
74 | CLog.e("Native test not found: " + nativeExe);
75 | return false;
76 | }
77 |
78 | File devicePath = new File(NATIVE_TESTS_DIRECTORY, mExeName);
79 | if (!mDevice.pushFile(nativeExe, devicePath.toString())) {
80 | CLog.e("Failed to push native test to device");
81 | return false;
82 | }
83 | return true;
84 | }
85 |
86 | private boolean createRemoteDir(String remoteFilePath) throws DeviceNotAvailableException {
87 | if (mDevice.doesFileExist(remoteFilePath)) {
88 | return true;
89 | }
90 | File remoteFile = new File(remoteFilePath);
91 | String parentPath = remoteFile.getParent();
92 | if (parentPath != null) {
93 | if (!createRemoteDir(parentPath)) {
94 | return false;
95 | }
96 | }
97 | mDevice.executeShellCommand(String.format("mkdir %s", remoteFilePath));
98 | return mDevice.doesFileExist(remoteFilePath);
99 | }
100 |
101 | void runTest(ITestRunListener listener) throws DeviceNotAvailableException {
102 | GeeTestResultParser resultParser = new GeeTestResultParser(mPackageName, listener);
103 | resultParser.setFakePackagePrefix(mPackageName + ".");
104 |
105 | String fullPath = NATIVE_TESTS_DIRECTORY + File.separator + mExeName;
106 | String flags = "";
107 | CLog.v("Running gtest %s %s on %s", fullPath, flags, mDevice.getSerialNumber());
108 | // force file to be executable
109 | CLog.v("%s", mDevice.executeShellCommand(String.format("chmod 755 %s", fullPath)));
110 |
111 | try {
112 | mDevice.executeShellCommand(String.format("%s %s", fullPath, flags), resultParser,
113 | mMaxTestTimeMs /* maxTimeToShellOutputResponse */,
114 | 0 /* retryAttempts */);
115 | } catch (DeviceNotAvailableException e) {
116 | resultParser.flush();
117 | throw e;
118 | } catch (RuntimeException e) {
119 | resultParser.flush();
120 | throw e;
121 | }
122 | }
123 |
124 |
125 | @Override
126 | public void setBuild(IBuildInfo buildInfo) {
127 | mCtsBuild = CtsBuildHelper.createBuildHelper(buildInfo);
128 | }
129 |
130 | @Override
131 | public void setDevice(ITestDevice device) {
132 | mDevice = device;
133 | }
134 |
135 | @Override
136 | public ITestDevice getDevice() {
137 | return mDevice;
138 | }
139 | }
140 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/testtype/ITestPackageDef.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2010 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.cts.tradefed.testtype;
18 |
19 | import com.android.ddmlib.testrunner.TestIdentifier;
20 | import com.android.tradefed.testtype.IRemoteTest;
21 |
22 | import java.io.File;
23 | import java.util.Collection;
24 |
25 | /**
26 | * Container for CTS test info.
27 | *
28 | * Knows how to translate this info into a runnable {@link IRemoteTest}.
29 | */
30 | public interface ITestPackageDef {
31 |
32 | /**
33 | * Get the unique URI, aka the appPackageName, of the test package.
34 | * @return the {@link String} uri
35 | */
36 | public String getUri();
37 |
38 | /**
39 | * Creates a runnable {@link IRemoteTest} from info stored in this definition.
40 | *
41 | * @param testCaseDir {@link File} representing directory of test case data
42 | * @param className the test class to restrict this run to or null
to run all tests
43 | * in package
44 | * @param methodName the optional test method to restrict this run to, or null
to
45 | * run all tests in class/package
46 | * @return a {@link IRemoteTest} with all necessary data populated to run the test or
47 | * null
if test could not be created
48 | */
49 | public IRemoteTest createTest(File testCaseDir);
50 |
51 | /**
52 | * Determine if given test is defined in this package.
53 | *
54 | * @param testDef the {@link TestIdentifier}
55 | * @return true
if test is defined
56 | */
57 | public boolean isKnownTest(TestIdentifier testDef);
58 |
59 | /**
60 | * Determine if given test class is defined in this package.
61 | *
62 | * @param testClassName the fully qualified test class name
63 | * @return true
if test class is defined
64 | */
65 | public boolean isKnownTestClass(String testClassName);
66 |
67 | /**
68 | * Get the collection of tests in this test package.
69 | */
70 | public Collection getTests();
71 |
72 | /**
73 | * Return the sha1sum of the binary file for this test package.
74 | *
75 | * Will only return a valid value after {@link #createTest(File, String, String)} has been
76 | * called.
77 | *
78 | * @return the sha1sum in {@link String} form
79 | */
80 | public String getDigest();
81 |
82 | /**
83 | * @return the name of this test package.
84 | */
85 | public String getName();
86 |
87 | /**
88 | * Set the filter to use to exclude tests
89 | *
90 | * @param excludedTestFilter
91 | */
92 | public void setExcludedTestFilter(TestFilter excludedTestFilter);
93 |
94 | /**
95 | * Restrict this test package to run a specific class and method name
96 | *
97 | * @param className the test class to restrict this run to
98 | * @param methodName the optional test method to restrict this run to, or null
to
99 | * run all tests in class
100 | */
101 | public void setClassName(String className, String methodName);
102 |
103 | /**
104 | * Return the file name of this package's instrumentation target apk.
105 | *
106 | * @return the file name or null
if not applicable.
107 | */
108 | public String getTargetApkName();
109 |
110 | /**
111 | * Return the Android package name of this package's instrumentation target, or
112 | * null
if not applicable.
113 | */
114 | public String getTargetPackageName();
115 |
116 | }
117 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/testtype/ITestPackageRepo.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2010 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.cts.tradefed.testtype;
18 |
19 | import java.util.Collection;
20 |
21 |
22 | /**
23 | * Interface for accessing tests from the CTS repository.
24 | */
25 | public interface ITestPackageRepo {
26 |
27 | /**
28 | * Get a {@link TestPackageDef} given a uri
29 | *
30 | * @param testUri the string uris
31 | * @return a {@link TestPackageDef} or null
if the uri cannot be found in repo
32 | */
33 | public ITestPackageDef getTestPackage(String testUri);
34 |
35 | /**
36 | * Attempt to find the package uri for a given test class name
37 | *
38 | * @param testClassName the test class name
39 | * @return the package uri or null
if the package cannot be found
40 | */
41 | public String findPackageForTest(String testClassName);
42 |
43 | /**
44 | * Return a sorted {@link Collection} of all package names found in repo.
45 | */
46 | public Collection getPackageNames();
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/testtype/ITestPlan.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2010 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.cts.tradefed.testtype;
18 |
19 | import com.android.ddmlib.testrunner.TestIdentifier;
20 | import com.android.tradefed.util.xml.AbstractXmlParser.ParseException;
21 |
22 | import java.io.IOException;
23 | import java.io.InputStream;
24 | import java.io.OutputStream;
25 | import java.util.Collection;
26 |
27 | /**
28 | * Interface for accessing test plan data.
29 | */
30 | public interface ITestPlan {
31 |
32 | /**
33 | * Populates the test plan data from given XML stream.
34 | *
35 | * @param xmlStream the {@link InputStream} that contains the test plan xml.
36 | */
37 | public void parse(InputStream xmlStream) throws ParseException;
38 |
39 | /**
40 | * Gets the list of test uris contained in this plan.
41 | */
42 | public Collection getTestUris();
43 |
44 | /**
45 | * Gets the {@link TestFilter} that should be used to exclude tests from given package.
46 | */
47 | public TestFilter getExcludedTestFilter(String uri);
48 |
49 | /**
50 | * Add a package to this test plan
51 | * @param uri
52 | */
53 | public void addPackage(String uri);
54 |
55 | /**
56 | * Add a excluded test to this test plan
57 | *
58 | * @param uri the package uri
59 | * @param testToExclude the test to exclude for given package
60 | */
61 | public void addExcludedTest(String uri, TestIdentifier testToExclude);
62 |
63 | /**
64 | * Adds the list of excluded tests for given package
65 | *
66 | * @param pkgUri
67 | * @param excludedTests
68 | */
69 | public void addExcludedTests(String uri, Collection excludedTests);
70 |
71 | /**
72 | * Serialize the contents of this test plan.
73 | *
74 | * @param xmlOutStream the {@link OutputStream} to serialize test plan contents to
75 | * @throws IOException
76 | */
77 | public void serialize(OutputStream xmlOutStream) throws IOException;
78 |
79 | /**
80 | * @return the test plan name
81 | */
82 | public String getName();
83 |
84 | }
85 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/testtype/InstrumentationApkTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 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.cts.tradefed.testtype;
17 |
18 | import com.android.cts.tradefed.build.CtsBuildHelper;
19 | import com.android.ddmlib.Log;
20 | import com.android.tradefed.build.IBuildInfo;
21 | import com.android.tradefed.device.DeviceNotAvailableException;
22 | import com.android.tradefed.result.ITestInvocationListener;
23 | import com.android.tradefed.testtype.IBuildReceiver;
24 | import com.android.tradefed.testtype.InstrumentationTest;
25 |
26 | import java.io.FileNotFoundException;
27 | import java.util.ArrayList;
28 | import java.util.Collection;
29 |
30 | import junit.framework.Assert;
31 |
32 | /**
33 | * A {@link InstrumentationTest] that will install CTS apks before test execution,
34 | * and uninstall on execution completion.
35 | */
36 | public class InstrumentationApkTest extends InstrumentationTest implements IBuildReceiver {
37 |
38 | private static final String LOG_TAG = "InstrumentationApkTest";
39 |
40 | /** the file names of the CTS apks to install */
41 | private Collection mInstallFileNames = new ArrayList();
42 | private Collection mUninstallPackages = new ArrayList();
43 |
44 | private CtsBuildHelper mCtsBuild = null;
45 |
46 | /**
47 | * {@inheritDoc}
48 | */
49 | @Override
50 | public void setBuild(IBuildInfo build) {
51 | mCtsBuild = CtsBuildHelper.createBuildHelper(build);
52 | }
53 |
54 | /**
55 | * Add an apk to install.
56 | *
57 | * @param apkFileName the apk file name
58 | * @param packageName the apk's Android package name
59 | */
60 | public void addInstallApk(String apkFileName, String packageName) {
61 | mInstallFileNames.add(apkFileName);
62 | mUninstallPackages.add(packageName);
63 | }
64 |
65 | /**
66 | * {@inheritDoc}
67 | */
68 | @Override
69 | public void run(final ITestInvocationListener listener)
70 | throws DeviceNotAvailableException {
71 | Assert.assertNotNull("missing device", getDevice());
72 | Assert.assertNotNull("missing build", mCtsBuild);
73 |
74 | for (String apkFileName : mInstallFileNames) {
75 | Log.d(LOG_TAG, String.format("Installing %s on %s", apkFileName,
76 | getDevice().getSerialNumber()));
77 | try {
78 | String installCode = getDevice().installPackage(mCtsBuild.getTestApp(apkFileName),
79 | true);
80 | Assert.assertNull(String.format("Failed to install %s on %s. Reason: %s",
81 | apkFileName, getDevice().getSerialNumber(), installCode), installCode);
82 |
83 | } catch (FileNotFoundException e) {
84 | Assert.fail(String.format("Could not find file %s", apkFileName));
85 | }
86 | }
87 | super.run(listener);
88 | for (String packageName : mUninstallPackages) {
89 | Log.d(LOG_TAG, String.format("Uninstalling %s on %s", packageName,
90 | getDevice().getSerialNumber()));
91 | getDevice().uninstallPackage(packageName);
92 | }
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/testtype/ResultFilter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2010 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.cts.tradefed.testtype;
17 |
18 | import java.util.Collection;
19 | import java.util.HashMap;
20 | import java.util.HashSet;
21 | import java.util.LinkedHashMap;
22 | import java.util.LinkedHashSet;
23 | import java.util.List;
24 | import java.util.Map;
25 |
26 | import junit.framework.TestFailure;
27 |
28 | import com.android.cts.tradefed.testtype.CtsTest.TestPackage;
29 | import com.android.ddmlib.testrunner.TestIdentifier;
30 | import com.android.tradefed.log.LogUtil.CLog;
31 | import com.android.tradefed.result.ITestInvocationListener;
32 | import com.android.tradefed.result.ResultForwarder;
33 |
34 | /**
35 | * A {@link ITestInvocationListener} that filters test results based on the set of expected tests
36 | * in CTS test package xml files.
37 | *
38 | * It will only report test results for expected tests, and at end of invocation, will report the
39 | * set of expected tests that were not executed.
40 | */
41 | class ResultFilter extends ResultForwarder {
42 |
43 | private final Map> mKnownTestsMap;
44 | private final Map> mRemainingTestsMap;
45 | private String mCurrentTestRun = null;
46 |
47 | /**
48 | * Create a {@link ResultFilter}.
49 | *
50 | * @param listener the real {@link ITestInvocationListener} to forward results to
51 | */
52 | ResultFilter(ITestInvocationListener listener, List testPackages) {
53 | super(listener);
54 |
55 | mKnownTestsMap = new HashMap>();
56 | // use LinkedHashMap for predictable test order
57 | mRemainingTestsMap = new LinkedHashMap>();
58 |
59 | for (TestPackage testPkg : testPackages) {
60 | mKnownTestsMap.put(testPkg.getTestRunName(), new HashSet(
61 | testPkg.getKnownTests()));
62 | mRemainingTestsMap.put(testPkg.getTestRunName(), new LinkedHashSet(
63 | testPkg.getKnownTests()));
64 | }
65 | }
66 |
67 | /**
68 | * {@inheritDoc}
69 | */
70 | @Override
71 | public void testRunStarted(String runName, int testCount) {
72 | super.testRunStarted(runName, testCount);
73 | mCurrentTestRun = runName;
74 | }
75 |
76 | /**
77 | * {@inheritDoc}
78 | */
79 | @Override
80 | public void testStarted(TestIdentifier test) {
81 | if (isKnownTest(test)) {
82 | super.testStarted(test);
83 | } else {
84 | CLog.d("Skipping reporting unknown test %s", test);
85 | }
86 | }
87 |
88 | /**
89 | * {@inheritDoc}
90 | */
91 |
92 |
93 | /**
94 | * {@inheritDoc}
95 | */
96 | @Override
97 | public void testEnded(TestIdentifier test, Map testMetrics) {
98 | if (isKnownTest(test)) {
99 | super.testEnded(test, testMetrics);
100 | removeExecutedTest(test);
101 | }
102 | }
103 |
104 | /**
105 | * @param test
106 | * @return
107 | */
108 | private boolean isKnownTest(TestIdentifier test) {
109 | if (mCurrentTestRun != null && mKnownTestsMap.containsKey(mCurrentTestRun)) {
110 | return mKnownTestsMap.get(mCurrentTestRun).contains(test);
111 | }
112 | return false;
113 | }
114 |
115 | /**
116 | * Remove given test from the 'remaining tests' data structure.
117 | * @param test
118 | */
119 | private void removeExecutedTest(TestIdentifier test) {
120 | if (mCurrentTestRun != null && mRemainingTestsMap.containsKey(mCurrentTestRun)) {
121 | mRemainingTestsMap.get(mCurrentTestRun).remove(test);
122 | }
123 | }
124 |
125 | /**
126 | * Report the set of expected tests that were not executed
127 | */
128 | public void reportUnexecutedTests() {
129 | for (Map.Entry> entry : mRemainingTestsMap.entrySet()) {
130 | if (!entry.getValue().isEmpty()) {
131 | super.testRunStarted(entry.getKey(), entry.getValue().size());
132 | for (TestIdentifier test : entry.getValue()) {
133 | // an unexecuted test is currently reported as a 'testStarted' event without a
134 | // 'testEnded'. TODO: consider adding an explict API for reporting an unexecuted
135 | // test
136 | super.testStarted(test);
137 | }
138 | super.testRunEnded(0, new HashMap());
139 | }
140 | }
141 | }
142 | }
143 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/testtype/TestFilter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 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.cts.tradefed.testtype;
18 |
19 | import com.android.ddmlib.testrunner.TestIdentifier;
20 |
21 | import java.util.ArrayList;
22 | import java.util.Collection;
23 | import java.util.Collections;
24 | import java.util.Comparator;
25 | import java.util.HashSet;
26 | import java.util.List;
27 | import java.util.Set;
28 |
29 | /**
30 | * Filter for {@link TestIdentifier}s.
31 | */
32 | public class TestFilter {
33 |
34 | private final Set mExcludedClasses;
35 | private final Set mExcludedTests;
36 | private String mIncludedClass = null;
37 | private String mIncludedMethod = null;
38 |
39 | /**
40 | * Creates a {@link TestFilter}
41 | */
42 | public TestFilter() {
43 | mExcludedClasses = new HashSet();
44 | mExcludedTests = new HashSet();
45 | }
46 |
47 | /**
48 | * Adds a test class to the filter.
49 | *
50 | * All tests in this class should be filtered.
51 | */
52 | public void addExcludedClass(String className) {
53 | mExcludedClasses.add(className);
54 | }
55 |
56 | /**
57 | * Adds a test class to the filter. All tests in this class should be excluded.
58 | */
59 | public void addExcludedTest(TestIdentifier test) {
60 | mExcludedTests.add(test);
61 | }
62 |
63 | /**
64 | * Get the test classes to exclude.
65 | *
66 | * Exposed for unit testing
67 | */
68 | Set getExcludedClasses() {
69 | return mExcludedClasses;
70 | }
71 |
72 | /**
73 | * Get the tests to exclude.
74 | *
75 | * Exposed for unit testing
76 | */
77 | Set getExcludedTests() {
78 | return mExcludedTests;
79 | }
80 |
81 | /**
82 | * Sets the class name and optionally method that should pass this filter. If non-null, all
83 | * other tests will be excluded.
84 | *
85 | * @param className the test class name to exclusively include
86 | * @param method the test method name to exclusively include
87 | */
88 | public void setTestInclusion(String className, String method) {
89 | mIncludedClass = className;
90 | mIncludedMethod = method;
91 | }
92 |
93 | /**
94 | * Filter the list of tests based on rules in this filter
95 | *
96 | * @param tests the list of tests to filter
97 | * @return a new sorted list of tests that passed the filter
98 | */
99 | public Collection filter(Collection tests) {
100 | List filteredTests = new ArrayList(tests.size());
101 | for (TestIdentifier test : tests) {
102 | if (mIncludedClass != null && !test.getClassName().equals(mIncludedClass)) {
103 | // skip
104 | continue;
105 | }
106 | if (mIncludedMethod != null && !test.getTestName().equals(mIncludedMethod)) {
107 | // skip
108 | continue;
109 | }
110 | if (mExcludedClasses.contains(test.getClassName())) {
111 | // skip
112 | continue;
113 | }
114 | if (mExcludedTests.contains(test)) {
115 | // skip
116 | continue;
117 | }
118 | filteredTests.add(test);
119 | }
120 | Collections.sort(filteredTests, new TestIdComparator());
121 | return filteredTests;
122 | }
123 |
124 | /**
125 | * Return true if there are exclusions rules defined.
126 | */
127 | public boolean hasExclusion() {
128 | return !mExcludedClasses.isEmpty() || !mExcludedTests.isEmpty();
129 | }
130 |
131 | /**
132 | * A {@link Comparator} for {@link TestIdentifier} that compares using
133 | * {@link TestIdentifier#toString()}
134 | */
135 | private class TestIdComparator implements Comparator {
136 |
137 | @Override
138 | public int compare(TestIdentifier o1, TestIdentifier o2) {
139 | return o1.toString().compareTo(o2.toString());
140 | }
141 | }
142 | }
143 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/testtype/TestPackageRepo.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2010 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.cts.tradefed.testtype;
17 |
18 | import com.android.ddmlib.Log;
19 | import com.android.tradefed.util.xml.AbstractXmlParser.ParseException;
20 |
21 | import java.io.BufferedInputStream;
22 | import java.io.File;
23 | import java.io.FileInputStream;
24 | import java.io.FileNotFoundException;
25 | import java.io.FilenameFilter;
26 | import java.io.InputStream;
27 | import java.util.ArrayList;
28 | import java.util.Collection;
29 | import java.util.Collections;
30 | import java.util.Hashtable;
31 | import java.util.List;
32 | import java.util.Map;
33 |
34 | /**
35 | * Retrieves CTS test package definitions from the repository.
36 | */
37 | public class TestPackageRepo implements ITestPackageRepo {
38 |
39 | private static final String LOG_TAG = "TestCaseRepo";
40 |
41 | private final File mTestCaseDir;
42 |
43 | /** mapping of uri to test definition */
44 | private final Map mTestMap;
45 |
46 | private final boolean mIncludeKnownFailures;
47 |
48 | /**
49 | * Creates a {@link TestPackageRepo}, initialized from provided repo files
50 | *
51 | * @param testCaseDir directory containing all test case definition xml and build files
52 | */
53 | public TestPackageRepo(File testCaseDir, boolean includeKnownFailures) {
54 | mTestCaseDir = testCaseDir;
55 | mTestMap = new Hashtable();
56 | mIncludeKnownFailures = includeKnownFailures;
57 | parse(mTestCaseDir);
58 | }
59 |
60 | /**
61 | * Builds mTestMap based on directory contents
62 | */
63 | private void parse(File dir) {
64 | File[] xmlFiles = dir.listFiles(new XmlFilter());
65 | for (File xmlFile : xmlFiles) {
66 | parseTestFromXml(xmlFile);
67 | }
68 | }
69 |
70 | private void parseTestFromXml(File xmlFile) {
71 | TestPackageXmlParser parser = new TestPackageXmlParser(mIncludeKnownFailures);
72 | try {
73 | parser.parse(createStreamFromFile(xmlFile));
74 | TestPackageDef def = parser.getTestPackageDef();
75 | if (def != null) {
76 | mTestMap.put(def.getUri(), def);
77 | } else {
78 | Log.w(LOG_TAG, String.format("Could not find test package info in xml file %s",
79 | xmlFile.getAbsolutePath()));
80 | }
81 | } catch (FileNotFoundException e) {
82 | Log.e(LOG_TAG, String.format("Could not find test case xml file %s",
83 | xmlFile.getAbsolutePath()));
84 | Log.e(LOG_TAG, e);
85 | } catch (ParseException e) {
86 | Log.e(LOG_TAG, String.format("Failed to parse test case xml file %s",
87 | xmlFile.getAbsolutePath()));
88 | Log.e(LOG_TAG, e);
89 | }
90 | }
91 |
92 | /**
93 | * Helper method to create a stream to read data from given file
94 | *
95 | * Exposed for unit testing
96 | *
97 | * @param xmlFile
98 | * @return stream to read data
99 | *
100 | */
101 | InputStream createStreamFromFile(File xmlFile) throws FileNotFoundException {
102 | return new BufferedInputStream(new FileInputStream(xmlFile));
103 | }
104 |
105 | private static class XmlFilter implements FilenameFilter {
106 |
107 | /**
108 | * {@inheritDoc}
109 | */
110 | @Override
111 | public boolean accept(File dir, String name) {
112 | return name.endsWith(".xml");
113 | }
114 | }
115 |
116 | /**
117 | * {@inheritDoc}
118 | */
119 | @Override
120 | public ITestPackageDef getTestPackage(String testUri) {
121 | return mTestMap.get(testUri);
122 | }
123 |
124 | /**
125 | * {@inheritDoc}
126 | */
127 | @Override
128 | public String findPackageForTest(String testClassName) {
129 | for (Map.Entry entry : mTestMap.entrySet()) {
130 | if (entry.getValue().isKnownTestClass(testClassName)) {
131 | return entry.getKey();
132 | }
133 | }
134 | return null;
135 | }
136 |
137 | /**
138 | * @return list of all package names found in repo
139 | */
140 | @Override
141 | public Collection getPackageNames() {
142 | List packageNames = new ArrayList();
143 | packageNames.addAll(mTestMap.keySet());
144 | Collections.sort(packageNames);
145 | return packageNames;
146 | }
147 | }
148 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/testtype/TestPackageXmlParser.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2010 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.cts.tradefed.testtype;
17 |
18 | import com.android.ddmlib.Log;
19 | import com.android.ddmlib.testrunner.TestIdentifier;
20 | import com.android.tradefed.util.xml.AbstractXmlParser;
21 |
22 | import org.xml.sax.Attributes;
23 | import org.xml.sax.helpers.DefaultHandler;
24 |
25 | import java.util.Iterator;
26 | import java.util.Stack;
27 |
28 | /**
29 | * Parser for CTS test case XML.
30 | *
31 | * Dumb parser that just retrieves data from in the test case xml and stuff it into a
32 | * {@link TestPackageDef}. Currently performs limited error checking.
33 | */
34 | public class TestPackageXmlParser extends AbstractXmlParser {
35 |
36 | private static final String LOG_TAG = "TestPackageXmlParser";
37 |
38 | private final boolean mIncludeKnownFailures;
39 |
40 | private TestPackageDef mPackageDef;
41 |
42 | public TestPackageXmlParser(boolean includeKnownFailures) {
43 | mIncludeKnownFailures = includeKnownFailures;
44 | }
45 |
46 | /**
47 | * SAX callback object. Handles parsing data from the xml tags.
48 | *
49 | * Expected structure:
50 | *
51 | *
52 | *
53 | *
54 | */
55 | private class TestPackageHandler extends DefaultHandler {
56 |
57 | private static final String TEST_PACKAGE_TAG = "TestPackage";
58 | private static final String TEST_SUITE_TAG = "TestSuite";
59 | private static final String TEST_CASE_TAG = "TestCase";
60 | private static final String TEST_TAG = "Test";
61 |
62 | // holds current class name segments
63 | private Stack mClassNameStack = new Stack();
64 |
65 | @Override
66 | public void startElement(String uri, String localName, String name, Attributes attributes) {
67 | if (TEST_PACKAGE_TAG.equals(localName)) {
68 | // appPackageName is used as the uri
69 | final String entryUriValue = attributes.getValue("appPackageName");
70 | final String testPackageNameSpace = attributes.getValue("appNameSpace");
71 | final String packageName = attributes.getValue("name");
72 | final String runnerName = attributes.getValue("runner");
73 | final String jarPath = attributes.getValue("jarPath");
74 | final String signatureCheck = attributes.getValue("signatureCheck");
75 | final String javaPackageFilter = attributes.getValue("javaPackageFilter");
76 | final String targetBinaryName = attributes.getValue("targetBinaryName");
77 | final String targetNameSpace = attributes.getValue("targetNameSpace");
78 |
79 | mPackageDef = new TestPackageDef();
80 | mPackageDef.setUri(entryUriValue);
81 | mPackageDef.setAppNameSpace(testPackageNameSpace);
82 | mPackageDef.setName(packageName);
83 | mPackageDef.setRunner(runnerName);
84 | mPackageDef.setTestType(getTestType(attributes));
85 | mPackageDef.setJarPath(jarPath);
86 | mPackageDef.setIsSignatureCheck(parseBoolean(signatureCheck));
87 | mPackageDef.setTestPackageName(javaPackageFilter);
88 | mPackageDef.setTargetBinaryName(targetBinaryName);
89 | mPackageDef.setTargetNameSpace(targetNameSpace);
90 |
91 | // reset the class name
92 | mClassNameStack = new Stack();
93 | } else if (TEST_SUITE_TAG.equals(localName)) {
94 | String packageSegment = attributes.getValue("name");
95 | if (packageSegment != null) {
96 | mClassNameStack.push(packageSegment);
97 | } else {
98 | Log.e(LOG_TAG, String.format("Invalid XML: missing 'name' attribute for '%s'",
99 | TEST_SUITE_TAG));
100 | }
101 | } else if (TEST_CASE_TAG.equals(localName)) {
102 | String classSegment = attributes.getValue("name");
103 | if (classSegment != null) {
104 | mClassNameStack.push(classSegment);
105 | } else {
106 | Log.e(LOG_TAG, String.format("Invalid XML: missing 'name' attribute for '%s'",
107 | TEST_CASE_TAG));
108 | }
109 | } else if (TEST_TAG.equals(localName)) {
110 | String methodName = attributes.getValue("name");
111 | if (mPackageDef == null) {
112 | Log.e(LOG_TAG, String.format(
113 | "Invalid XML: encountered a '%s' tag not enclosed within a '%s' tag",
114 | TEST_TAG, TEST_PACKAGE_TAG));
115 | } else if (methodName == null) {
116 | Log.e(LOG_TAG, String.format("Invalid XML: missing 'name' attribute for '%s'",
117 | TEST_TAG));
118 | } else {
119 | // build class name from package segments
120 | StringBuilder classNameBuilder = new StringBuilder();
121 | for (Iterator iter = mClassNameStack.iterator(); iter.hasNext(); ) {
122 | classNameBuilder.append(iter.next());
123 | if (iter.hasNext()) {
124 | classNameBuilder.append(".");
125 | }
126 | }
127 | int timeout = -1;
128 | String timeoutStr = attributes.getValue("timeout");
129 | if (timeoutStr != null) {
130 | timeout = Integer.parseInt(timeoutStr);
131 | }
132 | TestIdentifier testId = new TestIdentifier(classNameBuilder.toString(),
133 | methodName);
134 | boolean isKnownFailure = "failure".equals(attributes.getValue("expectation"));
135 | if (!isKnownFailure || mIncludeKnownFailures) {
136 | mPackageDef.addTest(testId, timeout);
137 | }
138 | }
139 | }
140 |
141 | }
142 |
143 | private String getTestType(Attributes attributes) {
144 | if (parseBoolean(attributes.getValue("hostSideOnly"))) {
145 | return TestPackageDef.HOST_SIDE_ONLY_TEST;
146 | } else if (parseBoolean(attributes.getValue("vmHostTest"))) {
147 | return TestPackageDef.VM_HOST_TEST;
148 | } else {
149 | return attributes.getValue("testType");
150 | }
151 | }
152 |
153 | @Override
154 | public void endElement (String uri, String localName, String qName) {
155 | if (TEST_SUITE_TAG.equals(localName) || TEST_CASE_TAG.equals(localName)) {
156 | mClassNameStack.pop();
157 | }
158 | }
159 |
160 | /**
161 | * Parse a boolean attribute value
162 | */
163 | private boolean parseBoolean(final String stringValue) {
164 | return stringValue != null &&
165 | Boolean.parseBoolean(stringValue);
166 | }
167 | }
168 |
169 | /**
170 | * {@inheritDoc}
171 | */
172 | @Override
173 | protected DefaultHandler createXmlHandler() {
174 | return new TestPackageHandler();
175 | }
176 |
177 | /**
178 | * @returns the {@link TestPackageDef} containing data parsed from xml or null
if
179 | * xml did not contain the correct information.
180 | */
181 | public TestPackageDef getTestPackageDef() {
182 | return mPackageDef;
183 | }
184 | }
185 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/testtype/TestPlan.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2010 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.cts.tradefed.testtype;
18 |
19 | import com.android.ddmlib.testrunner.TestIdentifier;
20 | import com.android.tradefed.util.ArrayUtil;
21 | import com.android.tradefed.util.xml.AbstractXmlParser;
22 |
23 | import org.kxml2.io.KXmlSerializer;
24 | import org.xml.sax.Attributes;
25 | import org.xml.sax.SAXException;
26 | import org.xml.sax.helpers.DefaultHandler;
27 |
28 | import java.io.IOException;
29 | import java.io.OutputStream;
30 | import java.util.ArrayList;
31 | import java.util.Collection;
32 | import java.util.LinkedHashMap;
33 | import java.util.List;
34 | import java.util.Map;
35 |
36 | /**
37 | * Implementation of {@link TestPlan}.
38 | */
39 | public class TestPlan extends AbstractXmlParser implements ITestPlan {
40 |
41 | /**
42 | * Map of uri names found in plan, and their excluded tests
43 | */
44 | private Map mUriExcludedTestsMap;
45 |
46 | private static final String ENTRY_TAG = "Entry";
47 | private static final String TEST_DELIM = ";";
48 | private static final String METHOD_DELIM = "#";
49 | private static final String EXCLUDE_ATTR = "exclude";
50 | private static final String URI_ATTR = "uri";
51 |
52 | private final String mName;
53 |
54 | /**
55 | * SAX callback object. Handles parsing data from the xml tags.
56 | */
57 | private class EntryHandler extends DefaultHandler {
58 |
59 | @Override
60 | public void startElement(String uri, String localName, String name, Attributes attributes)
61 | throws SAXException {
62 | if (ENTRY_TAG.equals(localName)) {
63 | final String entryUriValue = attributes.getValue(URI_ATTR);
64 | TestFilter filter = parseExcludedTests(attributes.getValue(EXCLUDE_ATTR));
65 | mUriExcludedTestsMap.put(entryUriValue, filter);
66 | }
67 | }
68 |
69 | /**
70 | * Parse the semi colon separated list of tests to exclude.
71 | *
72 | * Expected format:
73 | * testClassName[#testMethodName][;testClassName2...]
74 | *
75 | * @param excludedString the excluded string list
76 | * @return
77 | */
78 | private TestFilter parseExcludedTests(String excludedString) {
79 | TestFilter filter = new TestFilter();
80 | if (excludedString != null) {
81 | String[] testStrings = excludedString.split(TEST_DELIM);
82 | for (String testString : testStrings) {
83 | String[] classMethodPair = testString.split(METHOD_DELIM);
84 | if (classMethodPair.length == 2) {
85 | filter.addExcludedTest(new TestIdentifier(classMethodPair[0],
86 | classMethodPair[1]));
87 | } else {
88 | filter.addExcludedClass(testString);
89 | }
90 | }
91 | }
92 | return filter;
93 | }
94 | }
95 |
96 | public TestPlan(String name) {
97 | mName = name;
98 | // Uses a LinkedHashMap to have predictable iteration order
99 | mUriExcludedTestsMap = new LinkedHashMap();
100 | }
101 |
102 | /**
103 | * {@inheritDoc}
104 | */
105 | @Override
106 | public String getName() {
107 | return mName;
108 | }
109 |
110 | /**
111 | * {@inheritDoc}
112 | */
113 | @Override
114 | public Collection getTestUris() {
115 | return mUriExcludedTestsMap.keySet();
116 | }
117 |
118 | /**
119 | * {@inheritDoc}
120 | */
121 | @Override
122 | public TestFilter getExcludedTestFilter(String uri) {
123 | return mUriExcludedTestsMap.get(uri);
124 | }
125 |
126 | /**
127 | * {@inheritDoc}
128 | */
129 | @Override
130 | public void addPackage(String uri) {
131 | mUriExcludedTestsMap.put(uri, new TestFilter());
132 | }
133 |
134 | /**
135 | * {@inheritDoc}
136 | */
137 | @Override
138 | protected DefaultHandler createXmlHandler() {
139 | return new EntryHandler();
140 | }
141 |
142 | /**
143 | * {@inheritDoc}
144 | */
145 | @Override
146 | public void addExcludedTest(String uri, TestIdentifier testToExclude) {
147 | TestFilter filter = mUriExcludedTestsMap.get(uri);
148 | if (filter != null) {
149 | filter.addExcludedTest(testToExclude);
150 | } else {
151 | throw new IllegalArgumentException(String.format("Could not find package %s", uri));
152 | }
153 | }
154 |
155 | /**
156 | * {@inheritDoc}
157 | */
158 | @Override
159 | public void addExcludedTests(String uri, Collection excludedTests) {
160 | TestFilter filter = mUriExcludedTestsMap.get(uri);
161 | if (filter != null) {
162 | filter.getExcludedTests().addAll(excludedTests);
163 | } else {
164 | throw new IllegalArgumentException(String.format("Could not find package %s", uri));
165 | }
166 | }
167 |
168 | /**
169 | * {@inheritDoc}
170 | */
171 | @Override
172 | public void serialize(OutputStream stream) throws IOException {
173 | KXmlSerializer serializer = new KXmlSerializer();
174 | serializer.setOutput(stream, "UTF-8");
175 | serializer.startDocument("UTF-8", false);
176 | serializer.setFeature(
177 | "http://xmlpull.org/v1/doc/features.html#indent-output", true);
178 | serializer.startTag(null, "TestPlan");
179 | serializer.attribute(null, "version", "1.0");
180 | for (Map.Entry packageEntry : mUriExcludedTestsMap.entrySet()) {
181 | serializer.startTag(null, ENTRY_TAG);
182 | serializer.attribute(null, "uri", packageEntry.getKey());
183 | serializeFilter(serializer, packageEntry.getValue());
184 | serializer.endTag(null, ENTRY_TAG);
185 | }
186 | serializer.endTag(null, "TestPlan");
187 | serializer.endDocument();
188 | }
189 |
190 | /**
191 | * Adds an xml attribute containing {@link TestFilter} contents.
192 | *
193 | * If {@link TestFilter} is empty, no data will be outputted.
194 | *
195 | * @param serializer
196 | * @param value
197 | * @throws IOException
198 | */
199 | private void serializeFilter(KXmlSerializer serializer, TestFilter testFilter)
200 | throws IOException {
201 | if (!testFilter.hasExclusion()) {
202 | return;
203 | }
204 | List exclusionStrings = new ArrayList();
205 | exclusionStrings.addAll(testFilter.getExcludedClasses());
206 | for (TestIdentifier test : testFilter.getExcludedTests()) {
207 | // TODO: this relies on TestIdentifier.toString() using METHOD_DELIM.
208 | exclusionStrings.add(test.toString());
209 | }
210 | String exclusionAttrValue = ArrayUtil.join(TEST_DELIM, exclusionStrings);
211 | serializer.attribute(null, EXCLUDE_ATTR, exclusionAttrValue);
212 | }
213 | }
214 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/testtype/TestTimeoutException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2010 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.cts.tradefed.testtype;
17 |
18 | /**
19 | * An exception that indicates a test has timed out.
20 | * TODO: consider moving this to tradefed proper
21 | */
22 | public class TestTimeoutException extends Exception {
23 |
24 | private static final long serialVersionUID = 941691916057121118L;
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/testtype/UiAutomatorJarTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 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.cts.tradefed.testtype;
17 |
18 | import com.android.cts.tradefed.build.CtsBuildHelper;
19 | import com.android.tradefed.build.IBuildInfo;
20 | import com.android.tradefed.device.DeviceNotAvailableException;
21 | import com.android.tradefed.log.LogUtil.CLog;
22 | import com.android.tradefed.result.ITestInvocationListener;
23 | import com.android.tradefed.testtype.IBuildReceiver;
24 | import com.android.tradefed.testtype.UiAutomatorTest;
25 |
26 | import java.io.FileNotFoundException;
27 | import java.util.Arrays;
28 |
29 | import junit.framework.Assert;
30 |
31 | /**
32 | * A {@link UiAutomatorTest} that will install a uiautomator jar before test
33 | * execution, and uninstall on execution completion.
34 | */
35 | public class UiAutomatorJarTest extends UiAutomatorTest implements IBuildReceiver {
36 |
37 | // TODO: expose this in parent
38 | private static final String SHELL_EXE_BASE = "/data/local/tmp/";
39 |
40 | /** the file names of the CTS jar to install */
41 | private String mTestJarFileName;
42 |
43 | private CtsBuildHelper mCtsBuild = null;
44 |
45 | /**
46 | * {@inheritDoc}
47 | */
48 | @Override
49 | public void setBuild(IBuildInfo build) {
50 | mCtsBuild = CtsBuildHelper.createBuildHelper(build);
51 | }
52 |
53 | /**
54 | * Setter for CTS build files needed to perform the test.
55 | *
56 | * @param testJarName the file name of the jar containing the uiautomator tests
57 | */
58 | public void setInstallArtifacts(String testJarName) {
59 | mTestJarFileName = testJarName;
60 | }
61 |
62 | /**
63 | * {@inheritDoc}
64 | */
65 | @Override
66 | public void run(final ITestInvocationListener listener)
67 | throws DeviceNotAvailableException {
68 | Assert.assertNotNull("missing device", getDevice());
69 | Assert.assertNotNull("missing build", mCtsBuild);
70 | Assert.assertNotNull("missing jar to install", mTestJarFileName);
71 |
72 | installJar();
73 |
74 | super.run(listener);
75 |
76 | uninstallJar();
77 | }
78 |
79 | private void installJar() throws DeviceNotAvailableException {
80 | CLog.d("Installing %s on %s", mTestJarFileName, getDevice().getSerialNumber());
81 | String fullJarPath = String.format("%s%s", SHELL_EXE_BASE, mTestJarFileName);
82 | try {
83 | boolean result = getDevice().pushFile(mCtsBuild.getTestApp(mTestJarFileName),
84 | fullJarPath);
85 | Assert.assertTrue(String.format("Failed to push file to %s", fullJarPath), result);
86 | setTestJarPaths(Arrays.asList(fullJarPath));
87 | } catch (FileNotFoundException e) {
88 | Assert.fail(String.format("Could not find file %s", mTestJarFileName));
89 | }
90 | }
91 |
92 | private void uninstallJar() throws DeviceNotAvailableException {
93 | CLog.d("Uninstalling %s on %s", mTestJarFileName, getDevice().getSerialNumber());
94 | String fullJarPath = String.format("%s%s", SHELL_EXE_BASE, mTestJarFileName);
95 | getDevice().executeShellCommand(String.format("rm %s", fullJarPath));
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/testtype/VMHostTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 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.cts.tradefed.testtype;
17 |
18 | import com.android.cts.tradefed.build.CtsBuildHelper;
19 | import com.android.tradefed.device.DeviceNotAvailableException;
20 | import com.android.tradefed.device.ITestDevice;
21 | import com.android.tradefed.log.LogUtil.CLog;
22 | import com.android.tradefed.result.ITestInvocationListener;
23 | import com.android.tradefed.util.FileUtil;
24 |
25 | import java.io.File;
26 | import java.io.IOException;
27 | import java.util.zip.ZipFile;
28 |
29 | /**
30 | * A wrapper around {@link JarHostTest} that includes additional device setup and clean up.
31 | *
32 | */
33 | public class VMHostTest extends JarHostTest {
34 |
35 | private static final String VM_TEST_TEMP_DIR = "/data/local/tmp/vm-tests";
36 |
37 | /**
38 | * {@inheritDoc}
39 | */
40 | @Override
41 | @SuppressWarnings("unchecked")
42 | public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
43 | if (!installVmPrereqs(getDevice(), getBuildHelper())) {
44 | throw new RuntimeException(String.format(
45 | "Failed to install vm-tests prereqs on device %s",
46 | getDevice().getSerialNumber()));
47 | }
48 | super.run(listener);
49 | cleanupDeviceFiles(getDevice());
50 | }
51 |
52 | /**
53 | * Install pre-requisite jars for running vm-tests, creates temp directories for test.
54 | *
55 | * @param device the {@link ITestDevice}
56 | * @param ctsBuild the {@link CtsBuildHelper}
57 | * @throws DeviceNotAvailableException
58 | * @return true if test jar files are extracted and pushed to device successfully
59 | */
60 | private boolean installVmPrereqs(ITestDevice device, CtsBuildHelper ctsBuild)
61 | throws DeviceNotAvailableException {
62 | cleanupDeviceFiles(device);
63 | // Creates temp directory recursively. We also need to create the dalvik-cache directory
64 | // which is used by the dalvikvm to optimize things. Without the dalvik-cache, there will be
65 | // a sigsev thrown by the vm.
66 | CLog.d("Creating device temp directory, including dalvik-cache.");
67 | createRemoteDir(device, VM_TEST_TEMP_DIR + "/dalvik-cache" );
68 | try {
69 | File localTmpDir = FileUtil.createTempDir("cts-vm", new File("/tmp/"));
70 | CLog.d("Creating host temp dir %s", localTmpDir.getPath());
71 | File jarFile = new File(ctsBuild.getTestCasesDir(), getJarFileName());
72 | if (!jarFile.exists()) {
73 | CLog.e("Missing jar file %s", jarFile.getPath());
74 | return false;
75 | }
76 | CLog.d("Extracting jar file %s to host temp directory %s.",
77 | jarFile.getPath(), localTmpDir.getPath());
78 | ZipFile zipFile = new ZipFile(jarFile);
79 | FileUtil.extractZip(zipFile, localTmpDir);
80 | File localTestTmpDir = new File(localTmpDir, "tests");
81 | CLog.d("Syncing host dir %s to device dir %s",
82 | localTestTmpDir.getPath(), VM_TEST_TEMP_DIR);
83 | if (!device.pushDir(localTestTmpDir, VM_TEST_TEMP_DIR)) {
84 | CLog.e("Failed to push vm test files");
85 | return false;
86 | }
87 | CLog.d("Cleaning up host temp dir %s", localTmpDir.getPath());
88 | FileUtil.recursiveDelete(localTmpDir);
89 | } catch (IOException e) {
90 | CLog.e("Failed to extract jar file %s and sync it to device %s.",
91 | getJarFileName(), device.getSerialNumber());
92 | return false;
93 | }
94 | return true;
95 | }
96 |
97 | /**
98 | * Removes temporary file directory from device
99 | *
100 | * @param device
101 | * @throws DeviceNotAvailableException
102 | */
103 | private void cleanupDeviceFiles(ITestDevice device) throws DeviceNotAvailableException {
104 | if (device.doesFileExist(VM_TEST_TEMP_DIR)) {
105 | CLog.d("Removing device's temp dir %s from previous runs.", VM_TEST_TEMP_DIR);
106 | device.executeShellCommand(String.format("rm -r %s", VM_TEST_TEMP_DIR));
107 | }
108 | }
109 |
110 | /**
111 | * Creates the file directory recursively in the device.
112 | *
113 | * @param device the {@link ITestDevice}
114 | * @param remoteFilePath the absolute path.
115 | * @throws DeviceNotAvailableException
116 | */
117 | private void createRemoteDir(ITestDevice device, String remoteFilePath)
118 | throws DeviceNotAvailableException {
119 | if (device.doesFileExist(remoteFilePath)) {
120 | return;
121 | }
122 | File f = new File(remoteFilePath);
123 | String parentPath = f.getParent();
124 | if (parentPath != null) {
125 | createRemoteDir(device, parentPath);
126 | }
127 | device.executeShellCommand(String.format("mkdir %s", remoteFilePath));
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/testtype/WrappedGTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012 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.cts.tradefed.testtype;
18 |
19 | import com.android.cts.tradefed.build.CtsBuildHelper;
20 | import com.android.ddmlib.testrunner.ITestRunListener;
21 | import com.android.tradefed.build.IBuildInfo;
22 | import com.android.tradefed.device.DeviceNotAvailableException;
23 | import com.android.tradefed.device.ITestDevice;
24 | import com.android.tradefed.log.LogUtil.CLog;
25 | import com.android.tradefed.result.ITestInvocationListener;
26 | import com.android.tradefed.testtype.IBuildReceiver;
27 | import com.android.tradefed.testtype.IDeviceTest;
28 | import com.android.tradefed.testtype.IRemoteTest;
29 |
30 | import java.io.File;
31 | import java.io.FileNotFoundException;
32 |
33 | /**
34 | * Test runner for wrapped (native) GTests
35 | */
36 | public class WrappedGTest implements IBuildReceiver, IDeviceTest, IRemoteTest {
37 |
38 | private int mMaxTestTimeMs = 1 * 60 * 1000;
39 |
40 | private CtsBuildHelper mCtsBuild;
41 | private ITestDevice mDevice;
42 |
43 | private final String mAppNameSpace;
44 | private final String mRunner;
45 | private final String mName;
46 | private final String mUri;
47 |
48 |
49 | public WrappedGTest(String appNameSpace, String uri, String name, String runner) {
50 | mAppNameSpace = appNameSpace;
51 | mRunner = runner;
52 | mName = name;
53 | mUri = uri;
54 | }
55 |
56 | @Override
57 | public void setBuild(IBuildInfo buildInfo) {
58 | mCtsBuild = CtsBuildHelper.createBuildHelper(buildInfo);
59 | }
60 |
61 | @Override
62 | public void setDevice(ITestDevice device) {
63 | mDevice = device;
64 | }
65 |
66 | @Override
67 | public ITestDevice getDevice() {
68 | return mDevice;
69 | }
70 |
71 | @Override
72 | public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
73 | if (installTest()) {
74 | runTest(listener);
75 | uninstallTest();
76 | } else {
77 | CLog.e("Failed to install test");
78 | }
79 | }
80 |
81 | private boolean installTest() throws DeviceNotAvailableException {
82 | try {
83 | File testApp = mCtsBuild.getTestApp(String.format("%s.apk", mName));
84 | String installCode = mDevice.installPackage(testApp, true);
85 |
86 | if (installCode != null) {
87 | CLog.e("Failed to install %s.apk on %s. Reason: %s", mName,
88 | mDevice.getSerialNumber(), installCode);
89 | return false;
90 | }
91 | }
92 | catch (FileNotFoundException e) {
93 | CLog.e("Package %s.apk not found", mName);
94 | return false;
95 | }
96 | return true;
97 | }
98 |
99 | private void runTest(ITestRunListener listener) throws DeviceNotAvailableException {
100 | WrappedGTestResultParser resultParser = new WrappedGTestResultParser(mUri, listener);
101 | resultParser.setFakePackagePrefix(mUri + ".");
102 | try {
103 | String command = String.format("am instrument -w %s/.%s", mAppNameSpace, mRunner);
104 | mDevice.executeShellCommand(command, resultParser, mMaxTestTimeMs, 0);
105 | } catch (DeviceNotAvailableException e) {
106 | resultParser.flush();
107 | throw e;
108 | } catch (RuntimeException e) {
109 | resultParser.flush();
110 | throw e;
111 | }
112 | }
113 |
114 | private void uninstallTest() throws DeviceNotAvailableException {
115 | mDevice.uninstallPackage(mAppNameSpace);
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/testtype/WrappedGTestResultParser.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012 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.cts.tradefed.testtype;
17 |
18 | import com.android.ddmlib.testrunner.ITestRunListener;
19 | import com.android.tradefed.log.LogUtil.CLog;
20 |
21 | import java.util.Collection;
22 | import java.util.List;
23 | import java.util.ArrayList;
24 |
25 | public class WrappedGTestResultParser extends GeeTestResultParser {
26 |
27 | private boolean mInstrumentationError;
28 |
29 | /**
30 | * Creates the WrappedGTestResultParser.
31 | *
32 | * @param testRunName the test run name to provide to
33 | * {@link ITestRunListener#testRunStarted(String, int)}
34 | * @param listeners informed of test results as the tests are executing
35 | */
36 | public WrappedGTestResultParser(String testRunName, Collection listeners) {
37 | super(testRunName, listeners);
38 | }
39 |
40 | /**
41 | * Creates the WrappedGTestResultParser for a single listener.
42 | *
43 | * @param testRunName the test run name to provide to
44 | * {@link ITestRunListener#testRunStarted(String, int)}
45 | * @param listener informed of test results as the tests are executing
46 | */
47 | public WrappedGTestResultParser(String testRunName, ITestRunListener listener) {
48 | super(testRunName, listener);
49 | }
50 |
51 | /**
52 | * Strips the instrumentation information and then forwards
53 | * the raw gtest output to the {@link GeeTestResultParser}.
54 | */
55 | @Override
56 | public void processNewLines(String[] lines) {
57 | if (mInstrumentationError) {
58 | return;
59 | }
60 |
61 | String[] gtestOutput = parseInstrumentation(lines);
62 | super.processNewLines(gtestOutput);
63 | }
64 |
65 | /**
66 | * Parses raw instrumentation output and returns the
67 | * contained gtest output
68 | *
69 | * @param lines the raw instrumentation output
70 | * @return the gtest output
71 | */
72 | public String[] parseInstrumentation(String[] lines) {
73 | List output = new ArrayList();
74 | boolean readMultiLine = false;
75 | for (String line : lines) {
76 |
77 | if (line.startsWith("INSTRUMENTATION_RESULT: ")) {
78 | CLog.e("Instrumentation Error:");
79 | mInstrumentationError = true;
80 | }
81 |
82 | if (mInstrumentationError) {
83 | CLog.e(line);
84 | continue;
85 | }
86 |
87 | if (line.startsWith("INSTRUMENTATION_STATUS: gtest=")) {
88 | output.add(line.replace("INSTRUMENTATION_STATUS: gtest=", ""));
89 | readMultiLine = true;
90 | continue;
91 | }
92 |
93 | if (line.startsWith("INSTRUMENTATION_")) {
94 | readMultiLine = false;
95 | continue;
96 | }
97 |
98 | if (readMultiLine) {
99 | output.add(line);
100 | }
101 | }
102 |
103 | return output.toArray(new String[output.size()]);
104 | }
105 | }
106 |
107 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/testtype/monkey/Monkey.java:
--------------------------------------------------------------------------------
1 | package com.android.cts.tradefed.testtype.monkey;
2 |
3 | import java.security.SecureRandom;
4 | import java.util.ArrayList;
5 | import java.util.Random;
6 |
7 | import com.android.chimpchat.adb.AdbChimpDevice;
8 | import com.android.cts.tradefed.result.CtsXmlResultReporter;
9 |
10 | public class Monkey {
11 |
12 | private String testPackage;
13 |
14 | private MonkeySourceRandom mEventSource;
15 |
16 | /** Categories we are allowed to launch **/
17 | private ArrayList mMainCategories = new ArrayList();
18 | /** Applications we can switch to. */
19 |
20 | private long mThrottle = 300;
21 | private int mVerbose = 1;
22 | private boolean mRandomizeThrottle = false;
23 | private AdbChimpDevice mDevice;
24 | private Rectangle mRectangle = null;
25 |
26 | public Monkey(String testPackage, AdbChimpDevice device, float[] factors) {
27 | this.testPackage = testPackage;
28 | this.mDevice = device;
29 | init(factors);
30 | }
31 |
32 | /**
33 | * Fire next random event
34 | */
35 | public void nextRandomEvent(CtsXmlResultReporter ctsXmlResultReporter) {
36 | MonkeyEvent ev = mEventSource.getNextEvent();
37 |
38 | // System.out.println("Firing Monkey Event:" + ev.toString());
39 | if (ev != null) {
40 | ctsXmlResultReporter.addMonkeyEvent(ev);
41 | ev.fireEvent(mDevice);
42 | }
43 |
44 | }
45 |
46 | public void setY(int y){
47 | mRectangle.setY(y);
48 | }
49 |
50 | /**
51 | * Initiate the monkey
52 | */
53 | private void init(float[] factors) {
54 | Random mRandom = new SecureRandom();
55 | mRandom.setSeed(-1);
56 |
57 | mRectangle = new Rectangle(Integer.parseInt(mDevice
58 | .getProperty("display.width")), Integer.parseInt(mDevice
59 | .getProperty("display.height")));
60 | mEventSource = new MonkeySourceRandom(mRandom, mThrottle,
61 | mRandomizeThrottle, mRectangle);
62 | mEventSource.setVerbose(mVerbose);
63 | for (int i = 0; i < factors.length; i++) {
64 | if (factors[i] > 0) {
65 | mEventSource.setFactors(i, -factors[i]);
66 | }
67 | }
68 |
69 | mEventSource.validate();
70 |
71 | // start a random activity
72 | // mEventSource.generateActivity();
73 | }
74 |
75 | }
76 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/testtype/monkey/MonkeyDragEvent.java:
--------------------------------------------------------------------------------
1 | package com.android.cts.tradefed.testtype.monkey;
2 |
3 | import java.awt.Point;
4 | import java.util.ArrayList;
5 | import java.util.List;
6 |
7 | import com.android.chimpchat.adb.AdbChimpDevice;
8 |
9 | public class MonkeyDragEvent extends MonkeyEvent {
10 |
11 | private Point downPoint = null;
12 | private Point upPoint = null;
13 |
14 | public MonkeyDragEvent() {
15 | super(EVENT_TYPE_DRAG);
16 | // TODO Auto-generated constructor stub
17 | }
18 |
19 | public void setDownPoint(Point point) {
20 | downPoint = point;
21 | }
22 |
23 | public void setUpPoint(Point point) {
24 | upPoint = point;
25 | }
26 |
27 | public Point getDownPoint() {
28 | return downPoint;
29 | }
30 |
31 | public Point getUpPoint() {
32 | return upPoint;
33 | }
34 |
35 | @Override
36 | public int fireEvent(AdbChimpDevice acDevice) {
37 | // TODO Auto-generated method stub
38 |
39 | acDevice.drag(downPoint.x, downPoint.y, upPoint.x, upPoint.y, 10, 1000);
40 |
41 | return 0;
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/testtype/monkey/MonkeyEvent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2008 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.cts.tradefed.testtype.monkey;
18 |
19 | import com.android.chimpchat.adb.AdbChimpDevice;
20 |
21 | /**
22 | * abstract class for monkey event
23 | */
24 | public abstract class MonkeyEvent{
25 | protected int eventType;
26 | public static final int EVENT_TYPE_KEY = 0;
27 | public static final int EVENT_TYPE_TAP = 1;
28 | public static final int EVENT_TYPE_MOTION = 2;
29 | public static final int EVENT_TYPE_DRAG = 3;
30 |
31 |
32 |
33 |
34 | public MonkeyEvent(int type) {
35 | eventType = type;
36 | }
37 |
38 | /* (non-Javadoc)
39 | * @see com.android.cts.tradefed.testtype.monkey.IMonkeyEvent#getEventType()
40 | */
41 | public int getEventType() {
42 | return eventType;
43 | }
44 |
45 | /* (non-Javadoc)
46 | * @see com.android.cts.tradefed.testtype.monkey.IMonkeyEvent#isThrottlable()
47 | */
48 | public boolean isThrottlable() {
49 | return true;
50 | }
51 |
52 | /* (non-Javadoc)
53 | * @see com.android.cts.tradefed.testtype.monkey.IMonkeyEvent#fireEvent(com.android.chimpchat.adb.AdbChimpDevice)
54 | */
55 | public abstract int fireEvent(AdbChimpDevice acDevice);
56 | }
57 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/testtype/monkey/MonkeyEventQueue.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2008 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.cts.tradefed.testtype.monkey;
18 |
19 | import java.util.LinkedList;
20 | import java.util.Random;
21 |
22 |
23 | /**
24 | * class for keeping a monkey event queue
25 | */
26 | @SuppressWarnings("serial")
27 | public class MonkeyEventQueue extends LinkedList {
28 |
29 | private Random mRandom;
30 | private long mThrottle;
31 | private boolean mRandomizeThrottle;
32 |
33 | public MonkeyEventQueue(Random random, long throttle, boolean randomizeThrottle) {
34 | super();
35 | mRandom = random;
36 | mThrottle = throttle;
37 | mRandomizeThrottle = randomizeThrottle;
38 | }
39 |
40 | @Override
41 | public void addLast(MonkeyEvent e) {
42 | super.add(e);
43 | if (e.isThrottlable()) {
44 | long throttle = mThrottle;
45 | if (mRandomizeThrottle && (mThrottle > 0)) {
46 | throttle = mRandom.nextLong();
47 | if (throttle < 0) {
48 | throttle = -throttle;
49 | }
50 | throttle %= mThrottle;
51 | ++throttle;
52 | }
53 | // super.add(new MonkeyThrottleEvent(throttle));
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/testtype/monkey/MonkeyEventSource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2008 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.cts.tradefed.testtype.monkey;
18 |
19 |
20 | /**
21 | * event source interface
22 | */
23 | public interface MonkeyEventSource {
24 | /**
25 | * @return the next monkey event from the source
26 | */
27 | public MonkeyEvent getNextEvent();
28 |
29 | /**
30 | * set verbose to allow different level of log
31 | *
32 | * @param verbose output mode? 1= verbose, 2=very verbose
33 | */
34 | public void setVerbose(int verbose);
35 |
36 | /**
37 | * check whether precondition is satisfied
38 | *
39 | * @return false if something fails, e.g. factor failure in random source or
40 | * file can not open from script source etc
41 | */
42 | public boolean validate();
43 | }
44 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/testtype/monkey/MonkeyKeyEvent.java:
--------------------------------------------------------------------------------
1 | package com.android.cts.tradefed.testtype.monkey;
2 |
3 | import java.io.IOException;
4 |
5 | import com.android.chimpchat.adb.AdbChimpDevice;
6 |
7 |
8 | //设备按键事件,包括:基本的导航事件(nav),主要导航事件(majornav)和系统事件(syskeys)
9 | public class MonkeyKeyEvent extends MonkeyEvent {
10 | public String getKeyCode() {
11 | return mKeyCode;
12 | }
13 |
14 | public void setKeyCode(String mKeyCode) {
15 | this.mKeyCode = mKeyCode;
16 | }
17 |
18 | private String mKeyCode;
19 |
20 | public MonkeyKeyEvent(String keyCode) {
21 | super(EVENT_TYPE_KEY);
22 | this.mKeyCode = keyCode;
23 | }
24 |
25 | @Override
26 | public int fireEvent(AdbChimpDevice acDevice) {
27 | try {
28 | acDevice.getManager().press(mKeyCode);
29 | } catch (IOException e) {
30 | // TODO Auto-generated catch block
31 | e.printStackTrace();
32 | }
33 | return 0;
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/testtype/monkey/MonkeyMotionEvent.java:
--------------------------------------------------------------------------------
1 | package com.android.cts.tradefed.testtype.monkey;
2 |
3 | import java.awt.Point;
4 | import java.io.IOException;
5 | import java.sql.Time;
6 | import java.util.ArrayList;
7 | import java.util.List;
8 | import java.util.concurrent.TimeUnit;
9 |
10 | import com.android.chimpchat.adb.AdbChimpDevice;
11 |
12 | //motion事件是由屏幕上某处一个down事件、一系列伪随机的移动事件和一个up事件组成
13 | public class MonkeyMotionEvent extends MonkeyEvent {
14 |
15 | private List movePoints = new ArrayList();
16 | private Point downPoint = null;
17 | private Point upPoint = null;
18 |
19 | public MonkeyMotionEvent() {
20 | super(EVENT_TYPE_MOTION);
21 | // TODO Auto-generated constructor stub
22 | }
23 |
24 | public void addMovePoint(Point point) {
25 | movePoints.add(point);
26 | }
27 |
28 | public void setDownPoint(Point point) {
29 | downPoint = point;
30 | }
31 |
32 | public void setUpPoint(Point point) {
33 | upPoint = point;
34 | }
35 |
36 | public List getMovePoints() {
37 | return movePoints;
38 | }
39 |
40 | public void setMovePoints(List movePoints) {
41 | this.movePoints = movePoints;
42 | }
43 |
44 | public Point getDownPoint() {
45 | return downPoint;
46 | }
47 |
48 | public Point getUpPoint() {
49 | return upPoint;
50 | }
51 |
52 | @Override
53 | public int fireEvent(AdbChimpDevice acDevice) {
54 | // TODO Auto-generated method stub
55 |
56 | // try {
57 | // acDevice.getManager().touchDown(downPoint.x, downPoint.y);
58 | // for (Point point : movePoints) {
59 | // acDevice.getManager().touchMove(point.x, point.y);
60 | // }
61 | //
62 | // acDevice.getManager().touchUp(upPoint.x, upPoint.y);
63 | //
64 | // } catch (IOException e) {
65 | // // TODO Auto-generated catch block
66 | // e.printStackTrace();
67 | // }
68 | acDevice.drag(downPoint.x, downPoint.y, upPoint.x, upPoint.y, 1, 1000);
69 |
70 | return 0;
71 | }
72 |
73 | }
74 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/testtype/monkey/MonkeyTapEvent.java:
--------------------------------------------------------------------------------
1 | package com.android.cts.tradefed.testtype.monkey;
2 |
3 | import java.awt.Point;
4 | import java.io.IOException;
5 |
6 | import com.android.chimpchat.adb.AdbChimpDevice;
7 |
8 | //触摸事件是指在屏幕中的一个down-up事件,即在屏幕某处按下并抬起的操作
9 |
10 | public class MonkeyTapEvent extends MonkeyEvent {
11 |
12 | public static final int ACTION_UP = 0;
13 | public static final int ACTION_MOVE = 1;
14 | public static final int ACTION_DOWN = 2;
15 | private Point mPoint;
16 |
17 | public MonkeyTapEvent(Point point) {
18 | super(EVENT_TYPE_TAP);
19 | this.mPoint = point;
20 | }
21 |
22 | public Point getPoint() {
23 | return mPoint;
24 | }
25 |
26 | public void setPoint(Point mPoint) {
27 | this.mPoint = mPoint;
28 | }
29 |
30 | @Override
31 | public int fireEvent(AdbChimpDevice acDevice) {
32 | // TODO Auto-generated method stub
33 | try {
34 | acDevice.getManager().tap(mPoint.x, mPoint.y);
35 |
36 | } catch (IOException e) {
37 | // TODO Auto-generated catch block
38 | e.printStackTrace();
39 | }
40 | return 0;
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/src/com/android/cts/tradefed/testtype/monkey/Rectangle.java:
--------------------------------------------------------------------------------
1 | package com.android.cts.tradefed.testtype.monkey;
2 |
3 | public class Rectangle {
4 |
5 | private int x;
6 | private int y;
7 | private int width;
8 | private int height;
9 |
10 | public Rectangle(int width, int height) {
11 | this.width = width;
12 | this.height = height;
13 | }
14 |
15 | public int getX() {
16 | return x;
17 | }
18 |
19 | public void setX(int x) {
20 | this.x = x;
21 | }
22 |
23 | public int getY() {
24 | return y;
25 | }
26 |
27 | public void setY(int y) {
28 | this.y = y;
29 | }
30 |
31 | public int getWidth() {
32 | return width;
33 | }
34 |
35 | public void setWidth(int width) {
36 | this.width = width;
37 | }
38 |
39 | public int getHeight() {
40 | return height;
41 | }
42 |
43 | public void setHeight(int height) {
44 | this.height = height;
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------