Skip to content

Commit

Permalink
Test.
Browse files Browse the repository at this point in the history
  • Loading branch information
kwlzn committed Nov 3, 2017
1 parent 503cdba commit 148e236
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 123 deletions.
2 changes: 1 addition & 1 deletion tests/python/pants_test/pantsd/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ python_tests(
'tests/python/pants_test/testutils:process_test_util'
],
tags = {'integration'},
timeout = 300
timeout = 600
)

python_tests(
Expand Down
229 changes: 107 additions & 122 deletions tests/python/pants_test/pantsd/test_pantsd_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
from __future__ import (absolute_import, division, generators, nested_scopes, print_function,
unicode_literals, with_statement)

import functools
import itertools
import os
import signal
import time
Expand All @@ -19,15 +21,30 @@ class PantsDaemonMonitor(ProcessManager):
def __init__(self, metadata_base_dir=None):
super(PantsDaemonMonitor, self).__init__(name='pantsd', metadata_base_dir=metadata_base_dir)

def await_pantsd(self, timeout=10):
def _log(self):
print('PantsDaemonMonitor: pid is {} is_alive={}'.format(self._pid, self.is_alive()))

def await_pantsd(self, timeout=3):
self._process = None
self._pid = self.await_pid(timeout)
self.assert_running()
return self._pid

def assert_running(self):
self._log()
assert self._pid is not None and self.is_alive(), 'pantsd should be running!'
return self._pid

def assert_stopped(self):
self._log()
assert self._pid is not None and self.is_dead(), 'pantsd should be stopped!'
return self._pid


def banner(s):
print('=' * 63)
print('- {} {}'.format(s, '-' * (60 - len(s))))
print('=' * 63)


def read_pantsd_log(workdir):
Expand All @@ -43,6 +60,7 @@ def pantsd_test_context(self, log_level='info'):
with self.temporary_workdir() as workdir_base:
pid_dir = os.path.join(workdir_base, '.pids')
workdir = os.path.join(workdir_base, '.workdir.pants.d')
print('\npantsd log is {}/pantsd/pantsd.log'.format(workdir))
pantsd_config = {
'GLOBAL': {
'enable_pantsd': True,
Expand All @@ -54,79 +72,56 @@ def pantsd_test_context(self, log_level='info'):
}
}
checker = PantsDaemonMonitor(pid_dir)
yield workdir, pantsd_config, checker

def test_pantsd_compile(self):
with self.pantsd_test_context('debug') as (workdir, pantsd_config, checker):
# Explicitly kill any running pantsd instances for the current buildroot.
self.assert_success(self.run_pants_with_workdir(['kill-pantsd'], workdir, pantsd_config))
self.assert_success_runner(workdir, pantsd_config, ['kill-pantsd'])
try:
# Start pantsd implicitly via a throwaway invocation.
self.assert_success(self.run_pants_with_workdir(['help'], workdir, pantsd_config))
checker.await_pantsd()

# This tests a deeper pantsd-based run by actually invoking a full compile.
self.assert_success(
self.run_pants_with_workdir(
['compile', 'examples/src/scala/org/pantsbuild/example/hello/welcome'],
workdir,
pantsd_config)
)
checker.assert_running()
yield workdir, pantsd_config, checker
finally:
try:
for line in read_pantsd_log(workdir):
print(line)
finally:
# Explicitly kill pantsd (from a pantsd-launched runner).
self.assert_success(self.run_pants_with_workdir(['kill-pantsd'], workdir, pantsd_config))
checker.assert_stopped()
banner('BEGIN pantsd.log')
for line in read_pantsd_log(workdir):
print(line)
banner('END pantsd.log')
self.assert_success_runner(workdir, pantsd_config, ['kill-pantsd'])
checker.assert_stopped()

@contextmanager
def pantsd_successful_run_context(self, log_level='info'):
with self.pantsd_test_context(log_level) as (workdir, pantsd_config, checker):
yield (
functools.partial(
self.assert_success_runner,
workdir,
pantsd_config
),
checker,
workdir
)

def assert_success_runner(self, workdir, config, cmd):
print('running: ./pants {}'.format(' '.join(cmd)))
return self.assert_success(
self.run_pants_with_workdir(cmd, workdir, config)
)

def test_pantsd_compile(self):
with self.pantsd_successful_run_context('debug') as (pantsd_run, checker, workdir):
# This tests a deeper pantsd-based run by actually invoking a full compile.
pantsd_run(['compile', 'examples/src/scala/org/pantsbuild/example/hello/welcome'])
checker.await_pantsd()

def test_pantsd_run(self):
with self.pantsd_test_context('debug') as (workdir, pantsd_config, checker):
print('log: {}/pantsd/pantsd.log'.format(workdir))
# Explicitly kill any running pantsd instances for the current buildroot.
print('\nkill-pantsd')
self.assert_success(self.run_pants_with_workdir(['kill-pantsd'], workdir, pantsd_config))
try:
# Start pantsd implicitly via a throwaway invocation.
print('help')
self.assert_success(self.run_pants_with_workdir(['help'], workdir, pantsd_config))
checker.await_pantsd()

print('list 3rdparty:')
self.assert_success(self.run_pants_with_workdir(['list', '3rdparty:'],
workdir,
pantsd_config))
checker.assert_running()
with self.pantsd_successful_run_context('debug') as (pantsd_run, checker, workdir):
pantsd_run(['list', '3rdparty:'])
checker.await_pantsd()

print('list :')
self.assert_success(self.run_pants_with_workdir(['list', ':'],
workdir,
pantsd_config))
checker.assert_running()
pantsd_run(['list', ':'])
checker.assert_running()

print('list ::')
self.assert_success(self.run_pants_with_workdir(['list', '::'],
workdir,
pantsd_config))
checker.assert_running()
pantsd_run(['list', '::'])
checker.assert_running()

# And again using the cached BuildGraph.
print('list ::')
self.assert_success(self.run_pants_with_workdir(['list', '::'],
workdir,
pantsd_config))
checker.assert_running()
finally:
try:
for line in read_pantsd_log(workdir):
print(line)
finally:
# Explicitly kill pantsd (from a pantsd-launched runner).
print('kill-pantsd')
self.assert_success(self.run_pants_with_workdir(['kill-pantsd'], workdir, pantsd_config))
checker.assert_stopped()
# And again using the cached BuildGraph.
pantsd_run(['list', '::'])
checker.assert_running()

# Assert there were no warnings or errors thrown in the pantsd log.
for line in read_pantsd_log(workdir):
Expand All @@ -138,66 +133,56 @@ def test_pantsd_run(self):

def test_pantsd_broken_pipe(self):
with self.pantsd_test_context() as (workdir, pantsd_config, checker):
# Explicitly kill any running pantsd instances for the current buildroot.
self.assert_success(self.run_pants_with_workdir(['kill-pantsd'], workdir, pantsd_config))
try:
# Start pantsd implicitly via a throwaway invocation.
self.assert_success(self.run_pants_with_workdir(['help'], workdir, pantsd_config))
checker.await_pantsd()

run = self.run_pants_with_workdir('help | head -1', workdir, pantsd_config, shell=True)
self.assertNotIn('broken pipe', run.stderr_data.lower())
checker.assert_running()
finally:
# Explicitly kill pantsd (from a pantsd-launched runner).
self.assert_success(self.run_pants_with_workdir(['kill-pantsd'], workdir, pantsd_config))
checker.assert_stopped()
run = self.run_pants_with_workdir('help | head -1', workdir, pantsd_config, shell=True)
self.assertNotIn('broken pipe', run.stderr_data.lower())
checker.await_pantsd()

def test_pantsd_stacktrace_dump(self):
with self.pantsd_test_context() as (workdir, pantsd_config, checker):
print('log: {}/pantsd/pantsd.log'.format(workdir))
# Explicitly kill any running pantsd instances for the current buildroot.
self.assert_success(self.run_pants_with_workdir(['kill-pantsd'], workdir, pantsd_config))
try:
# Start pantsd implicitly via a throwaway invocation.
self.assert_success(self.run_pants_with_workdir(['help'], workdir, pantsd_config))
checker.await_pantsd()
with self.pantsd_successful_run_context() as (pantsd_run, checker, workdir):
pantsd_run(['help'])
checker.await_pantsd()

os.kill(checker.pid, signal.SIGUSR2)
os.kill(checker.pid, signal.SIGUSR2)

# Wait for log flush.
time.sleep(2)
# Wait for log flush.
time.sleep(2)

self.assertIn('Current thread 0x', '\n'.join(read_pantsd_log(workdir)))
finally:
# Explicitly kill pantsd (from a pantsd-launched runner).
self.assert_success(self.run_pants_with_workdir(['kill-pantsd'], workdir, pantsd_config))
checker.assert_stopped()
self.assertIn('Current thread 0x', '\n'.join(read_pantsd_log(workdir)))

def test_pantsd_runner_doesnt_die_after_failed_run(self):
def test_pantsd_pantsd_runner_doesnt_die_after_failed_run(self):
with self.pantsd_test_context() as (workdir, pantsd_config, checker):
self.assert_success(self.run_pants_with_workdir(['kill-pantsd'], workdir, pantsd_config))
try:
# Start pantsd implicitly via a throwaway invocation.
self.assert_success(self.run_pants_with_workdir(['help'], workdir, pantsd_config))
checker.await_pantsd()

# Run target that throws an exception in pants.
self.assert_failure(
self.run_pants_with_workdir(
['bundle', 'testprojects/src/java/org/pantsbuild/testproject/bundle:missing-files'],
workdir,
pantsd_config)
)
checker.assert_running()

# Check for no stray pantsd-runner prcesses.
self.assertFalse(check_process_exists_by_command('pantsd-runner'))

# Assert pantsd is in a good functional state.
self.assert_success(self.run_pants_with_workdir(['help'], workdir, pantsd_config))
# Run target that throws an exception in pants.
self.assert_failure(
self.run_pants_with_workdir(
['bundle', 'testprojects/src/java/org/pantsbuild/testproject/bundle:missing-files'],
workdir,
pantsd_config)
)
checker.await_pantsd()

# Check for no stray pantsd-runner prcesses.
self.assertFalse(check_process_exists_by_command('pantsd-runner'))

# Assert pantsd is in a good functional state.
self.assert_success(self.run_pants_with_workdir(['help'], workdir, pantsd_config))
checker.assert_running()

def test_pantsd_lifecycle_invalidation(self):
"""Runs pants commands with pantsd enabled, in a loop, alternating between options that
should invalidate pantsd and incur a restart and then asserts for pid consistency.
"""
with self.pantsd_successful_run_context() as (pantsd_run, checker, workdir):
variants = (
['-ldebug', 'help'],
['-linfo', 'help']
)
last_pid = None
for cmd in itertools.chain(*itertools.repeat(variants, 3)):
pantsd_run(cmd)
next_pid = checker.await_pantsd()
if last_pid:
self.assertNotEqual(last_pid, next_pid)
last_pid = next_pid

pantsd_run(cmd)
checker.assert_running()
finally:
# Explicitly kill pantsd (from a pantsd-launched runner).
self.assert_success(self.run_pants_with_workdir(['kill-pantsd'], workdir, pantsd_config))
checker.assert_stopped()

0 comments on commit 148e236

Please sign in to comment.