1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "gn/exec_process.h"
6
7 #include "base/command_line.h"
8 #include "base/files/scoped_temp_dir.h"
9 #include "base/strings/string_util.h"
10 #include "util/build_config.h"
11 #include "util/test/test.h"
12
13 #if defined(OS_WIN)
14 #include "base/strings/utf_string_conversions.h"
15 #endif
16
17 namespace internal {
18
19 // TODO(cjhopman): Enable these tests when windows ExecProcess handles stderr.
20 // 'python' is not runnable on Windows. Adding ["cmd", "/c"] fails because
21 // CommandLine does unusual reordering of args.
22 #if !defined(OS_WIN)
23 namespace {
ExecPython(const std::string & command,std::string * std_out,std::string * std_err,int * exit_code)24 bool ExecPython(const std::string& command,
25 std::string* std_out,
26 std::string* std_err,
27 int* exit_code) {
28 base::ScopedTempDir temp_dir;
29 CHECK(temp_dir.CreateUniqueTempDir());
30 base::CommandLine::StringVector args;
31 #if defined(OS_WIN)
32 args.push_back(L"python");
33 args.push_back(L"-c");
34 args.push_back(base::UTF8ToUTF16(command));
35 #else
36 args.push_back("python");
37 args.push_back("-c");
38 args.push_back(command);
39 #endif
40 return ExecProcess(base::CommandLine(args), temp_dir.GetPath(), std_out,
41 std_err, exit_code);
42 }
43 } // namespace
44
TEST(ExecProcessTest,TestExitCode)45 TEST(ExecProcessTest, TestExitCode) {
46 std::string std_out, std_err;
47 int exit_code;
48
49 ASSERT_TRUE(
50 ExecPython("import sys; sys.exit(0)", &std_out, &std_err, &exit_code));
51 EXPECT_EQ(0, exit_code);
52
53 ASSERT_TRUE(
54 ExecPython("import sys; sys.exit(1)", &std_out, &std_err, &exit_code));
55 EXPECT_EQ(1, exit_code);
56
57 ASSERT_TRUE(
58 ExecPython("import sys; sys.exit(253)", &std_out, &std_err, &exit_code));
59 EXPECT_EQ(253, exit_code);
60
61 ASSERT_TRUE(ExecPython("throw Exception()", &std_out, &std_err, &exit_code));
62 EXPECT_EQ(1, exit_code);
63 }
64
65 // Test that large output is handled correctly. There are various ways that this
66 // could potentially fail. For example, non-blocking Linux pipes have a 65536
67 // byte buffer and, if stdout is non-blocking, python will throw an IOError when
68 // a write exceeds the buffer size.
TEST(ExecProcessTest,TestLargeOutput)69 TEST(ExecProcessTest, TestLargeOutput) {
70 std::string std_out, std_err;
71 int exit_code;
72
73 ASSERT_TRUE(ExecPython("import sys; print('o' * 1000000)", &std_out, &std_err,
74 &exit_code));
75 EXPECT_EQ(0, exit_code);
76 EXPECT_EQ(1000001u, std_out.size());
77 }
78
TEST(ExecProcessTest,TestStdoutAndStderrOutput)79 TEST(ExecProcessTest, TestStdoutAndStderrOutput) {
80 std::string std_out, std_err;
81 int exit_code;
82
83 ASSERT_TRUE(
84 ExecPython("from __future__ import print_function; import sys; print('o' "
85 "* 10000); print('e' * 10000, file=sys.stderr)",
86 &std_out, &std_err, &exit_code));
87 EXPECT_EQ(0, exit_code);
88 EXPECT_EQ(10001u, std_out.size());
89 EXPECT_EQ(10001u, std_err.size());
90
91 std_out.clear();
92 std_err.clear();
93 ASSERT_TRUE(
94 ExecPython("from __future__ import print_function; import sys; print('e' "
95 "* 10000, file=sys.stderr); print('o' * 10000)",
96 &std_out, &std_err, &exit_code));
97 EXPECT_EQ(0, exit_code);
98 EXPECT_EQ(10001u, std_out.size());
99 EXPECT_EQ(10001u, std_err.size());
100 }
101
TEST(ExecProcessTest,TestOneOutputClosed)102 TEST(ExecProcessTest, TestOneOutputClosed) {
103 std::string std_out, std_err;
104 int exit_code;
105
106 ASSERT_TRUE(ExecPython("import sys; sys.stderr.close(); print('o' * 10000)",
107 &std_out, &std_err, &exit_code));
108 EXPECT_EQ(0, exit_code);
109 EXPECT_EQ(10001u, std_out.size());
110 EXPECT_EQ(std_err.size(), 0u);
111
112 std_out.clear();
113 std_err.clear();
114 ASSERT_TRUE(
115 ExecPython("from __future__ import print_function; import sys; "
116 "sys.stdout.close(); print('e' * 10000, file=sys.stderr)",
117 &std_out, &std_err, &exit_code));
118 EXPECT_EQ(0, exit_code);
119 EXPECT_EQ(0u, std_out.size());
120 EXPECT_EQ(10001u, std_err.size());
121 }
122 #endif
123 } // namespace internal
124