Repository: pantsbuild/pants

Issue:
`tests/python/pants_test/rules:test_integration` is flaky
See e.g., https://travis-ci.org/pantsbuild/pants/jobs/455855728

In `test_mixed_python_tests`, the expected output contains pytest's output for both `test_fail` and `test_pass`, but the output in practice contains only `test_pass`.

This works fine on my MacOS laptop, but fails fairly consistently for me in CI.


Discussion:
Skipped here: https://github.com/pantsbuild/pants/pull/6781
This seemed reliably fixed by b2ac3726085da09c7c7c3b0286c8ee21eab10f7b, I guess maybe 8cfbdafb7da9afe1fdbbe1cd87b7c2f9c5f42d11 didn't fix it as well? I'm going to try reverting 8cfbdafb7da9afe1fdbbe1cd87b7c2f9c5f42d11 and see if things get stable - if we can hold off on the skip, that would be appreciated...
Too late... But in any case I would rather have the skip there until we're more sure that this has been fixed.
Mmm... I have a hypothesis about this one. Will take a quick swing.

Resolving patch:
diff --git a/src/python/pants/engine/console.py b/src/python/pants/engine/console.py
--- a/src/python/pants/engine/console.py
+++ b/src/python/pants/engine/console.py
@@ -8,7 +8,6 @@
 
 
 class Console(object):
-
   @property
   def stdout(self):
     return sys.stdout
@@ -28,3 +27,7 @@ def print_stdout(self, payload):
 
   def print_stderr(self, payload):
     print(payload, file=self.stderr)
+
+  def flush(self):
+    self.stdout.flush()
+    self.stderr.flush()
diff --git a/src/python/pants/init/engine_initializer.py b/src/python/pants/init/engine_initializer.py
--- a/src/python/pants/init/engine_initializer.py
+++ b/src/python/pants/init/engine_initializer.py
@@ -140,15 +140,15 @@ def _tuplify(v):
   return (v,)
 
 
-class LegacyGraphScheduler(datatype(['scheduler', 'symbol_table', 'goal_map'])):
+class LegacyGraphScheduler(datatype(['scheduler', 'symbol_table', 'console', 'goal_map'])):
   """A thin wrapper around a Scheduler configured with @rules for a symbol table."""
 
   def new_session(self):
     session = self.scheduler.new_session()
-    return LegacyGraphSession(session, self.symbol_table, self.goal_map)
+    return LegacyGraphSession(session, self.symbol_table, self.console, self.goal_map)
 
 
-class LegacyGraphSession(datatype(['scheduler_session', 'symbol_table', 'goal_map'])):
+class LegacyGraphSession(datatype(['scheduler_session', 'symbol_table', 'console', 'goal_map'])):
   """A thin wrapper around a SchedulerSession configured with @rules for a symbol table."""
 
   class InvalidGoals(Exception):
@@ -206,9 +206,12 @@ def run_console_rules(self, goals, target_roots, v2_ui):
     # Console rule can only have one subject.
     assert len(subjects) == 1
     for goal in goals:
-      goal_product = self.goal_map[goal]
-      logger.debug('requesting {} to satisfy execution of `{}` goal'.format(goal_product, goal))
-      self.scheduler_session.run_console_rule(goal_product, subjects[0], v2_ui)
+      try:
+        goal_product = self.goal_map[goal]
+        logger.debug('requesting {} to satisfy execution of `{}` goal'.format(goal_product, goal))
+        self.scheduler_session.run_console_rule(goal_product, subjects[0], v2_ui)
+      finally:
+        self.console.flush()
 
   def create_build_graph(self, target_roots, build_root=None):
     """Construct and return a `BuildGraph` given a set of input specs.
@@ -367,4 +370,4 @@ def setup_legacy_graph_extended(
       include_trace_on_error=include_trace_on_error,
     )
 
-    return LegacyGraphScheduler(scheduler, symbol_table, goal_map)
+    return LegacyGraphScheduler(scheduler, symbol_table, console, goal_map)


Test patch:
diff --git a/tests/python/pants_test/rules/test_test_integration.py b/tests/python/pants_test/rules/test_test_integration.py
--- a/tests/python/pants_test/rules/test_test_integration.py
+++ b/tests/python/pants_test/rules/test_test_integration.py
@@ -4,8 +4,6 @@
 
 from __future__ import absolute_import, division, print_function, unicode_literals
 
-import unittest
-
 from pants_test.pants_run_integration_test import PantsRunIntegrationTest
 
 
@@ -92,7 +90,6 @@ def test_fail():
 """,
     )
 
-  @unittest.skip('Flaky test: https://github.com/pantsbuild/pants/issues/6782')
   def test_mixed_python_tests(self):
     args = [
       '--no-v1',