this repo has no description
1// Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com)
2#include "sys-module.h"
3
4#include <sys/utsname.h>
5
6#include <cstdio>
7#include <cstdlib>
8
9#include "gtest/gtest.h"
10
11#include "builtins.h"
12#include "runtime.h"
13#include "str-builtins.h"
14#include "test-utils.h"
15
16namespace py {
17namespace testing {
18
19using SysModuleTest = RuntimeFixture;
20
21TEST_F(SysModuleTest,
22 ExcInfoWhileExceptionNotBeingHandledReturnsTupleOfThreeNone) {
23 ASSERT_FALSE(runFromCStr(runtime_, R"(
24import sys
25result = sys.exc_info()
26)")
27 .isError());
28 HandleScope scope(thread_);
29 Object result_obj(&scope, mainModuleAt(runtime_, "result"));
30 ASSERT_TRUE(result_obj.isTuple());
31
32 Tuple result(&scope, *result_obj);
33 ASSERT_EQ(result.length(), 3);
34 EXPECT_EQ(result.at(0), NoneType::object());
35 EXPECT_EQ(result.at(1), NoneType::object());
36 EXPECT_EQ(result.at(2), NoneType::object());
37}
38
39TEST_F(
40 SysModuleTest,
41 ExcInfoWhileExceptionNotBeingHandledAfterExceptionIsRaisedReturnsTupleOfThreeNone) {
42 ASSERT_FALSE(runFromCStr(runtime_, R"(
43import sys
44try:
45 raise IndexError(3)
46except:
47 pass
48result = sys.exc_info()
49)")
50 .isError());
51 HandleScope scope(thread_);
52 Object result_obj(&scope, mainModuleAt(runtime_, "result"));
53 ASSERT_TRUE(result_obj.isTuple());
54
55 Tuple result(&scope, *result_obj);
56 ASSERT_EQ(result.length(), 3);
57 EXPECT_EQ(result.at(0), NoneType::object());
58 EXPECT_EQ(result.at(1), NoneType::object());
59 EXPECT_EQ(result.at(2), NoneType::object());
60}
61
62TEST_F(SysModuleTest,
63 ExcInfoWhileExceptionBeingHandledReturnsTupleOfTypeValueTraceback) {
64 ASSERT_FALSE(runFromCStr(runtime_, R"(
65import sys
66try:
67 raise IndexError(4)
68except:
69 result = sys.exc_info()
70)")
71 .isError());
72 HandleScope scope(thread_);
73 Object result_obj(&scope, mainModuleAt(runtime_, "result"));
74 ASSERT_TRUE(result_obj.isTuple());
75
76 Tuple result(&scope, *result_obj);
77 ASSERT_EQ(result.length(), 3);
78
79 Type expected_type(&scope, runtime_->typeAt(LayoutId::kIndexError));
80 EXPECT_EQ(result.at(0), expected_type);
81
82 ASSERT_TRUE(result.at(1).isIndexError());
83 IndexError actual_value(&scope, result.at(1));
84 ASSERT_TRUE(actual_value.args().isTuple());
85 Tuple value_args(&scope, actual_value.args());
86 ASSERT_EQ(value_args.length(), 1);
87 EXPECT_EQ(value_args.at(0), SmallInt::fromWord(4));
88
89 // TODO(T42241510): Traceback support isn't implemented yet. Once it's ready,
90 // inspect result.at(2) here.
91}
92
93TEST_F(SysModuleTest, ExcInfoReturnsInfoOfExceptionCurrentlyBeingHandled) {
94 ASSERT_FALSE(runFromCStr(runtime_, R"(
95import sys
96try:
97 raise IndexError(4)
98except:
99 try:
100 raise IndexError(5)
101 except:
102 result = sys.exc_info()
103)")
104 .isError());
105 HandleScope scope(thread_);
106 Object result_obj(&scope, mainModuleAt(runtime_, "result"));
107 ASSERT_TRUE(result_obj.isTuple());
108
109 Tuple result(&scope, *result_obj);
110 ASSERT_EQ(result.length(), 3);
111
112 Type expected_type(&scope, runtime_->typeAt(LayoutId::kIndexError));
113 EXPECT_EQ(result.at(0), expected_type);
114
115 ASSERT_TRUE(result.at(1).isIndexError());
116 IndexError actual_value(&scope, result.at(1));
117 ASSERT_TRUE(actual_value.args().isTuple());
118 Tuple value_args(&scope, actual_value.args());
119 ASSERT_EQ(value_args.length(), 1);
120 EXPECT_EQ(value_args.at(0), SmallInt::fromWord(5));
121
122 // TODO(T42241510): Traceback support isn't implemented yet. Once it's ready,
123 // inspect result.at(2) here.
124}
125
126TEST_F(SysModuleTest, ExecutableIsValid) {
127 HandleScope scope(thread_);
128 Object executable_obj(&scope, moduleAtByCStr(runtime_, "sys", "executable"));
129 ASSERT_TRUE(executable_obj.isStr());
130 Str executable(&scope, *executable_obj);
131 ASSERT_TRUE(executable.length() > 0);
132 EXPECT_TRUE(executable.byteAt(0) == '/');
133 Str test_executable_name(&scope, runtime_->newStrFromCStr("python-tests"));
134 word result = strFind(executable, test_executable_name);
135 EXPECT_GE(result, 0);
136}
137
138TEST_F(SysModuleTest, SysExit) {
139 const char* src = R"(
140import sys
141sys.exit()
142)";
143 ASSERT_EXIT(static_cast<void>(runFromCStr(runtime_, src)),
144 ::testing::ExitedWithCode(0), "");
145}
146
147TEST_F(SysModuleTest, SysExitCode) { // pystone dependency
148 const char* src = R"(
149import sys
150sys.exit(100)
151)";
152 ASSERT_EXIT(static_cast<void>(runFromCStr(runtime_, src)),
153 ::testing::ExitedWithCode(100), "");
154}
155
156TEST_F(SysModuleTest, SysExitWithNonCodeReturnsOne) { // pystone dependency
157 const char* src = R"(
158import sys
159sys.exit("barf")
160)";
161 ASSERT_EXIT(static_cast<void>(runFromCStr(runtime_, src)),
162 ::testing::ExitedWithCode(1), "barf");
163}
164
165TEST_F(SysModuleTest, SysExitWithFalseReturnsZero) {
166 const char* src = R"(
167import sys
168sys.exit(False)
169)";
170 ASSERT_EXIT(static_cast<void>(runFromCStr(runtime_, src)),
171 ::testing::ExitedWithCode(0), "");
172}
173
174TEST_F(SysModuleTest, Platform) {
175 HandleScope scope(thread_);
176 ASSERT_FALSE(runFromCStr(runtime_, R"(
177import sys
178sysname = sys.platform
179)")
180 .isError());
181 Object sysname(&scope, mainModuleAt(runtime_, "sysname"));
182 ASSERT_TRUE(sysname.isStr());
183 struct utsname name;
184 ASSERT_EQ(uname(&name), 0);
185 bool is_darwin = !std::strcmp(name.sysname, "Darwin");
186 bool is_linux = !std::strcmp(name.sysname, "Linux");
187 ASSERT_TRUE(is_darwin || is_linux);
188 if (is_darwin) {
189 EXPECT_TRUE(Str::cast(*sysname).equalsCStr("darwin"));
190 }
191 if (is_linux) {
192 EXPECT_TRUE(Str::cast(*sysname).equalsCStr("linux"));
193 }
194}
195
196TEST_F(SysModuleTest, PathImporterCache) {
197 HandleScope scope(thread_);
198 ASSERT_FALSE(runFromCStr(runtime_, R"(
199import sys
200result = sys.path_importer_cache
201)")
202 .isError());
203 Object result(&scope, mainModuleAt(runtime_, "result"));
204 EXPECT_TRUE(result.isDict());
205}
206
207TEST_F(SysModuleTest, BuiltinModuleNames) {
208 HandleScope scope(thread_);
209 ASSERT_FALSE(runFromCStr(runtime_, R"(
210import sys
211builtin_names = sys.builtin_module_names
212)")
213 .isError());
214 Object builtins(&scope, mainModuleAt(runtime_, "builtin_names"));
215 ASSERT_TRUE(builtins.isTuple());
216
217 // Test that builtin list is greater than 0
218 Tuple builtins_tuple(&scope, *builtins);
219 EXPECT_GT(builtins_tuple.length(), 0);
220
221 // Test that sys and _stat are both in the builtin list
222 bool builtin_sys = false;
223 bool builtin__stat = false;
224 for (int i = 0; i < builtins_tuple.length(); i++) {
225 builtin_sys |= Str::cast(builtins_tuple.at(i)).equalsCStr("sys");
226 builtin__stat |= Str::cast(builtins_tuple.at(i)).equalsCStr("_stat");
227 }
228 EXPECT_TRUE(builtin_sys);
229 EXPECT_TRUE(builtin__stat);
230}
231
232TEST_F(SysModuleTest, FlagsVerbose) {
233 HandleScope scope(thread_);
234 ASSERT_FALSE(runFromCStr(runtime_, R"(
235import sys
236result = sys.flags.verbose
237)")
238 .isError());
239 Object result(&scope, mainModuleAt(runtime_, "result"));
240 EXPECT_TRUE(isIntEqualsWord(*result, 0));
241}
242
243TEST_F(SysModuleTest, MaxsizeIsMaxWord) {
244 HandleScope scope(thread_);
245 Object maxsize(&scope, moduleAtByCStr(runtime_, "sys", "maxsize"));
246 EXPECT_TRUE(isIntEqualsWord(*maxsize, kMaxWord));
247}
248
249TEST_F(SysModuleTest, ByteorderIsCorrectString) {
250 HandleScope scope(thread_);
251 Object byteorder(&scope, moduleAtByCStr(runtime_, "sys", "byteorder"));
252 EXPECT_TRUE(isStrEqualsCStr(
253 *byteorder, endian::native == endian::little ? "little" : "big"));
254}
255
256} // namespace testing
257} // namespace py