Skip to content

Commit

Permalink
Windows: native launcher can run from a long path
Browse files Browse the repository at this point in the history
This change fixed a bug in `src/tools/launcher/util/data_parser.cc` when running the native launcher at a long path.

Closes bazelbuild#7222.

Change-Id: I2ed2c6cb32592d6a178df9a69fe31d6df0974f0c
PiperOrigin-RevId: 230705416
  • Loading branch information
meteorcloudy authored and Copybara-Service committed Jan 24, 2019
1 parent 84aaca1 commit f21ca8a
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 5 deletions.
83 changes: 81 additions & 2 deletions src/test/py/bazel/launcher_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import os
import stat
import string
import unittest
from src.test.py.bazel import test_base

Expand Down Expand Up @@ -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))
Expand All @@ -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:
Expand Down
7 changes: 5 additions & 2 deletions src/test/py/bazel/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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
"""
Expand All @@ -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)
Expand Down
4 changes: 3 additions & 1 deletion src/tools/launcher/util/data_parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <string>
#include <unordered_map>

#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"
Expand Down Expand Up @@ -89,7 +90,8 @@ bool LaunchDataParser::ParseLaunchData(LaunchInfo* launch_info,
bool LaunchDataParser::GetLaunchInfo(const wstring& binary_path,
LaunchInfo* launch_info) {
unique_ptr<ifstream> binary =
make_unique<ifstream>(binary_path, ios::binary | ios::in);
make_unique<ifstream>(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!");
Expand Down

0 comments on commit f21ca8a

Please sign in to comment.