def test_constraints(self) -> None:
     """
     Test constraints
     :return:
     """
     app_user = AppUser('*****@*****.**', 'pass', AppUserRole.ADMIN)
     job = Job(app_user)
     JobTransitionRepository.create(JobTransition(JobStatusEnum.QUEUED,
                                                  job))
     self.assertRaises(IntegrityError, JobTransitionRepository.create,
                       JobTransition(JobStatusEnum.QUEUED, job))
Beispiel #2
0
def get_job_status(user_id: int, job_id: UUID) -> JobStatusEnum:
    get_and_guard_job(user_id, job_id)
    latest_transition = JobTransitionRepository.get_latest_job_transition(
        job_id)
    # todo better handling with asserts
    assert latest_transition is not None
    return latest_transition.status
def obtain_job_result(user_id: int, job_id: UUID) -> Union[bytes, str]:
    """
    Returns bytes if the file was read, returns string if the file must be read
    from the remote file storage
    """
    get_and_guard_job(user_id, job_id)
    latest_transition = JobTransitionRepository.get_latest_job_transition(
        job_id)
    if not latest_transition or latest_transition.status != JobStatusEnum.FINISHED:
        # TODO custom exceptions
        raise Exception(
            f'Job {job_id} is not in FINISHED state but rather in {latest_transition}.'
        )

    fs = get_file_storage()
    # TODO enable redirects as soon as we know how to prevent redirecting with
    # TODO authorization header and how to generate valid urls
    if isinstance(fs, MinIoStorage) and False:
        # noinspection PyTypeChecker
        # we know that this is indeed MinIoStorage because of the check
        return _obtain_url_for_file(fs, job_id)
    else:
        # TODO implement other storages
        data, error = fs.download_bytes(str(job_id), OUTPUT_FILE_NAME)
        if not data:
            raise Exception(error)
        return data
Beispiel #4
0
    def create_job(app_user_id: int) -> Job:
        """
        Created new job with initial QUEUED status in transition.
        :param app_user_id:
        :return:
        """
        app_user = AppUserRepository.get_by_id(app_user_id)
        if app_user is None:
            raise InvalidArgumentException(
                f"App user {app_user_id} does not exist.")

        job = JobRepository.create(Job(app_user), False)
        JobTransitionRepository.create(
            JobTransition(JobStatusEnum.INITIAL, job), False)
        # pylint: disable=E1101
        JobTransitionRepository.get_session().commit()  # type: ignore
        return job
    def test_get_queued_job_to_process(self) -> None:
        # Should get no job
        no_job = JobRepository.get_queued_job_to_process()
        self.assertIsNone(no_job)

        # Should get job1
        app_user = AppUser('*****@*****.**', 'pass', AppUserRole.ADMIN)
        job1 = JobRepository.create(Job(app_user))
        JobTransitionRepository.create_many([JobTransition(JobStatusEnum.QUEUED, job1)]
                                            )
        queued_job = JobRepository.get_queued_job_to_process()
        self.assertEqual(job1, queued_job)

        # Should get job1 again even job2 is created
        job2 = JobRepository.create(Job(app_user))
        JobTransitionRepository.create_many([JobTransition(JobStatusEnum.QUEUED, job2)])
        queued_job = JobRepository.get_queued_job_to_process()
        self.assertEqual(job1, queued_job)

        # Should not get job1 cause it is finished, but job2
        JobTransitionRepository.create_many([
            JobTransition(JobStatusEnum.IN_PROGRESS, job1),
            JobTransition(JobStatusEnum.FINISHED, job1)
        ])

        finished_job = JobRepository.get_queued_job_to_process()
        self.assertEqual(job2, finished_job)
    def test_job_transition_crud(self) -> None:
        """
        Creates and fetch data from db
        :return:
        """
        # Insert one

        app_user = AppUser('*****@*****.**', 'pass', AppUserRole.ADMIN)
        job = Job(app_user)
        job_transition = JobTransition(JobStatusEnum.QUEUED, job)
        job_transition1 = JobTransitionRepository.create(job_transition)
        self.assertEqual(job_transition, job_transition1)

        job_transitions = JobTransitionRepository.get_all()
        self.assertEqual(1, len(job_transitions))
        self.assertEqual(job_transitions[0], job_transition1)

        # Insert and get many
        JobTransitionRepository.create_many([
            JobTransition(JobStatusEnum.IN_PROGRESS, job),
            JobTransition(JobStatusEnum.FINISHED, job)
        ])
        job_transitions = JobTransitionRepository.get_all()
        self.assertEqual(3, len(job_transitions))

        # Get by id
        job_transition_from_db = JobTransitionRepository.get_by_id(
            job_transition1.id)
        self.assertEqual(job_transition1, job_transition_from_db)
Beispiel #7
0
    def test_get_queued_job_to_process_and_set_it_to_in_progress(self) -> None:
        # Should get no job
        no_job = JobService.get_queued_job_to_process_and_set_it_to_in_progress(
        )
        self.assertIsNone(no_job)

        # Get proper one
        app_user = self._create_app_user()
        job1 = JobService.create_job(app_user.id)
        JobService.add_job_status(job1.id, JobStatusEnum.QUEUED)

        job = JobService.get_queued_job_to_process_and_set_it_to_in_progress()
        self.assertEqual(job1, job)
        new_transition = JobTransitionRepository.get_latest_job_transition(
            job.id)
        self.assertEqual(JobStatusEnum.IN_PROGRESS, new_transition.status)
Beispiel #8
0
    def add_job_status(job_id: UUID, status: JobStatusEnum) -> JobTransition:
        """
        Add new to status to Job.
        :param job_id:
        :param status:
        :return:
        """
        job = JobRepository.get_by_id(job_id)
        if job is None:
            raise InvalidArgumentException(f"Job {job_id} does not exist.")

        job_transition = sorted(job.transitions,
                                key=lambda transition: transition.id,
                                reverse=True)[0]  # type: ignore
        if status not in ALLOWED_JOB_STATUS_TRANSITIONS.get(
                job_transition.status, {}):
            raise InvalidArgumentException(
                f"Invalid transition from status {job_transition.status} to {status}."
            )

        return JobTransitionRepository.create(JobTransition(status, job))