Esempio n. 1
0
def load_images(blender_output_file_name: str, result_file: str,
                subtask_id: str) -> Tuple[ndarray, ndarray]:
    # Read both files with OpenCV.
    cv2 = import_cv2()  # type: ignore
    try:
        image_1 = cv2.imread(  # pylint: disable=no-member
            generate_verifier_storage_file_path(blender_output_file_name))

        image_2 = cv2.imread(  # pylint: disable=no-member
            result_file)
    except MemoryError as exception:
        log(
            logger,
            f'Loading result files into memory exceeded available memory and failed with: {exception}',
            subtask_id=subtask_id,
        )
        raise VerificationError(
            str(exception),
            ErrorCode.VERIFIER_LOADING_FILES_INTO_MEMORY_FAILED,
            subtask_id,
        )
    # If loading fails because of wrong path, cv2.imread does not raise any error but returns None.
    if image_1 is None or image_2 is None:
        log(
            logger,
            f'Loading files using OpenCV fails.',
            subtask_id=subtask_id,
        )
        raise VerificationError(
            'Loading files using OpenCV fails.',
            ErrorCode.VERIFIER_LOADING_FILES_WITH_OPENCV_FAILED,
            subtask_id,
        )
    return (image_1, image_2)
Esempio n. 2
0
    def test_blender_verification_order_should_call_verification_result_with_result_error_if_render_image_raises_exception(
            self):
        with mock.patch('verifier.tasks.download_archives_from_storage', autospec=True) as mock_download_archives_from_storage, \
            mock.patch('verifier.tasks.validate_downloaded_archives', autospec=True) as mock_validate_downloaded_archives, \
            mock.patch('verifier.tasks.unpack_archives', autospec=True) as mock_unpack_archives, \
            mock.patch('verifier.tasks.get_files_list_from_archive', autospec=True, side_effect=[self.frames]) as mock_get_files_list_from_archive, \
            mock.patch('verifier.tasks.parse_result_files_with_frames', autospec=True, return_value=self.mocked_parse_result_files_with_frames()) as mock_parse_result_files_with_frames, \
            mock.patch('core.tasks.verification_result.delay', autospec=True) as mock_verification_result, \
            mock.patch(
                'verifier.tasks.render_images_by_frames',
                side_effect=VerificationError(
                    'error',
                    ErrorCode.VERIFIER_RUNNING_BLENDER_FAILED,
                    self.subtask_id
                ),
                autospec=True, return_value=(True, True)):  # noqa: E125

            self._send_blender_verification_order()

        self.assertEqual(mock_download_archives_from_storage.call_count, 1)
        self.assertEqual(mock_validate_downloaded_archives.call_count, 1)
        self.assertEqual(mock_get_files_list_from_archive.call_count, 1)
        self.assertEqual(mock_parse_result_files_with_frames.call_count, 1)
        self.assertEqual(mock_unpack_archives.call_count, 1)
        mock_verification_result.assert_called_once_with(
            self.subtask_id,
            VerificationResult.ERROR.name,
            'error',
            ErrorCode.VERIFIER_RUNNING_BLENDER_FAILED.name,
        )
Esempio n. 3
0
def download_archives_from_storage(
    file_transfer_token: message.concents.FileTransferToken,
    subtask_id: str,
    package_paths_to_downloaded_file_names: Dict[str, str],
) -> None:
    # Remove any files from VERIFIER_STORAGE_PATH.
    clean_directory(settings.VERIFIER_STORAGE_PATH, subtask_id)

    # Download all the files listed in the message from the storage server to local storage.
    for file_path, download_file_name in package_paths_to_downloaded_file_names.items(
    ):
        try:
            file_transfer_token.sig = None
            cluster_response = send_request_to_storage_cluster(
                prepare_storage_request_headers(file_transfer_token),
                settings.STORAGE_SERVER_INTERNAL_ADDRESS +
                CLUSTER_DOWNLOAD_PATH + file_path,
                method='get',
            )
            path_to_store = os.path.join(settings.VERIFIER_STORAGE_PATH,
                                         download_file_name)
            store_file_from_response_in_chunks(cluster_response, path_to_store)
        except Exception as exception:
            log(
                logger,
                f'blender_verification_order for SUBTASK_ID {subtask_id} failed with error {exception}.'
                f'ErrorCode: {ErrorCode.VERIFIER_FILE_DOWNLOAD_FAILED.name}')
            raise VerificationError(
                str(exception),
                ErrorCode.VERIFIER_FILE_DOWNLOAD_FAILED,
                subtask_id=subtask_id,
            )
Esempio n. 4
0
def validate_downloaded_archives(subtask_id: str, archives_list: Iterable[str],
                                 scene_file: str) -> None:
    # If archive is broken, it means that Provider must have intentionally uploaded damaged zip file.
    # In such case verification end with MISMATCH result.
    package_files_list = []  # type: List[str]
    try:
        # If any file which is supposed to be unpacked from archives already exists, finish with error and raise exception.
        for package_file_path in archives_list:
            package_files_list += get_files_list_from_archive(
                generate_verifier_storage_file_path(package_file_path))
    except zipfile.BadZipFile:
        raise VerificationMismatch(subtask_id)

    already_existing_files = set(os.listdir(
        settings.VERIFIER_STORAGE_PATH)).intersection(package_files_list)
    if already_existing_files:
        # This should not happen normally as the directory is cleaned before
        raise VerificationError(
            f'Files:<{", ".join(already_existing_files)}> already exist.',
            ErrorCode.VERIFIER_UNPACKING_ARCHIVE_FAILED,
            subtask_id,
        )

    # Similarly, it is Provider's responsibility to upload scene file.
    # If it is missing, verification end with MISMATCH result.
    if scene_file not in package_files_list:
        raise VerificationMismatch(subtask_id)
Esempio n. 5
0
def render_image(
    frame_number: int,
    output_format: str,
    scene_file: str,
    subtask_id: str,
    verification_deadline: Union[int, float],
    blender_crop_script_parameters: Dict[str, Union[int, List[float], bool]],
) -> None:
    # Verifier runs blender process.
    try:
        completed_process = run_blender(
            scene_file,
            output_format,
            frame_number,
            verification_deadline,
            blender_crop_script_parameters,
            subtask_id,
        )
        clean_directory(
            os.path.join(settings.VERIFIER_STORAGE_PATH, 'render-scripts'),
            subtask_id)
        # If Blender finishes with errors, verification ends here
        # Verification_result informing about the error is sent to the work queue.
        if completed_process.returncode != 0:
            log(
                logger, 'Blender finished with errors',
                f'SUBTASK_ID: {subtask_id}.'
                f'Returncode: {str(completed_process.returncode)}.'
                f'stderr: {str(completed_process.stderr)}.'
                f'stdout: {str(completed_process.stdout)}.')
            raise VerificationError(
                str(completed_process.stderr),
                ErrorCode.VERIFIER_RUNNING_BLENDER_FAILED,
                subtask_id,
            )
    except subprocess.SubprocessError as exception:
        log(
            logger,
            f'Blender finished with errors. Error: {exception} SUBTASK_ID {subtask_id}'
        )
        raise VerificationError(
            str(exception),
            ErrorCode.VERIFIER_RUNNING_BLENDER_FAILED,
            subtask_id,
        )
Esempio n. 6
0
def compare_images(image_1: ndarray, image_2: ndarray, subtask_id: str) -> float:
    # Compute SSIM for the image pair.
    try:
        ssim = compare_ssim(image_1, image_2, multichannel=True)
    except ValueError as exception:
        logger.info(f'Computing SSIM fails with: {exception}')
        raise VerificationError(
            str(exception),
            ErrorCode.VERIFIER_COMPUTING_SSIM_FAILED,
            subtask_id,
        )
    assert isinstance(ssim, float)
    return ssim
Esempio n. 7
0
    def test_blender_verification_order_should_call_verification_result_with_result_error_if_compare_ssim_raise_value_error(
            self):
        with mock.patch('verifier.tasks.download_archives_from_storage', autospec=True) as mock_download_archives_from_storage, \
            mock.patch('verifier.tasks.validate_downloaded_archives', autospec=True) as mock_validate_downloaded_archives, \
            mock.patch('verifier.tasks.unpack_archives', autospec=True) as mock_unpack_archives, \
            mock.patch('verifier.tasks.get_files_list_from_archive', autospec=True, side_effect=[self.frames]) as mock_get_files_list_from_archive, \
            mock.patch('verifier.tasks.parse_result_files_with_frames', autospec=True, return_value=self.mocked_parse_result_files_with_frames()) as mock_parse_result_files_with_frames, \
            mock.patch('verifier.tasks.render_images_by_frames', autospec=True, return_value=(self.blender_output_file_name_list, self.parsed_all_files)) as mock_render_image, \
            mock.patch('verifier.tasks.delete_source_files', autospec=True) as mock_delete_source_files, \
            mock.patch('verifier.tasks.upload_blender_output_file', autospec=True) as mock_try_to_upload_file, \
            mock.patch(
                'verifier.tasks.compare_all_rendered_images_with_user_results_files',
                autospec=True,
                side_effect=VerificationError(
                    'error',
                    ErrorCode.VERIFIER_COMPUTING_SSIM_FAILED,
                    self.subtask_id
                ),
            ), \
            mock.patch('core.tasks.verification_result.delay', autospec=True) as mock_verification_result:  # noqa: E125

            current_time = get_current_utc_timestamp()
            self._send_blender_verification_order(current_time=current_time)

        self.assertEqual(mock_download_archives_from_storage.call_count, 1)
        self.assertEqual(mock_parse_result_files_with_frames.call_count, 1)
        self.assertEqual(mock_validate_downloaded_archives.call_count, 1)
        self.assertEqual(mock_get_files_list_from_archive.call_count, 1)
        self.assertEqual(mock_unpack_archives.call_count, 1)
        mock_render_image.assert_called_once_with(
            frames=self.frames,
            parsed_files_to_compare=self.mocked_parse_result_files_with_frames(
            ),
            output_format=self.output_format,
            scene_file=self.scene_file,
            subtask_id=self.subtask_id,
            verification_deadline=self._get_verification_deadline_as_timestamp(
                current_time,
                self.report_computed_task.size,
            ),
            blender_crop_script=self.compute_task_def['extra_data']
            ['script_src'],
        )
        self.assertEqual(mock_delete_source_files.call_count, 1)
        self.assertEqual(mock_try_to_upload_file.call_count, 1)
        mock_verification_result.assert_called_once_with(
            self.subtask_id,
            VerificationResult.ERROR.name,
            'error',
            ErrorCode.VERIFIER_COMPUTING_SSIM_FAILED.name,
        )
Esempio n. 8
0
def render_image(frame_number: int, output_format: str, scene_file: str, subtask_id: str, verification_deadline: int, blender_crop_script: Optional[str]=None) -> None:
    # Verifier stores Blender crop script to a file.
    if blender_crop_script is not None:
        blender_script_file_name = store_blender_script_file(subtask_id, blender_crop_script)  # type: Optional[str]
    else:
        blender_script_file_name = None
    # Verifier runs blender process.
    try:
        completed_process = run_blender(
            scene_file,
            output_format,
            frame_number,
            verification_deadline,
            blender_script_file_name,
        )
        # If Blender finishes with errors, verification ends here
        # Verification_result informing about the error is sent to the work queue.
        if completed_process.returncode != 0:
            log_string_message(
                logger,
                'Blender finished with errors',
                f'SUBTASK_ID: {subtask_id}.'
                f'Returncode: {str(completed_process.returncode)}.'
                f'stderr: {str(completed_process.stderr)}.'
                f'stdout: {str(completed_process.stdout)}.'
            )
            raise VerificationError(
                str(completed_process.stderr),
                ErrorCode.VERIFIER_RUNNING_BLENDER_FAILED,
                subtask_id,
            )
    except subprocess.SubprocessError as exception:
        log_string_message(logger, f'Blender finished with errors. Error: {exception} SUBTASK_ID {subtask_id}')
        raise VerificationError(
            str(exception),
            ErrorCode.VERIFIER_RUNNING_BLENDER_FAILED,
            subtask_id,
        )
Esempio n. 9
0
def try_to_upload_blender_output_file(blender_output_file_name: str,
                                      output_format: str, subtask_id: str,
                                      frame_number: int) -> None:
    upload_file_path = generate_upload_file_path(subtask_id, output_format,
                                                 frame_number)
    # Read Blender output file.
    try:
        with open(
                generate_verifier_storage_file_path(blender_output_file_name),
                'rb') as upload_file:
            upload_file_content = upload_file.read()  # type: bytes
            upload_file_checksum = 'sha1:' + hashlib.sha1(
                upload_file_content).hexdigest()

            # Generate a FileTransferToken valid for an upload of the image generated by blender.
            upload_file_transfer_token = create_file_transfer_token_for_concent(
                subtask_id=subtask_id,
                result_package_path=upload_file_path,
                result_size=len(upload_file_content),
                result_package_hash=upload_file_checksum,
                operation=message.concents.FileTransferToken.Operation.upload,
            )

            # Upload the image.
            upload_file_to_storage_cluster(
                upload_file_content,
                upload_file_path,
                upload_file_transfer_token,
                settings.CONCENT_PRIVATE_KEY,
                settings.CONCENT_PUBLIC_KEY,
                settings.CONCENT_PUBLIC_KEY,
                settings.STORAGE_SERVER_INTERNAL_ADDRESS,
            )
    except OSError as exception:
        log(crash_logger,
            str(exception),
            subtask_id=subtask_id,
            logging_level=LoggingLevel.ERROR)
    except MemoryError as exception:
        log(logger,
            f'Loading result files into memory failed with: {exception}',
            subtask_id=subtask_id,
            logging_level=LoggingLevel.ERROR)
        raise VerificationError(
            str(exception),
            ErrorCode.VERIFIER_LOADING_FILES_INTO_MEMORY_FAILED,
            subtask_id,
        )
Esempio n. 10
0
def unpack_archives(file_paths: Iterable[str], subtask_id: str) -> None:
    # Verifier unpacks the archive with project source.
    for archive_file_path in file_paths:
        try:
            unpack_archive(os.path.basename(archive_file_path))
        except zipfile.BadZipFile as exception:
            log(
                logger,
                f'Verifier failed to unpack the archive with project source with error {exception} '
                f'SUBTASK_ID {subtask_id}. '
                f'ErrorCode: {ErrorCode.VERIFIER_UNPACKING_ARCHIVE_FAILED.name}'
            )
            raise VerificationError(
                str(exception),
                ErrorCode.VERIFIER_UNPACKING_ARCHIVE_FAILED,
                subtask_id,
            )
Esempio n. 11
0
    def test_blender_verification_order_should_call_verification_result_with_result_error_if_unpacking_archive_fails(
            self):
        with  mock.patch('verifier.tasks.download_archives_from_storage', autospec=True) as mock_download_archives_from_storage, \
            mock.patch('verifier.tasks.validate_downloaded_archives', autospec=True) as mock_validate_downloaded_archives, \
            mock.patch('verifier.tasks.unpack_archives', side_effect=VerificationError(
            "error",
            ErrorCode.VERIFIER_UNPACKING_ARCHIVE_FAILED,
            self.subtask_id
        ), autospec=True), \
            mock.patch('core.tasks.verification_result.delay', autospec=True) as mock_verification_result:  # noqa: E125

            self._send_blender_verification_order()

        self.assertEqual(mock_download_archives_from_storage.call_count, 1)
        self.assertEqual(mock_validate_downloaded_archives.call_count, 1)
        mock_verification_result.assert_called_once_with(
            self.subtask_id,
            VerificationResult.ERROR.name,
            'error',
            ErrorCode.VERIFIER_UNPACKING_ARCHIVE_FAILED.name,
        )
Esempio n. 12
0
    def test_that_blender_verification_order_should_call_verification_result_with_result_error_if_download_fails(
            self):
        with mock.patch(
                'verifier.tasks.download_archives_from_storage',
                autospec=True,
                side_effect=VerificationError(
                    'error',
                    ErrorCode.VERIFIER_FILE_DOWNLOAD_FAILED,
                    self.compute_task_def['subtask_id']
                )
            ) as mock_download_archives_from_storage, \
            mock.patch('core.tasks.verification_result.delay', autospec=True) as mock_verification_result:  # noqa: E129
            self._send_blender_verification_order()

        self.assertEqual(mock_download_archives_from_storage.call_count, 1)
        mock_verification_result.assert_called_once_with(
            self.compute_task_def['subtask_id'],
            VerificationResult.ERROR.name,
            'error',
            ErrorCode.VERIFIER_FILE_DOWNLOAD_FAILED.name,
        )