From 4f23a77de04bfdfafd4bf8f16b0365df7663e9e5 Mon Sep 17 00:00:00 2001 From: Richard Theis Date: Tue, 8 Mar 2016 15:18:16 -0600 Subject: Add network segment create, delete and set support Add network segment create, delete and set in support of routed networks. This patch set includes documentation, unit tests and functional tests for the following new commands: - "os network segment create" - "os network segment delete" - "os network segment set" This patch set also includes support for the name and description properties. These new commands are currently marked as beta commands. Change-Id: I86bc223c4adc5b5fe1b1ee5c9253e43ba52fb5ed Depends-On: Ib194125162057fccb4e951587c2fa4ec2e2f098c Partially-Implements: blueprint routed-networks --- openstackclient/tests/unit/network/v2/fakes.py | 9 +- .../tests/unit/network/v2/test_network_segment.py | 317 +++++++++++++++++++++ 2 files changed, 323 insertions(+), 3 deletions(-) (limited to 'openstackclient/tests/unit') diff --git a/openstackclient/tests/unit/network/v2/fakes.py b/openstackclient/tests/unit/network/v2/fakes.py index ed30bad3..d33b84c5 100644 --- a/openstackclient/tests/unit/network/v2/fakes.py +++ b/openstackclient/tests/unit/network/v2/fakes.py @@ -362,11 +362,14 @@ class FakeNetworkSegment(object): attrs = attrs or {} # Set default attributes. + fake_uuid = uuid.uuid4().hex network_segment_attrs = { - 'id': 'network-segment-id-' + uuid.uuid4().hex, - 'network_id': 'network-id-' + uuid.uuid4().hex, + 'description': 'network-segment-description-' + fake_uuid, + 'id': 'network-segment-id-' + fake_uuid, + 'name': 'network-segment-name-' + fake_uuid, + 'network_id': 'network-id-' + fake_uuid, 'network_type': 'vlan', - 'physical_network': 'physical-network-name-' + uuid.uuid4().hex, + 'physical_network': 'physical-network-name-' + fake_uuid, 'segmentation_id': 1024, } diff --git a/openstackclient/tests/unit/network/v2/test_network_segment.py b/openstackclient/tests/unit/network/v2/test_network_segment.py index b9fce078..3e755e07 100644 --- a/openstackclient/tests/unit/network/v2/test_network_segment.py +++ b/openstackclient/tests/unit/network/v2/test_network_segment.py @@ -12,6 +12,7 @@ # import mock +from mock import call from osc_lib import exceptions @@ -32,6 +33,243 @@ class TestNetworkSegment(network_fakes.TestNetworkV2): self.network = self.app.client_manager.network +class TestCreateNetworkSegment(TestNetworkSegment): + + # The network segment to create along with associated network. + _network_segment = \ + network_fakes.FakeNetworkSegment.create_one_network_segment() + _network = network_fakes.FakeNetwork.create_one_network({ + 'id': _network_segment.network_id, + }) + + columns = ( + 'description', + 'id', + 'name', + 'network_id', + 'network_type', + 'physical_network', + 'segmentation_id', + ) + + data = ( + _network_segment.description, + _network_segment.id, + _network_segment.name, + _network_segment.network_id, + _network_segment.network_type, + _network_segment.physical_network, + _network_segment.segmentation_id, + ) + + def setUp(self): + super(TestCreateNetworkSegment, self).setUp() + + self.network.create_segment = mock.Mock( + return_value=self._network_segment + ) + self.network.find_network = mock.Mock(return_value=self._network) + + # Get the command object to test + self.cmd = network_segment.CreateNetworkSegment( + self.app, + self.namespace + ) + + def test_create_no_options(self): + # Missing required args should bail here + self.assertRaises(tests_utils.ParserException, self.check_parser, + self.cmd, [], []) + + def test_create_no_beta_commands(self): + arglist = [ + '--network', self._network_segment.network_id, + '--network-type', self._network_segment.network_type, + self._network_segment.name, + ] + verifylist = [ + ('network', self._network_segment.network_id), + ('network_type', self._network_segment.network_type), + ('name', self._network_segment.name), + ] + self.app.options.os_beta_command = False + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + self.assertRaises(exceptions.CommandError, self.cmd.take_action, + parsed_args) + + def test_create_invalid_network_type(self): + arglist = [ + '--network', self._network_segment.network_id, + '--network-type', 'foo', + self._network_segment.name, + ] + self.assertRaises(tests_utils.ParserException, self.check_parser, + self.cmd, arglist, []) + + def test_create_minimum_options(self): + arglist = [ + '--network', self._network_segment.network_id, + '--network-type', self._network_segment.network_type, + self._network_segment.name, + ] + verifylist = [ + ('network', self._network_segment.network_id), + ('network_type', self._network_segment.network_type), + ('name', self._network_segment.name), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + + self.network.find_network.assert_called_once_with( + self._network_segment.network_id, + ignore_missing=False + ) + self.network.create_segment.assert_called_once_with(**{ + 'network_id': self._network_segment.network_id, + 'network_type': self._network_segment.network_type, + 'name': self._network_segment.name, + }) + + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) + + def test_create_all_options(self): + arglist = [ + '--description', self._network_segment.description, + '--network', self._network_segment.network_id, + '--network-type', self._network_segment.network_type, + '--physical-network', self._network_segment.physical_network, + '--segment', str(self._network_segment.segmentation_id), + self._network_segment.name, + ] + verifylist = [ + ('description', self._network_segment.description), + ('network', self._network_segment.network_id), + ('network_type', self._network_segment.network_type), + ('physical_network', self._network_segment.physical_network), + ('segment', self._network_segment.segmentation_id), + ('name', self._network_segment.name), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + + self.network.find_network.assert_called_once_with( + self._network_segment.network_id, + ignore_missing=False + ) + self.network.create_segment.assert_called_once_with(**{ + 'description': self._network_segment.description, + 'network_id': self._network_segment.network_id, + 'network_type': self._network_segment.network_type, + 'physical_network': self._network_segment.physical_network, + 'segmentation_id': self._network_segment.segmentation_id, + 'name': self._network_segment.name, + }) + + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) + + +class TestDeleteNetworkSegment(TestNetworkSegment): + + # The network segments to delete. + _network_segments = \ + network_fakes.FakeNetworkSegment.create_network_segments() + + def setUp(self): + super(TestDeleteNetworkSegment, self).setUp() + + self.network.delete_segment = mock.Mock(return_value=None) + self.network.find_segment = mock.MagicMock( + side_effect=self._network_segments + ) + + # Get the command object to test + self.cmd = network_segment.DeleteNetworkSegment( + self.app, + self.namespace + ) + + def test_delete_no_beta_commands(self): + arglist = [ + self._network_segments[0].id, + ] + verifylist = [ + ('network_segment', [self._network_segments[0].id]), + ] + self.app.options.os_beta_command = False + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + self.assertRaises(exceptions.CommandError, self.cmd.take_action, + parsed_args) + + def test_delete(self): + arglist = [ + self._network_segments[0].id, + ] + verifylist = [ + ('network_segment', [self._network_segments[0].id]), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + result = self.cmd.take_action(parsed_args) + + self.network.delete_segment.assert_called_once_with( + self._network_segments[0] + ) + self.assertIsNone(result) + + def test_delete_multiple(self): + arglist = [] + for _network_segment in self._network_segments: + arglist.append(_network_segment.id) + verifylist = [ + ('network_segment', arglist), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + result = self.cmd.take_action(parsed_args) + + calls = [] + for _network_segment in self._network_segments: + calls.append(call(_network_segment)) + self.network.delete_segment.assert_has_calls(calls) + self.assertIsNone(result) + + def test_delete_multiple_with_exception(self): + arglist = [ + self._network_segments[0].id, + 'doesnotexist' + ] + verifylist = [ + ('network_segment', [self._network_segments[0].id, + 'doesnotexist']), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + find_mock_result = [self._network_segments[0], + exceptions.CommandError] + self.network.find_segment = ( + mock.MagicMock(side_effect=find_mock_result) + ) + + try: + self.cmd.take_action(parsed_args) + self.fail('CommandError should be raised.') + except exceptions.CommandError as e: + self.assertEqual('1 of 2 network segments failed to delete.', + str(e)) + + self.network.find_segment.assert_any_call( + self._network_segments[0].id, ignore_missing=False) + self.network.find_segment.assert_any_call( + 'doesnotexist', ignore_missing=False) + self.network.delete_segment.assert_called_once_with( + self._network_segments[0] + ) + + class TestListNetworkSegment(TestNetworkSegment): _network = network_fakes.FakeNetwork.create_one_network() _network_segments = \ @@ -39,6 +277,7 @@ class TestListNetworkSegment(TestNetworkSegment): columns = ( 'ID', + 'Name', 'Network', 'Network Type', 'Segment', @@ -51,6 +290,7 @@ class TestListNetworkSegment(TestNetworkSegment): for _network_segment in _network_segments: data.append(( _network_segment.id, + _network_segment.name, _network_segment.network_id, _network_segment.network_type, _network_segment.segmentation_id, @@ -60,6 +300,7 @@ class TestListNetworkSegment(TestNetworkSegment): for _network_segment in _network_segments: data_long.append(( _network_segment.id, + _network_segment.name, _network_segment.network_id, _network_segment.network_type, _network_segment.segmentation_id, @@ -131,6 +372,78 @@ class TestListNetworkSegment(TestNetworkSegment): self.assertEqual(self.data, list(data)) +class TestSetNetworkSegment(TestNetworkSegment): + + # The network segment to show. + _network_segment = \ + network_fakes.FakeNetworkSegment.create_one_network_segment() + + def setUp(self): + super(TestSetNetworkSegment, self).setUp() + + self.network.find_segment = mock.Mock( + return_value=self._network_segment + ) + self.network.update_segment = mock.Mock( + return_value=self._network_segment + ) + + # Get the command object to test + self.cmd = network_segment.SetNetworkSegment(self.app, self.namespace) + + def test_set_no_beta_commands(self): + arglist = [ + self._network_segment.id, + ] + verifylist = [ + ('network_segment', self._network_segment.id), + ] + self.app.options.os_beta_command = False + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + self.assertRaises(exceptions.CommandError, self.cmd.take_action, + parsed_args) + + def test_set_no_options(self): + arglist = [ + self._network_segment.id, + ] + verifylist = [ + ('network_segment', self._network_segment.id), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + result = self.cmd.take_action(parsed_args) + + self.network.update_segment.assert_called_once_with( + self._network_segment, **{} + ) + self.assertIsNone(result) + + def test_set_all_options(self): + arglist = [ + '--description', 'new description', + '--name', 'new name', + self._network_segment.id, + ] + verifylist = [ + ('description', 'new description'), + ('name', 'new name'), + ('network_segment', self._network_segment.id), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + result = self.cmd.take_action(parsed_args) + + attrs = { + 'description': 'new description', + 'name': 'new name', + } + self.network.update_segment.assert_called_once_with( + self._network_segment, **attrs + ) + self.assertIsNone(result) + + class TestShowNetworkSegment(TestNetworkSegment): # The network segment to show. @@ -138,7 +451,9 @@ class TestShowNetworkSegment(TestNetworkSegment): network_fakes.FakeNetworkSegment.create_one_network_segment() columns = ( + 'description', 'id', + 'name', 'network_id', 'network_type', 'physical_network', @@ -146,7 +461,9 @@ class TestShowNetworkSegment(TestNetworkSegment): ) data = ( + _network_segment.description, _network_segment.id, + _network_segment.name, _network_segment.network_id, _network_segment.network_type, _network_segment.physical_network, -- cgit v1.2.1