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