xref: /aosp_15_r20/art/runtime/exec_utils_test.cc (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2011 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker #include "exec_utils.h"
18*795d594fSAndroid Build Coastguard Worker 
19*795d594fSAndroid Build Coastguard Worker #include <sys/utsname.h>
20*795d594fSAndroid Build Coastguard Worker #include <unistd.h>
21*795d594fSAndroid Build Coastguard Worker 
22*795d594fSAndroid Build Coastguard Worker #include <csignal>
23*795d594fSAndroid Build Coastguard Worker #include <cstdio>
24*795d594fSAndroid Build Coastguard Worker #include <cstring>
25*795d594fSAndroid Build Coastguard Worker #include <filesystem>
26*795d594fSAndroid Build Coastguard Worker #include <memory>
27*795d594fSAndroid Build Coastguard Worker #include <optional>
28*795d594fSAndroid Build Coastguard Worker #include <tuple>
29*795d594fSAndroid Build Coastguard Worker 
30*795d594fSAndroid Build Coastguard Worker #include "android-base/logging.h"
31*795d594fSAndroid Build Coastguard Worker #include "android-base/result.h"
32*795d594fSAndroid Build Coastguard Worker #include "android-base/stringprintf.h"
33*795d594fSAndroid Build Coastguard Worker #include "base/file_utils.h"
34*795d594fSAndroid Build Coastguard Worker #include "base/memory_tool.h"
35*795d594fSAndroid Build Coastguard Worker #include "common_runtime_test.h"
36*795d594fSAndroid Build Coastguard Worker #include "gmock/gmock.h"
37*795d594fSAndroid Build Coastguard Worker #include "gtest/gtest.h"
38*795d594fSAndroid Build Coastguard Worker 
39*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
40*795d594fSAndroid Build Coastguard Worker 
41*795d594fSAndroid Build Coastguard Worker using ::android::base::Result;
42*795d594fSAndroid Build Coastguard Worker using ::testing::_;
43*795d594fSAndroid Build Coastguard Worker using ::testing::AllOf;
44*795d594fSAndroid Build Coastguard Worker using ::testing::Gt;
45*795d594fSAndroid Build Coastguard Worker using ::testing::HasSubstr;
46*795d594fSAndroid Build Coastguard Worker using ::testing::InSequence;
47*795d594fSAndroid Build Coastguard Worker using ::testing::MockFunction;
48*795d594fSAndroid Build Coastguard Worker using ::testing::Ne;
49*795d594fSAndroid Build Coastguard Worker using ::testing::Return;
50*795d594fSAndroid Build Coastguard Worker 
51*795d594fSAndroid Build Coastguard Worker std::string PrettyArguments(const char* signature);
52*795d594fSAndroid Build Coastguard Worker std::string PrettyReturnType(const char* signature);
53*795d594fSAndroid Build Coastguard Worker 
GetBin(const std::string & name)54*795d594fSAndroid Build Coastguard Worker std::string GetBin(const std::string& name) {
55*795d594fSAndroid Build Coastguard Worker   if (kIsTargetBuild) {
56*795d594fSAndroid Build Coastguard Worker     std::string android_root(GetAndroidRoot());
57*795d594fSAndroid Build Coastguard Worker     return android_root + "/bin/" + name;
58*795d594fSAndroid Build Coastguard Worker   } else if (std::filesystem::exists("/usr/bin/" + name)) {
59*795d594fSAndroid Build Coastguard Worker     return "/usr/bin/" + name;
60*795d594fSAndroid Build Coastguard Worker   } else {
61*795d594fSAndroid Build Coastguard Worker     return "/bin/" + name;
62*795d594fSAndroid Build Coastguard Worker   }
63*795d594fSAndroid Build Coastguard Worker }
64*795d594fSAndroid Build Coastguard Worker 
GetKernelVersion()65*795d594fSAndroid Build Coastguard Worker std::tuple<int, int> GetKernelVersion() {
66*795d594fSAndroid Build Coastguard Worker   std::tuple<int, int> version;
67*795d594fSAndroid Build Coastguard Worker   utsname uts;
68*795d594fSAndroid Build Coastguard Worker   CHECK_EQ(uname(&uts), 0);
69*795d594fSAndroid Build Coastguard Worker   CHECK_EQ(sscanf(uts.release, "%d.%d", &std::get<0>(version), &std::get<1>(version)), 2);
70*795d594fSAndroid Build Coastguard Worker   return version;
71*795d594fSAndroid Build Coastguard Worker }
72*795d594fSAndroid Build Coastguard Worker 
73*795d594fSAndroid Build Coastguard Worker class TestingExecUtils : public ExecUtils {
74*795d594fSAndroid Build Coastguard Worker  public:
75*795d594fSAndroid Build Coastguard Worker   MOCK_METHOD(std::string, GetProcStat, (pid_t pid), (const, override));
76*795d594fSAndroid Build Coastguard Worker   MOCK_METHOD(Result<int64_t>, DoGetUptimeMs, (), (const));
77*795d594fSAndroid Build Coastguard Worker   MOCK_METHOD(int64_t, GetTicksPerSec, (), (const, override));
78*795d594fSAndroid Build Coastguard Worker 
79*795d594fSAndroid Build Coastguard Worker   // A workaround to avoid MOCK_METHOD on a method with an `std::string*` parameter, which will lead
80*795d594fSAndroid Build Coastguard Worker   // to a conflict between gmock and android-base/logging.h (b/132668253).
GetUptimeMs(std::string * error_msg) const81*795d594fSAndroid Build Coastguard Worker   std::optional<int64_t> GetUptimeMs(std::string* error_msg) const override {
82*795d594fSAndroid Build Coastguard Worker     Result<int64_t> result = DoGetUptimeMs();
83*795d594fSAndroid Build Coastguard Worker     if (result.ok()) {
84*795d594fSAndroid Build Coastguard Worker       return *result;
85*795d594fSAndroid Build Coastguard Worker     }
86*795d594fSAndroid Build Coastguard Worker     *error_msg = result.error().message();
87*795d594fSAndroid Build Coastguard Worker     return std::nullopt;
88*795d594fSAndroid Build Coastguard Worker   }
89*795d594fSAndroid Build Coastguard Worker };
90*795d594fSAndroid Build Coastguard Worker 
91*795d594fSAndroid Build Coastguard Worker class AlwaysFallbackExecUtils : public TestingExecUtils {
92*795d594fSAndroid Build Coastguard Worker  protected:
PidfdOpen(pid_t) const93*795d594fSAndroid Build Coastguard Worker   android::base::unique_fd PidfdOpen(pid_t) const override { return android::base::unique_fd(-1); }
94*795d594fSAndroid Build Coastguard Worker };
95*795d594fSAndroid Build Coastguard Worker 
96*795d594fSAndroid Build Coastguard Worker class NeverFallbackExecUtils : public TestingExecUtils {
97*795d594fSAndroid Build Coastguard Worker  protected:
PidfdOpen(pid_t pid) const98*795d594fSAndroid Build Coastguard Worker   android::base::unique_fd PidfdOpen(pid_t pid) const override {
99*795d594fSAndroid Build Coastguard Worker     android::base::unique_fd pidfd = ExecUtils::PidfdOpen(pid);
100*795d594fSAndroid Build Coastguard Worker     CHECK_GE(pidfd.get(), 0) << strerror(errno);
101*795d594fSAndroid Build Coastguard Worker     return pidfd;
102*795d594fSAndroid Build Coastguard Worker   }
103*795d594fSAndroid Build Coastguard Worker };
104*795d594fSAndroid Build Coastguard Worker 
105*795d594fSAndroid Build Coastguard Worker class ExecUtilsTest : public CommonRuntimeTest, public testing::WithParamInterface<bool> {
106*795d594fSAndroid Build Coastguard Worker  protected:
SetUp()107*795d594fSAndroid Build Coastguard Worker   void SetUp() override {
108*795d594fSAndroid Build Coastguard Worker     CommonRuntimeTest::SetUp();
109*795d594fSAndroid Build Coastguard Worker     bool always_fallback = GetParam();
110*795d594fSAndroid Build Coastguard Worker     if (always_fallback) {
111*795d594fSAndroid Build Coastguard Worker       exec_utils_ = std::make_unique<AlwaysFallbackExecUtils>();
112*795d594fSAndroid Build Coastguard Worker     } else {
113*795d594fSAndroid Build Coastguard Worker       if (GetKernelVersion() >= std::make_tuple(5, 4)) {
114*795d594fSAndroid Build Coastguard Worker         exec_utils_ = std::make_unique<NeverFallbackExecUtils>();
115*795d594fSAndroid Build Coastguard Worker       } else {
116*795d594fSAndroid Build Coastguard Worker         GTEST_SKIP() << "Kernel version older than 5.4";
117*795d594fSAndroid Build Coastguard Worker       }
118*795d594fSAndroid Build Coastguard Worker     }
119*795d594fSAndroid Build Coastguard Worker   }
120*795d594fSAndroid Build Coastguard Worker 
121*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<TestingExecUtils> exec_utils_;
122*795d594fSAndroid Build Coastguard Worker };
123*795d594fSAndroid Build Coastguard Worker 
TEST_P(ExecUtilsTest,ExecSuccess)124*795d594fSAndroid Build Coastguard Worker TEST_P(ExecUtilsTest, ExecSuccess) {
125*795d594fSAndroid Build Coastguard Worker   std::vector<std::string> command;
126*795d594fSAndroid Build Coastguard Worker   command.push_back(GetBin("id"));
127*795d594fSAndroid Build Coastguard Worker   std::string error_msg;
128*795d594fSAndroid Build Coastguard Worker   // Historical note: Running on Valgrind failed due to some memory
129*795d594fSAndroid Build Coastguard Worker   // that leaks in thread alternate signal stacks.
130*795d594fSAndroid Build Coastguard Worker   EXPECT_TRUE(exec_utils_->Exec(command, &error_msg));
131*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, error_msg.size()) << error_msg;
132*795d594fSAndroid Build Coastguard Worker }
133*795d594fSAndroid Build Coastguard Worker 
TEST_P(ExecUtilsTest,ExecError)134*795d594fSAndroid Build Coastguard Worker TEST_P(ExecUtilsTest, ExecError) {
135*795d594fSAndroid Build Coastguard Worker   std::vector<std::string> command;
136*795d594fSAndroid Build Coastguard Worker   command.push_back("bogus");
137*795d594fSAndroid Build Coastguard Worker   std::string error_msg;
138*795d594fSAndroid Build Coastguard Worker   // Historical note: Running on Valgrind failed due to some memory
139*795d594fSAndroid Build Coastguard Worker   // that leaks in thread alternate signal stacks.
140*795d594fSAndroid Build Coastguard Worker   ExecResult result = exec_utils_->ExecAndReturnResult(command, /*timeout_sec=*/-1, &error_msg);
141*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(result.status, ExecResult::kSignaled);
142*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(result.signal, SIGABRT);
143*795d594fSAndroid Build Coastguard Worker   EXPECT_FALSE(error_msg.empty());
144*795d594fSAndroid Build Coastguard Worker }
145*795d594fSAndroid Build Coastguard Worker 
TEST_P(ExecUtilsTest,EnvSnapshotAdditionsAreNotVisible)146*795d594fSAndroid Build Coastguard Worker TEST_P(ExecUtilsTest, EnvSnapshotAdditionsAreNotVisible) {
147*795d594fSAndroid Build Coastguard Worker   static constexpr const char* kModifiedVariable = "EXEC_SHOULD_NOT_EXPORT_THIS";
148*795d594fSAndroid Build Coastguard Worker   static constexpr int kOverwrite = 1;
149*795d594fSAndroid Build Coastguard Worker   // Set an variable in the current environment.
150*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(setenv(kModifiedVariable, "NEVER", kOverwrite), 0);
151*795d594fSAndroid Build Coastguard Worker   // Test that it is not exported.
152*795d594fSAndroid Build Coastguard Worker   std::vector<std::string> command;
153*795d594fSAndroid Build Coastguard Worker   command.push_back(GetBin("printenv"));
154*795d594fSAndroid Build Coastguard Worker   command.push_back(kModifiedVariable);
155*795d594fSAndroid Build Coastguard Worker   std::string error_msg;
156*795d594fSAndroid Build Coastguard Worker   // Historical note: Running on Valgrind failed due to some memory
157*795d594fSAndroid Build Coastguard Worker   // that leaks in thread alternate signal stacks.
158*795d594fSAndroid Build Coastguard Worker   EXPECT_FALSE(exec_utils_->Exec(command, &error_msg));
159*795d594fSAndroid Build Coastguard Worker   EXPECT_NE(0U, error_msg.size()) << error_msg;
160*795d594fSAndroid Build Coastguard Worker }
161*795d594fSAndroid Build Coastguard Worker 
TEST_P(ExecUtilsTest,EnvSnapshotDeletionsAreNotVisible)162*795d594fSAndroid Build Coastguard Worker TEST_P(ExecUtilsTest, EnvSnapshotDeletionsAreNotVisible) {
163*795d594fSAndroid Build Coastguard Worker   static constexpr const char* kDeletedVariable = "PATH";
164*795d594fSAndroid Build Coastguard Worker   static constexpr int kOverwrite = 1;
165*795d594fSAndroid Build Coastguard Worker   // Save the variable's value.
166*795d594fSAndroid Build Coastguard Worker   const char* save_value = getenv(kDeletedVariable);
167*795d594fSAndroid Build Coastguard Worker   EXPECT_NE(save_value, nullptr);
168*795d594fSAndroid Build Coastguard Worker   // Delete the variable.
169*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(unsetenv(kDeletedVariable), 0);
170*795d594fSAndroid Build Coastguard Worker   // Test that it is not exported.
171*795d594fSAndroid Build Coastguard Worker   std::vector<std::string> command;
172*795d594fSAndroid Build Coastguard Worker   command.push_back(GetBin("printenv"));
173*795d594fSAndroid Build Coastguard Worker   command.push_back(kDeletedVariable);
174*795d594fSAndroid Build Coastguard Worker   std::string error_msg;
175*795d594fSAndroid Build Coastguard Worker   // Historical note: Running on Valgrind failed due to some memory
176*795d594fSAndroid Build Coastguard Worker   // that leaks in thread alternate signal stacks.
177*795d594fSAndroid Build Coastguard Worker   EXPECT_TRUE(exec_utils_->Exec(command, &error_msg));
178*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, error_msg.size()) << error_msg;
179*795d594fSAndroid Build Coastguard Worker   // Restore the variable's value.
180*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(setenv(kDeletedVariable, save_value, kOverwrite), 0);
181*795d594fSAndroid Build Coastguard Worker }
182*795d594fSAndroid Build Coastguard Worker 
SleepCommand(int sleep_seconds)183*795d594fSAndroid Build Coastguard Worker static std::vector<std::string> SleepCommand(int sleep_seconds) {
184*795d594fSAndroid Build Coastguard Worker   std::vector<std::string> command;
185*795d594fSAndroid Build Coastguard Worker   command.push_back(GetBin("sleep"));
186*795d594fSAndroid Build Coastguard Worker   command.push_back(android::base::StringPrintf("%d", sleep_seconds));
187*795d594fSAndroid Build Coastguard Worker   return command;
188*795d594fSAndroid Build Coastguard Worker }
189*795d594fSAndroid Build Coastguard Worker 
TEST_P(ExecUtilsTest,ExecTimeout)190*795d594fSAndroid Build Coastguard Worker TEST_P(ExecUtilsTest, ExecTimeout) {
191*795d594fSAndroid Build Coastguard Worker   static constexpr int kSleepSeconds = 5;
192*795d594fSAndroid Build Coastguard Worker   static constexpr int kWaitSeconds = 1;
193*795d594fSAndroid Build Coastguard Worker   std::vector<std::string> command = SleepCommand(kSleepSeconds);
194*795d594fSAndroid Build Coastguard Worker   std::string error_msg;
195*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(exec_utils_->ExecAndReturnResult(command, kWaitSeconds, &error_msg).status,
196*795d594fSAndroid Build Coastguard Worker             ExecResult::kTimedOut)
197*795d594fSAndroid Build Coastguard Worker       << error_msg;
198*795d594fSAndroid Build Coastguard Worker   EXPECT_THAT(error_msg, HasSubstr("timed out"));
199*795d594fSAndroid Build Coastguard Worker }
200*795d594fSAndroid Build Coastguard Worker 
TEST_P(ExecUtilsTest,ExecNoTimeout)201*795d594fSAndroid Build Coastguard Worker TEST_P(ExecUtilsTest, ExecNoTimeout) {
202*795d594fSAndroid Build Coastguard Worker   static constexpr int kSleepSeconds = 1;
203*795d594fSAndroid Build Coastguard Worker   static constexpr int kWaitSeconds = 5;
204*795d594fSAndroid Build Coastguard Worker   std::vector<std::string> command = SleepCommand(kSleepSeconds);
205*795d594fSAndroid Build Coastguard Worker   std::string error_msg;
206*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(exec_utils_->ExecAndReturnResult(command, kWaitSeconds, &error_msg).status,
207*795d594fSAndroid Build Coastguard Worker             ExecResult::kExited)
208*795d594fSAndroid Build Coastguard Worker       << error_msg;
209*795d594fSAndroid Build Coastguard Worker }
210*795d594fSAndroid Build Coastguard Worker 
TEST_P(ExecUtilsTest,ExecStat)211*795d594fSAndroid Build Coastguard Worker TEST_P(ExecUtilsTest, ExecStat) {
212*795d594fSAndroid Build Coastguard Worker   std::vector<std::string> command;
213*795d594fSAndroid Build Coastguard Worker   command.push_back(GetBin("id"));
214*795d594fSAndroid Build Coastguard Worker 
215*795d594fSAndroid Build Coastguard Worker   std::string error_msg;
216*795d594fSAndroid Build Coastguard Worker   ProcessStat stat;
217*795d594fSAndroid Build Coastguard Worker 
218*795d594fSAndroid Build Coastguard Worker   // The process filename is "a) b".
219*795d594fSAndroid Build Coastguard Worker   EXPECT_CALL(*exec_utils_, GetProcStat(_))
220*795d594fSAndroid Build Coastguard Worker       .WillOnce(Return(
221*795d594fSAndroid Build Coastguard Worker           "14963 (a) b) Z 6067 14963 1 0 -1 4228108 105 0 0 0 94 5 0 0 39 19 1 0 0 0 0 "
222*795d594fSAndroid Build Coastguard Worker           "18446744073709551615 0 0 0 0 0 0 20999 0 0 1 0 0 17 71 0 0 0 0 0 0 0 0 0 0 0 0 9"));
223*795d594fSAndroid Build Coastguard Worker   EXPECT_CALL(*exec_utils_, DoGetUptimeMs())
224*795d594fSAndroid Build Coastguard Worker       .WillOnce(Return(1620343880ll))
225*795d594fSAndroid Build Coastguard Worker       .WillOnce(Return(1620344887ll));
226*795d594fSAndroid Build Coastguard Worker   EXPECT_CALL(*exec_utils_, GetTicksPerSec()).WillOnce(Return(100));
227*795d594fSAndroid Build Coastguard Worker 
228*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(exec_utils_
229*795d594fSAndroid Build Coastguard Worker                 ->ExecAndReturnResult(command,
230*795d594fSAndroid Build Coastguard Worker                                       /*timeout_sec=*/-1,
231*795d594fSAndroid Build Coastguard Worker                                       ExecCallbacks(),
232*795d594fSAndroid Build Coastguard Worker                                       /*new_process_group=*/false,
233*795d594fSAndroid Build Coastguard Worker                                       &stat,
234*795d594fSAndroid Build Coastguard Worker                                       &error_msg)
235*795d594fSAndroid Build Coastguard Worker                 .status,
236*795d594fSAndroid Build Coastguard Worker             ExecResult::kExited)
237*795d594fSAndroid Build Coastguard Worker       << error_msg;
238*795d594fSAndroid Build Coastguard Worker 
239*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(stat.cpu_time_ms, 990);
240*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(stat.wall_time_ms, 1007);
241*795d594fSAndroid Build Coastguard Worker }
242*795d594fSAndroid Build Coastguard Worker 
TEST_P(ExecUtilsTest,ExecStatNoStartTime)243*795d594fSAndroid Build Coastguard Worker TEST_P(ExecUtilsTest, ExecStatNoStartTime) {
244*795d594fSAndroid Build Coastguard Worker   std::vector<std::string> command;
245*795d594fSAndroid Build Coastguard Worker   command.push_back(GetBin("id"));
246*795d594fSAndroid Build Coastguard Worker 
247*795d594fSAndroid Build Coastguard Worker   std::string error_msg;
248*795d594fSAndroid Build Coastguard Worker   ProcessStat stat;
249*795d594fSAndroid Build Coastguard Worker 
250*795d594fSAndroid Build Coastguard Worker   EXPECT_CALL(*exec_utils_, DoGetUptimeMs())
251*795d594fSAndroid Build Coastguard Worker       .WillOnce(Return(Result<int64_t>(Errorf("Failed to get uptime"))));
252*795d594fSAndroid Build Coastguard Worker 
253*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(exec_utils_
254*795d594fSAndroid Build Coastguard Worker                 ->ExecAndReturnResult(command,
255*795d594fSAndroid Build Coastguard Worker                                       /*timeout_sec=*/-1,
256*795d594fSAndroid Build Coastguard Worker                                       ExecCallbacks(),
257*795d594fSAndroid Build Coastguard Worker                                       /*new_process_group=*/false,
258*795d594fSAndroid Build Coastguard Worker                                       &stat,
259*795d594fSAndroid Build Coastguard Worker                                       &error_msg)
260*795d594fSAndroid Build Coastguard Worker                 .status,
261*795d594fSAndroid Build Coastguard Worker             ExecResult::kExited)
262*795d594fSAndroid Build Coastguard Worker       << error_msg;
263*795d594fSAndroid Build Coastguard Worker 
264*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(stat.cpu_time_ms, 0);
265*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(stat.wall_time_ms, 0);
266*795d594fSAndroid Build Coastguard Worker }
267*795d594fSAndroid Build Coastguard Worker 
TEST_P(ExecUtilsTest,ExecStatNoUptime)268*795d594fSAndroid Build Coastguard Worker TEST_P(ExecUtilsTest, ExecStatNoUptime) {
269*795d594fSAndroid Build Coastguard Worker   std::vector<std::string> command;
270*795d594fSAndroid Build Coastguard Worker   command.push_back(GetBin("id"));
271*795d594fSAndroid Build Coastguard Worker 
272*795d594fSAndroid Build Coastguard Worker   std::string error_msg;
273*795d594fSAndroid Build Coastguard Worker   ProcessStat stat;
274*795d594fSAndroid Build Coastguard Worker 
275*795d594fSAndroid Build Coastguard Worker   EXPECT_CALL(*exec_utils_, DoGetUptimeMs())
276*795d594fSAndroid Build Coastguard Worker       .WillOnce(Return(162034388ll))
277*795d594fSAndroid Build Coastguard Worker       .WillOnce(Return(Result<int64_t>(Errorf("Failed to get uptime"))));
278*795d594fSAndroid Build Coastguard Worker 
279*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(exec_utils_
280*795d594fSAndroid Build Coastguard Worker                 ->ExecAndReturnResult(command,
281*795d594fSAndroid Build Coastguard Worker                                       /*timeout_sec=*/-1,
282*795d594fSAndroid Build Coastguard Worker                                       ExecCallbacks(),
283*795d594fSAndroid Build Coastguard Worker                                       /*new_process_group=*/false,
284*795d594fSAndroid Build Coastguard Worker                                       &stat,
285*795d594fSAndroid Build Coastguard Worker                                       &error_msg)
286*795d594fSAndroid Build Coastguard Worker                 .status,
287*795d594fSAndroid Build Coastguard Worker             ExecResult::kExited)
288*795d594fSAndroid Build Coastguard Worker       << error_msg;
289*795d594fSAndroid Build Coastguard Worker 
290*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(stat.cpu_time_ms, 0);
291*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(stat.wall_time_ms, 0);
292*795d594fSAndroid Build Coastguard Worker }
293*795d594fSAndroid Build Coastguard Worker 
TEST_P(ExecUtilsTest,ExecStatFailed)294*795d594fSAndroid Build Coastguard Worker TEST_P(ExecUtilsTest, ExecStatFailed) {
295*795d594fSAndroid Build Coastguard Worker   std::vector<std::string> command = SleepCommand(5);
296*795d594fSAndroid Build Coastguard Worker 
297*795d594fSAndroid Build Coastguard Worker   std::string error_msg;
298*795d594fSAndroid Build Coastguard Worker   ProcessStat stat;
299*795d594fSAndroid Build Coastguard Worker 
300*795d594fSAndroid Build Coastguard Worker   EXPECT_CALL(*exec_utils_, GetProcStat(_))
301*795d594fSAndroid Build Coastguard Worker       .WillOnce(Return(
302*795d594fSAndroid Build Coastguard Worker           "14963 (a) b) Z 6067 14963 1 0 -1 4228108 105 0 0 0 94 5 0 0 39 19 1 0 0 0 0 "
303*795d594fSAndroid Build Coastguard Worker           "18446744073709551615 0 0 0 0 0 0 20999 0 0 1 0 0 17 71 0 0 0 0 0 0 0 0 0 0 0 0 9"));
304*795d594fSAndroid Build Coastguard Worker   EXPECT_CALL(*exec_utils_, DoGetUptimeMs())
305*795d594fSAndroid Build Coastguard Worker       .WillOnce(Return(1620343880ll))
306*795d594fSAndroid Build Coastguard Worker       .WillOnce(Return(1620344887ll));
307*795d594fSAndroid Build Coastguard Worker   EXPECT_CALL(*exec_utils_, GetTicksPerSec()).WillOnce(Return(100));
308*795d594fSAndroid Build Coastguard Worker 
309*795d594fSAndroid Build Coastguard Worker   // This will always time out.
310*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(exec_utils_
311*795d594fSAndroid Build Coastguard Worker                 ->ExecAndReturnResult(command,
312*795d594fSAndroid Build Coastguard Worker                                       /*timeout_sec=*/1,
313*795d594fSAndroid Build Coastguard Worker                                       ExecCallbacks(),
314*795d594fSAndroid Build Coastguard Worker                                       /*new_process_group=*/false,
315*795d594fSAndroid Build Coastguard Worker                                       &stat,
316*795d594fSAndroid Build Coastguard Worker                                       &error_msg)
317*795d594fSAndroid Build Coastguard Worker                 .status,
318*795d594fSAndroid Build Coastguard Worker             ExecResult::kTimedOut);
319*795d594fSAndroid Build Coastguard Worker 
320*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(stat.cpu_time_ms, 990);
321*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(stat.wall_time_ms, 1007);
322*795d594fSAndroid Build Coastguard Worker }
323*795d594fSAndroid Build Coastguard Worker 
TEST_P(ExecUtilsTest,ExecCallbacks)324*795d594fSAndroid Build Coastguard Worker TEST_P(ExecUtilsTest, ExecCallbacks) {
325*795d594fSAndroid Build Coastguard Worker   MockFunction<void(pid_t)> on_start;
326*795d594fSAndroid Build Coastguard Worker   MockFunction<void(pid_t)> on_end;
327*795d594fSAndroid Build Coastguard Worker 
328*795d594fSAndroid Build Coastguard Worker   {
329*795d594fSAndroid Build Coastguard Worker     InSequence s;
330*795d594fSAndroid Build Coastguard Worker     EXPECT_CALL(on_start, Call(AllOf(Gt(0), Ne(getpid()))));
331*795d594fSAndroid Build Coastguard Worker     EXPECT_CALL(on_end, Call(AllOf(Gt(0), Ne(getpid()))));
332*795d594fSAndroid Build Coastguard Worker   }
333*795d594fSAndroid Build Coastguard Worker 
334*795d594fSAndroid Build Coastguard Worker   std::vector<std::string> command;
335*795d594fSAndroid Build Coastguard Worker   command.push_back(GetBin("id"));
336*795d594fSAndroid Build Coastguard Worker 
337*795d594fSAndroid Build Coastguard Worker   std::string error_msg;
338*795d594fSAndroid Build Coastguard Worker   exec_utils_->ExecAndReturnResult(command,
339*795d594fSAndroid Build Coastguard Worker                                    /*timeout_sec=*/-1,
340*795d594fSAndroid Build Coastguard Worker                                    ExecCallbacks{
341*795d594fSAndroid Build Coastguard Worker                                        .on_start = on_start.AsStdFunction(),
342*795d594fSAndroid Build Coastguard Worker                                        .on_end = on_end.AsStdFunction(),
343*795d594fSAndroid Build Coastguard Worker                                    },
344*795d594fSAndroid Build Coastguard Worker                                    /*new_process_group=*/false,
345*795d594fSAndroid Build Coastguard Worker                                    /*stat=*/nullptr,
346*795d594fSAndroid Build Coastguard Worker                                    &error_msg);
347*795d594fSAndroid Build Coastguard Worker }
348*795d594fSAndroid Build Coastguard Worker 
TEST_P(ExecUtilsTest,ExecNewProcessGroupTrue)349*795d594fSAndroid Build Coastguard Worker TEST_P(ExecUtilsTest, ExecNewProcessGroupTrue) {
350*795d594fSAndroid Build Coastguard Worker   auto on_end = [](pid_t pid) {
351*795d594fSAndroid Build Coastguard Worker     pid_t pgid = getpgid(pid);
352*795d594fSAndroid Build Coastguard Worker     ASSERT_GE(pgid, 0) << strerror(errno);
353*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(pgid, pid);
354*795d594fSAndroid Build Coastguard Worker   };
355*795d594fSAndroid Build Coastguard Worker 
356*795d594fSAndroid Build Coastguard Worker   std::vector<std::string> command;
357*795d594fSAndroid Build Coastguard Worker   command.push_back(GetBin("id"));
358*795d594fSAndroid Build Coastguard Worker 
359*795d594fSAndroid Build Coastguard Worker   std::string error_msg;
360*795d594fSAndroid Build Coastguard Worker   exec_utils_->ExecAndReturnResult(command,
361*795d594fSAndroid Build Coastguard Worker                                    /*timeout_sec=*/-1,
362*795d594fSAndroid Build Coastguard Worker                                    ExecCallbacks{
363*795d594fSAndroid Build Coastguard Worker                                        .on_end = on_end,
364*795d594fSAndroid Build Coastguard Worker                                    },
365*795d594fSAndroid Build Coastguard Worker                                    /*new_process_group=*/true,
366*795d594fSAndroid Build Coastguard Worker                                    /*stat=*/nullptr,
367*795d594fSAndroid Build Coastguard Worker                                    &error_msg);
368*795d594fSAndroid Build Coastguard Worker }
369*795d594fSAndroid Build Coastguard Worker 
TEST_P(ExecUtilsTest,ExecNewProcessGroupFalse)370*795d594fSAndroid Build Coastguard Worker TEST_P(ExecUtilsTest, ExecNewProcessGroupFalse) {
371*795d594fSAndroid Build Coastguard Worker   auto on_end = [](pid_t pid) {
372*795d594fSAndroid Build Coastguard Worker     pid_t pgid = getpgid(pid);
373*795d594fSAndroid Build Coastguard Worker     ASSERT_GE(pgid, 0) << strerror(errno);
374*795d594fSAndroid Build Coastguard Worker     pid_t parent_pgid = getpgid(0);
375*795d594fSAndroid Build Coastguard Worker     ASSERT_GE(parent_pgid, 0) << strerror(errno);
376*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(pgid, parent_pgid);
377*795d594fSAndroid Build Coastguard Worker   };
378*795d594fSAndroid Build Coastguard Worker 
379*795d594fSAndroid Build Coastguard Worker   std::vector<std::string> command;
380*795d594fSAndroid Build Coastguard Worker   command.push_back(GetBin("id"));
381*795d594fSAndroid Build Coastguard Worker 
382*795d594fSAndroid Build Coastguard Worker   std::string error_msg;
383*795d594fSAndroid Build Coastguard Worker   exec_utils_->ExecAndReturnResult(command,
384*795d594fSAndroid Build Coastguard Worker                                    /*timeout_sec=*/-1,
385*795d594fSAndroid Build Coastguard Worker                                    ExecCallbacks{
386*795d594fSAndroid Build Coastguard Worker                                        .on_end = on_end,
387*795d594fSAndroid Build Coastguard Worker                                    },
388*795d594fSAndroid Build Coastguard Worker                                    /*new_process_group=*/false,
389*795d594fSAndroid Build Coastguard Worker                                    /*stat=*/nullptr,
390*795d594fSAndroid Build Coastguard Worker                                    &error_msg);
391*795d594fSAndroid Build Coastguard Worker }
392*795d594fSAndroid Build Coastguard Worker 
393*795d594fSAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(AlwaysOrNeverFallback, ExecUtilsTest, testing::Values(true, false));
394*795d594fSAndroid Build Coastguard Worker 
395*795d594fSAndroid Build Coastguard Worker }  // namespace art
396