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 
24 #include "environment.h"
25 #include "read_elf.h"
26 #include "workload.h"
27 
28 static const std::string SLEEP_SEC = "0.001";
29 
30 void RunWorkloadFunction();
31 void CreateProcesses(size_t count, std::vector<std::unique_ptr<Workload>>* workloads);
32 
33 void ParseSymbol(const ElfFileSymbol& symbol, std::map<std::string, ElfFileSymbol>* symbols);
34 void CheckElfFileSymbols(const std::map<std::string, ElfFileSymbol>& symbols);
35 
36 bool IsRoot();
37 
38 #define TEST_IN_ROOT(TestStatement)                                                                \
39   do {                                                                                             \
40     if (IsRoot()) {                                                                                \
41       TestStatement;                                                                               \
42     } else {                                                                                       \
43       GTEST_LOG_(INFO) << "Didn't test \"" << #TestStatement << "\" requires root privileges";     \
44     }                                                                                              \
45   } while (0)
46 
47 #if defined(__ANDROID__)
48 #define TEST_REQUIRE_HOST_ROOT()
49 #else
50 #define TEST_REQUIRE_HOST_ROOT()  if (!IsRoot()) return
51 #endif
52 
53 bool IsInNativeAbi();
54 // Used to skip tests not supposed to run on non-native ABIs.
55 #define OMIT_TEST_ON_NON_NATIVE_ABIS()  \
56   do { \
57     if (!IsInNativeAbi()) { \
58       GTEST_LOG_(INFO) << "Skip this test as it only runs on native ABIs."; \
59       return; \
60     } \
61   } while (0)
62 
63 bool HasHardwareCounter();
64 #define TEST_REQUIRE_HW_COUNTER() \
65   do { \
66     if (!HasHardwareCounter()) { \
67       GTEST_LOG_(INFO) << "Skip this test as the machine doesn't have hardware PMU counters."; \
68       return; \
69     } \
70   } while (0)
71 
72 #if defined(IN_CTS_TEST)
73 #define TEST_REQUIRE_APPS()
74 #else
75 #define TEST_REQUIRE_APPS() \
76   do { \
77     GTEST_LOG_(INFO) << "Skip this test as test apps aren't available."; \
78     return; \
79   } while (0)
80 #endif
81 
82 class CaptureStdout {
83  public:
CaptureStdout()84   CaptureStdout() : started_(false) {}
85 
~CaptureStdout()86   ~CaptureStdout() {
87     if (started_) {
88       Finish();
89     }
90   }
91 
Start()92   bool Start() {
93     fflush(stdout);
94     old_stdout_ = dup(STDOUT_FILENO);
95     if (old_stdout_ == -1) {
96       return false;
97     }
98     started_ = true;
99     tmpfile_.reset(new TemporaryFile);
100     if (dup2(tmpfile_->fd, STDOUT_FILENO) == -1) {
101       return false;
102     }
103     return true;
104   }
105 
Finish()106   std::string Finish() {
107     fflush(stdout);
108     started_ = false;
109     dup2(old_stdout_, STDOUT_FILENO);
110     close(old_stdout_);
111     std::string s;
112     if (!android::base::ReadFileToString(tmpfile_->path, &s)) {
113       return "";
114     }
115     return s;
116   }
117 
118  private:
119   bool started_;
120   int old_stdout_;
121   std::unique_ptr<TemporaryFile> tmpfile_;
122 };
123