• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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 android.cts.statsdatom.statsd;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 import static com.google.common.truth.Truth.assertWithMessage;
21 
22 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
23 import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
24 import com.android.ddmlib.testrunner.TestResult.TestStatus;
25 import com.android.tradefed.build.IBuildInfo;
26 import com.android.tradefed.device.CollectingByteOutputReceiver;
27 import com.android.tradefed.device.DeviceNotAvailableException;
28 import com.android.tradefed.log.LogUtil.CLog;
29 import com.android.tradefed.result.CollectingTestListener;
30 import com.android.tradefed.result.TestDescription;
31 import com.android.tradefed.result.TestResult;
32 import com.android.tradefed.result.TestRunResult;
33 import com.android.tradefed.testtype.DeviceTestCase;
34 import com.android.tradefed.testtype.IBuildReceiver;
35 
36 import com.google.protobuf.InvalidProtocolBufferException;
37 import com.google.protobuf.MessageLite;
38 import com.google.protobuf.Parser;
39 
40 import java.io.FileNotFoundException;
41 import java.util.Map;
42 
43 import javax.annotation.Nonnull;
44 import javax.annotation.Nullable;
45 
46 // Largely copied from incident's ProtoDumpTestCase
47 public class BaseTestCase extends DeviceTestCase implements IBuildReceiver {
48 
49     protected IBuildInfo mCtsBuild;
50 
51     private static final String TEST_RUNNER = "androidx.test.runner.AndroidJUnitRunner";
52 
53     @Override
setUp()54     protected void setUp() throws Exception {
55         super.setUp();
56         assertThat(mCtsBuild).isNotNull();
57     }
58 
59     @Override
setBuild(IBuildInfo buildInfo)60     public void setBuild(IBuildInfo buildInfo) {
61         mCtsBuild = buildInfo;
62     }
63 
getBuild()64     public IBuildInfo getBuild() {
65         return mCtsBuild;
66     }
67 
68     /**
69      * Call onto the device with an adb shell command and get the results of
70      * that as a proto of the given type.
71      *
72      * @param parser A protobuf parser object. e.g. MyProto.parser()
73      * @param command The adb shell command to run. e.g. "dumpsys fingerprint --proto"
74      *
75      * @throws DeviceNotAvailableException If there was a problem communicating with
76      *      the test device.
77      * @throws InvalidProtocolBufferException If there was an error parsing
78      *      the proto. Note that a 0 length buffer is not necessarily an error.
79      */
getDump(Parser<T> parser, String command)80     public <T extends MessageLite> T getDump(Parser<T> parser, String command)
81             throws DeviceNotAvailableException, InvalidProtocolBufferException {
82         final CollectingByteOutputReceiver receiver = new CollectingByteOutputReceiver();
83         getDevice().executeShellCommand(command, receiver);
84         if (false) {
85             CLog.d("Command output while parsing " + parser.getClass().getCanonicalName()
86                     + " for command: " + command + "\n"
87                     + BufferDebug.debugString(receiver.getOutput(), -1));
88         }
89         try {
90             return parser.parseFrom(receiver.getOutput());
91         } catch (Exception ex) {
92             CLog.d("Error parsing " + parser.getClass().getCanonicalName() + " for command: "
93                     + command
94                     + BufferDebug.debugString(receiver.getOutput(), 16384));
95             throw ex;
96         }
97     }
98 
99     /**
100      * Install a device side test package.
101      *
102      * @param appFileName Apk file name, such as "CtsNetStatsApp.apk".
103      * @param grantPermissions whether to give runtime permissions.
104      */
installPackage(String appFileName, boolean grantPermissions)105     protected void installPackage(String appFileName, boolean grantPermissions)
106             throws FileNotFoundException, DeviceNotAvailableException {
107         CLog.d("Installing app " + appFileName);
108         CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuild);
109         final String result = getDevice().installPackage(
110                 buildHelper.getTestFile(appFileName), true, grantPermissions);
111         assertWithMessage(String.format("Failed to install %s: %s", appFileName, result))
112             .that(result).isNull();
113     }
114 
getBuildHelper()115     protected CompatibilityBuildHelper getBuildHelper() {
116         return new CompatibilityBuildHelper(mCtsBuild);
117     }
118 
119     /**
120      * Run a device side test.
121      *
122      * @param pkgName Test package name, such as "com.android.server.cts.netstats".
123      * @param testClassName Test class name; either a fully qualified name, or "." + a class name.
124      * @param testMethodName Test method name.
125      * @return {@link TestRunResult} of this invocation.
126      * @throws DeviceNotAvailableException
127      */
128     @Nonnull
runDeviceTests(@onnull String pkgName, @Nullable String testClassName, @Nullable String testMethodName)129     protected TestRunResult runDeviceTests(@Nonnull String pkgName,
130             @Nullable String testClassName, @Nullable String testMethodName)
131             throws DeviceNotAvailableException {
132         if (testClassName != null && testClassName.startsWith(".")) {
133             testClassName = pkgName + testClassName;
134         }
135 
136         RemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(
137                 pkgName, TEST_RUNNER, getDevice().getIDevice());
138         if (testClassName != null && testMethodName != null) {
139             testRunner.setMethodName(testClassName, testMethodName);
140         } else if (testClassName != null) {
141             testRunner.setClassName(testClassName);
142         }
143 
144         CollectingTestListener listener = new CollectingTestListener();
145         assertThat(getDevice().runInstrumentationTests(testRunner, listener)).isTrue();
146 
147         final TestRunResult result = listener.getCurrentRunResults();
148         if (result.isRunFailure()) {
149             throw new Error("Failed to successfully run device tests for "
150                     + result.getName() + ": " + result.getRunFailureMessage());
151         }
152         if (result.getNumTests() == 0) {
153             throw new Error("No tests were run on the device");
154         }
155 
156         if (result.hasFailedTests()) {
157             // build a meaningful error message
158             StringBuilder errorBuilder = new StringBuilder("On-device tests failed:\n");
159             for (Map.Entry<TestDescription, TestResult> resultEntry :
160                     result.getTestResults().entrySet()) {
161                 if (!resultEntry.getValue().getStatus().equals(TestStatus.PASSED)) {
162                     errorBuilder.append(resultEntry.getKey().toString());
163                     errorBuilder.append(":\n");
164                     errorBuilder.append(resultEntry.getValue().getStackTrace());
165                 }
166             }
167             throw new AssertionError(errorBuilder.toString());
168         }
169 
170         return result;
171     }
172 }
173