From 9fe79a4aacfd47be6a1d92097c1d84ccd6763073 Mon Sep 17 00:00:00 2001
From: Feng Liu <mefengliu23@gmail.com>
Date: Thu, 17 Oct 2013 11:12:06 +0800
Subject: [PATCH] Add close to swiftclient.client.Connection

Change-Id: I2f5fa9c46886607a9ba99e8915ea84ac4975d004
---
 swiftclient/client.py     |  8 ++++++++
 tests/test_swiftclient.py | 25 +++++++++++++++++++++++++
 tests/utils.py            | 16 ++++++++++++++--
 3 files changed, 47 insertions(+), 2 deletions(-)

diff --git a/swiftclient/client.py b/swiftclient/client.py
index 3bbbc54f..155c8cba 100644
--- a/swiftclient/client.py
+++ b/swiftclient/client.py
@@ -1072,6 +1072,14 @@ class Connection(object):
         self.insecure = insecure
         self.ssl_compression = ssl_compression
 
+    def close(self):
+        if self.http_conn and type(self.http_conn) is tuple\
+                and len(self.http_conn) > 1:
+            conn = self.http_conn[1]
+            if hasattr(conn, 'close') and callable(conn.close):
+                conn.close()
+                self.http_conn = None
+
     def get_auth(self):
         return get_auth(self.authurl, self.user, self.key,
                         snet=self.snet,
diff --git a/tests/test_swiftclient.py b/tests/test_swiftclient.py
index e827a2a9..9fc13a2b 100644
--- a/tests/test_swiftclient.py
+++ b/tests/test_swiftclient.py
@@ -938,5 +938,30 @@ class TestLogging(MockHttpTest):
             http_conn=conn, headers=headers)
 
 
+class TestCloseConnection(MockHttpTest):
+
+    def test_close_none(self):
+        c.http_connection = self.fake_http_connection(200)
+        conn = c.Connection('http://www.test.com', 'asdf', 'asdf')
+        self.assertEqual(conn.http_conn, None)
+        conn.close()
+        self.assertEqual(conn.http_conn, None)
+
+    def test_close_ok(self):
+        url = 'http://www.test.com'
+        c.http_connection = self.fake_http_connection(200)
+        conn = c.Connection(url, 'asdf', 'asdf')
+        self.assertEqual(conn.http_conn, None)
+
+        conn.http_conn = c.http_connection(url)
+        self.assertEqual(type(conn.http_conn), tuple)
+        self.assertEqual(len(conn.http_conn), 2)
+        http_conn_obj = conn.http_conn[1]
+        self.assertEqual(http_conn_obj.isclosed(), False)
+        conn.close()
+        self.assertEqual(http_conn_obj.isclosed(), True)
+        self.assertEqual(conn.http_conn, None)
+
+
 if __name__ == '__main__':
     testtools.main()
diff --git a/tests/utils.py b/tests/utils.py
index 07776b1e..93972e41 100644
--- a/tests/utils.py
+++ b/tests/utils.py
@@ -56,6 +56,16 @@ def fake_http_connect(*code_iter, **kwargs):
             self.etag = etag
             self.body = body
             self.timestamp = timestamp
+            self._is_closed = True
+
+        def connect(self):
+            self._is_closed = False
+
+        def close(self):
+            self._is_closed = True
+
+        def isclosed(self):
+            return self._is_closed
 
         def getresponse(self):
             if kwargs.get('raise_exc'):
@@ -132,7 +142,9 @@ def fake_http_connect(*code_iter, **kwargs):
         timestamp = timestamps_iter.next()
         if status <= 0:
             raise HTTPException()
-        return FakeConn(status, etag, body=kwargs.get('body', ''),
-                        timestamp=timestamp)
+        fake_conn = FakeConn(status, etag, body=kwargs.get('body', ''),
+                             timestamp=timestamp)
+        fake_conn.connect()
+        return fake_conn
 
     return connect