def it_logs_continuously_when_run_interactively(self, in_example_dir): check_call(('pgctl', 'start')) # this pty simulates running in a terminal read, write = os.openpty() pty.normalize_newlines(read) p = Popen(('pgctl', 'log'), stdout=write, stderr=write) os.close(write) import fcntl fl = fcntl.fcntl(read, fcntl.F_GETFL) fcntl.fcntl(read, fcntl.F_SETFL, fl | os.O_NONBLOCK) assert p.poll() is None # it's still running # needs to loop for several seconds because the default event loop # in tail-f is one second. # TODO: buf is a list, use wait_for() to append to it limit = 3.0 wait = .1 buf = b'' while True: try: block = os.read(read, 1024) print('BLOCK:', block) except OSError as error: print('ERROR:', error) if error.errno == 11: # other end didn't write yet if limit > 0: import time time.sleep(wait) limit -= wait continue else: break else: raise buf += block from testfixtures import StringComparison as S buf = norm.pgctl(buf.decode('UTF-8')) print('NORMED:') print(buf) assert buf == S('''(?s)\ ==> playground/ohhi/logs/current <== {TIMESTAMP} [oe].* ==> playground/sweet/logs/current <== {TIMESTAMP} sweet {TIMESTAMP} sweet_error ==> playground/ohhi/logs/current <== .*{TIMESTAMP} .*$''') assert p.poll() is None # it's still running p.terminate() assert p.wait() == -15
def it_logs_continuously_when_run_interactively(self, in_example_dir): check_call(('pgctl', 'start')) # this pty simulates running in a terminal read, write = os.openpty() pty.normalize_newlines(read) p = Popen(('pgctl', 'log'), stdout=write, stderr=write) os.close(write) import fcntl fl = fcntl.fcntl(read, fcntl.F_GETFL) fcntl.fcntl(read, fcntl.F_SETFL, fl | os.O_NONBLOCK) assert p.poll() is None # it's still running # needs to loop for several seconds because the default event loop # in tail-f is one second. # TODO: buf is a list, use wait_for() to append to it limit = 3.0 wait = .1 buf = b'' while True: try: block = os.read(read, 1024) print('BLOCK:', block) except OSError as error: print('ERROR:', error) if error.errno == 11: # other end didn't write yet if limit > 0: import time time.sleep(wait) limit -= wait continue else: break else: raise buf += block from testfixtures import StringComparison as S buf = norm.pgctl(buf.decode('UTF-8')) print('NORMED:') print(buf) assert buf == S('''(?s)\ ==> playground/ohhi/log <== {TIMESTAMP} [oe].* ==> playground/sweet/log <== {TIMESTAMP} sweet {TIMESTAMP} sweet_error ==> playground/ohhi/log <== .*{TIMESTAMP} .*$''') assert p.poll() is None # it's still running p.terminate() assert p.wait() == -15
def it_kills_processes_holding_the_lock(self, tmpdir): lockfile = tmpdir.ensure('lock') lock = lockfile.open() process = Popen(('sleep', 'infinity')) lock.close() # assert `process` has `lock` assert list(fuser(lockfile.strpath)) == [process.pid] with mock.patch('sys.stderr', new_callable=StringIO.StringIO) as mock_stderr: terminate_runaway_processes(lockfile.strpath) assert 'WARNING: Killing these runaway ' in mock_stderr.getvalue() wait_for(lambda: process.poll() == -9)
def it_stays_locked_for_the_lifetime_of_subprocesses(self, tmpfile): from pgctl.subprocess import Popen with flock(tmpfile): p = Popen(('sleep', '99999')) assert p.poll() is None assert_locked(tmpfile) assert_locked(tmpfile) p.terminate() assert p.wait() == -15 with flock(tmpfile): print('oh hi there!')