1414# limitations under the License.
1515
1616import os
17+ import json
1718import random
1819import unittest
1920
2021import requests
2122import requests_mock
23+ from requests .structures import CaseInsensitiveDict
2224
2325from libcloud .http import LibcloudConnection
2426from libcloud .utils .py3 import PY2 , httplib , parse_qs , urlparse , urlquote , parse_qsl
@@ -87,6 +89,23 @@ def read(self, chunk_size=None):
8789 return StringIO .read (self )
8890
8991
92+ class MockRequest :
93+ def __init__ (self , method , url , query , body , headers ):
94+ self .method = method
95+ self .url = url
96+ self .query = parse_qs (query )
97+ self .headers = CaseInsensitiveDict (headers )
98+ self .body = body
99+
100+ @property
101+ def json (self ):
102+ return json .loads (self .body )
103+
104+ @property
105+ def json (self ):
106+ return json .loads (self .body )
107+
108+
90109class MockHttp (LibcloudConnection , unittest .TestCase ):
91110 """
92111 A mock HTTP client/server suitable for testing purposes. This replaces
@@ -102,6 +121,8 @@ class MockHttp(LibcloudConnection, unittest.TestCase):
102121 use_param = None # will use this param to namespace the request function
103122 test = None # TestCase instance which is using this mock
104123 proxy_url = None
124+ keep_history = False
125+ history = []
105126
106127 def __init__ (self , * args , ** kwargs ):
107128 # Load assertion methods into the class, in case people want to assert
@@ -118,6 +139,10 @@ def _get_request(self, method, url, body=None, headers=None):
118139 # Find a method we can use for this request
119140 parsed = urlparse .urlparse (url )
120141 _ , _ , path , _ , query , _ = parsed
142+
143+ if self .keep_history :
144+ self .history .append (MockRequest (method , path , query , body , headers ))
145+
121146 qs = parse_qs (query )
122147 if path .endswith ("/" ):
123148 path = path [:- 1 ]
0 commit comments