blob: 21b89a5e2f935aae5e9a3c49ce6d7211df87cea5 [file] [log] [blame]
Yabin Cuib032de72015-06-17 21:15:09 -07001/*
2 * Copyright (C) 2015 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
Yabin Cuib1a885b2016-02-14 19:18:02 -080017#include <map>
Yabin Cui05400532016-03-17 21:18:53 -070018#include <memory>
Yabin Cui6e51bef2016-02-23 21:41:03 -080019#include <string>
Yabin Cui05400532016-03-17 21:18:53 -070020#include <vector>
Yabin Cuib1a885b2016-02-14 19:18:02 -080021
Yabin Cui900ea072018-03-06 11:35:22 -080022#include <android-base/file.h>
Yabin Cuidc1a4752020-02-10 17:53:34 -080023#include <android-base/strings.h>
Yabin Cui900ea072018-03-06 11:35:22 -080024
Yabin Cui87418d82018-05-21 18:31:56 -070025#include "environment.h"
Yabin Cuib1a885b2016-02-14 19:18:02 -080026#include "read_elf.h"
Yabin Cuifaa7b922021-01-11 17:35:57 -080027#include "utils.h"
Yabin Cuib032de72015-06-17 21:15:09 -070028#include "workload.h"
29
Yabin Cuifaa7b922021-01-11 17:35:57 -080030using namespace simpleperf;
31
Yabin Cui6e51bef2016-02-23 21:41:03 -080032static const std::string SLEEP_SEC = "0.001";
33
Yabin Cui616b3a02017-07-14 15:59:56 -070034void RunWorkloadFunction();
Yabin Cuib1a885b2016-02-14 19:18:02 -080035void CreateProcesses(size_t count, std::vector<std::unique_ptr<Workload>>* workloads);
36
37void ParseSymbol(const ElfFileSymbol& symbol, std::map<std::string, ElfFileSymbol>* symbols);
38void CheckElfFileSymbols(const std::map<std::string, ElfFileSymbol>& symbols);
Yabin Cui4b6720d2016-03-31 14:39:19 -070039
Thiébaud Weksteen4848ee02020-10-23 16:06:59 +020040#define TEST_IN_ROOT(TestStatement) \
41 do { \
42 if (IsRoot()) { \
43 TestStatement; \
44 } else { \
45 GTEST_LOG_(INFO) << "Didn't test \"" << #TestStatement << "\" requires root privileges"; \
46 } \
Yabin Cui4b6720d2016-03-31 14:39:19 -070047 } while (0)
Yabin Cui68b83832017-07-19 17:54:57 -070048
Thiébaud Weksteen4848ee02020-10-23 16:06:59 +020049#define TEST_REQUIRE_ROOT() \
50 do { \
51 if (!IsRoot()) { \
Yabin Cui142acc82020-10-14 10:24:38 -070052 GTEST_LOG_(INFO) << "Skip this test as it needs root privileges."; \
Thiébaud Weksteen4848ee02020-10-23 16:06:59 +020053 return; \
54 } \
Yabin Cui142acc82020-10-14 10:24:38 -070055 } while (0)
56
Yabin Cui6e7f33a2021-05-05 15:43:35 -070057#define TEST_REQUIRE_NON_ROOT() \
58 do { \
59 if (IsRoot()) { \
60 GTEST_LOG_(INFO) << "Skip this test as it tests non-root behavior."; \
61 return; \
62 } \
63 } while (0)
64
Yabin Cui68b83832017-07-19 17:54:57 -070065#if defined(__ANDROID__)
66#define TEST_REQUIRE_HOST_ROOT()
67#else
Thiébaud Weksteen4848ee02020-10-23 16:06:59 +020068#define TEST_REQUIRE_HOST_ROOT() TEST_REQUIRE_ROOT()
Yabin Cui68b83832017-07-19 17:54:57 -070069#endif
Yabin Cui64a9ecd2017-09-13 13:21:32 -070070
71bool IsInNativeAbi();
72// Used to skip tests not supposed to run on non-native ABIs.
Thiébaud Weksteen4848ee02020-10-23 16:06:59 +020073#define OMIT_TEST_ON_NON_NATIVE_ABIS() \
74 do { \
75 if (!IsInNativeAbi()) { \
Yabin Cui64a9ecd2017-09-13 13:21:32 -070076 GTEST_LOG_(INFO) << "Skip this test as it only runs on native ABIs."; \
Thiébaud Weksteen4848ee02020-10-23 16:06:59 +020077 return; \
78 } \
Yabin Cui64a9ecd2017-09-13 13:21:32 -070079 } while (0)
Yabin Cui900ea072018-03-06 11:35:22 -080080
Yabin Cui8faa6152018-06-07 15:52:57 -070081bool HasHardwareCounter();
Thiébaud Weksteen4848ee02020-10-23 16:06:59 +020082#define TEST_REQUIRE_HW_COUNTER() \
83 do { \
84 if (!HasHardwareCounter()) { \
Yabin Cui8faa6152018-06-07 15:52:57 -070085 GTEST_LOG_(INFO) << "Skip this test as the machine doesn't have hardware PMU counters."; \
Thiébaud Weksteen4848ee02020-10-23 16:06:59 +020086 return; \
87 } \
Yabin Cui8faa6152018-06-07 15:52:57 -070088 } while (0)
89
Namhyung Kim52ff4262019-10-23 12:37:34 +090090bool HasPmuCounter();
Thiébaud Weksteen4848ee02020-10-23 16:06:59 +020091#define TEST_REQUIRE_PMU_COUNTER() \
92 do { \
93 if (!HasPmuCounter()) { \
Namhyung Kim52ff4262019-10-23 12:37:34 +090094 GTEST_LOG_(INFO) << "Skip this test as the machine doesn't have low-level PMU counters."; \
Thiébaud Weksteen4848ee02020-10-23 16:06:59 +020095 return; \
96 } \
Namhyung Kim52ff4262019-10-23 12:37:34 +090097 } while (0)
98
Yabin Cui538fb532020-01-27 13:59:24 -080099bool HasTracepointEvents();
Thiébaud Weksteen4848ee02020-10-23 16:06:59 +0200100#define TEST_REQUIRE_TRACEPOINT_EVENTS() \
101 do { \
102 if (!HasTracepointEvents()) { \
Yabin Cui538fb532020-01-27 13:59:24 -0800103 GTEST_LOG_(INFO) << "Skip this test as the machine doesn't support tracepoint events."; \
Thiébaud Weksteen4848ee02020-10-23 16:06:59 +0200104 return; \
105 } \
Yabin Cui538fb532020-01-27 13:59:24 -0800106 } while (0)
107
Yabin Cuia24cf962019-01-29 17:06:42 -0800108#if defined(IN_CTS_TEST)
109#define TEST_REQUIRE_APPS()
110#else
Thiébaud Weksteen4848ee02020-10-23 16:06:59 +0200111#define TEST_REQUIRE_APPS() \
112 do { \
Yabin Cuia24cf962019-01-29 17:06:42 -0800113 GTEST_LOG_(INFO) << "Skip this test as test apps aren't available."; \
Thiébaud Weksteen4848ee02020-10-23 16:06:59 +0200114 return; \
Yabin Cuia24cf962019-01-29 17:06:42 -0800115 } while (0)
116#endif
117
Yabin Cui900ea072018-03-06 11:35:22 -0800118class CaptureStdout {
119 public:
120 CaptureStdout() : started_(false) {}
121
122 ~CaptureStdout() {
123 if (started_) {
124 Finish();
125 }
126 }
127
128 bool Start() {
129 fflush(stdout);
130 old_stdout_ = dup(STDOUT_FILENO);
131 if (old_stdout_ == -1) {
132 return false;
133 }
134 started_ = true;
135 tmpfile_.reset(new TemporaryFile);
136 if (dup2(tmpfile_->fd, STDOUT_FILENO) == -1) {
137 return false;
138 }
139 return true;
140 }
141
142 std::string Finish() {
143 fflush(stdout);
144 started_ = false;
145 dup2(old_stdout_, STDOUT_FILENO);
146 close(old_stdout_);
147 std::string s;
148 if (!android::base::ReadFileToString(tmpfile_->path, &s)) {
149 return "";
150 }
151 return s;
152 }
153
154 private:
155 bool started_;
156 int old_stdout_;
157 std::unique_ptr<TemporaryFile> tmpfile_;
158};
Yabin Cuidc1a4752020-02-10 17:53:34 -0800159
160class AppHelper {
161 public:
162 ~AppHelper() {
163 for (auto& package : installed_packages_) {
164 Workload::RunCmd({"pm", "uninstall", package});
165 }
166 }
167
168 bool InstallApk(const std::string& apk_path, const std::string& package_name) {
169 if (Workload::RunCmd({"pm", "install", "-t", "--abi", GetABI(), apk_path})) {
170 installed_packages_.emplace_back(package_name);
171 return true;
172 }
173 return false;
174 }
175
176 bool StartApp(const std::string& start_cmd) {
177 app_start_proc_ = Workload::CreateWorkload(android::base::Split(start_cmd, " "));
178 return app_start_proc_ && app_start_proc_->Start();
179 }
180
181 private:
182 const char* GetABI() {
183#if defined(__i386__)
184 return "x86";
185#elif defined(__x86_64__)
186 return "x86_64";
187#elif defined(__aarch64__)
188 return "arm64-v8a";
189#elif defined(__arm__)
190 return "armeabi-v7a";
haocheng.zy1808a5b2022-10-12 22:59:45 +0800191#elif defined(__riscv)
192 return "riscv64";
Yabin Cuidc1a4752020-02-10 17:53:34 -0800193#else
Thiébaud Weksteen4848ee02020-10-23 16:06:59 +0200194#error "unrecognized ABI"
Yabin Cuidc1a4752020-02-10 17:53:34 -0800195#endif
196 }
197
198 std::vector<std::string> installed_packages_;
199 std::unique_ptr<Workload> app_start_proc_;
haocheng.zy1808a5b2022-10-12 22:59:45 +0800200};