def test_delete_status_code(self, entity_cls): """@Test Issue an HTTP DELETE request and check the returned status code. @Feature: Test multiple API paths @Assert: HTTP 200, 202 or 204 is returned with an ``application/json`` content-type. """ logger.debug('test_delete_status_code arg: %s', entity_cls) skip_if_sam(self, entity_cls) if entity_cls is entities.ConfigTemplate and bz_bug_is_open(1096333): self.skipTest('Cannot delete config templates.') try: entity = entity_cls(id=entity_cls().create_json()['id']) except HTTPError as err: self.fail(err) response = entity.delete_raw() if entity_cls in BZ_1187366_ENTITIES and bz_bug_is_open(1187366): self.skipTest('BZ 1187366 is open.') self.assertIn(response.status_code, (httplib.NO_CONTENT, httplib.OK, httplib.ACCEPTED)) # According to RFC 2616, HTTP 204 responses "MUST NOT include a # message-body". If a message does not have a body, there is no need to # set the content-type of the message. if response.status_code is not httplib.NO_CONTENT: self.assertIn('application/json', response.headers['content-type'])
def test_delete_and_get(self, entity_cls): """@Test: Issue an HTTP DELETE request and GET the deleted entity. @Feature: Test multiple API paths @Assert: An HTTP 404 is returned when fetching the missing entity. """ logger.debug('test_delete_and_get arg: %s', entity_cls) skip_if_sam(self, entity_cls) if entity_cls is entities.ConfigTemplate and bz_bug_is_open(1096333): self.skipTest('Cannot delete config templates.') # Create an entity, delete it and get it. try: entity = entity_cls(id=entity_cls().create_json()['id']) except HTTPError as err: self.fail(err) if entity_cls in BZ_1187366_ENTITIES and bz_bug_is_open(1187366): self.skipTest('BZ 1187366 is open.') entity.delete() if entity_cls is entities.Repository and bz_bug_is_open(1166365): return self.assertEqual(httplib.NOT_FOUND, entity.read_raw().status_code)
def test_delete_status_code(self, entity_cls): """@Test Issue an HTTP DELETE request and check the returned status code. @Feature: Test multiple API paths @Assert: HTTP 200, 202 or 204 is returned with an ``application/json`` content-type. """ logger.debug('test_delete_status_code arg: %s', entity_cls) skip_if_sam(self, entity_cls) if entity_cls is entities.ConfigTemplate and bz_bug_is_open(1096333): self.skipTest('Cannot delete config templates.') try: entity = entity_cls(id=entity_cls().create_json()['id']) except HTTPError as err: self.fail(err) response = entity.delete_raw() if entity_cls in BZ_1187366_ENTITIES and bz_bug_is_open(1187366): self.skipTest('BZ 1187366 is open.') self.assertIn( response.status_code, (httplib.NO_CONTENT, httplib.OK, httplib.ACCEPTED) ) # According to RFC 2616, HTTP 204 responses "MUST NOT include a # message-body". If a message does not have a body, there is no need to # set the content-type of the message. if response.status_code is not httplib.NO_CONTENT: self.assertIn('application/json', response.headers['content-type'])
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)
def test_bug_is_open(self): """Assert ``True`` is returned if the bug is 'NEW' or 'ASSIGNED'.""" class MockBug(object): # pylint:disable=R0903 """A mock bug with an open status.""" status = 'NEW' decorators._get_bugzilla_bug = lambda bug_id: MockBug() self.assertTrue(decorators.bz_bug_is_open(self.bug_id)) MockBug.status = 'ASSIGNED' self.assertTrue(decorators.bz_bug_is_open(self.bug_id))
def test_bug_is_closed(self): """Assert ``False`` is returned if the bug is not open.""" class MockBug(object): # pylint:disable=R0903 """A mock bug with a closed status.""" status = 'CLOSED' decorators._get_bugzilla_bug = lambda bug_id: MockBug() self.assertFalse(decorators.bz_bug_is_open(self.bug_id)) MockBug.status = 'ON_QA' self.assertFalse(decorators.bz_bug_is_open(self.bug_id)) MockBug.status = 'SLOWLY DRIVING A DEV INSANE' self.assertFalse(decorators.bz_bug_is_open(self.bug_id))
def test_put_and_get(self, entity_cls): """@Test: Issue a PUT request and GET the updated entity. @Assert: The updated entity has the correct attributes. """ logger.debug('test_put_and_get arg: {0}'.format(entity_cls)) skip_if_sam(self, entity_cls) if entity_cls in BZ_1154156_ENTITIES and bz_bug_is_open(1154156): self.skipTest("Bugzilla bug 1154156 is open.") # Create an entity. entity = entity_cls(id=entity_cls().create_json()['id']) # Update that entity. entity.create_missing() payload = entity.create_payload() # FIXME: use entity.update_payload() response = client.put( entity.path(), payload, auth=get_server_credentials(), verify=False, ) response.raise_for_status() # Drop the extra outer dict and sensitive params from `payload`. if len(payload.keys()) == 1 and isinstance(payload.values()[0], dict): payload = payload.values()[0] if isinstance(entity, entities.Host): del payload['root_pass'] del payload['name'] # FIXME: "Foo" in, "foo.example.com" out. if issubclass(_get_partial_func(entity_cls), entities.User): del payload['password'] # It is impossible to easily verify foreign keys. if bz_bug_is_open(1151240): for key in payload.keys(): if key.endswith('_id') or key.endswith('_ids'): del payload[key] if issubclass( _get_partial_func(entity_cls), entities.LifecycleEnvironment): del payload['prior'] # this foreign key is oddly named # Compare a trimmed-down `payload` against what the server has. attrs = entity.read_json() for key, value in payload.items(): self.assertIn(key, attrs.keys()) self.assertEqual(value, attrs[key], key)
def test_put_and_get(self, entity_cls): """@Test: Update an entity, then read it back. @Feature: Test multiple API paths @Assert: The entity is updated with the given attributes. """ logger.debug('test_put_and_get arg: %s', entity_cls) skip_if_sam(self, entity_cls) if entity_cls in BZ_1154156_ENTITIES and bz_bug_is_open(1154156): self.skipTest("Bugzilla bug 1154156 is open.") # Create an entity. entity_id = entity_cls().create_json()['id'] # Update that entity. FIXME: This whole procedure is a hack. entity = entity_cls() entity.create_missing() # Generate randomized instance attributes response = client.put( entity_cls(id=entity_id).path(), entity.create_payload(), auth=get_server_credentials(), verify=False, ) response.raise_for_status() # Compare `payload` against entity information returned by the server. payload = _get_readable_attributes(entity) entity_attrs = entity_cls(id=entity_id).read_json() for key, value in payload.items(): self.assertIn(key, entity_attrs.keys()) self.assertEqual(value, entity_attrs[key], key)
def test_negative_update_1(self, options): """@Test: Update subnet with invalid or missing required attributes @Feature: Subnet - Update @Assert: Subnet is not updated """ bug_id = options.pop('bz-bug', None) if bug_id is not None and bz_bug_is_open(bug_id): self.skipTest('Bugzilla bug {0} is open.'.format(bug_id)) try: subnet = make_subnet() except CLIFactoryError as err: self.fail(err) options['id'] = subnet['id'] result = Subnet.update(options) self.assertNotEqual(result.return_code, 0) self.assertNotEqual(len(result.stderr), 0) # check - subnet is not updated result = Subnet.info({u'id': subnet['id']}) for key in options.keys(): self.assertEqual(subnet[key], result.stdout[key])
def _check_bz_1186432(humanized_errors): """Check whether any error messages appear to be due to BZ 1186432. This is an example of ``humanized_errors`` from a server suffering from BZ 1186432: > [u'ERF12-4115 [ProxyAPI::ProxyException]: Unable to get classes from > Puppet for example_env ([RestClient::NotAcceptable]: 406 Not > Acceptable) for proxy https://<snip>:9090/puppet'] :param list humanized_errors: A list of strings. This list can be extracted from a response like so: ``response['humanized']['errors']``. :returns: Nothing. :rtype: None :raises: ``unittest.SkipTest`` if any of the strings in ``humanized_errors`` look suspicious. """ bz_1186432_re = ( r'ERF12-4115 \[ProxyAPI::ProxyException\].*' r'\[RestClient::NotAcceptable\]: 406 Not Acceptable' ) for error in humanized_errors: if (re.search(bz_1186432_re, error) is not None and bz_bug_is_open(1186432)): raise SkipTest('BZ 1186432 is open: {0}'.format(error))
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) )
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)
def test_bug_lookup_fails(self): """Assert ``False`` is returned if the bug cannot be found.""" def bomb(_): """A function that mocks a failure to fetch a bug.""" raise decorators.BugFetchError decorators._get_bugzilla_bug = bomb self.assertFalse(decorators.bz_bug_is_open(self.bug_id))
def test_delete_and_get(self, entity): """@Test: Issue an HTTP DELETE request and GET the deleted entity. @Assert: An HTTP 404 is returned when fetching the missing entity. """ if entity is entities.ConfigTemplate and bz_bug_is_open(1096333): self.skipTest('Cannot delete config templates.') # Create an entity, then delete it. try: entity_n = entity(id=entity().create()['id']) except factory.FactoryError as err: self.fail(err) logger.info('test_delete_and_get path: {0}'.format(entity_n.path())) entity_n.delete() # Get the now non-existent entity. response = client.get( entity_n.path(), auth=get_server_credentials(), verify=False, ) status_code = httplib.NOT_FOUND self.assertEqual( status_code, response.status_code, status_code_error(entity_n.path(), status_code, response), )
def test_put_status_code(self, entity_cls): """@Test Issue a PUT request and check the returned status code. @Feature: Test multiple API paths @Assert: HTTP 200 is returned with an ``application/json`` content-type """ logger.debug('test_put_status_code arg: %s', entity_cls) skip_if_sam(self, entity_cls) if entity_cls in BZ_1154156_ENTITIES and bz_bug_is_open(1154156): self.skipTest("Bugzilla bug 1154156 is open.") # Create an entity entity_id = entity_cls().create_json()['id'] # Update that entity. entity = entity_cls() entity.create_missing() response = client.put( entity_cls(id=entity_id).path(), entity.create_payload(), # FIXME: use entity.update_payload() auth=get_server_credentials(), verify=False, ) self.assertEqual(httplib.OK, response.status_code) self.assertIn('application/json', response.headers['content-type'])
def test_positive_delete_bz1225588(self, org_name): """@test: Create Organization with valid values and upload manifest. Then try to delete that organization. @feature: Organization Positive Delete Test. @assert: Organization is deleted successfully. """ org = entities.Organization(name=org_name).create() with open(manifests.clone(), 'rb') as manifest: upload_manifest(org.id, manifest) with Session(self.browser) as session: make_lifecycle_environment(session, org_name, name='DEV') make_lifecycle_environment( session, org_name, name='QE', prior='DEV' ) # Org cannot be deleted when selected, # So switching to Default Org and then deleting. session.nav.go_to_select_org('Default Organization') self.org.remove(org_name) status = self.org.search(org_name) if bz_bug_is_open(1251926): # Check for at max Five times, the org is deleted for _ in range(5): status = self.org.search(org_name) if status is None: break self.assertIsNone(status)
def test_update_name(self, content_type): """@Test: Update a repository's name. @Assert: The repository's name is updated. @Feature: Repository The only data provided with the PUT request is a name. No other information about the repository (such as its URL) is provided. """ if content_type == 'docker' and bz_bug_is_open(1194476): self.skipTest(1194476) repo_id = entities.Repository( content_type=content_type ).create_json()['id'] name = entities.Repository.name.gen_value() repository = entities.Repository(id=repo_id) client.put( repository.path(), {'name': name}, auth=get_server_credentials(), verify=False, ).raise_for_status() self.assertEqual(name, repository.read_json()['name'])
def test_update_name(self, content_type): """@Test: Update a repository's name. @Assert: The repository's name is updated. @Feature: Repository The only data provided with the PUT request is a name. No other information about the repository (such as its URL) is provided. """ if content_type == 'docker' and bz_bug_is_open(1194476): self.skipTest(1194476) repo_id = entities.Repository( content_type=content_type).create_json()['id'] name = entities.Repository.name.gen_value() repository = entities.Repository(id=repo_id) client.put( repository.path(), { 'name': name }, auth=get_server_credentials(), verify=False, ).raise_for_status() self.assertEqual(name, repository.read_json()['name'])
def test_put_status_code(self, entity_cls): """@Test Issue a PUT request and check the returned status code. @Feature: Test multiple API paths @Assert: HTTP 200 is returned with an ``application/json`` content-type """ logger.debug('test_put_status_code arg: %s', entity_cls) skip_if_sam(self, entity_cls) if entity_cls in BZ_1154156_ENTITIES and bz_bug_is_open(1154156): self.skipTest("Bugzilla bug 1154156 is open.") # Create an entity entity = entity_cls(id=entity_cls().create_json()['id']) # Update that entity. entity.create_missing() response = client.put( entity.path(), entity.create_payload(), # FIXME: use entity.update_payload() auth=get_server_credentials(), verify=False, ) self.assertEqual(httplib.OK, response.status_code) self.assertIn('application/json', response.headers['content-type'])
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'])
def test_positive_update_1(self, name_generator): """@Test: Update a role with and give a name of ``name_generator()``. @Feature: Role @Assert: The role is updated with the given name. """ if decorators.bz_bug_is_open(1112657) and ( name_generator is gen_cjk or name_generator is gen_latin1 or name_generator is gen_utf8): self.skipTest('Bugzilla bug 1112657 is open.') try: role_id = entities.Role().create_json()['id'] except HTTPError as err: self.fail(err) # fail instead of error role = entities.Role(id=role_id) name = name_generator() response = client.put( role.path(), {u'name': name}, auth=get_server_credentials(), verify=False, ) response.raise_for_status() self.assertEqual(role.read_json()['name'], name)
def test_get_status_code(self, entity): """@Test: Create an entity and GET it. @Assert: HTTP 200 is returned with an ``application/json`` content-type """ if entity is entities.ActivationKey and bz_bug_is_open(1127335): self.skipTest("Bugzilla bug 1127335 is open.""") try: attrs = entity().create() except factory.FactoryError as err: self.fail(err) path = entity(id=attrs['id']).path() 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'])
def test_positive_update_1(self, name_generator): """@Test: Update a role with and give a name of ``name_generator()``. @Feature: Role @Assert: The role is updated with the given name. """ if decorators.bz_bug_is_open(1112657) and ( name_generator is gen_cjk or name_generator is gen_latin1 or name_generator is gen_utf8): self.skipTest('Bugzilla bug 1112657 is open.') try: role_id = entities.Role().create()['id'] except HTTPError as err: self.fail(err) # fail instead of error role = entities.Role(id=role_id) name = name_generator() response = client.put( role.path(), {u'name': name}, auth=get_server_credentials(), verify=False, ) response.raise_for_status() self.assertEqual(role.read_json()['name'], name)
def test_delete_status_code(self, entity): """@Test Issue an HTTP DELETE request and check the returned status code. @Assert: HTTP 200, 202 or 204 is returned with an ``application/json`` content-type. """ if entity is entities.ConfigTemplate and bz_bug_is_open(1096333): self.skipTest('Cannot delete config templates.') try: attrs = entity().create() except factory.FactoryError as err: self.fail(err) path = entity(id=attrs['id']).path() response = client.delete( path, auth=get_server_credentials(), verify=False, ) status_code = (httplib.NO_CONTENT, httplib.OK, httplib.ACCEPTED) self.assertIn( response.status_code, status_code, status_code_error(path, status_code, response), ) # According to RFC 2616, HTTP 204 responses "MUST NOT include a # message-body". If a message does not have a body, there is no need to # set the content-type of the message. if response.status_code is not httplib.NO_CONTENT: self.assertIn('application/json', response.headers['content-type'])
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(): if ( group == 'external_usergroups' and bz_bug_is_open(1184170) and get_distro_info()[1] == 7 ): continue # BZ 1184170 is open and affects the server. self.assertItemsEqual(api_paths[group], API_PATHS[group], group)
def test_delete_and_get(self, entity_cls): """@Test: Issue an HTTP DELETE request and GET the deleted entity. @Assert: An HTTP 404 is returned when fetching the missing entity. """ logger.debug('test_delete_and_get arg: {0}'.format(entity_cls)) skip_if_sam(self, entity_cls) if entity_cls is entities.ConfigTemplate and bz_bug_is_open(1096333): self.skipTest('Cannot delete config templates.') # Create an entity, delete it and get it. try: entity = entity_cls(id=entity_cls().create_json()['id']) except HTTPError as err: self.fail(err) entity.delete() if entity_cls is entities.Repository and bz_bug_is_open(1166365): return self.assertEqual(httplib.NOT_FOUND, entity.read_raw().status_code)
def test_entity_read(self, entity): """@Test: Create an entity and get it using :meth:`robottelo.orm.EntityReadMixin.read`. @Assert: The just-read entity is an instance of the correct class. """ if entity is entities.AuthSourceLDAP and bz_bug_is_open(1140313): self.skipTest("Bugzilla bug 1140313 is open.""") attrs = entity().create() read_entity = entity(id=attrs['id']).read() self.assertIsInstance(read_entity, entity)
def test_negative_update_1(self, attrs): """@Test: Update a content view and provide an invalid attribute. @Assert: The content view's attributes are not updated. @Feature: ContentView """ bug_id = attrs.pop("bz-bug", None) if bug_id is not None and bz_bug_is_open(bug_id): self.skipTest("Bugzilla bug {0} is open.".format(bug_id)) with self.assertRaises(HTTPError): entities.ContentView(id=self.content_view.id, **attrs).update()
def test_post_and_get(self, entity_cls): """@Test Issue a POST request and GET the created entity. @Assert: The created entity has the correct attributes. """ logger.debug('test_post_and_get arg: {0}'.format(entity_cls)) skip_if_sam(self, entity_cls) if entity_cls in BZ_1151240_ENTITIES and bz_bug_is_open(1151240): self.skipTest("Bugzilla bug 1151240 is open.""") if entity_cls in BZ_1154156_ENTITIES and bz_bug_is_open(1154156): self.skipTest("Bugzilla bug 1154156 is open.") # Create an entity. entity = entity_cls() entity.id = entity.create_json()['id'] # Drop the extra outer dict and sensitive params from `payload`. payload = entity.create_payload() if len(payload.keys()) == 1 and isinstance(payload.values()[0], dict): payload = payload.values()[0] if isinstance(entity, entities.Host): del payload['root_pass'] del payload['name'] # FIXME: "Foo" in, "foo.example.com" out. if isinstance(entity, entities.User): del payload['password'] # It is impossible to easily verify foreign keys. if bz_bug_is_open(1151240): for key in payload.keys(): if key.endswith('_id') or key.endswith('_ids'): del payload[key] # Compare a trimmed-down `payload` against what the server has. attrs = entity.read_json() for key, value in payload.items(): self.assertIn(key, attrs.keys()) self.assertEqual(value, attrs[key], key)
def test_negative_create_1(self, options): """@Test: Create subnet with invalid or missing required attributes @Feature: Subnet create @Assert: Subnet is not created """ bug_id = options.pop('bz-bug', None) if bug_id is not None and bz_bug_is_open(bug_id): self.skipTest('Bugzilla bug {0} is open.'.format(bug_id)) with self.assertRaises(CLIFactoryError): make_subnet(options)
def test_create_role(self, test_data): """@Test: Create new role @Feature: Role - Positive Create @Assert: Role is created """ bug_id = test_data.pop('bz-bug', None) if bug_id is not None and bz_bug_is_open(bug_id): self.skipTest('Bugzilla bug {0} is open.'.format(bug_id)) with Session(self.browser) as session: make_role(session, name=test_data['name']) self.assertIsNotNone(self.role.search(test_data['name']))
def test_update_owner_type(self, owner_type): """@Test: Update a host and specify an ``owner_type``. @Feature: Host @Assert: The host can be read back, and the ``owner_type`` attribute is correct. """ if owner_type == 'Usergroup' and bz_bug_is_open(1210001): self.skipTest('BZ 1210001: host update should block or yield task') host = entities.Host().create() host.owner_type = owner_type host = host.update(['owner_type']) self.assertEqual(host.owner_type, owner_type)
def test_delete_and_get(self, entity_cls): """@Test: Issue an HTTP DELETE request and GET the deleted entity. @Feature: Test multiple API paths @Assert: An HTTP 404 is returned when fetching the missing entity. """ logger.debug('test_delete_and_get arg: %s', entity_cls) skip_if_sam(self, entity_cls) if entity_cls is entities.ConfigTemplate and bz_bug_is_open(1096333): self.skipTest('BZ 1096333: Cannot delete config templates.') if entity_cls in BZ_1187366_ENTITIES and bz_bug_is_open(1187366): self.skipTest('BZ 1187366: Cannot delete orgs or environments.') if entity_cls == entities.System and bz_bug_is_open(1133071): self.skipTest('BZ 1133071: Receive HTTP 400s instead of 404s.') # Create an entity, delete it and get it. try: entity = entity_cls(id=entity_cls().create_json()['id']) except HTTPError as err: self.fail(err) entity.delete() self.assertEqual(httplib.NOT_FOUND, entity.read_raw().status_code)
def test_create_owner_type(self, owner_type): """@Test: Create a host and specify an ``owner_type``. @Feature: Host @Assert: The host can be read back, and the ``owner_type`` attribute is correct. """ if owner_type == 'Usergroup' and bz_bug_is_open(1203865): self.skipTest('BZ 1203865: owner_type ignored when creating host') host = entities.Host() host.create_missing() host.owner_type = owner_type host = host.create(create_missing=False) self.assertEqual(host.owner_type, owner_type)
def test_search_by_name(self, permission_name): """@test: Search for a permission by name. @feature: Permissions @assert: Only one permission is returned, and the permission returned is the one searched for. """ if ( permission_name == 'power_compute_resources_vms' and bz_bug_is_open(1198731)): self.skipTest('BZ 1198731 is open.') result = entities.Permission(name=permission_name).search() self.assertEqual(len(result), 1, permission_name) self.assertEqual(permission_name, result[0]['name'])
def test_negative_create_role_2(self, test_data): """@Test: Create new role with 256 characters in name @Feature: Role - Negative Create @Assert: Role is not created """ bug_id = test_data.pop('bz-bug', None) if bug_id is not None and bz_bug_is_open(bug_id): self.skipTest('Bugzilla bug {0} is open.'.format(bug_id)) with Session(self.browser) as session: make_role(session, name=test_data['name']) error = session.nav.wait_until_element( common_locators["name_haserror"]) self.assertIsNotNone(error)
def test_remove_role(self, test_data): """@Test: Delete an existing role @Feature: Role - Positive Delete @Assert: Role is deleted """ bug_id = test_data.pop('bz-bug', None) if bug_id is not None and bz_bug_is_open(bug_id): self.skipTest('Bugzilla bug {0} is open.'.format(bug_id)) with Session(self.browser) as session: make_role(session, name=test_data['name']) self.assertIsNotNone(self.role.search(test_data['name'])) self.role.remove(test_data['name'], True) self.assertIsNone(self.role.search(test_data['name']))
def test_remove_configtemplate_1(self, testdata): """ @test: Remove config template @feature: Locations @assert: configtemplate is added then removed """ bug_id = testdata.pop('bugzilla', None) if bug_id is not None and bz_bug_is_open(bug_id): self.skipTest('Bugzilla bug {0} is open.'.format(bug_id)) template = testdata['user_name'] strategy, value = common_locators["all_values_selection"] loc_name = gen_string("alpha", 8) temp_type = 'provision' template_path = get_data_file(OS_TEMPLATE_DATA_FILE) with Session(self.browser) as session: make_templates(session, name=template, template_path=template_path, template_type=temp_type, custom_really=True) self.assertIsNotNone(self.template.search(template)) make_loc(session, name=loc_name) self.location.search(loc_name).click() session.nav.wait_until_element( tab_locators["context.tab_template"]).click() element = session.nav.wait_until_element( (strategy, value % template)) # Item is listed in 'Selected Items' list and not 'All Items' list. self.assertIsNotNone(element) self.template.delete(template, True) self.location.search(loc_name).click() session.nav.wait_until_element( tab_locators["context.tab_template"]).click() element = session.nav.wait_until_element( (strategy, value % template)) # Item is listed in 'All Items' list and not 'Selected Items' list. self.assertIsNone(element)
def test_negative_update_1(self, attrs): """@Test: Update a content view and provide an invalid attribute. @Assert: The content view's attributes are not updated. @Feature: ContentView """ bug_id = attrs.pop('bz-bug', None) if bug_id is not None and bz_bug_is_open(bug_id): self.skipTest('Bugzilla bug {0} is open.'.format(bug_id)) response = client.put( self.content_view.path(), attrs, auth=get_server_credentials(), verify=False, ) with self.assertRaises(HTTPError): response.raise_for_status()
def test_post_status_code(self, entity_cls): """@Test: Issue a POST request and check the returned status code. @Feature: Test multiple API paths @Assert: HTTP 201 is returned with an ``application/json`` content-type """ logger.debug('test_post_status_code arg: %s', entity_cls) skip_if_sam(self, entity_cls) # Some arguments are "normal" classes and others are objects produced # by functools.partial. Also, `partial(SomeClass).func == SomeClass`. if (_get_partial_func(entity_cls) in BZ_1118015_ENTITIES and bz_bug_is_open(1118015)): self.skipTest('Bugzilla bug 1118015 is open.') response = entity_cls().create_raw() self.assertEqual(httplib.CREATED, response.status_code) self.assertIn('application/json', response.headers['content-type'])
def test_positive_create_1(self, name_generator): """@Test: Create a role with name ``name_generator()``. @Feature: Role @Assert: An entity can be created without receiving any errors, the entity can be fetched, and the fetched entity has the specified name. """ if decorators.bz_bug_is_open(1112657) and ( name_generator is gen_cjk or name_generator is gen_latin1 or name_generator is gen_utf8): self.skipTest('Bugzilla bug 1112657 is open.') name = name_generator() try: role_id = entities.Role(name=name).create()['id'] except HTTPError as err: self.fail(err) # fail instead of error # GET the role and verify it's name. self.assertEqual(entities.Role(id=role_id).read_json()['name'], name)
def test_create_subnet_2(self, test_data): """@Test: Create new subnet with 255 characters in name @Feature: Subnet - Positive Create @Assert: Subnet is created with 255 chars """ bug_id = test_data.pop('bz-bug', None) if bug_id is not None and bz_bug_is_open(bug_id): self.skipTest('Bugzilla bug {0} is open.'.format(bug_id)) network = gen_ipaddr(ip3=True) mask = gen_netmask() with Session(self.browser) as session: make_subnet(session, subnet_name=test_data['name'], subnet_network=network, subnet_mask=mask) self.assertIsNotNone( self.subnet.search_subnet(subnet_name=test_data['name']))
def generate_strings_list(len1=None, remove_str=None, bug_id=None): """Generates a list of all the input strings. :param int len1: Specifies the length of the strings to be be generated. If the len1 is None then the list is returned with string types of random length. :return: Returns a list of various string types. :rtype: list """ if len1 is None: len1 = gen_integer(3, 30) strings = { str_type: gen_string(str_type, len1) for str_type in (u'alpha', u'numeric', u'alphanumeric', u'latin1', u'utf8', u'cjk', u'html') } # Handle No bug_id, If some entity doesn't support a str_type. # Remove str_type from dictionary only if bug is open. if remove_str and (bug_id is None or bz_bug_is_open(bug_id)): del strings[remove_str] return list(strings.values())
def test_post_and_get(self, entity_cls): """@Test: Create an entity, then read it back. @Feature: Test multiple API paths @Assert: The entity is created with the given attributes. """ logger.debug('test_post_and_get arg: %s', entity_cls) skip_if_sam(self, entity_cls) if entity_cls in BZ_1154156_ENTITIES and bz_bug_is_open(1154156): self.skipTest("Bugzilla bug 1154156 is open.") entity = entity_cls() entity_id = entity.create_json()['id'] # Compare `payload` against entity information returned by the server. payload = _get_readable_attributes(entity) entity_attrs = entity_cls(id=entity_id).read_json() for key, value in payload.items(): self.assertIn(key, entity_attrs.keys()) self.assertEqual(value, entity_attrs[key], key)
def test_positive_delete_1(self, name_generator): """@Test: Delete a role with name ``name_generator()``. @Feature: Role @Assert: The role cannot be fetched after it is deleted. """ if decorators.bz_bug_is_open(1112657) and ( name_generator is gen_cjk or name_generator is gen_latin1 or name_generator is gen_utf8): self.skipTest('Bugzilla bug 1112657 is open.') name = name_generator() try: role_id = entities.Role(name=name).create()['id'] except HTTPError as err: self.fail(err) # fail instead of error # DELETE the role and verify that it cannot be fetched role = entities.Role(id=role_id) role.delete() with self.assertRaises(HTTPError): role.read_json()
def _check_bz_1186432(humanized_errors): """Check whether any error messages appear to be due to BZ 1186432. This is an example of ``humanized_errors`` from a server suffering from BZ 1186432: > [u'ERF12-4115 [ProxyAPI::ProxyException]: Unable to get classes from > Puppet for example_env ([RestClient::NotAcceptable]: 406 Not > Acceptable) for proxy https://<snip>:9090/puppet'] :param list humanized_errors: A list of strings. This list can be extracted from a response like so: ``response['humanized']['errors']``. :returns: Nothing. :rtype: None :raises: ``unittest.SkipTest`` if any of the strings in ``humanized_errors`` look suspicious. """ bz_1186432_re = (r'ERF12-4115 \[ProxyAPI::ProxyException\].*' r'\[RestClient::NotAcceptable\]: 406 Not Acceptable') for error in humanized_errors: if (re.search(bz_1186432_re, error) is not None and bz_bug_is_open(1186432)): raise SkipTest('BZ 1186432 is open: {0}'.format(error))
def test_smoke(self): """@Test: Check that basic content can be created * Create a new user with admin permissions * Using the new user from above: * Create a new organization * Create two new lifecycle environments * Create a custom product * Create a custom YUM repository * Create a custom PUPPET repository * Synchronize both custom repositories * Create a new content view * Associate both repositories to new content view * Publish content view * Promote content view to both lifecycles * Create a new libvirt compute resource * Create a new subnet * Create a new domain * Create a new hostgroup and associate previous entities to it @Feature: Smoke Test @Assert: All entities are created and associated. """ user_name = gen_string("alpha", 6) password = gen_string("alpha", 6) org_name = gen_string("alpha", 6) env_1_name = gen_string("alpha", 6) env_2_name = gen_string("alpha", 6) product_name = gen_string("alpha", 6) yum_repository_name = gen_string("alpha", 6) puppet_repository_name = gen_string("alpha", 6) cv_name = gen_string("alpha", 6) puppet_module = "httpd" module_ver = 'Latest' compute_resource_name = gen_string("alpha", 6) libvirt_url = "qemu+tcp://%s:16509/system" provider_type = FOREMAN_PROVIDERS['libvirt'] url = (libvirt_url % conf.properties['main.server.hostname']) subnet_name = gen_string("alpha", 6) domain_name = gen_string("alpha", 6) domain = description = DOMAIN % domain_name hostgroup_name = gen_string("alpha", 6) # Create new user with admin permissions with Session(self.browser) as session: make_user(session, username=user_name, password1=password, password2=password) self.assertIsNotNone(self.user.search(user_name, "login")) is_admin_role_selected = self.user.admin_role_to_user(user_name) self.assertTrue(is_admin_role_selected) # FIX ME: UI doesn't authenticate user created via UI auto: Issue #1152 # Once #1152 is fixed; need to pass user_name and password to Session with Session(self.browser) as session: # Create New organization make_org(session, org_name=org_name) self.assertIsNotNone(self.org.search(org_name)) # Create New Lifecycle environment1 make_lifecycle_environment(session, org=org_name, name=env_1_name) strategy, value = locators["content_env.select_name"] self.assertIsNotNone( self.contentenv.wait_until_element( (strategy, value % env_1_name))) # Create New Lifecycle environment2 make_lifecycle_environment(session, org=org_name, name=env_2_name, prior=env_1_name) self.assertIsNotNone( self.contentenv.wait_until_element( (strategy, value % env_2_name))) # Create custom product make_product(session, org=org_name, name=product_name) self.assertIsNotNone(self.products.search(product_name)) # Create a YUM repository make_repository(session, org=org_name, name=yum_repository_name, product=product_name, url=GOOGLE_CHROME_REPO) self.assertIsNotNone(self.repository.search(yum_repository_name)) # Create a puppet Repository make_repository(session, org=org_name, name=puppet_repository_name, product=product_name, url=FAKE_0_PUPPET_REPO, repo_type=REPO_TYPE['puppet']) self.assertIsNotNone( self.repository.search(puppet_repository_name)) # Sync YUM and puppet repository self.navigator.go_to_sync_status() sync = self.sync.sync_custom_repos( product_name, [yum_repository_name, puppet_repository_name]) self.assertIsNotNone(sync) # Create new content-view make_contentview(session, org=org_name, name=cv_name) self.assertIsNotNone(self.content_views.search(cv_name)) # Add YUM repository to content-view self.content_views.add_remove_repos(cv_name, [yum_repository_name]) if not bz_bug_is_open(1191422): self.assertIsNotNone( self.content_views.wait_until_element( common_locators["alert.success"])) # Add puppet-module to content-view self.content_views.add_puppet_module(cv_name, puppet_module, filter_term=module_ver) # Publish content-view self.content_views.publish(cv_name) if not bz_bug_is_open(1191422): self.assertIsNotNone( self.content_views.wait_until_element( common_locators["alert.success"])) # Promote content-view to life-cycle environment 1 self.content_views.promote(cv_name, version="Version 1", env=env_1_name) if not bz_bug_is_open(1191422): self.assertIsNotNone( self.content_views.wait_until_element( common_locators["alert.success"])) # Promote content-view to life-cycle environment 2 self.content_views.promote(cv_name, version="Version 1", env=env_2_name) if not bz_bug_is_open(1191422): self.assertIsNotNone( self.content_views.wait_until_element( common_locators["alert.success"])) # Create a new libvirt compute resource make_resource(session, org=org_name, name=compute_resource_name, provider_type=provider_type, url=url) self.assertIsNotNone( self.compute_resource.search(compute_resource_name)) # Create a subnet make_subnet(session, org=org_name, subnet_name=subnet_name, subnet_network=gen_ipaddr(ip3=True), subnet_mask="255.255.255.0") self.assertIsNotNone(self.subnet.search_subnet(subnet_name)) # Create a Domain make_domain(session, org=org_name, name=domain, description=description) self.assertIsNotNone(self.domain.search(description)) # Create a HostGroup make_hostgroup(session, name=hostgroup_name) self.assertIsNotNone(self.hostgroup.search(hostgroup_name))
def test_end_to_end(self): """@Test: Perform end to end smoke tests using RH repos. @Feature: Smoke test @Assert: All tests should succeed and Content should be successfully fetched by client """ org_name = gen_string("alpha", 6) cv_name = gen_string("alpha", 6) activation_key_name = gen_string("alpha", 6) env_name = gen_string("alpha", 6) product_name = "Red Hat Employee Subscription" repo_names = [ "Red Hat Enterprise Virtualization Agents for RHEL 6 Server " "RPMs x86_64 6.5", "Red Hat Enterprise Virtualization Agents for RHEL 6 Server " "RPMs x86_64 6Server", ] repos = self.sync.create_repos_tree(RHVA_REPO_TREE) package_name = "python-kitchen" cloned_manifest_path = manifests.clone() # upload_file function should take care of uploading to sauce labs. upload_file(cloned_manifest_path, remote_file=cloned_manifest_path) with Session(self.browser) as session: # Create New organization make_org(session, org_name=org_name) self.assertIsNotNone(self.org.search(org_name)) # Create New Lifecycle environment make_lifecycle_environment(session, org=org_name, name=env_name) strategy, value = locators["content_env.select_name"] self.assertIsNotNone( self.contentenv.wait_until_element( (strategy, value % env_name))) # Navigate UI to select org and redhat subscription page session.nav.go_to_select_org(org_name) session.nav.go_to_red_hat_subscriptions() # Upload manifest from webui self.subscriptions.upload(cloned_manifest_path) self.assertTrue( session.nav.wait_until_element( common_locators['alert.success'])) session.nav.go_to_red_hat_repositories() # List of dictionary passed to enable the redhat repos # It selects Product->Reposet-> Repo self.sync.enable_rh_repos(repos) session.nav.go_to_sync_status() # Sync the repos sync = self.sync.sync_rh_repos(repos) # syn.sync_rh_repos returns boolean values and not objects self.assertTrue(sync) # Create new content-view make_contentview(session, org=org_name, name=cv_name) self.assertIsNotNone(self.content_views.search(cv_name)) # Add YUM repository to content-view self.content_views.add_remove_repos(cv_name, repo_names) if not bz_bug_is_open(1191422): self.assertIsNotNone( self.content_views.wait_until_element( common_locators["alert.success"])) # Publish content-view self.content_views.publish(cv_name) if not bz_bug_is_open(1191422): self.assertIsNotNone( self.content_views.wait_until_element( common_locators["alert.success"])) # Promote content-view to life-cycle environment 1 self.content_views.promote(cv_name, version="Version 1", env=env_name) if not bz_bug_is_open(1191422): self.assertIsNotNone( self.content_views.wait_until_element( common_locators["alert.success"])) # Create Activation-Key make_activationkey(session, org=org_name, name=activation_key_name, env=env_name, content_view=cv_name) self.activationkey.associate_product(activation_key_name, [product_name]) self.activationkey.enable_repos(activation_key_name, [REPOSET['rhva6']]) if not bz_bug_is_open(1191541): self.assertIsNotNone( self.activationkey.wait_until_element( common_locators["alert.success"])) # Create VM with VirtualMachine(distro='rhel66') as vm: # Download and Install rpm result = vm.run( "wget -nd -r -l1 --no-parent -A '*.noarch.rpm' " "http://{0}/pub/".format(self.server_name)) self.assertEqual( result.return_code, 0, "failed to fetch katello-ca rpm: {0}, return code: {1}". format(result.stderr, result.return_code)) result = vm.run('rpm -i katello-ca-consumer*.noarch.rpm') self.assertEqual( result.return_code, 0, "failed to install katello-ca rpm: {0}, return code: {1}". format(result.stderr, result.return_code)) # Register client with foreman server using activation-key result = vm.run( 'subscription-manager register --activationkey {0} ' '--org {1} --force'.format(activation_key_name, org_name)) self.assertEqual( result.return_code, 0, "failed to register client:: {0} and return code: {1}". format(result.stderr, result.return_code)) # Install contents from sat6 server result = vm.run('yum install -y {0}'.format(package_name)) self.assertEqual( result.return_code, 0, "Package install failed: {0} and return code: {1}".format( result.stderr, result.return_code)) # Verify if package is installed by query it result = vm.run('rpm -q {0}'.format(package_name)) self.assertIn(package_name, result.stdout[0])