this repo has no description
1// Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com)
2#include <signal.h>
3
4#include <cwchar>
5
6#include "Python.h"
7#include "gtest/gtest.h"
8
9#include "capi-fixture.h"
10#include "capi-testing.h"
11
12namespace py {
13namespace testing {
14
15using PylifecycleExtensionApiTest = ExtensionApi;
16
17TEST_F(PylifecycleExtensionApiTest, FatalErrorPrintsAndAbortsDeathTest) {
18 EXPECT_DEATH(Py_FatalError("hello world"), "hello world");
19}
20
21TEST_F(PylifecycleExtensionApiTest, AtExitRegistersExitFunction) {
22 ASSERT_EXIT(PyRun_SimpleString(R"(
23def cleanup():
24 import sys
25 print("foo", file=sys.stderr)
26
27import atexit
28atexit.register(cleanup)
29raise SystemExit(123)
30)"),
31 ::testing::ExitedWithCode(123), "foo");
32}
33
34TEST_F(PylifecycleExtensionApiTest, GetsigGetsCurrentSignalHandler) {
35 PyOS_sighandler_t handler = [](int) {};
36 PyOS_sighandler_t saved = PyOS_setsig(SIGABRT, handler);
37
38 EXPECT_EQ(PyOS_getsig(SIGABRT), handler);
39
40 PyOS_setsig(SIGABRT, saved);
41}
42
43TEST(PylifecycleExtensionApiTestNoFixture, InitializeSetsSysFlagsVariant0) {
44 resetPythonEnv();
45 Py_DontWriteBytecodeFlag = 1;
46 Py_IgnoreEnvironmentFlag = 0;
47 Py_InspectFlag = 13;
48 Py_InteractiveFlag = 0;
49 Py_IsolatedFlag = 0;
50 Py_NoSiteFlag = 1;
51 Py_NoUserSiteDirectory = 0;
52 Py_OptimizeFlag = 2;
53 Py_QuietFlag = 0;
54 Py_VerboseFlag = 13;
55 Py_Initialize();
56
57 {
58 PyObjectPtr flags(moduleGet("sys", "flags"));
59 ASSERT_NE(flags.get(), nullptr);
60 EXPECT_TRUE(isLongEqualsLong(
61 PyObject_GetAttrString(flags, "dont_write_bytecode"), 1));
62 EXPECT_TRUE(isLongEqualsLong(
63 PyObject_GetAttrString(flags, "ignore_environment"), 0));
64 EXPECT_TRUE(isLongEqualsLong(PyObject_GetAttrString(flags, "inspect"), 13));
65 EXPECT_TRUE(
66 isLongEqualsLong(PyObject_GetAttrString(flags, "interactive"), 0));
67 EXPECT_TRUE(isLongEqualsLong(PyObject_GetAttrString(flags, "isolated"), 0));
68 EXPECT_TRUE(isLongEqualsLong(PyObject_GetAttrString(flags, "no_site"), 1));
69 EXPECT_TRUE(
70 isLongEqualsLong(PyObject_GetAttrString(flags, "no_user_site"), 0));
71 EXPECT_TRUE(isLongEqualsLong(PyObject_GetAttrString(flags, "optimize"), 2));
72 EXPECT_TRUE(isLongEqualsLong(PyObject_GetAttrString(flags, "quiet"), 0));
73 EXPECT_TRUE(isLongEqualsLong(PyObject_GetAttrString(flags, "verbose"), 13));
74 }
75
76 Py_FinalizeEx();
77}
78
79TEST(PylifecycleExtensionApiTestNoFixture, InitializeSetsSysFlagsVariant1) {
80 resetPythonEnv();
81 Py_DontWriteBytecodeFlag = 0;
82 Py_IgnoreEnvironmentFlag = 1;
83 Py_InspectFlag = 0;
84 Py_InteractiveFlag = 1;
85 Py_IsolatedFlag = 1;
86 Py_NoSiteFlag = 0;
87 Py_NoUserSiteDirectory = 1;
88 Py_OptimizeFlag = 0;
89 Py_QuietFlag = 1;
90 Py_VerboseFlag = 0;
91 Py_Initialize();
92
93 {
94 PyObjectPtr flags(moduleGet("sys", "flags"));
95 ASSERT_NE(flags.get(), nullptr);
96 EXPECT_TRUE(isLongEqualsLong(
97 PyObject_GetAttrString(flags, "dont_write_bytecode"), 0));
98 EXPECT_TRUE(isLongEqualsLong(
99 PyObject_GetAttrString(flags, "ignore_environment"), 1));
100 EXPECT_TRUE(isLongEqualsLong(PyObject_GetAttrString(flags, "inspect"), 0));
101 EXPECT_TRUE(
102 isLongEqualsLong(PyObject_GetAttrString(flags, "interactive"), 1));
103 EXPECT_TRUE(isLongEqualsLong(PyObject_GetAttrString(flags, "isolated"), 1));
104 EXPECT_TRUE(isLongEqualsLong(PyObject_GetAttrString(flags, "no_site"), 0));
105 EXPECT_TRUE(
106 isLongEqualsLong(PyObject_GetAttrString(flags, "no_user_site"), 1));
107 EXPECT_TRUE(isLongEqualsLong(PyObject_GetAttrString(flags, "optimize"), 0));
108 EXPECT_TRUE(isLongEqualsLong(PyObject_GetAttrString(flags, "quiet"), 1));
109 EXPECT_TRUE(isLongEqualsLong(PyObject_GetAttrString(flags, "verbose"), 0));
110 }
111
112 Py_FinalizeEx();
113}
114
115TEST(PylifecycleExtensionApiTestNoFixture, IsInitialized) {
116 resetPythonEnv();
117 EXPECT_FALSE(Py_IsInitialized());
118
119 Py_Initialize();
120
121 EXPECT_TRUE(Py_IsInitialized());
122 Py_FinalizeEx();
123}
124
125TEST_F(PylifecycleExtensionApiTest, SetsigSetsSignalHandler) {
126 PyOS_sighandler_t saved = PyOS_getsig(SIGUSR1);
127 PyOS_sighandler_t handler = [](int) { PyRun_SimpleString("handled = True"); };
128
129 PyOS_sighandler_t old_handler = PyOS_setsig(SIGUSR1, handler);
130 EXPECT_EQ(old_handler, saved);
131 EXPECT_EQ(PyOS_getsig(SIGUSR1), handler);
132
133 ::raise(SIGUSR1);
134 PyObjectPtr handled(mainModuleGet("handled"));
135 EXPECT_EQ(handled, Py_True);
136
137 PyOS_setsig(SIGUSR1, saved);
138}
139
140TEST_F(PylifecycleExtensionApiTest, RestoreSignalRestoresToDefault) {
141 PyOS_sighandler_t handler = [](int) {};
142 EXPECT_NE(handler, SIG_DFL);
143
144 PyOS_setsig(SIGUSR1, handler);
145 PyOS_setsig(SIGPIPE, handler);
146 PyOS_setsig(SIGXFSZ, handler);
147
148 EXPECT_EQ(PyOS_getsig(SIGUSR1), handler);
149 EXPECT_EQ(PyOS_getsig(SIGPIPE), handler);
150 EXPECT_EQ(PyOS_getsig(SIGXFSZ), handler);
151
152 _Py_RestoreSignals();
153
154 EXPECT_EQ(PyOS_getsig(SIGUSR1), handler);
155 EXPECT_EQ(PyOS_getsig(SIGPIPE), SIG_DFL);
156 EXPECT_EQ(PyOS_getsig(SIGXFSZ), SIG_DFL);
157}
158
159TEST_F(PylifecycleExtensionApiTest, GetProgramNameReturnsString) {
160 const wchar_t* program_name = Py_GetProgramName();
161 EXPECT_TRUE(std::wcsstr(program_name, L"python-tests") != nullptr ||
162 std::wcsstr(program_name, L"cpython-tests") != nullptr);
163}
164
165TEST_F(PylifecycleExtensionApiTest, SetProgramNameSetsName) {
166 wchar_t name[] = L"new-program-name";
167 Py_SetProgramName(name);
168 EXPECT_STREQ(Py_GetProgramName(), L"new-program-name");
169}
170
171TEST(PylifecycleExtensionApiTestNoFixture,
172 IsFinalizingReturnsFalseBeforeAndAfterFinalizePyro) {
173 resetPythonEnv();
174 Py_Initialize();
175 ASSERT_EQ(_Py_IsFinalizing(), 0);
176 ASSERT_EQ(Py_FinalizeEx(), 0);
177 EXPECT_EQ(_Py_IsFinalizing(), 0);
178}
179
180TEST(PylifecycleExtensionApiTestNoFixture,
181 PyUnbufferedStdioFlagEqualsZeroSetsBufferedStdio) {
182 resetPythonEnv();
183 Py_UnbufferedStdioFlag = 0;
184 Py_Initialize();
185 {
186 PyObjectPtr sys_stdout(Borrowed(PySys_GetObject("stdout")));
187 ASSERT_NE(sys_stdout, nullptr);
188 ASSERT_EQ(PyErr_Occurred(), nullptr);
189 PyObjectPtr line_buffering(
190 PyObject_GetAttrString(sys_stdout, "line_buffering"));
191 ASSERT_NE(line_buffering, nullptr);
192 ASSERT_EQ(PyErr_Occurred(), nullptr);
193 // TODO(emacs): Split this into multiple tests or fake a tty somehow.
194 EXPECT_EQ(line_buffering, ::isatty(fileno(stdout)) ? Py_True : Py_False);
195 }
196 Py_FinalizeEx();
197}
198
199TEST(PylifecycleExtensionApiTestNoFixture,
200 PyUnbufferedStdioFlagEqualsOneSetsUnbufferedStdio) {
201 resetPythonEnv();
202 Py_UnbufferedStdioFlag = 1;
203 Py_Initialize();
204 {
205 PyObjectPtr sys_stdout(Borrowed(PySys_GetObject("stdout")));
206 ASSERT_NE(sys_stdout, nullptr);
207 ASSERT_EQ(PyErr_Occurred(), nullptr);
208 PyObjectPtr line_buffering(
209 PyObject_GetAttrString(sys_stdout, "line_buffering"));
210 ASSERT_NE(line_buffering, nullptr);
211 ASSERT_EQ(PyErr_Occurred(), nullptr);
212 EXPECT_EQ(line_buffering, Py_False);
213 }
214 Py_FinalizeEx();
215}
216
217TEST(PylifecycleExtensionApiTestNoFixture,
218 PyUnbufferedStdioFlagEqualsOneSetsUnbufferedStdin) {
219 resetPythonEnv();
220 Py_UnbufferedStdioFlag = 1;
221 Py_Initialize();
222 {
223 PyObjectPtr sys_stdin(Borrowed(PySys_GetObject("stdin")));
224 ASSERT_NE(sys_stdin, nullptr);
225 ASSERT_EQ(PyErr_Occurred(), nullptr);
226 PyObjectPtr line_buffering(
227 PyObject_GetAttrString(sys_stdin, "line_buffering"));
228 ASSERT_NE(line_buffering, nullptr);
229 ASSERT_EQ(PyErr_Occurred(), nullptr);
230 EXPECT_EQ(line_buffering, Py_False);
231 }
232 Py_FinalizeEx();
233}
234
235} // namespace testing
236} // namespace py