close http connections
Running full tempest one might run out of file descriptors. httplib2
does not close the connection by default. This patch adds
connection:close header to every request, so that sockets won't be
hanging around.
fixes bug 1215804
Change-Id: Iea19936c45add98fc66588f623854e629cf448fb
diff --git a/tempest/common/http.py b/tempest/common/http.py
new file mode 100644
index 0000000..49dca18
--- /dev/null
+++ b/tempest/common/http.py
@@ -0,0 +1,27 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 OpenStack, LLC
+# Copyright 2013 Citrix Systems, Inc.
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import httplib2
+
+
+class ClosingHttp(httplib2.Http):
+ def request(self, *args, **kwargs):
+ original_headers = kwargs.get('headers', {})
+ new_headers = dict(original_headers, connection='close')
+ new_kwargs = dict(kwargs, headers=new_headers)
+ return super(ClosingHttp, self).request(*args, **new_kwargs)
diff --git a/tempest/common/rest_client.py b/tempest/common/rest_client.py
index ea5b4f4..d744e3d 100644
--- a/tempest/common/rest_client.py
+++ b/tempest/common/rest_client.py
@@ -18,12 +18,12 @@
import collections
import hashlib
-import httplib2
import json
from lxml import etree
import re
import time
+from tempest.common import http
from tempest import exceptions
from tempest.openstack.common import log as logging
from tempest.services.compute.xml.common import xml_to_json
@@ -64,7 +64,8 @@
'retry-after', 'server',
'vary', 'www-authenticate'))
dscv = self.config.identity.disable_ssl_certificate_validation
- self.http_obj = httplib2.Http(disable_ssl_certificate_validation=dscv)
+ self.http_obj = http.ClosingHttp(
+ disable_ssl_certificate_validation=dscv)
def _set_auth(self):
"""
diff --git a/tempest/services/identity/json/identity_client.py b/tempest/services/identity/json/identity_client.py
index 90e64e7..47977df 100644
--- a/tempest/services/identity/json/identity_client.py
+++ b/tempest/services/identity/json/identity_client.py
@@ -12,9 +12,9 @@
# License for the specific language governing permissions and limitations
# under the License.
-import httplib2
import json
+from tempest.common import http
from tempest.common.rest_client import RestClient
from tempest import exceptions
@@ -260,7 +260,8 @@
def request(self, method, url, headers=None, body=None):
"""A simple HTTP request interface."""
dscv = self.config.identity.disable_ssl_certificate_validation
- self.http_obj = httplib2.Http(disable_ssl_certificate_validation=dscv)
+ self.http_obj = http.ClosingHttp(
+ disable_ssl_certificate_validation=dscv)
if headers is None:
headers = {}
diff --git a/tempest/services/identity/v3/xml/endpoints_client.py b/tempest/services/identity/v3/xml/endpoints_client.py
index f81fccf..e211cee 100644
--- a/tempest/services/identity/v3/xml/endpoints_client.py
+++ b/tempest/services/identity/v3/xml/endpoints_client.py
@@ -16,9 +16,9 @@
# under the License.
import urlparse
-import httplib2
from lxml import etree
+from tempest.common import http
from tempest.common.rest_client import RestClientXML
from tempest.services.compute.xml.common import Document
from tempest.services.compute.xml.common import Element
@@ -50,7 +50,8 @@
def request(self, method, url, headers=None, body=None, wait=None):
"""Overriding the existing HTTP request in super class RestClient."""
dscv = self.config.identity.disable_ssl_certificate_validation
- self.http_obj = httplib2.Http(disable_ssl_certificate_validation=dscv)
+ self.http_obj = http.ClosingHttp(
+ disable_ssl_certificate_validation=dscv)
self._set_auth()
self.base_url = self.base_url.replace(
urlparse.urlparse(self.base_url).path, "/v3")
diff --git a/tempest/services/identity/v3/xml/policy_client.py b/tempest/services/identity/v3/xml/policy_client.py
index c3f6d99..0f07728 100644
--- a/tempest/services/identity/v3/xml/policy_client.py
+++ b/tempest/services/identity/v3/xml/policy_client.py
@@ -17,9 +17,9 @@
from urlparse import urlparse
-import httplib2
from lxml import etree
+from tempest.common import http
from tempest.common.rest_client import RestClientXML
from tempest.services.compute.xml.common import Document
from tempest.services.compute.xml.common import Element
@@ -51,7 +51,8 @@
def request(self, method, url, headers=None, body=None, wait=None):
"""Overriding the existing HTTP request in super class RestClient."""
dscv = self.config.identity.disable_ssl_certificate_validation
- self.http_obj = httplib2.Http(disable_ssl_certificate_validation=dscv)
+ self.http_obj = http.ClosingHttp(
+ disable_ssl_certificate_validation=dscv)
self._set_auth()
self.base_url = self.base_url.replace(urlparse(self.base_url).path,
"/v3")
diff --git a/tempest/services/identity/xml/identity_client.py b/tempest/services/identity/xml/identity_client.py
index 99a155a..7a00b84 100644
--- a/tempest/services/identity/xml/identity_client.py
+++ b/tempest/services/identity/xml/identity_client.py
@@ -15,11 +15,11 @@
# License for the specific language governing permissions and limitations
# under the License.
-import httplib2
import json
from lxml import etree
+from tempest.common import http
from tempest.common.rest_client import RestClientXML
from tempest import exceptions
from tempest.services.compute.xml.common import Document
@@ -275,7 +275,8 @@
def request(self, method, url, headers=None, body=None):
"""A simple HTTP request interface."""
dscv = self.config.identity.disable_ssl_certificate_validation
- self.http_obj = httplib2.Http(disable_ssl_certificate_validation=dscv)
+ self.http_obj = http.ClosingHttp(
+ disable_ssl_certificate_validation=dscv)
if headers is None:
headers = {}
self._log_request(method, url, headers, body)
diff --git a/tempest/services/object_storage/account_client.py b/tempest/services/object_storage/account_client.py
index 8defbbb..eb9910f 100644
--- a/tempest/services/object_storage/account_client.py
+++ b/tempest/services/object_storage/account_client.py
@@ -15,10 +15,10 @@
# License for the specific language governing permissions and limitations
# under the License.
-import httplib2
import json
import urllib
+from tempest.common import http
from tempest.common.rest_client import RestClient
from tempest import exceptions
@@ -108,7 +108,7 @@
def request(self, method, url, headers=None, body=None):
"""A simple HTTP request interface."""
- self.http_obj = httplib2.Http()
+ self.http_obj = http.ClosingHttp()
if headers is None:
headers = {}
if self.base_url is None:
diff --git a/tempest/services/object_storage/object_client.py b/tempest/services/object_storage/object_client.py
index 181838e..1c97869 100644
--- a/tempest/services/object_storage/object_client.py
+++ b/tempest/services/object_storage/object_client.py
@@ -17,9 +17,9 @@
import hashlib
import hmac
-import httplib2
import urlparse
+from tempest.common import http
from tempest.common.rest_client import RestClient
from tempest import exceptions
@@ -162,7 +162,8 @@
def request(self, method, url, headers=None, body=None):
"""A simple HTTP request interface."""
dscv = self.config.identity.disable_ssl_certificate_validation
- self.http_obj = httplib2.Http(disable_ssl_certificate_validation=dscv)
+ self.http_obj = http.ClosingHttp(
+ disable_ssl_certificate_validation=dscv)
if headers is None:
headers = {}
if self.base_url is None: