diff options
Diffstat (limited to 'openstackclient/tests')
65 files changed, 2418 insertions, 404 deletions
diff --git a/openstackclient/tests/functional/common/test_extension.py b/openstackclient/tests/functional/common/test_extension.py index d7dc398b..e3a91fe6 100644 --- a/openstackclient/tests/functional/common/test_extension.py +++ b/openstackclient/tests/functional/common/test_extension.py @@ -25,6 +25,7 @@ class ExtensionTests(base.TestCase): @classmethod def setUpClass(cls): + super(ExtensionTests, cls).setUpClass() cls.haz_network = base.is_service_enabled('network') def test_extension_list_compute(self): diff --git a/openstackclient/tests/functional/common/test_help.py b/openstackclient/tests/functional/common/test_help.py index e31d3b86..7f274099 100644 --- a/openstackclient/tests/functional/common/test_help.py +++ b/openstackclient/tests/functional/common/test_help.py @@ -12,6 +12,8 @@ import os +import fixtures + from openstackclient.tests.functional import base @@ -76,10 +78,11 @@ class HelpTests(base.TestCase): def test_commands_help_no_auth(self): """Check help commands without auth info.""" - # Pop all auth info - auth_info = {key: os.environ.pop(key) - for key in os.environ.keys() - if key.startswith('OS_')} + # Pop all auth info. os.environ will be changed in loop, so do not + # replace os.environ.keys() to os.environ + for key in os.environ.keys(): + if key.startswith('OS_'): + self.useFixture(fixtures.EnvironmentVariable(key, None)) raw_output = self.openstack('help') self.assertIn('usage: openstack', raw_output) @@ -115,6 +118,3 @@ class HelpTests(base.TestCase): self.assertIn('List containers', raw_output) raw_output = self.openstack('container list --help') self.assertIn('List containers', raw_output) - - # Restore auth info - os.environ.update(auth_info) diff --git a/openstackclient/tests/functional/common/test_quota.py b/openstackclient/tests/functional/common/test_quota.py index 1b13e95e..76c69a4d 100644 --- a/openstackclient/tests/functional/common/test_quota.py +++ b/openstackclient/tests/functional/common/test_quota.py @@ -26,6 +26,7 @@ class QuotaTests(base.TestCase): @classmethod def setUpClass(cls): + super(QuotaTests, cls).setUpClass() cls.haz_network = base.is_service_enabled('network') cls.PROJECT_NAME =\ cls.get_openstack_configuration_value('auth.project_name') diff --git a/openstackclient/tests/functional/compute/v2/test_flavor.py b/openstackclient/tests/functional/compute/v2/test_flavor.py index 0b01da51..eefd3fab 100644 --- a/openstackclient/tests/functional/compute/v2/test_flavor.py +++ b/openstackclient/tests/functional/compute/v2/test_flavor.py @@ -23,6 +23,7 @@ class FlavorTests(base.TestCase): @classmethod def setUpClass(cls): + super(FlavorTests, cls).setUpClass() # Make a project cmd_output = json.loads(cls.openstack( "project create -f json --enable " + cls.PROJECT_NAME @@ -31,8 +32,11 @@ class FlavorTests(base.TestCase): @classmethod def tearDownClass(cls): - raw_output = cls.openstack("project delete " + cls.PROJECT_NAME) - cls.assertOutput('', raw_output) + try: + raw_output = cls.openstack("project delete " + cls.PROJECT_NAME) + cls.assertOutput('', raw_output) + finally: + super(FlavorTests, cls).tearDownClass() def test_flavor_delete(self): """Test create w/project, delete multiple""" diff --git a/openstackclient/tests/functional/compute/v2/test_server.py b/openstackclient/tests/functional/compute/v2/test_server.py index c9f4d62c..b7a25996 100644 --- a/openstackclient/tests/functional/compute/v2/test_server.py +++ b/openstackclient/tests/functional/compute/v2/test_server.py @@ -25,6 +25,7 @@ class ServerTests(common.ComputeTestCase): @classmethod def setUpClass(cls): + super(ServerTests, cls).setUpClass() cls.haz_network = base.is_service_enabled('network') def test_server_list(self): diff --git a/openstackclient/tests/functional/identity/v2/common.py b/openstackclient/tests/functional/identity/v2/common.py index 69ef728b..f4bc10bd 100644 --- a/openstackclient/tests/functional/identity/v2/common.py +++ b/openstackclient/tests/functional/identity/v2/common.py @@ -12,6 +12,7 @@ import os +import fixtures from tempest.lib.common.utils import data_utils from tempest.lib import exceptions as tempest_exceptions @@ -41,17 +42,13 @@ class IdentityTests(base.TestCase): @classmethod def setUpClass(cls): - # prepare v2 env - os.environ['OS_IDENTITY_API_VERSION'] = '2.0' - auth_url = os.environ.get('OS_AUTH_URL') - if auth_url: - os.environ['OS_AUTH_URL'] = auth_url.replace('v3', 'v2.0') - + super(IdentityTests, cls).setUpClass() # create dummy project cls.project_name = data_utils.rand_name('TestProject') cls.project_description = data_utils.rand_name('description') try: cls.openstack( + '--os-identity-api-version 2 ' 'project create ' '--description %(description)s ' '--enable ' @@ -69,7 +66,25 @@ class IdentityTests(base.TestCase): @classmethod def tearDownClass(cls): - cls.openstack('project delete %s' % cls.project_name) + try: + cls.openstack( + '--os-identity-api-version 2 ' + 'project delete %s' % cls.project_name) + finally: + super(IdentityTests, cls).tearDownClass() + + def setUp(self): + super(IdentityTests, self).setUp() + # prepare v2 env + ver_fixture = fixtures.EnvironmentVariable( + 'OS_IDENTITY_API_VERSION', '2.0') + self.useFixture(ver_fixture) + auth_url = os.environ.get('OS_AUTH_URL') + if auth_url: + auth_url_fixture = fixtures.EnvironmentVariable( + 'OS_AUTH_URL', auth_url.replace('v3', 'v2.0') + ) + self.useFixture(auth_url_fixture) def _create_dummy_project(self, add_clean_up=True): project_name = data_utils.rand_name('TestProject') diff --git a/openstackclient/tests/functional/identity/v3/common.py b/openstackclient/tests/functional/identity/v3/common.py index 1ec3ac92..6d7896d8 100644 --- a/openstackclient/tests/functional/identity/v3/common.py +++ b/openstackclient/tests/functional/identity/v3/common.py @@ -12,6 +12,7 @@ import os +import fixtures from tempest.lib.common.utils import data_utils from openstackclient.tests.functional import base @@ -53,16 +54,12 @@ class IdentityTests(base.TestCase): @classmethod def setUpClass(cls): - # prepare v3 env - os.environ['OS_IDENTITY_API_VERSION'] = '3' - auth_url = os.environ.get('OS_AUTH_URL') - if auth_url: - os.environ['OS_AUTH_URL'] = auth_url.replace('v2.0', 'v3') - + super(IdentityTests, cls).setUpClass() # create dummy domain cls.domain_name = data_utils.rand_name('TestDomain') cls.domain_description = data_utils.rand_name('description') cls.openstack( + '--os-identity-api-version 3 ' 'domain create ' '--description %(description)s ' '--enable ' @@ -73,6 +70,7 @@ class IdentityTests(base.TestCase): cls.project_name = data_utils.rand_name('TestProject') cls.project_description = data_utils.rand_name('description') cls.openstack( + '--os-identity-api-version 3 ' 'project create ' '--domain %(domain)s ' '--description %(description)s ' @@ -83,11 +81,30 @@ class IdentityTests(base.TestCase): @classmethod def tearDownClass(cls): - # delete dummy project - cls.openstack('project delete %s' % cls.project_name) - # disable and delete dummy domain - cls.openstack('domain set --disable %s' % cls.domain_name) - cls.openstack('domain delete %s' % cls.domain_name) + try: + # delete dummy project + cls.openstack('--os-identity-api-version 3 ' + 'project delete %s' % cls.project_name) + # disable and delete dummy domain + cls.openstack('--os-identity-api-version 3 ' + 'domain set --disable %s' % cls.domain_name) + cls.openstack('--os-identity-api-version 3 ' + 'domain delete %s' % cls.domain_name) + finally: + super(IdentityTests, cls).tearDownClass() + + def setUp(self): + super(IdentityTests, self).setUp() + # prepare v3 env + ver_fixture = fixtures.EnvironmentVariable( + 'OS_IDENTITY_API_VERSION', '3') + self.useFixture(ver_fixture) + auth_url = os.environ.get('OS_AUTH_URL') + if auth_url: + auth_url_fixture = fixtures.EnvironmentVariable( + 'OS_AUTH_URL', auth_url.replace('v2.0', 'v3') + ) + self.useFixture(auth_url_fixture) def _create_dummy_user(self, add_clean_up=True): username = data_utils.rand_name('TestUser') diff --git a/openstackclient/tests/functional/image/v1/test_image.py b/openstackclient/tests/functional/image/v1/test_image.py index 901f4337..fa073f99 100644 --- a/openstackclient/tests/functional/image/v1/test_image.py +++ b/openstackclient/tests/functional/image/v1/test_image.py @@ -11,9 +11,10 @@ # under the License. import json -import os import uuid +import fixtures + from openstackclient.tests.functional import base @@ -25,8 +26,9 @@ class ImageTests(base.TestCase): @classmethod def setUpClass(cls): - os.environ['OS_IMAGE_API_VERSION'] = '1' + super(ImageTests, cls).setUpClass() json_output = json.loads(cls.openstack( + '--os-image-api-version 1 ' 'image create -f json ' + cls.NAME )) @@ -35,10 +37,21 @@ class ImageTests(base.TestCase): @classmethod def tearDownClass(cls): - cls.openstack( - 'image delete ' + - cls.image_id + try: + cls.openstack( + '--os-image-api-version 1 ' + 'image delete ' + + cls.image_id + ) + finally: + super(ImageTests, cls).tearDownClass() + + def setUp(self): + super(ImageTests, self).setUp() + ver_fixture = fixtures.EnvironmentVariable( + 'OS_IMAGE_API_VERSION', '1' ) + self.useFixture(ver_fixture) def test_image_list(self): json_output = json.loads(self.openstack( diff --git a/openstackclient/tests/functional/image/v2/test_image.py b/openstackclient/tests/functional/image/v2/test_image.py index 8fadd200..278ba5b9 100644 --- a/openstackclient/tests/functional/image/v2/test_image.py +++ b/openstackclient/tests/functional/image/v2/test_image.py @@ -11,9 +11,9 @@ # under the License. import json -import os import uuid +import fixtures # from glanceclient import exc as image_exceptions from openstackclient.tests.functional import base @@ -27,8 +27,9 @@ class ImageTests(base.TestCase): @classmethod def setUpClass(cls): - os.environ['OS_IMAGE_API_VERSION'] = '2' + super(ImageTests, cls).setUpClass() json_output = json.loads(cls.openstack( + '--os-image-api-version 2 ' 'image create -f json ' + cls.NAME )) @@ -37,10 +38,21 @@ class ImageTests(base.TestCase): @classmethod def tearDownClass(cls): - cls.openstack( - 'image delete ' + - cls.image_id + try: + cls.openstack( + '--os-image-api-version 2 ' + 'image delete ' + + cls.image_id + ) + finally: + super(ImageTests, cls).tearDownClass() + + def setUp(self): + super(ImageTests, self).setUp() + ver_fixture = fixtures.EnvironmentVariable( + 'OS_IMAGE_API_VERSION', '2' ) + self.useFixture(ver_fixture) def test_image_list(self): json_output = json.loads(self.openstack( @@ -51,6 +63,24 @@ class ImageTests(base.TestCase): [img['Name'] for img in json_output] ) + def test_image_list_with_name_filter(self): + json_output = json.loads(self.openstack( + 'image list --name ' + self.NAME + ' -f json' + )) + self.assertIn( + self.NAME, + [img['Name'] for img in json_output] + ) + + def test_image_list_with_status_filter(self): + json_output = json.loads(self.openstack( + 'image list ' + ' --status active -f json' + )) + self.assertIn( + 'active', + [img['Status'] for img in json_output] + ) + def test_image_attributes(self): """Test set, unset, show on attributes, tags and properties""" diff --git a/openstackclient/tests/functional/network/v2/common.py b/openstackclient/tests/functional/network/v2/common.py index bed07878..a18bc48f 100644 --- a/openstackclient/tests/functional/network/v2/common.py +++ b/openstackclient/tests/functional/network/v2/common.py @@ -10,6 +10,9 @@ # License for the specific language governing permissions and limitations # under the License. +import json +import uuid + from openstackclient.tests.functional import base @@ -18,5 +21,83 @@ class NetworkTests(base.TestCase): @classmethod def setUpClass(cls): - # super(NetworkTests, cls).setUp() + super(NetworkTests, cls).setUpClass() cls.haz_network = base.is_service_enabled('network') + + +class NetworkTagTests(NetworkTests): + """Functional tests with tag operation""" + + base_command = None + + def test_tag_operation(self): + # Get project IDs + cmd_output = json.loads(self.openstack('token issue -f json ')) + auth_project_id = cmd_output['project_id'] + + # Network create with no options + name1 = self._create_resource_and_tag_check('', []) + # Network create with tags + name2 = self._create_resource_and_tag_check('--tag red --tag blue', + ['red', 'blue']) + # Network create with no tag explicitly + name3 = self._create_resource_and_tag_check('--no-tag', []) + + self._set_resource_and_tag_check('set', name1, '--tag red --tag green', + ['red', 'green']) + + list_expected = ((name1, ['red', 'green']), + (name2, ['red', 'blue']), + (name3, [])) + self._list_tag_check(auth_project_id, list_expected) + + self._set_resource_and_tag_check('set', name1, '--tag blue', + ['red', 'green', 'blue']) + self._set_resource_and_tag_check( + 'set', name1, + '--no-tag --tag yellow --tag orange --tag purple', + ['yellow', 'orange', 'purple']) + self._set_resource_and_tag_check('unset', name1, '--tag yellow', + ['orange', 'purple']) + self._set_resource_and_tag_check('unset', name1, '--all-tag', []) + self._set_resource_and_tag_check('set', name2, '--no-tag', []) + + def _assertTagsEqual(self, expected, actual): + # TODO(amotoki): Should migrate to cliff format columns. + # At now, unit test assert method needs to be replaced + # to handle format columns, so format_list() is used. + # NOTE: The order of tag is undeterminestic. + actual_tags = filter(bool, actual.split(', ')) + self.assertEqual(set(expected), set(actual_tags)) + + def _list_tag_check(self, project_id, expected): + cmd_output = json.loads(self.openstack( + '{} list --long --project {} -f json'.format(self.base_command, + project_id))) + for name, tags in expected: + net = [n for n in cmd_output if n['Name'] == name][0] + self._assertTagsEqual(tags, net['Tags']) + + def _create_resource_for_tag_test(self, name, args): + return json.loads(self.openstack( + '{} create -f json {} {}'.format(self.base_command, args, name) + )) + + def _create_resource_and_tag_check(self, args, expected): + name = uuid.uuid4().hex + cmd_output = self._create_resource_for_tag_test(name, args) + self.addCleanup( + self.openstack, '{} delete {}'.format(self.base_command, name)) + self.assertIsNotNone(cmd_output["id"]) + self._assertTagsEqual(expected, cmd_output['tags']) + return name + + def _set_resource_and_tag_check(self, command, name, args, expected): + cmd_output = self.openstack( + '{} {} {} {}'.format(self.base_command, command, args, name) + ) + self.assertFalse(cmd_output) + cmd_output = json.loads(self.openstack( + '{} show -f json {}'.format(self.base_command, name) + )) + self._assertTagsEqual(expected, cmd_output['tags']) diff --git a/openstackclient/tests/functional/network/v2/test_floating_ip.py b/openstackclient/tests/functional/network/v2/test_floating_ip.py index 96521f09..1d11fc5d 100644 --- a/openstackclient/tests/functional/network/v2/test_floating_ip.py +++ b/openstackclient/tests/functional/network/v2/test_floating_ip.py @@ -19,17 +19,18 @@ from openstackclient.tests.functional.network.v2 import common class FloatingIpTests(common.NetworkTests): """Functional tests for floating ip""" - EXTERNAL_NETWORK_NAME = uuid.uuid4().hex - EXTERNAL_SUBNET_NAME = uuid.uuid4().hex - PRIVATE_NETWORK_NAME = uuid.uuid4().hex - PRIVATE_SUBNET_NAME = uuid.uuid4().hex - ROUTER = uuid.uuid4().hex - PORT_NAME = uuid.uuid4().hex @classmethod def setUpClass(cls): common.NetworkTests.setUpClass() if cls.haz_network: + cls.EXTERNAL_NETWORK_NAME = uuid.uuid4().hex + cls.EXTERNAL_SUBNET_NAME = uuid.uuid4().hex + cls.PRIVATE_NETWORK_NAME = uuid.uuid4().hex + cls.PRIVATE_SUBNET_NAME = uuid.uuid4().hex + cls.ROUTER = uuid.uuid4().hex + cls.PORT_NAME = uuid.uuid4().hex + # Create a network for the floating ip json_output = json.loads(cls.openstack( 'network create -f json ' + @@ -87,19 +88,22 @@ class FloatingIpTests(common.NetworkTests): @classmethod def tearDownClass(cls): - if cls.haz_network: - del_output = cls.openstack( - 'subnet delete ' + - cls.EXTERNAL_SUBNET_NAME + ' ' + - cls.PRIVATE_SUBNET_NAME - ) - cls.assertOutput('', del_output) - del_output = cls.openstack( - 'network delete ' + - cls.EXTERNAL_NETWORK_NAME + ' ' + - cls.PRIVATE_NETWORK_NAME - ) - cls.assertOutput('', del_output) + try: + if cls.haz_network: + del_output = cls.openstack( + 'subnet delete ' + + cls.EXTERNAL_SUBNET_NAME + ' ' + + cls.PRIVATE_SUBNET_NAME + ) + cls.assertOutput('', del_output) + del_output = cls.openstack( + 'network delete ' + + cls.EXTERNAL_NETWORK_NAME + ' ' + + cls.PRIVATE_NETWORK_NAME + ) + cls.assertOutput('', del_output) + finally: + super(FloatingIpTests, cls).tearDownClass() def setUp(self): super(FloatingIpTests, self).setUp() diff --git a/openstackclient/tests/functional/network/v2/test_ip_availability.py b/openstackclient/tests/functional/network/v2/test_ip_availability.py index 1aa0f64a..86a53c0c 100644 --- a/openstackclient/tests/functional/network/v2/test_ip_availability.py +++ b/openstackclient/tests/functional/network/v2/test_ip_availability.py @@ -23,9 +23,10 @@ class IPAvailabilityTests(common.NetworkTests): def setUpClass(cls): common.NetworkTests.setUpClass() if cls.haz_network: - # Create a network for the subnet. cls.NAME = uuid.uuid4().hex cls.NETWORK_NAME = uuid.uuid4().hex + + # Create a network for the subnet cls.openstack( 'network create ' + cls.NETWORK_NAME @@ -40,17 +41,20 @@ class IPAvailabilityTests(common.NetworkTests): @classmethod def tearDownClass(cls): - if cls.haz_network: - raw_subnet = cls.openstack( - 'subnet delete ' + - cls.NAME - ) - raw_network = cls.openstack( - 'network delete ' + - cls.NETWORK_NAME - ) - cls.assertOutput('', raw_subnet) - cls.assertOutput('', raw_network) + try: + if cls.haz_network: + raw_subnet = cls.openstack( + 'subnet delete ' + + cls.NAME + ) + raw_network = cls.openstack( + 'network delete ' + + cls.NETWORK_NAME + ) + cls.assertOutput('', raw_subnet) + cls.assertOutput('', raw_network) + finally: + super(IPAvailabilityTests, cls).tearDownClass() def setUp(self): super(IPAvailabilityTests, self).setUp() diff --git a/openstackclient/tests/functional/network/v2/test_network.py b/openstackclient/tests/functional/network/v2/test_network.py index b23323a0..40fb382a 100644 --- a/openstackclient/tests/functional/network/v2/test_network.py +++ b/openstackclient/tests/functional/network/v2/test_network.py @@ -16,9 +16,11 @@ import uuid from openstackclient.tests.functional.network.v2 import common -class NetworkTests(common.NetworkTests): +class NetworkTests(common.NetworkTagTests): """Functional tests for network""" + base_command = 'network' + def setUp(self): super(NetworkTests, self).setUp() # Nothing in this class works with Nova Network @@ -361,7 +363,7 @@ class NetworkTests(common.NetworkTests): self.assertNotIn(name2, col_name) def test_network_dhcp_agent(self): - if self.haz_network: + if not self.haz_network: self.skipTest("No Network service present") name1 = uuid.uuid4().hex @@ -408,7 +410,7 @@ class NetworkTests(common.NetworkTests): def test_network_set(self): """Tests create options, set, show, delete""" - if self.haz_network: + if not self.haz_network: self.skipTest("No Network service present") name = uuid.uuid4().hex diff --git a/openstackclient/tests/functional/network/v2/test_network_agent.py b/openstackclient/tests/functional/network/v2/test_network_agent.py index 16487955..0c74ea1d 100644 --- a/openstackclient/tests/functional/network/v2/test_network_agent.py +++ b/openstackclient/tests/functional/network/v2/test_network_agent.py @@ -137,3 +137,39 @@ class NetworkAgentListTests(common.NetworkTests): self.assertIn( agent_id, col_name ) + + def test_network_agent_list_routers(self): + """Add agent to router, list agents on router, delete.""" + name = uuid.uuid4().hex + cmd_output = json.loads(self.openstack( + 'router create -f json ' + name)) + + self.addCleanup(self.openstack, 'router delete ' + name) + # Get router ID + router_id = cmd_output['id'] + # Get l3 agent id + cmd_output = json.loads(self.openstack( + 'network agent list -f json --agent-type l3')) + + # Check at least one L3 agent is included in the response. + self.assertTrue(cmd_output) + agent_id = cmd_output[0]['ID'] + + # Add router to agent + self.openstack( + 'network agent add router --l3 ' + agent_id + ' ' + router_id) + + # Test router list --agent + cmd_output = json.loads(self.openstack( + 'network agent list -f json --router ' + router_id)) + + agent_ids = [x['ID'] for x in cmd_output] + self.assertIn(agent_id, agent_ids) + + # Remove router from agent + self.openstack( + 'network agent remove router --l3 ' + agent_id + ' ' + router_id) + cmd_output = json.loads(self.openstack( + 'network agent list -f json --router ' + router_id)) + agent_ids = [x['ID'] for x in cmd_output] + self.assertNotIn(agent_id, agent_ids) diff --git a/openstackclient/tests/functional/network/v2/test_network_meter_rule.py b/openstackclient/tests/functional/network/v2/test_network_meter_rule.py index b7090707..31bc0845 100644 --- a/openstackclient/tests/functional/network/v2/test_network_meter_rule.py +++ b/openstackclient/tests/functional/network/v2/test_network_meter_rule.py @@ -22,7 +22,6 @@ from openstackclient.tests.functional.network.v2 import common class TestMeterRule(common.NetworkTests): """Functional tests for meter rule""" - METER_NAME = uuid.uuid4().hex METER_ID = None METER_RULE_ID = None @@ -30,6 +29,8 @@ class TestMeterRule(common.NetworkTests): def setUpClass(cls): common.NetworkTests.setUpClass() if cls.haz_network: + cls.METER_NAME = uuid.uuid4().hex + json_output = json.loads(cls.openstack( 'network meter create -f json ' + cls.METER_NAME @@ -38,13 +39,15 @@ class TestMeterRule(common.NetworkTests): @classmethod def tearDownClass(cls): - common.NetworkTests.tearDownClass() - if cls.haz_network: - raw_output = cls.openstack( - 'network meter delete ' + - cls.METER_ID - ) - cls.assertOutput('', raw_output) + try: + if cls.haz_network: + raw_output = cls.openstack( + 'network meter delete ' + + cls.METER_ID + ) + cls.assertOutput('', raw_output) + finally: + common.NetworkTests.tearDownClass() def setUp(self): super(TestMeterRule, self).setUp() diff --git a/openstackclient/tests/functional/network/v2/test_network_qos_policy.py b/openstackclient/tests/functional/network/v2/test_network_qos_policy.py index 282efbfa..53c15ecf 100644 --- a/openstackclient/tests/functional/network/v2/test_network_qos_policy.py +++ b/openstackclient/tests/functional/network/v2/test_network_qos_policy.py @@ -19,8 +19,7 @@ from openstackclient.tests.functional.network.v2 import common class NetworkQosPolicyTests(common.NetworkTests): - """Functional tests for QoS policy. """ - NAME = uuid.uuid4().hex + """Functional tests for QoS policy""" HEADERS = ['Name'] FIELDS = ['name'] @@ -28,6 +27,8 @@ class NetworkQosPolicyTests(common.NetworkTests): def setUpClass(cls): common.NetworkTests.setUpClass() if cls.haz_network: + cls.NAME = uuid.uuid4().hex + opts = cls.get_opts(cls.FIELDS) raw_output = cls.openstack( 'network qos policy create ' + @@ -38,12 +39,15 @@ class NetworkQosPolicyTests(common.NetworkTests): @classmethod def tearDownClass(cls): - if cls.haz_network: - raw_output = cls.openstack( - 'network qos policy delete ' + - cls.NAME - ) - cls.assertOutput('', raw_output) + try: + if cls.haz_network: + raw_output = cls.openstack( + 'network qos policy delete ' + + cls.NAME + ) + cls.assertOutput('', raw_output) + finally: + super(NetworkQosPolicyTests, cls).tearDownClass() def setUp(self): super(NetworkQosPolicyTests, self).setUp() @@ -68,3 +72,16 @@ class NetworkQosPolicyTests(common.NetworkTests): raw_output = self.openstack('network qos policy show ' + self.NAME + opts) self.assertEqual("True\n", raw_output) + + def test_qos_policy_default(self): + self.openstack('network qos policy set --default ' + self.NAME) + opts = self.get_opts(['is_default']) + raw_output = self.openstack('network qos policy show ' + self.NAME + + opts) + self.assertEqual("True\n", raw_output) + + self.openstack('network qos policy set --no-default ' + self.NAME) + opts = self.get_opts(['is_default']) + raw_output = self.openstack('network qos policy show ' + self.NAME + + opts) + self.assertEqual("False\n", raw_output) diff --git a/openstackclient/tests/functional/network/v2/test_network_qos_rule.py b/openstackclient/tests/functional/network/v2/test_network_qos_rule.py index c6437d9c..8b34422f 100644 --- a/openstackclient/tests/functional/network/v2/test_network_qos_rule.py +++ b/openstackclient/tests/functional/network/v2/test_network_qos_rule.py @@ -21,7 +21,6 @@ from openstackclient.tests.functional.network.v2 import common class NetworkQosRuleTestsMinimumBandwidth(common.NetworkTests): """Functional tests for QoS minimum bandwidth rule""" RULE_ID = None - QOS_POLICY_NAME = 'qos_policy_' + uuid.uuid4().hex MIN_KBPS = 2800 MIN_KBPS_MODIFIED = 7500 DIRECTION = '--egress' @@ -33,6 +32,8 @@ class NetworkQosRuleTestsMinimumBandwidth(common.NetworkTests): def setUpClass(cls): common.NetworkTests.setUpClass() if cls.haz_network: + cls.QOS_POLICY_NAME = 'qos_policy_' + uuid.uuid4().hex + opts = cls.get_opts(cls.FIELDS) cls.openstack( 'network qos policy create ' + @@ -50,17 +51,20 @@ class NetworkQosRuleTestsMinimumBandwidth(common.NetworkTests): @classmethod def tearDownClass(cls): - if cls.haz_network: - raw_output = cls.openstack( - 'network qos rule delete ' + - cls.QOS_POLICY_NAME + ' ' + - cls.RULE_ID - ) - cls.openstack( - 'network qos policy delete ' + - cls.QOS_POLICY_NAME - ) - cls.assertOutput('', raw_output) + try: + if cls.haz_network: + raw_output = cls.openstack( + 'network qos rule delete ' + + cls.QOS_POLICY_NAME + ' ' + + cls.RULE_ID + ) + cls.openstack( + 'network qos policy delete ' + + cls.QOS_POLICY_NAME + ) + cls.assertOutput('', raw_output) + finally: + super(NetworkQosRuleTestsMinimumBandwidth, cls).tearDownClass() def setUp(self): super(NetworkQosRuleTestsMinimumBandwidth, self).setUp() @@ -122,14 +126,18 @@ class NetworkQosRuleTestsDSCPMarking(common.NetworkTests): @classmethod def tearDownClass(cls): - if cls.haz_network: - raw_output = cls.openstack( - 'network qos rule delete ' + - cls.QOS_POLICY_NAME + ' ' + - cls.RULE_ID - ) - cls.openstack('network qos policy delete ' + cls.QOS_POLICY_NAME) - cls.assertOutput('', raw_output) + try: + if cls.haz_network: + raw_output = cls.openstack( + 'network qos rule delete ' + + cls.QOS_POLICY_NAME + ' ' + + cls.RULE_ID + ) + cls.openstack( + 'network qos policy delete ' + cls.QOS_POLICY_NAME) + cls.assertOutput('', raw_output) + finally: + super(NetworkQosRuleTestsDSCPMarking, cls).tearDownClass() def setUp(self): super(NetworkQosRuleTestsDSCPMarking, self).setUp() @@ -169,6 +177,8 @@ class NetworkQosRuleTestsBandwidthLimit(common.NetworkTests): MAX_KBPS_MODIFIED = 15000 MAX_BURST_KBITS = 1400 MAX_BURST_KBITS_MODIFIED = 1800 + RULE_DIRECTION = 'egress' + RULE_DIRECTION_MODIFIED = 'ingress' HEADERS = ['ID'] FIELDS = ['id'] TYPE = 'bandwidth-limit' @@ -187,6 +197,7 @@ class NetworkQosRuleTestsBandwidthLimit(common.NetworkTests): '--type ' + cls.TYPE + ' ' + '--max-kbps ' + str(cls.MAX_KBPS) + ' ' + '--max-burst-kbits ' + str(cls.MAX_BURST_KBITS) + ' ' + + '--' + cls.RULE_DIRECTION + ' ' + cls.QOS_POLICY_NAME + opts ) @@ -194,14 +205,18 @@ class NetworkQosRuleTestsBandwidthLimit(common.NetworkTests): @classmethod def tearDownClass(cls): - if cls.haz_network: - raw_output = cls.openstack( - 'network qos rule delete ' + - cls.QOS_POLICY_NAME + ' ' + - cls.RULE_ID - ) - cls.openstack('network qos policy delete ' + cls.QOS_POLICY_NAME) - cls.assertOutput('', raw_output) + try: + if cls.haz_network: + raw_output = cls.openstack( + 'network qos rule delete ' + + cls.QOS_POLICY_NAME + ' ' + + cls.RULE_ID + ) + cls.openstack( + 'network qos policy delete ' + cls.QOS_POLICY_NAME) + cls.assertOutput('', raw_output) + finally: + super(NetworkQosRuleTestsBandwidthLimit, cls).tearDownClass() def setUp(self): super(NetworkQosRuleTestsBandwidthLimit, self).setUp() @@ -226,14 +241,13 @@ class NetworkQosRuleTestsBandwidthLimit(common.NetworkTests): self.openstack('network qos rule set --max-kbps ' + str(self.MAX_KBPS_MODIFIED) + ' --max-burst-kbits ' + str(self.MAX_BURST_KBITS_MODIFIED) + ' ' + + '--' + self.RULE_DIRECTION_MODIFIED + ' ' + self.QOS_POLICY_NAME + ' ' + self.RULE_ID) - opts = self.get_opts(['max_kbps']) - raw_output = self.openstack('network qos rule show ' + - self.QOS_POLICY_NAME + ' ' + self.RULE_ID + - opts) - self.assertEqual(str(self.MAX_KBPS_MODIFIED) + "\n", raw_output) - opts = self.get_opts(['max_burst_kbps']) + opts = self.get_opts(['direction', 'max_burst_kbps', 'max_kbps']) raw_output = self.openstack('network qos rule show ' + self.QOS_POLICY_NAME + ' ' + self.RULE_ID + opts) - self.assertEqual(str(self.MAX_BURST_KBITS_MODIFIED) + "\n", raw_output) + expected = (str(self.RULE_DIRECTION_MODIFIED) + "\n" + + str(self.MAX_BURST_KBITS_MODIFIED) + "\n" + + str(self.MAX_KBPS_MODIFIED) + "\n") + self.assertEqual(expected, raw_output) diff --git a/openstackclient/tests/functional/network/v2/test_network_rbac.py b/openstackclient/tests/functional/network/v2/test_network_rbac.py index 0d5492e5..2206761f 100644 --- a/openstackclient/tests/functional/network/v2/test_network_rbac.py +++ b/openstackclient/tests/functional/network/v2/test_network_rbac.py @@ -16,9 +16,7 @@ from openstackclient.tests.functional.network.v2 import common class NetworkRBACTests(common.NetworkTests): - """Functional tests for network rbac. """ - NET_NAME = uuid.uuid4().hex - PROJECT_NAME = uuid.uuid4().hex + """Functional tests for network rbac""" OBJECT_ID = None ID = None HEADERS = ['ID'] @@ -28,6 +26,9 @@ class NetworkRBACTests(common.NetworkTests): def setUpClass(cls): common.NetworkTests.setUpClass() if cls.haz_network: + cls.NET_NAME = uuid.uuid4().hex + cls.PROJECT_NAME = uuid.uuid4().hex + opts = cls.get_opts(cls.FIELDS) raw_output = cls.openstack( 'network create ' + cls.NET_NAME + opts @@ -46,15 +47,18 @@ class NetworkRBACTests(common.NetworkTests): @classmethod def tearDownClass(cls): - if cls.haz_network: - raw_output_rbac = cls.openstack( - 'network rbac delete ' + cls.ID - ) - raw_output_network = cls.openstack( - 'network delete ' + cls.OBJECT_ID - ) - cls.assertOutput('', raw_output_rbac) - cls.assertOutput('', raw_output_network) + try: + if cls.haz_network: + raw_output_rbac = cls.openstack( + 'network rbac delete ' + cls.ID + ) + raw_output_network = cls.openstack( + 'network delete ' + cls.OBJECT_ID + ) + cls.assertOutput('', raw_output_rbac) + cls.assertOutput('', raw_output_network) + finally: + super(NetworkRBACTests, cls).tearDownClass() def setUp(self): super(NetworkRBACTests, self).setUp() diff --git a/openstackclient/tests/functional/network/v2/test_network_segment.py b/openstackclient/tests/functional/network/v2/test_network_segment.py index 7fc79746..b34515fa 100644 --- a/openstackclient/tests/functional/network/v2/test_network_segment.py +++ b/openstackclient/tests/functional/network/v2/test_network_segment.py @@ -17,8 +17,6 @@ from openstackclient.tests.functional.network.v2 import common class NetworkSegmentTests(common.NetworkTests): """Functional tests for network segment""" - NETWORK_NAME = uuid.uuid4().hex - PHYSICAL_NETWORK_NAME = uuid.uuid4().hex NETWORK_SEGMENT_ID = None NETWORK_ID = None NETWORK_SEGMENT_EXTENSION = None @@ -27,7 +25,10 @@ class NetworkSegmentTests(common.NetworkTests): def setUpClass(cls): common.NetworkTests.setUpClass() if cls.haz_network: - # Create a network for the segment. + cls.NETWORK_NAME = uuid.uuid4().hex + cls.PHYSICAL_NETWORK_NAME = uuid.uuid4().hex + + # Create a network for the segment opts = cls.get_opts(['id']) raw_output = cls.openstack( 'network create ' + cls.NETWORK_NAME + opts @@ -54,11 +55,14 @@ class NetworkSegmentTests(common.NetworkTests): @classmethod def tearDownClass(cls): - if cls.haz_network: - raw_output = cls.openstack( - 'network delete ' + cls.NETWORK_NAME - ) - cls.assertOutput('', raw_output) + try: + if cls.haz_network: + raw_output = cls.openstack( + 'network delete ' + cls.NETWORK_NAME + ) + cls.assertOutput('', raw_output) + finally: + super(NetworkSegmentTests, cls).tearDownClass() def setUp(self): super(NetworkSegmentTests, self).setUp() diff --git a/openstackclient/tests/functional/network/v2/test_port.py b/openstackclient/tests/functional/network/v2/test_port.py index 6659e3e0..a7059790 100644 --- a/openstackclient/tests/functional/network/v2/test_port.py +++ b/openstackclient/tests/functional/network/v2/test_port.py @@ -16,8 +16,11 @@ import uuid from openstackclient.tests.functional.network.v2 import common -class PortTests(common.NetworkTests): +class PortTests(common.NetworkTagTests): """Functional tests for port""" + + base_command = 'port' + NAME = uuid.uuid4().hex NETWORK_NAME = uuid.uuid4().hex @@ -25,18 +28,24 @@ class PortTests(common.NetworkTests): def setUpClass(cls): common.NetworkTests.setUpClass() if cls.haz_network: - # Create a network for the port + cls.NAME = uuid.uuid4().hex + cls.NETWORK_NAME = uuid.uuid4().hex + + # Create a network for the port tests cls.openstack( 'network create ' + cls.NETWORK_NAME ) @classmethod def tearDownClass(cls): - if cls.haz_network: - raw_output = cls.openstack( - 'network delete ' + cls.NETWORK_NAME - ) - cls.assertOutput('', raw_output) + try: + if cls.haz_network: + raw_output = cls.openstack( + 'network delete ' + cls.NETWORK_NAME + ) + cls.assertOutput('', raw_output) + finally: + super(PortTests, cls).tearDownClass() def setUp(self): super(PortTests, self).setUp() @@ -246,3 +255,9 @@ class PortTests(common.NetworkTests): sg_id2, json_output.get('security_group_ids'), ) + + def _create_resource_for_tag_test(self, name, args): + return json.loads(self.openstack( + '{} create -f json --network {} {} {}' + .format(self.base_command, self.NETWORK_NAME, args, name) + )) diff --git a/openstackclient/tests/functional/network/v2/test_router.py b/openstackclient/tests/functional/network/v2/test_router.py index 313feefc..95c5a96f 100644 --- a/openstackclient/tests/functional/network/v2/test_router.py +++ b/openstackclient/tests/functional/network/v2/test_router.py @@ -16,9 +16,11 @@ import uuid from openstackclient.tests.functional.network.v2 import common -class RouterTests(common.NetworkTests): +class RouterTests(common.NetworkTagTests): """Functional tests for router""" + base_command = 'router' + def setUp(self): super(RouterTests, self).setUp() # Nothing in this class works with Nova Network @@ -151,6 +153,40 @@ class RouterTests(common.NetworkTests): self.assertIn(name1, names) self.assertIn(name2, names) + def test_router_list_l3_agent(self): + """Tests create router, add l3 agent, list, delete""" + name = uuid.uuid4().hex + cmd_output = json.loads(self.openstack( + 'router create -f json ' + name)) + + self.addCleanup(self.openstack, 'router delete ' + name) + # Get router ID + router_id = cmd_output['id'] + # Get l3 agent id + cmd_output = json.loads(self.openstack( + 'network agent list -f json --agent-type l3')) + + # Check at least one L3 agent is included in the response. + self.assertTrue(cmd_output) + agent_id = cmd_output[0]['ID'] + + # Add router to agent + self.openstack( + 'network agent add router --l3 ' + agent_id + ' ' + router_id) + + cmd_output = json.loads(self.openstack( + 'router list -f json --agent ' + agent_id)) + router_ids = [x['ID'] for x in cmd_output] + self.assertIn(router_id, router_ids) + + # Remove router from agent + self.openstack( + 'network agent remove router --l3 ' + agent_id + ' ' + router_id) + cmd_output = json.loads(self.openstack( + 'router list -f json --agent ' + agent_id)) + router_ids = [x['ID'] for x in cmd_output] + self.assertNotIn(router_id, router_ids) + def test_router_set_show_unset(self): """Tests create router, set, unset, show""" diff --git a/openstackclient/tests/functional/network/v2/test_security_group.py b/openstackclient/tests/functional/network/v2/test_security_group.py index 2a9c0b0a..b601c913 100644 --- a/openstackclient/tests/functional/network/v2/test_security_group.py +++ b/openstackclient/tests/functional/network/v2/test_security_group.py @@ -17,8 +17,6 @@ from openstackclient.tests.functional.network.v2 import common class SecurityGroupTests(common.NetworkTests): """Functional tests for security group""" - NAME = uuid.uuid4().hex - OTHER_NAME = uuid.uuid4().hex HEADERS = ['Name'] FIELDS = ['name'] @@ -26,6 +24,9 @@ class SecurityGroupTests(common.NetworkTests): def setUpClass(cls): common.NetworkTests.setUpClass() if cls.haz_network: + cls.NAME = uuid.uuid4().hex + cls.OTHER_NAME = uuid.uuid4().hex + opts = cls.get_opts(cls.FIELDS) raw_output = cls.openstack( 'security group create ' + @@ -37,20 +38,23 @@ class SecurityGroupTests(common.NetworkTests): @classmethod def tearDownClass(cls): - if cls.haz_network: - # Rename test - raw_output = cls.openstack( - 'security group set --name ' + - cls.OTHER_NAME + ' ' + - cls.NAME - ) - cls.assertOutput('', raw_output) - # Delete test - raw_output = cls.openstack( - 'security group delete ' + - cls.OTHER_NAME - ) - cls.assertOutput('', raw_output) + try: + if cls.haz_network: + # Rename test + raw_output = cls.openstack( + 'security group set --name ' + + cls.OTHER_NAME + ' ' + + cls.NAME + ) + cls.assertOutput('', raw_output) + # Delete test + raw_output = cls.openstack( + 'security group delete ' + + cls.OTHER_NAME + ) + cls.assertOutput('', raw_output) + finally: + super(SecurityGroupTests, cls).tearDownClass() def setUp(self): super(SecurityGroupTests, self).setUp() diff --git a/openstackclient/tests/functional/network/v2/test_security_group_rule.py b/openstackclient/tests/functional/network/v2/test_security_group_rule.py index 93f98642..40951a01 100644 --- a/openstackclient/tests/functional/network/v2/test_security_group_rule.py +++ b/openstackclient/tests/functional/network/v2/test_security_group_rule.py @@ -17,7 +17,6 @@ from openstackclient.tests.functional.network.v2 import common class SecurityGroupRuleTests(common.NetworkTests): """Functional tests for security group rule""" - SECURITY_GROUP_NAME = uuid.uuid4().hex SECURITY_GROUP_RULE_ID = None NAME_FIELD = ['name'] ID_FIELD = ['id'] @@ -27,7 +26,9 @@ class SecurityGroupRuleTests(common.NetworkTests): def setUpClass(cls): common.NetworkTests.setUpClass() if cls.haz_network: - # Create the security group to hold the rule. + cls.SECURITY_GROUP_NAME = uuid.uuid4().hex + + # Create the security group to hold the rule opts = cls.get_opts(cls.NAME_FIELD) raw_output = cls.openstack( 'security group create ' + @@ -50,18 +51,20 @@ class SecurityGroupRuleTests(common.NetworkTests): @classmethod def tearDownClass(cls): - if cls.haz_network: - raw_output = cls.openstack( - 'security group rule delete ' + - cls.SECURITY_GROUP_RULE_ID - ) - cls.assertOutput('', raw_output) - - raw_output = cls.openstack( - 'security group delete ' + - cls.SECURITY_GROUP_NAME - ) - cls.assertOutput('', raw_output) + try: + if cls.haz_network: + raw_output = cls.openstack( + 'security group rule delete ' + + cls.SECURITY_GROUP_RULE_ID + ) + cls.assertOutput('', raw_output) + raw_output = cls.openstack( + 'security group delete ' + + cls.SECURITY_GROUP_NAME + ) + cls.assertOutput('', raw_output) + finally: + super(SecurityGroupRuleTests, cls).tearDownClass() def setUp(self): super(SecurityGroupRuleTests, self).setUp() diff --git a/openstackclient/tests/functional/network/v2/test_subnet.py b/openstackclient/tests/functional/network/v2/test_subnet.py index 93e0593d..d5309ee6 100644 --- a/openstackclient/tests/functional/network/v2/test_subnet.py +++ b/openstackclient/tests/functional/network/v2/test_subnet.py @@ -17,15 +17,18 @@ import uuid from openstackclient.tests.functional.network.v2 import common -class SubnetTests(common.NetworkTests): +class SubnetTests(common.NetworkTagTests): """Functional tests for subnet""" + base_command = 'subnet' + @classmethod def setUpClass(cls): common.NetworkTests.setUpClass() if cls.haz_network: - # Create a network for the all subnet tests cls.NETWORK_NAME = uuid.uuid4().hex + + # Create a network for the all subnet tests cmd_output = json.loads(cls.openstack( 'network create -f json ' + cls.NETWORK_NAME @@ -35,12 +38,15 @@ class SubnetTests(common.NetworkTests): @classmethod def tearDownClass(cls): - if cls.haz_network: - raw_output = cls.openstack( - 'network delete ' + - cls.NETWORK_NAME - ) - cls.assertOutput('', raw_output) + try: + if cls.haz_network: + raw_output = cls.openstack( + 'network delete ' + + cls.NETWORK_NAME + ) + cls.assertOutput('', raw_output) + finally: + super(SubnetTests, cls).tearDownClass() def setUp(self): super(SubnetTests, self).setUp() @@ -281,3 +287,9 @@ class SubnetTests(common.NetworkTests): # break and no longer retry if create successfully break return cmd_output + + def _create_resource_for_tag_test(self, name, args): + cmd = ('subnet create -f json --network ' + + self.NETWORK_NAME + ' ' + args + + ' --subnet-range') + return self._subnet_create(cmd, name) diff --git a/openstackclient/tests/functional/network/v2/test_subnet_pool.py b/openstackclient/tests/functional/network/v2/test_subnet_pool.py index a4b823f1..46aa6f14 100644 --- a/openstackclient/tests/functional/network/v2/test_subnet_pool.py +++ b/openstackclient/tests/functional/network/v2/test_subnet_pool.py @@ -17,9 +17,11 @@ import uuid from openstackclient.tests.functional.network.v2 import common -class SubnetPoolTests(common.NetworkTests): +class SubnetPoolTests(common.NetworkTagTests): """Functional tests for subnet pool""" + base_command = 'subnet pool' + def setUp(self): super(SubnetPoolTests, self).setUp() # Nothing in this class works with Nova Network @@ -321,3 +323,7 @@ class SubnetPoolTests(common.NetworkTests): break return cmd_output, pool_prefix + + def _create_resource_for_tag_test(self, name, args): + cmd_output, _pool_prefix = self._subnet_pool_create(args, name) + return cmd_output diff --git a/openstackclient/tests/functional/object/v1/test_container.py b/openstackclient/tests/functional/object/v1/test_container.py index af76efd9..acfbab11 100644 --- a/openstackclient/tests/functional/object/v1/test_container.py +++ b/openstackclient/tests/functional/object/v1/test_container.py @@ -21,14 +21,18 @@ class ContainerTests(base.TestCase): @classmethod def setUpClass(cls): + super(ContainerTests, cls).setUpClass() opts = cls.get_opts(['container']) raw_output = cls.openstack('container create ' + cls.NAME + opts) cls.assertOutput(cls.NAME + '\n', raw_output) @classmethod def tearDownClass(cls): - raw_output = cls.openstack('container delete ' + cls.NAME) - cls.assertOutput('', raw_output) + try: + raw_output = cls.openstack('container delete ' + cls.NAME) + cls.assertOutput('', raw_output) + finally: + super(ContainerTests, cls).tearDownClass() def test_container_list(self): opts = self.get_opts(['Name']) diff --git a/openstackclient/tests/functional/object/v1/test_object.py b/openstackclient/tests/functional/object/v1/test_object.py index 776cf47c..0927d706 100644 --- a/openstackclient/tests/functional/object/v1/test_object.py +++ b/openstackclient/tests/functional/object/v1/test_object.py @@ -66,6 +66,10 @@ class ObjectTests(base.TestCase): + ' ' + object_file + ' --file ' + tmp_file) # TODO(stevemar): Assert returned fields + raw_output = self.openstack('object save ' + self.CONTAINER_NAME + + ' ' + object_file + ' --file -') + self.assertEqual(raw_output, 'test content') + self.openstack('object show ' + self.CONTAINER_NAME + ' ' + object_file) # TODO(stevemar): Assert returned fields diff --git a/openstackclient/tests/functional/volume/v1/common.py b/openstackclient/tests/functional/volume/v1/common.py index f9d96bbb..4978cea3 100644 --- a/openstackclient/tests/functional/volume/v1/common.py +++ b/openstackclient/tests/functional/volume/v1/common.py @@ -10,7 +10,7 @@ # License for the specific language governing permissions and limitations # under the License. -import os +import fixtures from openstackclient.tests.functional.volume import base @@ -18,6 +18,9 @@ from openstackclient.tests.functional.volume import base class BaseVolumeTests(base.BaseVolumeTests): """Base class for Volume functional tests. """ - @classmethod - def setUpClass(cls): - os.environ['OS_VOLUME_API_VERSION'] = '1' + def setUp(self): + super(BaseVolumeTests, self).setUp() + ver_fixture = fixtures.EnvironmentVariable( + 'OS_VOLUME_API_VERSION', '1' + ) + self.useFixture(ver_fixture) diff --git a/openstackclient/tests/functional/volume/v1/test_service.py b/openstackclient/tests/functional/volume/v1/test_service.py index c921c46a..fee73f18 100644 --- a/openstackclient/tests/functional/volume/v1/test_service.py +++ b/openstackclient/tests/functional/volume/v1/test_service.py @@ -64,10 +64,7 @@ class VolumeServiceTests(common.BaseVolumeTests): 'enabled', cmd_output[0]['Status'] ) - self.assertEqual( - None, - cmd_output[0]['Disabled Reason'] - ) + self.assertIsNone(cmd_output[0]['Disabled Reason']) # Test volume service set --disable and --disable-reason disable_reason = 'disable_reason' diff --git a/openstackclient/tests/functional/volume/v1/test_snapshot.py b/openstackclient/tests/functional/volume/v1/test_snapshot.py index 28726762..c60472c5 100644 --- a/openstackclient/tests/functional/volume/v1/test_snapshot.py +++ b/openstackclient/tests/functional/volume/v1/test_snapshot.py @@ -35,9 +35,12 @@ class VolumeSnapshotTests(common.BaseVolumeTests): @classmethod def tearDownClass(cls): - cls.wait_for_status('volume', cls.VOLLY, 'available') - raw_output = cls.openstack('volume delete --force ' + cls.VOLLY) - cls.assertOutput('', raw_output) + try: + cls.wait_for_status('volume', cls.VOLLY, 'available') + raw_output = cls.openstack('volume delete --force ' + cls.VOLLY) + cls.assertOutput('', raw_output) + finally: + super(VolumeSnapshotTests, cls).tearDownClass() def test_volume_snapshot__delete(self): """Test create, delete multiple""" diff --git a/openstackclient/tests/functional/volume/v1/test_transfer_request.py b/openstackclient/tests/functional/volume/v1/test_transfer_request.py index bd612829..73191fc9 100644 --- a/openstackclient/tests/functional/volume/v1/test_transfer_request.py +++ b/openstackclient/tests/functional/volume/v1/test_transfer_request.py @@ -37,12 +37,15 @@ class TransferRequestTests(common.BaseVolumeTests): @classmethod def tearDownClass(cls): - raw_output_transfer = cls.openstack( - 'volume transfer request delete ' + cls.NAME) - raw_output_volume = cls.openstack( - 'volume delete ' + cls.VOLUME_NAME) - cls.assertOutput('', raw_output_transfer) - cls.assertOutput('', raw_output_volume) + try: + raw_output_transfer = cls.openstack( + 'volume transfer request delete ' + cls.NAME) + raw_output_volume = cls.openstack( + 'volume delete ' + cls.VOLUME_NAME) + cls.assertOutput('', raw_output_transfer) + cls.assertOutput('', raw_output_volume) + finally: + super(TransferRequestTests, cls).tearDownClass() def test_volume_transfer_request_accept(self): volume_name = uuid.uuid4().hex diff --git a/openstackclient/tests/functional/volume/v1/test_volume_type.py b/openstackclient/tests/functional/volume/v1/test_volume_type.py index acad34ad..74e14070 100644 --- a/openstackclient/tests/functional/volume/v1/test_volume_type.py +++ b/openstackclient/tests/functional/volume/v1/test_volume_type.py @@ -31,8 +31,11 @@ class VolumeTypeTests(common.BaseVolumeTests): @classmethod def tearDownClass(cls): - raw_output = cls.openstack('volume type delete ' + cls.NAME) - cls.assertOutput('', raw_output) + try: + raw_output = cls.openstack('volume type delete ' + cls.NAME) + cls.assertOutput('', raw_output) + finally: + super(VolumeTypeTests, cls).tearDownClass() def test_volume_type_list(self): cmd_output = json.loads(self.openstack('volume type list -f json')) diff --git a/openstackclient/tests/functional/volume/v2/common.py b/openstackclient/tests/functional/volume/v2/common.py index 1d14719f..38176714 100644 --- a/openstackclient/tests/functional/volume/v2/common.py +++ b/openstackclient/tests/functional/volume/v2/common.py @@ -10,7 +10,7 @@ # License for the specific language governing permissions and limitations # under the License. -import os +import fixtures from openstackclient.tests.functional.volume import base @@ -18,6 +18,9 @@ from openstackclient.tests.functional.volume import base class BaseVolumeTests(base.BaseVolumeTests): """Base class for Volume functional tests. """ - @classmethod - def setUpClass(cls): - os.environ['OS_VOLUME_API_VERSION'] = '2' + def setUp(self): + super(BaseVolumeTests, self).setUp() + ver_fixture = fixtures.EnvironmentVariable( + 'OS_VOLUME_API_VERSION', '2' + ) + self.useFixture(ver_fixture) diff --git a/openstackclient/tests/functional/volume/v2/test_service.py b/openstackclient/tests/functional/volume/v2/test_service.py index 8d1944e4..6986fde6 100644 --- a/openstackclient/tests/functional/volume/v2/test_service.py +++ b/openstackclient/tests/functional/volume/v2/test_service.py @@ -64,8 +64,7 @@ class VolumeServiceTests(common.BaseVolumeTests): 'enabled', cmd_output[0]['Status'] ) - self.assertEqual( - None, + self.assertIsNone( cmd_output[0]['Disabled Reason'] ) diff --git a/openstackclient/tests/functional/volume/v2/test_snapshot.py b/openstackclient/tests/functional/volume/v2/test_snapshot.py index 2fff43c8..ba6b2c28 100644 --- a/openstackclient/tests/functional/volume/v2/test_snapshot.py +++ b/openstackclient/tests/functional/volume/v2/test_snapshot.py @@ -35,10 +35,13 @@ class VolumeSnapshotTests(common.BaseVolumeTests): @classmethod def tearDownClass(cls): - cls.wait_for_status('volume', cls.VOLLY, 'available') - raw_output = cls.openstack( - 'volume delete --force ' + cls.VOLLY) - cls.assertOutput('', raw_output) + try: + cls.wait_for_status('volume', cls.VOLLY, 'available') + raw_output = cls.openstack( + 'volume delete --force ' + cls.VOLLY) + cls.assertOutput('', raw_output) + finally: + super(VolumeSnapshotTests, cls).tearDownClass() def test_volume_snapshot__delete(self): """Test create, delete multiple""" diff --git a/openstackclient/tests/functional/volume/v2/test_transfer_request.py b/openstackclient/tests/functional/volume/v2/test_transfer_request.py index e9c2236b..33495af6 100644 --- a/openstackclient/tests/functional/volume/v2/test_transfer_request.py +++ b/openstackclient/tests/functional/volume/v2/test_transfer_request.py @@ -38,12 +38,15 @@ class TransferRequestTests(common.BaseVolumeTests): @classmethod def tearDownClass(cls): - raw_output_transfer = cls.openstack( - 'volume transfer request delete ' + cls.NAME) - raw_output_volume = cls.openstack( - 'volume delete ' + cls.VOLUME_NAME) - cls.assertOutput('', raw_output_transfer) - cls.assertOutput('', raw_output_volume) + try: + raw_output_transfer = cls.openstack( + 'volume transfer request delete ' + cls.NAME) + raw_output_volume = cls.openstack( + 'volume delete ' + cls.VOLUME_NAME) + cls.assertOutput('', raw_output_transfer) + cls.assertOutput('', raw_output_volume) + finally: + super(TransferRequestTests, cls).tearDownClass() def test_volume_transfer_request_accept(self): volume_name = uuid.uuid4().hex diff --git a/openstackclient/tests/functional/volume/v2/test_volume_type.py b/openstackclient/tests/functional/volume/v2/test_volume_type.py index 11acf2f8..99630e6b 100644 --- a/openstackclient/tests/functional/volume/v2/test_volume_type.py +++ b/openstackclient/tests/functional/volume/v2/test_volume_type.py @@ -31,8 +31,11 @@ class VolumeTypeTests(common.BaseVolumeTests): @classmethod def tearDownClass(cls): - raw_output = cls.openstack('volume type delete ' + cls.NAME) - cls.assertOutput('', raw_output) + try: + raw_output = cls.openstack('volume type delete ' + cls.NAME) + cls.assertOutput('', raw_output) + finally: + super(VolumeTypeTests, cls).tearDownClass() def test_volume_type_list(self): cmd_output = json.loads(self.openstack('volume type list -f json')) diff --git a/openstackclient/tests/functional/volume/v3/common.py b/openstackclient/tests/functional/volume/v3/common.py index bc8befa6..a710a683 100644 --- a/openstackclient/tests/functional/volume/v3/common.py +++ b/openstackclient/tests/functional/volume/v3/common.py @@ -10,7 +10,7 @@ # License for the specific language governing permissions and limitations # under the License. -import os +import fixtures from openstackclient.tests.functional.volume import base @@ -18,6 +18,9 @@ from openstackclient.tests.functional.volume import base class BaseVolumeTests(base.BaseVolumeTests): """Base class for Volume functional tests. """ - @classmethod - def setUpClass(cls): - os.environ['OS_VOLUME_API_VERSION'] = '3' + def setUp(self): + super(BaseVolumeTests, self).setUp() + ver_fixture = fixtures.EnvironmentVariable( + 'OS_VOLUME_API_VERSION', '3' + ) + self.useFixture(ver_fixture) diff --git a/openstackclient/tests/functional/volume/v3/test_qos.py b/openstackclient/tests/functional/volume/v3/test_qos.py index a7af3c5b..a6290fc5 100644 --- a/openstackclient/tests/functional/volume/v3/test_qos.py +++ b/openstackclient/tests/functional/volume/v3/test_qos.py @@ -10,15 +10,9 @@ # License for the specific language governing permissions and limitations # under the License. -import os - from openstackclient.tests.functional.volume.v2 import test_qos as v2 +from openstackclient.tests.functional.volume.v3 import common -class QosTests(v2.QosTests): +class QosTests(common.BaseVolumeTests, v2.QosTests): """Functional tests for volume qos. """ - - @classmethod - def setUpClass(cls): - super(QosTests, cls).setUpClass() - os.environ['OS_VOLUME_API_VERSION'] = '3' diff --git a/openstackclient/tests/functional/volume/v3/test_snapshot.py b/openstackclient/tests/functional/volume/v3/test_snapshot.py index bf05b9de..38e0563a 100644 --- a/openstackclient/tests/functional/volume/v3/test_snapshot.py +++ b/openstackclient/tests/functional/volume/v3/test_snapshot.py @@ -11,13 +11,8 @@ # under the License. from openstackclient.tests.functional.volume.v2 import test_snapshot as v2 -import os +from openstackclient.tests.functional.volume.v3 import common -class VolumeSnapshotTests(v2.VolumeSnapshotTests): +class VolumeSnapshotTests(common.BaseVolumeTests, v2.VolumeSnapshotTests): """Functional tests for volume snapshot. """ - - @classmethod - def setUpClass(cls): - super(VolumeSnapshotTests, cls).setUpClass() - os.environ['OS_VOLUME_API_VERSION'] = '3' diff --git a/openstackclient/tests/functional/volume/v3/test_transfer_request.py b/openstackclient/tests/functional/volume/v3/test_transfer_request.py index 7b54dd20..b3253237 100644 --- a/openstackclient/tests/functional/volume/v3/test_transfer_request.py +++ b/openstackclient/tests/functional/volume/v3/test_transfer_request.py @@ -12,13 +12,8 @@ from openstackclient.tests.functional.volume.v2 import test_transfer_request \ as v2 -import os +from openstackclient.tests.functional.volume.v3 import common -class TransferRequestTests(v2.TransferRequestTests): +class TransferRequestTests(common.BaseVolumeTests, v2.TransferRequestTests): """Functional tests for transfer request. """ - - @classmethod - def setUpClass(cls): - super(TransferRequestTests, cls).setUpClass() - os.environ['OS_VOLUME_API_VERSION'] = '3' diff --git a/openstackclient/tests/functional/volume/v3/test_volume.py b/openstackclient/tests/functional/volume/v3/test_volume.py index 333826d8..283b830f 100644 --- a/openstackclient/tests/functional/volume/v3/test_volume.py +++ b/openstackclient/tests/functional/volume/v3/test_volume.py @@ -11,13 +11,8 @@ # under the License. from openstackclient.tests.functional.volume.v2 import test_volume as v2 -import os +from openstackclient.tests.functional.volume.v3 import common -class VolumeTests(v2.VolumeTests): +class VolumeTests(common.BaseVolumeTests, v2.VolumeTests): """Functional tests for volume. """ - - @classmethod - def setUpClass(cls): - super(VolumeTests, cls).setUpClass() - os.environ['OS_VOLUME_API_VERSION'] = '3' diff --git a/openstackclient/tests/functional/volume/v3/test_volume_type.py b/openstackclient/tests/functional/volume/v3/test_volume_type.py index f10e64b4..eb66515e 100644 --- a/openstackclient/tests/functional/volume/v3/test_volume_type.py +++ b/openstackclient/tests/functional/volume/v3/test_volume_type.py @@ -11,13 +11,8 @@ # under the License. from openstackclient.tests.functional.volume.v2 import test_volume_type as v2 -import os +from openstackclient.tests.functional.volume.v3 import common -class VolumeTypeTests(v2.VolumeTypeTests): +class VolumeTypeTests(common.BaseVolumeTests, v2.VolumeTypeTests): """Functional tests for volume type. """ - - @classmethod - def setUpClass(cls): - super(VolumeTypeTests, cls).setUpClass() - os.environ['OS_VOLUME_API_VERSION'] = '3' diff --git a/openstackclient/tests/unit/common/test_project_purge.py b/openstackclient/tests/unit/common/test_project_purge.py new file mode 100644 index 00000000..05a8aa3e --- /dev/null +++ b/openstackclient/tests/unit/common/test_project_purge.py @@ -0,0 +1,314 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import mock + +from osc_lib import exceptions + +from openstackclient.common import project_purge +from openstackclient.tests.unit.compute.v2 import fakes as compute_fakes +from openstackclient.tests.unit import fakes +from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes +from openstackclient.tests.unit.image.v2 import fakes as image_fakes +from openstackclient.tests.unit import utils as tests_utils +from openstackclient.tests.unit.volume.v2 import fakes as volume_fakes + + +class TestProjectPurgeInit(tests_utils.TestCommand): + + def setUp(self): + super(TestProjectPurgeInit, self).setUp() + compute_client = compute_fakes.FakeComputev2Client( + endpoint=fakes.AUTH_URL, + token=fakes.AUTH_TOKEN, + ) + self.app.client_manager.compute = compute_client + self.servers_mock = compute_client.servers + self.servers_mock.reset_mock() + + volume_client = volume_fakes.FakeVolumeClient( + endpoint=fakes.AUTH_URL, + token=fakes.AUTH_TOKEN, + ) + self.app.client_manager.volume = volume_client + self.volumes_mock = volume_client.volumes + self.volumes_mock.reset_mock() + self.snapshots_mock = volume_client.volume_snapshots + self.snapshots_mock.reset_mock() + self.backups_mock = volume_client.backups + self.backups_mock.reset_mock() + + identity_client = identity_fakes.FakeIdentityv3Client( + endpoint=fakes.AUTH_URL, + token=fakes.AUTH_TOKEN, + ) + self.app.client_manager.identity = identity_client + self.domains_mock = identity_client.domains + self.domains_mock.reset_mock() + self.projects_mock = identity_client.projects + self.projects_mock.reset_mock() + + image_client = image_fakes.FakeImagev2Client( + endpoint=fakes.AUTH_URL, + token=fakes.AUTH_TOKEN, + ) + self.app.client_manager.image = image_client + self.images_mock = image_client.images + self.images_mock.reset_mock() + + +class TestProjectPurge(TestProjectPurgeInit): + + project = identity_fakes.FakeProject.create_one_project() + server = compute_fakes.FakeServer.create_one_server() + image = image_fakes.FakeImage.create_one_image() + volume = volume_fakes.FakeVolume.create_one_volume() + backup = volume_fakes.FakeBackup.create_one_backup() + snapshot = volume_fakes.FakeSnapshot.create_one_snapshot() + + def setUp(self): + super(TestProjectPurge, self).setUp() + self.projects_mock.get.return_value = self.project + self.projects_mock.delete.return_value = None + self.images_mock.list.return_value = [self.image] + self.images_mock.delete.return_value = None + self.servers_mock.list.return_value = [self.server] + self.servers_mock.delete.return_value = None + self.volumes_mock.list.return_value = [self.volume] + self.volumes_mock.delete.return_value = None + self.volumes_mock.force_delete.return_value = None + self.snapshots_mock.list.return_value = [self.snapshot] + self.snapshots_mock.delete.return_value = None + self.backups_mock.list.return_value = [self.backup] + self.backups_mock.delete.return_value = None + + self.cmd = project_purge.ProjectPurge(self.app, None) + + def test_project_no_options(self): + arglist = [] + verifylist = [] + + self.assertRaises(tests_utils.ParserException, self.check_parser, + self.cmd, arglist, verifylist) + + def test_project_purge_with_project(self): + arglist = [ + '--project', self.project.id, + ] + verifylist = [ + ('dry_run', False), + ('keep_project', False), + ('auth_project', False), + ('project', self.project.id), + ('project_domain', None), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + result = self.cmd.take_action(parsed_args) + self.projects_mock.get.assert_called_once_with(self.project.id) + self.projects_mock.delete.assert_called_once_with(self.project.id) + self.servers_mock.list.assert_called_once_with( + search_opts={'tenant_id': self.project.id}) + self.images_mock.list.assert_called_once_with( + owner=self.project.id) + volume_search_opts = {'project_id': self.project.id} + self.volumes_mock.list.assert_called_once_with( + search_opts=volume_search_opts) + self.snapshots_mock.list.assert_called_once_with( + search_opts=volume_search_opts) + self.backups_mock.list.assert_called_once_with( + search_opts=volume_search_opts) + self.servers_mock.delete.assert_called_once_with(self.server.id) + self.images_mock.delete.assert_called_once_with(self.image.id) + self.volumes_mock.force_delete.assert_called_once_with(self.volume.id) + self.snapshots_mock.delete.assert_called_once_with(self.snapshot.id) + self.backups_mock.delete.assert_called_once_with(self.backup.id) + self.assertIsNone(result) + + def test_project_purge_with_dry_run(self): + arglist = [ + '--dry-run', + '--project', self.project.id, + ] + verifylist = [ + ('dry_run', True), + ('keep_project', False), + ('auth_project', False), + ('project', self.project.id), + ('project_domain', None), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + result = self.cmd.take_action(parsed_args) + self.projects_mock.get.assert_called_once_with(self.project.id) + self.projects_mock.delete.assert_not_called() + self.servers_mock.list.assert_called_once_with( + search_opts={'tenant_id': self.project.id}) + self.images_mock.list.assert_called_once_with( + owner=self.project.id) + volume_search_opts = {'project_id': self.project.id} + self.volumes_mock.list.assert_called_once_with( + search_opts=volume_search_opts) + self.snapshots_mock.list.assert_called_once_with( + search_opts=volume_search_opts) + self.backups_mock.list.assert_called_once_with( + search_opts=volume_search_opts) + self.servers_mock.delete.assert_not_called() + self.images_mock.delete.assert_not_called() + self.volumes_mock.force_delete.assert_not_called() + self.snapshots_mock.delete.assert_not_called() + self.backups_mock.delete.assert_not_called() + self.assertIsNone(result) + + def test_project_purge_with_keep_project(self): + arglist = [ + '--keep-project', + '--project', self.project.id, + ] + verifylist = [ + ('dry_run', False), + ('keep_project', True), + ('auth_project', False), + ('project', self.project.id), + ('project_domain', None), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + result = self.cmd.take_action(parsed_args) + self.projects_mock.get.assert_called_once_with(self.project.id) + self.projects_mock.delete.assert_not_called() + self.servers_mock.list.assert_called_once_with( + search_opts={'tenant_id': self.project.id}) + self.images_mock.list.assert_called_once_with( + owner=self.project.id) + volume_search_opts = {'project_id': self.project.id} + self.volumes_mock.list.assert_called_once_with( + search_opts=volume_search_opts) + self.snapshots_mock.list.assert_called_once_with( + search_opts=volume_search_opts) + self.backups_mock.list.assert_called_once_with( + search_opts=volume_search_opts) + self.servers_mock.delete.assert_called_once_with(self.server.id) + self.images_mock.delete.assert_called_once_with(self.image.id) + self.volumes_mock.force_delete.assert_called_once_with(self.volume.id) + self.snapshots_mock.delete.assert_called_once_with(self.snapshot.id) + self.backups_mock.delete.assert_called_once_with(self.backup.id) + self.assertIsNone(result) + + def test_project_purge_with_auth_project(self): + self.app.client_manager.auth_ref = mock.Mock() + self.app.client_manager.auth_ref.project_id = self.project.id + arglist = [ + '--auth-project', + ] + verifylist = [ + ('dry_run', False), + ('keep_project', False), + ('auth_project', True), + ('project', None), + ('project_domain', None), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + result = self.cmd.take_action(parsed_args) + self.projects_mock.get.assert_not_called() + self.projects_mock.delete.assert_called_once_with(self.project.id) + self.servers_mock.list.assert_called_once_with( + search_opts={'tenant_id': self.project.id}) + self.images_mock.list.assert_called_once_with( + owner=self.project.id) + volume_search_opts = {'project_id': self.project.id} + self.volumes_mock.list.assert_called_once_with( + search_opts=volume_search_opts) + self.snapshots_mock.list.assert_called_once_with( + search_opts=volume_search_opts) + self.backups_mock.list.assert_called_once_with( + search_opts=volume_search_opts) + self.servers_mock.delete.assert_called_once_with(self.server.id) + self.images_mock.delete.assert_called_once_with(self.image.id) + self.volumes_mock.force_delete.assert_called_once_with(self.volume.id) + self.snapshots_mock.delete.assert_called_once_with(self.snapshot.id) + self.backups_mock.delete.assert_called_once_with(self.backup.id) + self.assertIsNone(result) + + @mock.patch.object(project_purge.LOG, 'error') + def test_project_purge_with_exception(self, mock_error): + self.servers_mock.delete.side_effect = exceptions.CommandError() + arglist = [ + '--project', self.project.id, + ] + verifylist = [ + ('dry_run', False), + ('keep_project', False), + ('auth_project', False), + ('project', self.project.id), + ('project_domain', None), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + result = self.cmd.take_action(parsed_args) + self.projects_mock.get.assert_called_once_with(self.project.id) + self.projects_mock.delete.assert_called_once_with(self.project.id) + self.servers_mock.list.assert_called_once_with( + search_opts={'tenant_id': self.project.id}) + self.images_mock.list.assert_called_once_with( + owner=self.project.id) + volume_search_opts = {'project_id': self.project.id} + self.volumes_mock.list.assert_called_once_with( + search_opts=volume_search_opts) + self.snapshots_mock.list.assert_called_once_with( + search_opts=volume_search_opts) + self.backups_mock.list.assert_called_once_with( + search_opts=volume_search_opts) + self.servers_mock.delete.assert_called_once_with(self.server.id) + self.images_mock.delete.assert_called_once_with(self.image.id) + self.volumes_mock.force_delete.assert_called_once_with(self.volume.id) + self.snapshots_mock.delete.assert_called_once_with(self.snapshot.id) + self.backups_mock.delete.assert_called_once_with(self.backup.id) + mock_error.assert_called_with("1 of 1 servers failed to delete.") + self.assertIsNone(result) + + def test_project_purge_with_force_delete_backup(self): + self.backups_mock.delete.side_effect = [exceptions.CommandError, None] + arglist = [ + '--project', self.project.id, + ] + verifylist = [ + ('dry_run', False), + ('keep_project', False), + ('auth_project', False), + ('project', self.project.id), + ('project_domain', None), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + result = self.cmd.take_action(parsed_args) + self.projects_mock.get.assert_called_once_with(self.project.id) + self.projects_mock.delete.assert_called_once_with(self.project.id) + self.servers_mock.list.assert_called_once_with( + search_opts={'tenant_id': self.project.id}) + self.images_mock.list.assert_called_once_with( + owner=self.project.id) + volume_search_opts = {'project_id': self.project.id} + self.volumes_mock.list.assert_called_once_with( + search_opts=volume_search_opts) + self.snapshots_mock.list.assert_called_once_with( + search_opts=volume_search_opts) + self.backups_mock.list.assert_called_once_with( + search_opts=volume_search_opts) + self.servers_mock.delete.assert_called_once_with(self.server.id) + self.images_mock.delete.assert_called_once_with(self.image.id) + self.volumes_mock.force_delete.assert_called_once_with(self.volume.id) + self.snapshots_mock.delete.assert_called_once_with(self.snapshot.id) + self.assertEqual(2, self.backups_mock.delete.call_count) + self.backups_mock.delete.assert_called_with(self.backup.id, force=True) + self.assertIsNone(result) diff --git a/openstackclient/tests/unit/compute/v2/test_server.py b/openstackclient/tests/unit/compute/v2/test_server.py index 084171ac..5b0d28a1 100644 --- a/openstackclient/tests/unit/compute/v2/test_server.py +++ b/openstackclient/tests/unit/compute/v2/test_server.py @@ -395,6 +395,8 @@ class TestServerCreate(TestServer): self.assertEqual(self.columns, columns) self.assertEqual(self.datalist(), data) + self.assertFalse(self.images_mock.called) + self.assertFalse(self.flavors_mock.called) def test_server_create_with_options(self): arglist = [ @@ -795,6 +797,66 @@ class TestServerCreate(TestServer): self.cmd.take_action, parsed_args) self.assertNotCalled(self.servers_mock.create) + def test_server_create_with_invalid_network_key(self): + arglist = [ + '--image', 'image1', + '--flavor', 'flavor1', + '--nic', 'abcdefgh=12324', + self.new_server.name, + ] + verifylist = [ + ('image', 'image1'), + ('flavor', 'flavor1'), + ('nic', ['abcdefgh=12324']), + ('config_drive', False), + ('server_name', self.new_server.name), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + self.assertRaises(exceptions.CommandError, + self.cmd.take_action, parsed_args) + self.assertNotCalled(self.servers_mock.create) + + def test_server_create_with_empty_network_key_value(self): + arglist = [ + '--image', 'image1', + '--flavor', 'flavor1', + '--nic', 'net-id=', + self.new_server.name, + ] + verifylist = [ + ('image', 'image1'), + ('flavor', 'flavor1'), + ('nic', ['net-id=']), + ('config_drive', False), + ('server_name', self.new_server.name), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + self.assertRaises(exceptions.CommandError, + self.cmd.take_action, parsed_args) + self.assertNotCalled(self.servers_mock.create) + + def test_server_create_with_only_network_key(self): + arglist = [ + '--image', 'image1', + '--flavor', 'flavor1', + '--nic', 'net-id', + self.new_server.name, + ] + verifylist = [ + ('image', 'image1'), + ('flavor', 'flavor1'), + ('nic', ['net-id']), + ('config_drive', False), + ('server_name', self.new_server.name), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + self.assertRaises(exceptions.CommandError, + self.cmd.take_action, parsed_args) + self.assertNotCalled(self.servers_mock.create) + @mock.patch.object(common_utils, 'wait_for_status', return_value=True) def test_server_create_with_wait_ok(self, mock_wait_for_status): arglist = [ @@ -1439,7 +1501,8 @@ class TestServerList(TestServer): 'Name', 'Status', 'Networks', - 'Image Name', + 'Image', + 'Flavor', ) columns_long = ( 'ID', @@ -1515,6 +1578,7 @@ class TestServerList(TestServer): # Prepare data returned by fake Nova API. self.data = [] self.data_long = [] + self.data_no_name_lookup = [] Image = collections.namedtuple('Image', 'id name') self.images_mock.list.return_value = [ @@ -1535,6 +1599,7 @@ class TestServerList(TestServer): s.status, server._format_servers_list_networks(s.networks), self.image.name, + self.flavor.name, )) self.data_long.append(( s.id, @@ -1553,6 +1618,14 @@ class TestServerList(TestServer): getattr(s, 'OS-EXT-SRV-ATTR:host'), s.Metadata, )) + self.data_no_name_lookup.append(( + s.id, + s.name, + s.status, + server._format_servers_list_networks(s.networks), + s.image['id'], + s.flavor['id'] + )) def test_server_list_no_option(self): arglist = [] @@ -1585,6 +1658,38 @@ class TestServerList(TestServer): self.assertEqual(self.columns_long, columns) self.assertEqual(tuple(self.data_long), tuple(data)) + def test_server_list_no_name_lookup_option(self): + arglist = [ + '--no-name-lookup', + ] + verifylist = [ + ('all_projects', False), + ('no_name_lookup', True), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + + self.servers_mock.list.assert_called_with(**self.kwargs) + self.assertEqual(self.columns, columns) + self.assertEqual(tuple(self.data_no_name_lookup), tuple(data)) + + def test_server_list_n_option(self): + arglist = [ + '-n', + ] + verifylist = [ + ('all_projects', False), + ('no_name_lookup', True), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + + self.servers_mock.list.assert_called_with(**self.kwargs) + self.assertEqual(self.columns, columns) + self.assertEqual(tuple(self.data_no_name_lookup), tuple(data)) + def test_server_list_with_image(self): arglist = [ diff --git a/openstackclient/tests/unit/identity/v3/fakes.py b/openstackclient/tests/unit/identity/v3/fakes.py index 291f977d..c7d29885 100644 --- a/openstackclient/tests/unit/identity/v3/fakes.py +++ b/openstackclient/tests/unit/identity/v3/fakes.py @@ -284,7 +284,8 @@ IDENTITY_PROVIDER = { 'id': idp_id, 'remote_ids': idp_remote_ids, 'enabled': True, - 'description': idp_description + 'description': idp_description, + 'domain_id': domain_id, } protocol_id = 'protocol' diff --git a/openstackclient/tests/unit/identity/v3/test_identity_provider.py b/openstackclient/tests/unit/identity/v3/test_identity_provider.py index cb672a92..def6e0ce 100644 --- a/openstackclient/tests/unit/identity/v3/test_identity_provider.py +++ b/openstackclient/tests/unit/identity/v3/test_identity_provider.py @@ -25,21 +25,33 @@ class TestIdentityProvider(identity_fakes.TestFederatedIdentity): def setUp(self): super(TestIdentityProvider, self).setUp() + # Identity Provider mocks federation_lib = self.app.client_manager.identity.federation self.identity_providers_mock = federation_lib.identity_providers self.identity_providers_mock.reset_mock() + # Domain mocks + self.domains_mock = self.app.client_manager.identity.domains + self.domains_mock.reset_mock() + self.domain = identity_fakes.FakeDomain.create_one_domain( + identity_fakes.DOMAIN + ) + self.domains_mock.list.return_value = [self.domain] + self.domains_mock.get.return_value = self.domain + class TestIdentityProviderCreate(TestIdentityProvider): columns = ( 'description', + 'domain_id', 'enabled', 'id', 'remote_ids', ) datalist = ( identity_fakes.idp_description, + identity_fakes.domain_id, True, identity_fakes.idp_id, identity_fakes.formatted_idp_remote_ids, @@ -68,6 +80,7 @@ class TestIdentityProviderCreate(TestIdentityProvider): 'remote_ids': None, 'enabled': True, 'description': None, + 'domain_id': None, } self.identity_providers_mock.create.assert_called_with( @@ -94,6 +107,7 @@ class TestIdentityProviderCreate(TestIdentityProvider): kwargs = { 'remote_ids': None, 'description': identity_fakes.idp_description, + 'domain_id': None, 'enabled': True, } @@ -121,6 +135,7 @@ class TestIdentityProviderCreate(TestIdentityProvider): kwargs = { 'remote_ids': identity_fakes.idp_remote_ids[:1], 'description': None, + 'domain_id': None, 'enabled': True, } @@ -149,6 +164,7 @@ class TestIdentityProviderCreate(TestIdentityProvider): kwargs = { 'remote_ids': identity_fakes.idp_remote_ids, 'description': None, + 'domain_id': None, 'enabled': True, } @@ -181,6 +197,7 @@ class TestIdentityProviderCreate(TestIdentityProvider): kwargs = { 'remote_ids': identity_fakes.idp_remote_ids, 'description': None, + 'domain_id': None, 'enabled': True, } @@ -217,6 +234,7 @@ class TestIdentityProviderCreate(TestIdentityProvider): 'remote_ids': None, 'enabled': False, 'description': None, + 'domain_id': None, } self.identity_providers_mock.create.assert_called_with( @@ -227,12 +245,69 @@ class TestIdentityProviderCreate(TestIdentityProvider): self.assertEqual(self.columns, columns) datalist = ( None, + identity_fakes.domain_id, False, identity_fakes.idp_id, identity_fakes.formatted_idp_remote_ids ) self.assertEqual(datalist, data) + def test_create_identity_provider_domain_name(self): + arglist = [ + '--domain', identity_fakes.domain_name, + identity_fakes.idp_id, + ] + verifylist = [ + ('identity_provider_id', identity_fakes.idp_id), + ('domain', identity_fakes.domain_name), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + + # Set expected values + kwargs = { + 'remote_ids': None, + 'description': None, + 'domain_id': identity_fakes.domain_id, + 'enabled': True, + } + + self.identity_providers_mock.create.assert_called_with( + id=identity_fakes.idp_id, + **kwargs + ) + + self.assertEqual(self.columns, columns) + self.assertEqual(self.datalist, data) + + def test_create_identity_provider_domain_id(self): + arglist = [ + '--domain', identity_fakes.domain_id, + identity_fakes.idp_id, + ] + verifylist = [ + ('identity_provider_id', identity_fakes.idp_id), + ('domain', identity_fakes.domain_id), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + + # Set expected values + kwargs = { + 'remote_ids': None, + 'description': None, + 'domain_id': identity_fakes.domain_id, + 'enabled': True, + } + + self.identity_providers_mock.create.assert_called_with( + id=identity_fakes.idp_id, + **kwargs + ) + + self.assertEqual(self.columns, columns) + self.assertEqual(self.datalist, data) + class TestIdentityProviderDelete(TestIdentityProvider): @@ -299,11 +374,12 @@ class TestIdentityProviderList(TestIdentityProvider): self.identity_providers_mock.list.assert_called_with() - collist = ('ID', 'Enabled', 'Description') + collist = ('ID', 'Enabled', 'Domain ID', 'Description') self.assertEqual(collist, columns) datalist = (( identity_fakes.idp_id, True, + identity_fakes.domain_id, identity_fakes.idp_description, ), ) self.assertEqual(datalist, tuple(data)) @@ -582,10 +658,11 @@ class TestIdentityProviderShow(TestIdentityProvider): id='test_idp' ) - collist = ('description', 'enabled', 'id', 'remote_ids') + collist = ('description', 'domain_id', 'enabled', 'id', 'remote_ids') self.assertEqual(collist, columns) datalist = ( identity_fakes.idp_description, + identity_fakes.domain_id, True, identity_fakes.idp_id, identity_fakes.formatted_idp_remote_ids diff --git a/openstackclient/tests/unit/identity/v3/test_project.py b/openstackclient/tests/unit/identity/v3/test_project.py index 7be81153..2ce26c64 100644 --- a/openstackclient/tests/unit/identity/v3/test_project.py +++ b/openstackclient/tests/unit/identity/v3/test_project.py @@ -19,6 +19,7 @@ from mock import call from osc_lib import exceptions from osc_lib import utils +from openstackclient.identity import common from openstackclient.identity.v3 import project from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes @@ -1060,3 +1061,48 @@ class TestProjectShow(TestProject): ['children-id'], ) self.assertEqual(data, datalist) + + def test_project_show_with_domain(self): + project = identity_fakes.FakeProject.create_one_project( + {"name": self.project.name}) + + self.app.client_manager.identity.tokens.get_token_data.return_value = \ + {'token': + {'project': + {'domain': {"id": self.project.domain_id}, + 'name': self.project.name, + 'id': self.project.id + } + } + } + + identity_client = self.app.client_manager.identity + arglist = [ + "--domain", self.domain.id, + project.name, + ] + verifylist = [ + ('domain', self.domain.id), + ('project', project.name), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + project_str = common._get_token_resource(identity_client, 'project', + parsed_args.project, + parsed_args.domain) + self.assertEqual(self.project.id, project_str) + + arglist = [ + "--domain", project.domain_id, + project.name, + ] + verifylist = [ + ('domain', project.domain_id), + ('project', project.name), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + project_str = common._get_token_resource(identity_client, 'project', + parsed_args.project, + parsed_args.domain) + self.assertEqual(project.name, project_str) diff --git a/openstackclient/tests/unit/identity/v3/test_trust.py b/openstackclient/tests/unit/identity/v3/test_trust.py index 93e8f63d..614aab54 100644 --- a/openstackclient/tests/unit/identity/v3/test_trust.py +++ b/openstackclient/tests/unit/identity/v3/test_trust.py @@ -94,7 +94,7 @@ class TestTrustCreate(TestTrust): kwargs = { 'impersonation': False, 'project': identity_fakes.project_id, - 'role_names': [identity_fakes.role_name], + 'role_ids': [identity_fakes.role_id], 'expires_at': None, } # TrustManager.create(trustee_id, trustor_id, impersonation=, diff --git a/openstackclient/tests/unit/identity/v3/test_user.py b/openstackclient/tests/unit/identity/v3/test_user.py index 2ce66e94..96f50766 100644 --- a/openstackclient/tests/unit/identity/v3/test_user.py +++ b/openstackclient/tests/unit/identity/v3/test_user.py @@ -19,6 +19,7 @@ import mock from osc_lib import exceptions from osc_lib import utils +from openstackclient.identity import common from openstackclient.identity.v3 import user from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes @@ -1091,7 +1092,7 @@ class TestUserShow(TestUser): self.app.client_manager.identity.tokens.get_token_data.return_value = \ {'token': {'user': - {'domain': {}, + {'domain': {'id': self.user.domain_id}, 'id': self.user.id, 'name': self.user.name, } @@ -1126,3 +1127,38 @@ class TestUserShow(TestUser): self.user.name, ) self.assertEqual(datalist, data) + + def test_user_show_with_domain(self): + user = identity_fakes.FakeUser.create_one_user( + {"name": self.user.name}) + identity_client = self.app.client_manager.identity + + arglist = [ + "--domain", self.user.domain_id, + user.name, + ] + verifylist = [ + ('domain', self.user.domain_id), + ('user', user.name), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + user_str = common._get_token_resource(identity_client, 'user', + parsed_args.user, + parsed_args.domain) + self.assertEqual(self.user.id, user_str) + + arglist = [ + "--domain", user.domain_id, + user.name, + ] + verifylist = [ + ('domain', user.domain_id), + ('user', user.name), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + user_str = common._get_token_resource(identity_client, 'user', + parsed_args.user, + parsed_args.domain) + self.assertEqual(user.name, user_str) diff --git a/openstackclient/tests/unit/image/v2/test_image.py b/openstackclient/tests/unit/image/v2/test_image.py index 65764e98..484a2bc6 100644 --- a/openstackclient/tests/unit/image/v2/test_image.py +++ b/openstackclient/tests/unit/image/v2/test_image.py @@ -750,6 +750,34 @@ class TestImageList(TestImage): marker=image_fakes.image_id, ) + def test_image_list_name_option(self): + arglist = [ + '--name', 'abc', + ] + verifylist = [ + ('name', 'abc'), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + self.api_mock.image_list.assert_called_with( + name='abc', marker=self._image.id + ) + + def test_image_list_status_option(self): + arglist = [ + '--status', 'active', + ] + verifylist = [ + ('status', 'active'), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + self.api_mock.image_list.assert_called_with( + status='active', marker=self._image.id + ) + class TestRemoveProjectImage(TestImage): diff --git a/openstackclient/tests/unit/integ/cli/test_shell.py b/openstackclient/tests/unit/integ/cli/test_shell.py index 9d819ed2..4e91f637 100644 --- a/openstackclient/tests/unit/integ/cli/test_shell.py +++ b/openstackclient/tests/unit/integ/cli/test_shell.py @@ -397,14 +397,14 @@ class TestIntegShellCliPrecedenceOCC(test_base.TestInteg): Run 1 has --os-password on CLI """ - config_mock.return_value = ( - 'file.yaml', - copy.deepcopy(test_shell.CLOUD_2), - ) - vendor_mock.return_value = ( - 'file.yaml', - copy.deepcopy(test_shell.PUBLIC_1), - ) + def config_mock_return(): + return ('file.yaml', copy.deepcopy(test_shell.CLOUD_2)) + config_mock.side_effect = config_mock_return + + def vendor_mock_return(): + return ('file.yaml', copy.deepcopy(test_shell.PUBLIC_1)) + vendor_mock.side_effect = vendor_mock_return + _shell = shell.OpenStackShell() _shell.run( "--os-password qaz configuration show".split(), @@ -466,14 +466,14 @@ class TestIntegShellCliPrecedenceOCC(test_base.TestInteg): Run 2 has --os-username, --os-password, --os-project-domain-id on CLI """ - config_mock.return_value = ( - 'file.yaml', - copy.deepcopy(test_shell.CLOUD_2), - ) - vendor_mock.return_value = ( - 'file.yaml', - copy.deepcopy(test_shell.PUBLIC_1), - ) + def config_mock_return(): + return ('file.yaml', copy.deepcopy(test_shell.CLOUD_2)) + config_mock.side_effect = config_mock_return + + def vendor_mock_return(): + return ('file.yaml', copy.deepcopy(test_shell.PUBLIC_1)) + vendor_mock.side_effect = vendor_mock_return + _shell = shell.OpenStackShell() _shell.run( "--os-username zarquon --os-password qaz " diff --git a/openstackclient/tests/unit/network/v2/fakes.py b/openstackclient/tests/unit/network/v2/fakes.py index e736b0fd..eadab584 100644 --- a/openstackclient/tests/unit/network/v2/fakes.py +++ b/openstackclient/tests/unit/network/v2/fakes.py @@ -346,9 +346,11 @@ class FakeNetwork(object): 'availability_zone_hints': [], 'is_default': False, 'port_security_enabled': True, + 'tags': ['test'], 'qos_policy_id': 'qos-policy-id-' + uuid.uuid4().hex, 'ipv4_address_scope': 'ipv4' + uuid.uuid4().hex, 'ipv6_address_scope': 'ipv6' + uuid.uuid4().hex, + 'tags': [], } # Overwrite default attributes. @@ -365,6 +367,7 @@ class FakeNetwork(object): network_attrs['port_security_enabled'] network.subnet_ids = network_attrs['subnets'] network.is_shared = network_attrs['shared'] + network.is_tags = network_attrs['tags'] network.provider_network_type = \ network_attrs['provider:network_type'] network.provider_physical_network = \ @@ -556,6 +559,7 @@ class FakePort(object): 'binding:vif_details': {}, 'binding:vif_type': 'ovs', 'binding:vnic_type': 'normal', + 'data_plane_status': None, 'description': 'description-' + uuid.uuid4().hex, 'device_id': 'device-id-' + uuid.uuid4().hex, 'device_owner': 'compute:nova', @@ -573,6 +577,7 @@ class FakePort(object): 'status': 'ACTIVE', 'tenant_id': 'project-id-' + uuid.uuid4().hex, 'qos_policy_id': 'qos-policy-id-' + uuid.uuid4().hex, + 'tags': [], } # Overwrite default attributes. @@ -839,6 +844,7 @@ class FakeNetworkQosPolicy(object): qos_policy_attrs = { 'name': 'qos-policy-name-' + uuid.uuid4().hex, 'id': qos_id, + 'is_default': False, 'tenant_id': 'project-id-' + uuid.uuid4().hex, 'shared': False, 'description': 'qos-policy-description-' + uuid.uuid4().hex, @@ -921,6 +927,7 @@ class FakeNetworkQosRule(object): if type == RULE_TYPE_BANDWIDTH_LIMIT: qos_rule_attrs['max_kbps'] = randint(1, 10000) qos_rule_attrs['max_burst_kbits'] = randint(1, 10000) + qos_rule_attrs['direction'] = 'egress' elif type == RULE_TYPE_DSCP_MARKING: qos_rule_attrs['dscp_mark'] = choice(VALID_DSCP_MARKS) elif type == RULE_TYPE_MINIMUM_BANDWIDTH: @@ -1048,6 +1055,7 @@ class FakeRouter(object): 'external_gateway_info': {}, 'availability_zone_hints': [], 'availability_zones': [], + 'tags': [], } # Overwrite default attributes. @@ -1289,6 +1297,7 @@ class FakeSubnet(object): 'service_types': [], 'subnetpool_id': None, 'description': 'subnet-description-' + uuid.uuid4().hex, + 'tags': [], } # Overwrite default attributes. @@ -1539,6 +1548,7 @@ class FakeSubnetPool(object): 'default_quota': None, 'ip_version': '4', 'description': 'subnet-pool-description-' + uuid.uuid4().hex, + 'tags': [], } # Overwrite default attributes. diff --git a/openstackclient/tests/unit/network/v2/test_network.py b/openstackclient/tests/unit/network/v2/test_network.py index 1bd7bac6..7b20c793 100644 --- a/openstackclient/tests/unit/network/v2/test_network.py +++ b/openstackclient/tests/unit/network/v2/test_network.py @@ -75,6 +75,7 @@ class TestCreateNetworkIdentityV3(TestNetwork): 'shared', 'status', 'subnets', + 'tags', ) data = ( @@ -97,12 +98,14 @@ class TestCreateNetworkIdentityV3(TestNetwork): _network.shared, _network.status, utils.format_list(_network.subnets), + utils.format_list(_network.tags), ) def setUp(self): super(TestCreateNetworkIdentityV3, self).setUp() self.network.create_network = mock.Mock(return_value=self._network) + self.network.set_tags = mock.Mock(return_value=None) # Get the command object to test self.cmd = network.CreateNetwork(self.app, self.namespace) @@ -137,6 +140,7 @@ class TestCreateNetworkIdentityV3(TestNetwork): 'admin_state_up': True, 'name': self._network.name, }) + self.assertFalse(self.network.set_tags.called) self.assertEqual(self.columns, columns) self.assertEqual(self.data, data) @@ -226,6 +230,44 @@ class TestCreateNetworkIdentityV3(TestNetwork): self.assertEqual(self.columns, columns) self.assertEqual(self.data, data) + def _test_create_with_tag(self, add_tags=True): + arglist = [self._network.name] + if add_tags: + arglist += ['--tag', 'red', '--tag', 'blue'] + else: + arglist += ['--no-tag'] + verifylist = [ + ('name', self._network.name), + ('enable', True), + ('share', None), + ('project', None), + ('external', False), + ] + if add_tags: + verifylist.append(('tags', ['red', 'blue'])) + else: + verifylist.append(('no_tag', True)) + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = (self.cmd.take_action(parsed_args)) + + self.network.create_network.assert_called_once_with( + name=self._network.name, admin_state_up=True) + if add_tags: + self.network.set_tags.assert_called_once_with( + self._network, + tests_utils.CompareBySet(['red', 'blue'])) + else: + self.assertFalse(self.network.set_tags.called) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) + + def test_create_with_tags(self): + self._test_create_with_tag(add_tags=True) + + def test_create_with_no_tag(self): + self._test_create_with_tag(add_tags=False) + class TestCreateNetworkIdentityV2(TestNetwork): @@ -255,6 +297,7 @@ class TestCreateNetworkIdentityV2(TestNetwork): 'shared', 'status', 'subnets', + 'tags', ) data = ( @@ -277,12 +320,14 @@ class TestCreateNetworkIdentityV2(TestNetwork): _network.shared, _network.status, utils.format_list(_network.subnets), + utils.format_list(_network.tags), ) def setUp(self): super(TestCreateNetworkIdentityV2, self).setUp() self.network.create_network = mock.Mock(return_value=self._network) + self.network.set_tags = mock.Mock(return_value=None) # Get the command object to test self.cmd = network.CreateNetwork(self.app, self.namespace) @@ -324,6 +369,7 @@ class TestCreateNetworkIdentityV2(TestNetwork): 'tenant_id': self.project.id, 'project_id': self.project.id, }) + self.assertFalse(self.network.set_tags.called) self.assertEqual(self.columns, columns) self.assertEqual(self.data, data) @@ -457,6 +503,7 @@ class TestListNetwork(TestNetwork): 'Network Type', 'Router Type', 'Availability Zones', + 'Tags', ) data = [] @@ -480,6 +527,7 @@ class TestListNetwork(TestNetwork): net.provider_network_type, network._format_router_external(net.is_router_external), utils.format_list(net.availability_zones), + utils.format_list(net.tags), )) def setUp(self): @@ -497,6 +545,9 @@ class TestListNetwork(TestNetwork): self.network.dhcp_agent_hosting_networks = mock.Mock( return_value=self._network) + # TestListTagMixin + self._tag_list_resource_mock = self.network.networks + def test_network_list_no_options(self): arglist = [] verifylist = [ @@ -790,11 +841,37 @@ class TestListNetwork(TestNetwork): self.assertEqual(self.columns, columns) self.assertEqual(list(data), list(self.data)) + def test_list_with_tag_options(self): + arglist = [ + '--tags', 'red,blue', + '--any-tags', 'red,green', + '--not-tags', 'orange,yellow', + '--not-any-tags', 'black,white', + ] + verifylist = [ + ('tags', ['red', 'blue']), + ('any_tags', ['red', 'green']), + ('not_tags', ['orange', 'yellow']), + ('not_any_tags', ['black', 'white']), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + + self.network.networks.assert_called_once_with( + **{'tags': 'red,blue', + 'any_tags': 'red,green', + 'not_tags': 'orange,yellow', + 'not_any_tags': 'black,white'} + ) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, list(data)) + class TestSetNetwork(TestNetwork): # The network to set. - _network = network_fakes.FakeNetwork.create_one_network() + _network = network_fakes.FakeNetwork.create_one_network( + {'tags': ['green', 'red']}) qos_policy = (network_fakes.FakeNetworkQosPolicy. create_one_qos_policy(attrs={'id': _network.qos_policy_id})) @@ -802,6 +879,7 @@ class TestSetNetwork(TestNetwork): super(TestSetNetwork, self).setUp() self.network.update_network = mock.Mock(return_value=None) + self.network.set_tags = mock.Mock(return_value=None) self.network.find_network = mock.Mock(return_value=self._network) self.network.find_qos_policy = mock.Mock(return_value=self.qos_policy) @@ -821,7 +899,6 @@ class TestSetNetwork(TestNetwork): '--provider-network-type', 'vlan', '--provider-physical-network', 'physnet1', '--provider-segment', '400', - '--no-transparent-vlan', '--enable-port-security', '--qos-policy', self.qos_policy.name, ] @@ -836,7 +913,6 @@ class TestSetNetwork(TestNetwork): ('provider_network_type', 'vlan'), ('physical_network', 'physnet1'), ('segmentation_id', '400'), - ('no_transparent_vlan', True), ('enable_port_security', True), ('qos_policy', self.qos_policy.name), ] @@ -854,7 +930,6 @@ class TestSetNetwork(TestNetwork): 'provider:network_type': 'vlan', 'provider:physical_network': 'physnet1', 'provider:segmentation_id': '400', - 'vlan_transparent': False, 'port_security_enabled': True, 'qos_policy_id': self.qos_policy.id, } @@ -901,11 +976,38 @@ class TestSetNetwork(TestNetwork): parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) - attrs = {} - self.network.update_network.assert_called_once_with( - self._network, **attrs) + self.assertFalse(self.network.update_network.called) + self.assertFalse(self.network.set_tags.called) self.assertIsNone(result) + def _test_set_tags(self, with_tags=True): + if with_tags: + arglist = ['--tag', 'red', '--tag', 'blue'] + verifylist = [('tags', ['red', 'blue'])] + expected_args = ['red', 'blue', 'green'] + else: + arglist = ['--no-tag'] + verifylist = [('no_tag', True)] + expected_args = [] + arglist.append(self._network.name) + verifylist.append( + ('network', self._network.name)) + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + result = self.cmd.take_action(parsed_args) + + self.assertFalse(self.network.update_network.called) + self.network.set_tags.assert_called_once_with( + self._network, + tests_utils.CompareBySet(expected_args)) + self.assertIsNone(result) + + def test_set_with_tags(self): + self._test_set_tags(with_tags=True) + + def test_set_with_no_tag(self): + self._test_set_tags(with_tags=False) + class TestShowNetwork(TestNetwork): @@ -932,6 +1034,7 @@ class TestShowNetwork(TestNetwork): 'shared', 'status', 'subnets', + 'tags', ) data = ( @@ -954,6 +1057,7 @@ class TestShowNetwork(TestNetwork): _network.shared, _network.status, utils.format_list(_network.subnets), + utils.format_list(_network.tags), ) def setUp(self): @@ -987,3 +1091,63 @@ class TestShowNetwork(TestNetwork): self.assertEqual(self.columns, columns) self.assertEqual(self.data, data) + + +class TestUnsetNetwork(TestNetwork): + + # The network to set. + _network = network_fakes.FakeNetwork.create_one_network( + {'tags': ['green', 'red']}) + qos_policy = (network_fakes.FakeNetworkQosPolicy. + create_one_qos_policy(attrs={'id': _network.qos_policy_id})) + + def setUp(self): + super(TestUnsetNetwork, self).setUp() + + self.network.update_network = mock.Mock(return_value=None) + self.network.set_tags = mock.Mock(return_value=None) + + self.network.find_network = mock.Mock(return_value=self._network) + self.network.find_qos_policy = mock.Mock(return_value=self.qos_policy) + + # Get the command object to test + self.cmd = network.UnsetNetwork(self.app, self.namespace) + + def test_unset_nothing(self): + arglist = [self._network.name, ] + verifylist = [('network', self._network.name), ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + result = self.cmd.take_action(parsed_args) + + self.assertFalse(self.network.update_network.called) + self.assertFalse(self.network.set_tags.called) + self.assertIsNone(result) + + def _test_unset_tags(self, with_tags=True): + if with_tags: + arglist = ['--tag', 'red', '--tag', 'blue'] + verifylist = [('tags', ['red', 'blue'])] + expected_args = ['green'] + else: + arglist = ['--all-tag'] + verifylist = [('all_tag', True)] + expected_args = [] + arglist.append(self._network.name) + verifylist.append( + ('network', self._network.name)) + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + result = self.cmd.take_action(parsed_args) + + self.assertFalse(self.network.update_network.called) + self.network.set_tags.assert_called_once_with( + self._network, + tests_utils.CompareBySet(expected_args)) + self.assertIsNone(result) + + def test_unset_with_tags(self): + self._test_unset_tags(with_tags=True) + + def test_unset_with_all_tag(self): + self._test_unset_tags(with_tags=False) diff --git a/openstackclient/tests/unit/network/v2/test_network_agent.py b/openstackclient/tests/unit/network/v2/test_network_agent.py index 9bb3f090..12e40cdb 100644 --- a/openstackclient/tests/unit/network/v2/test_network_agent.py +++ b/openstackclient/tests/unit/network/v2/test_network_agent.py @@ -73,6 +73,46 @@ class TestAddNetworkToAgent(TestNetworkAgent): self.agent, self.net) +class TestAddRouterAgent(TestNetworkAgent): + + _router = network_fakes.FakeRouter.create_one_router() + _agent = network_fakes.FakeNetworkAgent.create_one_network_agent() + + def setUp(self): + super(TestAddRouterAgent, self).setUp() + self.network.add_router_to_agent = mock.Mock() + self.cmd = network_agent.AddRouterToAgent(self.app, self.namespace) + self.network.get_agent = mock.Mock(return_value=self._agent) + self.network.find_router = mock.Mock(return_value=self._router) + + def test_add_no_options(self): + arglist = [] + verifylist = [] + + # Missing agent ID will cause command to bail + self.assertRaises(tests_utils.ParserException, self.check_parser, + self.cmd, arglist, verifylist) + + def test_add_router_required_options(self): + arglist = [ + self._agent.id, + self._router.id, + '--l3', + ] + verifylist = [ + ('l3', True), + ('agent_id', self._agent.id), + ('router', self._router.id), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + result = self.cmd.take_action(parsed_args) + + self.network.add_router_to_agent.assert_called_with( + self._agent, self._router) + self.assertIsNone(result) + + class TestDeleteNetworkAgent(TestNetworkAgent): network_agents = ( @@ -171,34 +211,16 @@ class TestListNetworkAgent(TestNetworkAgent): ) data = [] for agent in network_agents: - agent.agent_type = 'DHCP agent' data.append(( agent.id, agent.agent_type, agent.host, agent.availability_zone, - agent.alive, + network_agent._format_alive(agent.alive), network_agent._format_admin_state(agent.admin_state_up), agent.binary, )) - network_agent_columns = ( - 'ID', - 'Host', - 'Admin State Up', - 'Alive', - ) - - network_agent_data = [] - - for agent in network_agents: - network_agent_data.append(( - agent.id, - agent.host, - network_agent._format_admin_state(agent.admin_state_up), - agent.alive, - )) - def setUp(self): super(TestListNetworkAgent, self).setUp() self.network.agents = mock.Mock( @@ -213,6 +235,14 @@ class TestListNetworkAgent(TestNetworkAgent): self.network.network_hosting_dhcp_agents = mock.Mock( return_value=self.network_agents) + self.network.get_agent = mock.Mock(return_value=_testagent) + + self._testrouter = \ + network_fakes.FakeRouter.create_one_router() + self.network.find_router = mock.Mock(return_value=self._testrouter) + self.network.routers_hosting_l3_agents = mock.Mock( + return_value=self.network_agents) + # Get the command object to test self.cmd = network_agent.ListNetworkAgent(self.app, self.namespace) @@ -239,7 +269,7 @@ class TestListNetworkAgent(TestNetworkAgent): columns, data = self.cmd.take_action(parsed_args) self.network.agents.assert_called_once_with(**{ - 'agent_type': self.network_agents[0].agent_type, + 'agent_type': 'DHCP agent', }) self.assertEqual(self.columns, columns) self.assertEqual(self.data, list(data)) @@ -276,8 +306,53 @@ class TestListNetworkAgent(TestNetworkAgent): self.network.network_hosting_dhcp_agents.assert_called_once_with( *attrs) - self.assertEqual(self.network_agent_columns, columns) - self.assertEqual(list(self.network_agent_data), list(data)) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, list(data)) + + def test_network_agents_list_routers(self): + arglist = [ + '--router', self._testrouter.id, + ] + verifylist = [ + ('router', self._testrouter.id), + ('long', False) + ] + + attrs = {self._testrouter, } + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + + self.network.routers_hosting_l3_agents.assert_called_once_with( + *attrs) + + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, list(data)) + + def test_network_agents_list_routers_with_long_option(self): + arglist = [ + '--router', self._testrouter.id, + '--long', + ] + verifylist = [ + ('router', self._testrouter.id), + ('long', True) + ] + + attrs = {self._testrouter, } + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + + self.network.routers_hosting_l3_agents.assert_called_once_with( + *attrs) + + # Add a column 'HA State' and corresponding data. + router_agent_columns = self.columns + ('HA State',) + router_agent_data = [d + ('',) for d in self.data] + + self.assertEqual(router_agent_columns, columns) + self.assertEqual(router_agent_data, list(data)) class TestRemoveNetworkFromAgent(TestNetworkAgent): @@ -303,6 +378,16 @@ class TestRemoveNetworkFromAgent(TestNetworkAgent): self.assertRaises(tests_utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) + def test_network_agents_list_routers_no_arg(self): + arglist = [ + '--routers', + ] + verifylist = [] + + # Missing required args should bail here + self.assertRaises(tests_utils.ParserException, self.check_parser, + self.cmd, arglist, verifylist) + def test_network_from_dhcp_agent(self): arglist = [ '--dhcp', @@ -322,6 +407,46 @@ class TestRemoveNetworkFromAgent(TestNetworkAgent): self.agent, self.net) +class TestRemoveRouterAgent(TestNetworkAgent): + _router = network_fakes.FakeRouter.create_one_router() + _agent = network_fakes.FakeNetworkAgent.create_one_network_agent() + + def setUp(self): + super(TestRemoveRouterAgent, self).setUp() + self.network.remove_router_from_agent = mock.Mock() + self.cmd = network_agent.RemoveRouterFromAgent(self.app, + self.namespace) + self.network.get_agent = mock.Mock(return_value=self._agent) + self.network.find_router = mock.Mock(return_value=self._router) + + def test_remove_no_options(self): + arglist = [] + verifylist = [] + + # Missing agent ID will cause command to bail + self.assertRaises(tests_utils.ParserException, self.check_parser, + self.cmd, arglist, verifylist) + + def test_remove_router_required_options(self): + arglist = [ + '--l3', + self._agent.id, + self._router.id, + ] + verifylist = [ + ('l3', True), + ('agent_id', self._agent.id), + ('router', self._router.id), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + result = self.cmd.take_action(parsed_args) + + self.network.remove_router_from_agent.assert_called_with( + self._agent, self._router) + self.assertIsNone(result) + + class TestSetNetworkAgent(TestNetworkAgent): _network_agent = ( @@ -415,9 +540,9 @@ class TestShowNetworkAgent(TestNetworkAgent): 'id', ) data = ( - network_agent._format_admin_state(_network_agent.admin_state_up), + network_agent._format_admin_state(_network_agent.is_admin_state_up), _network_agent.agent_type, - _network_agent.alive, + network_agent._format_alive(_network_agent.is_alive), _network_agent.availability_zone, _network_agent.binary, utils.format_dict(_network_agent.configurations), diff --git a/openstackclient/tests/unit/network/v2/test_network_qos_policy.py b/openstackclient/tests/unit/network/v2/test_network_qos_policy.py index 667f5015..e7239932 100644 --- a/openstackclient/tests/unit/network/v2/test_network_qos_policy.py +++ b/openstackclient/tests/unit/network/v2/test_network_qos_policy.py @@ -48,6 +48,7 @@ class TestCreateNetworkQosPolicy(TestQosPolicy): columns = ( 'description', 'id', + 'is_default', 'name', 'project_id', 'rules', @@ -57,6 +58,7 @@ class TestCreateNetworkQosPolicy(TestQosPolicy): data = ( new_qos_policy.description, new_qos_policy.id, + new_qos_policy.is_default, new_qos_policy.name, new_qos_policy.project_id, new_qos_policy.rules, @@ -106,12 +108,14 @@ class TestCreateNetworkQosPolicy(TestQosPolicy): '--project', self.project.name, self.new_qos_policy.name, '--description', 'QoS policy description', + '--default', ] verifylist = [ ('share', True), ('project', self.project.name), ('name', self.new_qos_policy.name), ('description', 'QoS policy description'), + ('default', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -122,6 +126,28 @@ class TestCreateNetworkQosPolicy(TestQosPolicy): 'tenant_id': self.project.id, 'name': self.new_qos_policy.name, 'description': 'QoS policy description', + 'is_default': True, + }) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) + + def test_create_no_default(self): + arglist = [ + self.new_qos_policy.name, + '--no-default' + ] + verifylist = [ + ('project', None), + ('name', self.new_qos_policy.name), + ('default', False), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = (self.cmd.take_action(parsed_args)) + + self.network.create_qos_policy.assert_called_once_with(**{ + 'name': self.new_qos_policy.name, + 'is_default': False, }) self.assertEqual(self.columns, columns) self.assertEqual(self.data, data) @@ -220,6 +246,7 @@ class TestListNetworkQosPolicy(TestQosPolicy): 'ID', 'Name', 'Shared', + 'Default', 'Project', ) data = [] @@ -228,6 +255,7 @@ class TestListNetworkQosPolicy(TestQosPolicy): qos_policy.id, qos_policy.name, qos_policy.shared, + qos_policy.is_default, qos_policy.project_id, )) @@ -333,17 +361,19 @@ class TestSetNetworkQosPolicy(TestQosPolicy): self._qos_policy, **attrs) self.assertIsNone(result) - def test_set_name_share_description(self): + def test_set_name_share_description_default(self): arglist = [ '--name', 'new_qos_policy', '--share', '--description', 'QoS policy description', + '--default', self._qos_policy.name, ] verifylist = [ ('name', 'new_qos_policy'), ('share', True), ('description', 'QoS policy description'), + ('default', True), ('policy', self._qos_policy.name), ] @@ -353,25 +383,29 @@ class TestSetNetworkQosPolicy(TestQosPolicy): 'name': 'new_qos_policy', 'description': 'QoS policy description', 'shared': True, + 'is_default': True, } self.network.update_qos_policy.assert_called_with( self._qos_policy, **attrs) self.assertIsNone(result) - def test_set_no_share(self): + def test_set_no_share_no_default(self): arglist = [ '--no-share', + '--no-default', self._qos_policy.name, ] verifylist = [ ('no_share', True), + ('no_default', True), ('policy', self._qos_policy.name), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) attrs = { - 'shared': False + 'shared': False, + 'is_default': False } self.network.update_qos_policy.assert_called_with( self._qos_policy, **attrs) @@ -386,6 +420,7 @@ class TestShowNetworkQosPolicy(TestQosPolicy): columns = ( 'description', 'id', + 'is_default', 'name', 'project_id', 'rules', @@ -394,6 +429,7 @@ class TestShowNetworkQosPolicy(TestQosPolicy): data = ( _qos_policy.description, _qos_policy.id, + _qos_policy.is_default, _qos_policy.name, _qos_policy.project_id, _qos_policy.rules, diff --git a/openstackclient/tests/unit/network/v2/test_network_qos_rule.py b/openstackclient/tests/unit/network/v2/test_network_qos_rule.py index 41ccae32..176bc86d 100644 --- a/openstackclient/tests/unit/network/v2/test_network_qos_rule.py +++ b/openstackclient/tests/unit/network/v2/test_network_qos_rule.py @@ -127,7 +127,7 @@ class TestCreateNetworkQosRuleMinimumBandwidth(TestNetworkQosRule): self.cmd.take_action(parsed_args) except exceptions.CommandError as e: msg = ('"Create" rule command for type "minimum-bandwidth" ' - 'requires arguments min_kbps, direction') + 'requires arguments direction, min_kbps') self.assertEqual(msg, str(e)) @@ -229,6 +229,7 @@ class TestCreateNetworkQosRuleBandwidtLimit(TestNetworkQosRule): self.new_rule = network_fakes.FakeNetworkQosRule.create_one_qos_rule( attrs) self.columns = ( + 'direction', 'id', 'max_burst_kbits', 'max_kbps', @@ -238,6 +239,7 @@ class TestCreateNetworkQosRuleBandwidtLimit(TestNetworkQosRule): ) self.data = ( + self.new_rule.direction, self.new_rule.id, self.new_rule.max_burst_kbits, self.new_rule.max_kbps, @@ -265,6 +267,7 @@ class TestCreateNetworkQosRuleBandwidtLimit(TestNetworkQosRule): '--type', RULE_TYPE_BANDWIDTH_LIMIT, '--max-kbps', str(self.new_rule.max_kbps), '--max-burst-kbits', str(self.new_rule.max_burst_kbits), + '--egress', self.new_rule.qos_policy_id, ] @@ -272,6 +275,7 @@ class TestCreateNetworkQosRuleBandwidtLimit(TestNetworkQosRule): ('type', RULE_TYPE_BANDWIDTH_LIMIT), ('max_kbps', self.new_rule.max_kbps), ('max_burst_kbits', self.new_rule.max_burst_kbits), + ('egress', True), ('qos_policy', self.new_rule.qos_policy_id), ] @@ -281,7 +285,8 @@ class TestCreateNetworkQosRuleBandwidtLimit(TestNetworkQosRule): self.network.create_qos_bandwidth_limit_rule.assert_called_once_with( self.qos_policy.id, **{'max_kbps': self.new_rule.max_kbps, - 'max_burst_kbps': self.new_rule.max_burst_kbits} + 'max_burst_kbps': self.new_rule.max_burst_kbits, + 'direction': self.new_rule.direction} ) self.assertEqual(self.columns, columns) self.assertEqual(self.data, data) @@ -304,7 +309,7 @@ class TestCreateNetworkQosRuleBandwidtLimit(TestNetworkQosRule): self.cmd.take_action(parsed_args) except exceptions.CommandError as e: msg = ('"Create" rule command for type "bandwidth-limit" ' - 'requires arguments max_kbps, max_burst_kbps') + 'requires arguments max_burst_kbps, max_kbps') self.assertEqual(msg, str(e)) @@ -574,8 +579,8 @@ class TestSetNetworkQosRuleMinimumBandwidth(TestNetworkQosRule): self.cmd.take_action(parsed_args) except exceptions.CommandError as e: msg = ('Failed to set Network QoS rule ID "%(rule)s": Rule type ' - '"minimum-bandwidth" only requires arguments min_kbps, ' - 'direction' % {'rule': self.new_rule.id}) + '"minimum-bandwidth" only requires arguments direction, ' + 'min_kbps' % {'rule': self.new_rule.id}) self.assertEqual(msg, str(e)) @@ -716,9 +721,13 @@ class TestSetNetworkQosRuleBandwidthLimit(TestNetworkQosRule): def test_set_max_kbps_to_zero(self): self._set_max_kbps(max_kbps=0) + def _reset_max_kbps(self, max_kbps): + self.new_rule.max_kbps = max_kbps + def _set_max_kbps(self, max_kbps=None): if max_kbps: - previous_max_kbps = self.new_rule.max_kbps + self.addCleanup(self._reset_max_kbps, + self.new_rule.max_kbps) self.new_rule.max_kbps = max_kbps arglist = [ @@ -742,18 +751,19 @@ class TestSetNetworkQosRuleBandwidthLimit(TestNetworkQosRule): self.new_rule, self.qos_policy.id, **attrs) self.assertIsNone(result) - if max_kbps: - self.new_rule.max_kbps = previous_max_kbps - def test_set_max_burst_kbits(self): self._set_max_burst_kbits() def test_set_max_burst_kbits_to_zero(self): self._set_max_burst_kbits(max_burst_kbits=0) + def _reset_max_burst_kbits(self, max_burst_kbits): + self.new_rule.max_burst_kbits = max_burst_kbits + def _set_max_burst_kbits(self, max_burst_kbits=None): if max_burst_kbits: - previous_max_burst_kbits = self.new_rule.max_burst_kbits + self.addCleanup(self._reset_max_burst_kbits, + self.new_rule.max_burst_kbits) self.new_rule.max_burst_kbits = max_burst_kbits arglist = [ @@ -777,8 +787,38 @@ class TestSetNetworkQosRuleBandwidthLimit(TestNetworkQosRule): self.new_rule, self.qos_policy.id, **attrs) self.assertIsNone(result) - if max_burst_kbits: - self.new_rule.max_burst_kbits = previous_max_burst_kbits + def test_set_direction_egress(self): + self._set_direction('egress') + + def test_set_direction_ingress(self): + self._set_direction('ingress') + + def _reset_direction(self, direction): + self.new_rule.direction = direction + + def _set_direction(self, direction): + self.addCleanup(self._reset_direction, self.new_rule.direction) + + arglist = [ + '--%s' % direction, + self.new_rule.qos_policy_id, + self.new_rule.id, + ] + verifylist = [ + (direction, True), + ('qos_policy', self.new_rule.qos_policy_id), + ('id', self.new_rule.id), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + result = self.cmd.take_action(parsed_args) + + attrs = { + 'direction': direction, + } + self.network.update_qos_bandwidth_limit_rule.assert_called_with( + self.new_rule, self.qos_policy.id, **attrs) + self.assertIsNone(result) def test_set_wrong_options(self): arglist = [ @@ -797,8 +837,8 @@ class TestSetNetworkQosRuleBandwidthLimit(TestNetworkQosRule): self.cmd.take_action(parsed_args) except exceptions.CommandError as e: msg = ('Failed to set Network QoS rule ID "%(rule)s": Rule type ' - '"bandwidth-limit" only requires arguments max_kbps, ' - 'max_burst_kbps' % {'rule': self.new_rule.id}) + '"bandwidth-limit" only requires arguments direction, ' + 'max_burst_kbps, max_kbps' % {'rule': self.new_rule.id}) self.assertEqual(msg, str(e)) @@ -999,6 +1039,7 @@ class TestShowNetworkQosBandwidthLimit(TestNetworkQosRule): attrs) self.qos_policy.rules = [self.new_rule] self.columns = ( + 'direction', 'id', 'max_burst_kbits', 'max_kbps', @@ -1007,6 +1048,7 @@ class TestShowNetworkQosBandwidthLimit(TestNetworkQosRule): 'type' ) self.data = ( + self.new_rule.direction, self.new_rule.id, self.new_rule.max_burst_kbits, self.new_rule.max_kbps, diff --git a/openstackclient/tests/unit/network/v2/test_port.py b/openstackclient/tests/unit/network/v2/test_port.py index 851bf25a..97be5afd 100644 --- a/openstackclient/tests/unit/network/v2/test_port.py +++ b/openstackclient/tests/unit/network/v2/test_port.py @@ -35,7 +35,8 @@ class TestPort(network_fakes.TestNetworkV2): # Get a shortcut to the ProjectManager Mock self.projects_mock = self.app.client_manager.identity.projects - def _get_common_cols_data(self, fake_port): + @staticmethod + def _get_common_cols_data(fake_port): columns = ( 'admin_state_up', 'allowed_address_pairs', @@ -44,6 +45,7 @@ class TestPort(network_fakes.TestNetworkV2): 'binding_vif_details', 'binding_vif_type', 'binding_vnic_type', + 'data_plane_status', 'description', 'device_id', 'device_owner', @@ -60,6 +62,7 @@ class TestPort(network_fakes.TestNetworkV2): 'qos_policy_id', 'security_group_ids', 'status', + 'tags', ) data = ( @@ -70,6 +73,7 @@ class TestPort(network_fakes.TestNetworkV2): utils.format_dict(fake_port.binding_vif_details), fake_port.binding_vif_type, fake_port.binding_vnic_type, + fake_port.data_plane_status, fake_port.description, fake_port.device_id, fake_port.device_owner, @@ -86,6 +90,7 @@ class TestPort(network_fakes.TestNetworkV2): fake_port.qos_policy_id, utils.format_list(fake_port.security_group_ids), fake_port.status, + utils.format_list(fake_port.tags), ) return columns, data @@ -94,11 +99,13 @@ class TestPort(network_fakes.TestNetworkV2): class TestCreatePort(TestPort): _port = network_fakes.FakePort.create_one_port() + columns, data = TestPort._get_common_cols_data(_port) def setUp(self): super(TestCreatePort, self).setUp() self.network.create_port = mock.Mock(return_value=self._port) + self.network.set_tags = mock.Mock(return_value=None) fake_net = network_fakes.FakeNetwork.create_one_network({ 'id': self._port.network_id, }) @@ -127,10 +134,10 @@ class TestCreatePort(TestPort): 'network_id': self._port.network_id, 'name': 'test-port', }) + self.assertFalse(self.network.set_tags.called) - ref_columns, ref_data = self._get_common_cols_data(self._port) - self.assertEqual(ref_columns, columns) - self.assertEqual(ref_data, data) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) def test_create_full_options(self): arglist = [ @@ -164,7 +171,6 @@ class TestCreatePort(TestPort): ('network', self._port.network_id), ('dns_name', '8.8.8.8'), ('name', 'test-port'), - ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -185,9 +191,8 @@ class TestCreatePort(TestPort): 'name': 'test-port', }) - ref_columns, ref_data = self._get_common_cols_data(self._port) - self.assertEqual(ref_columns, columns) - self.assertEqual(ref_data, data) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) def test_create_invalid_json_binding_profile(self): arglist = [ @@ -237,9 +242,8 @@ class TestCreatePort(TestPort): 'name': 'test-port', }) - ref_columns, ref_data = self._get_common_cols_data(self._port) - self.assertEqual(ref_columns, columns) - self.assertEqual(ref_data, data) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) def test_create_with_security_group(self): secgroup = network_fakes.FakeSecurityGroup.create_one_security_group() @@ -267,9 +271,8 @@ class TestCreatePort(TestPort): 'name': 'test-port', }) - ref_columns, ref_data = self._get_common_cols_data(self._port) - self.assertEqual(ref_columns, columns) - self.assertEqual(ref_data, data) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) def test_create_port_with_dns_name(self): arglist = [ @@ -294,9 +297,8 @@ class TestCreatePort(TestPort): 'name': 'test-port', }) - ref_columns, ref_data = self._get_common_cols_data(self._port) - self.assertEqual(ref_columns, columns) - self.assertEqual(ref_data, data) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) def test_create_with_security_groups(self): sg_1 = network_fakes.FakeSecurityGroup.create_one_security_group() @@ -325,9 +327,8 @@ class TestCreatePort(TestPort): 'name': 'test-port', }) - ref_columns, ref_data = self._get_common_cols_data(self._port) - self.assertEqual(ref_columns, columns) - self.assertEqual(ref_data, data) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) def test_create_with_no_security_groups(self): arglist = [ @@ -352,9 +353,8 @@ class TestCreatePort(TestPort): 'name': 'test-port', }) - ref_columns, ref_data = self._get_common_cols_data(self._port) - self.assertEqual(ref_columns, columns) - self.assertEqual(ref_data, data) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) def test_create_port_with_allowed_address_pair_ipaddr(self): pairs = [{'ip_address': '192.168.1.123'}, @@ -383,9 +383,8 @@ class TestCreatePort(TestPort): 'name': 'test-port', }) - ref_columns, ref_data = self._get_common_cols_data(self._port) - self.assertEqual(ref_columns, columns) - self.assertEqual(ref_data, data) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) def test_create_port_with_allowed_address_pair(self): pairs = [{'ip_address': '192.168.1.123', @@ -420,9 +419,8 @@ class TestCreatePort(TestPort): 'name': 'test-port', }) - ref_columns, ref_data = self._get_common_cols_data(self._port) - self.assertEqual(ref_columns, columns) - self.assertEqual(ref_data, data) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) def test_create_port_with_qos(self): qos_policy = network_fakes.FakeNetworkQosPolicy.create_one_qos_policy() @@ -449,9 +447,8 @@ class TestCreatePort(TestPort): 'name': 'test-port', }) - ref_columns, ref_data = self._get_common_cols_data(self._port) - self.assertEqual(ref_columns, columns) - self.assertEqual(ref_data, data) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) def test_create_port_security_enabled(self): arglist = [ @@ -501,6 +498,48 @@ class TestCreatePort(TestPort): 'name': 'test-port', }) + def _test_create_with_tag(self, add_tags=True): + arglist = [ + '--network', self._port.network_id, + 'test-port', + ] + if add_tags: + arglist += ['--tag', 'red', '--tag', 'blue'] + else: + arglist += ['--no-tag'] + verifylist = [ + ('network', self._port.network_id,), + ('enable', True), + ('name', 'test-port'), + ] + if add_tags: + verifylist.append(('tags', ['red', 'blue'])) + else: + verifylist.append(('no_tag', True)) + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = (self.cmd.take_action(parsed_args)) + + self.network.create_port.assert_called_once_with( + admin_state_up=True, + network_id=self._port.network_id, + name='test-port' + ) + if add_tags: + self.network.set_tags.assert_called_once_with( + self._port, + tests_utils.CompareBySet(['red', 'blue'])) + else: + self.assertFalse(self.network.set_tags.called) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) + + def test_create_with_tags(self): + self._test_create_with_tag(add_tags=True) + + def test_create_with_no_tag(self): + self._test_create_with_tag(add_tags=False) + class TestDeletePort(TestPort): @@ -601,6 +640,7 @@ class TestListPort(TestPort): 'Status', 'Security Groups', 'Device Owner', + 'Tags', ) data = [] @@ -623,6 +663,7 @@ class TestListPort(TestPort): prt.status, utils.format_list(prt.security_group_ids), prt.device_owner, + utils.format_list(prt.tags), )) def setUp(self): @@ -899,10 +940,35 @@ class TestListPort(TestPort): self.assertEqual(self.columns, columns) self.assertEqual(self.data, list(data)) + def test_list_with_tag_options(self): + arglist = [ + '--tags', 'red,blue', + '--any-tags', 'red,green', + '--not-tags', 'orange,yellow', + '--not-any-tags', 'black,white', + ] + verifylist = [ + ('tags', ['red', 'blue']), + ('any_tags', ['red', 'green']), + ('not_tags', ['orange', 'yellow']), + ('not_any_tags', ['black', 'white']), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + + self.network.ports.assert_called_once_with( + **{'tags': 'red,blue', + 'any_tags': 'red,green', + 'not_tags': 'orange,yellow', + 'not_any_tags': 'black,white'} + ) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, list(data)) + class TestSetPort(TestPort): - _port = network_fakes.FakePort.create_one_port() + _port = network_fakes.FakePort.create_one_port({'tags': ['green', 'red']}) def setUp(self): super(TestSetPort, self).setUp() @@ -910,6 +976,7 @@ class TestSetPort(TestPort): self.network.find_subnet = mock.Mock(return_value=self.fake_subnet) self.network.find_port = mock.Mock(return_value=self._port) self.network.update_port = mock.Mock(return_value=None) + self.network.set_tags = mock.Mock(return_value=None) # Get the command object to test self.cmd = port.SetPort(self.app, self.namespace) @@ -924,8 +991,8 @@ class TestSetPort(TestPort): parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) - attrs = {} - self.network.update_port.assert_called_once_with(self._port, **attrs) + self.assertFalse(self.network.update_port.called) + self.assertFalse(self.network.set_tags.called) self.assertIsNone(result) def test_set_port_fixed_ip(self): @@ -1371,11 +1438,74 @@ class TestSetPort(TestPort): self.network.update_port.assert_called_once_with(_testport, **attrs) self.assertIsNone(result) + def test_set_port_data_plane_status(self): + _testport = network_fakes.FakePort.create_one_port( + {'data_plane_status': None}) + self.network.find_port = mock.Mock(return_value=_testport) + arglist = [ + '--data-plane-status', 'ACTIVE', + _testport.name, + ] + verifylist = [ + ('data_plane_status', 'ACTIVE'), + ('port', _testport.name), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + result = self.cmd.take_action(parsed_args) + + attrs = { + 'data_plane_status': 'ACTIVE', + } + + self.network.update_port.assert_called_once_with(_testport, **attrs) + self.assertIsNone(result) + + def test_set_port_invalid_data_plane_status_value(self): + arglist = [ + '--data-plane-status', 'Spider-Man', + 'test-port', + ] + self.assertRaises(tests_utils.ParserException, + self.check_parser, + self.cmd, + arglist, + None) + + def _test_set_tags(self, with_tags=True): + if with_tags: + arglist = ['--tag', 'red', '--tag', 'blue'] + verifylist = [('tags', ['red', 'blue'])] + expected_args = ['red', 'blue', 'green'] + else: + arglist = ['--no-tag'] + verifylist = [('no_tag', True)] + expected_args = [] + arglist.append(self._port.name) + verifylist.append( + ('port', self._port.name)) + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + result = self.cmd.take_action(parsed_args) + + self.assertFalse(self.network.update_port.called) + self.network.set_tags.assert_called_once_with( + self._port, + tests_utils.CompareBySet(expected_args)) + self.assertIsNone(result) + + def test_set_with_tags(self): + self._test_set_tags(with_tags=True) + + def test_set_with_no_tag(self): + self._test_set_tags(with_tags=False) + class TestShowPort(TestPort): # The port to show. _port = network_fakes.FakePort.create_one_port() + columns, data = TestPort._get_common_cols_data(_port) def setUp(self): super(TestShowPort, self).setUp() @@ -1406,9 +1536,8 @@ class TestShowPort(TestPort): self.network.find_port.assert_called_once_with( self._port.name, ignore_missing=False) - ref_columns, ref_data = self._get_common_cols_data(self._port) - self.assertEqual(ref_columns, columns) - self.assertEqual(ref_data, data) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) class TestUnsetPort(TestPort): @@ -1420,12 +1549,14 @@ class TestUnsetPort(TestPort): 'ip_address': '0.0.0.1'}, {'subnet_id': '042eb10a-3a18-4658-ab-cf47c8d03152', 'ip_address': '1.0.0.0'}], - 'binding:profile': {'batman': 'Joker', 'Superman': 'LexLuthor'}}) + 'binding:profile': {'batman': 'Joker', 'Superman': 'LexLuthor'}, + 'tags': ['green', 'red'], }) self.fake_subnet = network_fakes.FakeSubnet.create_one_subnet( {'id': '042eb10a-3a18-4658-ab-cf47c8d03152'}) self.network.find_subnet = mock.Mock(return_value=self.fake_subnet) self.network.find_port = mock.Mock(return_value=self._testport) self.network.update_port = mock.Mock(return_value=None) + self.network.set_tags = mock.Mock(return_value=None) # Get the command object to test self.cmd = port.UnsetPort(self.app, self.namespace) @@ -1573,3 +1704,54 @@ class TestUnsetPort(TestPort): self.assertRaises(exceptions.CommandError, self.cmd.take_action, parsed_args) + + def test_unset_port_data_plane_status(self): + _fake_port = network_fakes.FakePort.create_one_port( + {'data_plane_status': 'ACTIVE'}) + self.network.find_port = mock.Mock(return_value=_fake_port) + arglist = [ + '--data-plane-status', + _fake_port.name, + ] + verifylist = [ + ('data_plane_status', True), + ('port', _fake_port.name), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + result = self.cmd.take_action(parsed_args) + + attrs = { + 'data_plane_status': None, + } + + self.network.update_port.assert_called_once_with(_fake_port, **attrs) + self.assertIsNone(result) + + def _test_unset_tags(self, with_tags=True): + if with_tags: + arglist = ['--tag', 'red', '--tag', 'blue'] + verifylist = [('tags', ['red', 'blue'])] + expected_args = ['green'] + else: + arglist = ['--all-tag'] + verifylist = [('all_tag', True)] + expected_args = [] + arglist.append(self._testport.name) + verifylist.append( + ('port', self._testport.name)) + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + result = self.cmd.take_action(parsed_args) + + self.assertFalse(self.network.update_port.called) + self.network.set_tags.assert_called_once_with( + self._testport, + tests_utils.CompareBySet(expected_args)) + self.assertIsNone(result) + + def test_unset_with_tags(self): + self._test_unset_tags(with_tags=True) + + def test_unset_with_all_tag(self): + self._test_unset_tags(with_tags=False) diff --git a/openstackclient/tests/unit/network/v2/test_router.py b/openstackclient/tests/unit/network/v2/test_router.py index 02e0be94..2248db9a 100644 --- a/openstackclient/tests/unit/network/v2/test_router.py +++ b/openstackclient/tests/unit/network/v2/test_router.py @@ -129,6 +129,7 @@ class TestCreateRouter(TestRouter): 'project_id', 'routes', 'status', + 'tags', ) data = ( router._format_admin_state(new_router.admin_state_up), @@ -143,12 +144,14 @@ class TestCreateRouter(TestRouter): new_router.tenant_id, router._format_routes(new_router.routes), new_router.status, + osc_utils.format_list(new_router.tags), ) def setUp(self): super(TestCreateRouter, self).setUp() self.network.create_router = mock.Mock(return_value=self.new_router) + self.network.set_tags = mock.Mock(return_value=None) # Get the command object to test self.cmd = router.CreateRouter(self.app, self.namespace) @@ -159,6 +162,7 @@ class TestCreateRouter(TestRouter): self.assertRaises(tests_utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) + self.assertFalse(self.network.set_tags.called) def test_create_default_options(self): arglist = [ @@ -178,6 +182,7 @@ class TestCreateRouter(TestRouter): 'admin_state_up': True, 'name': self.new_router.name, }) + self.assertFalse(self.network.set_tags.called) self.assertEqual(self.columns, columns) self.assertEqual(self.data, data) @@ -265,6 +270,45 @@ class TestCreateRouter(TestRouter): self.assertEqual(self.columns, columns) self.assertEqual(self.data, data) + def _test_create_with_tag(self, add_tags=True): + arglist = [self.new_router.name] + if add_tags: + arglist += ['--tag', 'red', '--tag', 'blue'] + else: + arglist += ['--no-tag'] + verifylist = [ + ('name', self.new_router.name), + ('enable', True), + ('distributed', False), + ('ha', False), + ] + if add_tags: + verifylist.append(('tags', ['red', 'blue'])) + else: + verifylist.append(('no_tag', True)) + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = (self.cmd.take_action(parsed_args)) + + self.network.create_router.assert_called_once_with( + name=self.new_router.name, + admin_state_up=True + ) + if add_tags: + self.network.set_tags.assert_called_once_with( + self.new_router, + tests_utils.CompareBySet(['red', 'blue'])) + else: + self.assertFalse(self.network.set_tags.called) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) + + def test_create_with_tags(self): + self._test_create_with_tag(add_tags=True) + + def test_create_with_no_tag(self): + self._test_create_with_tag(add_tags=False) + class TestDeleteRouter(TestRouter): @@ -363,11 +407,13 @@ class TestListRouter(TestRouter): columns_long = columns + ( 'Routes', 'External gateway info', - 'Availability zones' + 'Availability zones', + 'Tags', ) columns_long_no_az = columns + ( 'Routes', 'External gateway info', + 'Tags', ) data = [] @@ -381,6 +427,21 @@ class TestListRouter(TestRouter): r.ha, r.tenant_id, )) + + router_agent_data = [] + for r in routers: + router_agent_data.append(( + r.id, + r.name, + r.external_gateway_info, + )) + + agents_columns = ( + 'ID', + 'Name', + 'External Gateway Info', + ) + data_long = [] for i in range(0, len(routers)): r = routers[i] @@ -389,6 +450,7 @@ class TestListRouter(TestRouter): router._format_routes(r.routes), router._format_external_gateway_info(r.external_gateway_info), osc_utils.format_list(r.availability_zones), + osc_utils.format_list(r.tags), ) ) data_long_no_az = [] @@ -398,6 +460,7 @@ class TestListRouter(TestRouter): data[i] + ( router._format_routes(r.routes), router._format_external_gateway_info(r.external_gateway_info), + osc_utils.format_list(r.tags), ) ) @@ -407,8 +470,15 @@ class TestListRouter(TestRouter): # Get the command object to test self.cmd = router.ListRouter(self.app, self.namespace) + self.network.agent_hosted_routers = mock.Mock( + return_value=self.routers) self.network.routers = mock.Mock(return_value=self.routers) self.network.find_extension = mock.Mock(return_value=self._extensions) + self.network.find_router = mock.Mock(return_value=self.routers[0]) + self._testagent = \ + network_fakes.FakeNetworkAgent.create_one_network_agent() + self.network.get_agent = mock.Mock(return_value=self._testagent) + self.network.get_router = mock.Mock(return_value=self.routers[0]) def test_router_list_no_options(self): arglist = [] @@ -556,6 +626,59 @@ class TestListRouter(TestRouter): self.assertEqual(self.columns, columns) self.assertEqual(self.data, list(data)) + def test_router_list_agents_no_args(self): + arglist = [ + '--agents', + ] + verifylist = [] + + # Missing required router ID should bail here + self.assertRaises(tests_utils.ParserException, self.check_parser, + self.cmd, arglist, verifylist) + + def test_router_list_agents(self): + arglist = [ + '--agent', self._testagent.id, + ] + verifylist = [ + ('agent', self._testagent.id), + ] + + attrs = {self._testagent.id, } + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + + self.network.agent_hosted_routers( + *attrs) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, list(data)) + + def test_list_with_tag_options(self): + arglist = [ + '--tags', 'red,blue', + '--any-tags', 'red,green', + '--not-tags', 'orange,yellow', + '--not-any-tags', 'black,white', + ] + verifylist = [ + ('tags', ['red', 'blue']), + ('any_tags', ['red', 'green']), + ('not_tags', ['orange', 'yellow']), + ('not_any_tags', ['black', 'white']), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + + self.network.routers.assert_called_once_with( + **{'tags': 'red,blue', + 'any_tags': 'red,green', + 'not_tags': 'orange,yellow', + 'not_any_tags': 'black,white'} + ) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, list(data)) + class TestRemovePortFromRouter(TestRouter): '''Remove port from a Router ''' @@ -641,13 +764,15 @@ class TestSetRouter(TestRouter): _network = network_fakes.FakeNetwork.create_one_network() _subnet = network_fakes.FakeSubnet.create_one_subnet() _router = network_fakes.FakeRouter.create_one_router( - attrs={'routes': [_default_route]} + attrs={'routes': [_default_route], + 'tags': ['green', 'red']} ) def setUp(self): super(TestSetRouter, self).setUp() self.network.router_add_gateway = mock.Mock() self.network.update_router = mock.Mock(return_value=None) + self.network.set_tags = mock.Mock(return_value=None) self.network.find_router = mock.Mock(return_value=self._router) self.network.find_network = mock.Mock(return_value=self._network) self.network.find_subnet = mock.Mock(return_value=self._subnet) @@ -852,9 +977,8 @@ class TestSetRouter(TestRouter): parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) - attrs = {} - self.network.update_router.assert_called_once_with( - self._router, **attrs) + self.assertFalse(self.network.update_router.called) + self.assertFalse(self.network.set_tags.called) self.assertIsNone(result) def test_wrong_gateway_params(self): @@ -961,6 +1085,34 @@ class TestSetRouter(TestRouter): 'enable_snat': True, }}) self.assertIsNone(result) + def _test_set_tags(self, with_tags=True): + if with_tags: + arglist = ['--tag', 'red', '--tag', 'blue'] + verifylist = [('tags', ['red', 'blue'])] + expected_args = ['red', 'blue', 'green'] + else: + arglist = ['--no-tag'] + verifylist = [('no_tag', True)] + expected_args = [] + arglist.append(self._router.name) + verifylist.append( + ('router', self._router.name)) + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + result = self.cmd.take_action(parsed_args) + + self.assertFalse(self.network.update_router.called) + self.network.set_tags.assert_called_once_with( + self._router, + tests_utils.CompareBySet(expected_args)) + self.assertIsNone(result) + + def test_set_with_tags(self): + self._test_set_tags(with_tags=True) + + def test_set_with_no_tag(self): + self._test_set_tags(with_tags=False) + class TestShowRouter(TestRouter): @@ -980,6 +1132,7 @@ class TestShowRouter(TestRouter): 'project_id', 'routes', 'status', + 'tags', ) data = ( router._format_admin_state(_router.admin_state_up), @@ -994,6 +1147,7 @@ class TestShowRouter(TestRouter): _router.tenant_id, router._format_routes(_router.routes), _router.status, + osc_utils.format_list(_router.tags), ) def setUp(self): @@ -1036,10 +1190,12 @@ class TestUnsetRouter(TestRouter): {'routes': [{"destination": "192.168.101.1/24", "nexthop": "172.24.4.3"}, {"destination": "192.168.101.2/24", - "nexthop": "172.24.4.3"}], }) + "nexthop": "172.24.4.3"}], + 'tags': ['green', 'red'], }) self.fake_subnet = network_fakes.FakeSubnet.create_one_subnet() self.network.find_router = mock.Mock(return_value=self._testrouter) self.network.update_router = mock.Mock(return_value=None) + self.network.set_tags = mock.Mock(return_value=None) # Get the command object to test self.cmd = router.UnsetRouter(self.app, self.namespace) @@ -1090,3 +1246,31 @@ class TestUnsetRouter(TestRouter): self.network.update_router.assert_called_once_with( self._testrouter, **attrs) self.assertIsNone(result) + + def _test_unset_tags(self, with_tags=True): + if with_tags: + arglist = ['--tag', 'red', '--tag', 'blue'] + verifylist = [('tags', ['red', 'blue'])] + expected_args = ['green'] + else: + arglist = ['--all-tag'] + verifylist = [('all_tag', True)] + expected_args = [] + arglist.append(self._testrouter.name) + verifylist.append( + ('router', self._testrouter.name)) + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + result = self.cmd.take_action(parsed_args) + + self.assertFalse(self.network.update_router.called) + self.network.set_tags.assert_called_once_with( + self._testrouter, + tests_utils.CompareBySet(expected_args)) + self.assertIsNone(result) + + def test_unset_with_tags(self): + self._test_unset_tags(with_tags=True) + + def test_unset_with_all_tag(self): + self._test_unset_tags(with_tags=False) diff --git a/openstackclient/tests/unit/network/v2/test_subnet.py b/openstackclient/tests/unit/network/v2/test_subnet.py index 47de5616..c96d680f 100644 --- a/openstackclient/tests/unit/network/v2/test_subnet.py +++ b/openstackclient/tests/unit/network/v2/test_subnet.py @@ -125,6 +125,7 @@ class TestCreateSubnet(TestSubnet): 'segment_id', 'service_types', 'subnetpool_id', + 'tags', ) data = ( @@ -145,6 +146,7 @@ class TestCreateSubnet(TestSubnet): _subnet.segment_id, utils.format_list(_subnet.service_types), _subnet.subnetpool_id, + utils.format_list(_subnet.tags), ) data_subnet_pool = ( @@ -165,6 +167,7 @@ class TestCreateSubnet(TestSubnet): _subnet_from_pool.segment_id, utils.format_list(_subnet_from_pool.service_types), _subnet_from_pool.subnetpool_id, + utils.format_list(_subnet.tags), ) data_ipv6 = ( @@ -185,6 +188,7 @@ class TestCreateSubnet(TestSubnet): _subnet_ipv6.segment_id, utils.format_list(_subnet_ipv6.service_types), _subnet_ipv6.subnetpool_id, + utils.format_list(_subnet.tags), ) def setUp(self): @@ -197,6 +201,8 @@ class TestCreateSubnet(TestSubnet): self.domains_mock.get.return_value = self.domain # Mock SDK calls for all tests. + self.network.create_subnet = mock.Mock(return_value=self._subnet) + self.network.set_tags = mock.Mock(return_value=None) self.network.find_network = mock.Mock(return_value=self._network) self.network.find_segment = mock.Mock( return_value=self._network_segment @@ -213,10 +219,11 @@ class TestCreateSubnet(TestSubnet): # throw a "ParserExecption" self.assertRaises(tests_utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) + self.assertFalse(self.network.create_subnet.called) + self.assertFalse(self.network.set_tags.called) def test_create_default_options(self): # Mock SDK calls for this test. - self.network.create_subnet = mock.Mock(return_value=self._subnet) self._network.id = self._subnet.network_id arglist = [ @@ -230,7 +237,6 @@ class TestCreateSubnet(TestSubnet): ('network', self._subnet.network_id), ('ip_version', self._subnet.ip_version), ('gateway', 'auto'), - ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -242,13 +248,14 @@ class TestCreateSubnet(TestSubnet): 'name': self._subnet.name, 'network_id': self._subnet.network_id, }) + self.assertFalse(self.network.set_tags.called) self.assertEqual(self.columns, columns) self.assertEqual(self.data, data) def test_create_from_subnet_pool_options(self): # Mock SDK calls for this test. - self.network.create_subnet = \ - mock.Mock(return_value=self._subnet_from_pool) + self.network.create_subnet.return_value = self._subnet_from_pool + self.network.set_tags = mock.Mock(return_value=None) self._network.id = self._subnet_from_pool.network_id arglist = [ @@ -309,7 +316,7 @@ class TestCreateSubnet(TestSubnet): def test_create_options_subnet_range_ipv6(self): # Mock SDK calls for this test. - self.network.create_subnet = mock.Mock(return_value=self._subnet_ipv6) + self.network.create_subnet.return_value = self._subnet_ipv6 self._network.id = self._subnet_ipv6.network_id arglist = [ @@ -376,12 +383,12 @@ class TestCreateSubnet(TestSubnet): 'allocation_pools': self._subnet_ipv6.allocation_pools, 'service_types': self._subnet_ipv6.service_types, }) + self.assertFalse(self.network.set_tags.called) self.assertEqual(self.columns, columns) self.assertEqual(self.data_ipv6, data) def test_create_with_network_segment(self): # Mock SDK calls for this test. - self.network.create_subnet = mock.Mock(return_value=self._subnet) self._network.id = self._subnet.network_id arglist = [ @@ -410,12 +417,12 @@ class TestCreateSubnet(TestSubnet): 'network_id': self._subnet.network_id, 'segment_id': self._network_segment.id, }) + self.assertFalse(self.network.set_tags.called) self.assertEqual(self.columns, columns) self.assertEqual(self.data, data) def test_create_with_description(self): # Mock SDK calls for this test. - self.network.create_subnet = mock.Mock(return_value=self._subnet) self._network.id = self._subnet.network_id arglist = [ @@ -444,9 +451,55 @@ class TestCreateSubnet(TestSubnet): 'network_id': self._subnet.network_id, 'description': self._subnet.description, }) + self.assertFalse(self.network.set_tags.called) self.assertEqual(self.columns, columns) self.assertEqual(self.data, data) + def _test_create_with_tag(self, add_tags=True): + arglist = [ + "--subnet-range", self._subnet.cidr, + "--network", self._subnet.network_id, + self._subnet.name, + ] + if add_tags: + arglist += ['--tag', 'red', '--tag', 'blue'] + else: + arglist += ['--no-tag'] + verifylist = [ + ('name', self._subnet.name), + ('subnet_range', self._subnet.cidr), + ('network', self._subnet.network_id), + ('ip_version', self._subnet.ip_version), + ('gateway', 'auto'), + ] + if add_tags: + verifylist.append(('tags', ['red', 'blue'])) + else: + verifylist.append(('no_tag', True)) + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = (self.cmd.take_action(parsed_args)) + + self.network.create_subnet.assert_called_once_with( + cidr=self._subnet.cidr, + ip_version=self._subnet.ip_version, + name=self._subnet.name, + network_id=self._subnet.network_id) + if add_tags: + self.network.set_tags.assert_called_once_with( + self._subnet, + tests_utils.CompareBySet(['red', 'blue'])) + else: + self.assertFalse(self.network.set_tags.called) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) + + def test_create_with_tags(self): + self._test_create_with_tag(add_tags=True) + + def test_create_with_no_tag(self): + self._test_create_with_tag(add_tags=False) + class TestDeleteSubnet(TestSubnet): @@ -546,6 +599,7 @@ class TestListSubnet(TestSubnet): 'IP Version', 'Gateway', 'Service Types', + 'Tags', ) data = [] @@ -572,6 +626,7 @@ class TestListSubnet(TestSubnet): subnet.ip_version, subnet.gateway_ip, utils.format_list(subnet.service_types), + utils.format_list(subnet.tags), )) def setUp(self): @@ -801,14 +856,41 @@ class TestListSubnet(TestSubnet): self.assertEqual(self.columns, columns) self.assertEqual(self.data, list(data)) + def test_list_with_tag_options(self): + arglist = [ + '--tags', 'red,blue', + '--any-tags', 'red,green', + '--not-tags', 'orange,yellow', + '--not-any-tags', 'black,white', + ] + verifylist = [ + ('tags', ['red', 'blue']), + ('any_tags', ['red', 'green']), + ('not_tags', ['orange', 'yellow']), + ('not_any_tags', ['black', 'white']), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + + self.network.subnets.assert_called_once_with( + **{'tags': 'red,blue', + 'any_tags': 'red,green', + 'not_tags': 'orange,yellow', + 'not_any_tags': 'black,white'} + ) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, list(data)) + class TestSetSubnet(TestSubnet): - _subnet = network_fakes.FakeSubnet.create_one_subnet() + _subnet = network_fakes.FakeSubnet.create_one_subnet( + {'tags': ['green', 'red']}) def setUp(self): super(TestSetSubnet, self).setUp() self.network.update_subnet = mock.Mock(return_value=None) + self.network.set_tags = mock.Mock(return_value=None) self.network.find_subnet = mock.Mock(return_value=self._subnet) self.cmd = subnet_v2.SetSubnet(self.app, self.namespace) @@ -867,8 +949,8 @@ class TestSetSubnet(TestSubnet): parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) - attrs = {} - self.network.update_subnet.assert_called_with(self._subnet, **attrs) + self.assertFalse(self.network.update_subnet.called) + self.assertFalse(self.network.set_tags.called) self.assertIsNone(result) def test_append_options(self): @@ -959,6 +1041,34 @@ class TestSetSubnet(TestSubnet): _testsubnet, **attrs) self.assertIsNone(result) + def _test_set_tags(self, with_tags=True): + if with_tags: + arglist = ['--tag', 'red', '--tag', 'blue'] + verifylist = [('tags', ['red', 'blue'])] + expected_args = ['red', 'blue', 'green'] + else: + arglist = ['--no-tag'] + verifylist = [('no_tag', True)] + expected_args = [] + arglist.append(self._subnet.name) + verifylist.append( + ('subnet', self._subnet.name)) + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + result = self.cmd.take_action(parsed_args) + + self.assertFalse(self.network.update_subnet.called) + self.network.set_tags.assert_called_once_with( + self._subnet, + tests_utils.CompareBySet(expected_args)) + self.assertIsNone(result) + + def test_set_with_tags(self): + self._test_set_tags(with_tags=True) + + def test_set_with_no_tag(self): + self._test_set_tags(with_tags=False) + class TestShowSubnet(TestSubnet): # The subnets to be shown @@ -982,6 +1092,7 @@ class TestShowSubnet(TestSubnet): 'segment_id', 'service_types', 'subnetpool_id', + 'tags', ) data = ( @@ -1002,6 +1113,7 @@ class TestShowSubnet(TestSubnet): _subnet.segment_id, utils.format_list(_subnet.service_types), _subnet.subnetpool_id, + utils.format_list(_subnet.tags), ) def setUp(self): @@ -1055,9 +1167,11 @@ class TestUnsetSubnet(TestSubnet): {'start': '8.8.8.160', 'end': '8.8.8.170'}], 'service_types': ['network:router_gateway', - 'network:floatingip_agent_gateway'], }) + 'network:floatingip_agent_gateway'], + 'tags': ['green', 'red'], }) self.network.find_subnet = mock.Mock(return_value=self._testsubnet) self.network.update_subnet = mock.Mock(return_value=None) + self.network.set_tags = mock.Mock(return_value=None) # Get the command object to test self.cmd = subnet_v2.UnsetSubnet(self.app, self.namespace) @@ -1169,3 +1283,31 @@ class TestUnsetSubnet(TestSubnet): parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises(exceptions.CommandError, self.cmd.take_action, parsed_args) + + def _test_unset_tags(self, with_tags=True): + if with_tags: + arglist = ['--tag', 'red', '--tag', 'blue'] + verifylist = [('tags', ['red', 'blue'])] + expected_args = ['green'] + else: + arglist = ['--all-tag'] + verifylist = [('all_tag', True)] + expected_args = [] + arglist.append(self._testsubnet.name) + verifylist.append( + ('subnet', self._testsubnet.name)) + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + result = self.cmd.take_action(parsed_args) + + self.assertFalse(self.network.update_subnet.called) + self.network.set_tags.assert_called_once_with( + self._testsubnet, + tests_utils.CompareBySet(expected_args)) + self.assertIsNone(result) + + def test_unset_with_tags(self): + self._test_unset_tags(with_tags=True) + + def test_unset_with_all_tag(self): + self._test_unset_tags(with_tags=False) diff --git a/openstackclient/tests/unit/network/v2/test_subnet_pool.py b/openstackclient/tests/unit/network/v2/test_subnet_pool.py index 80a57bbb..139fddf8 100644 --- a/openstackclient/tests/unit/network/v2/test_subnet_pool.py +++ b/openstackclient/tests/unit/network/v2/test_subnet_pool.py @@ -60,6 +60,7 @@ class TestCreateSubnetPool(TestSubnetPool): 'prefixes', 'project_id', 'shared', + 'tags', ) data = ( _subnet_pool.address_scope_id, @@ -75,6 +76,7 @@ class TestCreateSubnetPool(TestSubnetPool): utils.format_list(_subnet_pool.prefixes), _subnet_pool.project_id, _subnet_pool.shared, + utils.format_list(_subnet_pool.tags), ) def setUp(self): @@ -82,6 +84,7 @@ class TestCreateSubnetPool(TestSubnetPool): self.network.create_subnet_pool = mock.Mock( return_value=self._subnet_pool) + self.network.set_tags = mock.Mock(return_value=None) # Get the command object to test self.cmd = subnet_pool.CreateSubnetPool(self.app, self.namespace) @@ -98,6 +101,7 @@ class TestCreateSubnetPool(TestSubnetPool): self.assertRaises(tests_utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) + self.assertFalse(self.network.set_tags.called) def test_create_no_pool_prefix(self): """Make sure --pool-prefix is a required argument""" @@ -127,6 +131,7 @@ class TestCreateSubnetPool(TestSubnetPool): 'prefixes': ['10.0.10.0/24'], 'name': self._subnet_pool.name, }) + self.assertFalse(self.network.set_tags.called) self.assertEqual(self.columns, columns) self.assertEqual(self.data, data) @@ -291,6 +296,46 @@ class TestCreateSubnetPool(TestSubnetPool): self.assertEqual(self.columns, columns) self.assertEqual(self.data, data) + def _test_create_with_tag(self, add_tags=True): + arglist = [ + '--pool-prefix', '10.0.10.0/24', + self._subnet_pool.name, + ] + if add_tags: + arglist += ['--tag', 'red', '--tag', 'blue'] + else: + arglist += ['--no-tag'] + verifylist = [ + ('prefixes', ['10.0.10.0/24']), + ('name', self._subnet_pool.name), + ] + if add_tags: + verifylist.append(('tags', ['red', 'blue'])) + else: + verifylist.append(('no_tag', True)) + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = (self.cmd.take_action(parsed_args)) + + self.network.create_subnet_pool.assert_called_once_with( + prefixes=['10.0.10.0/24'], + name=self._subnet_pool.name + ) + if add_tags: + self.network.set_tags.assert_called_once_with( + self._subnet_pool, + tests_utils.CompareBySet(['red', 'blue'])) + else: + self.assertFalse(self.network.set_tags.called) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) + + def test_create_with_tags(self): + self._test_create_with_tag(add_tags=True) + + def test_create_with_no_tag(self): + self._test_create_with_tag(add_tags=False) + class TestDeleteSubnetPool(TestSubnetPool): @@ -388,6 +433,7 @@ class TestListSubnetPool(TestSubnetPool): 'Address Scope', 'Default Subnet Pool', 'Shared', + 'Tags', ) data = [] @@ -408,6 +454,7 @@ class TestListSubnetPool(TestSubnetPool): pool.address_scope_id, pool.is_default, pool.shared, + utils.format_list(pool.tags), )) def setUp(self): @@ -584,12 +631,38 @@ class TestListSubnetPool(TestSubnetPool): self.assertEqual(self.columns, columns) self.assertEqual(self.data, list(data)) + def test_list_with_tag_options(self): + arglist = [ + '--tags', 'red,blue', + '--any-tags', 'red,green', + '--not-tags', 'orange,yellow', + '--not-any-tags', 'black,white', + ] + verifylist = [ + ('tags', ['red', 'blue']), + ('any_tags', ['red', 'green']), + ('not_tags', ['orange', 'yellow']), + ('not_any_tags', ['black', 'white']), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + + self.network.subnet_pools.assert_called_once_with( + **{'tags': 'red,blue', + 'any_tags': 'red,green', + 'not_tags': 'orange,yellow', + 'not_any_tags': 'black,white'} + ) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, list(data)) + class TestSetSubnetPool(TestSubnetPool): # The subnet_pool to set. _subnet_pool = network_fakes.FakeSubnetPool.create_one_subnet_pool( - {'default_quota': 10}, + {'default_quota': 10, + 'tags': ['green', 'red']} ) _address_scope = network_fakes.FakeAddressScope.create_one_address_scope() @@ -598,6 +671,7 @@ class TestSetSubnetPool(TestSubnetPool): super(TestSetSubnetPool, self).setUp() self.network.update_subnet_pool = mock.Mock(return_value=None) + self.network.set_tags = mock.Mock(return_value=None) self.network.find_subnet_pool = mock.Mock( return_value=self._subnet_pool) @@ -667,9 +741,8 @@ class TestSetSubnetPool(TestSubnetPool): parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) - attrs = {} - self.network.update_subnet_pool.assert_called_once_with( - self._subnet_pool, **attrs) + self.assertFalse(self.network.update_subnet_pool.called) + self.assertFalse(self.network.set_tags.called) self.assertIsNone(result) def test_set_len_negative(self): @@ -834,6 +907,34 @@ class TestSetSubnetPool(TestSubnetPool): ) self.assertIsNone(result) + def _test_set_tags(self, with_tags=True): + if with_tags: + arglist = ['--tag', 'red', '--tag', 'blue'] + verifylist = [('tags', ['red', 'blue'])] + expected_args = ['red', 'blue', 'green'] + else: + arglist = ['--no-tag'] + verifylist = [('no_tag', True)] + expected_args = [] + arglist.append(self._subnet_pool.name) + verifylist.append( + ('subnet_pool', self._subnet_pool.name)) + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + result = self.cmd.take_action(parsed_args) + + self.assertFalse(self.network.update_subnet_pool.called) + self.network.set_tags.assert_called_once_with( + self._subnet_pool, + tests_utils.CompareBySet(expected_args)) + self.assertIsNone(result) + + def test_set_with_tags(self): + self._test_set_tags(with_tags=True) + + def test_set_with_no_tag(self): + self._test_set_tags(with_tags=False) + class TestShowSubnetPool(TestSubnetPool): @@ -854,6 +955,7 @@ class TestShowSubnetPool(TestSubnetPool): 'prefixes', 'project_id', 'shared', + 'tags', ) data = ( @@ -870,6 +972,7 @@ class TestShowSubnetPool(TestSubnetPool): utils.format_list(_subnet_pool.prefixes), _subnet_pool.tenant_id, _subnet_pool.shared, + utils.format_list(_subnet_pool.tags), ) def setUp(self): @@ -914,10 +1017,12 @@ class TestUnsetSubnetPool(TestSubnetPool): super(TestUnsetSubnetPool, self).setUp() self._subnetpool = network_fakes.FakeSubnetPool.create_one_subnet_pool( {'prefixes': ['10.0.10.0/24', '10.1.10.0/24', - '10.2.10.0/24'], }) + '10.2.10.0/24'], + 'tags': ['green', 'red']}) self.network.find_subnet_pool = mock.Mock( return_value=self._subnetpool) self.network.update_subnet_pool = mock.Mock(return_value=None) + self.network.set_tags = mock.Mock(return_value=None) # Get the command object to test self.cmd = subnet_pool.UnsetSubnetPool(self.app, self.namespace) @@ -927,7 +1032,10 @@ class TestUnsetSubnetPool(TestSubnetPool): '--pool-prefix', '10.1.10.0/24', self._subnetpool.name, ] - verifylist = [('prefixes', ['10.0.10.0/24', '10.1.10.0/24'])] + verifylist = [ + ('prefixes', ['10.0.10.0/24', '10.1.10.0/24']), + ('subnet_pool', self._subnetpool.name), + ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) attrs = {'prefixes': ['10.2.10.0/24']} @@ -940,8 +1048,39 @@ class TestUnsetSubnetPool(TestSubnetPool): '--pool-prefix', '10.100.1.1/25', self._subnetpool.name, ] - verifylist = [('prefixes', ['10.100.1.1/25'])] + verifylist = [ + ('prefixes', ['10.100.1.1/25']), + ('subnet_pool', self._subnetpool.name), + ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises(exceptions.CommandError, self.cmd.take_action, parsed_args) + + def _test_unset_tags(self, with_tags=True): + if with_tags: + arglist = ['--tag', 'red', '--tag', 'blue'] + verifylist = [('tags', ['red', 'blue'])] + expected_args = ['green'] + else: + arglist = ['--all-tag'] + verifylist = [('all_tag', True)] + expected_args = [] + arglist.append(self._subnetpool.name) + verifylist.append( + ('subnet_pool', self._subnetpool.name)) + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + result = self.cmd.take_action(parsed_args) + + self.assertFalse(self.network.update_subnet_pool.called) + self.network.set_tags.assert_called_once_with( + self._subnetpool, + tests_utils.CompareBySet(expected_args)) + self.assertIsNone(result) + + def test_unset_with_tags(self): + self._test_unset_tags(with_tags=True) + + def test_unset_with_all_tag(self): + self._test_unset_tags(with_tags=False) diff --git a/openstackclient/tests/unit/object/v1/fakes.py b/openstackclient/tests/unit/object/v1/fakes.py index 72646d25..5d65d106 100644 --- a/openstackclient/tests/unit/object/v1/fakes.py +++ b/openstackclient/tests/unit/object/v1/fakes.py @@ -13,6 +13,8 @@ # under the License. # +import six + from keystoneauth1 import session from openstackclient.api import object_store_v1 as object_store @@ -67,6 +69,8 @@ OBJECT = { 'last_modified': object_modified_1, } +object_1_content = six.b('object 1 content') + OBJECT_2 = { 'name': object_name_2, 'bytes': object_bytes_2, diff --git a/openstackclient/tests/unit/object/v1/test_object_all.py b/openstackclient/tests/unit/object/v1/test_object_all.py index f215836e..363f2ea2 100644 --- a/openstackclient/tests/unit/object/v1/test_object_all.py +++ b/openstackclient/tests/unit/object/v1/test_object_all.py @@ -13,8 +13,10 @@ import copy +import mock from osc_lib import exceptions from requests_mock.contrib import fixture +import six from openstackclient.object.v1 import object as object_cmds from openstackclient.tests.unit.object.v1 import fakes as object_fakes @@ -202,3 +204,44 @@ class TestObjectShow(TestObjectAll): 'manifest', ) self.assertEqual(datalist, data) + + +class TestObjectSave(TestObjectAll): + + def setUp(self): + super(TestObjectSave, self).setUp() + + # Get the command object to test + self.cmd = object_cmds.SaveObject(self.app, None) + + def test_save_to_stdout(self): + self.requests_mock.register_uri( + 'GET', + object_fakes.ENDPOINT + + '/' + + object_fakes.container_name + + '/' + + object_fakes.object_name_1, + status_code=200, + content=object_fakes.object_1_content + ) + + arglist = [ + object_fakes.container_name, + object_fakes.object_name_1, + '--file', + '-' + ] + + verifylist = [ + ('container', object_fakes.container_name), + ('object', object_fakes.object_name_1), + ('file', '-'), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + with mock.patch('sys.stdout', new=six.BytesIO()) as fake_stdout: + self.cmd.take_action(parsed_args) + + self.assertEqual(fake_stdout.getvalue(), object_fakes.object_1_content) diff --git a/openstackclient/tests/unit/utils.py b/openstackclient/tests/unit/utils.py index 3c5c8683..8f9cc7b1 100644 --- a/openstackclient/tests/unit/utils.py +++ b/openstackclient/tests/unit/utils.py @@ -25,6 +25,12 @@ class ParserException(Exception): pass +class CompareBySet(list): + """Class to compare value using set.""" + def __eq__(self, other): + return set(self) == set(other) + + class TestCase(testtools.TestCase): def setUp(self): diff --git a/openstackclient/tests/unit/volume/test_find_resource.py b/openstackclient/tests/unit/volume/test_find_resource.py index d2509315..dbf9592f 100644 --- a/openstackclient/tests/unit/volume/test_find_resource.py +++ b/openstackclient/tests/unit/volume/test_find_resource.py @@ -45,7 +45,6 @@ class TestFindResourceVolumes(test_utils.TestCase): resp = mock.Mock() body = {"volumes": [{"id": ID, 'display_name': NAME}]} api.client.get.side_effect = [Exception("Not found"), - Exception("Not found"), (resp, body)] self.manager = volumes.VolumeManager(api) @@ -69,7 +68,6 @@ class TestFindResourceVolumeSnapshots(test_utils.TestCase): resp = mock.Mock() body = {"snapshots": [{"id": ID, 'display_name': NAME}]} api.client.get.side_effect = [Exception("Not found"), - Exception("Not found"), (resp, body)] self.manager = volume_snapshots.SnapshotManager(api) |
