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 "workload.h" 28 29 static const std::string SLEEP_SEC = "0.001"; 30 31 void RunWorkloadFunction(); 32 void CreateProcesses(size_t count, std::vector<std::unique_ptr<Workload>>* workloads); 33 34 void ParseSymbol(const ElfFileSymbol& symbol, std::map<std::string, ElfFileSymbol>* symbols); 35 void CheckElfFileSymbols(const std::map<std::string, ElfFileSymbol>& symbols); 36 37 bool IsRoot(); 38 39 #define TEST_IN_ROOT(TestStatement) \ 40 do { \ 41 if (IsRoot()) { \ 42 TestStatement; \ 43 } else { \ 44 GTEST_LOG_(INFO) << "Didn't test \"" << #TestStatement << "\" requires root privileges"; \ 45 } \ 46 } while (0) 47 48 #if defined(__ANDROID__) 49 #define TEST_REQUIRE_HOST_ROOT() 50 #else 51 #define TEST_REQUIRE_HOST_ROOT() if (!IsRoot()) return 52 #endif 53 54 bool IsInNativeAbi(); 55 // Used to skip tests not supposed to run on non-native ABIs. 56 #define OMIT_TEST_ON_NON_NATIVE_ABIS() \ 57 do { \ 58 if (!IsInNativeAbi()) { \ 59 GTEST_LOG_(INFO) << "Skip this test as it only runs on native ABIs."; \ 60 return; \ 61 } \ 62 } while (0) 63 64 bool HasHardwareCounter(); 65 #define TEST_REQUIRE_HW_COUNTER() \ 66 do { \ 67 if (!HasHardwareCounter()) { \ 68 GTEST_LOG_(INFO) << "Skip this test as the machine doesn't have hardware PMU counters."; \ 69 return; \ 70 } \ 71 } while (0) 72 73 bool HasPmuCounter(); 74 #define TEST_REQUIRE_PMU_COUNTER() \ 75 do { \ 76 if (!HasPmuCounter()) { \ 77 GTEST_LOG_(INFO) << "Skip this test as the machine doesn't have low-level PMU counters."; \ 78 return; \ 79 } \ 80 } while (0) 81 82 bool HasTracepointEvents(); 83 #define TEST_REQUIRE_TRACEPOINT_EVENTS() \ 84 do { \ 85 if (!HasTracepointEvents()) { \ 86 GTEST_LOG_(INFO) << "Skip this test as the machine doesn't support tracepoint events."; \ 87 return; \ 88 } \ 89 } while (0) 90 91 #if defined(IN_CTS_TEST) 92 #define TEST_REQUIRE_APPS() 93 #else 94 #define TEST_REQUIRE_APPS() \ 95 do { \ 96 GTEST_LOG_(INFO) << "Skip this test as test apps aren't available."; \ 97 return; \ 98 } while (0) 99 #endif 100 101 class CaptureStdout { 102 public: CaptureStdout()103 CaptureStdout() : started_(false) {} 104 ~CaptureStdout()105 ~CaptureStdout() { 106 if (started_) { 107 Finish(); 108 } 109 } 110 Start()111 bool Start() { 112 fflush(stdout); 113 old_stdout_ = dup(STDOUT_FILENO); 114 if (old_stdout_ == -1) { 115 return false; 116 } 117 started_ = true; 118 tmpfile_.reset(new TemporaryFile); 119 if (dup2(tmpfile_->fd, STDOUT_FILENO) == -1) { 120 return false; 121 } 122 return true; 123 } 124 Finish()125 std::string Finish() { 126 fflush(stdout); 127 started_ = false; 128 dup2(old_stdout_, STDOUT_FILENO); 129 close(old_stdout_); 130 std::string s; 131 if (!android::base::ReadFileToString(tmpfile_->path, &s)) { 132 return ""; 133 } 134 return s; 135 } 136 137 private: 138 bool started_; 139 int old_stdout_; 140 std::unique_ptr<TemporaryFile> tmpfile_; 141 }; 142 143 class AppHelper { 144 public: ~AppHelper()145 ~AppHelper() { 146 for (auto& package : installed_packages_) { 147 Workload::RunCmd({"pm", "uninstall", package}); 148 } 149 } 150 InstallApk(const std::string & apk_path,const std::string & package_name)151 bool InstallApk(const std::string& apk_path, const std::string& package_name) { 152 if (Workload::RunCmd({"pm", "install", "-t", "--abi", GetABI(), apk_path})) { 153 installed_packages_.emplace_back(package_name); 154 return true; 155 } 156 return false; 157 } 158 StartApp(const std::string & start_cmd)159 bool StartApp(const std::string& start_cmd) { 160 app_start_proc_ = Workload::CreateWorkload(android::base::Split(start_cmd, " ")); 161 return app_start_proc_ && app_start_proc_->Start(); 162 } 163 164 private: GetABI()165 const char* GetABI() { 166 #if defined(__i386__) 167 return "x86"; 168 #elif defined(__x86_64__) 169 return "x86_64"; 170 #elif defined(__aarch64__) 171 return "arm64-v8a"; 172 #elif defined(__arm__) 173 return "armeabi-v7a"; 174 #else 175 #error "unrecognized ABI" 176 #endif 177 } 178 179 std::vector<std::string> installed_packages_; 180 std::unique_ptr<Workload> app_start_proc_; 181 };