def test_allocate_vip(self, mock_get_session, mock_get_lb, mock_get_net_driver): mock_driver = mock.MagicMock() mock_get_lb.return_value = LB mock_get_net_driver.return_value = mock_driver net = network_tasks.AllocateVIP() mock_driver.allocate_vip.return_value = LB.vip mock_driver.reset_mock() self.assertEqual(LB.vip.to_dict(), net.execute(self.load_balancer_mock)) mock_driver.allocate_vip.assert_called_once_with(LB) # revert vip_mock = VIP.to_dict() net.revert(vip_mock, self.load_balancer_mock) mock_driver.deallocate_vip.assert_called_once_with( o_data_models.Vip(**vip_mock)) # revert exception mock_driver.reset_mock() mock_driver.deallocate_vip.side_effect = Exception('DeallVipException') vip_mock = VIP.to_dict() net.revert(vip_mock, self.load_balancer_mock) mock_driver.deallocate_vip.assert_called_once_with(o_data_models.Vip( **vip_mock))
def test_listeners_update(self, mock_driver, mock_generate_uuid, mock_log, mock_get_session, mock_listener_repo_get, mock_listener_repo_update, mock_amphora_repo_update): listeners_update_obj = amphora_driver_tasks.ListenersUpdate() listeners = [ data_models.Listener(id='listener1'), data_models.Listener(id='listener2') ] vip = data_models.Vip(ip_address='10.0.0.1') lb = data_models.LoadBalancer(id='lb1', listeners=listeners, vip=vip) listeners_update_obj.execute(lb) mock_driver.update.assert_called_once_with(lb) self.assertEqual(1, mock_driver.update.call_count) # Test the revert amp = listeners_update_obj.revert(lb) expected_db_calls = [ mock.call(_session_mock, id=listeners[0].id, provisioning_status=constants.ERROR), mock.call(_session_mock, id=listeners[1].id, provisioning_status=constants.ERROR) ] repo.ListenerRepository.update.has_calls(expected_db_calls) self.assertEqual(2, repo.ListenerRepository.update.call_count) self.assertIsNone(amp)
def test_allocate_vip_when_port_already_provided(self): fake_lb_vip = data_models.Vip() fake_lb = data_models.LoadBalancer(id='1', vip=fake_lb_vip) self.assertRaises(network_base.AllocateVIPException, self.driver.allocate_vip, fake_lb) show_port = self.driver.neutron_client.show_port show_port.return_value = n_constants.MOCK_NEUTRON_PORT fake_lb_vip = data_models.Vip(port_id=n_constants.MOCK_PORT_ID, subnet_id=n_constants.MOCK_SUBNET_ID) fake_lb = data_models.LoadBalancer(id='1', vip=fake_lb_vip) vip = self.driver.allocate_vip(fake_lb) self.assertIsInstance(vip, data_models.Vip) self.assertEqual(n_constants.MOCK_IP_ADDRESS, vip.ip_address) self.assertEqual(n_constants.MOCK_SUBNET_ID, vip.subnet_id) self.assertEqual(n_constants.MOCK_PORT_ID, vip.port_id) self.assertEqual(fake_lb.id, vip.load_balancer_id)
def test_allocate_vip_when_port_creation_fails(self): fake_lb_vip = data_models.Vip(subnet_id=t_constants.MOCK_SUBNET_ID) fake_lb = data_models.LoadBalancer(id='1', vip=fake_lb_vip) create_port = self.driver.neutron_client.create_port create_port.side_effect = Exception self.assertRaises(network_base.AllocateVIPException, self.driver.allocate_vip, fake_lb)
def test_update_vip_when_listener_deleted(self): listeners = [data_models.Listener(protocol_port=80, protocol=constants.PROTOCOL_TCP), data_models.Listener( protocol_port=443, protocol=constants.PROTOCOL_TCP, provisioning_status=constants.PENDING_DELETE), data_models.Listener( protocol_port=50, protocol=constants.PROTOCOL_UDP, provisioning_status=constants.PENDING_DELETE)] vip = data_models.Vip(ip_address='10.0.0.2') lb = data_models.LoadBalancer(id='1', listeners=listeners, vip=vip) list_sec_grps = self.driver.neutron_client.list_security_groups list_sec_grps.return_value = {'security_groups': [{'id': 'secgrp-1'}]} fake_rules = { 'security_group_rules': [ {'id': 'rule-80', 'port_range_max': 80, 'protocol': 'tcp'}, {'id': 'rule-22', 'port_range_max': 443, 'protocol': 'tcp'}, {'id': 'rule-udp-50', 'port_range_max': 50, 'protocol': 'tcp'} ] } list_rules = self.driver.neutron_client.list_security_group_rules list_rules.return_value = fake_rules delete_rule = self.driver.neutron_client.delete_security_group_rule create_rule = self.driver.neutron_client.create_security_group_rule self.driver.update_vip(lb) delete_rule.assert_has_calls( [mock.call('rule-22'), mock.call('rule-udp-50')]) self.assertTrue(create_rule.called)
def test_deallocate_vip_when_port_not_found(self): lb = dmh.generate_load_balancer_tree() vip = data_models.Vip(port_id='1') vip.load_balancer = lb show_port = self.driver.neutron_client.show_port show_port.side_effect = neutron_exceptions.PortNotFoundClient self.driver.deallocate_vip(vip)
def test_allocate_vip_when_no_port_provided(self): port_create_dict = copy.deepcopy(t_constants.MOCK_NEUTRON_PORT) port_create_dict['port']['device_owner'] = ( allowed_address_pairs.OCTAVIA_OWNER) port_create_dict['port']['device_id'] = 'lb-1' create_port = self.driver.neutron_client.create_port create_port.return_value = port_create_dict show_subnet = self.driver.neutron_client.show_subnet show_subnet.return_value = {'subnet': { 'id': t_constants.MOCK_SUBNET_ID, 'network_id': t_constants.MOCK_NETWORK_ID }} fake_lb_vip = data_models.Vip(subnet_id=t_constants.MOCK_SUBNET_ID, network_id=t_constants.MOCK_NETWORK_ID) fake_lb = data_models.LoadBalancer(id='1', vip=fake_lb_vip, project_id='test-project') vip = self.driver.allocate_vip(fake_lb) exp_create_port_call = { 'port': { 'name': 'octavia-lb-1', 'network_id': t_constants.MOCK_NETWORK_ID, 'device_id': 'lb-1', 'device_owner': allowed_address_pairs.OCTAVIA_OWNER, 'admin_state_up': False, 'project_id': 'test-project', 'fixed_ips': [{'subnet_id': t_constants.MOCK_SUBNET_ID}] } } create_port.assert_called_once_with(exp_create_port_call) self.assertIsInstance(vip, data_models.Vip) self.assertEqual(t_constants.MOCK_IP_ADDRESS, vip.ip_address) self.assertEqual(t_constants.MOCK_SUBNET_ID, vip.subnet_id) self.assertEqual(t_constants.MOCK_PORT_ID, vip.port_id) self.assertEqual(fake_lb.id, vip.load_balancer_id)
def setUp(self): super(TestNoopAmphoraLoadBalancerDriver, self).setUp() self.driver = driver.NoopAmphoraLoadBalancerDriver() self.listener = data_models.Listener() self.listener.id = uuidutils.generate_uuid() self.listener.protocol_port = 80 self.vip = data_models.Vip() self.vip.ip_address = "10.0.0.1" self.amphora = data_models.Amphora() self.amphora.id = self.FAKE_UUID_1 self.load_balancer = data_models.LoadBalancer( id=FAKE_UUID_1, amphorae=[self.amphora], vip=self.vip, listeners=[self.listener]) self.listener.load_balancer = self.load_balancer self.network = network_models.Network(id=self.FAKE_UUID_1) self.port = network_models.Port(id=uuidutils.generate_uuid()) self.amphorae_net_configs = { self.amphora.id: network_models.AmphoraNetworkConfig( amphora=self.amphora, vip_subnet=network_models.Subnet(id=self.FAKE_UUID_1)) } self.pem_file = 'test_pem_file' self.agent_config = 'test agent config' self.timeout_dict = { constants.REQ_CONN_TIMEOUT: 1, constants.REQ_READ_TIMEOUT: 2, constants.CONN_MAX_RETRIES: 3, constants.CONN_RETRY_INTERVAL: 4 }
def test_LoadBalancer_update_add_vip(self): new_ip = '192.0.2.44' new_subnet_id = uuidutils.generate_uuid() new_network_id = uuidutils.generate_uuid() new_port_id = uuidutils.generate_uuid() new_qos_id = uuidutils.generate_uuid() reference_VIP_obj = data_models.Vip( load_balancer_id=self.LB_ID, ip_address=new_ip, subnet_id=new_subnet_id, network_id=new_network_id, port_id=new_port_id, load_balancer=None, qos_policy_id=new_qos_id ) update_dict = { 'vip': { 'ip_address': new_ip, 'subnet_id': new_subnet_id, 'network_id': new_network_id, 'port_id': new_port_id, 'load_balancer': None, 'qos_policy_id': new_qos_id } } test_LB_obj = copy.deepcopy(self.LB_obj) test_LB_obj.update(update_dict) self.assertEqual(reference_VIP_obj, test_LB_obj.vip)
def test_update_vip_for_delete(self, mock_get_net_driver): mock_driver = mock.MagicMock() mock_get_net_driver.return_value = mock_driver vip = o_data_models.Vip() lb = o_data_models.LoadBalancer(vip=vip) net_task = network_tasks.UpdateVIPForDelete() net_task.execute(lb) mock_driver.update_vip.assert_called_once_with(lb, for_delete=True)
def test_deallocate_vip(self, mock_get_net_driver): mock_driver = mock.MagicMock() mock_get_net_driver.return_value = mock_driver net = network_tasks.DeallocateVIP() vip = o_data_models.Vip() lb = o_data_models.LoadBalancer(vip=vip) net.execute(lb) mock_driver.deallocate_vip.assert_called_once_with(lb.vip)
def test_update_vip_when_security_group_missing(self): listeners = [] vip = data_models.Vip(ip_address='10.0.0.2') lb = data_models.LoadBalancer(id='1', listeners=listeners, vip=vip) list_sec_grps = self.driver.neutron_client.list_security_groups list_sec_grps.return_value = {'security_groups': []} self.assertRaises(exceptions.MissingVIPSecurityGroup, self.driver.update_vip, lb)
def test_lb_dict_to_provider_dict(self, mock_load_cert, mock_secret, mock_get_session, mock_get_flavor): cert1 = data_models.TLSContainer(certificate='cert 1') cert2 = data_models.TLSContainer(certificate='cert 2') cert3 = data_models.TLSContainer(certificate='cert 3') mock_secret.side_effect = ['X509 POOL CA CERT FILE', 'X509 POOL CRL FILE', 'ca cert', 'X509 CRL FILE', 'ca cert', 'X509 CRL FILE', 'X509 POOL CA CERT FILE', 'X509 CRL FILE'] listener_certs = {'tls_cert': cert1, 'sni_certs': [cert2, cert3]} pool_cert = data_models.TLSContainer(certificate='pool cert') pool_certs = {'tls_cert': pool_cert, 'sni_certs': []} mock_load_cert.side_effect = [pool_certs, listener_certs, listener_certs, listener_certs, listener_certs] mock_get_flavor.return_value = {'shaved_ice': 'cherry'} test_lb_dict = {'name': 'lb1', 'project_id': self.sample_data.project_id, 'vip_subnet_id': self.sample_data.subnet_id, 'vip_port_id': self.sample_data.port_id, 'vip_address': self.sample_data.ip_address, 'vip_network_id': self.sample_data.network_id, 'vip_qos_policy_id': self.sample_data.qos_policy_id, 'id': self.sample_data.lb_id, 'listeners': [], 'pools': [], 'description': '', 'admin_state_up': True, 'provisioning_status': constants.PENDING_CREATE, 'operating_status': constants.OFFLINE, 'flavor_id': 'flavor_id', 'provider': 'noop_driver'} ref_listeners = copy.deepcopy(self.sample_data.provider_listeners) ref_prov_lb_dict = { 'vip_address': self.sample_data.ip_address, 'admin_state_up': True, 'loadbalancer_id': self.sample_data.lb_id, 'vip_subnet_id': self.sample_data.subnet_id, 'listeners': ref_listeners, 'description': '', 'project_id': self.sample_data.project_id, 'vip_port_id': self.sample_data.port_id, 'vip_qos_policy_id': self.sample_data.qos_policy_id, 'vip_network_id': self.sample_data.network_id, 'pools': self.sample_data.provider_pools, 'flavor': {'shaved_ice': 'cherry'}, 'name': 'lb1'} vip = data_models.Vip(ip_address=self.sample_data.ip_address, network_id=self.sample_data.network_id, port_id=self.sample_data.port_id, subnet_id=self.sample_data.subnet_id, qos_policy_id=self.sample_data.qos_policy_id) provider_lb_dict = utils.lb_dict_to_provider_dict( test_lb_dict, vip=vip, db_pools=self.sample_data.test_db_pools, db_listeners=self.sample_data.test_db_listeners) self.assertEqual(ref_prov_lb_dict, provider_lb_dict)
def test_update_vip_for_delete_when_security_group_missing(self, update_rules): listeners = [] vip = data_models.Vip(ip_address='10.0.0.2') lb = data_models.LoadBalancer(id='1', listeners=listeners, vip=vip) list_sec_grps = self.driver.neutron_client.list_security_groups list_sec_grps.return_value = {'security_groups': []} self.driver.update_vip(lb, for_delete=True) update_rules.assert_not_called()
def allocate_vip(self, load_balancer): LOG.debug("Network %s no-op, allocate_vip load_balancer %s", self.__class__.__name__, load_balancer) self.networkconfigconfig[load_balancer] = ( load_balancer, 'allocate_vip') return data_models.Vip(ip_address='198.51.100.1', subnet_id=uuidutils.generate_uuid(), port_id=uuidutils.generate_uuid(), load_balancer_id=load_balancer.id)
def test_deallocate_vip_when_delete_port_fails(self): vip = data_models.Vip(port_id='1') show_port = self.driver.neutron_client.show_port show_port.return_value = {'port': { 'device_owner': allowed_address_pairs.OCTAVIA_OWNER}} delete_port = self.driver.neutron_client.delete_port delete_port.side_effect = TypeError self.assertRaises(network_base.DeallocateVIPException, self.driver.deallocate_vip, vip)
def revert(self, result, loadbalancer, *args, **kwargs): """Handle a failure to allocate vip.""" if isinstance(result, failure.Failure): LOG.exception("Unable to allocate VIP") return vip = data_models.Vip(**result) LOG.info("Failover revert is not deallocating vip %s because this is " "a failover.", vip.ip_address)
def test_post_vip_plug(self, exec_command): amps = [data_models.Amphora(id=MOCK_AMP_ID, compute_id=MOCK_COMPUTE_ID, lb_network_ip=MOCK_IP_ADDRESS)] vip = data_models.Vip(ip_address=MOCK_IP_ADDRESS) lb = data_models.LoadBalancer(amphorae=amps, vip=vip) vip_subnet = network_models.Subnet(id=MOCK_SUBNET_ID, gateway_ip=MOCK_IP_ADDRESS, cidr=MOCK_CIDR) vip_port = network_models.Port(id=MOCK_PORT_ID, device_id=MOCK_COMPUTE_ID) amphorae_net_config = {amps[0].id: network_models.AmphoraNetworkConfig( amphora=amps[0], vip_subnet=vip_subnet, vip_port=vip_port, vrrp_port=self.port )} iface = 'eth1' exec_command.return_value = ('{0}: '.format(iface), '') self.driver.post_vip_plug(lb, amphorae_net_config) grep_call = mock.call( ssh_driver.CMD_GREP_LINK_BY_MAC.format(mac_address='123')) dhclient_call = mock.call(ssh_driver.CMD_DHCLIENT.format(iface), run_as_root=True) add_ip_call = mock.call(ssh_driver.CMD_ADD_IP_ADDR.format( MOCK_IP_ADDRESS, iface), run_as_root=True) show_ip_call = mock.call(ssh_driver.CMD_SHOW_IP_ADDR.format(iface)) create_vip_table_call = mock.call( ssh_driver.CMD_CREATE_VIP_ROUTE_TABLE.format( ssh_driver.VIP_ROUTE_TABLE), run_as_root=True ) add_route_call = mock.call( ssh_driver.CMD_ADD_ROUTE_TO_TABLE.format( MOCK_CIDR, iface, ssh_driver.VIP_ROUTE_TABLE), run_as_root=True ) add_default_route_call = mock.call( ssh_driver.CMD_ADD_DEFAULT_ROUTE_TO_TABLE.format( MOCK_IP_ADDRESS, iface, ssh_driver.VIP_ROUTE_TABLE), run_as_root=True ) add_rule_from_call = mock.call( ssh_driver.CMD_ADD_RULE_FROM_NET_TO_TABLE.format( MOCK_CIDR, ssh_driver.VIP_ROUTE_TABLE), run_as_root=True ) add_rule_to_call = mock.call( ssh_driver.CMD_ADD_RULE_TO_NET_TO_TABLE.format( MOCK_CIDR, ssh_driver.VIP_ROUTE_TABLE), run_as_root=True ) exec_command.assert_has_calls([grep_call, dhclient_call, add_ip_call, show_ip_call, create_vip_table_call, add_route_call, add_default_route_call, add_rule_from_call, add_rule_to_call]) self.assertEqual(9, exec_command.call_count)
def generate_vip(load_balancer=None): global VIP_SEED VIP_SEED += 1 vip = data_models.Vip(ip_address='10.0.0.{0}'.format(VIP_SEED), subnet_id=ut_constants.MOCK_VIP_SUBNET_ID, port_id='vrrp-port-{0}'.format(VIP_SEED), load_balancer=load_balancer) if load_balancer: vip.load_balancer_id = load_balancer.id return vip
def generate_vip(load_balancer=None): global VIP_SEED VIP_SEED += 1 vip = data_models.Vip(ip_address='10.0.0.{0}'.format(VIP_SEED), subnet_id='subnet{0}-id'.format(VIP_SEED), port_id='port{0}-id'.format(VIP_SEED), load_balancer=load_balancer) if load_balancer: vip.load_balancer_id = load_balancer.id return vip
def test_deallocate_vip_when_vip_port_not_found(self): vip = data_models.Vip(port_id='1') admin_tenant_id = 'octavia' session_mock = mock.MagicMock() session_mock.get_project_id.return_value = admin_tenant_id self.k_session.return_value = session_mock show_port = self.driver.neutron_client.show_port show_port.side_effect = neutron_exceptions.PortNotFoundClient self.assertRaises(network_base.VIPConfigurationNotFound, self.driver.deallocate_vip, vip)
def test_deallocate_vip_when_port_not_found_for_update(self): lb = dmh.generate_load_balancer_tree() vip = data_models.Vip(port_id='1') vip.load_balancer = lb show_port = self.driver.neutron_client.show_port show_port.return_value = {'port': { 'device_owner': allowed_address_pairs.OCTAVIA_OWNER}} update_port = self.driver.neutron_client.update_port update_port.side_effect = neutron_exceptions.PortNotFoundClient self.driver.deallocate_vip(vip)
def _port_to_vip(self, port, load_balancer): fixed_ip = None for port_fixed_ip in port.fixed_ips: if port_fixed_ip.subnet_id == load_balancer.vip.subnet_id: fixed_ip = port_fixed_ip break return data_models.Vip(ip_address=fixed_ip.ip_address, subnet_id=fixed_ip.subnet_id, port_id=port.id, load_balancer_id=load_balancer.id)
def test_deallocate_vip_when_vip_port_not_found(self): lb = dmh.generate_load_balancer_tree() vip = data_models.Vip(port_id='1') vip.load_balancer = lb admin_project_id = 'octavia' session_mock = mock.MagicMock() session_mock.get_project_id.return_value = admin_project_id self.k_session.return_value = session_mock show_port = self.driver.neutron_client.show_port show_port.side_effect = neutron_exceptions.PortNotFoundClient self.driver.deallocate_vip(vip)
def test_update_vip_for_delete(self, mock_get_session, mock_get_lb, mock_get_net_driver): mock_driver = mock.MagicMock() mock_get_net_driver.return_value = mock_driver vip = o_data_models.Vip() lb = o_data_models.LoadBalancer(vip=vip) mock_get_lb.return_value = lb listener = {constants.LOADBALANCER_ID: lb.id} net_task = network_tasks.UpdateVIPForDelete() net_task.execute(listener) mock_driver.update_vip.assert_called_once_with(lb, for_delete=True)
def test_deallocate_vip_when_delete_port_fails(self): lb = dmh.generate_load_balancer_tree() vip = data_models.Vip(port_id='1') vip.load_balancer = lb show_port = self.driver.neutron_client.show_port show_port.return_value = {'port': { 'device_owner': allowed_address_pairs.OCTAVIA_OWNER}} delete_port = self.driver.neutron_client.delete_port delete_port.side_effect = [None, None, TypeError] self.assertRaises(network_base.DeallocateVIPException, self.driver.deallocate_vip, vip)
def test_lb_dict_to_provider_dict(self, mock_load_cert): cert1 = data_models.TLSContainer(certificate='cert 1') cert2 = data_models.TLSContainer(certificate='cert 2') cert3 = data_models.TLSContainer(certificate='cert 3') mock_load_cert.return_value = { 'tls_cert': cert1, 'sni_certs': [cert2, cert3] } test_lb_dict = { 'name': 'lb1', 'project_id': self.sample_data.project_id, 'vip_subnet_id': self.sample_data.subnet_id, 'vip_port_id': self.sample_data.port_id, 'vip_address': self.sample_data.ip_address, 'vip_network_id': self.sample_data.network_id, 'vip_qos_policy_id': self.sample_data.qos_policy_id, 'id': self.sample_data.lb_id, 'listeners': [], 'pools': [], 'description': '', 'admin_state_up': True, 'provisioning_status': constants.PENDING_CREATE, 'operating_status': constants.OFFLINE, 'flavor_id': '', 'provider': 'noop_driver' } ref_prov_lb_dict = { 'vip_address': self.sample_data.ip_address, 'admin_state_up': True, 'loadbalancer_id': self.sample_data.lb_id, 'vip_subnet_id': self.sample_data.subnet_id, 'listeners': self.sample_data.provider_listeners, 'description': '', 'project_id': self.sample_data.project_id, 'flavor_id': '', 'vip_port_id': self.sample_data.port_id, 'vip_qos_policy_id': self.sample_data.qos_policy_id, 'vip_network_id': self.sample_data.network_id, 'pools': self.sample_data.provider_pools, 'name': 'lb1' } vip = data_models.Vip(ip_address=self.sample_data.ip_address, network_id=self.sample_data.network_id, port_id=self.sample_data.port_id, subnet_id=self.sample_data.subnet_id, qos_policy_id=self.sample_data.qos_policy_id) provider_lb_dict = utils.lb_dict_to_provider_dict( test_lb_dict, vip=vip, db_pools=self.sample_data.test_db_pools, db_listeners=self.sample_data.test_db_listeners) self.assertEqual(ref_prov_lb_dict, provider_lb_dict)
def test_update_vip_during_update_loadbalancer(self, mock_vip): vip_object = o_data_models.Vip() lb_object = o_data_models.LoadBalancer(vip=vip_object) update_attr = model_tasks.UpdateAttributes() update_attr.execute(lb_object, { 'vip': { 'fool1': 'bar1' }, 'description': 'bar2' }) mock_vip.assert_called_once_with({'fool1': 'bar1'})
def _port_to_vip(self, port, load_balancer, octavia_owned=False): fixed_ip = None for port_fixed_ip in port.fixed_ips: if port_fixed_ip.subnet_id == load_balancer.vip.subnet_id: fixed_ip = port_fixed_ip break if fixed_ip: return data_models.Vip(ip_address=fixed_ip.ip_address, subnet_id=fixed_ip.subnet_id, network_id=port.network_id, port_id=port.id, load_balancer=load_balancer, load_balancer_id=load_balancer.id, octavia_owned=octavia_owned) return data_models.Vip(ip_address=None, subnet_id=None, network_id=port.network_id, port_id=port.id, load_balancer=load_balancer, load_balancer_id=load_balancer.id, octavia_owned=octavia_owned)
def test_update_vip(self): listeners = [data_models.Listener(protocol_port=80, peer_port=1024), data_models.Listener(protocol_port=443, peer_port=1025)] vip = data_models.Vip(ip_address='10.0.0.2') lb = data_models.LoadBalancer(id='1', listeners=listeners, vip=vip) list_sec_grps = self.driver.neutron_client.list_security_groups list_sec_grps.return_value = {'security_groups': [{'id': 'secgrp-1'}]} fake_rules = { 'security_group_rules': [ {'id': 'rule-80', 'port_range_max': 80, 'protocol': 'tcp'}, {'id': 'rule-22', 'port_range_max': 22, 'protocol': 'tcp'} ] } list_rules = self.driver.neutron_client.list_security_group_rules list_rules.return_value = fake_rules delete_rule = self.driver.neutron_client.delete_security_group_rule create_rule = self.driver.neutron_client.create_security_group_rule self.driver.update_vip(lb) delete_rule.assert_called_once_with('rule-22') expected_create_rule_1 = { 'security_group_rule': { 'security_group_id': 'secgrp-1', 'direction': 'ingress', 'protocol': 'TCP', 'port_range_min': 1024, 'port_range_max': 1024, 'ethertype': 'IPv4' } } expected_create_rule_2 = { 'security_group_rule': { 'security_group_id': 'secgrp-1', 'direction': 'ingress', 'protocol': 'TCP', 'port_range_min': 1025, 'port_range_max': 1025, 'ethertype': 'IPv4' } } expected_create_rule_3 = { 'security_group_rule': { 'security_group_id': 'secgrp-1', 'direction': 'ingress', 'protocol': 'TCP', 'port_range_min': 443, 'port_range_max': 443, 'ethertype': 'IPv4' } } create_rule.assert_has_calls([mock.call(expected_create_rule_1), mock.call(expected_create_rule_2), mock.call(expected_create_rule_3)])