16d528ed9Sopenharmony_ci// Copyright 2014 The Chromium Authors. All rights reserved.
26d528ed9Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
36d528ed9Sopenharmony_ci// found in the LICENSE file.
46d528ed9Sopenharmony_ci
56d528ed9Sopenharmony_ci#include "gn/exec_process.h"
66d528ed9Sopenharmony_ci
76d528ed9Sopenharmony_ci#include "base/command_line.h"
86d528ed9Sopenharmony_ci#include "base/files/scoped_temp_dir.h"
96d528ed9Sopenharmony_ci#include "base/strings/string_util.h"
106d528ed9Sopenharmony_ci#include "util/build_config.h"
116d528ed9Sopenharmony_ci#include "util/test/test.h"
126d528ed9Sopenharmony_ci
136d528ed9Sopenharmony_ci#if defined(OS_WIN)
146d528ed9Sopenharmony_ci#include "base/strings/utf_string_conversions.h"
156d528ed9Sopenharmony_ci#endif
166d528ed9Sopenharmony_ci
176d528ed9Sopenharmony_cinamespace internal {
186d528ed9Sopenharmony_ci
196d528ed9Sopenharmony_ci// TODO(cjhopman): Enable these tests when windows ExecProcess handles stderr.
206d528ed9Sopenharmony_ci// 'python' is not runnable on Windows. Adding ["cmd", "/c"] fails because
216d528ed9Sopenharmony_ci// CommandLine does unusual reordering of args.
226d528ed9Sopenharmony_ci#if !defined(OS_WIN)
236d528ed9Sopenharmony_cinamespace {
246d528ed9Sopenharmony_cibool ExecPython(const std::string& command,
256d528ed9Sopenharmony_ci                std::string* std_out,
266d528ed9Sopenharmony_ci                std::string* std_err,
276d528ed9Sopenharmony_ci                int* exit_code) {
286d528ed9Sopenharmony_ci  base::ScopedTempDir temp_dir;
296d528ed9Sopenharmony_ci  CHECK(temp_dir.CreateUniqueTempDir());
306d528ed9Sopenharmony_ci  base::CommandLine::StringVector args;
316d528ed9Sopenharmony_ci#if defined(OS_WIN)
326d528ed9Sopenharmony_ci  args.push_back(L"python");
336d528ed9Sopenharmony_ci  args.push_back(L"-c");
346d528ed9Sopenharmony_ci  args.push_back(base::UTF8ToUTF16(command));
356d528ed9Sopenharmony_ci#else
366d528ed9Sopenharmony_ci  args.push_back("python3");
376d528ed9Sopenharmony_ci  args.push_back("-c");
386d528ed9Sopenharmony_ci  args.push_back(command);
396d528ed9Sopenharmony_ci#endif
406d528ed9Sopenharmony_ci  return ExecProcess(base::CommandLine(args), temp_dir.GetPath(), std_out,
416d528ed9Sopenharmony_ci                     std_err, exit_code);
426d528ed9Sopenharmony_ci}
436d528ed9Sopenharmony_ci}  // namespace
446d528ed9Sopenharmony_ci
456d528ed9Sopenharmony_ciTEST(ExecProcessTest, TestExitCode) {
466d528ed9Sopenharmony_ci  std::string std_out, std_err;
476d528ed9Sopenharmony_ci  int exit_code;
486d528ed9Sopenharmony_ci
496d528ed9Sopenharmony_ci  ASSERT_TRUE(
506d528ed9Sopenharmony_ci      ExecPython("import sys; sys.exit(0)", &std_out, &std_err, &exit_code));
516d528ed9Sopenharmony_ci  EXPECT_EQ(0, exit_code);
526d528ed9Sopenharmony_ci
536d528ed9Sopenharmony_ci  ASSERT_TRUE(
546d528ed9Sopenharmony_ci      ExecPython("import sys; sys.exit(1)", &std_out, &std_err, &exit_code));
556d528ed9Sopenharmony_ci  EXPECT_EQ(1, exit_code);
566d528ed9Sopenharmony_ci
576d528ed9Sopenharmony_ci  ASSERT_TRUE(
586d528ed9Sopenharmony_ci      ExecPython("import sys; sys.exit(253)", &std_out, &std_err, &exit_code));
596d528ed9Sopenharmony_ci  EXPECT_EQ(253, exit_code);
606d528ed9Sopenharmony_ci
616d528ed9Sopenharmony_ci  ASSERT_TRUE(ExecPython("throw Exception()", &std_out, &std_err, &exit_code));
626d528ed9Sopenharmony_ci  EXPECT_EQ(1, exit_code);
636d528ed9Sopenharmony_ci}
646d528ed9Sopenharmony_ci
656d528ed9Sopenharmony_ci// Test that large output is handled correctly. There are various ways that this
666d528ed9Sopenharmony_ci// could potentially fail. For example, non-blocking Linux pipes have a 65536
676d528ed9Sopenharmony_ci// byte buffer and, if stdout is non-blocking, python will throw an IOError when
686d528ed9Sopenharmony_ci// a write exceeds the buffer size.
696d528ed9Sopenharmony_ciTEST(ExecProcessTest, TestLargeOutput) {
706d528ed9Sopenharmony_ci  std::string std_out, std_err;
716d528ed9Sopenharmony_ci  int exit_code;
726d528ed9Sopenharmony_ci
736d528ed9Sopenharmony_ci  ASSERT_TRUE(ExecPython("import sys; print('o' * 1000000)", &std_out, &std_err,
746d528ed9Sopenharmony_ci                         &exit_code));
756d528ed9Sopenharmony_ci  EXPECT_EQ(0, exit_code);
766d528ed9Sopenharmony_ci  EXPECT_EQ(1000001u, std_out.size());
776d528ed9Sopenharmony_ci}
786d528ed9Sopenharmony_ci
796d528ed9Sopenharmony_ciTEST(ExecProcessTest, TestStdoutAndStderrOutput) {
806d528ed9Sopenharmony_ci  std::string std_out, std_err;
816d528ed9Sopenharmony_ci  int exit_code;
826d528ed9Sopenharmony_ci
836d528ed9Sopenharmony_ci  ASSERT_TRUE(
846d528ed9Sopenharmony_ci      ExecPython("from __future__ import print_function; import sys; print('o' "
856d528ed9Sopenharmony_ci                 "* 10000); print('e' * 10000, file=sys.stderr)",
866d528ed9Sopenharmony_ci                 &std_out, &std_err, &exit_code));
876d528ed9Sopenharmony_ci  EXPECT_EQ(0, exit_code);
886d528ed9Sopenharmony_ci  EXPECT_EQ(10001u, std_out.size());
896d528ed9Sopenharmony_ci  EXPECT_EQ(10001u, std_err.size());
906d528ed9Sopenharmony_ci
916d528ed9Sopenharmony_ci  std_out.clear();
926d528ed9Sopenharmony_ci  std_err.clear();
936d528ed9Sopenharmony_ci  ASSERT_TRUE(
946d528ed9Sopenharmony_ci      ExecPython("from __future__ import print_function; import sys; print('e' "
956d528ed9Sopenharmony_ci                 "* 10000, file=sys.stderr); print('o' * 10000)",
966d528ed9Sopenharmony_ci                 &std_out, &std_err, &exit_code));
976d528ed9Sopenharmony_ci  EXPECT_EQ(0, exit_code);
986d528ed9Sopenharmony_ci  EXPECT_EQ(10001u, std_out.size());
996d528ed9Sopenharmony_ci  EXPECT_EQ(10001u, std_err.size());
1006d528ed9Sopenharmony_ci}
1016d528ed9Sopenharmony_ci
1026d528ed9Sopenharmony_ciTEST(ExecProcessTest, TestOneOutputClosed) {
1036d528ed9Sopenharmony_ci  std::string std_out, std_err;
1046d528ed9Sopenharmony_ci  int exit_code;
1056d528ed9Sopenharmony_ci
1066d528ed9Sopenharmony_ci  ASSERT_TRUE(ExecPython("import sys; sys.stderr.close(); print('o' * 10000)",
1076d528ed9Sopenharmony_ci                         &std_out, &std_err, &exit_code));
1086d528ed9Sopenharmony_ci  EXPECT_EQ(0, exit_code);
1096d528ed9Sopenharmony_ci  EXPECT_EQ(10001u, std_out.size());
1106d528ed9Sopenharmony_ci  EXPECT_EQ(std_err.size(), 0u);
1116d528ed9Sopenharmony_ci
1126d528ed9Sopenharmony_ci  std_out.clear();
1136d528ed9Sopenharmony_ci  std_err.clear();
1146d528ed9Sopenharmony_ci  ASSERT_TRUE(
1156d528ed9Sopenharmony_ci      ExecPython("from __future__ import print_function; import sys; "
1166d528ed9Sopenharmony_ci                 "sys.stdout.close(); print('e' * 10000, file=sys.stderr)",
1176d528ed9Sopenharmony_ci                 &std_out, &std_err, &exit_code));
1186d528ed9Sopenharmony_ci  EXPECT_EQ(0, exit_code);
1196d528ed9Sopenharmony_ci  EXPECT_EQ(0u, std_out.size());
1206d528ed9Sopenharmony_ci  EXPECT_EQ(10001u, std_err.size());
1216d528ed9Sopenharmony_ci}
1226d528ed9Sopenharmony_ci#endif
1236d528ed9Sopenharmony_ci}  // namespace internal
124