1# Copyright 2020 The Abseil Authors.
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#      http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15"""Tests for test fail fast protocol."""
16
17import subprocess
18
19from absl import logging
20from absl.testing import _bazelize_command
21from absl.testing import absltest
22from absl.testing import parameterized
23from absl.testing.tests import absltest_env
24
25
26@parameterized.named_parameters(
27    ('use_app_run', True),
28    ('no_argv', False),
29)
30class TestFailFastTest(parameterized.TestCase):
31  """Integration tests: Runs a test binary with fail fast.
32
33  This is done by setting the fail fast environment variable
34  """
35
36  def setUp(self):
37    super().setUp()
38    self._test_name = 'absl/testing/tests/absltest_fail_fast_test_helper'
39
40  def _run_fail_fast(self, fail_fast, use_app_run):
41    """Runs the py_test binary in a subprocess.
42
43    Args:
44      fail_fast: string, the fail fast value.
45      use_app_run: bool, whether the test helper should call
46          `absltest.main(argv=)` inside `app.run`.
47
48    Returns:
49      (stdout, exit_code) tuple of (string, int).
50    """
51    env = absltest_env.inherited_env()
52    if fail_fast is not None:
53      env['TESTBRIDGE_TEST_RUNNER_FAIL_FAST'] = fail_fast
54    env['USE_APP_RUN'] = '1' if use_app_run else '0'
55
56    proc = subprocess.Popen(
57        args=[_bazelize_command.get_executable_path(self._test_name)],
58        env=env,
59        stdout=subprocess.PIPE,
60        stderr=subprocess.STDOUT,
61        universal_newlines=True)
62    stdout = proc.communicate()[0]
63
64    logging.info('output: %s', stdout)
65    return stdout, proc.wait()
66
67  def test_no_fail_fast(self, use_app_run):
68    out, exit_code = self._run_fail_fast(None, use_app_run)
69    self.assertEqual(1, exit_code)
70    self.assertIn('class A test A', out)
71    self.assertIn('class A test B', out)
72    self.assertIn('class A test C', out)
73    self.assertIn('class A test D', out)
74    self.assertIn('class A test E', out)
75
76  def test_empty_fail_fast(self, use_app_run):
77    out, exit_code = self._run_fail_fast('', use_app_run)
78    self.assertEqual(1, exit_code)
79    self.assertIn('class A test A', out)
80    self.assertIn('class A test B', out)
81    self.assertIn('class A test C', out)
82    self.assertIn('class A test D', out)
83    self.assertIn('class A test E', out)
84
85  def test_fail_fast_1(self, use_app_run):
86    out, exit_code = self._run_fail_fast('1', use_app_run)
87    self.assertEqual(1, exit_code)
88    self.assertIn('class A test A', out)
89    self.assertIn('class A test B', out)
90    self.assertIn('class A test C', out)
91    self.assertNotIn('class A test D', out)
92    self.assertNotIn('class A test E', out)
93
94  def test_fail_fast_0(self, use_app_run):
95    out, exit_code = self._run_fail_fast('0', use_app_run)
96    self.assertEqual(1, exit_code)
97    self.assertIn('class A test A', out)
98    self.assertIn('class A test B', out)
99    self.assertIn('class A test C', out)
100    self.assertIn('class A test D', out)
101    self.assertIn('class A test E', out)
102
103
104if __name__ == '__main__':
105  absltest.main()
106