From f21ca8ad99d0f0048af21ccf31c18bbb808336f3 Mon Sep 17 00:00:00 2001 From: Yun Peng Date: Thu, 24 Jan 2019 05:34:50 -0800 Subject: [PATCH] Windows: native launcher can run from a long path This change fixed a bug in `src/tools/launcher/util/data_parser.cc` when running the native launcher at a long path. Closes #7222. Change-Id: I2ed2c6cb32592d6a178df9a69fe31d6df0974f0c PiperOrigin-RevId: 230705416 --- src/test/py/bazel/launcher_test.py | 83 +++++++++++++++++++++++++- src/test/py/bazel/test_base.py | 7 ++- src/tools/launcher/util/data_parser.cc | 4 +- 3 files changed, 89 insertions(+), 5 deletions(-) diff --git a/src/test/py/bazel/launcher_test.py b/src/test/py/bazel/launcher_test.py index 8284a1a15c23e2..dfab59f76bd7a8 100644 --- a/src/test/py/bazel/launcher_test.py +++ b/src/test/py/bazel/launcher_test.py @@ -15,6 +15,7 @@ import os import stat +import string import unittest from src.test.py.bazel import test_base @@ -548,8 +549,11 @@ def testWindowsNativeLauncherInNonEnglishPath(self): self.AssertExitCode(exit_code, 0, stderr) for f in [ - 'bin_java.exe', 'bin_java.exe.runfiles_manifest', 'bin_sh.exe', - 'bin_sh', 'bin_sh.exe.runfiles_manifest' + 'bin_java.exe', + 'bin_java.exe.runfiles_manifest', + 'bin_sh.exe', + 'bin_sh', + 'bin_sh.exe.runfiles_manifest', ]: self.CopyFile(os.path.join(bazel_bin, 'bin', f), os.path.join(u'./\u6d4b\u8bd5', f)) @@ -564,6 +568,81 @@ def testWindowsNativeLauncherInNonEnglishPath(self): self.AssertExitCode(exit_code, 0, stderr) self.assertEqual('helloworld', ''.join(stdout)) + def testWindowsNativeLauncherInLongPath(self): + if not self.IsWindows(): + return + self.ScratchFile('WORKSPACE') + self.ScratchFile('bin/BUILD', [ + 'java_binary(', + ' name = "bin_java",', + ' srcs = ["Main.java"],', + ' main_class = "Main",', + ')', + 'sh_binary(', + ' name = "bin_sh",', + ' srcs = ["main.sh"],', + ')', + 'py_binary(', + ' name = "bin_py",', + ' srcs = ["bin_py.py"],', + ')', + ]) + self.ScratchFile('bin/Main.java', [ + 'public class Main {', + ' public static void main(String[] args) {' + ' System.out.println("helloworld");', + ' }', + '}', + ]) + self.ScratchFile('bin/main.sh', [ + 'echo "helloworld"', + ]) + self.ScratchFile('bin/bin_py.py', [ + 'print("helloworld")', + ]) + + exit_code, stdout, stderr = self.RunBazel(['info', 'bazel-bin']) + self.AssertExitCode(exit_code, 0, stderr) + bazel_bin = stdout[0] + + exit_code, _, stderr = self.RunBazel(['build', '//bin/...']) + self.AssertExitCode(exit_code, 0, stderr) + + # Create a directory with a path longer than 260 + long_dir_path = './' + '/'.join( + [(c * 8 + '.' + c * 3) for c in string.ascii_lowercase]) + + for f in [ + 'bin_java.exe', + 'bin_java.exe.runfiles_manifest', + 'bin_sh.exe', + 'bin_sh', + 'bin_sh.exe.runfiles_manifest', + 'bin_py.exe', + 'bin_py.zip', + 'bin_py.exe.runfiles_manifest', + ]: + self.CopyFile( + os.path.join(bazel_bin, 'bin', f), os.path.join(long_dir_path, f)) + + long_binary_path = os.path.abspath(long_dir_path + '/bin_java.exe') + # subprocess doesn't support long path without shell=True + exit_code, stdout, stderr = self.RunProgram([long_binary_path], shell=True) + self.AssertExitCode(exit_code, 0, stderr) + self.assertEqual('helloworld', ''.join(stdout)) + + long_binary_path = os.path.abspath(long_dir_path + '/bin_sh.exe') + # subprocess doesn't support long path without shell=True + exit_code, stdout, stderr = self.RunProgram([long_binary_path], shell=True) + self.AssertExitCode(exit_code, 0, stderr) + self.assertEqual('helloworld', ''.join(stdout)) + + long_binary_path = os.path.abspath(long_dir_path + '/bin_py.exe') + # subprocess doesn't support long path without shell=True + exit_code, stdout, stderr = self.RunProgram([long_binary_path], shell=True) + self.AssertExitCode(exit_code, 0, stderr) + self.assertEqual('helloworld', ''.join(stdout)) + def AssertRunfilesManifestContains(self, manifest, entry): with open(manifest, 'r') as f: for l in f: diff --git a/src/test/py/bazel/test_base.py b/src/test/py/bazel/test_base.py index 6455ae2365bd85..01f694f9143600 100644 --- a/src/test/py/bazel/test_base.py +++ b/src/test/py/bazel/test_base.py @@ -310,7 +310,7 @@ def StopRemoteWorker(self): print('--------------------------') print('\n'.join(stderr_lines)) - def RunProgram(self, args, env_remove=None, env_add=None): + def RunProgram(self, args, env_remove=None, env_add=None, shell=False): """Runs a program (args[0]), waits for it to exit. Args: @@ -319,6 +319,8 @@ def RunProgram(self, args, env_remove=None, env_add=None): to the program env_add: {string: string}; optional; environment variables to pass to the program, won't be removed by env_remove. + shell: {bool: bool}; optional; whether to use the shell as the program + to execute Returns: (int, [string], [string]) tuple: exit code, stdout lines, stderr lines """ @@ -329,7 +331,8 @@ def RunProgram(self, args, env_remove=None, env_add=None): stdout=stdout, stderr=stderr, cwd=self._test_cwd, - env=self._EnvMap(env_remove, env_add)) + env=self._EnvMap(env_remove, env_add), + shell=shell) exit_code = proc.wait() stdout.seek(0) diff --git a/src/tools/launcher/util/data_parser.cc b/src/tools/launcher/util/data_parser.cc index cb77abefed1ee4..aeff52c898ebcb 100644 --- a/src/tools/launcher/util/data_parser.cc +++ b/src/tools/launcher/util/data_parser.cc @@ -17,6 +17,7 @@ #include #include +#include "src/main/cpp/util/path_platform.h" #include "src/main/cpp/util/strings.h" #include "src/tools/launcher/util/data_parser.h" #include "src/tools/launcher/util/launcher_util.h" @@ -89,7 +90,8 @@ bool LaunchDataParser::ParseLaunchData(LaunchInfo* launch_info, bool LaunchDataParser::GetLaunchInfo(const wstring& binary_path, LaunchInfo* launch_info) { unique_ptr binary = - make_unique(binary_path, ios::binary | ios::in); + make_unique(AsAbsoluteWindowsPath(binary_path.c_str()).c_str(), + ios::binary | ios::in); int64_t data_size = ReadDataSize(binary.get()); if (data_size == 0) { PrintError(L"No data appended, cannot launch anything!");