1 /* 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 17 #include <map> 18 #include <memory> 19 #include <string> 20 #include <vector> 21 22 #include <android-base/file.h> 23 #include <android-base/strings.h> 24 25 #include "environment.h" 26 #include "read_elf.h" 27 #include "utils.h" 28 #include "workload.h" 29 30 using namespace simpleperf; 31 32 static const std::string SLEEP_SEC = "0.001"; 33 34 void RunWorkloadFunction(); 35 void CreateProcesses(size_t count, std::vector<std::unique_ptr<Workload>>* workloads); 36 37 void ParseSymbol(const ElfFileSymbol& symbol, std::map<std::string, ElfFileSymbol>* symbols); 38 void CheckElfFileSymbols(const std::map<std::string, ElfFileSymbol>& symbols); 39 40 #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 } \ 47 } while (0) 48 49 #define TEST_REQUIRE_ROOT() \ 50 do { \ 51 if (!IsRoot()) { \ 52 GTEST_LOG_(INFO) << "Skip this test as it needs root privileges."; \ 53 return; \ 54 } \ 55 } while (0) 56 57 #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 65 #if defined(__ANDROID__) 66 #define TEST_REQUIRE_HOST_ROOT() 67 #else 68 #define TEST_REQUIRE_HOST_ROOT() TEST_REQUIRE_ROOT() 69 #endif 70 71 bool IsInNativeAbi(); 72 // Used to skip tests not supposed to run on non-native ABIs. 73 #define OMIT_TEST_ON_NON_NATIVE_ABIS() \ 74 do { \ 75 if (!IsInNativeAbi()) { \ 76 GTEST_LOG_(INFO) << "Skip this test as it only runs on native ABIs."; \ 77 return; \ 78 } \ 79 } while (0) 80 81 bool HasHardwareCounter(); 82 #define TEST_REQUIRE_HW_COUNTER() \ 83 do { \ 84 if (!HasHardwareCounter()) { \ 85 GTEST_LOG_(INFO) << "Skip this test as the machine doesn't have hardware PMU counters."; \ 86 return; \ 87 } \ 88 } while (0) 89 90 bool HasPmuCounter(); 91 #define TEST_REQUIRE_PMU_COUNTER() \ 92 do { \ 93 if (!HasPmuCounter()) { \ 94 GTEST_LOG_(INFO) << "Skip this test as the machine doesn't have low-level PMU counters."; \ 95 return; \ 96 } \ 97 } while (0) 98 99 bool HasTracepointEvents(); 100 #define TEST_REQUIRE_TRACEPOINT_EVENTS() \ 101 do { \ 102 if (!HasTracepointEvents()) { \ 103 GTEST_LOG_(INFO) << "Skip this test as the machine doesn't support tracepoint events."; \ 104 return; \ 105 } \ 106 } while (0) 107 108 #if defined(IN_CTS_TEST) 109 #define TEST_REQUIRE_APPS() 110 #else 111 #define TEST_REQUIRE_APPS() \ 112 do { \ 113 GTEST_LOG_(INFO) << "Skip this test as test apps aren't available."; \ 114 return; \ 115 } while (0) 116 #endif 117 118 class CaptureStdout { 119 public: CaptureStdout()120 CaptureStdout() : started_(false) {} 121 ~CaptureStdout()122 ~CaptureStdout() { 123 if (started_) { 124 Finish(); 125 } 126 } 127 Start()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 Finish()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 }; 159 160 class AppHelper { 161 public: ~AppHelper()162 ~AppHelper() { 163 for (auto& package : installed_packages_) { 164 Workload::RunCmd({"pm", "uninstall", package}); 165 } 166 } 167 InstallApk(const std::string & apk_path,const std::string & package_name)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 StartApp(const std::string & start_cmd)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: GetABI()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"; 191 #else 192 #error "unrecognized ABI" 193 #endif 194 } 195 196 std::vector<std::string> installed_packages_; 197 std::unique_ptr<Workload> app_start_proc_; 198 };