def make_cookies(*args, **kwargs): cookies = kwargs['cookies'] r = MagicMock() try: r.headers = HTTPMessage() add_header = r.headers.add_header except TypeError: # PY2 r.headers = HTTPMessage(StringIO()) add_header = r.headers.addheader r.info.return_value = r.headers for name, value in (('Foo', 'bar'), ('Baz', 'qux')): cookie = Cookie( version=0, name=name, value=value, port=None, port_specified=False, domain="ansible.com", domain_specified=True, domain_initial_dot=False, path="/", path_specified=True, secure=False, expires=None, discard=False, comment=None, comment_url=None, rest=None ) cookies.set_cookie(cookie) add_header('Set-Cookie', '%s=%s' % (name, value)) return r
def create_mock_response(url, response_type, **kwargs): response = MagicMock() response.request.url = url response.request.method = kwargs.get("method", "GET") response.request.headers = {} response.request.body = None if response_type == "redirect": response.status_code = 301 response.headers = {"location": kwargs["location"]} elif response_type == "error": response.status_code = kwargs.get("status_code", 500) response.reason = kwargs.get("reason", "fake reason") response.text = '{{"reason":"{}"}}'.format(kwargs.get("reason", "fake reason")) response.json = lambda: json.loads(response.text) elif response_type == "stream": response.status_code = kwargs.get("status_code", 200) response.headers = { "content-disposition": 'attachment; filename="fname.ext"', "content-type": "application/octet-stream", "content-length": len(response.text), } response.iter_content = lambda buffer_size: IterateContents( kwargs["contents"], kwargs["buffer_size"], kwargs.get("partial_start", 0), kwargs.get("partial_end", None) ) else: response.status_code = 200 response.text = kwargs["text"] response.json = lambda: json.loads(response.text) response.headers = {"content-type": "application/json", "content-length": len(response.text)} return response
def test_get_request_location_history(): """ Request location follows redirect history. """ url = "http://pypi.python.org/simple/foo" redirect = MagicMock() redirect.headers = {"location": "https://pypi.python.org/simple/foo"} response = MagicMock() response.history = [redirect] response.headers = {} eq_(get_request_location(response, url), "https://pypi.python.org/simple/foo")
def test_admin_token(self, cfg): req = MagicMock() req.headers = {'X-AUTH-TOKEN': 'ADMIN'} resp = MagicMock() cfg.CONF = {'DEFAULT': {'admin_token': 'ADMIN'}} admin_token(req, resp, {}) self.assertTrue(req.env['is_admin']) req.headers = {'X-AUTH-TOKEN': 'ABC'} req.env = {} admin_token(req, resp, {}) self.assertIsNone(req.env.get('is_admin'))
def test_parameter_validator(monkeypatch): request = MagicMock(name='request') request.args = {} request.headers = {} request.params = {} app = MagicMock(name='app') app.response_class = lambda a, mimetype, status: json.loads(''.join(a))['detail'] monkeypatch.setattr('flask.request', request) monkeypatch.setattr('flask.current_app', app) def orig_handler(*args, **kwargs): return 'OK' params = [{'name': 'p1', 'in': 'path', 'type': 'integer', 'required': True}, {'name': 'h1', 'in': 'header', 'type': 'string', 'enum': ['a', 'b']}, {'name': 'q1', 'in': 'query', 'type': 'integer', 'maximum': 3}, {'name': 'a1', 'in': 'query', 'type': 'array', 'minItems': 2, 'maxItems': 3, 'items': {'type': 'integer', 'minimum': 0}}] validator = ParameterValidator(params) handler = validator(orig_handler) assert handler() == "Missing path parameter 'p1'" assert handler(p1='123') == 'OK' assert handler(p1='') == "Wrong type, expected 'integer' for path parameter 'p1'" assert handler(p1='foo') == "Wrong type, expected 'integer' for path parameter 'p1'" assert handler(p1='1.2') == "Wrong type, expected 'integer' for path parameter 'p1'" request.args = {'q1': '4'} assert handler(p1=1).startswith('4 is greater than the maximum of 3') request.args = {'q1': '3'} assert handler(p1=1) == 'OK' request.args = {'a1': "1,2"} assert handler(p1=1) == "OK" request.args = {'a1': "1,a"} assert handler(p1=1).startswith("'a' is not of type 'integer'") request.args = {'a1': "1,-1"} assert handler(p1=1).startswith("-1 is less than the minimum of 0") request.args = {'a1': "1"} assert handler(p1=1).startswith("[1] is too short") request.args = {'a1': "1,2,3,4"} assert handler(p1=1).startswith("[1, 2, 3, 4] is too long") del request.args['a1'] request.headers = {'h1': 'a'} assert handler(p1='123') == 'OK' request.headers = {'h1': 'x'} assert handler(p1='123').startswith("'x' is not one of ['a', 'b']")
def set_up_test(test, content_type="application/json"): """A small function for setting up test cases.""" core.req = Mock() response = MagicMock() response.headers = {'content-type': content_type} core.req.get.return_value = response test.get = core.req.get
def test_handle_response(self): connection = Connection("store.mybigcommerce.com", ("user", "abcdef")) # A normal, 200-ok response data = {"name": "Shirt"} res = MagicMock() res.headers = {"Content-Type": "application/json"} res.status_code = 200 res.content = json.dumps(data) res.json.return_value = data self.assertEqual(connection._handle_response("products/1", res), data) res.status_code = 500 self.assertRaisesHttpException( ServerException, lambda: connection._handle_response("products/1", res), # Test all of the properties of a HttpException 500, {"Content-Type": "application/json"}, json.dumps(data), ) res.status_code = 404 self.assertRaisesHttpException( ClientRequestException, lambda: connection._handle_response("products/1", res), 404 ) res.status_code = 301 self.assertRaisesHttpException( RedirectionException, lambda: connection._handle_response("products/1", res), 301 )
def test_get_request_location_multiple_history(): """ Request location follows redirect history across multiple redirects. """ url = "http://pypi.python.org/simple/foo" redirect1 = MagicMock() redirect1.headers = {"location": "https://pypi.python.org/simple/foo"} redirect2 = MagicMock() redirect2.headers = {"location": "https://pypi.python.org/simple/foo/"} response = MagicMock() response.history = [redirect1, redirect2] response.headers = {} eq_(get_request_location(response, url), "https://pypi.python.org/simple/foo/")
def test_notification_rate_limit2(self, mock_retry, mock_summ, mock_delay, verify_signature_mock, debug_mock): """ Test that the notification task rate limit errors ok """ # Check that we fail gracefully when we hit the rate limit mock_delay.side_effect = lambda arg: process_notification(arg) resp = MagicMock() resp.headers = {'x-ratelimit-reset': 1404298869} exc = misfit_exceptions.MisfitRateLimitError(429, '', resp) mock_summ.side_effect = exc mock_retry.side_effect = Exception with HTTMock(JsonMock().goal_http, JsonMock().profile_http, JsonMock('summary_detail').summary_http): try: content = json.dumps(self.notification_content).encode('utf8') self.client.post(reverse('misfit-notification'), data=content, content_type='application/json') assert False, 'We should have raised an exception' except Exception: assert True mock_delay.assert_called_once_with(content) mock_summ.assert_called_once_with( detail=True, end_date=datetime.date(2014, 10, 8), start_date=datetime.date(2014, 10, 5)) mock_retry.assert_called_once_with(countdown=549) eq_(Goal.objects.filter(user=self.user).count(), 2) eq_(Profile.objects.filter(user=self.user).count(), 1) eq_(Summary.objects.filter(user=self.user).count(), 0)
def test_verify_oauth_scopes_remote(monkeypatch): tokeninfo = dict(uid="foo", scope="scope1 scope2") def get_tokeninfo_response(*args, **kwargs): tokeninfo_response = requests.Response() tokeninfo_response.status_code = requests.codes.ok tokeninfo_response._content = json.dumps(tokeninfo).encode() return tokeninfo_response def func(request): pass wrapped_func = verify_oauth_remote('https://example.org/tokeninfo', set(['admin']), func) request = MagicMock() request.headers = {"Authorization": "Bearer 123"} app = MagicMock() monkeypatch.setattr('flask.current_app', app) session = MagicMock() session.get = get_tokeninfo_response monkeypatch.setattr('connexion.decorators.security.session', session) with pytest.raises(OAuthScopeProblem, message="Provided token doesn't have the required scope"): wrapped_func(request) tokeninfo["scope"] += " admin" wrapped_func(request) tokeninfo["scope"] = ["foo", "bar"] with pytest.raises(OAuthScopeProblem, message="Provided token doesn't have the required scope"): wrapped_func(request) tokeninfo["scope"].append("admin") wrapped_func(request)
def _build_mock_request(method): status_values = { 'get': 200, 'put': 200, 'post': 201, 'delete': 204 } # Build response response = MagicMock() response.status_code = status_values[method] if method == 'get': response.headers = { 'content-type': 'application/rdf+xml' } response.text = 'value returned' def _mock_request(url, headers={}, data=''): # Check headers if 'Authorization' not in headers: response.status_code = 401 if method == 'get' and 'Accept' not in headers: response.status_code = 406 if (method == 'put' or method == 'post') and 'Content-Type' not in headers: response.status_code = 415 response.url = url return response return _mock_request
def test_verify_oauth_scopes_local(monkeypatch): tokeninfo = dict(uid="foo", scope="scope1 scope2") def func(request): pass def token_info(token): return tokeninfo wrapped_func = verify_oauth_local(token_info, set(['admin']), func) request = MagicMock() request.headers = {"Authorization": "Bearer 123"} app = MagicMock() monkeypatch.setattr('flask.current_app', app) with pytest.raises(OAuthScopeProblem, message="Provided token doesn't have the required scope"): wrapped_func(request) tokeninfo["scope"] += " admin" wrapped_func(request) tokeninfo["scope"] = ["foo", "bar"] with pytest.raises(OAuthScopeProblem, message="Provided token doesn't have the required scope"): wrapped_func(request) tokeninfo["scope"].append("admin") wrapped_func(request)
def test_getContextForCollectionMappings_contextRecieved(self, mock_get): mappingResponse = MagicMock(spec=Response) collection = ["Some Results"] mappingResponse.json.return_value = collection mappingResponse.status_code = 200 mappingResponse.headers = [] mock_get.return_value = mappingResponse collectionMappingsView = views.CollectionMappingsView() collectionMappingsView.request = FakeRequest() hash = {'collection': 'test', 'org': 'org1'} collectionMappingsView.kwargs = hash context = collectionMappingsView.get_context_data() self.assertEquals(context['url_params'], {}) self.assertEquals(context['kwargs'], hash) self.assertEquals(context['selected_tab'], 'Mappings') self.assertEquals(context['results'], collection) self.assertEquals(context['pagination_url'], '/foobar') self.assertEquals(context['search_query'], '') self.assertIsInstance(context['search_filters'], SearchFilterList) # TODO: Revise sort assertion to work with new sort option definitions # self.assertEquals(context['search_sort_options'], ['Best Match', 'Last Update (Desc)', 'Last Update (Asc)', 'Name (Asc)', 'Name (Desc)']) self.assertEquals(context['search_sort'], '') self.assertEquals(context['search_facets_json'], None)
def _mock_response(self, status_code=404, headers={}, content='PAGE_NOT_FOUND'): r = MagicMock(Response()) r.status_code = status_code r.headers = CaseInsensitiveDict(headers if headers is not None else {}) r.content = content r.ok = status_code < 400 return r
def test_handle_response(self): connection = Connection('store.mybigcommerce.com', ('user', 'abcdef')) # A normal, 200-ok response data = { 'name': 'Shirt' } res = MagicMock() res.headers = {'Content-Type': 'application/json'} res.status_code = 200 res.content = json.dumps(data) res.json.return_value = data self.assertEqual(connection._handle_response('products/1', res), data) res.status_code = 500 self.assertRaisesHttpException(ServerException, lambda: connection._handle_response('products/1', res), # Test all of the properties of a HttpException 500, {'Content-Type': 'application/json'}, json.dumps(data)) res.status_code = 404 self.assertRaisesHttpException(ClientRequestException, lambda: connection._handle_response('products/1', res), 404) res.status_code = 301 self.assertRaisesHttpException(RedirectionException, lambda: connection._handle_response('products/1', res), 301)
def test_verify_oauth_scopes_remote(monkeypatch): tokeninfo = dict(uid="foo", scope="scope1 scope2") def get_tokeninfo_response(*args, **kwargs): tokeninfo_response = requests.Response() tokeninfo_response.status_code = requests.codes.ok tokeninfo_response._content = json.dumps(tokeninfo).encode() return tokeninfo_response token_info_func = get_tokeninfo_func({'x-tokenInfoUrl': 'https://example.org/tokeninfo'}) wrapped_func = verify_oauth(token_info_func, validate_scope) request = MagicMock() request.headers = {"Authorization": "Bearer 123"} session = MagicMock() session.get = get_tokeninfo_response monkeypatch.setattr('connexion.decorators.security.session', session) with pytest.raises(OAuthScopeProblem, message="Provided token doesn't have the required scope"): wrapped_func(request, ['admin']) tokeninfo["scope"] += " admin" assert wrapped_func(request, ['admin']) is not None tokeninfo["scope"] = ["foo", "bar"] with pytest.raises(OAuthScopeProblem, message="Provided token doesn't have the required scope"): wrapped_func(request, ['admin']) tokeninfo["scope"].append("admin") assert wrapped_func(request, ['admin']) is not None
def TestCommandParsing(self): request = MagicMock() request.path = "/test" request.query = "item1=value1" request.remote_ip = "1.2.3.4" request.method = "PUT" request.headers = { 'User': '******', 'Creation-Time': 'test_time', 'User-Agent': 'test_user_agent' } request.body="item2=value2&item2=value3&item2=value4" self.command = Command(request) self.assertEqual(self.command.command_name, 'test') self.assertEqual(self.command.command_type, 'PUT') self.assertEqual(self.command.has_param('item1'), True) self.assertEqual(self.command.has_param('item2'), True) self.assertEqual(self.command.has_param('item3'), False) self.assertEqual(self.command.get_param('item1'), 'value1') self.assertEqual('value2' in self.command.get_param('item2'), True) self.assertEqual('value3' in self.command.get_param('item2'), True) self.assertEqual('value4' in self.command.get_param('item2'), True) data = self.command.format_trace self.assertEqual(data['Username'], 'test_user') self.assertEqual(data['Created'], 'test_time') self.assertEqual(data['Source_Address'], '1.2.3.4') self.assertEqual(data['Source_ID'], 'test_user_agent')
def test_negative_skew(self): now = datetime.datetime.utcnow() + datetime.timedelta(minutes=-11) now_str = now.strftime('%a, %d %b %Y %H:%M:%S GMT') response = MagicMock() response.headers = {'Date': now_str} with self.assertRaises(ClockSkew): ClockSkewHook().post_request('POST', 'http://example.com', {}, response)
def test_copy(self, computed_md5_mock): # the md5sum of the file being copied md5sum = 'd41d8cd98f00b204e9800998ecf84eee' # patch the compute_md5 function in vos to return the above value computed_md5_mock.return_value = md5sum #mock the props of the corresponding node props = MagicMock() props.get.return_value = md5sum #add props to the mocked node node = MagicMock(spec=Node) node.props = props # mock one by one the chain of connection.session.response.headers conn = MagicMock(spec=Connection) session = MagicMock() response = MagicMock() headers = MagicMock() headers.get.return_value = md5sum response.headers = headers session.get.return_value = response conn.session = session test_client = Client() # use the mocked connection instead of the real one test_client.conn = conn get_node_url_mock = Mock(return_value=['http://cadc.ca/test', 'http://cadc.ca/test']) test_client.get_node_url = get_node_url_mock #patch Client.get_node to return our mocked node get_node_mock = Mock(return_value=node) test_client.get_node = get_node_mock # time to test... vospaceLocation = 'vos://test/foo' osLocation = '/tmp/foo' # copy from vospace test_client.copy(vospaceLocation, osLocation) get_node_url_mock.assert_called_once_with(vospaceLocation, method='GET', cutout=None, view='data') computed_md5_mock.assert_called_once_with(osLocation) get_node_mock.assert_called_once_with(vospaceLocation) # copy to vospace get_node_url_mock.reset_mock() computed_md5_mock.reset_mock() test_client.copy(osLocation, vospaceLocation) get_node_url_mock.assert_called_once_with(vospaceLocation, 'PUT') computed_md5_mock.assert_called_once_with(osLocation) # error tests - md5sum mismatch computed_md5_mock.return_value = '000bad000' with self.assertRaises(OSError): test_client.copy(vospaceLocation, osLocation) with self.assertRaises(OSError): test_client.copy(osLocation, vospaceLocation)
def test_get_request_location_no_history(): """ Request location follows response location header. """ url = "http://pypi.python.org/simple/foo" response = MagicMock() response.history = [] response.headers = {"location": "http://pypi.python.org/simple/foo/"} eq_(get_request_location(response, url), "http://pypi.python.org/simple/foo/")
def test_get_request_location_no_history_no_headers(): """ Request location defaults to the request url. """ url = "http://pypi.python.org/simple/foo" response = MagicMock() response.history = [] response.headers = {} eq_(get_request_location(response, url), url)
def test_upstream_xauth(self): req = MagicMock() req.headers = {} req.method = 'GET' req.path = '/v2/servers' req.env = {'REMOTE_USER': '******'} resp = MagicMock() validate_token(req, resp, {}) self.assertIsNone(req.env.get('auth'))
def test_upstream_admin(self): req = MagicMock() req.headers = {} req.method = 'GET' req.path = '/v2/servers' req.env = {'is_admin': True} resp = MagicMock() validate_token(req, resp, {}) self.assertIsNone(req.env.get('auth'))
def test_parameter_validator(monkeypatch): request = MagicMock(name='request') request.args = {} request.headers = {} request.params = {} app = MagicMock(name='app') app.response_class = lambda a, mimetype, status: json.loads(a)['detail'] monkeypatch.setattr('flask.request', request) monkeypatch.setattr('flask.current_app', app) def orig_handler(*args, **kwargs): return 'OK' params = [{'name': 'p1', 'in': 'path', 'type': 'integer', 'required': True}, {'name': 'h1', 'in': 'header', 'type': 'string', 'enum': ['a', 'b']}, {'name': 'q1', 'in': 'query', 'type': 'integer', 'maximum': 3}, {'name': 'a1', 'in': 'query', 'type': 'array', 'items': {'type': 'integer', 'minimum': 0}}] validator = ParameterValidator(params) handler = validator(orig_handler) assert handler() == "Missing path parameter 'p1'" assert handler(p1='123') == 'OK' assert handler(p1='') == "Wrong type, expected 'integer' for path parameter 'p1'" assert handler(p1='foo') == "Wrong type, expected 'integer' for path parameter 'p1'" assert handler(p1='1.2') == "Wrong type, expected 'integer' for path parameter 'p1'" request.args = {'q1': '4'} assert handler(p1=1) == 'Invalid value, must be at most 3' request.args = {'q1': '3'} assert handler(p1=1) == 'OK' request.args = {'a1': '1,2'} assert handler(p1=1) == "OK" request.args = {'a1': '1,a'} assert handler(p1=1) == "Wrong type, expected 'integer' for query parameter 'a1'" request.args = {'a1': '1,-1'} assert handler(p1=1) == "Invalid value, must be at least 0" del request.args['a1'] request.headers = {'h1': 'a'} assert handler(p1='123') == 'OK' request.headers = {'h1': 'x'} assert handler(p1='123') == "Enum value must be one of ['a', 'b']"
def test_upstream_preauth(self): req = MagicMock() auth = {'user': '******'} req.headers = {} req.method = 'GET' req.path = '/v2/servers' req.env = {'auth': auth} resp = MagicMock() validate_token(req, resp, {}) self.assertEquals(req.env.get('auth'), auth)
def request(self, method, path, data=None, stream=False, **kwargs): self._reason = self.REASONS[self.counter % len(self.REASONS)] self._status = self.STATI[self.counter % len(self.STATI)] print(self.counter, self._status) self.counter += 1 mock_response = MagicMock() mock_response.status = self._status mock_response.reason = self._reason mock_response.headers = {"content-type": self.content_type} return mock_response
def test_call_unauthed(self): request = MagicMock() request.headers = {} self.auth.auth_token = None self.auth(request) self.assertEqual(self.auth.auth_token, 'NEW_AUTH_TOKEN') request.register_hook.assert_called_with( 'response', self.auth.handle_error) self.assertEqual(request.headers, {'X-Auth-Token': 'NEW_AUTH_TOKEN'})
def test_download_using_original_request_language(self, download_file_mock): fakerequest = MagicMock() fakerequest.registry.settings = {'convertit.downloads_path': '/path'} fakerequest.headers = {'Accept-language': 'fr', 'Host': 'localhost:1234'} download(fakerequest, 'http://geotrek.fr') download_file_mock.assert_called_with('http://geotrek.fr', '/path', headers={'Accept-language': 'fr', 'Host': 'localhost:1234'})
def test_verify_oauth_missing_auth_header(): def somefunc(token): return None wrapped_func = verify_oauth(somefunc, validate_scope) request = MagicMock() request.headers = {} assert wrapped_func(request, ['admin']) is None
def test_invalid_auth(self): req = MagicMock() req.headers = {'X-AUTH-TOKEN': 'IAMBAD'} req.method = 'GET' req.path = '/v2/servers' req.env = {} resp = MagicMock() with self.assertRaises(InvalidTokenError): validate_token(req, resp, {}) self.assertIsNone(req.env.get('auth'))
def fake_response(status, reason=None, content_type='application/json'): m = MagicMock(spec=urllib3.response.HTTPResponse) m.status = status m.reason = reason or '' m.headers = {'content-type': content_type} return m
def test_parse_json(): response = MagicMock() response.headers = {'Content-Type': JSON_MIME_TYPE} response.json.return_value = sentinel.json_content content = parse_response(response) assert content == sentinel.json_content
def mock_http_response(json, iter_content=None): m = MagicMock(name='http_response') m.headers = {} m.json.return_value = json m.iter_content = iter_content return m
def test_bad_format(self): response = MagicMock() response.headers = {'Date': 'bad format'} with self.assertRaises(BadDateFormat): ClockSkewHook().post_request('POST', 'http://example.com', {}, response)
def test_parameter_validator(monkeypatch): request = MagicMock(name='request') request.args = {} request.headers = {} request.params = {} app = MagicMock(name='app') def _response_class(data, mimetype, content_type, headers): response = MagicMock(name='response') response.detail = json.loads(''.join(data))['detail'] response.headers = MagicMock() return response app.response_class = _response_class monkeypatch.setattr('flask.request', request) monkeypatch.setattr('flask.current_app', app) def orig_handler(*args, **kwargs): return 'OK' params = [{ 'name': 'p1', 'in': 'path', 'type': 'integer', 'required': True }, { 'name': 'h1', 'in': 'header', 'type': 'string', 'enum': ['a', 'b'] }, { 'name': 'q1', 'in': 'query', 'type': 'integer', 'maximum': 3 }, { 'name': 'a1', 'in': 'query', 'type': 'array', 'minItems': 2, 'maxItems': 3, 'items': { 'type': 'integer', 'minimum': 0 } }] validator = ParameterValidator(params) handler = validator(orig_handler) assert handler().flask_response_object( ).detail == "Missing path parameter 'p1'" assert handler(p1='123') == 'OK' assert handler(p1='').flask_response_object( ).detail == "Wrong type, expected 'integer' for path parameter 'p1'" assert handler(p1='foo').flask_response_object( ).detail == "Wrong type, expected 'integer' for path parameter 'p1'" assert handler(p1='1.2').flask_response_object( ).detail == "Wrong type, expected 'integer' for path parameter 'p1'" request.args = {'q1': '4'} assert handler(p1=1).flask_response_object().detail.startswith( '4 is greater than the maximum of 3') request.args = {'q1': '3'} assert handler(p1=1) == 'OK' request.args = {'a1': "1,2"} assert handler(p1=1) == "OK" request.args = {'a1': "1,a"} assert handler(p1=1).flask_response_object().detail.startswith( "'a' is not of type 'integer'") request.args = {'a1': "1,-1"} assert handler(p1=1).flask_response_object().detail.startswith( "-1 is less than the minimum of 0") request.args = {'a1': "1"} assert handler( p1=1).flask_response_object().detail.startswith("[1] is too short") request.args = {'a1': "1,2,3,4"} assert handler(p1=1).flask_response_object().detail.startswith( "[1, 2, 3, 4] is too long") del request.args['a1'] request.headers = {'h1': 'a'} assert handler(p1='123') == 'OK' request.headers = {'h1': 'x'} assert handler(p1='123').flask_response_object().detail.startswith( "'x' is not one of ['a', 'b']")
def _response_class(data, mimetype, content_type, headers): response = MagicMock(name='response') response.detail = json.loads(''.join(data))['detail'] response.headers = MagicMock() return response
def test_copy(self, computed_md5_mock): # the md5sum of the file being copied md5sum = 'd41d8cd98f00b204e9800998ecf84eee' # patch the compute_md5 function in vos to return the above value computed_md5_mock.return_value = md5sum # mock the props of the corresponding node props = MagicMock() props.get.return_value = md5sum # add props to the mocked node node = MagicMock(spec=Node) node.props = props # mock one by one the chain of connection.session.response.headers conn = MagicMock(spec=Connection) session = MagicMock() response = MagicMock() headers = MagicMock() headers.get.return_value = md5sum response.headers = headers session.get.return_value = response conn.session = session test_client = Client() # use the mocked connection instead of the real one test_client.conn = conn get_node_url_mock = Mock( return_value=['http://cadc.ca/test', 'http://cadc.ca/test']) test_client.get_node_url = get_node_url_mock mock_update = Mock() test_client.update = mock_update # patch Client.get_node to return our mocked node get_node_mock = Mock(return_value=node) test_client.get_node = get_node_mock # time to test... vospaceLocation = 'vos://test/foo' osLocation = '/tmp/foo' if os.path.isfile(osLocation): os.remove(osLocation) # copy from vospace test_client.copy(vospaceLocation, osLocation) get_node_url_mock.assert_called_once_with(vospaceLocation, method='GET', cutout=None, view='data') computed_md5_mock.assert_called_once_with(osLocation) assert not get_node_mock.called # repeat - local file and vospace file are now the same -> only # get_node is called to get the md5 of remote file get_node_url_mock.reset_mock() computed_md5_mock.reset_mock() get_node_mock.reset_mock() test_client.copy(vospaceLocation, osLocation) assert not get_node_url_mock.called computed_md5_mock.assert_called_once_with(osLocation) get_node_mock.assert_called_once_with(vospaceLocation) # change the content of local files to trigger a new copy get_node_url_mock.reset_mock() computed_md5_mock.reset_mock() computed_md5_mock.side_effect = ['d002233', md5sum] get_node_mock.reset_mock() test_client.copy(vospaceLocation, osLocation) get_node_url_mock.assert_called_once_with(vospaceLocation, method='GET', cutout=None, view='data') computed_md5_mock.assert_called_with(osLocation) get_node_mock.assert_called_once_with(vospaceLocation) # copy to vospace when md5 sums are the same -> only update occurs get_node_url_mock.reset_mock() computed_md5_mock.reset_mock() computed_md5_mock.side_effect = None computed_md5_mock.return_value = md5sum test_client.copy(osLocation, vospaceLocation) mock_update.assert_called_once() assert not get_node_url_mock.called # make md5 different get_node_url_mock.reset_mock() get_node_url_mock.return_value =\ ['http://cadc.ca/test', 'http://cadc.ca/test'] computed_md5_mock.reset_mock() mock_update.reset_mock() props.get.side_effect = ['d00223344', md5sum] test_client.copy(osLocation, vospaceLocation) assert not mock_update.called get_node_url_mock.assert_called_once_with(vospaceLocation, 'PUT') computed_md5_mock.assert_called_once_with(osLocation) # copy 0 size file -> delete and create on client but no bytes # transferred get_node_url_mock.reset_mock() computed_md5_mock.reset_mock() computed_md5_mock.return_value = vos.ZERO_MD5 props.get.side_effect = [md5sum] mock_delete = Mock() mock_create = Mock() test_client.delete = mock_delete test_client.create = mock_create test_client.copy(osLocation, vospaceLocation) mock_create.assert_called_once_with(vospaceLocation) mock_delete.assert_called_once_with(vospaceLocation) assert not get_node_url_mock.called # copy new 0 size file -> reate on client but no bytes transferred get_node_url_mock.reset_mock() computed_md5_mock.reset_mock() mock_delete.reset_mock() mock_create.reset_mock() computed_md5_mock.return_value = vos.ZERO_MD5 props.get.side_effect = [None] mock_delete = Mock() mock_create = Mock() test_client.delete = mock_delete test_client.create = mock_create test_client.copy(osLocation, vospaceLocation) mock_create.assert_called_once_with(vospaceLocation) assert not mock_delete.called assert not get_node_url_mock.called # error tests - md5sum mismatch props.get.side_effect = [md5sum] computed_md5_mock.return_value = '000bad000' with self.assertRaises(OSError): test_client.copy(vospaceLocation, osLocation) with self.assertRaises(OSError): test_client.copy(osLocation, vospaceLocation)
def test_authorize_case_4(self): """Test authorize wit signature but wrong one.""" request = MagicMock() request.headers = {'X-Hub-Signature': 'md5=signature'} assert authorize(request, config) is False
def request(self, method, path, data=None, stream=False, **kwargs): mock_response = MagicMock() mock_response.status = self.status mock_response.reason = self.reason mock_response.headers = {"content-type": self.content_type} return mock_response
def test_parse_urlencoded(): response = MagicMock() response.headers = {'Content-Type': URLENCODED_MIME_TYPE} response.text = 'key=value&multi=a&multi=b' content = parse_response(response) assert content == {'key': 'value', 'multi': ['a', 'b']}
import sys from mock import patch, MagicMock from indicoio.utils import is_url mock_response = MagicMock() mock_response.headers = {'x-warning': 'testing warning'} mock_response.status_code = 200 mock_response.json = MagicMock(return_value={'results': 0.5}) def test_is_urls(): boring_image = [0] * (32**2) boring_images = [boring_image] * 100 assert not is_url(boring_image, batch=False) assert not is_url(boring_images, batch=True) url = 'http://picturepicture.com/picture' urls = [url] * 100 assert is_url(url, batch=False) assert is_url(urls, batch=True) @patch('indicoio.utils.api.warnings.warn') @patch('indicoio.utils.api.requests.post', MagicMock(return_value=mock_response)) def test_api_handler(mock_warn): from indicoio.utils.api import api_handler
from mock import patch, MagicMock import msgpack from indicoio.utils import is_url mock_response = MagicMock() mock_response.headers = {"x-warning": "testing warning"} results = {"results": 0.5} mock_response.status_code = 200 mock_response.json = MagicMock(return_value=results) mock_response.content = msgpack.packb(results) def test_is_urls(): boring_image = [0] * (32**2) boring_images = [boring_image] * 100 assert not is_url(boring_image, batch=False) assert not is_url(boring_images, batch=True) url = "http://picturepicture.com/picture" urls = [url] * 100 assert is_url(url, batch=False) assert is_url(urls, batch=True) @patch("warnings.warn") @patch("requests.post", MagicMock(return_value=mock_response)) def test_api_handler(mock_warn): from indicoio.utils.api import api_handler
def test_no_skew(self): now = datetime.datetime.utcnow() now_str = now.strftime('%a, %d %b %Y %H:%M:%S GMT') response = MagicMock() response.headers = {'Date': now_str} ClockSkewHook().post_request('POST', 'http://example.com', {}, response)
def test_bad_month(self): response = MagicMock() response.headers = {'Date': 'Fri, 16 XXX 2016 20:52:30 GMT'} with self.assertRaises(BadDateFormat): ClockSkewHook().post_request('POST', 'http://example.com', {}, response)
def test_parameter_validator(monkeypatch): request = MagicMock(name='request') request.args = {} request.headers = {} request.params = {} app = MagicMock(name='app') app.response_class = flask.Response monkeypatch.setattr('flask.request', request) monkeypatch.setattr('flask.current_app', app) def orig_handler(*args, **kwargs): return 'OK' params = [{ 'name': 'p1', 'in': 'path', 'type': 'integer', 'required': True }, { 'name': 'h1', 'in': 'header', 'type': 'string', 'enum': ['a', 'b'] }, { 'name': 'q1', 'in': 'query', 'type': 'integer', 'maximum': 3 }, { 'name': 'a1', 'in': 'query', 'type': 'array', 'minItems': 2, 'maxItems': 3, 'items': { 'type': 'integer', 'minimum': 0 } }] validator = ParameterValidator(params, FlaskApi) handler = validator(orig_handler) kwargs = {'query': {}, 'headers': {}} request = MagicMock(path_params={}, **kwargs) assert json.loads(handler( request).data.decode())['detail'] == "Missing path parameter 'p1'" request = MagicMock(path_params={'p1': '123'}, **kwargs) assert handler(request) == 'OK' request = MagicMock(path_params={'p1': ''}, **kwargs) assert json.loads(handler(request).data.decode( ))['detail'] == "Wrong type, expected 'integer' for path parameter 'p1'" request = MagicMock(path_params={'p1': 'foo'}, **kwargs) assert json.loads(handler(request).data.decode( ))['detail'] == "Wrong type, expected 'integer' for path parameter 'p1'" request = MagicMock(path_params={'p1': '1.2'}, **kwargs) assert json.loads(handler(request).data.decode( ))['detail'] == "Wrong type, expected 'integer' for path parameter 'p1'" request = MagicMock(path_params={'p1': 1}, query={'q1': '4'}, headers={}) assert json.loads(handler(request).data.decode())['detail'].startswith( '4 is greater than the maximum of 3') request = MagicMock(path_params={'p1': 1}, query={'q1': '3'}, headers={}) assert handler(request) == 'OK' request = MagicMock(path_params={'p1': 1}, query={'a1': ['1', '2']}, headers={}) assert handler(request) == "OK" request = MagicMock(path_params={'p1': 1}, query={'a1': ['1', 'a']}, headers={}) assert json.loads(handler(request).data.decode())['detail'].startswith( "'a' is not of type 'integer'") request = MagicMock(path_params={'p1': 1}, query={'a1': ['1', '-1']}, headers={}) assert json.loads(handler(request).data.decode())['detail'].startswith( "-1 is less than the minimum of 0") request = MagicMock(path_params={'p1': 1}, query={'a1': ['1']}, headers={}) assert json.loads(handler(request).data.decode())['detail'].startswith( "[1] is too short") request = MagicMock(path_params={'p1': 1}, query={'a1': ['1', '2', '3', '4']}, headers={}) assert json.loads(handler(request).data.decode())['detail'].startswith( "[1, 2, 3, 4] is too long") request = MagicMock(path_params={'p1': '123'}, query={}, headers={'h1': 'a'}) assert handler(request) == 'OK' request = MagicMock(path_params={'p1': '123'}, query={}, headers={'h1': 'x'}) assert json.loads(handler(request).data.decode())['detail'].startswith( "'x' is not one of ['a', 'b']")
def get_response(self, method, url, verify, cert=None, headers=None, data=None): resp = MagicMock() parts = urlparse(url) url = parts[2] params = parts[4] if method not in self.call_count: self.call_count[method] = {} if url not in self.call_count[method]: self.call_count[method][url] = 0 self.call_count[method][url] += 1 resp.status_code = 404 if method == "GET": if url == "": resp.status_code = 300 resp.json.return_value = { "versions": { "values": [{ "id": "v3.6" }, { "id": "v2.0" }] } } if url == "/-/": resp.status_code = 200 resp.text = self.read_file_as_string("files/occi.txt") elif url == "/compute/1": resp.status_code = 200 resp.text = self.read_file_as_string("files/occi_vm_info.txt") elif url.startswith("/storage"): resp.status_code = 200 resp.text = 'X-OCCI-Attribute: occi.storage.state="online"' elif url == "/v2.0/tenants": resp.status_code = 200 resp.json.return_value = {"tenants": [{"name": "tenantname"}]} elif url == "/v3/auth/projects": resp.status_code = 200 resp.json.return_value = { "projects": [{ "id": "projectid", "name": "prname" }] } elif url == "/v3/OS-FEDERATION/identity_providers/egi.eu/protocols/oidc/auth": resp.status_code = 200 resp.headers = {'X-Subject-Token': 'token1'} elif url.endswith("/link/storagelink/compute_10_disk_1"): resp.status_code = 404 elif url == "/rest/1.0/va_providers": resp.status_code = 200 resp.text = """<appdb:appdb> <virtualization:provider id="4454G0" in_production="true"> <provider:name>CESNET-MetaCloud</provider:name> </virtualization:provider> <virtualization:provider id="id" in_production="true"> <provider:name>some</provider:name> </virtualization:provider> </appdb:appdb>""" elif url == "/rest/1.0/va_providers/4454G0": resp.status_code = 200 resp.text = """<appdb:appdb> <virtualization:provider id="4454G0" in_production="true"> <provider:endpoint_url>https://carach5.ics.muni.cz:11443</provider:endpoint_url> <provider:image va_provider_image_id="http://url/os_tpl#image_id" appcname="egi.docker.ubuntu.16.04" voname="fedcloud.egi.eu"/> <provider:image va_provider_image_id="http://url/os_tpl#image_id2" appcname="egi.ubuntu.16.04" voname="fedcloud.egi.eu"/> </virtualization:provider> </appdb:appdb>""" elif url == "/network/": resp.status_code = 200 resp.text = ("X-OCCI-Location: http://server.com/network/1" "\nX-OCCI-Location: http://server.com/network/2") elif url == "/network/2": resp.status_code = 200 resp.text = "X-OCCI-Attribute: occi.network.address=\"158.42.0.0/24\"" elif url == "/network/1": resp.status_code = 200 resp.text = "X-OCCI-Attribute: occi.network.address=\"10.0.0.0/24\"" elif method == "POST": if url == "/compute/": if self.return_error: resp.status_code = 400 resp.reason = 'Error msg' resp.text = '' else: resp.status_code = 201 resp.text = 'https://server.com/compute/1' elif params == "action=suspend": resp.status_code = 204 elif params == "action=start": resp.status_code = 200 elif params == "action=restart": resp.status_code = 200 elif url == "/storagelink/": resp.status_code = 200 elif url == "/storage/": resp.status_code = 201 resp.text = 'https://server.com/storage/1' elif url == "/networkinterface/": resp.status_code = 201 elif url == "/v2.0/tokens": if json.loads(data) == {"auth": {"voms": True}}: resp.status_code = 200 resp.json.return_value = { "access": { "token": { "id": "token1" } } } elif json.loads(data) == { "auth": { "voms": True, "tenantName": "tenantname" } }: resp.status_code = 200 resp.json.return_value = { "access": { "token": { "id": "token2" } } } else: resp.status_code = 400 elif url == "/v3/auth/tokens": if json.loads(data) == { "auth": { "scope": { "project": { "id": "projectid" } }, "identity": { "token": { "id": "token1" }, "methods": ["token"] } } }: resp.status_code = 200 resp.headers = {'X-Subject-Token': 'token3'} else: resp.status_code = 400 elif method == "DELETE": if url.endswith("/compute/1"): resp.status_code = 200 elif url.endswith("/storage/1"): resp.status_code = 200 elif url.endswith("/link/storagelink/compute_10_disk_1"): resp.status_code = 200 elif url.endswith("/link/networkinterface/compute_10_nic_1"): resp.status_code = 200 return resp
def test_parameter_validator(monkeypatch): request = MagicMock(name='request') request.args = {} request.headers = {} request.params = {} app = MagicMock(name='app') app.response_class = lambda a, mimetype, status: json.loads(a)['detail'] monkeypatch.setattr('flask.request', request) monkeypatch.setattr('flask.current_app', app) def orig_handler(*args, **kwargs): return 'OK' params = [{ 'name': 'p1', 'in': 'path', 'type': 'integer', 'required': True }, { 'name': 'h1', 'in': 'header', 'type': 'string', 'enum': ['a', 'b'] }, { 'name': 'q1', 'in': 'query', 'type': 'integer', 'maximum': 3 }, { 'name': 'a1', 'in': 'query', 'type': 'array', 'items': { 'type': 'integer', 'minimum': 0 } }] validator = ParameterValidator(params) handler = validator(orig_handler) assert handler() == "Missing path parameter 'p1'" assert handler(p1='123') == 'OK' assert handler( p1='') == "Wrong type, expected 'integer' for path parameter 'p1'" assert handler( p1='foo') == "Wrong type, expected 'integer' for path parameter 'p1'" assert handler( p1='1.2') == "Wrong type, expected 'integer' for path parameter 'p1'" request.args = {'q1': '4'} assert handler(p1=1) == 'Invalid value, must be at most 3' request.args = {'q1': '3'} assert handler(p1=1) == 'OK' request.args = {'a1': '1,2'} assert handler(p1=1) == "OK" request.args = {'a1': '1,a'} assert handler( p1=1) == "Wrong type, expected 'integer' for query parameter 'a1'" request.args = {'a1': '1,-1'} assert handler(p1=1) == "Invalid value, must be at least 0" del request.args['a1'] request.headers = {'h1': 'a'} assert handler(p1='123') == 'OK' request.headers = {'h1': 'x'} assert handler(p1='123') == "Enum value must be one of ['a', 'b']"
def test_authorize_case_1(self): """Test authorize without signature.""" request = MagicMock() request.headers = {'Something': 'bar'} assert authorize(request, config) is False