示例#1
0
def test_positive_get_routes():
    """Issue an HTTP GET response to both available routes.

    :id: 9e40ea7f-71ea-4ced-94ba-cde03620c654

    :expectedresults: The same response is returned.

    :BZ: 1132817

    :CaseImportance: Critical
    """
    org = entities.Organization().create()
    entities.SyncPlan(organization=org).create()
    response1 = client.get(
        f'{settings.server.get_url()}/katello/api/v2/sync_plans',
        auth=settings.server.get_credentials(),
        data={'organization_id': org.id},
        verify=False,
    )
    response2 = client.get(
        f'{settings.server.get_url()}/katello/api/v2/organizations/{org.id}/sync_plans',
        auth=settings.server.get_credentials(),
        verify=False,
    )
    for response in (response1, response2):
        response.raise_for_status()
    assert response1.json()['results'] == response2.json()['results']
示例#2
0
    def test_positive_get_routes(self):
        """Issue an HTTP GET response to both available routes.

        @id: 9e40ea7f-71ea-4ced-94ba-cde03620c654

        @Assert: The same response is returned.

        Targets BZ 1132817.
        """
        org = entities.Organization().create()
        entities.SyncPlan(organization=org).create()
        response1 = client.get(
            '{0}/katello/api/v2/sync_plans'.format(settings.server.get_url()),
            auth=settings.server.get_credentials(),
            data={'organization_id': org.id},
            verify=False,
        )
        response2 = client.get(
            '{0}/katello/api/v2/organizations/{1}/sync_plans'.format(
                settings.server.get_url(), org.id),
            auth=settings.server.get_credentials(),
            verify=False,
        )
        for response in (response1, response2):
            response.raise_for_status()
        self.assertEqual(
            response1.json()['results'],
            response2.json()['results'],
        )
示例#3
0
    def test_get_routes(self):
        """@Test: Issue an HTTP GET response to both available routes.

        @Assert: The same response is returned.

        @Feature: SyncPlan

        Targets BZ 1132817.

        """
        org = entities.Organization().create()
        entities.SyncPlan(organization=org).create()
        response1 = client.get(
            '{0}/katello/api/v2/sync_plans'.format(settings.server.get_url()),
            auth=settings.server.get_credentials(),
            data={'organization_id': org.id},
            verify=False,
        )
        response2 = client.get(
            '{0}/katello/api/v2/organizations/{1}/sync_plans'.format(
                settings.server.get_url(),
                org.id
            ),
            auth=settings.server.get_credentials(),
            verify=False,
        )
        for response in (response1, response2):
            response.raise_for_status()
        self.assertEqual(
            response1.json()['results'],
            response2.json()['results'],
        )
示例#4
0
    def test_positive_get_routes(self):
        """Issue an HTTP GET response to both available routes.

        :id: 9e40ea7f-71ea-4ced-94ba-cde03620c654

        :expectedresults: The same response is returned.

        Targets BZ 1132817.

        :CaseImportance: Critical
        """
        org = entities.Organization().create()
        entities.SyncPlan(organization=org).create()
        response1 = client.get(
            '{0}/katello/api/v2/sync_plans'.format(settings.server.get_url()),
            auth=settings.server.get_credentials(),
            data={'organization_id': org.id},
            verify=False,
        )
        response2 = client.get(
            '{0}/katello/api/v2/organizations/{1}/sync_plans'.format(
                settings.server.get_url(),
                org.id
            ),
            auth=settings.server.get_credentials(),
            verify=False,
        )
        for response in (response1, response2):
            response.raise_for_status()
        self.assertEqual(
            response1.json()['results'],
            response2.json()['results'],
        )
    def test_positive_get_status_code(self):
        """GET an entity-dependent path.

        :id: 89e4fafe-7780-4be4-acc1-90f7c02a8530

        :expectedresults: HTTP 200 is returned with an ``application/json``
            content-type

        :CaseImportance: Critical
        """
        exclude_list = (
            entities.ActivationKey,  # need organization_id or environment_id
            entities.ContentView,  # need organization_id
            entities.GPGKey,  # need organization_id
            entities.HostCollection,  # need organization_id
            entities.LifecycleEnvironment,  # need organization_id
            entities.Product,  # need organization_id
            entities.Repository,  # need organization_id
        )
        for entity_cls in set(valid_entities()) - set(exclude_list):
            with self.subTest(entity_cls):
                self.logger.info('test_get_status_code arg: %s', entity_cls)
                skip_if_sam(self, entity_cls)
                response = client.get(
                    entity_cls().path(),
                    auth=settings.server.get_credentials(),
                    verify=False,
                )
                response.raise_for_status()
                self.assertEqual(http_client.OK, response.status_code)
                self.assertIn(
                    'application/json',
                    response.headers['content-type']
                )
示例#6
0
    def test_positive_get_links(self):
        """GET ``api/v2`` and check the links returned.

        :id: 7b2dd77a-a821-485b-94db-b583f93c9a89

        :expectedresults: The paths returned are equal to ``API_PATHS``.

        """
        # Did the server give us any paths at all?
        response = client.get(
            self.path,
            auth=settings.server.get_credentials(),
            verify=False,
        )
        response.raise_for_status()
        # See below for an explanation of this transformation.
        api_paths = response.json()['links']
        for group, path_pairs in api_paths.items():
            api_paths[group] = list(path_pairs.values())

        if bz_bug_is_open(1166875):
            # The server returns incorrect paths.
            api_paths['docker_manifests'].append(
                u'/katello/api/docker_manifests')
            api_paths['docker_manifests'].remove(u'/katello/api/compare')
            api_paths['docker_tags'].append(u'/katello/api/docker_tags')
            api_paths['docker_tags'].remove(u'/katello/api/compare')
            api_paths['errata'].append(u'/katello/api/errata')
            api_paths['errata'].append(u'/katello/api/errata/compare')
            api_paths['errata'].remove(u'/katello/api/compare')

        self.assertEqual(frozenset(api_paths.keys()),
                         frozenset(API_PATHS.keys()))
        for group in api_paths.keys():
            self.assertItemsEqual(api_paths[group], API_PATHS[group], group)
示例#7
0
    def test_get_status_code(self):
        """@Test: GET an entity-dependent path.

        @Feature: Test multiple API paths

        @Assert: HTTP 200 is returned with an ``application/json`` content-type

        """
        exclude_list = (
            entities.ActivationKey,  # need organization_id or environment_id
            entities.ContentView,  # need organization_id
            entities.GPGKey,  # need organization_id
            entities.HostCollection,  # need organization_id
            entities.LifecycleEnvironment,  # need organization_id
            entities.Product,  # need organization_id
            entities.Repository,  # need organization_id
            entities.System,  # need organization_id
        )
        for entity_cls in set(valid_entities()) - set(exclude_list):
            with self.subTest(entity_cls):
                logger.debug('test_get_status_code arg: %s', entity_cls)
                skip_if_sam(self, entity_cls)
                response = client.get(
                    entity_cls().path(),
                    auth=get_server_credentials(),
                    verify=False,
                )
                response.raise_for_status()
                self.assertEqual(httplib.OK, response.status_code)
                self.assertIn(
                    'application/json',
                    response.headers['content-type']
                )
示例#8
0
    def test_positive_get_links(self):
        """GET ``api/v2`` and check the links returned.

        :id: 7b2dd77a-a821-485b-94db-b583f93c9a89

        :expectedresults: The paths returned are equal to ``API_PATHS``.

        """
        # Did the server give us any paths at all?
        response = client.get(
            self.path,
            auth=settings.server.get_credentials(),
            verify=False,
        )
        response.raise_for_status()
        # See below for an explanation of this transformation.
        api_paths = response.json()['links']
        for group, path_pairs in api_paths.items():
            api_paths[group] = list(path_pairs.values())

        self.assertEqual(
            frozenset(api_paths.keys()),
            frozenset(API_PATHS.keys())
        )
        for group in api_paths.keys():
            self.assertItemsEqual(api_paths[group], API_PATHS[group], group)
示例#9
0
    def test_get_releases_status_code(self):
        """@Test: Get an activation key's releases. Check response format.

        @Assert: HTTP 200 is returned with an ``application/json`` content-type

        @Feature: ActivationKey

        """
        try:
            attrs = entities.ActivationKey().create()
        except HTTPError as err:
            self.fail(err)
        path = entities.ActivationKey(id=attrs['id']).path(which='releases')
        response = client.get(
            path,
            auth=get_server_credentials(),
            verify=False,
        )
        status_code = httplib.OK
        self.assertEqual(
            status_code,
            response.status_code,
            status_code_error(path, status_code, response),
        )
        self.assertIn('application/json', response.headers['content-type'])
示例#10
0
    def test_ping(self):
        """@Test: Check if all services are running

        @Feature: Smoke Test

        @Assert: Overall and individual services status should be 'ok'.

        """
        response = client.get(
            entities.Ping().path(),
            auth=get_server_credentials(),
            verify=False,
        )
        response.raise_for_status()
        self.assertEqual(response.json()['status'], u'ok')  # overall status

        # Check that all services are OK. ['services'] is in this format:
        #
        # {u'services': {
        #    u'candlepin': {u'duration_ms': u'40', u'status': u'ok'},
        #    u'candlepin_auth': {u'duration_ms': u'41', u'status': u'ok'},
        #    …
        # }, u'status': u'ok'}
        services = response.json()['services']
        self.assertTrue(
            all([service['status'] == u'ok' for service in services.values()]),
            u"Not all services seem to be up and running!"
        )
示例#11
0
    def test_positive_get_status_code(self):
        """GET an entity-dependent path.

        :id: 89e4fafe-7780-4be4-acc1-90f7c02a8530

        :expectedresults: HTTP 200 is returned with an ``application/json``
            content-type

        :CaseImportance: Critical
        """
        exclude_list = (
            entities.ActivationKey,  # need organization_id or environment_id
            entities.ContentView,  # need organization_id
            entities.GPGKey,  # need organization_id
            entities.HostCollection,  # need organization_id
            entities.LifecycleEnvironment,  # need organization_id
            entities.Product,  # need organization_id
            entities.Repository,  # need organization_id
        )
        for entity_cls in set(valid_entities()) - set(exclude_list):
            with self.subTest(entity_cls):
                self.logger.info('test_get_status_code arg: %s', entity_cls)
                skip_if_sam(self, entity_cls)
                response = client.get(
                    entity_cls().path(),
                    auth=settings.server.get_credentials(),
                    verify=False,
                )
                response.raise_for_status()
                self.assertEqual(http_client.OK, response.status_code)
                self.assertIn('application/json',
                              response.headers['content-type'])
示例#12
0
    def test_positive_build_pxe_default(self, tftpboot):
        """Call the "build_pxe_default" path.

        :id: ca19d9da-1049-4b39-823b-933fc1a0cebd

        :expectedresults: The response is a JSON payload, all templates are deployed to TFTP/HTTP
                          and are rendered correctly

        :CaseLevel: Integration

        :CaseImportance: Critical

        :BZ: 1202564
        """
        response = client.post(
            entities.ProvisioningTemplate().path('build_pxe_default'),
            auth=settings.server.get_credentials(),
            verify=False,
        )
        response.raise_for_status()
        assert type(response.json()) == dict
        for template in tftpboot.values():
            if template['path'].startswith('http'):
                r = client.get(template['path'], verify=False)
                r.raise_for_status()
                rendered = r.text
            else:
                rendered = ssh.command(f"cat {template['path']}").stdout[0]
            assert (rendered == f"{settings.server.scheme}://"
                    f"{settings.server.hostname} {template['kind']}")
    def test_negative_get_unauthorized(self):
        """GET an entity-dependent path without credentials.

        :id: 49127c71-55a2-42d1-b418-59229e9bad00

        :expectedresults: HTTP 401 is returned

        :CaseImportance: Critical
        """
        exclude_list = (
            entities.ActivationKey,  # need organization_id or environment_id
        )
        test_entities = self.get_entities_for_unauthorized(
            valid_entities(), exclude_list)
        for entity_cls in test_entities:
            with self.subTest(entity_cls):
                self.logger.info('test_get_unauthorized arg: %s', entity_cls)
                skip_if_sam(self, entity_cls)
                response = client.get(
                    entity_cls().path(),
                    auth=(),
                    verify=False
                )
                self.assertEqual(
                    http_client.UNAUTHORIZED, response.status_code)
示例#14
0
    def test_get_links(self):
        """@Test: GET ``api/v2`` and check the links returned.

        @Feature: API

        @Assert: The paths returned are equal to ``API_PATHS``.

        """
        # Did the server give us any paths at all?
        response = client.get(self.path, auth=helpers.get_server_credentials(), verify=False)
        response.raise_for_status()
        # See below for an explanation of this transformation.
        api_paths = response.json()["links"]
        for group, path_pairs in api_paths.items():
            api_paths[group] = path_pairs.values()

        if bz_bug_is_open(1166875):
            # The server returns incorrect paths.
            api_paths["docker_images"].append(u"/katello/api/docker_images")
            api_paths["docker_images"].remove(u"/katello/api/compare")
            api_paths["docker_tags"].append(u"/katello/api/docker_tags")
            api_paths["docker_tags"].remove(u"/katello/api/compare")
            api_paths["errata"].append(u"/katello/api/errata")
            api_paths["errata"].append(u"/katello/api/errata/compare")
            api_paths["errata"].remove(u"/katello/api/compare")

        self.assertEqual(frozenset(api_paths.keys()), frozenset(API_PATHS.keys()))
        for group in api_paths.keys():
            self.assertItemsEqual(api_paths[group], API_PATHS[group], group)
示例#15
0
    def test_ping(self):
        """@Test: Check if all services are running

        @Feature: Smoke Test

        @Assert: Overall and individual services status should be 'ok'.

        """
        response = client.get(
            entities.Ping().path(),
            auth=get_server_credentials(),
            verify=False,
        )
        response.raise_for_status()
        self.assertEqual(response.json()['status'], u'ok')  # overall status

        # Check that all services are OK. ['services'] is in this format:
        #
        # {u'services': {
        #    u'candlepin': {u'duration_ms': u'40', u'status': u'ok'},
        #    u'candlepin_auth': {u'duration_ms': u'41', u'status': u'ok'},
        #    …
        # }, u'status': u'ok'}
        services = response.json()['services']
        self.assertTrue(
            all([service['status'] == u'ok' for service in services.values()]),
            u"Not all services seem to be up and running!"
        )
示例#16
0
    def _search(self, entity, query, auth=None):
        """Performs a GET ``api/v2/<entity>`` and specify the ``search``
        parameter.

        :param robottelo.orm.Entity entity: A logical representation of a
            Foreman entity.
        :param string query: A ``search`` parameter.
        :param tuple auth: A ``tuple`` containing the credentials to be used
            for authentication when accessing the API. If ``None``,
            credentials are automatically read from
            :func:`robottelo.common.helpers.get_server_credentials`.
        :return: A ``list`` of found entity dicts or an empty list if nothing
            found
        :rtype: list

        """
        # Use the server credentials if None are provided
        if auth is None:
            auth = get_server_credentials()

        path = entity().path()
        response = client.get(
            path,
            auth=auth,
            data={u'search': query},
            verify=False,
        )
        response.raise_for_status()
        return response.json()['results']
    def test_positive_get_status_code(self):
        """GET an entity-dependent path.

        @Feature: Test multiple API paths

        @Assert: HTTP 200 is returned with an ``application/json`` content-type
        """
        exclude_list = (
            entities.ActivationKey,  # need organization_id or environment_id
            entities.ContentView,  # need organization_id
            entities.GPGKey,  # need organization_id
            entities.HostCollection,  # need organization_id
            entities.LifecycleEnvironment,  # need organization_id
            entities.Product,  # need organization_id
            entities.Repository,  # need organization_id
            entities.System,  # need organization_id
        )
        for entity_cls in set(valid_entities()) - set(exclude_list):
            with self.subTest(entity_cls):
                logger.debug('test_get_status_code arg: %s', entity_cls)
                skip_if_sam(self, entity_cls)
                response = client.get(
                    entity_cls().path(),
                    auth=settings.server.get_credentials(),
                    verify=False,
                )
                response.raise_for_status()
                self.assertEqual(http_client.OK, response.status_code)
                self.assertIn(
                    'application/json',
                    response.headers['content-type']
                )
示例#18
0
    def test_positive_get_links(self):
        """GET ``api/v2`` and check the links returned.

        :id: 7b2dd77a-a821-485b-94db-b583f93c9a89

        :expectedresults: The paths returned are equal to ``API_PATHS``.

        """
        # Did the server give us any paths at all?
        response = client.get(
            self.path,
            auth=settings.server.get_credentials(),
            verify=False,
        )
        response.raise_for_status()
        # See below for an explanation of this transformation.
        api_paths = response.json()['links']
        for group, path_pairs in api_paths.items():
            api_paths[group] = list(path_pairs.values())

        self.assertEqual(
            frozenset(api_paths.keys()),
            frozenset(API_PATHS.keys())
        )
        for group in api_paths.keys():
            self.assertItemsEqual(api_paths[group], API_PATHS[group], group)
示例#19
0
    def _search(self, entity, query, auth=None):
        """Performs a GET ``api/v2/<entity>`` and specify the ``search``
        parameter.

        :param entity: A ``nailgun.entity_mixins.Entity`` object.
        :param string query: A ``search`` parameter.
        :param tuple auth: A ``tuple`` containing the credentials to be used
            for authentication when accessing the API. If ``None``,
            credentials are automatically read from
            :func:`robottelo.common.helpers.get_server_credentials`.
        :return: A ``list`` of found entity dicts or an empty list if nothing
            found
        :rtype: list

        """
        # Use the server credentials if None are provided
        if auth is None:
            auth = get_server_credentials()

        path = entity().path()
        response = client.get(
            path,
            auth=auth,
            data={u'search': query},
            verify=False,
        )
        response.raise_for_status()
        return response.json()['results']
示例#20
0
def get_organization(server_config, label):
    """Return the organization object with label ``label``.

    This function is necessary because NailGun does not yet have a mixin
    facilitating entity searches.

    :param nailgun.config.ServerConfig server_config: This object defines which
        server will be searched, what credentials will be used when searching
        and so on.
    :param label: A string label that will be used when searching. Every
        organization should have a unique label.
    :returns: An ``Organization`` object.

    """
    response = client.get(
        Organization(server_config).path(),
        data={'search': 'label={}'.format(label)},
        **server_config.get_client_kwargs()
    )
    response.raise_for_status()
    decoded = response.json()
    if decoded['subtotal'] != 1:
        print(
            'Expected to find one organization, but instead found {0}. Search '
            'results: {1}'.format(decoded['subtotal'], decoded['results'])
        )
        exit(1)
    return Organization(
        server_config,
        id=decoded['results'][0]['id']
    ).read()
示例#21
0
    def test_subscribe_system_to_cv(self):
        """@Test: Subscribe a system to a content view.

        @Feature: ContentView

        @Assert: It is possible to create a system and set its
        'content_view_id' attribute.

        """
        # organization
        # ├── lifecycle environment
        # └── content view
        org = entities.Organization()
        org.id = org.create()['id']
        lifecycle_env = entities.LifecycleEnvironment(organization=org.id)
        lifecycle_env.id = lifecycle_env.create()['id']
        content_view = entities.ContentView(organization=org.id)
        content_view.id = content_view.create()['id']

        # Publish the content view.
        response = content_view.publish()
        humanized_errors = response['humanized']['errors']
        _check_bz_1186432(humanized_errors)
        self.assertEqual(response['result'], 'success', humanized_errors)

        # Get the content view version's ID.
        response = client.get(
            entities.ContentViewVersion().path(),
            auth=get_server_credentials(),
            data={u'content_view_id': content_view.id},
            verify=False,
        )
        response.raise_for_status()
        results = response.json()['results']
        self.assertEqual(len(results), 1)
        cv_version = entities.ContentViewVersion(id=results[0]['id'])

        # Promote the content view version.
        response = cv_version.promote(environment_id=lifecycle_env.id)
        humanized_errors = response['humanized']['errors']
        _check_bz_1186432(humanized_errors)
        self.assertEqual('success', response['result'], humanized_errors)

        # Create a system that is subscribed to the published and promoted
        # content view. Associating this system with the organization and
        # environment created above is not particularly important, but doing so
        # means a shorter test where fewer entities are created, as
        # System.organization and System.environment are required attributes.
        system_attrs = entities.System(
            content_view=content_view.id,
            environment=lifecycle_env.id,
            organization=org.id,
        ).create()

        # See BZ #1151240
        self.assertEqual(system_attrs['content_view_id'], content_view.id)
        self.assertEqual(system_attrs['environment']['id'], lifecycle_env.id)
        self.assertEqual(system_attrs['organization_id'], org.id)
示例#22
0
    def test_subscribe_system_to_cv(self):
        """@Test: Subscribe a system to a content view.

        @Feature: ContentView

        @Assert: It is possible to create a system and set its
        'content_view_id' attribute.

        """
        # organization
        # ├── lifecycle environment
        # └── content view
        org = entities.Organization()
        org.id = org.create()['id']
        lifecycle_env = entities.LifecycleEnvironment(organization=org.id)
        lifecycle_env.id = lifecycle_env.create()['id']
        content_view = entities.ContentView(organization=org.id)
        content_view.id = content_view.create()['id']

        # Publish the content view.
        response = content_view.publish()
        humanized_errors = response['humanized']['errors']
        _check_bz_1186432(humanized_errors)
        self.assertEqual(response['result'], 'success', humanized_errors)

        # Get the content view version's ID.
        response = client.get(
            entities.ContentViewVersion().path(),
            auth=get_server_credentials(),
            data={u'content_view_id': content_view.id},
            verify=False,
        )
        response.raise_for_status()
        results = response.json()['results']
        self.assertEqual(len(results), 1)
        cv_version = entities.ContentViewVersion(id=results[0]['id'])

        # Promote the content view version.
        response = cv_version.promote(environment_id=lifecycle_env.id)
        humanized_errors = response['humanized']['errors']
        _check_bz_1186432(humanized_errors)
        self.assertEqual('success', response['result'], humanized_errors)

        # Create a system that is subscribed to the published and promoted
        # content view. Associating this system with the organization and
        # environment created above is not particularly important, but doing so
        # means a shorter test where fewer entities are created, as
        # System.organization and System.environment are required attributes.
        system_attrs = entities.System(
            content_view=content_view.id,
            environment=lifecycle_env.id,
            organization=org.id,
        ).create()

        # See BZ #1151240
        self.assertEqual(system_attrs['content_view_id'], content_view.id)
        self.assertEqual(system_attrs['environment']['id'], lifecycle_env.id)
        self.assertEqual(system_attrs['organization_id'], org.id)
示例#23
0
def _poll_task(task_id, server_config, poll_rate=None, timeout=None):
    """Implement :meth:`nailgun.entities.ForemanTask.poll`.

    See :meth:`nailgun.entities.ForemanTask.poll` for a full description of how
    this method acts. Other methods may also call this method, such as
    :meth:`nailgun.entity_mixins.EntityDeleteMixin.delete`.

    Certain mixins benefit from being able to poll the server after performing
    an operation. However, this module cannot use
    :meth:`nailgun.entities.ForemanTask.poll`, as that would be a circular
    import. Placing the implementation of
    :meth:`nailgun.entities.ForemanTask.poll` here allows both that method and
    the mixins in this module to use the same logic.

    """
    if poll_rate is None:
        poll_rate = TASK_POLL_RATE
    if timeout is None:
        timeout = TASK_TIMEOUT

    # Implement the timeout.
    def raise_task_timeout():
        """Raise a KeyboardInterrupt exception in the main thread."""
        thread.interrupt_main()
    timer = threading.Timer(timeout, raise_task_timeout)

    # Poll until the task finishes. The timeout prevents an infinite loop.
    try:
        timer.start()
        path = '{0}/foreman_tasks/api/tasks/{1}'.format(
            server_config.url,
            task_id
        )
        while True:
            response = client.get(path, **server_config.get_client_kwargs())
            response.raise_for_status()
            task_info = response.json()
            if task_info['state'] != 'running':
                break
            time.sleep(poll_rate)
    except KeyboardInterrupt:
        # raise_task_timeout will raise a KeyboardInterrupt when the timeout
        # expires. Catch the exception and raise TaskTimedOutError
        raise TaskTimedOutError('Timed out polling task {0}'.format(task_id))
    finally:
        timer.cancel()

    # Check for task success or failure.
    if task_info['result'] != 'success':
        raise TaskFailedError(
            'Task {0} completed with result {1}. Error message(s): {2}'.format(
                task_id,
                task_info['result'],
                task_info['humanized']['errors']
            )
        )
    return task_info
示例#24
0
    def read_raw(self):
        """Get information about the current entity.

        Make an HTTP PUT call to ``self.path('self')``. Return the response.

        :return: A ``requests.response`` object.

        """
        return client.get(self.path('self'),
                          **self._server_config.get_client_kwargs())
示例#25
0
    def test_get_status_code(self):
        """@Test: GET ``api/v2`` and examine the response.

        @Feature: API

        @Assert: HTTP 200 is returned with an ``application/json`` content-type

        """
        response = client.get(self.path, auth=helpers.get_server_credentials(), verify=False)
        self.assertEqual(response.status_code, httplib.OK)
        self.assertIn("application/json", response.headers["content-type"])
示例#26
0
def _poll_task(task_id, server_config, poll_rate=None, timeout=None):
    """Implement :meth:`nailgun.entities.ForemanTask.poll`.

    See :meth:`nailgun.entities.ForemanTask.poll` for a full description of how
    this method acts. Other methods may also call this method, such as
    :meth:`nailgun.entity_mixins.EntityDeleteMixin.delete`.

    Certain mixins benefit from being able to poll the server after performing
    an operation. However, this module cannot use
    :meth:`nailgun.entities.ForemanTask.poll`, as that would be a circular
    import. Placing the implementation of
    :meth:`nailgun.entities.ForemanTask.poll` here allows both that method and
    the mixins in this module to use the same logic.

    """
    if poll_rate is None:
        poll_rate = TASK_POLL_RATE
    if timeout is None:
        timeout = TASK_TIMEOUT

    # Implement the timeout.
    def raise_task_timeout():  # pragma: no cover
        """Raise a KeyboardInterrupt exception in the main thread."""
        thread.interrupt_main()

    timer = threading.Timer(timeout, raise_task_timeout)

    # Poll until the task finishes. The timeout prevents an infinite loop.
    path = '{0}/foreman_tasks/api/tasks/{1}'.format(server_config.url, task_id)
    try:
        timer.start()
        while True:
            response = client.get(path, **server_config.get_client_kwargs())
            response.raise_for_status()
            task_info = response.json()
            if task_info['state'] in ('paused', 'stopped'):
                break
            time.sleep(poll_rate)
    except KeyboardInterrupt:  # pragma: no cover
        # raise_task_timeout will raise a KeyboardInterrupt when the timeout
        # expires. Catch the exception and raise TaskTimedOutError
        raise TaskTimedOutError(
            'Timed out polling task {0}. Task information: {1}'.format(
                task_id, task_info))
    finally:
        timer.cancel()

    # Check for task success or failure.
    if task_info['result'] != 'success':
        raise TaskFailedError(
            'Task {0} did not succeed. Task information: {1}'.format(
                task_id, task_info))
    return task_info
示例#27
0
    def read_raw(self):
        """Get information about the current entity.

        Make an HTTP PUT call to ``self.path('self')``. Return the response.

        :return: A ``requests.response`` object.

        """
        return client.get(
            self.path('self'),
            **self._server_config.get_client_kwargs()
        )
示例#28
0
    def test_positive_get_status_code(self, api_url):
        """GET ``api/v2`` and examine the response.

        :id: 9d9c1afd-9158-419e-9a6e-91e9888f0c04

        :expectedresults: HTTP 200 is returned with an ``application/json``
            content-type

        """
        response = client.get(api_url, auth=get_credentials(), verify=False)
        assert response.status_code == http.client.OK
        assert 'application/json' in response.headers['content-type']
示例#29
0
    def test_get_unauthorized(self, entity_cls):
        """@Test: GET an entity-dependent path without credentials.

        @Feature: Test multiple API paths

        @Assert: HTTP 401 is returned

        """
        logger.debug('test_get_unauthorized arg: %s', entity_cls)
        skip_if_sam(self, entity_cls)
        response = client.get(entity_cls().path(), auth=(), verify=False)
        self.assertEqual(httplib.UNAUTHORIZED, response.status_code)
示例#30
0
    def test_get_with_no_args(self):
        """@Test: Issue an HTTP GET to the base content view filters path.

        @Feature: ContentViewFilter

        @Assert: An HTTP 400 or 422 response is received if a GET request is
        issued with no arguments specified.

        This test targets bugzilla bug #1102120.

        """
        response = client.get(entities.AbstractContentViewFilter().path(), auth=get_server_credentials(), verify=False)
        self.assertIn(response.status_code, (httplib.BAD_REQUEST, httplib.UNPROCESSABLE_ENTITY))
示例#31
0
文件: orm.py 项目: cswiii/robottelo
def _poll_task(task_id, poll_rate=None, timeout=None, auth=None):
    """Implement :meth:`robottelo.entities.ForemanTask.poll`.

    See :meth:`robottelo.entities.ForemanTask.poll` for a full description of
    how this method acts. Other methods may also call this method, such as
    :meth:`robottelo.orm.EntityDeleteMixin.delete`.

    This function has been placed in this module to keep the import tree sane.
    This function could also be placed in :mod:`robottelo.api.utils`. However,
    doing so precludes :mod:`robottelo.api.utils` from importing
    :mod:`robottelo.entities`, which may be desirable in the future.

    This function is private because only entity mixins should use this.
    :class:`robottelo.entities.ForemanTask` is, for obvious reasons, an
    exception.

    """
    if poll_rate is None:
        poll_rate = TASK_POLL_RATE
    if timeout is None:
        timeout = TASK_TIMEOUT
    if auth is None:
        auth = helpers.get_server_credentials()

    # Implement the timeout.
    def raise_task_timeout():
        """Raise a KeyboardInterrupt exception in the main thread."""
        thread.interrupt_main()

    timer = threading.Timer(timeout, raise_task_timeout)

    # Poll until the task finishes. The timeout prevents an infinite loop.
    try:
        timer.start()

        path = '{0}/foreman_tasks/api/tasks/{1}'.format(
            helpers.get_server_url(), task_id)
        while True:
            response = client.get(path, auth=auth, verify=False)
            response.raise_for_status()
            task_info = response.json()
            if task_info['state'] != 'running':
                return task_info
            time.sleep(poll_rate)
    except KeyboardInterrupt:
        # raise_task_timeout will raise a KeyboardInterrupt when the timeout
        # expires. Catch the exception and raise TaskTimeout
        raise TaskTimeout("Timed out polling task {0}".format(task_id))
    finally:
        timer.cancel()
示例#32
0
    def test_positive_build_pxe_default(self):
        """Call the "build_pxe_default" path.

        @Assert: The response is a JSON payload.

        @Feature: ConfigTemplate
        """
        response = client.get(
            entities.ConfigTemplate().path('build_pxe_default'),
            auth=settings.server.get_credentials(),
            verify=False,
        )
        response.raise_for_status()
        self.assertIsInstance(response.json(), dict)
示例#33
0
    def test_negative_get_unauthorized(self, entity_cls):
        """GET an entity-dependent path without credentials.

        :id: 49127c71-55a2-42d1-b418-59229e9bad00

        :parametrized: yes

        :expectedresults: HTTP 401 is returned

        :CaseImportance: Critical
        """
        logger.info('test_get_unauthorized arg: %s', entity_cls)
        response = client.get(entity_cls().path(), auth=(), verify=False)
        assert http.client.UNAUTHORIZED == response.status_code
示例#34
0
    def test_positive_build_pxe_default(self):
        """Call the "build_pxe_default" path.

        @Assert: The response is a JSON payload.

        @Feature: ConfigTemplate
        """
        response = client.get(
            entities.ConfigTemplate().path('build_pxe_default'),
            auth=settings.server.get_credentials(),
            verify=False,
        )
        response.raise_for_status()
        self.assertIsInstance(response.json(), dict)
示例#35
0
    def test_positive_get_status_code(self):
        """GET ``api/v2`` and examine the response.

        :id: 9d9c1afd-9158-419e-9a6e-91e9888f0c04

        :expectedresults: HTTP 200 is returned with an ``application/json``
            content-type

        """
        response = client.get(self.path,
                              auth=settings.server.get_credentials(),
                              verify=False)
        self.assertEqual(response.status_code, http.client.OK)
        self.assertIn('application/json', response.headers['content-type'])
示例#36
0
    def test_positive_get_status_code(self):
        """GET ``api/v2`` and examine the response.

        @Feature: API

        @Assert: HTTP 200 is returned with an ``application/json`` content-type

        """
        response = client.get(
            self.path,
            auth=settings.server.get_credentials(),
            verify=False,
        )
        self.assertEqual(response.status_code, http_client.OK)
        self.assertIn('application/json', response.headers['content-type'])
    def test_positive_get_releases_content(self):
        """Get an activation key's releases. Check response contents.

        @Assert: A list of results is returned.

        @Feature: ActivationKey
        """
        act_key = entities.ActivationKey().create()
        response = client.get(
            act_key.path('releases'),
            auth=settings.server.get_credentials(),
            verify=False,
        ).json()
        self.assertIn('results', response.keys())
        self.assertEqual(type(response['results']), list)
示例#38
0
    def test_positive_get_status_code(self):
        """GET ``api/v2`` and examine the response.

        @Feature: API

        @Assert: HTTP 200 is returned with an ``application/json`` content-type

        """
        response = client.get(
            self.path,
            auth=settings.server.get_credentials(),
            verify=False,
        )
        self.assertEqual(response.status_code, http_client.OK)
        self.assertIn('application/json', response.headers['content-type'])
示例#39
0
    def read_raw(self):
        """Get information about the current entity.

        Send an HTTP GET request to :meth:`Entity.path`. Return the response.
        Do not check the response for any errors, such as an HTTP 4XX or 5XX
        status code.

        :return: A ``requests.response`` object.

        """
        return client.get(
            self.path('self'),
            auth=self._server_config.auth,
            verify=self._server_config.verify,
        )
    def test_positive_get_releases_content(self):
        """Get an activation key's releases. Check response contents.

        :id: 2fec3d71-33e9-40e5-b934-90b03afc26a1

        :expectedresults: A list of results is returned.

        :CaseLevel: Integration
        """
        act_key = entities.ActivationKey().create()
        response = client.get(
            act_key.path('releases'), auth=settings.server.get_credentials(), verify=False
        ).json()
        self.assertIn('results', response.keys())
        self.assertEqual(type(response['results']), list)
示例#41
0
文件: orm.py 项目: cswiii/robottelo
    def read_raw(self, auth=None):
        """Get information about the current entity.

        Send an HTTP GET request to :meth:`Entity.path`. Return the response.
        Do not check the response for any errors, such as an HTTP 4XX or 5XX
        status code.

        :param tuple auth: A ``(username, password)`` tuple used when accessing
            the API. If ``None``, the credentials provided by
            :func:`robottelo.common.helpers.get_server_credentials` are used.
        :return: A ``requests.response`` object.

        """
        if auth is None:
            auth = helpers.get_server_credentials()
        return client.get(self.path(), auth=auth, verify=False)
示例#42
0
    def test_positive_get_status_code(self):
        """GET ``api/v2`` and examine the response.

        :id: 9d9c1afd-9158-419e-9a6e-91e9888f0c04

        :expectedresults: HTTP 200 is returned with an ``application/json``
            content-type

        """
        response = client.get(
            self.path,
            auth=settings.server.get_credentials(),
            verify=False,
        )
        self.assertEqual(response.status_code, http_client.OK)
        self.assertIn('application/json', response.headers['content-type'])
示例#43
0
    def test_positive_get_search(self):
        """@Test: GET ``api/v2/hosts`` and specify the ``search`` parameter.

        @Feature: Host

        @Assert: HTTP 200 is returned, along with ``search`` term.
        """
        query = gen_string('utf8', gen_integer(1, 100))
        response = client.get(
            entities.Host().path(),
            auth=settings.server.get_credentials(),
            data={u'search': query},
            verify=False,
        )
        self.assertEqual(response.status_code, http_client.OK)
        self.assertEqual(response.json()['search'], query)
    def test_positive_get_releases_status_code(self):
        """Get an activation key's releases. Check response format.

        :id: e1ea4797-8d92-4bec-ae6b-7a26599825ab

        :expectedresults: HTTP 200 is returned with an ``application/json``
            content-type

        :CaseLevel: Integration
        """
        act_key = entities.ActivationKey().create()
        path = act_key.path('releases')
        response = client.get(path, auth=settings.server.get_credentials(), verify=False)
        status_code = http.client.OK
        self.assertEqual(status_code, response.status_code)
        self.assertIn('application/json', response.headers['content-type'])
示例#45
0
    def test_positive_build_pxe_default(self):
        """Call the "build_pxe_default" path.

        :id: ca19d9da-1049-4b39-823b-933fc1a0cebd

        :expectedresults: The response is a JSON payload.

        :CaseLevel: Integration
        """
        response = client.get(
            entities.ConfigTemplate().path('build_pxe_default'),
            auth=settings.server.get_credentials(),
            verify=False,
        )
        response.raise_for_status()
        self.assertIsInstance(response.json(), dict)
    def test_negative_get_with_no_args(self):
        """Issue an HTTP GET to the base content view filters path.

        :id: da29fd90-cd96-49f9-b94e-71d4e3a35a57

        :expectedresults: An HTTP 200 response is received if a GET request is
            issued with no arguments specified.

        :CaseLevel: Integration
        """
        response = client.get(
            entities.AbstractContentViewFilter().path(),
            auth=settings.server.get_credentials(),
            verify=False,
        )
        self.assertEqual(response.status_code, http_client.OK)
    def test_negative_get_unauthorized(self):
        """GET an entity-dependent path without credentials.

        :id: 49127c71-55a2-42d1-b418-59229e9bad00

        :expectedresults: HTTP 401 is returned

        :CaseImportance: Critical
        """
        exclude_list = (entities.ActivationKey,)  # need organization_id or environment_id
        test_entities = self.get_entities_for_unauthorized(valid_entities(), exclude_list)
        for entity_cls in test_entities:
            with self.subTest(entity_cls):
                self.logger.info('test_get_unauthorized arg: %s', entity_cls)
                response = client.get(entity_cls().path(), auth=(), verify=False)
                self.assertEqual(http.client.UNAUTHORIZED, response.status_code)
示例#48
0
    def test_positive_build_pxe_default(self):
        """Call the "build_pxe_default" path.

        :id: ca19d9da-1049-4b39-823b-933fc1a0cebd

        :expectedresults: The response is a JSON payload.

        :CaseLevel: Integration
        """
        response = client.get(
            entities.ConfigTemplate().path('build_pxe_default'),
            auth=settings.server.get_credentials(),
            verify=False,
        )
        response.raise_for_status()
        self.assertIsInstance(response.json(), dict)
    def test_negative_get_with_no_args(self):
        """Issue an HTTP GET to the base content view filters path.

        :id: da29fd90-cd96-49f9-b94e-71d4e3a35a57

        :expectedresults: An HTTP 200 response is received if a GET request is
            issued with no arguments specified.

        :CaseLevel: Integration
        """
        response = client.get(
            entities.AbstractContentViewFilter().path(),
            auth=settings.server.get_credentials(),
            verify=False,
        )
        self.assertEqual(response.status_code, http_client.OK)
示例#50
0
    def test_positive_get_per_page(self):
        """GET ``api/v2/hosts`` and specify the ``per_page`` parameter.

        @id: 9086f41c-b3b9-4af2-b6c4-46b80b4d1cfd

        @Assert: HTTP 200 is returned, along with per ``per_page`` value.
        """
        per_page = gen_integer(1, 1000)
        response = client.get(
            entities.Host().path(),
            auth=settings.server.get_credentials(),
            data={u'per_page': per_page},
            verify=False,
        )
        self.assertEqual(response.status_code, http_client.OK)
        self.assertEqual(response.json()['per_page'], per_page)
示例#51
0
    def test_positive_get_search(self):
        """GET ``api/v2/hosts`` and specify the ``search`` parameter.

        @id: d63f87e5-66e6-4886-8b44-4129259493a6

        @Assert: HTTP 200 is returned, along with ``search`` term.
        """
        query = gen_string('utf8', gen_integer(1, 100))
        response = client.get(
            entities.Host().path(),
            auth=settings.server.get_credentials(),
            data={u'search': query},
            verify=False,
        )
        self.assertEqual(response.status_code, http_client.OK)
        self.assertEqual(response.json()['search'], query)
示例#52
0
    def test_positive_get_per_page(self):
        """@Test: GET ``api/v2/hosts`` and specify the ``per_page`` parameter.

        @Feature: Host

        @Assert: HTTP 200 is returned, along with per ``per_page`` value.
        """
        per_page = gen_integer(1, 1000)
        response = client.get(
            entities.Host().path(),
            auth=settings.server.get_credentials(),
            data={u'per_page': per_page},
            verify=False,
        )
        self.assertEqual(response.status_code, http_client.OK)
        self.assertEqual(response.json()['per_page'], per_page)
示例#53
0
    def test_positive_get_releases_content(self):
        """Get an activation key's releases. Check response contents.

        :id: 2fec3d71-33e9-40e5-b934-90b03afc26a1

        :expectedresults: A list of results is returned.

        :CaseLevel: Integration
        """
        act_key = entities.ActivationKey().create()
        response = client.get(
            act_key.path('releases'),
            auth=settings.server.get_credentials(),
            verify=False,
        ).json()
        self.assertIn('results', response.keys())
        self.assertEqual(type(response['results']), list)
    def test_positive_get_releases_status_code(self):
        """Get an activation key's releases. Check response format.

        @Assert: HTTP 200 is returned with an ``application/json`` content-type

        @Feature: ActivationKey
        """
        act_key = entities.ActivationKey().create()
        path = act_key.path('releases')
        response = client.get(
            path,
            auth=settings.server.get_credentials(),
            verify=False,
        )
        status_code = http_client.OK
        self.assertEqual(status_code, response.status_code)
        self.assertIn('application/json', response.headers['content-type'])
    def test_negative_get_with_bad_args(self):
        """Issue an HTTP GET to the base content view filters path.

        :id: e6fea726-930b-4b74-b784-41528811994f

        :expectedresults: An HTTP 200 response is received if a GET request is
            issued with bad arguments specified.

        :CaseLevel: Integration
        """
        response = client.get(
            entities.AbstractContentViewFilter().path(),
            auth=settings.server.get_credentials(),
            verify=False,
            data={'foo': 'bar'},
        )
        self.assertEqual(response.status_code, http_client.OK)
    def test_negative_get_with_bad_args(self):
        """Issue an HTTP GET to the base content view filters path.

        :id: e6fea726-930b-4b74-b784-41528811994f

        :expectedresults: An HTTP 200 response is received if a GET request is
            issued with bad arguments specified.

        :CaseLevel: Integration
        """
        response = client.get(
            entities.AbstractContentViewFilter().path(),
            auth=settings.server.get_credentials(),
            verify=False,
            data={'foo': 'bar'},
        )
        self.assertEqual(response.status_code, http_client.OK)
示例#57
0
    def test_get_status_code(self):
        """@Test: Create a system and GET it.

        @Feature: System APIs

        @Assert: HTTP 200 is returned with an ``application/json`` content-type

        """
        system = System(uuid=System().create_json()['uuid'])
        logger.debug('system uuid: {0}'.format(system.uuid))
        response = client.get(
            system.path(),
            auth=get_server_credentials(),
            verify=False,
        )
        self.assertEqual(httplib.OK, response.status_code)
        self.assertIn('application/json', response.headers['content-type'])
    def test_get_all(self):
        """@Test: Get ``katello/api/v2/environments`` and specify just an
        organization ID.

        @Feature: LifecycleEnvironment

        @Assert: HTTP 200 is returned with an ``application/json`` content-type

        """
        org_attrs = entities.Organization().create()
        response = client.get(
            entities.LifecycleEnvironment().path(),
            auth=get_server_credentials(),
            data={u'organization_id': org_attrs['id']},
            verify=False,
        )
        self.assertEqual(response.status_code, httplib.OK)
        self.assertIn('application/json', response.headers['content-type'])