示例#1
0
    async def test_prepare(
        self,
        mock_instance_repo: unittest.mock.MagicMock,
    ) -> None:
        async def _run_sub_test(
            wait_for_containers: bool,
            expected_container_status: ContainerInstanceStatus,
        ) -> None:
            with patch.object(
                    CppUnionPIDDataPreparerService,
                    "prepare_on_container_async"
            ) as mock_prepare_on_container_async, patch.object(
                    PIDStage, "update_instance_containers"):
                container = ContainerInstance(
                    instance_id="123",
                    ip_address="192.0.2.0",
                    status=expected_container_status,
                )
                mock_prepare_on_container_async.return_value = container
                stage = PIDPrepareStage(
                    stage=UnionPIDStage.PUBLISHER_PREPARE,
                    instance_repository=mock_instance_repo,
                    storage_svc="STORAGE",  # pyre-ignore
                    onedocker_svc="ONEDOCKER",  # pyre-ignore
                    onedocker_binary_config=MagicMock(
                        task_definition="offline-task:1#container",
                        tmp_directory="/tmp/",
                        binary_version="latest",
                    ),
                )

                res = await stage.prepare(
                    instance_id="123",
                    input_path="in",
                    output_path="out",
                    num_shards=1,
                    wait_for_containers=wait_for_containers,
                )
                self.assertEqual(
                    PIDStage.get_stage_status_from_containers([container]),
                    res,
                )

        data_tests = (
            (True, ContainerInstanceStatus.COMPLETED),
            (True, ContainerInstanceStatus.FAILED),
            (False, ContainerInstanceStatus.STARTED),
        )
        for data_test in data_tests:
            with self.subTest(
                    wait_for_containers=data_test[0],
                    expected_container_status=data_test[1],
            ):
                # reset mocks for each subTests
                mock_instance_repo.reset_mock()
                await _run_sub_test(
                    data_test[0],
                    data_test[1],
                )
示例#2
0
    async def test_run(
        self,
        mock_onedocker_svc: unittest.mock.MagicMock,
        mock_instance_repo: unittest.mock.MagicMock,
        mock_storage_svc: unittest.mock.MagicMock,
        mock_wait_for_containers_async: unittest.mock.MagicMock,
    ) -> None:
        async def _run_sub_test(wait_for_containers: bool, ) -> None:
            ip = "192.0.2.0"
            container = ContainerInstance(
                instance_id="123",
                ip_address=ip,
                status=ContainerInstanceStatus.STARTED)

            mock_onedocker_svc.start_containers = MagicMock(
                return_value=[container])
            mock_onedocker_svc.wait_for_pending_containers = AsyncMock(
                return_value=[container])

            container.status = (ContainerInstanceStatus.COMPLETED
                                if wait_for_containers else
                                ContainerInstanceStatus.STARTED)
            mock_wait_for_containers_async.return_value = [container]

            stage = PIDPrepareStage(
                stage=UnionPIDStage.PUBLISHER_PREPARE,
                instance_repository=mock_instance_repo,
                storage_svc=mock_storage_svc,
                onedocker_svc=mock_onedocker_svc,
                onedocker_binary_config=MagicMock(
                    task_definition="offline-task:1#container",
                    tmp_directory="/tmp/",
                    binary_version="latest",
                ),
            )
            instance_id = "444"
            stage_input = PIDStageInput(
                input_paths=["in"],
                output_paths=["out"],
                num_shards=2,
                instance_id=instance_id,
            )

            # Basic test: All good
            with patch.object(PIDPrepareStage, "files_exist") as mock_fe:
                mock_fe.return_value = True
                stage = PIDPrepareStage(
                    stage=UnionPIDStage.PUBLISHER_PREPARE,
                    instance_repository=mock_instance_repo,
                    storage_svc=mock_storage_svc,
                    onedocker_svc=mock_onedocker_svc,
                    onedocker_binary_config=MagicMock(
                        task_definition="offline-task:1#container",
                        tmp_directory="/tmp/",
                        binary_version="latest",
                    ),
                )
                status = await stage.run(
                    stage_input, wait_for_containers=wait_for_containers)
                self.assertEqual(
                    PIDStageStatus.COMPLETED
                    if wait_for_containers else PIDStageStatus.STARTED,
                    status,
                )

                self.assertEqual(
                    mock_onedocker_svc.start_containers.call_count, 2)
                if wait_for_containers:
                    self.assertEqual(mock_wait_for_containers_async.call_count,
                                     2)
                else:
                    mock_wait_for_containers_async.assert_not_called()
                mock_instance_repo.read.assert_called_with(instance_id)
                self.assertEqual(mock_instance_repo.read.call_count, 4)
                self.assertEqual(mock_instance_repo.update.call_count, 4)

            with patch.object(PIDPrepareStage,
                              "files_exist") as mock_fe, patch.object(
                                  PIDPrepareStage, "prepare") as mock_prepare:
                mock_fe.return_value = True
                status = await stage.run(
                    stage_input, wait_for_containers=wait_for_containers)
                mock_prepare.assert_called_with(instance_id, "in", "out", 2,
                                                wait_for_containers, None)

            # Input not ready
            with patch.object(PIDPrepareStage, "files_exist") as mock_fe:
                mock_fe.return_value = False
                status = await stage.run(
                    stage_input, wait_for_containers=wait_for_containers)
                self.assertEqual(PIDStageStatus.FAILED, status)

            # Multiple input paths (invariant exception)
            with patch.object(PIDPrepareStage, "files_exist") as mock_fe:
                with self.assertRaises(ValueError):
                    mock_fe.return_value = True
                    stage_input.input_paths = ["in1", "in2"]
                    stage = PIDPrepareStage(
                        stage=UnionPIDStage.PUBLISHER_PREPARE,
                        instance_repository=mock_instance_repo,
                        storage_svc=mock_storage_svc,
                        onedocker_svc=mock_onedocker_svc,
                        onedocker_binary_config=MagicMock(
                            task_definition="offline-task:1#container",
                            tmp_directory="/tmp/",
                            binary_version="latest",
                        ),
                    )
                    status = await stage.run(
                        stage_input, wait_for_containers=wait_for_containers)

        for data_test in data_test_run():
            wait_for_containers = data_test["wait_for_containers"]
            with self.subTest(
                    "Subtest with wait_for_containers: {wait_for_containers}",
                    wait_for_containers=wait_for_containers,
            ):
                # reset mocks for each subTests
                mock_onedocker_svc.reset_mock()
                mock_instance_repo.reset_mock()
                mock_storage_svc.reset_mock()
                mock_wait_for_containers_async.reset_mock()
                await _run_sub_test(wait_for_containers)