# pylint: disable=g-bad-file-header
# Copyright 2017 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

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

# pylint: disable=g-import-not-at-top
if os.name == 'nt':
  import win32api


class LauncherTest(test_base.TestBase):

  def _buildJavaTargets(self, bazel_bin, binary_suffix):
    exit_code, _, stderr = self.RunBazel(['build', '//foo'])
    self.AssertExitCode(exit_code, 0, stderr)
    main_binary = os.path.join(bazel_bin, 'foo/foo%s' % binary_suffix)
    self.assertTrue(os.path.isfile(main_binary))
    self.assertTrue(
        os.path.isdir(
            os.path.join(bazel_bin, 'foo/foo%s.runfiles' % binary_suffix)))

    if self.IsWindows():
      self.assertTrue(os.path.isfile(main_binary))
      self.AssertRunfilesManifestContains(
          os.path.join(bazel_bin,
                       'foo/foo%s.runfiles/MANIFEST' % binary_suffix),
          '__main__/bar/bar.txt')
    else:
      self.assertTrue(
          os.path.islink(
              os.path.join(bazel_bin, 'foo/foo.runfiles/__main__/bar/bar.txt')))

    exit_code, stdout, stderr = self.RunProgram([main_binary])
    self.AssertExitCode(exit_code, 0, stderr)
    self.assertEqual(len(stdout), 4)
    self.assertEqual(stdout[0], 'hello java')
    if self.IsWindows():
      self.assertRegexpMatches(
          stdout[1], r'java_runfiles=.*foo\\foo%s.runfiles' % binary_suffix)
      self.assertEqual(stdout[2], 'runfiles_manifest_only=1')
      self.assertRegexpMatches(
          stdout[3], r'^runfiles_manifest_file=[a-zA-Z]:[/\\].*MANIFEST$')
    else:
      self.assertRegexpMatches(stdout[1], r'java_runfiles=.*/foo/foo.runfiles')
      self.assertEqual(stdout[2], 'runfiles_manifest_only=')
      self.assertRegexpMatches(stdout[3], r'^runfiles_manifest_file.*MANIFEST$')

  def _buildShBinaryTargets(self, bazel_bin, bin1_suffix):
    exit_code, _, stderr = self.RunBazel(['build', '//foo:bin1.sh'])
    self.AssertExitCode(exit_code, 0, stderr)

    bin1 = os.path.join(bazel_bin, 'foo', 'bin1.sh%s' % bin1_suffix)

    self.assertTrue(os.path.exists(bin1))
    self.assertTrue(
        os.path.isdir(
            os.path.join(bazel_bin, 'foo/bin1.sh%s.runfiles' % bin1_suffix)))

    exit_code, _, stderr = self.RunBazel(['build', '//foo:bin2.cmd'])
    self.AssertExitCode(exit_code, 0, stderr)

    bin2 = os.path.join(bazel_bin, 'foo/bin2.cmd')
    self.assertTrue(os.path.exists(bin2))
    self.assertTrue(
        os.path.isdir(os.path.join(bazel_bin, 'foo/bin2.cmd.runfiles')))

    exit_code, _, stderr = self.RunBazel(['build', '//foo:bin3.bat'])
    if self.IsWindows():
      self.AssertExitCode(exit_code, 1, stderr)
      self.assertIn('target name extension should match source file extension',
                    os.linesep.join(stderr))
    else:
      bin3 = os.path.join(bazel_bin, 'foo', 'bin3.bat')
      self.assertTrue(os.path.exists(bin3))
      self.assertTrue(
          os.path.isdir(os.path.join(bazel_bin, 'foo/bin3.bat.runfiles')))

    if self.IsWindows():
      self.assertTrue(os.path.isfile(bin1))
      self.assertTrue(os.path.isfile(bin2))
    else:
      self.assertTrue(os.path.islink(bin1))
      self.assertTrue(os.path.islink(bin2))
      self.assertTrue(os.path.islink(bin3))

    if self.IsWindows():
      self.AssertRunfilesManifestContains(
          os.path.join(bazel_bin,
                       'foo/bin1.sh%s.runfiles/MANIFEST' % bin1_suffix),
          '__main__/bar/bar.txt')
      self.AssertRunfilesManifestContains(
          os.path.join(bazel_bin, 'foo/bin2.cmd.runfiles/MANIFEST'),
          '__main__/bar/bar.txt')
    else:
      self.assertTrue(
          os.path.islink(
              os.path.join(bazel_bin,
                           'foo/bin1.sh.runfiles/__main__/bar/bar.txt')))
      self.assertTrue(
          os.path.islink(
              os.path.join(bazel_bin,
                           'foo/bin2.cmd.runfiles/__main__/bar/bar.txt')))
      self.assertTrue(
          os.path.islink(
              os.path.join(bazel_bin,
                           'foo/bin3.bat.runfiles/__main__/bar/bar.txt')))

    exit_code, stdout, stderr = self.RunProgram([bin1])
    self.AssertExitCode(exit_code, 0, stderr)
    self.assertEqual(len(stdout), 3)
    self.assertEqual(stdout[0], 'hello shell')
    if self.IsWindows():
      self.assertEqual(stdout[1], 'runfiles_manifest_only=1')
      self.assertRegexpMatches(
          stdout[2],
          (r'^runfiles_manifest_file='
           r'[a-zA-Z]:/.*/foo/bin1.sh%s.runfiles/MANIFEST$' % bin1_suffix))
    else:
      # TODO(laszlocsomor): Find out whether the runfiles-related envvars should
      # be set on Linux (e.g. $RUNFILES, $RUNFILES_MANIFEST_FILE). Currently
      # they aren't, and that may be a bug. If it's indeed a bug, fix that bug
      # and update this test.
      self.assertEqual(stdout[1], 'runfiles_manifest_only=')
      self.assertEqual(stdout[2], 'runfiles_manifest_file=')

    if self.IsWindows():
      exit_code, stdout, stderr = self.RunProgram([bin2])
      self.AssertExitCode(exit_code, 0, stderr)
      self.assertEqual(stdout[0], 'hello batch')

  def _buildPyTargets(self, bazel_bin, binary_suffix):
    # Verify that the build of our py_binary succeeds.
    exit_code, _, stderr = self.RunBazel(['build', '//foo:foo'])
    self.AssertExitCode(exit_code, 0, stderr)

    # Verify that generated files exist.
    foo_bin = os.path.join(bazel_bin, 'foo', 'foo%s' % binary_suffix)
    self.assertTrue(os.path.isfile(foo_bin))
    self.assertTrue(
        os.path.isdir(
            os.path.join(bazel_bin, 'foo/foo%s.runfiles' % binary_suffix)))

    # Verify contents of runfiles (manifest).
    if self.IsWindows():
      self.AssertRunfilesManifestContains(
          os.path.join(bazel_bin,
                       'foo/foo%s.runfiles/MANIFEST' % binary_suffix),
          '__main__/bar/bar.txt')
    else:
      self.assertTrue(
          os.path.islink(
              os.path.join(bazel_bin, 'foo/foo.runfiles/__main__/bar/bar.txt')))

    # Try to run the built py_binary.
    exit_code, stdout, stderr = self.RunProgram([foo_bin])
    self.AssertExitCode(exit_code, 0, stderr)
    self.assertEqual(stdout[0], 'Hello World!')

    # Try to use the py_binary as an executable in a Starlark rule.
    exit_code, stdout, stderr = self.RunBazel(['build', '//foo:hello'])
    self.AssertExitCode(exit_code, 0, stderr)

    # Verify that the Starlark action generated the right output.
    hello_path = os.path.join(bazel_bin, 'foo', 'hello.txt')
    self.assertTrue(os.path.isfile(hello_path))
    with open(hello_path, 'r') as f:
      self.assertEqual(f.read(), 'Hello World!')

    # Verify that running py_test succeeds.
    exit_code, _, stderr = self.RunBazel(['test', '//foo:test'])
    self.AssertExitCode(exit_code, 0, stderr)

  def _buildAndCheckArgumentPassing(self, package, target_name):
    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', '//%s:%s' % (package, target_name)])
    self.AssertExitCode(exit_code, 0, stderr)

    bin_suffix = '.exe' if self.IsWindows() else ''
    bin1 = os.path.join(bazel_bin, package, '%s%s' % (target_name, bin_suffix))
    self.assertTrue(os.path.exists(bin1))
    self.assertTrue(
        os.path.isdir(
            os.path.join(bazel_bin, '%s/%s%s.runfiles' % (package, target_name,
                                                          bin_suffix))))

    arguments = ['a', 'a b', '"b"', 'C:\\a\\b\\', '"C:\\a b\\c\\"']
    exit_code, stdout, stderr = self.RunProgram([bin1] + arguments)
    self.AssertExitCode(exit_code, 0, stderr)
    self.assertEqual(stdout, arguments)

  def testJavaBinaryLauncher(self):
    self.CreateWorkspaceWithDefaultRepos('WORKSPACE')
    self.ScratchFile('foo/BUILD', [
        'java_binary(',
        '  name = "foo",',
        '  srcs = ["Main.java"],',
        '  main_class = "Main",',
        '  data = ["//bar:bar.txt"],',
        ')',
    ])
    self.ScratchFile('foo/Main.java', [
        'public class Main {',
        '  public static void main(String[] args) {'
        '    System.out.println("hello java");',
        '    System.out.println("java_runfiles=" + ',
        '        System.getenv("JAVA_RUNFILES"));',
        '    System.out.println("runfiles_manifest_only=" + ',
        '        System.getenv("RUNFILES_MANIFEST_ONLY"));',
        '    System.out.println("runfiles_manifest_file=" + ',
        '        System.getenv("RUNFILES_MANIFEST_FILE"));',
        '  }',
        '}',
    ])
    self.ScratchFile('bar/BUILD', ['exports_files(["bar.txt"])'])
    self.ScratchFile('bar/bar.txt', ['hello'])

    exit_code, stdout, stderr = self.RunBazel(['info', 'bazel-bin'])
    self.AssertExitCode(exit_code, 0, stderr)
    bazel_bin = stdout[0]
    self._buildJavaTargets(bazel_bin, '.exe' if self.IsWindows() else '')

  def testJavaBinaryArgumentPassing(self):
    self.CreateWorkspaceWithDefaultRepos('WORKSPACE')
    self.ScratchFile('foo/BUILD', [
        'java_binary(',
        '  name = "bin",',
        '  srcs = ["Main.java"],',
        '  main_class = "Main",',
        ')',
    ])
    self.ScratchFile('foo/Main.java', [
        'public class Main {',
        '  public static void main(String[] args) {'
        '    for (String arg : args) {',
        '      System.out.println(arg);',
        '    }'
        '  }',
        '}',
    ])

    self._buildAndCheckArgumentPassing('foo', 'bin')

  def testShBinaryLauncher(self):
    self.CreateWorkspaceWithDefaultRepos('WORKSPACE')
    self.ScratchFile(
        'foo/BUILD',
        [
            # On Linux/MacOS, all sh_binary rules generate an output file with
            # the same name as the rule, and this is a symlink to the file in
            # `srcs`. (Bazel allows only one file in `sh_binary.srcs`.)
            # On Windows, if the srcs's extension is one of ".exe", ".cmd", or
            # ".bat", then Bazel requires the rule's name has the same
            # extension, and the output file will be a copy of the source file.
            'sh_binary(',
            '  name = "bin1.sh",',
            '  srcs = ["foo.sh"],',
            '  data = ["//bar:bar.txt"],',
            ')',
            'sh_binary(',
            '  name = "bin2.cmd",',  # name's extension matches that of srcs[0]
            '  srcs = ["foo.cmd"],',
            '  data = ["//bar:bar.txt"],',
            ')',
            'sh_binary(',
            '  name = "bin3.bat",',  # name's extension doesn't match srcs[0]'s
            '  srcs = ["foo.cmd"],',
            '  data = ["//bar:bar.txt"],',
            ')',
        ])
    foo_sh = self.ScratchFile('foo/foo.sh', [
        '#!/bin/bash',
        'echo hello shell',
        'echo runfiles_manifest_only=${RUNFILES_MANIFEST_ONLY:-}',
        'echo runfiles_manifest_file=${RUNFILES_MANIFEST_FILE:-}',
    ])
    foo_cmd = self.ScratchFile('foo/foo.cmd', ['@echo hello batch'])
    self.ScratchFile('bar/BUILD', ['exports_files(["bar.txt"])'])
    self.ScratchFile('bar/bar.txt', ['hello'])
    os.chmod(foo_sh, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR)
    os.chmod(foo_cmd, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR)

    exit_code, stdout, stderr = self.RunBazel(['info', 'bazel-bin'])
    self.AssertExitCode(exit_code, 0, stderr)
    bazel_bin = stdout[0]
    self._buildShBinaryTargets(bazel_bin, '.exe' if self.IsWindows() else '')

  def testShBinaryArgumentPassing(self):
    self.CreateWorkspaceWithDefaultRepos('WORKSPACE')
    self.ScratchFile('foo/BUILD', [
        'sh_binary(',
        '  name = "bin",',
        '  srcs = ["bin.sh"],',
        ')',
    ])
    foo_sh = self.ScratchFile('foo/bin.sh', [
        '#!/bin/bash',
        '# Store arguments in a array',
        'args=("$@")',
        '# Get the number of arguments',
        'N=${#args[@]}',
        '# Echo each argument',
        'for (( i=0;i<$N;i++)); do',
        ' echo ${args[${i}]}',
        'done',
    ])
    os.chmod(foo_sh, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR)

    self._buildAndCheckArgumentPassing('foo', 'bin')

  def testPyBinaryLauncher(self):
    self.CreateWorkspaceWithDefaultRepos('WORKSPACE')
    self.ScratchFile(
        'foo/foo.bzl',
        [
            'def _impl(ctx):',
            '  ctx.actions.run(',
            '      arguments=[ctx.outputs.out.path],',
            '      outputs=[ctx.outputs.out],',
            '      executable=ctx.executable._hello_world,',
            '      use_default_shell_env=True)',
            '',
            'helloworld = rule(',
            '  implementation=_impl,',
            '  attrs={',
            '      "srcs": attr.label_list(allow_files=True),',
            '      "out": attr.output(mandatory=True),',
            '      "_hello_world": attr.label(executable=True, cfg="exec",',
            '                                 allow_files=True,',
            '                                 default=Label("//foo:foo"))',
            '  }',
            ')',
        ],
    )
    self.ScratchFile('foo/BUILD', [
        'load(":foo.bzl", "helloworld")', '', 'py_binary(', '  name = "foo",',
        '  srcs = ["foo.py"],', '  data = ["//bar:bar.txt"],', ')', '',
        'py_test(', '  name = "test",', '  srcs = ["test.py"],', ')', '',
        'helloworld(', '  name = "hello",', '  out = "hello.txt",', ')'
    ])
    foo_py = self.ScratchFile('foo/foo.py', [
        '#!/usr/bin/env python3',
        'import sys',
        'if len(sys.argv) == 2:',
        '  with open(sys.argv[1], "w") as f:',
        '    f.write("Hello World!")',
        'else:',
        '  print("Hello World!")',
    ])
    test_py = self.ScratchFile('foo/test.py', [
        '#!/usr/bin/env python3',
        'import unittest',
        'class MyTest(unittest.TestCase):',
        '  def test_dummy(self):',
        '      pass',
        'if __name__ == \'__main__\':',
        '  unittest.main()',
    ])
    self.ScratchFile('bar/BUILD', ['exports_files(["bar.txt"])'])
    self.ScratchFile('bar/bar.txt', ['hello'])
    os.chmod(foo_py, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR)
    os.chmod(test_py, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR)

    exit_code, stdout, stderr = self.RunBazel(['info', 'bazel-bin'])
    self.AssertExitCode(exit_code, 0, stderr)
    bazel_bin = stdout[0]
    self._buildPyTargets(bazel_bin, '.exe' if self.IsWindows() else '')

  def testPyBinaryArgumentPassing(self):
    self.CreateWorkspaceWithDefaultRepos('WORKSPACE')
    self.ScratchFile('foo/BUILD', [
        'py_binary(',
        '  name = "bin",',
        '  srcs = ["bin.py"],',
        ')',
    ])
    self.ScratchFile('foo/bin.py', [
        'import sys',
        'for arg in sys.argv[1:]:',
        '  print(arg)',
    ])

    self._buildAndCheckArgumentPassing('foo', 'bin')

  def testPyBinaryLauncherWithDifferentArgv0(self):
    """Test for https://github.com/bazelbuild/bazel/issues/14343."""
    self.CreateWorkspaceWithDefaultRepos('WORKSPACE')
    self.ScratchFile('foo/BUILD', [
        'py_binary(',
        '  name = "bin",',
        '  srcs = ["bin.py"],',
        ')',
    ])
    self.ScratchFile('foo/bin.py', ['print("Hello world")'])

    exit_code, stdout, stderr = self.RunBazel(['info', 'bazel-bin'])
    self.AssertExitCode(exit_code, 0, stderr)
    bazel_bin = stdout[0]

    # Verify that the build of our py_binary succeeds.
    exit_code, _, stderr = self.RunBazel(['build', '//foo:bin'])
    self.AssertExitCode(exit_code, 0, stderr)

    # Try to run the built py_binary.
    binary_suffix = '.exe' if self.IsWindows() else ''
    foo_bin = os.path.join(bazel_bin, 'foo', 'bin%s' % binary_suffix)
    args = [r'C:\Invalid.exe' if self.IsWindows() else '/invalid']
    exit_code, stdout, stderr = self.RunProgram(args, executable=foo_bin)
    self.AssertExitCode(exit_code, 0, stderr)
    self.assertEqual(stdout[0], 'Hello world')

  def testWindowsJavaExeLauncher(self):
    # Skip this test on non-Windows platforms
    if not self.IsWindows():
      return
    self.CreateWorkspaceWithDefaultRepos('WORKSPACE')
    self.ScratchFile('foo/BUILD', [
        'java_binary(',
        '  name = "foo",',
        '  srcs = ["Main.java"],',
        '  main_class = "Main",',
        '  jvm_flags = ["--flag1", "--flag2"],',
        '  data = ["advice-1.jar", "advice-2.jar"],',
        ')',
    ])
    self.ScratchFile('foo/advice-1.jar')
    self.ScratchFile('foo/advice-2.jar')
    self.ScratchFile('foo/Main.java', [
        'public class Main {',
        '  public static void main(String[] args) {',
        '    System.out.println("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', '//foo:foo'])
    self.AssertExitCode(exit_code, 0, stderr)

    binary = os.path.join(bazel_bin, 'foo', 'foo.exe')
    self.assertTrue(os.path.exists(binary))

    # Add this flag to make launcher print the command it generated instead of
    # launching the real program.
    print_cmd = '--print_launcher_command'

    exit_code, stdout, stderr = self.RunProgram([binary, '--debug', print_cmd])
    self.AssertExitCode(exit_code, 0, stderr)
    self.assertIn(
        '-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005',
        stdout)

    exit_code, stdout, stderr = self.RunProgram(
        [binary, '--debug', print_cmd],
        env_add={'DEFAULT_JVM_DEBUG_PORT': '12345'})
    self.AssertExitCode(exit_code, 0, stderr)
    self.assertIn(
        '-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=12345',
        stdout)

    exit_code, stdout, stderr = self.RunProgram(
        [binary, '--debug=12345', print_cmd],
        env_add={
            'DEFAULT_JVM_DEBUG_SUSPEND': 'n',
            'PERSISTENT_TEST_RUNNER': 'true'
        })
    self.AssertExitCode(exit_code, 0, stderr)
    self.assertIn(
        '-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=12345'
        ',quiet=y', stdout)

    exit_code, stdout, stderr = self.RunProgram(
        [binary, '--main_advice=MyMain', print_cmd])
    self.AssertExitCode(exit_code, 0, stderr)
    self.assertIn('MyMain', stdout)

    exit_code, stdout, stderr = self.RunProgram([
        binary, '--main_advice_classpath=foo/advice-1.jar;foo/advice-2.jar',
        print_cmd
    ])
    self.AssertExitCode(exit_code, 0, stderr)
    self.assertIn('-classpath', stdout)
    classpath = stdout[stdout.index('-classpath') + 1]
    self.assertIn('foo/advice-1.jar', classpath)
    self.assertIn('foo/advice-2.jar', classpath)

    exit_code, stdout, stderr = self.RunProgram(
        [binary, '--main_advice_classpath=C:\\foo\\bar', print_cmd])
    self.AssertExitCode(exit_code, 0, stderr)
    self.assertIn('-classpath', stdout)
    classpath = stdout[stdout.index('-classpath') + 1]
    self.assertIn('C:\\foo\\bar', classpath)

    exit_code, stdout, stderr = self.RunProgram(
        [binary, '--jvm_flag="--some_path="./a b/c""', print_cmd])
    self.AssertExitCode(exit_code, 0, stderr)
    self.assertIn('"--some_path=\\"./a b/c\\""', stdout)

    exit_code, stdout, stderr = self.RunProgram(
        [binary, '--jvm_flags="--path1=a --path2=b"', print_cmd])
    self.AssertExitCode(exit_code, 0, stderr)
    self.assertIn('--path1=a', stdout)
    self.assertIn('--path2=b', stdout)

    exit_code, stdout, stderr = self.RunProgram(
        [binary, print_cmd], env_add={'JVM_FLAGS': '--foo --bar'})
    self.AssertExitCode(exit_code, 0, stderr)
    self.assertIn('--flag1', stdout)
    self.assertIn('--flag2', stdout)
    self.assertIn('--foo', stdout)
    self.assertIn('--bar', stdout)

    exit_code, stdout, stderr = self.RunProgram(
        [binary, '--singlejar', print_cmd])
    self.AssertExitCode(exit_code, 1, stderr)
    self.assertIn('foo_deploy.jar does not exist', ''.join(stderr))
    exit_code, _, stderr = self.RunBazel(['build', '//foo:foo_deploy.jar'])
    self.AssertExitCode(exit_code, 0, stderr)
    exit_code, stdout, stderr = self.RunProgram(
        [binary, '--singlejar', print_cmd])
    self.AssertExitCode(exit_code, 0, stderr)
    self.assertIn('-classpath', stdout)
    classpath = stdout[stdout.index('-classpath') + 1]
    self.assertIn('foo_deploy.jar', classpath)

    exit_code, stdout, stderr = self.RunProgram([binary, '--print_javabin'])
    self.AssertExitCode(exit_code, 0, stderr)
    self.assertIn('local_jdk/bin/java.exe', ''.join(stdout))

    my_tmp_dir = self.ScratchDir('my/temp/dir')
    exit_code, stdout, stderr = self.RunProgram(
        [binary, print_cmd], env_add={'TEST_TMPDIR': my_tmp_dir})
    self.AssertExitCode(exit_code, 0, stderr)
    self.assertIn('-Djava.io.tmpdir=%s' % my_tmp_dir, stdout)

    exit_code, stdout, stderr = self.RunProgram(
        [binary, '--classpath_limit=0', print_cmd])
    self.AssertExitCode(exit_code, 0, stderr)
    self.assertIn('-classpath', stdout)
    classpath = stdout[stdout.index('-classpath') + 1]
    self.assertRegexpMatches(classpath, r'foo-[A-Za-z0-9]+-classpath.jar$')

  def testWindowsNativeLauncherInNonEnglishPath(self):
    if not self.IsWindows():
      return
    self.CreateWorkspaceWithDefaultRepos('WORKSPACE')
    self.ScratchFile('bin/BUILD', [
        'java_binary(',
        '  name = "bin_java",',
        '  srcs = ["Main.java"],',
        '  main_class = "Main",',
        ')',
        'sh_binary(',
        '  name = "bin_sh",',
        '  srcs = ["main.sh"],',
        ')',
    ])
    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"',
    ])

    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)

    for f in [
        '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))

    unicode_binary_path = u'./\u6d4b\u8bd5/bin_java.exe'
    exit_code, stdout, stderr = self.RunProgram([unicode_binary_path])
    self.AssertExitCode(exit_code, 0, stderr)
    self.assertEqual('helloworld', ''.join(stdout))

    unicode_binary_path = u'./\u6d4b\u8bd5/bin_sh.exe'
    exit_code, stdout, stderr = self.RunProgram([unicode_binary_path])
    self.AssertExitCode(exit_code, 0, stderr)
    self.assertEqual('helloworld', ''.join(stdout))

  def testWindowsNativeLauncherInLongPath(self):
    if not self.IsWindows():
      return
    self.CreateWorkspaceWithDefaultRepos('WORKSPACE')
    self.ScratchFile(
        'bin/BUILD',
        [
            'java_binary(',
            '  name = "not_short_bin_java",',
            '  srcs = ["Main.java"],',
            '  main_class = "Main",',
            ')',
            'sh_binary(',
            '  name = "not_short_bin_sh",',
            '  srcs = ["main.sh"],',
            ')',
            'py_binary(',
            '  name = "not_short_bin_py",',
            '  srcs = ["not_short_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/not_short_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])

    # The 'not_short_' prefix ensures that the basenames are not already 8.3
    # short paths. Due to the long directory path, the basename will thus be
    # replaced with a short path such as "not_sh~1.exe" below.
    for f in [
        'not_short_bin_java.exe',
        'not_short_bin_java.exe.runfiles_manifest',
        'not_short_bin_sh.exe',
        'not_short_bin_sh',
        'not_short_bin_sh.exe.runfiles_manifest',
        'not_short_bin_py.exe',
        'not_short_bin_py.zip',
        'not_short_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 + '/not_short_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))
    # Make sure we can launch the binary with a shortened Windows 8dot3 path
    short_binary_path = win32api.GetShortPathName(long_binary_path)
    self.assertIn('~', os.path.basename(short_binary_path))
    exit_code, stdout, stderr = self.RunProgram([short_binary_path], shell=True)
    self.AssertExitCode(exit_code, 0, stderr)
    self.assertEqual('helloworld', ''.join(stdout))

    long_binary_path = os.path.abspath(long_dir_path + '/not_short_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))
    # Make sure we can launch the binary with a shortened Windows 8dot3 path
    short_binary_path = win32api.GetShortPathName(long_binary_path)
    self.assertIn('~', os.path.basename(short_binary_path))
    exit_code, stdout, stderr = self.RunProgram([short_binary_path], shell=True)
    self.AssertExitCode(exit_code, 0, stderr)
    self.assertEqual('helloworld', ''.join(stdout))

    long_binary_path = os.path.abspath(long_dir_path + '/not_short_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))
    # Make sure we can launch the binary with a shortened Windows 8dot3 path
    short_binary_path = win32api.GetShortPathName(long_binary_path)
    self.assertIn('~', os.path.basename(short_binary_path))
    exit_code, stdout, stderr = self.RunProgram([short_binary_path], shell=True)
    self.AssertExitCode(exit_code, 0, stderr)
    self.assertEqual('helloworld', ''.join(stdout))

  def testWindowsNativeLauncherInvalidArgv0(self):
    if not self.IsWindows():
      return
    self.CreateWorkspaceWithDefaultRepos('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)

    exit_code, stdout, stderr = self.RunProgram(
        ['C:\\Invalid'],
        executable=os.path.join(bazel_bin, 'bin', 'bin_java.exe'),
    )
    self.AssertExitCode(exit_code, 0, stderr)
    self.assertEqual('helloworld', ''.join(stdout))

    exit_code, stdout, stderr = self.RunProgram(
        ['C:\\Invalid'], executable=os.path.join(bazel_bin, 'bin', 'bin_sh.exe')
    )
    self.AssertExitCode(exit_code, 0, stderr)
    self.assertEqual('helloworld', ''.join(stdout))

    exit_code, stdout, stderr = self.RunProgram(
        ['C:\\Invalid'], executable=os.path.join(bazel_bin, 'bin', 'bin_py.exe')
    )
    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:
        tokens = l.strip().split(' ', 1)
        if len(tokens) == 2 and tokens[0] == entry:
          return
    self.fail('Runfiles manifest "%s" did not contain "%s"' % (manifest, entry))


if __name__ == '__main__':
  unittest.main()
