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