diff --git a/openstack_dashboard/dashboards/project/networks/tests.py b/openstack_dashboard/dashboards/project/networks/tests.py index 049e5d4d07..afc878af01 100644 --- a/openstack_dashboard/dashboards/project/networks/tests.py +++ b/openstack_dashboard/dashboards/project/networks/tests.py @@ -39,7 +39,8 @@ def form_data_subnet(subnet, gateway_ip='', enable_dhcp=None, allocation_pools=None, dns_nameservers=None, - host_routes=None): + host_routes=None, + no_gateway=None): def get_value(value, default): return default if value is None else value @@ -50,7 +51,7 @@ def form_data_subnet(subnet, gateway_ip = subnet.gateway_ip if gateway_ip == '' else gateway_ip data['gateway_ip'] = gateway_ip or '' - data['no_gateway'] = (gateway_ip is None) + data['no_gateway'] = no_gateway or (gateway_ip is None) data['enable_dhcp'] = get_value(enable_dhcp, subnet.enable_dhcp) if data['ip_version'] == 6: @@ -906,6 +907,50 @@ class NetworkTests(test.TestCase, NetworkStubMixin): self.test_network_create_post_with_subnet_gw_inconsistent( test_with_subnetpool=True) + @test.create_mocks({api.neutron: ('network_create', + 'subnet_create', + 'is_extension_supported', + 'subnetpool_list')}) + def test_network_create_post_with_subnet_ignore_error_msg_for_gateway( + self): + network = self.networks.first() + subnet = self.subnets.first() + params = {'name': network.name, + 'admin_state_up': network.admin_state_up, + 'shared': False} + + self._stub_is_extension_supported({'network_availability_zone': False, + 'subnet_allocation': True}) + self.mock_subnetpool_list.return_value = self.subnetpools.list() + self.mock_network_create.return_value = network + self.mock_subnet_create.return_value = subnet + + form_data = {'net_name': network.name, + 'admin_state': network.admin_state_up, + 'shared': False, + 'with_subnet': True} + subnet_params = {'network_id': network.id, + 'name': subnet.name, + 'cidr': subnet.cidr, + 'ip_version': subnet.ip_version, + 'gateway_ip': None, + 'enable_dhcp': subnet.enable_dhcp} + form_data.update(form_data_subnet(subnet, allocation_pools=[], + no_gateway=True, gateway_ip=".")) + url = reverse('horizon:project:networks:create') + res = self.client.post(url, form_data) + self.assertNoWorkflowErrors(res) + self.assertRedirectsNoFollow(res, INDEX_URL) + + self.mock_subnetpool_list.assert_called_once_with(test.IsHttpRequest()) + self.mock_network_create.assert_called_once_with( + test.IsHttpRequest(), **params) + self.mock_subnet_create.assert_called_once_with( + test.IsHttpRequest(), + **subnet_params) + self._check_is_extension_supported({'network_availability_zone': 1, + 'subnet_allocation': 1}) + @test.create_mocks({api.neutron: ('network_get',)}) def test_network_update_get(self): network = self.networks.first() diff --git a/openstack_dashboard/dashboards/project/networks/workflows.py b/openstack_dashboard/dashboards/project/networks/workflows.py index 8106778f70..391d4ce3f9 100644 --- a/openstack_dashboard/dashboards/project/networks/workflows.py +++ b/openstack_dashboard/dashboards/project/networks/workflows.py @@ -316,6 +316,8 @@ class CreateSubnetInfoAction(workflows.Action): msg = _('Specify IP address of gateway or ' 'check "Disable Gateway" checkbox.') raise forms.ValidationError(msg) + if no_gateway and 'gateway_ip' in self._errors: + del self._errors['gateway_ip'] def clean(self): cleaned_data = super(CreateSubnetInfoAction, self).clean() diff --git a/openstack_dashboard/test/helpers.py b/openstack_dashboard/test/helpers.py index 83ba3089ba..d1c7eea042 100644 --- a/openstack_dashboard/test/helpers.py +++ b/openstack_dashboard/test/helpers.py @@ -385,6 +385,21 @@ class TestCase(horizon_helpers.TestCase): self.assertEqual(count, mocked_method.call_count) mocked_method.assert_has_calls([expected_call] * count) + def assertNoWorkflowErrors(self, response, context_name="workflow"): + """Checks for no workflow errors. + + Asserts that the response either does not contain a workflow in its + context, or that if it does, that workflow has no errors. + """ + context = getattr(response, "context", {}) + if not context or context_name not in context: + return True + errors = [step.action._errors for step in + response.context[context_name].steps] + self.assertEqual( + 0, len(errors), + "Unexpected errors were found on the workflow: %s" % errors) + class BaseAdminViewTests(TestCase): """Sets an active user with the "admin" role.