~ubuntu-branches/ubuntu/vivid/neutron/vivid-updates

« back to all changes in this revision

Viewing changes to neutron/tests/unit/scheduler/test_l3_agent_scheduler.py

  • Committer: Package Import Robot
  • Author(s): Corey Bryant
  • Date: 2015-08-05 11:23:17 UTC
  • mfrom: (1.1.24)
  • Revision ID: package-import@ubuntu.com-20150805112317-kmarnngty241s3he
Tags: 1:2015.1.1-0ubuntu2
* Additional support for stable/kilo (LP: #1481008):
  - d/neutron-pluging-linuxbridge-agent.init.in: Ensure that the right
    binary is used for neutron-plugin-linuxbridge-agent (LP: #1453188).

Show diffs side-by-side

added added

removed removed

Lines of Context:
86
86
        pass
87
87
 
88
88
 
 
89
class FakePortDB(object):
 
90
    def __init__(self, port_list):
 
91
        self._port_list = port_list
 
92
 
 
93
    def _get_query_answer(self, port_list, filters):
 
94
        answers = []
 
95
        for port in port_list:
 
96
            matched = True
 
97
            for key, search_values in filters.items():
 
98
                port_value = port.get(key, None)
 
99
                if not port_value:
 
100
                    matched = False
 
101
                    break
 
102
 
 
103
                if isinstance(port_value, list):
 
104
                    sub_answers = self._get_query_answer(port_value,
 
105
                                                         search_values)
 
106
                    matched = len(sub_answers) > 0
 
107
                else:
 
108
                    matched = port_value in search_values
 
109
 
 
110
                if not matched:
 
111
                    break
 
112
 
 
113
            if matched:
 
114
                answers.append(port)
 
115
 
 
116
        return answers
 
117
 
 
118
    def get_port(self, context, port_id):
 
119
        for port in self._port_list:
 
120
            if port['id'] == port_id:
 
121
                if port['tenant_id'] == context.tenant_id or context.is_admin:
 
122
                    return port
 
123
                break
 
124
 
 
125
        return None
 
126
 
 
127
    def get_ports(self, context, filters=None):
 
128
        query_filters = dict()
 
129
        if filters:
 
130
            query_filters.update(filters)
 
131
 
 
132
        if not context.is_admin:
 
133
            query_filters['tenant_id'] = [context.tenant_id]
 
134
 
 
135
        result = self._get_query_answer(self._port_list, query_filters)
 
136
        return result
 
137
 
 
138
 
89
139
class L3SchedulerBaseTestCase(base.BaseTestCase):
90
140
 
91
141
    def setUp(self):
1074
1124
        }
1075
1125
        self._test_dvr_serviced_port_exists_on_subnet(port=vip_port)
1076
1126
 
 
1127
    def _create_port(self, port_name, tenant_id, host, subnet_id, ip_address,
 
1128
                     status='ACTIVE',
 
1129
                     device_owner='compute:nova'):
 
1130
        return {
 
1131
            'id': port_name + '-port-id',
 
1132
            'tenant_id': tenant_id,
 
1133
            'device_id': port_name,
 
1134
            'device_owner': device_owner,
 
1135
            'status': status,
 
1136
            'binding:host_id': host,
 
1137
            'fixed_ips': [
 
1138
                {
 
1139
                    'subnet_id': subnet_id,
 
1140
                    'ip_address': ip_address
 
1141
                }
 
1142
            ]
 
1143
        }
 
1144
 
 
1145
    def test_dvr_deletens_if_no_port_no_routers(self):
 
1146
        # Delete a vm port, the port subnet has no router interface.
 
1147
        vm_tenant_id = 'tenant-1'
 
1148
        my_context = q_context.Context('user-1', vm_tenant_id, is_admin=False)
 
1149
        vm_port_host = 'compute-node-1'
 
1150
 
 
1151
        vm_port = self._create_port(
 
1152
            'deleted-vm', vm_tenant_id, vm_port_host,
 
1153
            'shared-subnet', '10.10.10.3',
 
1154
            status='INACTIVE')
 
1155
 
 
1156
        vm_port_id = vm_port['id']
 
1157
        fakePortDB = FakePortDB([vm_port])
 
1158
 
 
1159
        with contextlib.nested(
 
1160
            mock.patch.object(my_context, 'elevated',
 
1161
                              return_value=self.adminContext),
 
1162
            mock.patch('neutron.plugins.ml2.db.'
 
1163
                       'get_port_binding_host', return_value=vm_port_host),
 
1164
            mock.patch('neutron.db.db_base_plugin_v2.NeutronDbPluginV2.'
 
1165
                       'get_ports', side_effect=fakePortDB.get_ports),
 
1166
            mock.patch('neutron.db.db_base_plugin_v2.NeutronDbPluginV2.'
 
1167
                       'get_port', return_value=vm_port)) as (
 
1168
                _, mock_get_port_binding_host, _, _):
 
1169
 
 
1170
            routers = self.dut.dvr_deletens_if_no_port(my_context, vm_port_id)
 
1171
            self.assertEqual([], routers)
 
1172
            mock_get_port_binding_host.assert_called_once_with(
 
1173
                self.adminContext.session, vm_port_id)
 
1174
 
 
1175
    def test_dvr_deletens_if_no_ports_no_removeable_routers(self):
 
1176
        # A VM port is deleted, but the router can't be unscheduled from the
 
1177
        # compute node because there is another VM port present.
 
1178
        vm_tenant_id = 'tenant-1'
 
1179
        my_context = q_context.Context('user-1', vm_tenant_id, is_admin=False)
 
1180
        shared_subnet_id = '80947d4a-fbc8-484b-9f92-623a6bfcf3e0',
 
1181
        vm_port_host = 'compute-node-1'
 
1182
 
 
1183
        dvr_port = self._create_port(
 
1184
            'dvr-router', 'admin-tenant', vm_port_host,
 
1185
            shared_subnet_id, '10.10.10.1',
 
1186
            device_owner=constants.DEVICE_OWNER_DVR_INTERFACE)
 
1187
 
 
1188
        deleted_vm_port = self._create_port(
 
1189
            'deleted-vm', vm_tenant_id, vm_port_host,
 
1190
            shared_subnet_id, '10.10.10.3',
 
1191
            status='INACTIVE')
 
1192
        deleted_vm_port_id = deleted_vm_port['id']
 
1193
 
 
1194
        running_vm_port = self._create_port(
 
1195
            'running-vn', 'tenant-2', vm_port_host,
 
1196
            shared_subnet_id, '10.10.10.33')
 
1197
 
 
1198
        fakePortDB = FakePortDB([running_vm_port, deleted_vm_port, dvr_port])
 
1199
 
 
1200
        vm_port_binding = {
 
1201
            'port_id': deleted_vm_port_id,
 
1202
            'host': vm_port_host
 
1203
        }
 
1204
 
 
1205
        with contextlib.nested(
 
1206
            mock.patch.object(my_context, 'elevated',
 
1207
                              return_value=self.adminContext),
 
1208
            mock.patch('neutron.plugins.ml2.db.get_port_binding_host',
 
1209
                       return_value=vm_port_host),
 
1210
            mock.patch('neutron.db.db_base_plugin_v2.NeutronDbPluginV2.'
 
1211
                       'get_port', side_effect=fakePortDB.get_port),
 
1212
            mock.patch('neutron.db.db_base_plugin_v2.NeutronDbPluginV2.'
 
1213
                       'get_ports', side_effect=fakePortDB.get_ports),
 
1214
            mock.patch('neutron.plugins.ml2.db.get_dvr_port_binding_by_host',
 
1215
                       return_value=vm_port_binding)) as (_,
 
1216
                mock_get_port_binding_host, _,
 
1217
                mock_get_ports,
 
1218
                mock_get_dvr_port_binding_by_host):
 
1219
 
 
1220
            routers = self.dut.dvr_deletens_if_no_port(
 
1221
                my_context, deleted_vm_port_id)
 
1222
            self.assertEqual([], routers)
 
1223
 
 
1224
            mock_get_port_binding_host.assert_called_once_with(
 
1225
                self.adminContext.session, deleted_vm_port_id)
 
1226
            self.assertTrue(mock_get_ports.called)
 
1227
            self.assertFalse(mock_get_dvr_port_binding_by_host.called)
 
1228
 
 
1229
    def _test_dvr_deletens_if_no_ports_delete_routers(self,
 
1230
                                                      vm_tenant,
 
1231
                                                      router_tenant):
 
1232
        class FakeAgent(object):
 
1233
            def __init__(self, id, host, agent_type):
 
1234
                self.id = id
 
1235
                self.host = host
 
1236
                self.agent_type = agent_type
 
1237
 
 
1238
        my_context = q_context.Context('user-1', vm_tenant, is_admin=False)
 
1239
        shared_subnet_id = '80947d4a-fbc8-484b-9f92-623a6bfcf3e0',
 
1240
        vm_port_host = 'compute-node-1'
 
1241
 
 
1242
        router_id = 'dvr-router'
 
1243
        dvr_port = self._create_port(
 
1244
            router_id, router_tenant, vm_port_host,
 
1245
            shared_subnet_id, '10.10.10.1',
 
1246
            device_owner=constants.DEVICE_OWNER_DVR_INTERFACE)
 
1247
        dvr_port_id = dvr_port['id']
 
1248
 
 
1249
        deleted_vm_port = self._create_port(
 
1250
            'deleted-vm', vm_tenant, vm_port_host,
 
1251
            shared_subnet_id, '10.10.10.3',
 
1252
            status='INACTIVE')
 
1253
        deleted_vm_port_id = deleted_vm_port['id']
 
1254
 
 
1255
        running_vm_port = self._create_port(
 
1256
             'running-vn', vm_tenant, 'compute-node-2',
 
1257
             shared_subnet_id, '10.10.10.33')
 
1258
 
 
1259
        fakePortDB = FakePortDB([running_vm_port, dvr_port, deleted_vm_port])
 
1260
 
 
1261
        dvr_port_binding = {
 
1262
            'port_id': dvr_port_id, 'host': vm_port_host
 
1263
        }
 
1264
 
 
1265
        agent_id = 'l3-agent-on-compute-node-1'
 
1266
        l3_agent_on_vm_host = FakeAgent(agent_id,
 
1267
                                        vm_port_host,
 
1268
                                        constants.AGENT_TYPE_L3)
 
1269
 
 
1270
        with contextlib.nested(
 
1271
            mock.patch.object(my_context, 'elevated',
 
1272
                              return_value=self.adminContext),
 
1273
            mock.patch('neutron.plugins.ml2.db.get_port_binding_host',
 
1274
                       return_value=vm_port_host),
 
1275
            mock.patch('neutron.db.db_base_plugin_v2.NeutronDbPluginV2.'
 
1276
                       'get_port', side_effect=fakePortDB.get_port),
 
1277
            mock.patch('neutron.db.db_base_plugin_v2.NeutronDbPluginV2.'
 
1278
                       'get_ports', side_effect=fakePortDB.get_ports),
 
1279
            mock.patch('neutron.plugins.ml2.db.get_dvr_port_binding_by_host',
 
1280
                       return_value=dvr_port_binding),
 
1281
            mock.patch('neutron.db.agents_db.AgentDbMixin.'
 
1282
                       '_get_agent_by_type_and_host',
 
1283
                       return_value=l3_agent_on_vm_host)) as (_,
 
1284
                mock_get_port_binding_host, _,
 
1285
                mock_get_ports,
 
1286
                mock_get_dvr_port_binding_by_host,
 
1287
                mock__get_agent_by_type_and_host):
 
1288
 
 
1289
            routers = self.dut.dvr_deletens_if_no_port(
 
1290
                my_context, deleted_vm_port_id)
 
1291
 
 
1292
            expected_router = {
 
1293
                'router_id': router_id,
 
1294
                'host': vm_port_host,
 
1295
                'agent_id': agent_id
 
1296
            }
 
1297
            self.assertEqual([expected_router], routers)
 
1298
 
 
1299
            mock_get_port_binding_host.assert_called_once_with(
 
1300
                self.adminContext.session, deleted_vm_port_id)
 
1301
            self.assertTrue(mock_get_ports.called)
 
1302
            mock_get_dvr_port_binding_by_host.assert_called_once_with(
 
1303
                my_context.session, dvr_port_id, vm_port_host)
 
1304
 
 
1305
    def test_dvr_deletens_if_no_ports_delete_admin_routers(self):
 
1306
        # test to see whether the last VM using a router created
 
1307
        # by the admin will be unscheduled on the compute node
 
1308
        self._test_dvr_deletens_if_no_ports_delete_routers(
 
1309
            'tenant-1', 'admin-tenant')
 
1310
 
 
1311
    def test_dvr_deletens_if_no_ports_delete_tenant_routers(self):
 
1312
        # test to see whether the last VM using a tenant's private
 
1313
        # router will be unscheduled on the compute node
 
1314
        self._test_dvr_deletens_if_no_ports_delete_routers(
 
1315
            'tenant-1', 'tenant-1')
 
1316
 
1077
1317
    def test_dvr_serviced_dhcp_port_exists_on_subnet(self):
1078
1318
        dhcp_port = {
1079
1319
                'id': 'dhcp-port1',