• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 };