def open_project(self) -> 'exposed.ExposedProject': """ Returns the Response object populated by the open project command """ project_path = self.make_project_path() res = environ.Response() commander.execute('open', '{} --forget'.format(project_path), res) res.thread.join() # Prevent threading race conditions check_count = 0 while res.success and not cd.project.internal_project: if check_count > 100: break check_count += 1 time.sleep(0.25) if res.failed or not cd.project.internal_project: self.fail( 'Unable to open project at path "{}"'.format(project_path)) os.chdir(cd.project.internal_project.source_directory) return cd.project
def open_project(tester: scaffolds.ResultsTest, path: str) -> 'environ.Response': """...""" r = environ.Response() commander.execute('open', '{} --forget'.format(path), r) r.thread.join() return r
def execute(exec_async: bool = False): """ :param exec_async: Whether or not to allow asynchronous command execution that returns before the command is complete with a run_uid that can be used to track the continued execution of the command until completion. """ r = Response() r.update(server=server_runner.get_server_data()) cmd, args = parse_command_args(r) if r.failed: return flask.jsonify(r.serialize()) try: commander.execute(cmd, args, r) if not r.thread: return flask.jsonify(r.serialize()) if not exec_async: r.thread.join() server_runner.active_execution_responses[r.thread.uid] = r # Watch the thread for a bit to see if the command finishes in # that time. If it does the command result will be returned directly # to the caller. Otherwise, a waiting command will be issued count = 0 while count < 5: count += 1 r.thread.join(0.25) if not r.thread.is_alive(): break if r.thread.is_alive(): return flask.jsonify(Response().update( run_log=r.get_thread_log(), run_status='running', run_uid=r.thread.uid, step_changes=server_runner.get_running_step_changes(True), server=server_runner.get_server_data()).serialize()) del server_runner.active_execution_responses[r.thread.uid] r.update(run_log=r.get_thread_log(), run_status='complete', run_multiple_updates=False, run_uid=r.thread.uid) except Exception as err: r.fail(code='KERNEL_EXECUTION_FAILURE', message='Unable to execute command', cmd=cmd, args=args, error=err) return flask.jsonify(r.serialize())
def test_run_bokeh(self): """ """ support.open_project(self, '@examples:bokeh') r = environ.Response() commander.execute('run', '', r) r.thread.join() self.assertFalse(r.failed)
def test_run_bokeh(self): """ """ support.open_project(self, '@examples:bokeh') r = environ.Response() commander.execute('run', '', r) r.thread.join() self.assertFalse(r.failed)
def test_run_step_example(self): """ """ support.open_project(self, '@examples:hello_cauldron') r = environ.Response() commander.execute('run', '.', r) r.thread.join() self.assertFalse(r.failed)
def test_run_step_example(self): """ """ support.open_project(self, '@examples:hello_cauldron') r = environ.Response() commander.execute('run', '.', r) r.thread.join() self.assertFalse(r.failed)
def test_run_example(self): """ """ support.open_project(self, '@examples:hello_text') r = environ.Response() commander.execute('run', '', r) r.thread.join() self.assertFalse(r.failed) support.run_command('close')
def test_run_in_parts(self): """ """ support.open_project(self, '@examples:hello_cauldron') r = environ.Response() commander.execute('run', 'S01-create-data.py', r) r.thread.join() self.assertFalse(r.failed) r = environ.Response() commander.execute('run', 'S02-plot-data.py', r) r.thread.join() self.assertFalse(r.failed)
def test_run_in_parts(self): """ """ support.open_project(self, '@examples:hello_cauldron') r = environ.Response() commander.execute('run', 'S01-create-data.py', r) r.thread.join() self.assertFalse(r.failed) r = environ.Response() commander.execute('run', 'S02-plot-data.py', r) r.thread.join() self.assertFalse(r.failed)
def open_project(project_path: str) -> 'exposed.ExposedProject': """ Opens the project located at the specified path and returns the public (exposed) project after it has been loaded. If the project cannot be opened a `RuntimeError` will be raised instead. :param project_path: The path to the Cauldron project to open. It should be either a directory that contains a `cauldron.json` file or a file path to the `cauldron.json` file for the project to load. """ res = commander.execute( name='open', raw_args='{} --forget'.format(project_path), response=environ.Response() ) res.thread.join() # Prevent threading race conditions project = ( cd.project.get_internal_project() if res.success else None ) if res.failed or not project: raise RuntimeError( 'Unable to open project at path "{}"'.format(project_path) ) os.chdir(project.source_directory) return cd.project
def run_step(self, step_name: str, allow_failure: bool = False) -> StepTestRunResult: """ Runs the specified step by name its complete filename including extension :param step_name: The full filename of the step to be run including its extension. :param allow_failure: Whether or not to allow a failed result to be returned. If False, a failed attempt to run a step will cause the current test to fail immediately before returning a value from this function call. Override this with a True value to have the step failure data passed back for inspection. :return: A StepTestRunResult instance containing information about the execution of the step. """ project = cd.project.internal_project if not project: self.fail('No project was open. Unable to run step "{}"'.format( step_name)) step = project.get_step(step_name) if not step: self.fail('No step named "{}" was found'.format(step_name)) response = commander.execute('run', '"{}" --force'.format(step_name)) response.thread.join() if not allow_failure and response.failed: self.fail('Failed to run step "{}"'.format(step_name)) return StepTestRunResult(step, response)
def test_slow_printing(self): """Should not repeat print statements during slow running steps""" response = support.create_project(self, 'duluth') self.assertFalse( response.failed, Message('should have created project', response=response) ) code = '\n'.join([ 'import time', 'for letter in "BCFHMNOPRSTUVWX":', ' print("{}AT".format(letter))', ' time.sleep(0.5)' ]) support.add_step(self, contents=code) response = commander.execute('run', '-f') response.thread.join(2) step = cauldron.project.get_internal_project().steps[0] dom = step.dumps() self.assertEqual(dom.count('BAT'), 1, 'first check failed') response.thread.join(1) dom = step.dumps() self.assertEqual(dom.count('BAT'), 1, 'second check failed') response.thread.join() dom = step.dumps() self.assertEqual(dom.count('BAT'), 1, 'third check failed') self.assertLess(dom.count('SAT'), 2, 'fourth check failed')
def run_remote_command(command: str, app=None, remote_connection: 'environ.RemoteConnection' = None, mock_send_request=None) -> 'environ.Response': """ """ name, args = parse.split_line(command) if not remote_connection: remote_connection = environ.RemoteConnection( url='fake-run-remote.command', active=True) app = app if app else server.create_test_app() def default_mock_send_request(endpoint: str, data: dict = None, method: str = None, **kwargs): http_method = method.lower() if method else None func = server.post if data or http_method == 'post' else server.get result = func(app=app, endpoint=endpoint, data=data) return result.response side_effect = (mock_send_request if mock_send_request else default_mock_send_request) with patch('cauldron.cli.sync.comm.send_request', side_effect=side_effect): response = commander.execute(name=name, raw_args=args, remote_connection=remote_connection) response.thread.join() return response
def default(self, line: str): """ :param line: :return: """ line = line.strip() if len(line) < 1: return self.history.append(line) name, raw_args = parse.split_line(line) if name == 'help': return commander.show_help().ended result = commander.execute(name, raw_args) result = (result.response if hasattr(result, 'response') else environ.Response(failed=result)) if result.thread: result.thread.join() p = cauldron.project if not p or not p.internal_project or not p.internal_project.id: name = '' else: name = cauldron.project.internal_project.id[:20] self.prompt = '<{}>: '.format(name) self.last_response = result return result.ended
def test_execute_invalid(self): """ :return: """ result = commander.execute('fake-module', '') self.assertTrue(result.failed)
def tearDown(self): super(ResultsTest, self).tearDown() # Close any open project so that it doesn't persist to the next test if cauldron.project.internal_project is not None: close.execute(cli.make_command_context('close')) environ.configs.remove('results_directory', include_persists=False) environ.systems.remove(self.results_directory) self.results_directory = None for key, path in self.temp_directories.items(): environ.systems.remove(path) if cauldron.environ.remote_connection.active: commander.execute('disconnect', '')
def create_project( tester: scaffolds.ResultsTest, name: str, path: str = None, forget: bool = True, confirm: bool = True, remote_connection: cli.CommandContext = None, **kwargs ) -> 'environ.Response': """ :param tester: :param name: :param path: :param forget: :param confirm: :param remote_connection: :param kwargs: :return: """ version = ''.join(['{}'.format(s) for s in sys.version_info]) if path is None: path = tester.get_temp_path('project-{}-{}-'.format(name, version)) args = [name, path] for key, value in kwargs.items(): args.append('--{}="{}"'.format(key, value)) if forget: args.append('--forget') args = ' '.join([a for a in args if a and len(a) > 0]) r = commander.execute('create', args, remote_connection=remote_connection) if r.thread: r.thread.join() # Prevent threading race conditions check_count = 0 while confirm and r.success and not cauldron.project.internal_project: if check_count > 100: break check_count += 1 time.sleep(0.25) if confirm: tester.assertFalse(r.failed, Message( 'support.create_project', ['project should have been created'], response=r )) tester.assertIsNotNone(cauldron.project.internal_project) return r
def tearDown(self): super(StepTestCase, self).tearDown() # Close any open project so that it doesn't persist to the next test closed = commander.execute('close', '') closed.thread.join() environ.configs.remove('results_directory', include_persists=False) environ.systems.remove(self.results_directory) self.results_directory = None for key, path in self.temp_directories.items(): environ.systems.remove(path) environ.modes.remove(environ.modes.TESTING)
def tearDown(self): """ After a test is run this function is used to undo any side effects that were created by setting up and running the test. This includes removing the temporary directories that were created to store test information during test execution. """ super(StepTestCase, self).tearDown() # Close any open project so that it doesn't persist to the next test closed = commander.execute('close', '') closed.thread.join() environ.configs.remove('results_directory', include_persists=False) environ.systems.remove(self.results_directory) self.results_directory = None for key, path in self.temp_directories.items(): environ.systems.remove(path) environ.modes.remove(environ.modes.TESTING)
def tearDown(self): """ After a test is run this function is used to undo any side effects that were created by setting up and running the test. This includes removing the temporary directories that were created to store test information during test execution. """ super(StepTestCase, self).tearDown() # Close any open project so that it doesn't persist to the next test closed = commander.execute('close', '') closed.thread.join() environ.configs.remove('results_directory', include_persists=False) environ.systems.remove(self.results_directory) self.results_directory = None for key, path in self.temp_directories.items(): environ.systems.remove(path) environ.modes.remove(environ.modes.TESTING)
def run_step( step_name: str, allow_failure: bool = False ) -> StepTestRunResult: """ Runs the specified step by name its complete filename including extension :param step_name: The full filename of the step to be run including its extension. :param allow_failure: Whether or not to allow a failed result to be returned. If False, a failed attempt to run a step will cause the current test to fail immediately before returning a value from this function call. Override this with a True value to have the step failure data passed back for inspection. :return: A StepTestRunResult instance containing information about the execution of the step. """ project = cd.project.get_internal_project() if not project: raise AssertionError( 'No project was open. Unable to run step "{}"' .format(step_name) ) step = project.get_step(step_name) if not step: raise AssertionError('No step named "{}" was found'.format(step_name)) response = commander.execute('run', '"{}" --force'.format(step_name)) response.thread.join() if not allow_failure and response.failed: raise AssertionError('Failed to run step "{}"'.format(step_name)) return StepTestRunResult(step, response)
def tear_down(self): """ After a test is run this function is used to undo any side effects that were created by setting up and running the test. This includes removing the temporary directories that were created to store test information during test execution. """ # Close any open project so that it doesn't persist to the next test closed = commander.execute('close', '') closed.thread.join() environ.configs.remove('results_directory', include_persists=False) environ.systems.remove(self.results_directory) self.results_directory = None for path in self.temp_directories.values(): environ.systems.remove(path) paths_to_remove = [p for p in self._library_paths if p in sys.path] for path in paths_to_remove: sys.path.remove(path) environ.modes.remove(environ.modes.TESTING)
def default(self, line: str): """ :param line: :return: """ line = line.strip() if len(line) < 1: return self.history.append(line) name, raw_args = parse.split_line(line) if name == 'help': return commander.show_help().ended result = commander.execute(name, raw_args) result = ( result.response if hasattr(result, 'response') else environ.Response(failed=result) ) if result.thread: result.thread.join() p = cauldron.project if not p or not p.internal_project or not p.internal_project.id: name = '' else: name = cauldron.project.internal_project.id[:20] self.prompt = '<{}>: '.format(name) self.last_response = result return result.ended
def test_execute_invalid(self): """Should fail when executing an unknown module""" result = commander.execute('fake-module', '') self.assertTrue(result.failed)
def execute(asynchronous: bool = False): """ :param asynchronous: Whether or not to allow asynchronous command execution that returns before the command is complete with a run_uid that can be used to track the continued execution of the command until completion. """ r = Response() r.update(server=server_runner.get_server_data()) cmd, args = parse_command_args(r) if r.failed: return flask.jsonify(r.serialize()) try: commander.execute(cmd, args, r) if not r.thread: return flask.jsonify(r.serialize()) if not asynchronous: r.thread.join() server_runner.active_execution_responses[r.thread.uid] = r # Watch the thread for a bit to see if the command finishes in # that time. If it does the command result will be returned directly # to the caller. Otherwise, a waiting command will be issued count = 0 while count < 5: count += 1 r.thread.join(0.25) if not r.thread.is_alive(): break if r.thread.is_alive(): return flask.jsonify( Response() .update( run_log=r.get_thread_log(), run_status='running', run_uid=r.thread.uid, step_changes=server_runner.get_running_step_changes(True), server=server_runner.get_server_data() ) .serialize() ) del server_runner.active_execution_responses[r.thread.uid] r.update( run_log=r.get_thread_log(), run_status='complete', run_multiple_updates=False, run_uid=r.thread.uid ) except Exception as err: r.fail( code='KERNEL_EXECUTION_FAILURE', message='Unable to execute command', cmd=cmd, args=args, error=err ) return flask.jsonify(r.serialize())
def test_execute_help(self): """Should show help and return""" response = commander.execute('run', '--help') self.assertTrue(response.success)
""" :param async: Whether or not to allow asynchronous command execution that returns before the command is complete with a run_uid that can be used to track the continued execution of the command until completion. """ r = Response() r.update(server=server_runner.get_server_data()) cmd, args = parse_command_args(r) if r.failed: return flask.jsonify(r.serialize()) try: commander.execute(cmd, args, r) if not r.thread: return flask.jsonify(r.serialize()) if not async: r.thread.join() server_runner.active_execution_responses[r.thread.uid] = r # Watch the thread for a bit to see if the command finishes in # that time. If it does the command result will be returned directly # to the caller. Otherwise, a waiting command will be issued count = 0 while count < 5: count += 1 r.thread.join(0.25)