示例#1
0
    def test_single_step(self):
        """ should run single step only """

        support.create_project(self, 'white-bear-lake')
        support.add_step(self)
        support.add_step(self)
        support.add_step(self)

        project = cauldron.project.get_internal_project()

        r = run.execute(context=cli.make_command_context(name=run.NAME),
                        single_step=True)

        self.assertFalse(r.failed)
        self.assertFalse(project.steps[0].is_dirty())
        self.assertTrue(project.steps[1].is_dirty())
        self.assertTrue(project.steps[2].is_dirty())

        r = run.execute(context=cli.make_command_context(name=run.NAME),
                        single_step=True)

        self.assertFalse(r.failed)
        self.assertFalse(project.steps[0].is_dirty())
        self.assertFalse(project.steps[1].is_dirty())
        self.assertTrue(project.steps[2].is_dirty())
示例#2
0
    def test_single_step(self):
        """ should run single step only """

        support.create_project(self, 'white-bear-lake')
        support.add_step(self)
        support.add_step(self)
        support.add_step(self)

        project = cauldron.project.get_internal_project()

        r = run.execute(
            context=cli.make_command_context(name=run.NAME),
            single_step=True
        )

        self.assertFalse(r.failed)
        self.assertFalse(project.steps[0].is_dirty())
        self.assertTrue(project.steps[1].is_dirty())
        self.assertTrue(project.steps[2].is_dirty())

        r = run.execute(
            context=cli.make_command_context(name=run.NAME),
            single_step=True
        )

        self.assertFalse(r.failed)
        self.assertFalse(project.steps[0].is_dirty())
        self.assertFalse(project.steps[1].is_dirty())
        self.assertTrue(project.steps[2].is_dirty())
示例#3
0
def run_project(project_directory: str,
                output_directory: str = None,
                log_path: str = None,
                shared_data: dict = None) -> environ.Response:
    """

    :param project_directory:
    :param output_directory:
    :param log_path:
    :param shared_data:
    :return:
    """

    log_path = initialize_logging_path(log_path)

    logger.add_output_path(log_path)

    def on_complete(message: str = None) -> environ.Response:
        environ.modes.remove(environ.modes.SINGLE_RUN)
        if message:
            logger.log(message)
        logger.remove_output_path(log_path)
        return response

    environ.modes.add(environ.modes.SINGLE_RUN)

    response = open_command.execute(context=cli.make_command_context(
        open_command.NAME),
                                    path=project_directory,
                                    results_path=output_directory)
    if response.failed:
        return on_complete('[ERROR]: Aborted trying to open project')

    project = cauldron.project.internal_project
    project.shared.put(**(shared_data if shared_data is not None else dict()))

    commander.preload()
    response = run_command.execute(
        context=cli.make_command_context(run_command.NAME))
    if response.failed:
        return on_complete('[ERROR]: Aborted trying to run project steps')

    response = close_command.execute(
        context=cli.make_command_context(close_command.NAME))
    if response.failed:
        return on_complete(
            '[ERROR]: Failed to close project cleanly after run')

    return on_complete('Project execution complete')
示例#4
0
def execute(name: str,
            raw_args: str,
            response: Response = None,
            remote_connection: 'environ.RemoteConnection' = None) -> Response:
    """

    :return:
    """

    if not response:
        response = Response(identifier=name)

    command_module = fetch().get(name)
    if command_module is None:
        return response.fail(
            code='NO_SUCH_COMMAND',
            message='There is no command "{}"'.format(name)).kernel(
                name=name).console("""
            "{name}" is not a recognized command. For a list of available
            commands enter help or ?.
            """.format(name=name)).response

    args = parse.args(command_module, raw_args)
    response.consume(args.response)

    if args.parser is None:
        # The parse failed and the execution should be aborted
        return response

    if args.args is None or args.args['show_help']:
        # Overrides standard execution and instead displays the help for the
        # command
        args.parser.print_help()
        return response

    del args.args['show_help']

    context = cli.make_command_context(name=name,
                                       args=args.args,
                                       raw_args=raw_args,
                                       parser=args.parser,
                                       response=response,
                                       remote_connection=remote_connection)
    response.update(remote_connection=remote_connection)

    if not context.remote_connection.active and name == 'run':
        preload()

    t = CauldronThread()
    t.command = get_command_from_module(
        command_module=command_module,
        remote_connection=context.remote_connection)
    t.context = context
    t.parser = args.parser
    t.kwargs = args.args
    t.response = response

    response.thread = t
    t.start()
    return response
示例#5
0
def execute_remote(context: cli.CommandContext, **kwargs) -> Response:
    """ """

    sync_response = sync_command.execute(cli.make_command_context(
        name=sync_command.NAME,
        remote_connection=context.remote_connection
    ))
    context.response.consume(sync_response)

    if sync_response.failed:
        return context.response

    environ.log('[STARTED]: Remote run execution', whitespace=1)

    thread = sync.send_remote_command(
        command=context.name,
        raw_args=context.raw_args,
        asynchronous=True,
        show_logs=True
    )

    thread.join()

    response = thread.responses[-1]
    return context.response.consume(response)
示例#6
0
    def test_run_no_project(self):
        """ should abort if no project is open """

        r = environ.Response()
        run.execute(
            context=cli.make_command_context(name=run.NAME, response=r))

        self.assert_has_error_code(r, 'NO_OPEN_PROJECT')
示例#7
0
    def test_no_args(self):
        """ should fail if no path argument """

        support.create_project(self, 'mercury')

        r = export.execute(context=cli.make_command_context(export.NAME),
                           path='')
        self.assertTrue(r.failed)
        self.assertEqual(r.errors[0].code, 'MISSING_PATH_ARG')
示例#8
0
    def test_run_no_project(self):
        """ should abort if no project is open """

        r = environ.Response()
        run.execute(context=cli.make_command_context(
            name=run.NAME,
            response=r
        ))

        self.assert_has_error_code(r, 'NO_OPEN_PROJECT')
示例#9
0
    def test_no_args(self):
        """ should fail if no path argument """

        support.create_project(self, 'mercury')

        r = export.execute(
            context=cli.make_command_context(export.NAME),
            path=''
        )
        self.assertTrue(r.failed)
        self.assertEqual(r.errors[0].code, 'MISSING_PATH_ARG')
示例#10
0
def sync_create_project():
    """ """

    r = Response()
    args = arguments.from_request()

    name = args.get('name')
    remote_source_directory = args.get('source_directory')
    optional_args = args.get('args', {})

    if None in [name, remote_source_directory]:
        return r.fail(
            code='INVALID_ARGS',
            message='Invalid arguments. Unable to create project'
        ).response.flask_serialize()

    container_folder = tempfile.mkdtemp(prefix='cd-remote-project-')
    os.makedirs(os.path.join(container_folder, '__cauldron_shared_libs'))
    os.makedirs(os.path.join(container_folder, '__cauldron_downloads'))

    r.consume(create_command.execute(
        cli.make_command_context('create'),
        project_name=name,
        directory=container_folder,
        forget=True,
        **optional_args
    ))
    if r.failed:
        return r.flask_serialize()

    sync_status.update({}, time=-1, project=None)

    project = cd.project.get_internal_project()
    project.remote_source_directory = remote_source_directory

    with open(project.source_path, 'r') as f:
        definition = json.load(f)

    sync_status.update({}, time=-1, project=project)

    return r.update(
        source_directory=project.source_directory,
        remote_source_directory=remote_source_directory,
        definition=definition,
        project=project.kernel_serialize()
    ).notify(
        kind='SUCCESS',
        code='PROJECT_CREATED',
        message='Project created'
    ).response.flask_serialize()
示例#11
0
    def test_no_such_step(self):
        """ should fail if unable to find a step """

        support.create_project(self, 'fairfield')
        support.add_step(self)
        support.add_step(self)

        project = cauldron.project.get_internal_project()
        step_names = [s.filename for s in project.steps]
        step_names.append('FAKE-STEP')

        r = run.execute(context=cli.make_command_context(name=run.NAME),
                        step=step_names)

        self.assert_has_error_code(r, 'MISSING_STEP')
示例#12
0
    def test_run_count(self):
        """ should run single step only """

        support.create_project(self, 'eagan')
        support.add_step(self)
        support.add_step(self)
        support.add_step(self)

        project = cauldron.project.get_internal_project()

        r = run.execute(context=cli.make_command_context(name=run.NAME),
                        step=['2'])

        self.assertFalse(r.failed)
        self.assertFalse(project.steps[0].is_dirty())
        self.assertFalse(project.steps[1].is_dirty())
示例#13
0
    def test_no_such_step(self):
        """ should fail if unable to find a step """

        support.create_project(self, 'fairfield')
        support.add_step(self)
        support.add_step(self)

        project = cauldron.project.get_internal_project()
        step_names = [s.filename for s in project.steps]
        step_names.append('FAKE-STEP')

        r = run.execute(
            context=cli.make_command_context(name=run.NAME),
            step=step_names
        )

        self.assert_has_error_code(r, 'MISSING_STEP')
示例#14
0
    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', '')
示例#15
0
def sync_create_project():
    """ """

    r = Response()
    args = arguments.from_request()

    name = args.get('name')
    remote_source_directory = args.get('source_directory')
    optional_args = args.get('args', {})

    if None in [name, remote_source_directory]:
        return r.fail(code='INVALID_ARGS',
                      message='Invalid arguments. Unable to create project'
                      ).response.flask_serialize()

    container_folder = tempfile.mkdtemp(prefix='cd-remote-project-')
    os.makedirs(os.path.join(container_folder, '__cauldron_shared_libs'))
    os.makedirs(os.path.join(container_folder, '__cauldron_downloads'))

    r.consume(
        create_command.execute(cli.make_command_context('create'),
                               project_name=name,
                               directory=container_folder,
                               forget=True,
                               **optional_args))
    if r.failed:
        return r.flask_serialize()

    sync_status.update({}, time=-1, project=None)

    project = cd.project.get_internal_project()
    project.remote_source_directory = remote_source_directory

    with open(project.source_path, 'r') as f:
        definition = json.load(f)

    sync_status.update({}, time=-1, project=project)

    return r.update(source_directory=project.source_directory,
                    remote_source_directory=remote_source_directory,
                    definition=definition,
                    project=project.kernel_serialize()).notify(
                        kind='SUCCESS',
                        code='PROJECT_CREATED',
                        message='Project created').response.flask_serialize()
示例#16
0
def execute_remote(
        context: cli.CommandContext,
        action: str = None,
        step_name: str = None,
        position: str = None,
        title: str = None,
        new_name: str = None,
        keep: bool = False,
) -> Response:

    status_response = sync.comm.send_request(
        endpoint='/sync-status',
        remote_connection=context.remote_connection
    )
    if status_response.failed:
        return context.response.consume(status_response)

    source_directory = status_response.data['remote_source_directory']
    if not project_opener.project_exists(context.response, source_directory):
        return context.response

    context.response.consume(execute(
        context=context,
        action=action,
        step_name=step_name,
        position=position,
        title=title,
        new_name=new_name,
        keep=keep,
        project=projects.Project(source_directory)
    ))
    if context.response.failed:
        return context.response

    sync_response = sync_command.do_synchronize(
        context=cli.make_command_context(
            name='sync',
            response=context.response,
            remote_connection=context.remote_connection
        ),
        source_directory=source_directory,
        newer_than=status_response.data.get('sync_time', 0)
    )

    return context.response.consume(sync_response)
示例#17
0
    def test_multiple_steps(self):
        """ should run multiple named steps """

        support.create_project(self, 'robinsdale')
        support.add_step(self)
        support.add_step(self)
        support.add_step(self)

        project = cauldron.project.get_internal_project()
        step_names = [s.filename for s in project.steps[:-1]]

        r = run.execute(context=cli.make_command_context(name=run.NAME),
                        step=step_names)

        self.assertFalse(r.failed)
        self.assertFalse(project.steps[0].is_dirty())
        self.assertFalse(project.steps[1].is_dirty())
        self.assertTrue(project.steps[2].is_dirty())
示例#18
0
    def test_run_count(self):
        """ should run single step only """

        support.create_project(self, 'eagan')
        support.add_step(self)
        support.add_step(self)
        support.add_step(self)

        project = cauldron.project.get_internal_project()

        r = run.execute(
            context=cli.make_command_context(name=run.NAME),
            step=['2']
        )

        self.assertFalse(r.failed)
        self.assertFalse(project.steps[0].is_dirty())
        self.assertFalse(project.steps[1].is_dirty())
示例#19
0
    def test_repeats(self):
        """ should not repeat run multiple named steps in a single run """

        support.create_project(self, 'eden-prairie')
        support.add_step(self)
        support.add_step(self)
        support.add_step(self)

        project = cauldron.project.get_internal_project()
        step_names = [s.filename for s in project.steps[:-1]]
        step_names.append(project.steps[0].filename)

        r = run.execute(context=cli.make_command_context(name=run.NAME),
                        step=step_names)

        self.assertFalse(r.failed)
        self.assertFalse(project.steps[0].is_dirty())
        self.assertFalse(project.steps[1].is_dirty())
        self.assertTrue(project.steps[2].is_dirty())
示例#20
0
    def test_multiple_steps(self):
        """ should run multiple named steps """

        support.create_project(self, 'robinsdale')
        support.add_step(self)
        support.add_step(self)
        support.add_step(self)

        project = cauldron.project.get_internal_project()
        step_names = [s.filename for s in project.steps[:-1]]

        r = run.execute(
            context=cli.make_command_context(name=run.NAME),
            step=step_names
        )

        self.assertFalse(r.failed)
        self.assertFalse(project.steps[0].is_dirty())
        self.assertFalse(project.steps[1].is_dirty())
        self.assertTrue(project.steps[2].is_dirty())
示例#21
0
    def test_repeat_additions(self):
        """ should not repeat run multiple named steps in a single run """

        support.create_project(self, 'plymouth')
        support.add_step(self)
        support.add_step(self)
        support.add_step(self)

        project = cauldron.project.get_internal_project()
        step_names = [
            project.steps[1].filename, project.steps[0].filename, '..'
        ]

        r = run.execute(context=cli.make_command_context(name=run.NAME),
                        step=step_names)

        self.assertFalse(r.failed)
        self.assertFalse(project.steps[0].is_dirty())
        self.assertTrue(project.steps[1].is_dirty())
        self.assertTrue(project.steps[2].is_dirty())
示例#22
0
    def test_repeats(self):
        """ should not repeat run multiple named steps in a single run """

        support.create_project(self, 'eden-prairie')
        support.add_step(self)
        support.add_step(self)
        support.add_step(self)

        project = cauldron.project.get_internal_project()
        step_names = [s.filename for s in project.steps[:-1]]
        step_names.append(project.steps[0].filename)

        r = run.execute(
            context=cli.make_command_context(name=run.NAME),
            step=step_names
        )

        self.assertFalse(r.failed)
        self.assertFalse(project.steps[0].is_dirty())
        self.assertFalse(project.steps[1].is_dirty())
        self.assertTrue(project.steps[2].is_dirty())
示例#23
0
def execute_remote(
    context: cli.CommandContext,
    action: str = None,
    step_name: str = None,
    position: str = None,
    title: str = None,
    new_name: str = None,
    keep: bool = False,
) -> Response:

    status_response = sync.comm.send_request(
        endpoint='/sync-status', remote_connection=context.remote_connection)
    if status_response.failed:
        return context.response.consume(status_response)

    source_directory = status_response.data['remote_source_directory']
    if not project_opener.project_exists(context.response, source_directory):
        return context.response

    context.response.consume(
        execute(context=context,
                action=action,
                step_name=step_name,
                position=position,
                title=title,
                new_name=new_name,
                keep=keep,
                project=projects.Project(source_directory)))
    if context.response.failed:
        return context.response

    sync_response = sync_command.do_synchronize(
        context=cli.make_command_context(
            name='sync',
            response=context.response,
            remote_connection=context.remote_connection),
        source_directory=source_directory,
        newer_than=status_response.data.get('sync_time', 0))

    return context.response.consume(sync_response)
示例#24
0
def execute_remote(context: cli.CommandContext, **kwargs) -> Response:
    """ """

    sync_response = sync_command.execute(
        cli.make_command_context(name=sync_command.NAME,
                                 remote_connection=context.remote_connection))
    context.response.consume(sync_response)

    if sync_response.failed:
        return context.response

    environ.log('[STARTED]: Remote run execution', whitespace=1)

    thread = sync.send_remote_command(command=context.name,
                                      raw_args=context.raw_args,
                                      asynchronous=True,
                                      show_logs=True)

    thread.join()

    response = thread.responses[-1]
    return context.response.consume(response)
示例#25
0
    def test_repeat_additions(self):
        """ should not repeat run multiple named steps in a single run """

        support.create_project(self, 'plymouth')
        support.add_step(self)
        support.add_step(self)
        support.add_step(self)

        project = cauldron.project.get_internal_project()
        step_names = [
            project.steps[1].filename,
            project.steps[0].filename,
            '..'
        ]

        r = run.execute(
            context=cli.make_command_context(name=run.NAME),
            step=step_names
        )

        self.assertFalse(r.failed)
        self.assertFalse(project.steps[0].is_dirty())
        self.assertTrue(project.steps[1].is_dirty())
        self.assertTrue(project.steps[2].is_dirty())
示例#26
0
def run_project(
        project_directory: str,
        output_directory: str = None,
        log_path: str = None,
        shared_data: dict = None,
        reader_path: str = None,
        reload_project_libraries: bool = False
) -> ExecutionResult:
    """
    Opens, executes and closes a Cauldron project in a single command in
    production mode (non-interactive).

    :param project_directory:
        Directory where the project to run is located
    :param output_directory:
        Directory where the project display data will be saved
    :param log_path:
        Path to a file or directory where logging information will be
        written
    :param shared_data:
        Data to load into the cauldron.shared object prior to executing the
        project
    :param reader_path:
        Specifies a path where a reader file will be saved after the project
        has finished running. If no path is specified, no reader file will be
        saved. If the path is a directory, a reader file will be saved in that
        directory with the project name as the file name.
    :param reload_project_libraries:
        Whether or not to reload all project libraries prior to execution of
        the project. By default this is False, but can be enabled in cases
        where refreshing the project libraries before execution is needed.
    :return:
        The response result from the project execution
    """
    log_path = initialize_logging_path(log_path)
    logger.add_output_path(log_path)

    def on_complete(
            command_response: environ.Response,
            project_data: SharedCache = None,
            message: str = None
    ) -> ExecutionResult:
        environ.modes.remove(environ.modes.SINGLE_RUN)
        if message:
            logger.log(message)
        logger.remove_output_path(log_path)
        return ExecutionResult(
            command_response=command_response,
            project_data=project_data or SharedCache()
        )

    environ.modes.add(environ.modes.SINGLE_RUN)

    open_response = open_command.execute(
        context=cli.make_command_context(open_command.NAME),
        path=project_directory,
        results_path=output_directory
    )
    if open_response.failed:
        return on_complete(
            command_response=open_response,
            message='[ERROR]: Aborted trying to open project'
        )

    project = cauldron.project.get_internal_project()
    project.shared.put(**(shared_data if shared_data is not None else dict()))

    commander.preload()
    run_response = run_command.execute(
        context=cli.make_command_context(run_command.NAME),
        skip_library_reload=not reload_project_libraries
    )

    project_cache = SharedCache().put(
        **project.shared._shared_cache_data
    )

    if run_response.failed:
        return on_complete(
            command_response=run_response,
            project_data=project_cache,
            message='[ERROR]: Aborted trying to run project steps'
        )

    if reader_path:
        save_command.execute(
            context=cli.make_command_context(save_command.NAME),
            path=reader_path
        )

    close_response = close_command.execute(
        context=cli.make_command_context(close_command.NAME)
    )
    if close_response.failed:
        return on_complete(
            command_response=close_response,
            project_data=project_cache,
            message='[ERROR]: Failed to close project cleanly after run'
        )

    return on_complete(
        command_response=run_response,
        project_data=project_cache,
        message='Project execution complete'
    )
示例#27
0
def run_project(project_directory: str,
                output_directory: str = None,
                log_path: str = None,
                shared_data: dict = None,
                reader_path: str = None) -> environ.Response:
    """
    Opens, executes and closes a Cauldron project in a single command in
    production mode (non-interactive).

    :param project_directory:
        Directory where the project to run is located
    :param output_directory:
        Directory where the project display data will be saved
    :param log_path:
        Path to a file or directory where logging information will be
        written
    :param shared_data:
        Data to load into the cauldron.shared object prior to executing the
        project
    :param reader_path:
        Specifies a path where a reader file will be saved after the project
        has finished running. If no path is specified, no reader file will be
        saved. If the path is a directory, a reader file will be saved in that
        directory with the project name as the file name.
    :return:
        The response result from the project execution
    """

    log_path = initialize_logging_path(log_path)
    logger.add_output_path(log_path)

    def on_complete(message: str = None) -> environ.Response:
        environ.modes.remove(environ.modes.SINGLE_RUN)
        if message:
            logger.log(message)
        logger.remove_output_path(log_path)
        return response

    environ.modes.add(environ.modes.SINGLE_RUN)

    response = open_command.execute(context=cli.make_command_context(
        open_command.NAME),
                                    path=project_directory,
                                    results_path=output_directory)
    if response.failed:
        return on_complete('[ERROR]: Aborted trying to open project')

    project = cauldron.project.internal_project
    project.shared.put(**(shared_data if shared_data is not None else dict()))

    commander.preload()
    response = run_command.execute(
        context=cli.make_command_context(run_command.NAME))
    if response.failed:
        return on_complete('[ERROR]: Aborted trying to run project steps')

    if reader_path:
        save_command.execute(context=cli.make_command_context(
            save_command.NAME),
                             path=reader_path)

    response = close_command.execute(
        context=cli.make_command_context(close_command.NAME))
    if response.failed:
        return on_complete(
            '[ERROR]: Failed to close project cleanly after run')

    return on_complete('Project execution complete')