def test_execute(self):
     """Test executing a sequence of supported commands."""
     context = dict()
     fh = self.backend.projects.get_project(
         self.PROJECT_ID).filestore.upload_file(CSV_FILE)
     cmd = vizual.load_dataset(dataset_name=DATASET_NAME,
                               file={pckg.FILE_ID: fh.identifier},
                               validate=True)
     result = self.backend.execute(task=TaskHandle(
         task_id='000', project_id=self.PROJECT_ID),
                                   command=cmd,
                                   context=context)
     self.assertTrue(result.is_success)
     state = result.provenance.get_database_state(prev_state=dict())
     context = task_context(state)
     cmd = vizual.update_cell(dataset_name=DATASET_NAME,
                              column=1,
                              row=0,
                              value=9,
                              validate=True)
     result = self.backend.execute(task=TaskHandle(
         task_id='000', project_id=self.PROJECT_ID),
                                   command=cmd,
                                   context=context)
     self.assertTrue(result.is_success)
     state = result.provenance.get_database_state(prev_state=state)
     self.assertNotEqual(context[DATASET_NAME],
                         task_context(state)[DATASET_NAME])
     context = task_context(state)
     cmd = pycell.python_cell(source=CREATE_DATASET_PY, validate=True)
     result = self.backend.execute(task=TaskHandle(
         task_id='000', project_id=self.PROJECT_ID),
                                   command=cmd,
                                   context=context)
     self.assertTrue(result.is_success)
     state = result.provenance.get_database_state(prev_state=state)
     self.assertTrue(SECOND_DATASET_NAME in state)
     self.assertEqual(context[DATASET_NAME],
                      task_context(state)[DATASET_NAME])
     context = task_context(state)
     cmd = vizual.update_cell(dataset_name=SECOND_DATASET_NAME,
                              column=1,
                              row=0,
                              value=9,
                              validate=True)
     result = self.backend.execute(task=TaskHandle(
         task_id='000', project_id=self.PROJECT_ID),
                                   command=cmd,
                                   context=context)
     self.assertTrue(result.is_success)
     state = result.provenance.get_database_state(prev_state=state)
     self.assertEqual(context[DATASET_NAME],
                      task_context(state)[DATASET_NAME])
     self.assertNotEqual(context[SECOND_DATASET_NAME],
                         task_context(state)[SECOND_DATASET_NAME])
    def test_execute_unsupported_command(self):
        """Test executing commands that are not supported for synchronous
        execution.
        """
        with self.assertRaises(ValueError):
            self.backend.execute(task=TaskHandle(task_id='000',
                                                 project_id=self.PROJECT_ID),
                                 command=vizual.insert_row(
                                     dataset_name=DATASET_NAME,
                                     position=1,
                                     validate=True),
                                 context=dict())

        with self.assertRaises(ValueError):
            self.backend.execute(task=TaskHandle(task_id='000',
                                                 project_id=self.PROJECT_ID),
                                 command=vizual.drop_dataset(
                                     dataset_name=DATASET_NAME, validate=True),
                                 context=dict())
Пример #3
0
 def test_execute(self):
     """Test executing a sequence of supported commands."""
     context = dict()
     cmd = pycell.python_cell(source='print(2+2)', validate=True)
     controller = FakeWorkflowController()
     self.backend.execute_async(task=TaskHandle(task_id='000',
                                                project_id=self.PROJECT_ID,
                                                controller=controller),
                                command=cmd,
                                artifacts=context)
     time.sleep(3)
     self.assertEqual(controller.task_id, '000')
     self.assertEqual(controller.state, 'SUCCESS')
     self.assertEqual(controller.outputs.stdout[0].value, '4')
Пример #4
0
 def test_cancel(self) -> None:
     """Test executing a sequence of supported commands."""
     context: Dict[str, ArtifactDescriptor] = dict()
     cmd = pycell.python_cell(source='import time\ntime.sleep(5)',
                              validate=True)
     controller = FakeWorkflowController()
     self.backend.execute_async(task=TaskHandle(task_id='000',
                                                project_id=self.PROJECT_ID,
                                                controller=controller),
                                command=cmd,
                                artifacts=context)
     time.sleep(1)
     self.backend.cancel_task('000')
     time.sleep(5)
     self.assertIsNone(controller.task_id)
     self.assertIsNone(controller.state)
Пример #5
0
 def test_error(self) -> None:
     """Test executing a command with processor that raises an exception
     instead of returning an execution result.
     """
     context: Dict[str, ArtifactDescriptor] = dict()
     cmd = ModuleCommand(package_id='error',
                         command_id='error',
                         arguments=[],
                         packages=None)
     controller = FakeWorkflowController()
     self.backend.execute_async(task=TaskHandle(task_id='000',
                                                project_id=self.PROJECT_ID,
                                                controller=controller),
                                command=cmd,
                                artifacts=context)
     time.sleep(2)
     self.assertEqual(controller.task_id, '000')
     self.assertEqual(controller.state, 'ERROR')
     self.assertEqual(len(controller.outputs.stdout), 0)
     self.assertNotEqual(len(controller.outputs.stderr), 0)
Пример #6
0
    def execute_task(self,
                     project_id,
                     task_id,
                     command,
                     context,
                     resources=None):
        """Execute a given command asynchronously using the engies backend.

        Make use to use the remote web service as controller that orchestrates
        workflow execution.

        Parameters
        ----------
        project_id: string
            Unique project identifier
        task_id: string
            Unique task identifier
        command : vizier.viztrail.command.ModuleCommand
            Specification of the command that is to be executed
        context: dict
            Dictionary of available resource in the database state. The key is
            the resource name. Values are resource identifiers.
        resources: dict, optional
            Optional information about resources that were generated during a
            previous execution of the command

        Returns
        ------
        dict
        """
        self.engine.backend.execute_async(task=TaskHandle(
            project_id=project_id,
            task_id=task_id,
            controller=RemoteWorkflowController(urls=TaskUrlFactory(
                base_url=self.controller_url))),
                                          command=command,
                                          context=context,
                                          resources=resources)
        return {labels.RESULT: True}
Пример #7
0
    def append_workflow_module(self, project_id, branch_id, command):
        """Append module to the workflow at the head of the given viztrail
        branch. The modified workflow will be executed. The result is the new
        head of the branch.

        Returns the handle for the new module in the modified workflow. The
        result is None if the specified project or branch do not exist.

        Parameters
        ----------
        project_id: string
            Unique project identifier
        branch_id : string
            Unique branch identifier
        command : vizier.viztrail.command.ModuleCommand
            Specification of the command that is to be executed by the appended
            workflow module

        Returns
        -------
        vizier.viztrail.module.base.ModuleHandle
        """
        with self.backend.lock:
            # Get the handle for the specified branch
            branch = self.projects.get_branch(project_id=project_id,
                                              branch_id=branch_id)
            if branch is None:
                return None
            # Get the current database state from the last module in the current
            # branch head. At the same time we retrieve the list of modules for
            # the current head of the branch.
            head = branch.get_head()
            if not head is None and len(head.modules) > 0:
                datasets = head.modules[-1].datasets
                modules = head.modules
                is_active = head.is_active
                is_error = head.modules[-1].is_error or head.modules[
                    -1].is_canceled
            else:
                datasets = dict()
                modules = list()
                is_active = False
                is_error = False
            # Get the external representation for the command
            external_form = command.to_external_form(
                command=self.packages[command.package_id].get(
                    command.command_id),
                datasets=datasets)
            # If the workflow is not active and the command can be executed
            # synchronously we run the command immediately and return the
            # completed workflow. Otherwise, a pending workflow is created.
            if not is_active and self.backend.can_execute(command):
                ts_start = get_current_time()
                result = self.backend.execute(task=TaskHandle(
                    task_id=get_unique_identifier(),
                    project_id=project_id,
                    controller=self),
                                              command=command,
                                              context=task_context(datasets))
                ts = ModuleTimestamp(created_at=ts_start,
                                     started_at=ts_start,
                                     finished_at=get_current_time())
                # Depending on the execution outcome create a handle for the
                # executed module
                if result.is_success:
                    module = ModuleHandle(
                        state=mstate.MODULE_SUCCESS,
                        command=command,
                        external_form=external_form,
                        timestamp=ts,
                        datasets=result.provenance.get_database_state(
                            modules[-1].datasets if len(modules) > 0 else dict(
                            )),
                        outputs=result.outputs,
                        provenance=result.provenance)
                else:
                    module = ModuleHandle(state=mstate.MODULE_ERROR,
                                          command=command,
                                          external_form=external_form,
                                          timestamp=ts,
                                          outputs=result.outputs)
                workflow = branch.append_workflow(modules=modules,
                                                  action=wf.ACTION_APPEND,
                                                  command=command,
                                                  pending_modules=[module])
            else:
                # Create new workflow by appending one module to the current
                # head of the branch. The module state is pending if the
                # workflow is active otherwise it depends on the associated
                # backend.
                if is_active:
                    state = mstate.MODULE_PENDING
                elif is_error:
                    state = mstate.MODULE_CANCELED
                else:
                    state = self.backend.next_task_state()
                workflow = branch.append_workflow(
                    modules=modules,
                    action=wf.ACTION_APPEND,
                    command=command,
                    pending_modules=[
                        ModuleHandle(state=state,
                                     command=command,
                                     external_form=external_form)
                    ])
                if not is_active and not state == mstate.MODULE_CANCELED:
                    self.execute_module(project_id=project_id,
                                        branch_id=branch_id,
                                        module=workflow.modules[-1],
                                        datasets=datasets)
        return workflow.modules[-1]