Example #1
0
    def test_workflow_success(self):
        with TestAreaContext(
                "python/job_queue/workflow_runner_fast") as work_area:
            WorkflowCommon.createWaitJob()

            joblist = WorkflowJoblist()
            self.assertTrue(joblist.addJobFromFile("WAIT", "wait_job"))
            self.assertTrue(
                joblist.addJobFromFile("EXTERNAL_WAIT", "external_wait_job"))

            workflow = Workflow("fast_wait_workflow", joblist)

            self.assertEqual(len(workflow), 2)

            workflow_runner = WorkflowRunner(workflow,
                                             ert=None,
                                             context=SubstitutionList())

            self.assertFalse(workflow_runner.isRunning())

            workflow_runner.run()
            time.sleep(1)  # wait for workflow to start
            workflow_runner.wait()

            self.assertFileExists("wait_started_0")
            self.assertFileDoesNotExist("wait_cancelled_0")
            self.assertFileExists("wait_finished_0")

            self.assertFileExists("wait_started_1")
            self.assertFileDoesNotExist("wait_cancelled_1")
            self.assertFileExists("wait_finished_1")

            self.assertTrue(workflow_runner.workflowResult())
Example #2
0
def createWorkflowRunner(workflow_name):
    """ @rtype: WorkflowRunner """
    workflow_list = ERT.ert.getWorkflowList()

    workflow = workflow_list[workflow_name]
    context = workflow_list.getContext()
    return WorkflowRunner(workflow, ERT.ert, context)
Example #3
0
    def test_workflow_thread_cancel_external(self):
        with TestAreaContext(
                "python/job_queue/workflow_runner_external") as work_area:
            WorkflowCommon.createWaitJob()

            joblist = WorkflowJoblist()
            self.assertTrue(joblist.addJobFromFile("WAIT",
                                                   "external_wait_job"))
            self.assertTrue("WAIT" in joblist)

            workflow = Workflow("wait_workflow", joblist)

            self.assertEqual(len(workflow), 3)

            workflow_runner = WorkflowRunner(workflow,
                                             ert=None,
                                             context=SubstitutionList())

            self.assertFalse(workflow_runner.isRunning())

            with workflow_runner:
                wait_until(
                    lambda: self.assertTrue(workflow_runner.isRunning()))
                wait_until(lambda: self.assertFileExists("wait_started_0"))
                wait_until(lambda: self.assertFileExists("wait_finished_0"))
                wait_until(lambda: self.assertFileExists("wait_started_1"))
                workflow_runner.cancel()
                self.assertTrue(workflow_runner.isCancelled())

            self.assertFileDoesNotExist("wait_finished_1")
            self.assertFileDoesNotExist("wait_started_2")
            self.assertFileDoesNotExist("wait_cancelled_2")
            self.assertFileDoesNotExist("wait_finished_2")
Example #4
0
    def startWorkflow(self):
        self._running_workflow_dialog = WorkflowDialog("Running Workflow",
                                                       self.createSpinWidget(),
                                                       self)
        self._running_workflow_dialog.closeButtonPressed.connect(
            self.cancelWorkflow)

        workflow_thread = Thread(name="ert_gui_workflow_thread")
        workflow_thread.setDaemon(True)
        workflow_thread.run = self.runWorkflow

        workflow_list = self.ert.getWorkflowList()

        workflow = workflow_list[self.getCurrentWorkflowName()]
        context = workflow_list.getContext()
        self._workflow_runner = WorkflowRunner(workflow, self.ert, context)
        self._workflow_runner.run()

        workflow_thread.start()

        self._running_workflow_dialog.show()
Example #5
0
    def run(self, workflow):
        workflow = workflow.strip()
        if workflow in self.getWorkflowNames():
            workflow_list = self.ert().getWorkflowList()
            workflow = workflow_list[workflow]
            context = workflow_list.getContext()

            runner = WorkflowRunner(workflow, self.ert(), context)
            runner.run()
            runner.wait()
        else:
            self.lastCommandFailed("Unknown workflow: '%s'" % workflow)
Example #6
0
    def test_workflow_thread_cancel_ert_script(self):
        with TestAreaContext("python/job_queue/workflow_runner_ert_script"):
            WorkflowCommon.createWaitJob()

            joblist = WorkflowJoblist()
            self.assertTrue(joblist.addJobFromFile("WAIT", "wait_job"))
            self.assertTrue("WAIT" in joblist)

            workflow = Workflow("wait_workflow", joblist)

            self.assertEqual(len(workflow), 3)

            workflow_runner = WorkflowRunner(workflow)

            self.assertFalse(workflow_runner.isRunning())

            with workflow_runner:
                self.assertIsNone(workflow_runner.workflowResult())

                wait_until(lambda: self.assertTrue(workflow_runner.isRunning()))
                wait_until(lambda: self.assertFileExists("wait_started_0"))

                wait_until(lambda: self.assertFileExists("wait_finished_0"))

                wait_until(lambda: self.assertFileExists("wait_started_1"))

                workflow_runner.cancel()

                wait_until(lambda: self.assertFileExists("wait_cancelled_1"))

                self.assertTrue(workflow_runner.isCancelled())

            self.assertFileDoesNotExist("wait_finished_1")
            self.assertFileDoesNotExist("wait_started_2")
            self.assertFileDoesNotExist("wait_cancelled_2")
            self.assertFileDoesNotExist("wait_finished_2")
Example #7
0
    def test_workflow_failed_job(self):
        with TestAreaContext("python/job_queue/workflow_runner_fails"):
            WorkflowCommon.createExternalDumpJob()

            joblist = WorkflowJoblist()
            self.assertTrue(joblist.addJobFromFile("DUMP", "dump_failing_job"))
            workflow = Workflow("dump_workflow", joblist)
            self.assertEqual(len(workflow), 2)

            workflow_runner = WorkflowRunner(
                workflow, ert=None, context=SubstitutionList()
            )

            self.assertFalse(workflow_runner.isRunning())
            with patch.object(
                Workflow, "run", side_effect=Exception("mocked workflow error")
            ), workflow_runner:
                workflow_runner.wait()
                self.assertNotEqual(workflow_runner.exception(), None)
Example #8
0
class RunWorkflowWidget(QWidget):

    workflowSucceeded = Signal(list)
    workflowFailed = Signal()
    workflowKilled = Signal()

    def __init__(self, ert):
        self.ert = ert
        QWidget.__init__(self)

        layout = QHBoxLayout()
        layout.addSpacing(10)

        self._workflow_combo = QComboBox()
        addHelpToWidget(self._workflow_combo, "run/workflow")

        self._workflow_combo.addItems(
            sorted(ert.getWorkflowList().getWorkflowNames(), key=str.lower))

        layout.addWidget(QLabel("Select Workflow:"), 0, Qt.AlignVCenter)
        layout.addWidget(self._workflow_combo, 0, Qt.AlignVCenter)

        # simulation_mode_layout.addStretch()
        layout.addSpacing(20)

        self.run_button = QToolButton()
        self.run_button.setIconSize(QSize(32, 32))
        self.run_button.setText("Start Workflow")
        self.run_button.setIcon(resourceIcon("play_circle.svg"))
        self.run_button.clicked.connect(self.startWorkflow)
        self.run_button.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)

        layout.addWidget(self.run_button)
        layout.addStretch(1)

        self.setLayout(layout)

        self._running_workflow_dialog = None

        self.workflowSucceeded.connect(self.workflowFinished)
        self.workflowFailed.connect(self.workflowFinishedWithFail)
        self.workflowKilled.connect(self.workflowStoppedByUser)

        self._workflow_runner = None
        """:type: WorkflowRunner"""

    def createSpinWidget(self):
        widget = QWidget()
        layout = QHBoxLayout()

        size = 64
        spin_movie = resourceMovie("loading.gif")
        spin_movie.setSpeed(60)
        spin_movie.setScaledSize(QSize(size, size))
        spin_movie.start()

        processing_animation = QLabel()
        processing_animation.setMaximumSize(QSize(size, size))
        processing_animation.setMinimumSize(QSize(size, size))
        processing_animation.setMovie(spin_movie)
        layout.addWidget(processing_animation)

        processing_label = QLabel(
            f"Processing workflow '{self.getCurrentWorkflowName()}'")
        layout.addWidget(processing_label, Qt.AlignBottom)

        widget.setLayout(layout)

        return widget

    def cancelWorkflow(self):
        if self._workflow_runner.isRunning():
            cancel = QMessageBox.question(
                self,
                "Confirm Cancel",
                "Are you sure you want to cancel the running workflow?",
                QMessageBox.Yes | QMessageBox.No,
            )

            if cancel == QMessageBox.Yes:
                self._workflow_runner.cancel()
                self._running_workflow_dialog.disableCloseButton()

    def getCurrentWorkflowName(self):
        index = self._workflow_combo.currentIndex()
        return sorted(self.ert.getWorkflowList().getWorkflowNames(),
                      key=str.lower)[index]

    def startWorkflow(self):
        self._running_workflow_dialog = WorkflowDialog("Running Workflow",
                                                       self.createSpinWidget(),
                                                       self)
        self._running_workflow_dialog.closeButtonPressed.connect(
            self.cancelWorkflow)

        workflow_thread = Thread(name="ert_gui_workflow_thread")
        workflow_thread.setDaemon(True)
        workflow_thread.run = self.runWorkflow

        workflow_list = self.ert.getWorkflowList()

        workflow = workflow_list[self.getCurrentWorkflowName()]
        context = workflow_list.getContext()
        self._workflow_runner = WorkflowRunner(workflow, self.ert, context)
        self._workflow_runner.run()

        workflow_thread.start()

        self._running_workflow_dialog.show()

    def runWorkflow(self):
        while self._workflow_runner.isRunning():
            time.sleep(2)

        cancelled = self._workflow_runner.isCancelled()

        if cancelled:
            self.workflowKilled.emit()
        else:
            success = self._workflow_runner.workflowResult()

            if success:
                report = self._workflow_runner.workflowReport()
                failed_jobs = [
                    k for k, v in report.items() if not v["completed"]
                ]
                self.workflowSucceeded.emit(failed_jobs)
            else:
                self.workflowFailed.emit()

    def workflowFinished(self, failed_jobs):
        workflow_name = self.getCurrentWorkflowName()
        jobs_msg = "successfully!"
        if failed_jobs:
            jobs_msg = "\nThe following jobs failed: " + ", ".join(
                [j for j in failed_jobs])

        QMessageBox.information(
            self,
            "Workflow completed!",
            f"The workflow '{workflow_name}' completed {jobs_msg}",
        )
        self._running_workflow_dialog.accept()
        self._running_workflow_dialog = None

    def workflowFinishedWithFail(self):
        workflow_name = self.getCurrentWorkflowName()

        error = self._workflow_runner.workflowError()

        QMessageBox.critical(
            self,
            "Workflow failed!",
            f"The workflow '{workflow_name}' failed!\n\n{error}",
        )
        self._running_workflow_dialog.reject()
        self._running_workflow_dialog = None

    def workflowStoppedByUser(self):
        workflow_name = self.getCurrentWorkflowName()
        QMessageBox.information(
            self,
            "Workflow killed!",
            f"The workflow '{workflow_name}' was killed successfully!",
        )
        self._running_workflow_dialog.reject()
        self._running_workflow_dialog = None
Example #9
0
    def test_workflow_thread_cancel_ert_script(self):
        with TestAreaContext(
                "python/job_queue/workflow_runner_ert_script") as work_area:
            WorkflowCommon.createWaitJob()

            joblist = WorkflowJoblist()
            self.assertTrue(joblist.addJobFromFile("WAIT", "wait_job"))
            self.assertTrue("WAIT" in joblist)

            workflow = Workflow("wait_workflow", joblist)

            self.assertEqual(len(workflow), 3)

            workflow_runner = WorkflowRunner(workflow)

            self.assertFalse(workflow_runner.isRunning())

            workflow_runner.run()

            self.assertIsNone(workflow_runner.workflowResult())

            time.sleep(1)  # wait for workflow to start
            self.assertTrue(workflow_runner.isRunning())
            self.assertFileExists("wait_started_0")

            time.sleep(1)  # wait for first job to finish

            workflow_runner.cancel()
            time.sleep(1)  # wait for cancel to take effect
            self.assertFileExists("wait_finished_0")

            self.assertFileExists("wait_started_1")
            self.assertFileExists("wait_cancelled_1")
            self.assertFileDoesNotExist("wait_finished_1")

            self.assertTrue(workflow_runner.isCancelled())

            workflow_runner.wait()  # wait for runner to complete

            self.assertFileDoesNotExist("wait_started_2")
            self.assertFileDoesNotExist("wait_cancelled_2")
            self.assertFileDoesNotExist("wait_finished_2")