Skip to content

Commit

Permalink
Windows tests: Use the bazel MANIFEST file to locate the .exe of the …
Browse files Browse the repository at this point in the history
…py_binary.

Added a workaround for bazelbuild/bazel#4001 in absltest_test.py.

PiperOrigin-RevId: 182114298
  • Loading branch information
yilei authored and Copybara-Service committed Jan 16, 2018
1 parent 809bfce commit bf431a0
Show file tree
Hide file tree
Showing 10 changed files with 62 additions and 40 deletions.
3 changes: 1 addition & 2 deletions absl/logging/tests/logging_functional_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -280,8 +280,7 @@ class FunctionalTest(parameterized.TestCase):

def _get_helper(self):
return _bazelize_command.get_executable_path(
os.path.join(os.path.dirname(__file__),
'logging_functional_test_helper'))
'absl/logging/tests/logging_functional_test_helper')
def _get_logs(self,
verbosity,
include_info_prefix=True):
Expand Down
1 change: 1 addition & 0 deletions absl/testing/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ py_library(
srcs = ["_bazelize_command.py"],
srcs_version = "PY2AND3",
visibility = ["//:__subpackages__"],
deps = ["//absl/flags"],
)

py_test(
Expand Down
43 changes: 28 additions & 15 deletions absl/testing/_bazelize_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,30 +20,43 @@

import os

from absl import flags

def get_executable_path(py_binary_path):
FLAGS = flags.FLAGS


def get_executable_path(py_binary_name):
"""Returns the executable path of a py_binary.
This returns the executable path of a py_binary that is in another Bazel
target's data dependencies.
On Linux/macOS, it's the same as the py_binary_path.
On Windows, the py_binary_path points to a zip file, and Bazel 0.5.3+
generates a .cmd file that can be used to execute the py_binary.
On Linux/macOS, the path and __file__ has the same root directory.
On Windows, bazel builds an .exe file and we need to use the MANIFEST file
the location the actual binary.
Args:
py_binary_path: string, the path of a py_binary that is in another Bazel
py_binary_name: string, the name of a py_binary that is in another Bazel
target's data dependencies.
Raises:
RuntimeError: Raised when it cannot locate the executable path.
"""
if os.name == 'nt':
executable_path = py_binary_path + '.cmd'
if executable_path.startswith('\\\\?\\'):
# In Bazel 0.5.3 and Python 3, the paths starts with "\\?\".
# However, Python subprocess doesn't support those paths well.
# Strip them as we don't need the prefix.
# See this page for more informaton about "\\?\":
# https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247.
executable_path = executable_path[4:]
return executable_path
py_binary_name += '.exe'
manifest_file = os.path.join(FLAGS.test_srcdir, 'MANIFEST')
workspace_name = os.environ['TEST_WORKSPACE']
manifest_entry = '{}/{}'.format(workspace_name, py_binary_name)
with open(manifest_file, 'r') as manifest_fd:
for line in manifest_fd:
tokens = line.strip().split(' ')
if len(tokens) != 2:
continue
if manifest_entry == tokens[0]:
return tokens[1]
raise RuntimeError(
'Cannot locate executable path for {}, MANIFEST file: {}.'.format(
py_binary_name, manifest_file))
else:
return py_binary_path
root_directory = __file__[:-len('absl/testing/_bazelize_command.py')]
return os.path.join(root_directory, py_binary_name)
5 changes: 2 additions & 3 deletions absl/testing/tests/absltest_filtering_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@ class TestFilteringTest(absltest.TestCase):
"""

def setUp(self):
self._test_path = os.path.join(
os.path.dirname(__file__), 'absltest_filtering_test_helper')
self._test_name = 'absl/testing/tests/absltest_filtering_test_helper'

def _run_filtered(self, test_filter):
"""Runs the py_test binary in a subprocess.
Expand All @@ -54,7 +53,7 @@ def _run_filtered(self, test_filter):
env['TESTBRIDGE_TEST_ONLY'] = test_filter

proc = subprocess.Popen(
args=[_bazelize_command.get_executable_path(self._test_path)],
args=[_bazelize_command.get_executable_path(self._test_name)],
env=env,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
Expand Down
5 changes: 2 additions & 3 deletions absl/testing/tests/absltest_randomization_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@ class TestOrderRandomizationTest(parameterized.TestCase):
"""

def setUp(self):
self._test_path = os.path.join(
os.path.dirname(__file__), 'absltest_randomization_testcase')
self._test_name = 'absl/testing/tests/absltest_randomization_testcase'

def _run_test(self, extra_argv, extra_env):
"""Runs the py_test binary in a subprocess, with the given args or env.
Expand All @@ -58,7 +57,7 @@ def _run_test(self, extra_argv, extra_env):
env.update(extra_env)

command = (
[_bazelize_command.get_executable_path(self._test_path)] + extra_argv)
[_bazelize_command.get_executable_path(self._test_name)] + extra_argv)
proc = subprocess.Popen(
args=command,
env=env,
Expand Down
5 changes: 2 additions & 3 deletions absl/testing/tests/absltest_sharding_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,7 @@ class TestShardingTest(absltest.TestCase):
"""

def setUp(self):
self._test_path = os.path.join(
os.path.dirname(__file__), 'absltest_sharding_test_helper')
self._test_name = 'absl/testing/tests/absltest_sharding_test_helper'
self._shard_file = None

def tearDown(self):
Expand Down Expand Up @@ -69,7 +68,7 @@ def _run_sharded(self, total_shards, shard_index, shard_file=None):
os.unlink(shard_file)

proc = subprocess.Popen(
args=[_bazelize_command.get_executable_path(self._test_path)],
args=[_bazelize_command.get_executable_path(self._test_name)],
env=env,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
Expand Down
2 changes: 1 addition & 1 deletion absl/testing/tests/absltest_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class TestCaseTest(absltest.TestCase):
longMessage = True

def run_helper(self, test_id, args, env_overrides, expect_success):
helper = os.path.join(os.path.dirname(__file__), 'absltest_test_helper')
helper = 'absl/testing/tests/absltest_test_helper'
env = os.environ.copy()
for key, value in six.iteritems(env_overrides):
if value is None:
Expand Down
26 changes: 20 additions & 6 deletions absl/testing/tests/absltest_test_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,29 +47,43 @@ def test_flags(self):
self.assertTrue(os.access(FLAGS.test_tmpdir, os.W_OK))
elif FLAGS.test_id == 2:
self.assertEqual(FLAGS.test_random_seed, 321)
self.assertEqual(
self._assert_directories_equal(
FLAGS.test_srcdir,
os.environ['ABSLTEST_TEST_HELPER_EXPECTED_TEST_SRCDIR'])
self.assertEqual(
self._assert_directories_equal(
FLAGS.test_tmpdir,
os.environ['ABSLTEST_TEST_HELPER_EXPECTED_TEST_TMPDIR'])
elif FLAGS.test_id == 3:
self.assertEqual(FLAGS.test_random_seed, 123)
self.assertEqual(
self._assert_directories_equal(
FLAGS.test_srcdir,
os.environ['ABSLTEST_TEST_HELPER_EXPECTED_TEST_SRCDIR'])
self.assertEqual(
self._assert_directories_equal(
FLAGS.test_tmpdir,
os.environ['ABSLTEST_TEST_HELPER_EXPECTED_TEST_TMPDIR'])
elif FLAGS.test_id == 4:
self.assertEqual(FLAGS.test_random_seed, 221)
self.assertEqual(
self._assert_directories_equal(
FLAGS.test_srcdir,
os.environ['ABSLTEST_TEST_HELPER_EXPECTED_TEST_SRCDIR'])
self.assertEqual(
self._assert_directories_equal(
FLAGS.test_tmpdir,
os.environ['ABSLTEST_TEST_HELPER_EXPECTED_TEST_TMPDIR'])

def _assert_directories_equal(self, expected, actual):
if os.name == 'nt':
# Bazel on Windows has a bug where backslashes passed to subprocess are
# unnecessarily unescaped. This is the workaround before a new Bazel
# release that includes the fix is available.
# See https://github.com/bazelbuild/bazel/issues/4001.
if expected == actual:
return
if expected == actual.replace('\\', '\\\\'):
return
raise AssertionError('{} != {}', expected, actual)
else:
self.assertEqual(expected, actual)

@unittest.expectedFailure
def test_expected_failure(self):
if FLAGS.test_id == 5:
Expand Down
8 changes: 4 additions & 4 deletions absl/testing/tests/xml_reporter_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -693,8 +693,8 @@ def _run_test_and_get_xml(self, flag):
os.close(xml_fhandle)

try:
prog = os.path.join(os.path.dirname(__file__), 'xml_reporter_helper_test')
args = [_bazelize_command.get_executable_path(prog),
binary_name = 'absl/testing/tests/xml_reporter_helper_test'
args = [_bazelize_command.get_executable_path(binary_name),
flag, '--xml_output_file=%s' % xml_fname]
ret = subprocess.call(args)
self.assertNotEqual(ret, 0)
Expand All @@ -710,8 +710,8 @@ def _run_test(self, flag, num_errors, num_failures, suites):
os.close(xml_fhandle)

try:
prog = os.path.join(os.path.dirname(__file__), 'xml_reporter_helper_test')
args = [_bazelize_command.get_executable_path(prog),
binary_name = 'absl/testing/tests/xml_reporter_helper_test'
args = [_bazelize_command.get_executable_path(binary_name),
flag, '--xml_output_file=%s' % xml_fname]
ret = subprocess.call(args)
self.assertNotEqual(ret, 0)
Expand Down
4 changes: 1 addition & 3 deletions absl/tests/app_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,7 @@ def run_helper(self, expect_success,
env['APP_TEST_HELPER_TYPE'] = self.helper_type
if env_overrides:
env.update(env_overrides)
helper = os.path.join(
os.path.dirname(__file__),
'app_test_helper_{}'.format(self.helper_type))
helper = 'absl/tests/app_test_helper_{}'.format(self.helper_type)
process = subprocess.Popen(
[_bazelize_command.get_executable_path(helper)] + list(arguments),
stdout=subprocess.PIPE,
Expand Down

0 comments on commit bf431a0

Please sign in to comment.