示例#1
0
    def test_bad_target_request(
        self,
        high_quality_image: io.BytesIO,
        vws_client: VWS,
    ) -> None:
        """
        The ``request_usage`` count does not increase with each request to the
        target API, even if it is a bad request.
        """
        report = vws_client.get_database_summary_report()
        original_request_usage = report.request_usage

        with pytest.raises(Fail) as exc:
            vws_client.add_target(
                name='example',
                width=-1,
                image=high_quality_image,
                active_flag=True,
                application_metadata=None,
            )

        assert exc.value.response.status_code == HTTPStatus.BAD_REQUEST

        report = vws_client.get_database_summary_report()
        new_request_usage = report.request_usage
        assert new_request_usage == original_request_usage
示例#2
0
    def test_query_request(
        self,
        cloud_reco_client: CloudRecoService,
        high_quality_image: io.BytesIO,
        vws_client: VWS,
    ) -> None:
        """
        The ``*_recos`` counts seem to be delayed by a significant amount of
        time.

        We therefore test that they exist, are integers and do not change
        between quick requests.
        """
        target_id = vws_client.add_target(
            name=uuid.uuid4().hex,
            width=1,
            image=high_quality_image,
            active_flag=True,
            application_metadata=None,
        )
        vws_client.wait_for_target_processed(target_id=target_id)

        report_before = vws_client.get_database_summary_report()
        cloud_reco_client.query(image=high_quality_image)

        report_after = vws_client.get_database_summary_report()
        assert report_before.total_recos == report_after.total_recos
        assert (report_before.current_month_recos ==
                report_after.current_month_recos)
        assert (report_before.previous_month_recos ==
                report_after.previous_month_recos)
示例#3
0
 def test_inactive_project(
     self,
     inactive_vws_client: VWS,
 ) -> None:
     """
     The project's active state does not affect the database summary.
     """
     inactive_vws_client.get_database_summary_report()
示例#4
0
    def test_target_request(
        self,
        vws_client: VWS,
    ) -> None:
        """
        The ``request_usage`` count does not increase with each request to the
        target API.
        """
        report = vws_client.get_database_summary_report()
        original_request_usage = report.request_usage

        report = vws_client.get_database_summary_report()
        new_request_usage = report.request_usage
        assert new_request_usage == original_request_usage
示例#5
0
 def test_query_request(
     self,
     cloud_reco_client: CloudRecoService,
     high_quality_image: io.BytesIO,
     vws_client: VWS,
 ) -> None:
     """
     The ``request_usage`` count does not increase with each query.
     """
     report = vws_client.get_database_summary_report()
     original_request_usage = report.request_usage
     cloud_reco_client.query(image=high_quality_image)
     report = vws_client.get_database_summary_report()
     new_request_usage = report.request_usage
     # The request usage goes up for the database summary request, not the
     # query.
     assert new_request_usage == original_request_usage
示例#6
0
    def test_custom_seconds_between_requests(
        self,
        high_quality_image: io.BytesIO,
    ) -> None:
        """
        It is possible to customize the time waited between polling requests.
        """
        runner = CliRunner()
        with MockVWS(processing_time_seconds=0.5) as mock:
            mock_database = VuforiaDatabase()
            mock.add_database(database=mock_database)
            vws_client = VWS(
                server_access_key=mock_database.server_access_key,
                server_secret_key=mock_database.server_secret_key,
            )

            target_id = vws_client.add_target(
                name='x',
                width=1,
                image=high_quality_image,
                active_flag=True,
                application_metadata=None,
            )

            commands = [
                'wait-for-target-processed',
                '--target-id',
                target_id,
                '--seconds-between-requests',
                '0.3',
                '--server-access-key',
                mock_database.server_access_key,
                '--server-secret-key',
                mock_database.server_secret_key,
            ]
            result = runner.invoke(vws_group, commands, catch_exceptions=False)
            assert result.exit_code == 0
            assert result.stdout == ''
            report = vws_client.get_database_summary_report()
            expected_requests = (
                # Add target request
                1 +
                # Database summary request
                1 +
                # Initial request
                1 +
                # Request after 0.3 seconds - not processed
                # This assumes that there is less than 0.2 seconds taken
                # between the start of the target processing and the start of
                # waiting for the target to be processed.
                1 +
                # Request after 0.6 seconds - processed
                1)
            # At the time of writing there is a bug which prevents request
            # usage from being tracked so we cannot track this.
            expected_requests = 0
            assert report.request_usage == expected_requests
示例#7
0
 def test_quotas(self, vws_client: VWS) -> None:
     """
     Quotas are included in the database summary.
     These match the quotas given for a free license.
     """
     report = vws_client.get_database_summary_report()
     assert report.target_quota == 1000
     assert report.request_quota == 100000
     assert report.reco_threshold == 1000
示例#8
0
    def test_custom_seconds_between_requests(
        self,
        high_quality_image: io.BytesIO,
    ) -> None:
        """
        It is possible to customize the time waited between polling requests.
        """
        with MockVWS(processing_time_seconds=0.5) as mock:
            database = VuforiaDatabase()
            mock.add_database(database=database)
            vws_client = VWS(
                server_access_key=database.server_access_key,
                server_secret_key=database.server_secret_key,
            )

            target_id = vws_client.add_target(
                name='x',
                width=1,
                image=high_quality_image,
                active_flag=True,
                application_metadata=None,
            )

            vws_client.wait_for_target_processed(
                target_id=target_id,
                seconds_between_requests=0.3,
            )
            report = vws_client.get_database_summary_report()
            expected_requests = (
                # Add target request
                1
                +
                # Database summary request
                1
                +
                # Initial request
                1
                +
                # Request after 0.3 seconds - not processed
                # This assumes that there is less than 0.2 seconds taken
                # between the start of the target processing and the start of
                # waiting for the target to be processed.
                1
                +
                # Request after 0.6 seconds - processed
                1
            )
            # At the time of writing there is a bug which prevents request
            # usage from being tracked so we cannot track this.
            expected_requests = 0
            assert report.request_usage == expected_requests
示例#9
0
    def test_success(
        self,
        vuforia_database: VuforiaDatabase,
        vws_client: VWS,
    ) -> None:
        """
        It is possible to get a success response.
        """
        report = vws_client.get_database_summary_report()
        assert report.name == vuforia_database.database_name

        _wait_for_image_numbers(
            vws_client=vws_client,
            active_images=0,
            inactive_images=0,
            failed_images=0,
            processing_images=0,
        )
示例#10
0
def get_database_summary_report(
    server_access_key: str,
    server_secret_key: str,
    base_vws_url: str,
) -> None:
    """
    Get a database summary report.

    \b
    See
    https://library.vuforia.com/articles/Solution/How-To-Use-the-Vuforia-Web-Services-API.html#How-To-Get-a-Database-Summary-Report.
    """
    vws_client = VWS(
        server_access_key=server_access_key,
        server_secret_key=server_secret_key,
        base_vws_url=base_vws_url,
    )
    report = vws_client.get_database_summary_report()
    yaml_report = yaml.dump(dataclasses.asdict(report))
    click.echo(yaml_report)
示例#11
0
    def test_get_target(self, vws_client: VWS) -> None:
        """
        Details of a database are returned by ``get_database_summary_report``.
        """
        report = vws_client.get_database_summary_report()

        expected_report = DatabaseSummaryReport(
            active_images=0,
            current_month_recos=0,
            failed_images=0,
            inactive_images=0,
            name=report.name,
            previous_month_recos=0,
            processing_images=0,
            reco_threshold=1000,
            request_quota=100000,
            request_usage=0,
            target_quota=1000,
            total_recos=0,
        )
        assert report == expected_report
示例#12
0
def _wait_for_image_numbers(
    vws_client: VWS,
    active_images: int,
    inactive_images: int,
    failed_images: int,
    processing_images: int,
) -> None:
    """
    Wait up to 500 seconds (arbitrary, though we saw timeouts with 300 seconds)
    for the number of images in various categories to match the expected
    number.

    This is necessary because the database summary endpoint lags behind the
    real data.

    This is susceptible to false positives because if, for example, we expect
    no images, and the endpoint adds images with a delay, we will not know.

    Args:
        vws_client: The client to use to connect to Vuforia.
        active_images: The expected number of active images.
        inactive_images: The expected number of inactive images.
        failed_images: The expected number of failed images.
        processing_images: The expected number of processing images.

    Raises:
        Exception: The numbers of images in various categories do not match
            within the time limit.
    """
    requirements = {
        'active_images': active_images,
        'inactive_images': inactive_images,
        'failed_images': failed_images,
        'processing_images': processing_images,
    }

    maximum_wait_seconds = 500
    start_time = time.monotonic()

    # If we wait for all requirements to match at the same time,
    # we will often not reach that.
    # We therefore wait for each requirement to match at least once.

    # We wait 0.2 seconds rather than less than that to decrease the number
    # of calls made to the API, to decrease the likelihood of hitting the
    # request quota.
    sleep_seconds = 0.2

    for key, value in requirements.items():
        while True:
            seconds_waited = time.monotonic() - start_time
            if seconds_waited > maximum_wait_seconds:  # pragma: no cover
                raise Exception('Timed out waiting.')

            report = vws_client.get_database_summary_report()
            relevant_images_in_summary = getattr(report, key)
            if value != relevant_images_in_summary:  # pragma: no cover
                message = (f'Expected {value} `{key}`s. '
                           f'Found {relevant_images_in_summary} `{key}`s.')
                LOGGER.debug(message)

                time.sleep(sleep_seconds)

            # This makes the entire test invalid.
            # However, we have found that without this Vuforia is flaky.
            # We have waited over 10 minutes for the summary to change and
            # that is not sustainable in a test suite.
            break