blob: aa53739cfa447378169e6a457044b7b759fa76a6 [file] [log] [blame]
David Sehrb2ec9f52018-02-21 13:20:31 -08001/*
2 * Copyright (C) 2011 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 "exec_utils.h"
18
Jiakai Zhangdfc95a62022-07-07 20:36:59 +000019#include <unistd.h>
20
Orion Hodsondd732cc2021-01-15 16:31:30 +000021#include "android-base/stringprintf.h"
David Sehrb2ec9f52018-02-21 13:20:31 -080022#include "base/file_utils.h"
23#include "base/memory_tool.h"
24#include "common_runtime_test.h"
Jiakai Zhangdfc95a62022-07-07 20:36:59 +000025#include "gmock/gmock.h"
26#include "gtest/gtest.h"
David Sehrb2ec9f52018-02-21 13:20:31 -080027
28namespace art {
29
30std::string PrettyArguments(const char* signature);
31std::string PrettyReturnType(const char* signature);
32
Jiakai Zhangdfc95a62022-07-07 20:36:59 +000033bool IsPidfdSupported() {
34#ifdef __BIONIC__
35 return true;
36#else
37 constexpr int SYS_pidfd_open = 434;
38 int pidfd = syscall(SYS_pidfd_open, getpid(), /*flags=*/0);
39 if (pidfd < 0) {
40 return false;
41 }
42 close(pidfd);
43 return true;
44#endif
45}
46
David Sehrb2ec9f52018-02-21 13:20:31 -080047class ExecUtilsTest : public CommonRuntimeTest {};
48
49TEST_F(ExecUtilsTest, ExecSuccess) {
50 std::vector<std::string> command;
51 if (kIsTargetBuild) {
52 std::string android_root(GetAndroidRoot());
53 command.push_back(android_root + "/bin/id");
54 } else {
55 command.push_back("/usr/bin/id");
56 }
57 std::string error_msg;
Roland Levillain0b0d3b42018-06-14 13:55:49 +010058 // Historical note: Running on Valgrind failed due to some memory
59 // that leaks in thread alternate signal stacks.
60 EXPECT_TRUE(Exec(command, &error_msg));
David Sehrb2ec9f52018-02-21 13:20:31 -080061 EXPECT_EQ(0U, error_msg.size()) << error_msg;
62}
63
64TEST_F(ExecUtilsTest, ExecError) {
David Sehrb2ec9f52018-02-21 13:20:31 -080065 std::vector<std::string> command;
66 command.push_back("bogus");
67 std::string error_msg;
Roland Levillain0b0d3b42018-06-14 13:55:49 +010068 // Historical note: Running on Valgrind failed due to some memory
69 // that leaks in thread alternate signal stacks.
70 EXPECT_FALSE(Exec(command, &error_msg));
71 EXPECT_FALSE(error_msg.empty());
David Sehrb2ec9f52018-02-21 13:20:31 -080072}
73
74TEST_F(ExecUtilsTest, EnvSnapshotAdditionsAreNotVisible) {
75 static constexpr const char* kModifiedVariable = "EXEC_SHOULD_NOT_EXPORT_THIS";
76 static constexpr int kOverwrite = 1;
77 // Set an variable in the current environment.
78 EXPECT_EQ(setenv(kModifiedVariable, "NEVER", kOverwrite), 0);
79 // Test that it is not exported.
80 std::vector<std::string> command;
81 if (kIsTargetBuild) {
82 std::string android_root(GetAndroidRoot());
83 command.push_back(android_root + "/bin/printenv");
84 } else {
85 command.push_back("/usr/bin/printenv");
86 }
87 command.push_back(kModifiedVariable);
88 std::string error_msg;
Roland Levillain0b0d3b42018-06-14 13:55:49 +010089 // Historical note: Running on Valgrind failed due to some memory
90 // that leaks in thread alternate signal stacks.
91 EXPECT_FALSE(Exec(command, &error_msg));
92 EXPECT_NE(0U, error_msg.size()) << error_msg;
David Sehrb2ec9f52018-02-21 13:20:31 -080093}
94
95TEST_F(ExecUtilsTest, EnvSnapshotDeletionsAreNotVisible) {
96 static constexpr const char* kDeletedVariable = "PATH";
97 static constexpr int kOverwrite = 1;
98 // Save the variable's value.
99 const char* save_value = getenv(kDeletedVariable);
100 EXPECT_NE(save_value, nullptr);
101 // Delete the variable.
102 EXPECT_EQ(unsetenv(kDeletedVariable), 0);
103 // Test that it is not exported.
104 std::vector<std::string> command;
105 if (kIsTargetBuild) {
106 std::string android_root(GetAndroidRoot());
107 command.push_back(android_root + "/bin/printenv");
108 } else {
109 command.push_back("/usr/bin/printenv");
110 }
111 command.push_back(kDeletedVariable);
112 std::string error_msg;
Roland Levillain0b0d3b42018-06-14 13:55:49 +0100113 // Historical note: Running on Valgrind failed due to some memory
114 // that leaks in thread alternate signal stacks.
115 EXPECT_TRUE(Exec(command, &error_msg));
116 EXPECT_EQ(0U, error_msg.size()) << error_msg;
David Sehrb2ec9f52018-02-21 13:20:31 -0800117 // Restore the variable's value.
118 EXPECT_EQ(setenv(kDeletedVariable, save_value, kOverwrite), 0);
119}
120
Orion Hodsondd732cc2021-01-15 16:31:30 +0000121static std::vector<std::string> SleepCommand(int sleep_seconds) {
122 std::vector<std::string> command;
123 if (kIsTargetBuild) {
124 command.push_back(GetAndroidRoot() + "/bin/sleep");
125 } else {
126 command.push_back("/bin/sleep");
127 }
128 command.push_back(android::base::StringPrintf("%d", sleep_seconds));
129 return command;
130}
131
132TEST_F(ExecUtilsTest, ExecTimeout) {
Jiakai Zhangdfc95a62022-07-07 20:36:59 +0000133 if (!IsPidfdSupported()) {
134 GTEST_SKIP() << "pidfd not supported";
135 }
136
Orion Hodsondd732cc2021-01-15 16:31:30 +0000137 static constexpr int kSleepSeconds = 5;
138 static constexpr int kWaitSeconds = 1;
139 std::vector<std::string> command = SleepCommand(kSleepSeconds);
140 std::string error_msg;
141 bool timed_out;
142 ASSERT_EQ(ExecAndReturnCode(command, kWaitSeconds, &timed_out, &error_msg), -1);
143 EXPECT_TRUE(timed_out);
144}
145
146TEST_F(ExecUtilsTest, ExecNoTimeout) {
Jiakai Zhangdfc95a62022-07-07 20:36:59 +0000147 if (!IsPidfdSupported()) {
148 GTEST_SKIP() << "pidfd not supported";
149 }
150
Orion Hodsondd732cc2021-01-15 16:31:30 +0000151 static constexpr int kSleepSeconds = 1;
152 static constexpr int kWaitSeconds = 5;
153 std::vector<std::string> command = SleepCommand(kSleepSeconds);
154 std::string error_msg;
155 bool timed_out;
156 ASSERT_EQ(ExecAndReturnCode(command, kWaitSeconds, &timed_out, &error_msg), 0);
157 EXPECT_FALSE(timed_out);
158}
159
Jiakai Zhangdfc95a62022-07-07 20:36:59 +0000160TEST_F(ExecUtilsTest, ExecTimeoutNotSupported) {
161 if (IsPidfdSupported()) {
162 GTEST_SKIP() << "pidfd supported";
163 }
164
165 std::string error_msg;
166 bool timed_out;
167 ASSERT_EQ(ExecAndReturnCode({"command"}, /*timeout_sec=*/0, &timed_out, &error_msg), -1);
168 EXPECT_THAT(error_msg, testing::HasSubstr("pidfd_open failed for pid"));
169}
170
David Sehrb2ec9f52018-02-21 13:20:31 -0800171} // namespace art