Ejemplo n.º 1
0
    def test_post_and_get(self):
        """@Test Issue a POST request and GET the created system.

        @Assert: The created system has the correct attributes.

        """
        # Generate some attributes and use them to create a system.
        gen_attrs = System().build()
        response = client.post(
            System().path(),
            gen_attrs,
            auth=get_server_credentials(),
            verify=False,
        )
        path = System(uuid=response.json()['uuid']).path()
        self.assertIn(
            response.status_code, (httplib.OK, httplib.CREATED), path
        )

        # Get the just-created system and examine its attributes.
        real_attrs = client.get(
            path,
            auth=get_server_credentials(),
            verify=False,
        ).json()
        for key, value in gen_attrs.items():
            self.assertIn(key, real_attrs.keys(), path)
            self.assertEqual(
                value, real_attrs[key], '{0} {1}'.format(key, path)
            )
Ejemplo n.º 2
0
    def create_raw(self, auth=None, create_missing=True):
        """Create an entity.

        Generate values for required, unset fields by calling
        :meth:`create_missing`. Only do this if ``create_missing`` is true.
        Then make an HTTP POST call to ``self.path('base')``. Return the
        response received from the server.

        :param tuple auth: A ``(username, password)`` pair to use when
            communicating with the API. If ``None``, the credentials returned
            by :func:`robottelo.common.helpers.get_server_credentials` are
            used.
        :param bool create_missing: Should :meth:`create_missing` be called? In
            other words, should values be generated for required, empty fields?
        :return: A ``requests.response`` object.

        """
        if auth is None:
            auth = helpers.get_server_credentials()
        if create_missing:
            self.create_missing(auth)
        return client.post(
            self.path('base'),
            self.create_payload(),
            auth=auth,
            verify=False,
        )
Ejemplo n.º 3
0
    def test_post_hash(self):
        """@Test: Do not wrap API calls in an extra hash.

        @Assert: It is possible to associate an activation key with an
        organization.

        @Feature: Architecture

        """
        name = gen_utf8()
        os_id = entities.OperatingSystem().create()['id']
        response = client.post(
            entities.Architecture().path(),
            {u'name': name, u'operatingsystem_ids': [os_id]},
            auth=get_server_credentials(),
            verify=False,
        )
        response.raise_for_status()
        attrs = response.json()

        # The server will accept some POSTed attributes (name) and silently
        # ignore others (operatingsystem_ids).
        self.assertIn('name', attrs)
        self.assertEqual(name, attrs['name'])
        self.assertIn('operatingsystems', attrs)
        self.assertEqual([os_id], attrs['operatingsystems'])
Ejemplo n.º 4
0
    def test_positive_create_1(self, login):
        """
        @Test Create a user providing the initial login name.
        @Assert: User is created and contains provided login name.
        @Feature: User
        """
        path = entities.User().path()
        attrs = entities.User(login=login).build()
        response = client.post(
            path,
            attrs,
            auth=get_server_credentials(),
            verify=False,
        )
        status_code = (httplib.OK, httplib.CREATED)
        self.assertIn(
            response.status_code,
            status_code,
            status_code_error(path, status_code, response),
        )

        # Fetch the user
        real_attrs = client.get(
            entities.User(id=response.json()['id']).path(),
            auth=get_server_credentials(),
            verify=False,
        ).json()
        # Remove the ``password`` field from ``attrs`` since it isn't
        # returned by GET.
        attrs.pop('password')
        # Assert that keys and values match
        for key, value in attrs.items():
            self.assertIn(key, real_attrs.keys())
            self.assertEqual(value, real_attrs[key])
Ejemplo n.º 5
0
    def test_post_and_get(self, entity):
        """@Test Issue a POST request and GET the created entity.

        @Assert: The created entity has the correct attributes.

        """
        if entity in BZ_1122267_ENTITIES and bz_bug_is_open(1122267):
            self.skipTest("Bugzilla bug 1122267 is open.""")
        if entity is entities.AuthSourceLDAP and bz_bug_is_open(1140313):
            self.skipTest("Bugzilla bug 1140313 is open.""")

        # Generate some attributes and use them to create an entity.
        gen_attrs = entity().build()
        response = client.post(
            entity().path(),
            gen_attrs,
            auth=get_server_credentials(),
            verify=False,
        )
        response.raise_for_status()

        # Get the just-created entity and examine its attributes.
        entity_n = entity(id=response.json()['id'])
        logger.info('test_post_and_get path: {0}'.format(entity_n.path()))
        real_attrs = entity_n.read_json()
        for key, value in gen_attrs.items():
            self.assertIn(key, real_attrs.keys())
            self.assertEqual(value, real_attrs[key], key)
Ejemplo n.º 6
0
    def test_post_status_code(self, entity):
        """@Test: Issue a POST request and check the returned status code.

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

        """
        # Some arguments are "normal" classes and others are objects produced
        # by functools.partial. Also, `partial(SomeClass).func == SomeClass`.
        if ((entity.func if isinstance(entity, partial) else entity) in
                BZ_1118015_ENTITIES and bz_bug_is_open(1118015)):
            self.skipTest('Bugzilla bug 1118015 is open.')
        path = entity().path()
        response = client.post(
            path,
            entity().build(),
            auth=get_server_credentials(),
            verify=False,
        )
        status_code = httplib.CREATED
        self.assertEqual(
            status_code,
            response.status_code,
            status_code_error(path, status_code, response),
        )
        self.assertIn('application/json', response.headers['content-type'])
Ejemplo n.º 7
0
    def test_post_and_get(self, entity):
        """@Test Issue a POST request and GET the created entity.

        @Assert: The created entity has the correct attributes.

        """
        if entity in BZ_1122267_ENTITIES and bz_bug_is_open(1122267):
            self.skipTest("Bugzilla bug 1122267 is open.""")
        # Generate some attributes and use them to create an entity.
        gen_attrs = entity().build()
        response = client.post(
            entity().path(),
            gen_attrs,
            auth=get_server_credentials(),
            verify=False,
        )
        path = entity(id=response.json()['id']).path()
        self.assertIn(
            response.status_code, (httplib.OK, httplib.CREATED), path
        )

        # Get the just-created entity and examine its attributes.
        real_attrs = client.get(
            path,
            auth=get_server_credentials(),
            verify=False,
        ).json()
        for key, value in gen_attrs.items():
            self.assertIn(key, real_attrs.keys(), path)
            self.assertEqual(
                value, real_attrs[key], '{0} {1}'.format(key, path)
            )
Ejemplo n.º 8
0
    def test_update_contents(self):
        """@Test: Create a repository and upload RPM contents.

        @Assert: The repository's contents include one RPM.

        @Feature: Repository

        """
        # Create a repository and upload RPM content.
        repo_id = entities.Repository(product=self.prod_id).create()['id']
        client.post(
            entities.Repository(id=repo_id).path(which='upload_content'),
            {},
            auth=get_server_credentials(),
            files={u'content': open(get_data_file(RPM_TO_UPLOAD), 'rb')},
            verify=False,
        ).raise_for_status()

        # Verify the repository's contents.
        attrs = entities.Repository(id=repo_id).read_json()
        self.assertEqual(attrs[u'content_counts'][u'rpm'], 1)
Ejemplo n.º 9
0
    def test_post_unauthorized(self, entity):
        """@Test: POST to an entity-dependent path without credentials.

        @Assert: HTTP 401 is returned

        """
        path = entity().path()
        response = client.post(path, verify=False)
        status_code = httplib.UNAUTHORIZED
        self.assertEqual(
            status_code,
            response.status_code,
            status_code_error(path, status_code, response),
        )
Ejemplo n.º 10
0
    def test_create_text_plain(self):
        """@Test Create an organization using a 'text/plain' content-type.

        @Assert: HTTP 415 is returned.

        @Feature: Organization

        """
        organization = entities.Organization()
        organization.create_missing()
        response = client.post(
            organization.path(),
            organization.create_payload(),
            auth=get_server_credentials(),
            headers={'content-type': 'text/plain'},
            verify=False,
        )
        self.assertEqual(httplib.UNSUPPORTED_MEDIA_TYPE, response.status_code)
Ejemplo n.º 11
0
    def setup_to_create_cv(self, session, cv_name, repo_name=None,
                           repo_url=None, repo_type=None):
        """Create product/repo and sync it and create CV"""
        cv_name = cv_name or generate_string("alpha", 8)
        repo_name = repo_name or generate_string("alpha", 8)
        repo_url = repo_url or FAKE_1_YUM_REPO
        repo_type = repo_type or REPO_TYPE['yum']

        # Creates new product and repository via API's
        product_attrs = entities.Product(
            organization=self.org_id
        ).create()

        repo_attrs = entities.Repository(
            name=repo_name,
            url=repo_url,
            content_type=repo_type,
            product=product_attrs['id'],
        ).create()

        # Sync repository
        response = client.post(
            entities.Repository(id=repo_attrs['id']).path('sync'),
            {
                u'ids': [repo_attrs['id']],
                u'organization_id': self.org_id
            },
            auth=get_server_credentials(),
            verify=False,
        ).json()
        self.assertGreater(
            len(response['id']),
            1,
            u"Was not able to fetch a task ID.")
        task_status = entities.ForemanTask(id=response['id']).poll()
        self.assertEqual(
            task_status['result'],
            u'success',
            u"Sync for repository {0} failed.".format(repo_attrs['name']))
        make_contentview(session, org=self.org_name, name=cv_name)
        self.assertIsNotNone(self.content_views.search(cv_name))
Ejemplo n.º 12
0
    def test_positive_update_5(self):
        """@Test: Create a repository and upload rpm contents

        @Feature: Repositories

        @Assert: Repository is updated with contents

        """
        # Create a repository and upload an RPM file.
        attrs = entities.Repository(url=FAKE_1_YUM_REPO).create()
        response = client.post(
            entities.Repository(id=attrs['id']).path(which='upload_content'),
            {},
            auth=get_server_credentials(),
            files={u'content': open(get_data_file(RPM_TO_UPLOAD), 'rb')},
            verify=False,
        )
        response.raise_for_status()

        # Fetch info about the updated repo and verify the file was uploaded.
        attrs = entities.Repository(id=attrs['id']).read_json()
        self.assertEqual(attrs[u'content_counts'][u'rpm'], 1)
Ejemplo n.º 13
0
    def test_post_status_code(self, entity):
        """@Test: Issue a POST request and check the returned status code.

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

        """
        if entity in BZ_1118015_ENTITIES and bz_bug_is_open(1118015):
            self.skipTest("Bugzilla bug 1118015 is open.""")
        path = entity().path()
        response = client.post(
            path,
            entity().build(),
            auth=get_server_credentials(),
            verify=False,
        )
        status_code = httplib.CREATED
        self.assertEqual(
            status_code,
            response.status_code,
            status_code_error(path, status_code, response),
        )
        self.assertIn('application/json', response.headers['content-type'])
Ejemplo n.º 14
0
    def create(self, auth=None):
        """Create a new entity, plus all of its dependent entities.

        Create an entity at the path returned by :meth:`Factory._factory_path`.
        If necessary, recursively create dependent entities. When done, return
        a dict of information about the newly created entity.

        :param tuple auth: A ``(username, password)`` pair to use when
            communicating with the API. If ``None``, the credentials returned
            by :func:`robottelo.common.helpers.get_server_credentials` are
            used.
        :return: Information about the newly created entity.
        :rtype: dict
        :raises robottelo.factory.FactoryError: If the server returns an error
            when attempting to create an entity.

        """
        if auth is None:
            auth = get_server_credentials()

        # Create dependent entities and generate values for non-FK fields.
        values = self.build(auth)

        # Create the current entity.
        path = urljoin(get_server_url(), self._factory_path())
        response = client.post(path, values, auth=auth, verify=False).json()
        if 'error' in response.keys() or 'errors' in response.keys():
            if 'error' in response.keys():
                message = response['error']
            else:
                message = response['errors']
            raise FactoryError(
                'Error encountered while POSTing to {0}. Error received: {1}'
                ''.format(path, message)
            )

        # Tell caller about created entity.
        return response
Ejemplo n.º 15
0
    def test_create_text_plain(self):
        """@Test Create an organization using a 'text/plain' content-type.

        @Assert: HTTP 415 is returned.

        @Feature: Organization

        """
        path = entities.Organization().path()
        attrs = entities.Organization().build()
        response = client.post(
            path,
            attrs,
            auth=get_server_credentials(),
            headers={'content-type': 'text/plain'},
            verify=False,
        )
        status_code = httplib.UNSUPPORTED_MEDIA_TYPE
        self.assertEqual(
            status_code,
            response.status_code,
            status_code_error(path, status_code, response),
        )
Ejemplo n.º 16
0
    def test_smoke(self):
        """
        @Test: Check that basic content can be created

        1. Create a new user with admin permissions
        2. Using the new user from above:
            1. Create a new organization
            2. Create two new lifecycle environments
            3. Create a custom product
            4. Create a custom YUM repository
            5. Create a custom PUPPET repository
            6. Synchronize both custom repositories
            7. Create a new content view
            8. Associate both repositories to new content view
            9. Publish content view
            10. Promote content view to both lifecycles
            11. Create a new libvirt compute resource
            12. Create a new subnet
            13. Create a new domain
            14. Create a new hostgroup and associate previous entities to it

        @Feature: Smoke Test

        @Assert: All entities are created and associated.
        """
        # prep work
        #
        # FIXME: Use a larger charset when authenticating users.
        #
        # It is possible to create a user with a wide range of characters. (see
        # the "User" entity). However, Foreman supports only HTTP Basic
        # authentication, and the requests lib enforces the latin1 charset in
        # this auth mode. We then further restrict ourselves to the
        # alphanumeric charset, because Foreman complains about incomplete
        # multi-byte chars when latin1 chars are used.
        #
        login = orm.StringField(str_type=('alphanumeric',)).get_value()
        password = orm.StringField(str_type=('alphanumeric',)).get_value()

        # step 1: Create a new user with admin permissions
        entities.User(admin=True, login=login, password=password).create()

        # step 2.1: Create a new organization
        org = entities.Organization().create(auth=(login, password))

        # step 2.2: Create 2 new lifecycle environments
        le1 = entities.LifecycleEnvironment(organization=org['id']).create()
        le2 = entities.LifecycleEnvironment(
            organization=org['id'], prior=le1['id']).create()

        # step 2.3: Create a custom product
        prod = entities.Product(organization=org['id']).create()

        # step 2.4: Create custom YUM repository
        repo1 = entities.Repository(
            product=prod['id'],
            content_type=u'yum',
            url=GOOGLE_CHROME_REPO
        ).create()

        # step 2.5: Create custom PUPPET repository
        repo2 = entities.Repository(
            product=prod['id'],
            content_type=u'puppet',
            url=FAKE_PUPPET_REPO
        ).create()

        # step 2.6: Synchronize both repositories
        for repo in [repo1, repo2]:
            response = client.post(
                entities.Repository(id=repo['id']).path('sync'),
                {
                    u'ids': [repo['id']],
                    u'organization_id': org['id']
                },
                auth=get_server_credentials(),
                verify=False,
            ).json()
            self.assertGreater(
                len(response['id']),
                1,
                u"Was not able to fetch a task ID.")
            task_status = entities.ForemanTask(id=response['id']).poll()
            self.assertEqual(
                task_status['result'],
                u'success',
                u"Sync for repository {0} failed.".format(repo['name']))

        # step 2.7: Create content view
        content_view = entities.ContentView(organization=org['id']).create()

        # step 2.8: Associate YUM repository to new content view
        response = client.put(
            entities.ContentView(id=content_view['id']).path(),
            auth=get_server_credentials(),
            verify=False,
            data={u'repository_ids': [repo1['id']]})

        # Fetch all available puppet modules
        puppet_mods = client.get(
            entities.ContentView(id=content_view['id']).path(
                'available_puppet_module_names'),
            auth=get_server_credentials(),
            verify=False).json()
        self.assertGreater(
            puppet_mods['results'],
            0,
            u"No puppet modules were found")

        # Select a random puppet module from the results
        puppet_mod = random.choice(puppet_mods['results'])
        # ... and associate it to the content view
        path = entities.ContentView(id=content_view['id']).path(
            'content_view_puppet_modules')
        response = client.post(
            path,
            auth=get_server_credentials(),
            verify=False,
            data={u'name': puppet_mod['module_name']})
        self.assertEqual(
            response.status_code,
            httplib.OK,
            status_code_error(path, httplib.OK, response)
        )
        self.assertEqual(
            response.json()['name'],
            puppet_mod['module_name'],
        )

        # step 2.9: Publish content view
        task = entities.ContentView(id=content_view['id']).publish()
        task_status = entities.ForemanTask(id=task['id']).poll()
        self.assertEqual(
            task_status['result'],
            u'success',
            u"Publishing {0} failed.".format(content_view['name']))

        # step 2.10: Promote content view to both lifecycles
        content_view = entities.ContentView(id=content_view['id']).read_json()
        self.assertEqual(
            len(content_view['versions']),
            1,
            u'There should only be 1 version published.')
        self.assertEqual(
            len(content_view['versions'][0]['environment_ids']),
            1,
            u"Content view should be present on 1 lifecycle only")
        task = entities.ContentViewVersion(
            id=content_view['versions'][0]['id']).promote(le1['id'])
        task_status = entities.ForemanTask(id=task['id']).poll()
        self.assertEqual(
            task_status['result'],
            u'success',
            u"Promoting {0} to {1} failed.".format(
                content_view['name'], le1['name']))
        # Check that content view exists in 2 lifecycles
        content_view = entities.ContentView(id=content_view['id']).read_json()
        self.assertEqual(
            len(content_view['versions']),
            1,
            u'There should only be 1 version published.')
        self.assertEqual(
            len(content_view['versions'][0]['environment_ids']),
            2,
            u"Content view should be present on 2 lifecycles only")
        task = entities.ContentViewVersion(
            id=content_view['versions'][0]['id']).promote(le2['id'])
        task_status = entities.ForemanTask(id=task['id']).poll()
        self.assertEqual(
            task_status['result'],
            u'success',
            u"Promoting {0} to {1} failed.".format(
                content_view['name'], le2['name']))
        # Check that content view exists in 2 lifecycles
        content_view = entities.ContentView(id=content_view['id']).read_json()
        self.assertEqual(
            len(content_view['versions']),
            1,
            u'There should only be 1 version published.')
        self.assertEqual(
            len(content_view['versions'][0]['environment_ids']),
            3,
            u"Content view should be present on 3 lifecycle only")

        # BONUS: Create a content host and associate it with promoted
        # content view and last lifecycle where it exists
        content_host = entities.System(
            content_view=content_view['id'],
            environment=le2['id']
        ).create()
        # Check that content view matches what we passed
        self.assertEqual(
            content_host['content_view_id'],
            content_view['id'],
            u"Content views do not match."
        )
        # Check that lifecycle environment matches
        self.assertEqual(
            content_host['environment']['id'],
            le2['id'],
            u"Environments do not match."
        )
Ejemplo n.º 17
0
    def test_smoke(self):
        """
        @Test: Check that basic content can be created

        1. Create a new user with admin permissions
        2. Using the new user from above:
            1. Create a new organization
            2. Create two new lifecycle environments
            3. Create a custom product
            4. Create a custom YUM repository
            5. Create a custom PUPPET repository
            6. Synchronize both custom repositories
            7. Create a new content view
            8. Associate both repositories to new content view
            9. Publish content view
            10. Promote content view to both lifecycles
            11. Create a new libvirt compute resource
            12. Create a new subnet
            13. Create a new domain
            14. Create a new capsule
            15. Create a new hostgroup and associate previous entities to it

        @Feature: Smoke Test

        @Assert: All entities are created and associated.
        """
        # prep work
        #
        # FIXME: Use a larger charset when authenticating users.
        #
        # It is possible to create a user with a wide range of characters. (see
        # the "User" entity). However, Foreman supports only HTTP Basic
        # authentication, and the requests lib enforces the latin1 charset in
        # this auth mode. We then further restrict ourselves to the
        # alphanumeric charset, because Foreman complains about incomplete
        # multi-byte chars when latin1 chars are used.
        #
        login = orm.StringField(str_type=('alphanumeric',)).get_value()
        password = orm.StringField(str_type=('alphanumeric',)).get_value()

        # step 1: Create a new user with admin permissions
        entities.User(admin=True, login=login, password=password).create()

        # step 2.1: Create a new organization
        org = entities.Organization().create(auth=(login, password))

        # step 2.2: Create 2 new lifecycle environments
        le1 = entities.LifecycleEnvironment(organization=org['id']).create()
        le2 = entities.LifecycleEnvironment(
            organization=org['id'], prior=le1['id']).create()

        # step 2.3: Create a custom product
        prod = entities.Product(organization=org['id']).create()

        # step 2.4: Create custom YUM repository
        repo1 = entities.Repository(
            product=prod['id'],
            content_type=u'yum',
            url=GOOGLE_CHROME_REPO
        ).create()

        # step 2.5: Create custom PUPPET repository
        repo2 = entities.Repository(
            product=prod['id'],
            content_type=u'puppet',
            url=FAKE_PUPPET_REPO
        ).create()

        # step 2.6: Synchronize both repositories
        response = client.post(
            entities.Repository(id=repo1['id']).path('sync'),
            {u'ids': [repo1['id']]},
            auth=get_server_credentials(),
            verify=False,
            params={u'organization_id': org['id']}).json()
        # TODO: Fetch status of sync task from response task 'id'

        # step 2.7: Create content view
        content_view = entities.ContentView(organization=org['id']).create()