blob: 4264c9a396e6cdd6f573d85410858a30da7994f4 [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 Cui00994672023-07-26 10:59:42 -070019#include <optional>
Yabin Cui6e51bef2016-02-23 21:41:03 -080020#include <string>
Yabin Cui05400532016-03-17 21:18:53 -070021#include <vector>
Yabin Cuib1a885b2016-02-14 19:18:02 -080022
Yabin Cui900ea072018-03-06 11:35:22 -080023#include <android-base/file.h>
Yabin Cuidc1a4752020-02-10 17:53:34 -080024#include <android-base/strings.h>
Yabin Cui900ea072018-03-06 11:35:22 -080025
Yabin Cui87418d82018-05-21 18:31:56 -070026#include "environment.h"
Yabin Cuib1a885b2016-02-14 19:18:02 -080027#include "read_elf.h"
Yabin Cuifaa7b922021-01-11 17:35:57 -080028#include "utils.h"
Yabin Cuib032de72015-06-17 21:15:09 -070029#include "workload.h"
30
Yabin Cuifaa7b922021-01-11 17:35:57 -080031using namespace simpleperf;
32
Yabin Cui6e51bef2016-02-23 21:41:03 -080033static const std::string SLEEP_SEC = "0.001";
34
Yabin Cui616b3a02017-07-14 15:59:56 -070035void RunWorkloadFunction();
Yabin Cuib1a885b2016-02-14 19:18:02 -080036void CreateProcesses(size_t count, std::vector<std::unique_ptr<Workload>>* workloads);
37
38void ParseSymbol(const ElfFileSymbol& symbol, std::map<std::string, ElfFileSymbol>* symbols);
39void CheckElfFileSymbols(const std::map<std::string, ElfFileSymbol>& symbols);
Yabin Cui4b6720d2016-03-31 14:39:19 -070040
Thiébaud Weksteen4848ee02020-10-23 16:06:59 +020041#define TEST_IN_ROOT(TestStatement) \
42 do { \
43 if (IsRoot()) { \
44 TestStatement; \
45 } else { \
46 GTEST_LOG_(INFO) << "Didn't test \"" << #TestStatement << "\" requires root privileges"; \
47 } \
Yabin Cui4b6720d2016-03-31 14:39:19 -070048 } while (0)
Yabin Cui68b83832017-07-19 17:54:57 -070049
Thiébaud Weksteen4848ee02020-10-23 16:06:59 +020050#define TEST_REQUIRE_ROOT() \
51 do { \
52 if (!IsRoot()) { \
Yabin Cui142acc82020-10-14 10:24:38 -070053 GTEST_LOG_(INFO) << "Skip this test as it needs root privileges."; \
Thiébaud Weksteen4848ee02020-10-23 16:06:59 +020054 return; \
55 } \
Yabin Cui142acc82020-10-14 10:24:38 -070056 } while (0)
57
Yabin Cui6e7f33a2021-05-05 15:43:35 -070058#define TEST_REQUIRE_NON_ROOT() \
59 do { \
60 if (IsRoot()) { \
61 GTEST_LOG_(INFO) << "Skip this test as it tests non-root behavior."; \
62 return; \
63 } \
64 } while (0)
65
Yabin Cui68b83832017-07-19 17:54:57 -070066#if defined(__ANDROID__)
67#define TEST_REQUIRE_HOST_ROOT()
68#else
Thiébaud Weksteen4848ee02020-10-23 16:06:59 +020069#define TEST_REQUIRE_HOST_ROOT() TEST_REQUIRE_ROOT()
Yabin Cui68b83832017-07-19 17:54:57 -070070#endif
Yabin Cui64a9ecd2017-09-13 13:21:32 -070071
Yabin Cui00994672023-07-26 10:59:42 -070072std::optional<bool> IsInNativeAbi();
Yabin Cui64a9ecd2017-09-13 13:21:32 -070073// Used to skip tests not supposed to run on non-native ABIs.
Thiébaud Weksteen4848ee02020-10-23 16:06:59 +020074#define OMIT_TEST_ON_NON_NATIVE_ABIS() \
75 do { \
Yabin Cui00994672023-07-26 10:59:42 -070076 std::optional<bool> in_native_abi = IsInNativeAbi(); \
77 ASSERT_TRUE(in_native_abi.has_value()); \
78 if (!in_native_abi.value()) { \
Yabin Cui64a9ecd2017-09-13 13:21:32 -070079 GTEST_LOG_(INFO) << "Skip this test as it only runs on native ABIs."; \
Thiébaud Weksteen4848ee02020-10-23 16:06:59 +020080 return; \
81 } \
Yabin Cui64a9ecd2017-09-13 13:21:32 -070082 } while (0)
Yabin Cui900ea072018-03-06 11:35:22 -080083
Yabin Cui8faa6152018-06-07 15:52:57 -070084bool HasHardwareCounter();
Thiébaud Weksteen4848ee02020-10-23 16:06:59 +020085#define TEST_REQUIRE_HW_COUNTER() \
86 do { \
87 if (!HasHardwareCounter()) { \
Yabin Cui8faa6152018-06-07 15:52:57 -070088 GTEST_LOG_(INFO) << "Skip this test as the machine doesn't have hardware PMU counters."; \
Thiébaud Weksteen4848ee02020-10-23 16:06:59 +020089 return; \
90 } \
Yabin Cui8faa6152018-06-07 15:52:57 -070091 } while (0)
92
Namhyung Kim52ff4262019-10-23 12:37:34 +090093bool HasPmuCounter();
Thiébaud Weksteen4848ee02020-10-23 16:06:59 +020094#define TEST_REQUIRE_PMU_COUNTER() \
95 do { \
96 if (!HasPmuCounter()) { \
Namhyung Kim52ff4262019-10-23 12:37:34 +090097 GTEST_LOG_(INFO) << "Skip this test as the machine doesn't have low-level PMU counters."; \
Thiébaud Weksteen4848ee02020-10-23 16:06:59 +020098 return; \
99 } \
Namhyung Kim52ff4262019-10-23 12:37:34 +0900100 } while (0)
101
Yabin Cui538fb532020-01-27 13:59:24 -0800102bool HasTracepointEvents();
Thiébaud Weksteen4848ee02020-10-23 16:06:59 +0200103#define TEST_REQUIRE_TRACEPOINT_EVENTS() \
104 do { \
105 if (!HasTracepointEvents()) { \
Yabin Cui538fb532020-01-27 13:59:24 -0800106 GTEST_LOG_(INFO) << "Skip this test as the machine doesn't support tracepoint events."; \
Thiébaud Weksteen4848ee02020-10-23 16:06:59 +0200107 return; \
108 } \
Yabin Cui538fb532020-01-27 13:59:24 -0800109 } while (0)
110
Yabin Cuia24cf962019-01-29 17:06:42 -0800111#if defined(IN_CTS_TEST)
112#define TEST_REQUIRE_APPS()
113#else
Thiébaud Weksteen4848ee02020-10-23 16:06:59 +0200114#define TEST_REQUIRE_APPS() \
115 do { \
Yabin Cuia24cf962019-01-29 17:06:42 -0800116 GTEST_LOG_(INFO) << "Skip this test as test apps aren't available."; \
Thiébaud Weksteen4848ee02020-10-23 16:06:59 +0200117 return; \
Yabin Cuia24cf962019-01-29 17:06:42 -0800118 } while (0)
119#endif
120
Yabin Cui900ea072018-03-06 11:35:22 -0800121class CaptureStdout {
122 public:
123 CaptureStdout() : started_(false) {}
124
125 ~CaptureStdout() {
126 if (started_) {
127 Finish();
128 }
129 }
130
131 bool Start() {
132 fflush(stdout);
133 old_stdout_ = dup(STDOUT_FILENO);
134 if (old_stdout_ == -1) {
135 return false;
136 }
137 started_ = true;
138 tmpfile_.reset(new TemporaryFile);
139 if (dup2(tmpfile_->fd, STDOUT_FILENO) == -1) {
140 return false;
141 }
142 return true;
143 }
144
145 std::string Finish() {
146 fflush(stdout);
147 started_ = false;
148 dup2(old_stdout_, STDOUT_FILENO);
149 close(old_stdout_);
150 std::string s;
151 if (!android::base::ReadFileToString(tmpfile_->path, &s)) {
152 return "";
153 }
154 return s;
155 }
156
157 private:
158 bool started_;
159 int old_stdout_;
160 std::unique_ptr<TemporaryFile> tmpfile_;
161};
Yabin Cuidc1a4752020-02-10 17:53:34 -0800162
163class AppHelper {
164 public:
165 ~AppHelper() {
166 for (auto& package : installed_packages_) {
167 Workload::RunCmd({"pm", "uninstall", package});
168 }
169 }
170
171 bool InstallApk(const std::string& apk_path, const std::string& package_name) {
172 if (Workload::RunCmd({"pm", "install", "-t", "--abi", GetABI(), apk_path})) {
173 installed_packages_.emplace_back(package_name);
174 return true;
175 }
176 return false;
177 }
178
179 bool StartApp(const std::string& start_cmd) {
180 app_start_proc_ = Workload::CreateWorkload(android::base::Split(start_cmd, " "));
181 return app_start_proc_ && app_start_proc_->Start();
182 }
183
184 private:
185 const char* GetABI() {
186#if defined(__i386__)
187 return "x86";
188#elif defined(__x86_64__)
189 return "x86_64";
190#elif defined(__aarch64__)
191 return "arm64-v8a";
192#elif defined(__arm__)
193 return "armeabi-v7a";
haocheng.zy1808a5b2022-10-12 22:59:45 +0800194#elif defined(__riscv)
195 return "riscv64";
Yabin Cuidc1a4752020-02-10 17:53:34 -0800196#else
Thiébaud Weksteen4848ee02020-10-23 16:06:59 +0200197#error "unrecognized ABI"
Yabin Cuidc1a4752020-02-10 17:53:34 -0800198#endif
199 }
200
201 std::vector<std::string> installed_packages_;
202 std::unique_ptr<Workload> app_start_proc_;
haocheng.zy1808a5b2022-10-12 22:59:45 +0800203};
Yabin Cuib68f0f92024-04-15 16:34:00 -0700204
205bool IsInEmulator();