def test_foreground_background_output( test_fn, capfd, termios_on_or_off, tmpdir): """Tests hitting 'v' toggles output, and that force_echo works.""" if (sys.version_info >= (3, 8) and sys.platform == 'darwin' and termios_on_or_off == no_termios): return shell = PseudoShell(test_fn, synchronized_logger) log_path = str(tmpdir.join("log.txt")) # Locks for synchronizing with minion write_lock = multiprocessing.Lock() # must be held by minion to write v_lock = multiprocessing.Lock() # held while controller is in v mode with termios_on_or_off(): shell.start( write_lock=write_lock, v_lock=v_lock, debug=True, log_path=log_path ) exitcode = shell.join() out, err = capfd.readouterr() print(err) # will be shown if something goes wrong print(out) # processes completed successfully assert exitcode == 0 # split output into lines output = out.strip().split("\n") # also get lines of log file assert os.path.exists(log_path) with open(log_path) as log: log = log.read().strip().split("\n") # Controller and minion process coordinate with locks such that the minion # writes "off" when echo is off, and "on" when echo is on. The # output should contain mostly "on" lines, but may contain an "off" # or two. This is because the controller toggles echo by sending "v" on # stdin to the minion, but this is not synchronized with our locks. # It's good enough for a test, though. We allow at most 4 "off"'s in # the output to account for the race. # # Originally we only allowed 2, but GitHub's macOS runners seem to be # very slow, and frequently we get 3 "off"'s. Increased limit to 4 to # account for this. Real errors should still be caught with this limit. assert ( ['forced output', 'on'] == uniq(output) or output.count("off") <= 4 # if controller_fd is a bit slow ) # log should be off for a while, then on, then off assert ( ['forced output', 'off', 'on', 'off'] == uniq(log) and log.count("off") > 2 # ensure some "off" lines were omitted )
def test_foreground_background_output( test_fn, capfd, termios_on_or_off, tmpdir): """Tests hitting 'v' toggles output, and that force_echo works.""" if (sys.version_info >= (3, 8) and sys.platform == 'darwin' and termios_on_or_off == no_termios): return shell = PseudoShell(test_fn, synchronized_logger) log_path = str(tmpdir.join("log.txt")) # Locks for synchronizing with minion write_lock = multiprocessing.Lock() # must be held by minion to write v_lock = multiprocessing.Lock() # held while controller is in v mode with termios_on_or_off(): shell.start( write_lock=write_lock, v_lock=v_lock, debug=True, log_path=log_path ) exitcode = shell.join() out, err = capfd.readouterr() print(err) # will be shown if something goes wrong print(out) # processes completed successfully assert exitcode == 0 # split output into lines output = out.strip().split("\n") # also get lines of log file assert os.path.exists(log_path) with open(log_path) as log: log = log.read().strip().split("\n") # Controller and minion process coordinate with locks such that the # minion writes "off" when echo is off, and "on" when echo is on. The # output should contain mostly "on" lines, but may contain "off" # lines if the controller is slow. The important thing to observe # here is that we started seeing 'on' in the end. assert ( ['forced output', 'on'] == uniq(output) or ['forced output', 'off', 'on'] == uniq(output) ) # log should be off for a while, then on, then off assert ( ['forced output', 'off', 'on', 'off'] == uniq(log) and log.count("off") > 2 # ensure some "off" lines were omitted )
def test_foreground_background_output(test_fn, capfd, termios_on_or_off, tmpdir): """Tests hitting 'v' toggles output, and that force_echo works.""" shell = PseudoShell(test_fn, synchronized_logger) log_path = str(tmpdir.join("log.txt")) # Locks for synchronizing with child write_lock = multiprocessing.Lock() # must be held by child to write v_lock = multiprocessing.Lock() # held while master is in v mode with termios_on_or_off(): shell.start(write_lock=write_lock, v_lock=v_lock, debug=True, log_path=log_path) exitcode = shell.join() out, err = capfd.readouterr() print(err) # will be shown if something goes wrong print(out) # processes completed successfully assert exitcode == 0 # split output into lines output = out.strip().split("\n") # also get lines of log file assert os.path.exists(log_path) with open(log_path) as log: log = log.read().strip().split("\n") # Master and child process coordinate with locks such that the child # writes "off" when echo is off, and "on" when echo is on. The # output should contain mostly "on" lines, but may contain an "off" # or two. This is because the master toggles echo by sending "v" on # stdin to the child, but this is not synchronized with our locks. # It's good enough for a test, though. We allow at most 2 "off"'s in # the output to account for the race. assert (['forced output', 'on'] == uniq(output) or output.count("off") <= 2 # if master_fd is a bit slow ) # log should be off for a while, then on, then off assert (['forced output', 'off', 'on', 'off'] == uniq(log) and log.count("off") > 2 # ensure some "off" lines were omitted )