def _connect_and_execute(self, port): # Merge the nailgun TTY capability environment variables with the passed environment dict. ng_env = NailgunProtocol.isatty_to_env(self._stdin, self._stdout, self._stderr) modified_env = combined_dict(self._env, ng_env) modified_env['PANTSD_RUNTRACKER_CLIENT_START_TIME'] = str( self._start_time) assert isinstance(port, int), 'port {} is not an integer!'.format(port) # Instantiate a NailgunClient. client = NailgunClient(port=port, ins=self._stdin, out=self._stdout, err=self._stderr, exit_on_broken_pipe=True, expects_pid=True) with self._trapped_signals(client), STTYSettings.preserved(): # Execute the command on the pailgun. result = client.execute(self.PANTS_COMMAND, *self._args, **modified_env) # Exit. self._exiter.exit(result)
def _connect_and_execute(self, pantsd_handle): port = pantsd_handle.port # Merge the nailgun TTY capability environment variables with the passed environment dict. ng_env = NailgunProtocol.isatty_to_env(self._stdin, self._stdout, self._stderr) modified_env = combined_dict(self._env, ng_env) modified_env['PANTSD_RUNTRACKER_CLIENT_START_TIME'] = str( self._start_time) modified_env['PANTSD_REQUEST_TIMEOUT_LIMIT'] = str( self._bootstrap_options.for_global_scope( ).pantsd_timeout_when_multiple_invocations) assert isinstance(port, int), \ 'port {} is not an integer! It has type {}.'.format(port, type(port)) # Instantiate a NailgunClient. client = NailgunClient( port=port, ins=self._stdin, out=self._stdout, err=self._stderr, exit_on_broken_pipe=True, metadata_base_dir=pantsd_handle.metadata_base_dir) with self._trapped_signals(client), STTYSettings.preserved(): # Execute the command on the pailgun. result = client.execute(self.PANTS_COMMAND, *self._args, **modified_env) # Exit. self._exiter.exit(result)
def assert_success_runner(self, workdir, config, cmd, extra_config={}): combined_config = combined_dict(config, extra_config) print( bold( cyan('\nrunning: ./pants {} (config={})'.format( ' '.join(cmd), combined_config)))) run_count = self._run_count(workdir) start_time = time.time() run = self.run_pants_with_workdir( cmd, workdir, combined_config, # TODO: With this uncommented, `test_pantsd_run` fails. # tee_output=True ) elapsed = time.time() - start_time print(bold(cyan('\ncompleted in {} seconds'.format(elapsed)))) runs_created = self._run_count(workdir) - run_count self.assertEquals( runs_created, 1, 'Expected one RunTracker run to be created per pantsd run: was {}'. format(runs_created)) self.assert_success(run) return run
def pantsd_test_context(self, log_level='info', extra_config=None): with no_lingering_process_by_command('pantsd-runner'): 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': combined_dict({ 'enable_pantsd': True, # The absolute paths in CI can exceed the UNIX socket path limitation # (>104-108 characters), so we override that here with a shorter path. 'watchman_socket_path': '/tmp/watchman.{}.sock'.format(os.getpid()), 'level': log_level, 'pants_subprocessdir': pid_dir }, extra_config or {}) } checker = PantsDaemonMonitor(pid_dir) self.assert_success_runner(workdir, pantsd_config, ['kill-pantsd']) try: yield workdir, pantsd_config, checker finally: 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()
def post_fork_child(self): """Post-fork() child callback for ProcessManager.daemon_spawn().""" entry_point = '{}:launch'.format(__name__) exec_env = combined_dict(os.environ, dict(PANTS_ENTRYPOINT=entry_point)) # Pass all of sys.argv so that we can proxy arg flags e.g. `-ldebug`. cmd = [sys.executable] + sys.argv self._logger.debug('cmd is: PANTS_ENTRYPOINT={} {}'.format(entry_point, ' '.join(cmd))) # TODO: Improve error handling on launch failures. os.spawnve(os.P_NOWAIT, sys.executable, cmd, env=exec_env)
def test_combined_dict(self): self.assertEqual( combined_dict( {'a': 1, 'b': 1, 'c': 1}, {'b': 2, 'c': 2}, {'c': 3}, ), {'a': 1, 'b': 2, 'c': 3} )
def _connect_and_execute(self, port): # Merge the nailgun TTY capability environment variables with the passed environment dict. ng_env = NailgunProtocol.isatty_to_env(self._stdin, self._stdout, self._stderr) modified_env = combined_dict(self._env, ng_env) assert isinstance(port, int), 'port {} is not an integer!'.format(port) # Instantiate a NailgunClient. client = NailgunClient(port=port, ins=self._stdin, out=self._stdout, err=self._stderr, exit_on_broken_pipe=True) with self._trapped_control_c(client): # Execute the command on the pailgun. result = client.execute(self.PANTS_COMMAND, *self._args, **modified_env) # Exit. self._exiter.exit(result)
def post_fork_child(self): """Post-fork() child callback for ProcessManager.daemon_spawn().""" spawn_control_env = dict( PANTS_ENTRYPOINT=f'{__name__}:launch', # The daemon should run under the same sys.path as us; so we ensure # this. NB: It will scrub PYTHONPATH once started to avoid infecting # its own unrelated subprocesses. PYTHONPATH=os.pathsep.join(sys.path)) exec_env = combined_dict(os.environ, spawn_control_env) # Pass all of sys.argv so that we can proxy arg flags e.g. `-ldebug`. cmd = [sys.executable] + sys.argv spawn_control_env_vars = ' '.join( f'{k}={v}' for k, v in spawn_control_env.items()) cmd_line = ' '.join(cmd) self._logger.debug(f'cmd is: {spawn_control_env_vars} {cmd_line}') # TODO: Improve error handling on launch failures. os.spawnve(os.P_NOWAIT, sys.executable, cmd, env=exec_env)
def _connect_and_execute(self, port): # Merge the nailgun TTY capability environment variables with the passed environment dict. ng_env = NailgunProtocol.isatty_to_env(self._stdin, self._stdout, self._stderr) modified_env = combined_dict(self._env, ng_env) assert isinstance(port, int), 'port {} is not an integer!'.format(port) # Instantiate a NailgunClient. client = NailgunClient(port=port, ins=self._stdin, out=self._stdout, err=self._stderr, exit_on_broken_pipe=True) with self._trapped_signals(client), STTYSettings.preserved(): # Execute the command on the pailgun. result = client.execute(self.PANTS_COMMAND, *self._args, **modified_env) # Exit. self._exiter.exit(result)
def assert_success_runner(self, workdir, config, cmd, extra_config={}): combined_config = combined_dict(config, extra_config) print(bold(cyan('\nrunning: ./pants {} (config={})' .format(' '.join(cmd), combined_config)))) run_count = self._run_count(workdir) start_time = time.time() run = self.run_pants_with_workdir( cmd, workdir, combined_config, # TODO: With this uncommented, `test_pantsd_run` fails. # tee_output=True ) elapsed = time.time() - start_time print(bold(cyan('\ncompleted in {} seconds'.format(elapsed)))) runs_created = self._run_count(workdir) - run_count self.assertEquals( runs_created, 1, 'Expected one RunTracker run to be created per pantsd run: was {}'.format(runs_created) ) self.assert_success(run) return run
def assert_success_runner(self, workdir, config, cmd, extra_config={}): print('running: ./pants {} (extra_config={})'.format( ' '.join(cmd), extra_config)) return self.assert_success( self.run_pants_with_workdir(cmd, workdir, combined_dict(config, extra_config)))