• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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