Merge "Adding description for testcases - network part1"
diff --git a/tempest/api/compute/admin/test_aggregates_negative.py b/tempest/api/compute/admin/test_aggregates_negative.py
index d5adfed..7b115ce 100644
--- a/tempest/api/compute/admin/test_aggregates_negative.py
+++ b/tempest/api/compute/admin/test_aggregates_negative.py
@@ -49,7 +49,7 @@
@decorators.attr(type=['negative'])
@decorators.idempotent_id('86a1cb14-da37-4a70-b056-903fd56dfe29')
def test_aggregate_create_as_user(self):
- # Regular user is not allowed to create an aggregate.
+ """Regular user is not allowed to create an aggregate"""
aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
self.assertRaises(lib_exc.Forbidden,
self.aggregates_client.create_aggregate,
@@ -58,7 +58,7 @@
@decorators.attr(type=['negative'])
@decorators.idempotent_id('3b8a1929-3793-4e92-bcb4-dfa572ee6c1d')
def test_aggregate_create_aggregate_name_length_less_than_1(self):
- # the length of aggregate name should >= 1 and <=255
+ """The length of aggregate name should >=1"""
self.assertRaises(lib_exc.BadRequest,
self.client.create_aggregate,
name='')
@@ -66,7 +66,7 @@
@decorators.attr(type=['negative'])
@decorators.idempotent_id('4c194563-543b-4e70-a719-557bbe947fac')
def test_aggregate_create_aggregate_name_length_exceeds_255(self):
- # the length of aggregate name should >= 1 and <=255
+ """The length of aggregate name should <=255"""
aggregate_name = 'a' * 256
self.assertRaises(lib_exc.BadRequest,
self.client.create_aggregate,
@@ -75,7 +75,7 @@
@decorators.attr(type=['negative'])
@decorators.idempotent_id('9c23a291-b0b1-487b-b464-132e061151b3')
def test_aggregate_create_with_existent_aggregate_name(self):
- # creating an aggregate with existent aggregate name is forbidden
+ """Creating an aggregate with existent aggregate name is forbidden"""
aggregate = self._create_test_aggregate()
self.assertRaises(lib_exc.Conflict,
self.client.create_aggregate,
@@ -84,7 +84,7 @@
@decorators.attr(type=['negative'])
@decorators.idempotent_id('cd6de795-c15d-45f1-8d9e-813c6bb72a3d')
def test_aggregate_delete_as_user(self):
- # Regular user is not allowed to delete an aggregate.
+ """Regular user is not allowed to delete an aggregate"""
aggregate = self._create_test_aggregate()
self.assertRaises(lib_exc.Forbidden,
self.aggregates_client.delete_aggregate,
@@ -93,14 +93,14 @@
@decorators.attr(type=['negative'])
@decorators.idempotent_id('b7d475a6-5dcd-4ff4-b70a-cd9de66a6672')
def test_aggregate_list_as_user(self):
- # Regular user is not allowed to list aggregates.
+ """Regular user is not allowed to list aggregates"""
self.assertRaises(lib_exc.Forbidden,
self.aggregates_client.list_aggregates)
@decorators.attr(type=['negative'])
@decorators.idempotent_id('557cad12-34c9-4ff4-95f0-22f0dfbaf7dc')
def test_aggregate_get_details_as_user(self):
- # Regular user is not allowed to get aggregate details.
+ """Regular user is not allowed to get aggregate details"""
aggregate = self._create_test_aggregate()
self.assertRaises(lib_exc.Forbidden,
self.aggregates_client.show_aggregate,
@@ -109,21 +109,21 @@
@decorators.attr(type=['negative'])
@decorators.idempotent_id('c74f4bf1-4708-4ff2-95a0-f49eaca951bd')
def test_aggregate_delete_with_invalid_id(self):
- # Delete an aggregate with invalid id should raise exceptions.
+ """Delete an aggregate with invalid id should raise exceptions"""
self.assertRaises(lib_exc.NotFound,
self.client.delete_aggregate, -1)
@decorators.attr(type=['negative'])
@decorators.idempotent_id('3c916244-2c46-49a4-9b55-b20bb0ae512c')
def test_aggregate_get_details_with_invalid_id(self):
- # Get aggregate details with invalid id should raise exceptions.
+ """Get aggregate details with invalid id should raise exceptions"""
self.assertRaises(lib_exc.NotFound,
self.client.show_aggregate, -1)
@decorators.attr(type=['negative'])
@decorators.idempotent_id('0ef07828-12b4-45ba-87cc-41425faf5711')
def test_aggregate_add_non_exist_host(self):
- # Adding a non-exist host to an aggregate should raise exceptions.
+ """Adding a non-exist host to an aggregate should fail"""
while True:
non_exist_host = data_utils.rand_name('nonexist_host')
if non_exist_host not in self.hosts:
@@ -135,7 +135,7 @@
@decorators.attr(type=['negative'])
@decorators.idempotent_id('7324c334-bd13-4c93-8521-5877322c3d51')
def test_aggregate_add_host_as_user(self):
- # Regular user is not allowed to add a host to an aggregate.
+ """Regular user is not allowed to add a host to an aggregate"""
aggregate = self._create_test_aggregate()
self.assertRaises(lib_exc.Forbidden,
self.aggregates_client.add_host,
@@ -144,7 +144,7 @@
@decorators.attr(type=['negative'])
@decorators.idempotent_id('19dd44e1-c435-4ee1-a402-88c4f90b5950')
def test_aggregate_add_existent_host(self):
- # Adding already existing host to aggregate should fail.
+ """Adding already existing host to aggregate should fail"""
self.useFixture(fixtures.LockFixture('availability_zone'))
aggregate = self._create_test_aggregate()
@@ -158,7 +158,7 @@
@decorators.attr(type=['negative'])
@decorators.idempotent_id('7a53af20-137a-4e44-a4ae-e19260e626d9')
def test_aggregate_remove_host_as_user(self):
- # Regular user is not allowed to remove a host from an aggregate.
+ """Regular user is not allowed to remove a host from an aggregate"""
self.useFixture(fixtures.LockFixture('availability_zone'))
aggregate = self._create_test_aggregate()
@@ -173,7 +173,7 @@
@decorators.attr(type=['negative'])
@decorators.idempotent_id('95d6a6fa-8da9-4426-84d0-eec0329f2e4d')
def test_aggregate_remove_nonexistent_host(self):
- # Removing not existing host from aggregate should fail.
+ """Removing not existing host from aggregate should fail"""
aggregate = self._create_test_aggregate()
self.assertRaises(lib_exc.NotFound, self.client.remove_host,
diff --git a/tempest/api/compute/admin/test_create_server.py b/tempest/api/compute/admin/test_create_server.py
index 711b441..c4a8bf5 100644
--- a/tempest/api/compute/admin/test_create_server.py
+++ b/tempest/api/compute/admin/test_create_server.py
@@ -27,6 +27,8 @@
class ServersWithSpecificFlavorTestJSON(base.BaseV2ComputeAdminTest):
+ """Test creating servers with specific flavor"""
+
@classmethod
def setup_credentials(cls):
cls.prepare_instance_network()
@@ -41,7 +43,7 @@
@testtools.skipUnless(CONF.validation.run_validation,
'Instance validation tests are disabled.')
def test_verify_created_server_ephemeral_disk(self):
- # Verify that the ephemeral disk is created when creating server
+ """Verify that the ephemeral disk is created when creating server"""
flavor_base = self.flavors_client.show_flavor(
self.flavor_ref)['flavor']
diff --git a/tempest/api/compute/admin/test_delete_server.py b/tempest/api/compute/admin/test_delete_server.py
index 58cac57..c625939 100644
--- a/tempest/api/compute/admin/test_delete_server.py
+++ b/tempest/api/compute/admin/test_delete_server.py
@@ -19,6 +19,8 @@
class DeleteServersAdminTestJSON(base.BaseV2ComputeAdminTest):
+ """Test deletion of servers"""
+
# NOTE: Server creations of each test class should be under 10
# for preventing "Quota exceeded for instances".
@@ -30,7 +32,7 @@
@decorators.idempotent_id('99774678-e072-49d1-9d2a-49a59bc56063')
def test_delete_server_while_in_error_state(self):
- # Delete a server while it's VM state is error
+ """Delete a server while it's VM state is error"""
server = self.create_test_server(wait_until='ACTIVE')
self.admin_client.reset_state(server['id'], state='error')
# Verify server's state
@@ -43,7 +45,7 @@
@decorators.idempotent_id('73177903-6737-4f27-a60c-379e8ae8cf48')
def test_admin_delete_servers_of_others(self):
- # Administrator can delete servers of others
+ """Administrator can delete servers of others"""
server = self.create_test_server(wait_until='ACTIVE')
self.admin_client.delete_server(server['id'])
waiters.wait_for_server_termination(self.servers_client, server['id'])
diff --git a/tempest/api/network/admin/test_floating_ips_admin_actions.py b/tempest/api/network/admin/test_floating_ips_admin_actions.py
index 7d41019..ad7dfb3 100644
--- a/tempest/api/network/admin/test_floating_ips_admin_actions.py
+++ b/tempest/api/network/admin/test_floating_ips_admin_actions.py
@@ -23,6 +23,8 @@
class FloatingIPAdminTestJSON(base.BaseAdminNetworkTest):
+ """Test floating ips"""
+
credentials = ['primary', 'alt', 'admin']
@classmethod
@@ -55,6 +57,13 @@
@decorators.idempotent_id('64f2100b-5471-4ded-b46c-ddeeeb4f231b')
def test_list_floating_ips_from_admin_and_nonadmin(self):
+ """Test listing floating ips from admin and non admin users
+
+ This test performs below operations:
+ 1. Create couple floating ips for admin and non-admin users.
+ 2. Verify if admin can access all floating ips including other user
+ and non-admin user can only access its own floating ips.
+ """
# Create floating ip from admin user
floating_ip_admin = self.admin_floating_ips_client.create_floatingip(
floating_network_id=self.ext_net_id)
@@ -90,6 +99,7 @@
@decorators.idempotent_id('32727cc3-abe2-4485-a16e-48f2d54c14f2')
def test_create_list_show_floating_ip_with_tenant_id_by_admin(self):
+ """Verify if admin can create/list/show floating ip with tenant id"""
# Creates a floating IP
body = self.admin_floating_ips_client.create_floatingip(
floating_network_id=self.ext_net_id,
diff --git a/tempest/api/network/admin/test_negative_quotas.py b/tempest/api/network/admin/test_negative_quotas.py
index 3562d6f..190d9e3 100644
--- a/tempest/api/network/admin/test_negative_quotas.py
+++ b/tempest/api/network/admin/test_negative_quotas.py
@@ -53,6 +53,7 @@
@decorators.attr(type=['negative'])
@decorators.idempotent_id('644f4e1b-1bf9-4af0-9fd8-eb56ac0f51cf')
def test_network_quota_exceeding(self):
+ """Test creating network when exceeding network quota will fail"""
# Set the network quota to two
self.admin_quotas_client.update_quotas(self.project['id'], network=2)
diff --git a/tempest/api/network/admin/test_ports.py b/tempest/api/network/admin/test_ports.py
index 289e577..51f2857 100644
--- a/tempest/api/network/admin/test_ports.py
+++ b/tempest/api/network/admin/test_ports.py
@@ -24,6 +24,7 @@
class PortsAdminExtendedAttrsTestJSON(base.BaseAdminNetworkTest):
+ """Test extended attributes of ports"""
@classmethod
def setup_clients(cls):
@@ -41,6 +42,7 @@
@decorators.idempotent_id('8e8569c1-9ac7-44db-8bc1-f5fb2814f29b')
@utils.services('compute')
def test_create_port_binding_ext_attr(self):
+ """Test creating port with extended attribute"""
post_body = {"network_id": self.network['id'],
"binding:host_id": self.host_id,
"name": data_utils.rand_name(self.__class__.__name__)}
@@ -56,6 +58,7 @@
@decorators.idempotent_id('6f6c412c-711f-444d-8502-0ac30fbf5dd5')
@utils.services('compute')
def test_update_port_binding_ext_attr(self):
+ """Test updating port's extended attribute"""
post_body = {"network_id": self.network['id'],
"name": data_utils.rand_name(self.__class__.__name__)}
body = self.admin_ports_client.create_port(**post_body)
@@ -73,6 +76,7 @@
@decorators.idempotent_id('1c82a44a-6c6e-48ff-89e1-abe7eaf8f9f8')
@utils.services('compute')
def test_list_ports_binding_ext_attr(self):
+ """Test updating and listing port's extended attribute"""
# Create a new port
post_body = {"network_id": self.network['id'],
"name": data_utils.rand_name(self.__class__.__name__)}
@@ -101,6 +105,7 @@
@decorators.idempotent_id('b54ac0ff-35fc-4c79-9ca3-c7dbd4ea4f13')
def test_show_port_binding_ext_attr(self):
+ """Test showing port's extended attribute"""
body = self.admin_ports_client.create_port(
name=data_utils.rand_name(self.__class__.__name__),
network_id=self.network['id'])
diff --git a/tempest/api/network/admin/test_quotas.py b/tempest/api/network/admin/test_quotas.py
index 8b7bfb1..d8db298 100644
--- a/tempest/api/network/admin/test_quotas.py
+++ b/tempest/api/network/admin/test_quotas.py
@@ -89,6 +89,7 @@
@decorators.idempotent_id('2390f766-836d-40ef-9aeb-e810d78207fb')
def test_quotas(self):
+ """Test update/list/show/reset of network quotas"""
new_quotas = {'network': 0, 'port': 0}
self._check_quotas(new_quotas)
@@ -96,6 +97,7 @@
'quota_details', 'network'), 'Quota details extension not enabled.')
@decorators.idempotent_id('7b05ec5f-bf44-43cb-b28f-ddd72a824288')
def test_show_quota_details(self):
+ """Test showing network quota details"""
# Show quota details for an existing project
quota_details = self.admin_quotas_client.show_quota_details(
self.admin_quotas_client.tenant_id)['quota']
diff --git a/tempest/api/network/admin/test_routers_negative.py b/tempest/api/network/admin/test_routers_negative.py
index f605945..914c046 100644
--- a/tempest/api/network/admin/test_routers_negative.py
+++ b/tempest/api/network/admin/test_routers_negative.py
@@ -27,6 +27,7 @@
class RoutersAdminNegativeTest(base.BaseAdminNetworkTest):
+ """Admin negative tests of routers"""
@classmethod
def skip_checks(cls):
@@ -41,6 +42,7 @@
@testtools.skipUnless(CONF.network.public_network_id,
'The public_network_id option must be specified.')
def test_router_set_gateway_used_ip_returns_409(self):
+ """Test creating router with gateway set to used ip should fail"""
# At first create a address from public_network_id
port = self.admin_ports_client.create_port(
name=data_utils.rand_name(self.__class__.__name__),
diff --git a/tempest/api/network/test_extensions.py b/tempest/api/network/test_extensions.py
index 4804ada..e116d7c 100644
--- a/tempest/api/network/test_extensions.py
+++ b/tempest/api/network/test_extensions.py
@@ -32,7 +32,7 @@
@decorators.attr(type='smoke')
@decorators.idempotent_id('ef28c7e6-e646-4979-9d67-deb207bc5564')
def test_list_show_extensions(self):
- # List available extensions for the project
+ """List available extensions and show the detail of each extension"""
expected_alias = ['security-group', 'l3_agent_scheduler',
'ext-gw-mode', 'binding', 'quotas',
'agent', 'dhcp_agent_scheduler', 'provider',
diff --git a/tempest/api/network/test_floating_ips.py b/tempest/api/network/test_floating_ips.py
index abcbbf7..c32d3c1 100644
--- a/tempest/api/network/test_floating_ips.py
+++ b/tempest/api/network/test_floating_ips.py
@@ -73,6 +73,7 @@
@decorators.attr(type='smoke')
@decorators.idempotent_id('62595970-ab1c-4b7f-8fcc-fddfe55e8718')
def test_create_list_show_update_delete_floating_ip(self):
+ """Test create/list/show/update/delete floating ip"""
# Creates a floating IP
body = self.floating_ips_client.create_floatingip(
floating_network_id=self.ext_net_id,
@@ -133,6 +134,14 @@
@decorators.idempotent_id('e1f6bffd-442f-4668-b30e-df13f2705e77')
def test_floating_ip_delete_port(self):
+ """Test deleting floating ip's port
+
+ 1. Create a floating ip
+ 2. Create a port
+ 3. Update the floating ip's port_id to the created port
+ 4. Delete the port
+ 5. Verify that the port details are cleared from the floating ip
+ """
# Create a floating IP
body = self.floating_ips_client.create_floatingip(
floating_network_id=self.ext_net_id)
@@ -163,6 +172,7 @@
@decorators.idempotent_id('1bb2f731-fe5a-4b8c-8409-799ade1bed4d')
def test_floating_ip_update_different_router(self):
+ """Test associating a floating ip to a port on different router"""
# Associate a floating IP to a port on a router
body = self.floating_ips_client.create_floatingip(
floating_network_id=self.ext_net_id,
@@ -211,6 +221,7 @@
@decorators.attr(type='smoke')
@decorators.idempotent_id('36de4bd0-f09c-43e3-a8e1-1decc1ffd3a5')
def test_create_floating_ip_specifying_a_fixed_ip_address(self):
+ """Test creating floating ip with specified fixed ip"""
body = self.floating_ips_client.create_floatingip(
floating_network_id=self.ext_net_id,
port_id=self.ports[1]['id'],
@@ -230,6 +241,12 @@
@decorators.idempotent_id('45c4c683-ea97-41ef-9c51-5e9802f2f3d7')
def test_create_update_floatingip_with_port_multiple_ip_address(self):
+ """Test updating floating ip's fixed_ips to another ip of same port
+
+ First we create a port with 2 fixed ips, then we create a floating ip
+ with one of the fixed ips, and then we update the floating ip to
+ another fixed ip of that port.
+ """
# Find out ips that can be used for tests
list_ips = net_utils.get_unused_ip_addresses(
self.ports_client,
diff --git a/tempest/api/network/test_ports.py b/tempest/api/network/test_ports.py
index c4ad720..c6d049a 100644
--- a/tempest/api/network/test_ports.py
+++ b/tempest/api/network/test_ports.py
@@ -70,6 +70,7 @@
@decorators.attr(type='smoke')
@decorators.idempotent_id('c72c1c0c-2193-4aca-aaa4-b1442640f51c')
def test_create_update_delete_port(self):
+ """Test creating, updating and deleting port"""
# Verify port creation
body = self.ports_client.create_port(
network_id=self.network['id'],
@@ -89,6 +90,7 @@
@decorators.idempotent_id('67f1b811-f8db-43e2-86bd-72c074d4a42c')
def test_create_bulk_port(self):
+ """Test creating multiple ports in a single request"""
network1 = self.network
network2 = self._create_network()
network_list = [network1['id'], network2['id']]
@@ -107,6 +109,7 @@
@decorators.attr(type='smoke')
@decorators.idempotent_id('0435f278-40ae-48cb-a404-b8a087bc09b1')
def test_create_port_in_allowed_allocation_pools(self):
+ """Test creating port in allowed allocation pools"""
network = self._create_network()
net_id = network['id']
address = self.cidr
@@ -136,7 +139,7 @@
@decorators.attr(type='smoke')
@decorators.idempotent_id('c9a685bd-e83f-499c-939f-9f7863ca259f')
def test_show_port(self):
- # Verify the details of port
+ """Verify the details of port"""
body = self.ports_client.show_port(self.port['id'])
port = body['port']
self.assertIn('id', port)
@@ -152,7 +155,7 @@
@decorators.idempotent_id('45fcdaf2-dab0-4c13-ac6c-fcddfb579dbd')
def test_show_port_fields(self):
- # Verify specific fields of a port
+ """Verify specific fields of a port"""
fields = ['id', 'mac_address']
body = self.ports_client.show_port(self.port['id'],
fields=fields)
@@ -164,7 +167,7 @@
@decorators.attr(type='smoke')
@decorators.idempotent_id('cf95b358-3e92-4a29-a148-52445e1ac50e')
def test_list_ports(self):
- # Verify the port exists in the list of all ports
+ """Verify the port exists in the list of all ports"""
body = self.ports_client.list_ports()
ports = [port['id'] for port in body['ports']
if port['id'] == self.port['id']]
@@ -172,6 +175,7 @@
@decorators.idempotent_id('e7fe260b-1e79-4dd3-86d9-bec6a7959fc5')
def test_port_list_filter_by_ip(self):
+ """Test listing ports filtered by ip"""
# Create network and subnet
network = self._create_network()
self._create_subnet(network)
@@ -211,6 +215,7 @@
utils.is_extension_enabled('ip-substring-filtering', 'network'),
'ip-substring-filtering extension not enabled.')
def test_port_list_filter_by_ip_substr(self):
+ """Test listing ports filtered by part of ip address string"""
# Create network and subnet
network = self._create_network()
subnet = self._create_subnet(network)
@@ -289,6 +294,7 @@
@decorators.idempotent_id('5ad01ed0-0e6e-4c5d-8194-232801b15c72')
def test_port_list_filter_by_router_id(self):
+ """Test listing ports filtered by router id"""
# Create a router
network = self._create_network()
self._create_subnet(network)
@@ -313,7 +319,7 @@
@decorators.idempotent_id('ff7f117f-f034-4e0e-abff-ccef05c454b4')
def test_list_ports_fields(self):
- # Verify specific fields of ports
+ """Verify specific fields of ports"""
fields = ['id', 'mac_address']
body = self.ports_client.list_ports(fields=fields)
ports = body['ports']
@@ -324,6 +330,7 @@
@decorators.idempotent_id('63aeadd4-3b49-427f-a3b1-19ca81f06270')
def test_create_update_port_with_second_ip(self):
+ """Test updating port from 2 fixed ips to 1 fixed ip and vice versa"""
# Create a network with two subnets
network = self._create_network()
subnet_1 = self._create_subnet(network)
@@ -410,6 +417,12 @@
utils.is_extension_enabled('security-group', 'network'),
'security-group extension not enabled.')
def test_update_port_with_security_group_and_extra_attributes(self):
+ """Test updating port's security_group along with extra attributes
+
+ First we create a port with one security group, and then we update the
+ port's security_group, in the same update request we also change
+ the port's fixed ips.
+ """
self._update_port_with_security_groups(
[data_utils.rand_name('secgroup')])
@@ -418,12 +431,19 @@
utils.is_extension_enabled('security-group', 'network'),
'security-group extension not enabled.')
def test_update_port_with_two_security_groups_and_extra_attributes(self):
+ """Test updating port with two security_groups and extra attributes
+
+ First we create a port with one security group, and then we update the
+ port to two security_groups, in the same update request we also change
+ the port's fixed ips.
+ """
self._update_port_with_security_groups(
[data_utils.rand_name('secgroup'),
data_utils.rand_name('secgroup')])
@decorators.idempotent_id('13e95171-6cbd-489c-9d7c-3f9c58215c18')
def test_create_show_delete_port_user_defined_mac(self):
+ """Test creating port with user defined mac address"""
# Create a port for a legal mac
body = self.ports_client.create_port(
network_id=self.network['id'],
@@ -450,6 +470,7 @@
utils.is_extension_enabled('security-group', 'network'),
'security-group extension not enabled.')
def test_create_port_with_no_securitygroups(self):
+ """Test creating port without security groups"""
network = self._create_network()
self._create_subnet(network)
port = self.create_port(network, security_groups=[])
diff --git a/tempest/api/network/test_tags.py b/tempest/api/network/test_tags.py
index 2b9719a..5219c34 100644
--- a/tempest/api/network/test_tags.py
+++ b/tempest/api/network/test_tags.py
@@ -51,7 +51,7 @@
@decorators.idempotent_id('ee76bfaf-ac94-4d74-9ecc-4bbd4c583cb1')
def test_create_list_show_update_delete_tags(self):
- # Validate that creating a tag on a network resource works.
+ """Validate that creating a tag on a network resource works"""
tag_name = data_utils.rand_name(self.__class__.__name__ + '-Tag')
self.tags_client.create_tag('networks', self.network['id'], tag_name)
self.addCleanup(self.tags_client.delete_all_tags, 'networks',
@@ -158,6 +158,7 @@
@decorators.idempotent_id('c6231efa-9a89-4adf-b050-2a3156b8a1d9')
def test_create_check_list_and_delete_tags(self):
+ """Test tag operations on subnets/ports/routers/subnetpools"""
tag_names = self._create_tags_for_each_resource()
for i, resource in enumerate(self.SUPPORTED_RESOURCES):
@@ -181,6 +182,7 @@
@decorators.idempotent_id('663a90f5-f334-4b44-afe0-c5fc1d408791')
def test_update_and_delete_all_tags(self):
+ """Test update/delete all tags on subnets/ports/routers/subnetpools"""
self._create_tags_for_each_resource()
for resource in self.SUPPORTED_RESOURCES: