def test_list_resources_with_long_filters(self): # In this tests, port_list is called with id=[10 port ID] # filter. It generates about 40*10 char length URI. # Each port ID is converted to "id=<UUID>&" in URI and # it means 40 chars (len(UUID)=36). # If excess length is 220, it means 400-220=180 chars # can be sent in the first request. # As a result three API calls with 4, 4, 2 port ID # are expected. ports = [{ 'id': str(uuid.uuid4()), 'name': 'port%s' % i, 'admin_state_up': True } for i in range(10)] port_ids = [port['id'] for port in ports] neutronclient = self.stub_neutronclient() uri_len_exc = neutron_exc.RequestURITooLong(excess=220) neutronclient.list_ports(id=port_ids).AndRaise(uri_len_exc) for i in range(0, 10, 4): neutronclient.list_ports(id=port_ids[i:i + 4]) \ .AndReturn({'ports': ports[i:i + 4]}) self.mox.ReplayAll() ret_val = api.neutron.list_resources_with_long_filters( api.neutron.port_list, 'id', port_ids, request=self.request) self.assertEqual(10, len(ret_val)) self.assertEqual(port_ids, [p.id for p in ret_val])
def test_extend_list_exceed_max_uri_len(self): data = [{ 'name': 'default', 'security_group_id': 'secgroupid%02d' % i, 'remote_group_id': 'remgroupid%02d' % i } for i in range(10)] data.append({ 'name': 'default', 'security_group_id': 'secgroupid10', 'remote_group_id': None }) resources = "security_groups" cmd = securitygroup.ListSecurityGroupRule(test_cli20.MyApp(sys.stdout), None) path = getattr(self.client, resources + '_path') responses = self._build_test_data(data, excess=1) known_args, _vs = cmd.get_parser('list' + resources).parse_known_args() mock_request_side_effects = [] mock_request_calls = [] mock_check_uri_side_effects = [exceptions.RequestURITooLong(excess=1)] mock_check_uri_calls = [mock.call(mock.ANY)] for item in responses: mock_request_side_effects.append(item['response']) mock_request_calls.append( mock.call(test_cli20.MyUrlComparator( test_cli20.end_url(path, item['filter']), self.client), 'GET', body=None, headers=test_cli20.ContainsKeyValue( {'X-Auth-Token': test_cli20.TOKEN}))) mock_check_uri_side_effects.append(None) mock_check_uri_calls.append(mock.call(mock.ANY)) with mock.patch.object(cmd, "get_client", return_value=self.client) as mock_get_client, \ mock.patch.object(self.client.httpclient, "request") as mock_request, \ mock.patch.object(self.client.httpclient, "_check_uri_length") as mock_check_uri: mock_request.side_effect = mock_request_side_effects mock_check_uri.side_effect = mock_check_uri_side_effects cmd.extend_list(data, known_args) mock_get_client.assert_called_once_with() mock_request.assert_has_calls(mock_request_calls) mock_check_uri.assert_has_calls(mock_check_uri_calls) self.assertEqual(len(mock_request_calls), mock_request.call_count) self.assertEqual(len(mock_check_uri_calls), mock_check_uri.call_count)
def mox_calls(path, data): # 1 char of extra URI len will cause a split in 2 requests self.mox.StubOutWithMock(self.client, '_check_uri_length') self.client._check_uri_length(mox.IgnoreArg()).AndRaise( exceptions.RequestURITooLong(excess=1)) responses = self._build_test_data(data, excess=1) for item in responses: self.client._check_uri_length(mox.IgnoreArg()).AndReturn(None) self.client.httpclient.request( test_cli20.end_url(path, item['filter']), 'GET', body=None, headers=mox.ContainsKeyValue('X-Auth-Token', test_cli20.TOKEN)).AndReturn( item['response'])
def test_extend_list_exceed_max_uri_len(self): data = [{ 'id': 'netid%d' % i, 'name': 'net%d' % i, 'subnets': ['mysubid%d' % i] } for i in range(10)] # Since in pagination we add &marker=<uuid> (44 symbols), total change # is 45 symbols. Single subnet takes 40 symbols (id=<uuid>&). # Because of it marker will take more space than single subnet filter, # and we expect neutron to send last 2 subnets in separate response. filters1, response1 = self._build_test_data(data[:len(data) - 2]) filters2, response2 = self._build_test_data(data[len(data) - 2:]) path = getattr(self.client, 'subnets_path') cmd = network.ListNetwork(test_cli20.MyApp(sys.stdout), None) with mock.patch.object(cmd, "get_client", return_value=self.client) as mock_get_client, \ mock.patch.object(self.client.httpclient, "request") as mock_request, \ mock.patch.object(self.client.httpclient, "_check_uri_length", return_value=None) as mock_check_uri_length: # 1 char of extra URI len will cause a split in 2 requests mock_check_uri_length.side_effect = [ exceptions.RequestURITooLong(excess=1), None, None ] mock_request.side_effect = [response1, response2] known_args, _vs = cmd.get_parser('create_subnets')\ .parse_known_args() cmd.extend_list(data, known_args) mock_get_client.assert_called_once_with() self.assertEqual(2, mock_request.call_count) mock_request.assert_has_calls([ mock.call(test_cli20.MyUrlComparator( test_cli20.end_url(path, 'fields=id&fields=cidr%s' % filters1), self.client), 'GET', body=None, headers=test_cli20.ContainsKeyValue( {'X-Auth-Token': test_cli20.TOKEN})), mock.call(test_cli20.MyUrlComparator( test_cli20.end_url(path, 'fields=id&fields=cidr%s' % filters2), self.client), 'GET', body=None, headers=test_cli20.ContainsKeyValue( {'X-Auth-Token': test_cli20.TOKEN})) ])
def mox_calls(path, data): sub_data_lists = [data[:len(data) - 1], data[len(data) - 1:]] filters, response = self._build_test_data(data) # 1 char of extra URI len will cause a split in 2 requests self.mox.StubOutWithMock(self.client, "_check_uri_length") self.client._check_uri_length(mox.IgnoreArg()).AndRaise( exceptions.RequestURITooLong(excess=1)) for data in sub_data_lists: filters, response = self._build_test_data(data) self.client._check_uri_length(mox.IgnoreArg()).AndReturn(None) self.client.httpclient.request( test_cli20.end_url(path, 'fields=id&fields=cidr%s' % filters), 'GET', body=None, headers=mox.ContainsKeyValue( 'X-Auth-Token', test_cli20.TOKEN)).AndReturn(response)
def test_extend_list_exceed_max_uri_len(self): data = [{ 'id': 'netid%d' % i, 'name': 'net%d' % i, 'subnets': ['mysubid%d' % i] } for i in range(10)] filters1, response1 = self._build_test_data(data[:len(data) - 1]) filters2, response2 = self._build_test_data(data[len(data) - 1:]) path = getattr(self.client, 'subnets_path') cmd = network.ListNetwork(test_cli20.MyApp(sys.stdout), None) with mock.patch.object(cmd, "get_client", return_value=self.client) as mock_get_client, \ mock.patch.object(self.client.httpclient, "request") as mock_request, \ mock.patch.object(self.client.httpclient, "_check_uri_length", return_value=None) as mock_check_uri_length: # 1 char of extra URI len will cause a split in 2 requests mock_check_uri_length.side_effect = [ exceptions.RequestURITooLong(excess=1), None, None ] mock_request.side_effect = [response1, response2] known_args, _vs = cmd.get_parser('create_subnets')\ .parse_known_args() cmd.extend_list(data, known_args) mock_get_client.assert_called_once_with() self.assertEqual(2, mock_request.call_count) mock_request.assert_has_calls([ mock.call(test_cli20.MyUrlComparator( test_cli20.end_url(path, 'fields=id&fields=cidr%s' % filters1), self.client), 'GET', body=None, headers=test_cli20.ContainsKeyValue( {'X-Auth-Token': test_cli20.TOKEN})), mock.call(test_cli20.MyUrlComparator( test_cli20.end_url(path, 'fields=id&fields=cidr%s' % filters2), self.client), 'GET', body=None, headers=test_cli20.ContainsKeyValue( {'X-Auth-Token': test_cli20.TOKEN})) ])
def _check_uri_length(self, action): uri_len = len(self.httpclient.endpoint_url) + len(action) if uri_len > self.MAX_URI_LEN: raise exceptions.RequestURITooLong(excess=uri_len - self.MAX_URI_LEN)
def _check_uri_length(self, url): uri_len = len(self.endpoint_url) + len(url) if uri_len > MAX_URI_LEN: raise exceptions.RequestURITooLong(excess=uri_len - MAX_URI_LEN)