def test_params_and_upload_files(): class PostApp(object): def __call__(self, environ, start_response): start_response("204 No content", []) self.request = WSGIRequest(environ) return [b''] post_app = PostApp() app = TestApp(post_app) app.post( '/', params={ 'param1': 'a', 'param2': 'b' }, upload_files=[ ('file1', 'myfile.txt', b'data1'), ('file2', b'yourfile.txt', b'data2'), ], ) params = post_app.request.params assert len(params) == 4 assert params['param1'] == 'a' assert params['param2'] == 'b' assert params['file1'].value == b'data1' assert params['file1'].filename == 'myfile.txt' assert params['file2'].value == b'data2' assert params['file2'].filename == 'yourfile.txt'
class TestAuthenticateFormDecorator(TestWSGIController): def setUp(self): TestWSGIController.setUp(self) app = ControllerWrap(ProtectedController) app = SetupCacheGlobal(app, self.environ, setup_session=True) app = SessionMiddleware(app, {}, data_dir=session_dir) app = RegistryManager(app) self.app = TestApp(app) def test_unauthenticated(self): self.environ['pylons.routes_dict']['action'] = 'protected' response = self.app.post('/protected', extra_environ=self.environ, expect_errors=True) assert response.status == 403 assert csrf_detected_message in response def test_authenticated(self): self.environ['pylons.routes_dict']['action'] = 'form' response = self.app.get('/form', extra_environ=self.environ) token = response.body self.environ['pylons.routes_dict']['action'] = 'protected' response = self.app.post('/protected', params={secure_form_tag.token_key: token}, extra_environ=self.environ, expect_errors=True) assert 'Authenticated' in response
class TestGET(): def setUp(self): middleware = [] self.client = TestApp(app.wsgifunc(*middleware)) self.lazy_url_2 = ''.join([lazy_controller, 'l222']) self.lazy_url_3 = ''.join([lazy_controller, 'l223']) canonical_url_1 = ''.join([canonical_controller, 'l221']) canonical_url_2 = ''.join([canonical_controller, 'l222']) self.client.post(canonical_url_1, 'test') #Propagated to all nodes self.client.post(canonical_url_2, 'test') #Propagated to all nodes def test_get_with_no_key_should_return_all_keys_present_in_any_node(self): r = self.client.get(lazy_controller) assert_equal(r.status, 200) r.mustcontain('l222') r.mustcontain('l221') def test_get_with_valid_key_present_in_all_nodes(self): r = self.client.get(self.lazy_url_2) assert_equal(r.status, 200) r.mustcontain('test') def test_get_with_invalid_key(self): """No Assertion required """ self.client.get(self.lazy_url_3, status=404)
def test_wsgirequest_charset(): # Jose, 'José' app = TestApp(AssertApp(assertfunc=valid_name(u'José', encoding='iso-8859-1'))) res = app.get('/?name=Jos%E9') # Tanaka, '田中' app = TestApp(AssertApp(assertfunc=valid_name(u'田中', encoding='UTF-8'))) res = app.get('/?name=%E7%94%B0%E4%B8%AD') # Nippon (Japan), '日本' app = TestApp(AssertApp(assertfunc=valid_name(u'日本', encoding='UTF-8', post=True))) res = app.post('/', params=dict(name='日本')) # WSGIRequest will determine the charset from the Content-Type header when # unicode is expected. # No encoding specified: not expecting unicode app = TestApp(AssertApp(assertfunc=valid_name('日本', post=True))) content_type = 'application/x-www-form-urlencoded; charset=%s' res = app.post('/', params=dict(name='日本'), headers={'content-type': content_type % 'UTF-8'}) # Encoding specified: expect unicode. Shiftjis is the default encoding, but # params become UTF-8 because the browser specified so app = TestApp(AssertApp(assertfunc=valid_name(u'日本', post=True, encoding='shiftjis'))) res = app.post('/', params=dict(name='日本'), headers={'content-type': content_type % 'UTF-8'}) # Browser did not specify: parse params as the fallback shiftjis app = TestApp(AssertApp(assertfunc=valid_name(u'日本', post=True, encoding='shiftjis'))) res = app.post('/', params=dict(name=u'日本'.encode('shiftjis')))
class TestGET(): def setUp(self): self.url_1 = ''.join([controller, 'c221']) self.url_2 = ''.join([controller, 'c222']) middleware = [] self.client = TestApp(app.wsgifunc(*middleware)) self.client.post(self.url_1, 'test') self.client.post(self.url_2, 'test') def test_get_with_no_key_should_return_all_keys(self): r = self.client.get(controller) assert_equal(r.status, 200) r.mustcontain('c222') r.mustcontain('c221') def test_get_with_valid_key(self): r = self.client.get(self.url_2) assert_equal(r.status, 200) r.mustcontain('test') def test_get_with_invalid_key(self): """No Assertion required """ self.url_3 = ''.join([controller, 'c223']) self.client.get(self.url_3, status=404)
class TestAuthenticateFormDecorator(TestWSGIController): def setUp(self): TestWSGIController.setUp(self) app = ControllerWrap(ProtectedController) app = SetupCacheGlobal(app, self.environ, setup_session=True) app = SessionMiddleware(app, {}, data_dir=session_dir) app = RegistryManager(app) self.app = TestApp(app) def test_unauthenticated(self): self.environ["pylons.routes_dict"]["action"] = "protected" response = self.app.post("/protected", extra_environ=self.environ, expect_errors=True) assert response.status == 403 assert csrf_detected_message in response def test_authenticated(self): self.environ["pylons.routes_dict"]["action"] = "form" response = self.app.get("/form", extra_environ=self.environ) token = response.body self.environ["pylons.routes_dict"]["action"] = "protected" response = self.app.post( "/protected", params={secure_form_tag.token_key: token}, extra_environ=self.environ, expect_errors=True ) assert "Authenticated" in response
class TestAuthenticateFormDecorator(TestWSGIController): def setUp(self): from pylons.testutil import ControllerWrap, SetupCacheGlobal ProtectedController = make_protected() TestWSGIController.setUp(self) app = ControllerWrap(ProtectedController) app = SetupCacheGlobal(app, self.environ, setup_session=True) app = SessionMiddleware(app, {}, data_dir=session_dir) app = RegistryManager(app) self.app = TestApp(app) def test_unauthenticated(self): from pylons.decorators.secure import csrf_detected_message self.environ['pylons.routes_dict']['action'] = 'protected' response = self.app.post('/protected', extra_environ=self.environ, expect_errors=True) assert response.status == 403 assert csrf_detected_message in response def test_authenticated(self): from webhelpers.pylonslib import secure_form self.environ['pylons.routes_dict']['action'] = 'form' response = self.app.get('/form', extra_environ=self.environ) token = response.body self.environ['pylons.routes_dict']['action'] = 'protected' response = self.app.post('/protected', params={secure_form.token_key: token}, extra_environ=self.environ, expect_errors=True) assert 'Authenticated' in response self.environ['pylons.routes_dict']['action'] = 'protected' response = self.app.put('/protected', params={secure_form.token_key: token}, extra_environ=self.environ, expect_errors=True) assert 'Authenticated' in response # GET with token_key in query string response = self.app.get('/protected', params={secure_form.token_key: token}, extra_environ=self.environ, expect_errors=True) assert 'Authenticated' in response # POST with token_key in query string response = self.app.post('/protected?' + secure_form.token_key + '=' + token, extra_environ=self.environ, expect_errors=True) assert 'Authenticated' in response
def test_size(self): middleware = [] testApp = TestApp(app.wsgifunc(*middleware)) comment_params = dict(self.correct_comment_params) comment_params['content'] = "a" * 100000 r = testApp.post('/add_comment', params=comment_params) assert_equal(r.status, 200) r.mustcontain("Thank you for your comment") comment_params['content'] = "a" * 102400 with assert_raises(ValueError): testApp.post('/add_comment', params=comment_params, expect_errors=True)
class TestValidateDecorator(TestWSGIController): def setUp(self): from pylons.testutil import ControllerWrap, SetupCacheGlobal ValidatingController = make_validating_controller() TestWSGIController.setUp(self) app = SetupCacheGlobal(ControllerWrap(ValidatingController), self.environ) app = RegistryManager(app) self.app = TestApp(app) def test_network_validated(self): response = self.post_response(action='network', new_network='http://pylonshq.com/') assert 'Your network is: http://pylonshq.com/' in response def test_network_failed_validation_non_ascii(self): response = self.post_response(action='network', new_network='Росси́я') assert 'That is not a valid URL' in response assert 'Росси́я' in response def test_recurse_validated(self): response = self.post_response(action='hello_recurse', new_network='http://pylonshq.com/') assert 'Your network is: http://pylonshq.com/' in response def test_hello(self): self.environ['pylons.routes_dict']['action'] = 'hello' response = self.app.post('/hello?hello=1&hello=2&hello=3', extra_environ=self.environ) assert "'hello': [1, 2, 3]" in response def test_hello_failed(self): self.environ['pylons.routes_dict']['action'] = 'hello' response = self.app.post('/hello?hello=1&hello=2&hello=hi', extra_environ=self.environ) assert 'Bad Hello! ' in response assert "[None, None, u'Please enter an integer value']" in response def test_hello_custom_failed(self): self.environ['pylons.routes_dict']['action'] = 'hello_custom' response = \ self.app.post('/hello_custom?hello=1&hello=2&hello=hi', extra_environ=self.environ) assert 'Bad Hello! ' in response assert "[None, None, u'Please enter an integer value']" in response assert ( """<p><span class="pylons-error">[None, None, u'Please enter """ """an integer value']</span></p>""") in response
class TestValidateDecorator(TestWSGIController): def setUp(self): from pylons.testutil import ControllerWrap, SetupCacheGlobal ValidatingController = make_validating_controller() TestWSGIController.setUp(self) app = SetupCacheGlobal(ControllerWrap(ValidatingController), self.environ) app = RegistryManager(app) self.app = TestApp(app) def test_network_validated(self): response = self.post_response(action='network', new_network='http://pylonshq.com/') assert 'Your network is: http://pylonshq.com/' in response def test_network_failed_validation_non_ascii(self): response = self.post_response(action='network', new_network='Росси́я') # assert 'That is not a valid URL' in response, response assert 'You must provide a full domain name' in response assert 'Росси́я' in response def test_recurse_validated(self): response = self.post_response(action='hello_recurse', new_network='http://pylonshq.com/') assert 'Your network is: http://pylonshq.com/' in response def test_hello(self): self.environ['pylons.routes_dict']['action'] = 'hello' response = self.app.post('/hello?hello=1&hello=2&hello=3', extra_environ=self.environ) assert "'hello': [1, 2, 3]" in response def test_hello_failed(self): self.environ['pylons.routes_dict']['action'] = 'hello' response = self.app.post('/hello?hello=1&hello=2&hello=hi', extra_environ=self.environ) assert 'Bad Hello! ' in response assert "[None, None, u'Please enter an integer value']" in response def test_hello_custom_failed(self): self.environ['pylons.routes_dict']['action'] = 'hello_custom' response = \ self.app.post('/hello_custom?hello=1&hello=2&hello=hi', extra_environ=self.environ) assert 'Bad Hello! ' in response assert "[None, None, u'Please enter an integer value']" in response assert ("""<p><span class="pylons-error">[None, None, u'Please enter """ """an integer value']</span></p>""") in response
def test_wsgirequest_charset_fileupload(): def handle_fileupload(environ, start_response): start_response('200 OK', [('Content-type','text/plain')]) request = WSGIRequest(environ) assert len(request.POST) == 1 assert isinstance(request.POST.keys()[0], str) fs = request.POST['thefile'] assert isinstance(fs, cgi.FieldStorage) assert isinstance(fs.filename, str) assert fs.filename == '寿司.txt' assert fs.value == 'Sushi' request.charset = 'UTF-8' assert len(request.POST) == 1 assert isinstance(request.POST.keys()[0], str) fs = request.POST['thefile'] assert isinstance(fs, cgi.FieldStorage) assert isinstance(fs.filename, unicode) assert fs.filename == u'寿司.txt' assert fs.value == 'Sushi' request.charset = None assert fs.value == 'Sushi' return [] app = TestApp(handle_fileupload) res = app.post('/', upload_files=[('thefile', '寿司.txt', 'Sushi')])
def test_basic_post(self, logging_info): # what the middleware app does is that creates a class based on another # and sets an attribute called `cls` class MadeUp(middleware_app.ImplementationWrapper): cls = AuxImplementation3 config = DotDict( logger=logging, web_server=DotDict( ip_address='127.0.0.1', port='88888' ) ) server = CherryPy(config, ( ('/aux/(.*)', MadeUp), )) testapp = TestApp(server._wsgi_func) response = testapp.post('/aux/') self.assertEqual(response.status, 200) self.assertEqual(json.loads(response.body), {'age': 100}) logging_info.assert_called_with('Running AuxImplementation3') response = testapp.get('/aux/', expect_errors=True) self.assertEqual(response.status, 405)
def test_normal_post(self): middleware = [] testApp = TestApp(app.wsgifunc(*middleware)) r = testApp.post('/add_comment', params=self.correct_comment_params) assert_equal(r.status, 200) r.mustcontain("Thank you for your comment")
def test_fixture(): app = TestApp(SimpleApplication()) res = app.get('/', params={'a': ['1', '2']}) assert (res.request.environ['QUERY_STRING'] == 'a=1&a=2') res = app.put('/') assert (res.request.environ['REQUEST_METHOD'] == 'PUT') res = app.delete('/') assert (res.request.environ['REQUEST_METHOD'] == 'DELETE') class FakeDict(object): def items(self): return [('a', '10'), ('a', '20')] res = app.post('/params', params=FakeDict()) # test multiple cookies in one request app.cookies['one'] = 'first'; app.cookies['two'] = 'second'; app.cookies['three'] = ''; res = app.get('/') hc = res.request.environ['HTTP_COOKIE'].split('; '); assert ('one=first' in hc) assert ('two=second' in hc) assert ('three=' in hc)
class TestMessageHandler(unittest.TestCase): @classmethod def setUpClass(cls): cls.web_data = open(os.path.join(grok.app.GROK_HOME, "tests/py/data/app/webservices/msg_manager.txt")).read() cls.message_manager_data = json.load( open(os.path.join( grok.app.GROK_HOME, "tests/py/data/app/webservices/message_manager_data.json"))) def setUp(self): self.app = TestApp(webapp.app.wsgifunc()) self.headers = getDefaultHTTPHeaders(grok.app.config) def testPOSTWithExplicit(self): response = self.app.post("/_msgs", self.web_data, headers=self.headers) assertions.assertSuccess(self, response) self.assertEqual(json.loads(response.body), self.message_manager_data) #TODO def testPOSTWithoutExaplicit(self): pass
class TestMessageHandler(unittest.TestCase): @classmethod def setUpClass(cls): cls.web_data = open( os.path.join( grok.app.GROK_HOME, "tests/py/data/app/webservices/msg_manager.txt")).read() cls.message_manager_data = json.load( open( os.path.join( grok.app.GROK_HOME, "tests/py/data/app/webservices/message_manager_data.json")) ) def setUp(self): self.app = TestApp(webapp.app.wsgifunc()) self.headers = getDefaultHTTPHeaders(grok.app.config) def testPOSTWithExplicit(self): response = self.app.post("/_msgs", self.web_data, headers=self.headers) assertions.assertSuccess(self, response) self.assertEqual(json.loads(response.body), self.message_manager_data) #TODO def testPOSTWithoutExaplicit(self): pass
def test_wsgirequest_charset_fileupload(): def handle_fileupload(environ, start_response): start_response('200 OK', [('Content-type', 'text/plain')]) request = WSGIRequest(environ) assert len(request.POST) == 1 assert isinstance(request.POST.keys()[0], str) fs = request.POST['thefile'] assert isinstance(fs, cgi.FieldStorage) assert isinstance(fs.filename, str) assert fs.filename == '寿司.txt' assert fs.value == 'Sushi' request.charset = 'UTF-8' assert len(request.POST) == 1 assert isinstance(request.POST.keys()[0], str) fs = request.POST['thefile'] assert isinstance(fs, cgi.FieldStorage) assert isinstance(fs.filename, unicode) assert fs.filename == u'寿司.txt' assert fs.value == 'Sushi' request.charset = None assert fs.value == 'Sushi' return [] app = TestApp(handle_fileupload) res = app.post('/', upload_files=[('thefile', '寿司.txt', 'Sushi')])
def post(self, server, url, data=None, expect_errors=False): a = TestApp(server._wsgi_func) data = data or '' if isinstance(data, dict): q = urllib.urlencode(data, True) else: q = data response = a.post(url, q, expect_errors=expect_errors) return self._respond(response, expect_errors)
class AWSAuthHandlerTest(unittest.TestCase): def setUp(self): #self.headers = getDefaultHTTPHeaders(grok.app.config) self.app = TestApp(webapp.app.wsgifunc()) @patch("grok.app.webservices.webapp.checkEC2Authorization") def testAuthInvalidCredentials(self, checkEC2AuthorizationMock): errorMessage = ("AWS was not able to validate the provided access " "credentials") exc = AuthFailure(errorMessage) checkEC2AuthorizationMock.side_effect = exc requestBody = { "aws_access_key_id": "bad_key", "aws_secret_access_key": "bad_key", } with self.assertRaises(AppError) as cm: self.app.post("/_auth", json.dumps(requestBody)) checkEC2AuthorizationMock.assert_called_once_with("bad_key", "bad_key") self.assertIn(errorMessage, cm.exception.message) @patch("grok.app.webservices.webapp.checkEC2Authorization") def testAuthCredentialsMissingPermissions(self, checkEC2AuthorizationMock): errorMessage = ("IAM credentials don't have correct permissions.") exc = AWSPermissionsError(errorMessage) checkEC2AuthorizationMock.side_effect = exc requestBody = { "aws_access_key_id": "good_key", "aws_secret_access_key": "good_key", } with self.assertRaises(AppError) as cm: self.app.post("/_auth", json.dumps(requestBody)) checkEC2AuthorizationMock.assert_called_once_with("good_key", "good_key") self.assertIn(errorMessage, cm.exception.message)
class TestHttpsDecorator(TestWSGIController): def setUp(self): TestWSGIController.setUp(self) from routes import Mapper map = Mapper() map.connect('/:action') map.connect('/:action/:id') map.connect('/:controller/:action/:id') map.connect('/:controller/:action') app = ControllerWrap(HttpsController) app = SetupCacheGlobal(app, self.environ, setup_cache=False) app = RoutesMiddleware(app, map) app = RegistryManager(app) self.app = TestApp(app) def test_https_explicit_path(self): self.environ['pylons.routes_dict']['action'] = 'index' response = self.app.get('/index', status=302) assert response.header_dict.get('location') == \ 'https://localhost/pylons' self.environ['wsgi.url_scheme'] = 'https' response = self.app.get('/index', status=200) assert 'location' not in response.header_dict assert 'index page' in response def test_https_disallows_post(self): self.environ['pylons.routes_dict']['action'] = 'index' response = self.app.post('/index', status=405) def test_https_url_for_kwargs(self): self.environ['pylons.routes_dict']['action'] = 'login' response = self.app.get('/login', status=302) assert response.header_dict.get('location') == \ 'https://localhost/auth/login' self.environ['wsgi.url_scheme'] = 'https' response = self.app.get('/login', status=200) assert 'location' not in response.header_dict assert 'login page' in response def test_https_redirect_to_self(self): self.environ['pylons.routes_dict']['action'] = 'get' response = self.app.get('/get', status=302) assert response.header_dict.get('location') == \ 'https://localhost/get' self.environ['wsgi.url_scheme'] = 'https' response = self.app.get('/get', status=200) assert 'location' not in response.header_dict assert 'get page' in response
def test_add(self): middleware = [] testApp = TestApp(app.wsgifunc(*middleware)) key = 'test2' message = 'jhfsdf' obj_data = {'key': key, 'message': message} r1 = testApp.post('/storage/' + key, params=json.dumps(obj_data)) r = testApp.get('/storage/' + key) self.assertEqual(r1.status, 200) self.assertEqual(r.status, 200) self.assertEqual(json.loads(r.body.decode('utf-8'))['message'], message)
class TestHttpsDecorator(TestWSGIController): def setUp(self): TestWSGIController.setUp(self) from routes import Mapper map = Mapper() map.connect('/:action/:id') map.connect('/:controller/:action/:id') app = ControllerWrap(HttpsController) app = SetupCacheGlobal(app, self.environ, setup_cache=False) app = RoutesMiddleware(app, map) app = RegistryManager(app) self.app = TestApp(app) def test_https_explicit_path(self): self.environ['pylons.routes_dict']['action'] = 'index' response = self.app.get('/index', status=302) assert response.header_dict.get('location') == \ 'https://localhost/pylons' self.environ['wsgi.url_scheme'] = 'https' response = self.app.get('/index', status=200) assert 'location' not in response.header_dict assert 'index page' in response def test_https_disallows_post(self): self.environ['pylons.routes_dict']['action'] = 'index' response = self.app.post('/index', status=405) def test_https_url_for_kwargs(self): self.environ['pylons.routes_dict']['action'] = 'login' response = self.app.get('/login', status=302) assert response.header_dict.get('location') == \ 'https://localhost/auth/login' self.environ['wsgi.url_scheme'] = 'https' response = self.app.get('/login', status=200) assert 'location' not in response.header_dict assert 'login page' in response def test_https_redirect_to_self(self): self.environ['pylons.routes_dict']['action'] = 'get' response = self.app.get('/get', status=302) assert response.header_dict.get('location') == \ 'https://localhost/get' self.environ['wsgi.url_scheme'] = 'https' response = self.app.get('/get', status=200) assert 'location' not in response.header_dict assert 'get page' in response
class TestPOST(): def setUp(self): middleware = [] self.client = TestApp(app.wsgifunc(*middleware)) def test_set_a_key_value(self): lazy_post_url = ''.join([lazy_controller, 'l555']) canonical_get_url = ''.join([canonical_controller, 'l555']) r = self.client.post(lazy_post_url, "testing post method: newly created value") assert_equal(r.status, 201) r2 = self.client.get(canonical_get_url) r2.mustcontain("testing post method: newly created value") def test_set_a_key_value_where_key_exists(self): lazy_post_url = ''.join([lazy_controller, 'l655']) canonical_url = ''.join([canonical_controller, 'l655']) self.client.post(canonical_url, "value exists. over written on canonical. Can be visible in others") r2 = self.client.get(canonical_url) r3 = self.client.post(lazy_post_url, "overwritten the existing value") assert_equal(r3.status, 201) r4 = self.client.get(canonical_url) r4.mustcontain("overwritten the existing value") def test_long_key_results_error(self): """No Assertion required """ key = "".join(map(str, range(40))) url_too_long_key = ''.join([lazy_controller, key]) self.client.post(url_too_long_key, "very very long. longer key than in database. should not get inserted", status=400) self.client.get(url_too_long_key, status=404)
class TestDELETE(): def setUp(self): middleware = [] self.client = TestApp(app.wsgifunc(*middleware)) def test_delete_a_key_value(self): lazy_url = ''.join([lazy_controller, 'l777']) canonical_url = ''.join([canonical_controller, 'l777']) self.client.post(canonical_url, "should have a deleted flag") self.client.delete(lazy_url, status=202) self.client.get(canonical_url, status=404) def test_cannot_delete_a_non_existing_key_value(self): url_xyz = ''.join([lazy_controller, 'lxyz']) self.client.delete(url_xyz, status=404) def test_delete_existing_and_immediately_insert_a_key_value(self): lazy_url = ''.join([lazy_controller, 'l737']) canonical_url = ''.join([canonical_controller, 'l737']) self.client.post(canonical_url, "will be deleted and over written on canonical. Can be visible in others.") self.client.delete(lazy_url, status=202) self.client.post(lazy_url, "deleted existing. and written a new value") r2 = self.client.get(canonical_url) r2.mustcontain("deleted existing. and written a new value")
class TestPOST(): def setUp(self): middleware = [] self.client = TestApp(app.wsgifunc(*middleware)) def test_set_a_key_value(self): url_225 = ''.join([controller, 'c225']) r = self.client.post(url_225, "testing post method:newly set key") assert_equal(r.status, 201) r.mustcontain("c225") r2 = self.client.get(url_225) r2.mustcontain("testing post method:newly set key") def test_set_a_key_value_where_key_exists(self): url_335 = ''.join([controller, 'c335']) self.client.post(url_335, "value exists. should have been overwritten.") r2 = self.client.get(url_335) r2.mustcontain("value exists. should have been overwritten.") r3 = self.client.post(url_335, "overwritten the existing value") assert_equal(r3.status, 201) r4 = self.client.get(url_335) r4.mustcontain("overwritten the existing value") def test_long_key_results_error(self): """No Assertion required """ key = "".join(map(str, range(40))) url_too_long_key = ''.join([controller, key]) self.client.post(url_too_long_key, "very very long. longer key than in database. should not get inserted", status=400) self.client.get(url_too_long_key, status=404)
def _createEC2Instance(self): """ Created EC2 instance to be used by the tests :return: Instance ID :rtype: str """ app = TestApp(instances_api.app.wsgifunc()) response = app.post("/" + self.instanceId, headers=self.headers) assertions.assertSuccess(self, response) result = app_utils.jsonDecode(response.body) self.assertIsInstance(result, dict) self.assertEqual(result, {"result": "success"})
class TestHttpsDecorator(TestWSGIController): def setUp(self): TestWSGIController.setUp(self) from routes import Mapper map = Mapper() map.connect("/:action/:id") map.connect("/:controller/:action/:id") app = ControllerWrap(HttpsController) app = SetupCacheGlobal(app, self.environ, setup_cache=False) app = RoutesMiddleware(app, map) app = RegistryManager(app) self.app = TestApp(app) def test_https_explicit_path(self): self.environ["pylons.routes_dict"]["action"] = "index" response = self.app.get("/index", status=302) assert response.header_dict.get("location") == "https://localhost/pylons" self.environ["wsgi.url_scheme"] = "https" response = self.app.get("/index", status=200) assert "location" not in response.header_dict assert "index page" in response def test_https_disallows_post(self): self.environ["pylons.routes_dict"]["action"] = "index" response = self.app.post("/index", status=405) def test_https_url_for_kwargs(self): self.environ["pylons.routes_dict"]["action"] = "login" response = self.app.get("/login", status=302) assert response.header_dict.get("location") == "https://localhost/auth/login" self.environ["wsgi.url_scheme"] = "https" response = self.app.get("/login", status=200) assert "location" not in response.header_dict assert "login page" in response def test_https_redirect_to_self(self): self.environ["pylons.routes_dict"]["action"] = "get" response = self.app.get("/get", status=302) assert response.header_dict.get("location") == "https://localhost/get" self.environ["wsgi.url_scheme"] = "https" response = self.app.get("/get", status=200) assert "location" not in response.header_dict assert "get page" in response
def test_wsgirequest_charset(): # Jose, 'José' app = TestApp( AssertApp(assertfunc=valid_name(u'José', encoding='iso-8859-1'))) res = app.get('/?name=Jos%E9') # Tanaka, '田中' app = TestApp(AssertApp(assertfunc=valid_name(u'田中', encoding='UTF-8'))) res = app.get('/?name=%E7%94%B0%E4%B8%AD') # Nippon (Japan), '日本' app = TestApp( AssertApp(assertfunc=valid_name(u'日本', encoding='UTF-8', post=True))) res = app.post('/', params=dict(name='日本')) # WSGIRequest will determine the charset from the Content-Type header when # unicode is expected. # No encoding specified: not expecting unicode app = TestApp(AssertApp(assertfunc=valid_name('日本', post=True))) content_type = 'application/x-www-form-urlencoded; charset=%s' res = app.post('/', params=dict(name='日本'), headers={'content-type': content_type % 'UTF-8'}) # Encoding specified: expect unicode. Shiftjis is the default encoding, but # params become UTF-8 because the browser specified so app = TestApp( AssertApp( assertfunc=valid_name(u'日本', post=True, encoding='shiftjis'))) res = app.post('/', params=dict(name='日本'), headers={'content-type': content_type % 'UTF-8'}) # Browser did not specify: parse params as the fallback shiftjis app = TestApp( AssertApp( assertfunc=valid_name(u'日本', post=True, encoding='shiftjis'))) res = app.post('/', params=dict(name=u'日本'.encode('shiftjis')))
def test_handlers_login_get_post(): # GET testApp = TestApp(app.wsgifunc(*[])) req = testApp.get('/login/') assert_equal(req.status, 200) req.mustcontain("Login") # POST req = testApp.post('/login/', params = { 'mail': '*****@*****.**', 'password': '******' }) assert_equal(req.status, 200) req.mustcontain("Hello")
class MetricsApiUnhappyTest(unittest.TestCase): """ Unhappy tests for Metrics API """ def setUp(self): self.app = TestApp(metrics_api.app.wsgifunc()) self.headers = getDefaultHTTPHeaders(YOMP.app.config) def testNoAuthHeaders(self): """ negative test for authentication guarded route. invoke get request without passing authentication headers resoponse is validated for appropriate headers and body """ response = self.app.get("/datasources", status="*") assertions.assertInvalidAuthenticationResponse(self, response) def testInvalidAuthHeaders(self): """ negative test for authentication guarded route. invoke get request with invalid authentication headers resoponse is validated for appropriate headers and body """ invalidHeaders = getInvalidHTTPHeaders() response = self.app.get("/datasources", status="*", headers=invalidHeaders) assertions.assertInvalidAuthenticationResponse(self, response) def testInvalidRoute(self): """ Invoke non supported route resoponse is validated for appropriate headers and body """ response = self.app.get("/foo", status="*", headers=self.headers) assertions.assertRouteNotFound(self, response) def testInvalidMethod(self): """ Invoe non supported methods resoponse is validated for appropriate headers and body """ response = self.app.post("/datasources", status="*", headers=self.headers) assertions.assertMethodNotAllowed(self, response) headers = dict(response.headers) self.assertEqual(headers["Allow"], "GET")
class MetricsApiUnhappyTest(unittest.TestCase): """ Unhappy tests for Metrics API """ def setUp(self): self.app = TestApp(metrics_api.app.wsgifunc()) self.headers = getDefaultHTTPHeaders(grok.app.config) def testNoAuthHeaders(self): """ negative test for authentication guarded route. invoke get request without passing authentication headers resoponse is validated for appropriate headers and body """ response = self.app.get("/datasources", status="*") assertions.assertInvalidAuthenticationResponse(self, response) def testInvalidAuthHeaders(self): """ negative test for authentication guarded route. invoke get request with invalid authentication headers resoponse is validated for appropriate headers and body """ invalidHeaders = getInvalidHTTPHeaders() response = self.app.get("/datasources", status="*", headers=invalidHeaders) assertions.assertInvalidAuthenticationResponse(self, response) def testInvalidRoute(self): """ Invoke non supported route resoponse is validated for appropriate headers and body """ response = self.app.get("/foo", status="*", headers=self.headers) assertions.assertRouteNotFound(self, response) def testInvalidMethod(self): """ Invoe non supported methods resoponse is validated for appropriate headers and body """ response = self.app.post("/datasources", status="*", headers=self.headers) assertions.assertMethodNotAllowed(self, response) headers = dict(response.headers) self.assertEqual(headers["Allow"], "GET")
class AppMixin(DBMixin): """ Set up to test web stuff. This sets up a db and creates a paste TestApp with the Mozpool web app, at `self.app`. This also adds some utilities. """ def setUpMixin(self): self.app = TestApp(server.get_app(self.db).wsgifunc()) def post_json(self, url, body, **kwargs): return self.app.post(url, headers={"Content-Type": "application/json"}, params=json.dumps(body), **kwargs) def check_json_result(self, r): """Verify a JSON result and return the unserialized data.""" self.assertEqual((200, 'application/json; charset=utf-8'), (r.status, r.header('Content-Type'))) return json.loads(r.body)
def test_location_post(self): middleware = [] testApp = TestApp(app.wsgifunc(*middleware)) ap_1 = {"SSID": "MPS01", "level": -67, "BSSID": "b4:b5:2f:4d:51:10"} ap_2 = {"SSID": "MPS02", "level": -56, "BSSID": "b4:b5:2f:4d:51:11"} ap_3 = {"SSID": "MPS03", "level": -40, "BSSID": "b4:b5:2f:4d:c1:90"} ap_4 = {"SSID": "MPS04", "level": -20, "BSSID": "b4:b5:2f:4d:c1:91"} # ap_mps01 = {"SSID": "MPS01", "level": -67, "BSSID": "28:2c:b2:5a:8c:be"} # ap_mps02 = {"SSID": "MPS02", "level": -56, "BSSID": "28:2c:b2:5a:6b:2c"} # ap_43 = {"SSID": "AP43", "level": -40, "BSSID": "b4:b5:2f:4d:c0:20"} req = {} # req["APInfo"] = [ap_mps01, ap_mps02, ap_43] req["APInfo"] = [ap_1, ap_2, ap_3, ap_4] r = testApp.post('/location', repr(req)) assert_equal(r.status, 200) r.mustcontain('"Location": "TV"')
def test_basic_post(self, logging_info): # what the middleware app does is that it creates a class based on # another and sets an attribute called `cls` class MadeUp(middleware_app.ImplementationWrapper): cls = AuxImplementation3 all_services = {} config = DotDict(logger=logging, web_server=DotDict(ip_address="127.0.0.1", port="88888")) server = CherryPy(config, (("/aux/(.*)", MadeUp),)) testapp = TestApp(server._wsgi_func) response = testapp.post("/aux/") eq_(response.status, 200) eq_(json.loads(response.body), {"age": 100}) logging_info.assert_called_with("Running AuxImplementation3") response = testapp.get("/aux/", expect_errors=True) eq_(response.status, 405)
class TestDELETE(): def setUp(self): middleware = [] self.client = TestApp(app.wsgifunc(*middleware)) def test_delete_a_key_value(self): url_995 = ''.join([controller, 'c995']) self.client.post(url_995, "should have a deleted flag") self.client.delete(url_995, status=202) self.client.get(url_995, status=404) def test_cannot_delete_a_non_existing_key_value(self): url_xyz = ''.join([controller, 'cxyz']) self.client.delete(url_xyz, status=404) def test_delete_and_immediately_insert_a_key_value(self): url_885 = ''.join([controller, 'c885']) self.client.post(url_885, "will be deleted and over written") self.client.delete(url_885, status=202) self.client.post(url_885, "deleted existing. and written a new value") r2 = self.client.get(url_885) r2.mustcontain("deleted existing. and written a new value")
class AnnotationsHandlerTest(unittest.TestCase): def setUp(self): self.headers = getDefaultHTTPHeaders(htm.it.app.config) self.app = TestApp(annotations_api.app.wsgifunc()) self.annotation = { "uid": "f4aa70b361f04036b0b39530900f38fa", "timestamp": "2014-01-25 05:00:00", "created": "2014-01-25 07:14:06", "device": "device1", "user": "******", "server": "htm-itdb2", "message": "My annotation", "data": None } # Prepare request as annotation without "uid" or "created" fields self.request = self.annotation.copy() del self.request["uid"] del self.request["created"] @patch("htm.it.app.repository.getAnnotationById") def testGETAnnotationById(self, getAnnotationById, _): """ Test Get Annotation Request:: GET /_annotations/{uid} Response:: HTTP 200 Ok [ { "uid": "2a123bb1dd4d46e7a806d62efc29cbb9", "device", "1231AC32FE", "created":"2013-08-27 16:46:51", "timestamp":"2013-08-27 16:45:00", "user":"******", "server":" AWS/EC2/i-53f52b67", "message":" The CPU Utilization was high ...", "data": { Optional JSON Object } } ] """ getAnnotationById.return_value = self.annotation response = self.app.get("/%s" % self.annotation["uid"], headers=self.headers) self.assertEqual(response.status, 200) actual = json.loads(response.body) expected = json.loads(app_utils.jsonEncode(self.annotation)) self.assertDictEqual(expected, actual[0]) @patch("htm.it.app.repository.getAnnotationById") def testGETAnnotationByIdNotFound(self, getAnnotationById, _): """ Test Get Annotation for unknown uid Request:: GET /_annotations/{uid} Response:: HTTP 404 Not Found """ getAnnotationById.side_effect = app_exceptions.ObjectNotFoundError with self.assertRaises(AppError) as e: self.app.get("/dummy", headers=self.headers) self.assertIn("Bad response: 404 Not Found", str(e.exception)) @patch("htm.it.app.repository.getAnnotations") def testGetAnnotations(self, getAnnotations, _): """ Test Get Annotation Request:: GET /_annotations?device={device}&user={user}&server={server} &from={from}&to={to} Response:: HTTP 200 Ok [ { "uid": "2a123bb1dd4d46e7a806d62efc29cbb9", "device", "1231AC32FE", "created":"2013-08-27 16:46:51", "timestamp":"2013-08-27 16:45:00", "user":"******", "server":" AWS/EC2/i-53f52b67", "message":" The CPU Utilization was high ...", "data": { Optional JSON Object } }, ... ] """ getAnnotations.return_value = [self.annotation] response = self.app.get("?%s=%s" % ("server", "dummy"), headers=self.headers) self.assertEqual(response.status, 200) actual = json.loads(response.body) expected = json.loads(app_utils.jsonEncode(self.annotation)) self.assertDictEqual(expected, actual[0]) @patch("htm.it.app.repository.deleteAnnotationById") def testDeleteAnnotationNotFound(self, deleteAnnotationById, _): """ Test Delete unknown Annotation Request:: DELETE /_annotations/{uid} Response:: HTTP 404 Not Found """ deleteAnnotationById.side_effect = app_exceptions.ObjectNotFoundError with self.assertRaises(AppError) as e: self.app.delete("/dummy", headers=self.headers) self.assertIn("Bad response: 404 Not Found", str(e.exception)) @patch("htm.it.app.repository.deleteAnnotationById") def testDeleteAnnotation(self, deleteAnnotationById, _): """ Test Delete Annotation Request:: DELETE /_annotations/{uid} Response:: HTTP 204 No Content """ response = self.app.delete("/%s" % self.annotation["uid"], headers=self.headers) self.assertEqual(response.status, 204) self.assertFalse(response.body) self.assertTrue(deleteAnnotationById.called) @patch("htm.it.app.repository.addAnnotation") def testAddAnnotation(self, addAnnotation, _): """ Test Create new Annotation Request:: POST /_annotations { "device", "1231AC32FE", "timestamp":"2013-08-27 16:45:00", "user":"******", "server":" AWS/EC2/i-53f52b67", "message":" The CPU Utilization was high ...", "data": { Optional JSON Object } } Response:: HTTP Status 201 Created { "uid": "2a123bb1dd4d46e7a806d62efc29cbb9", "device", "1231AC32FE", "created":"2013-08-27 16:46:51", "timestamp":"2013-08-27 16:45:00", "user":"******", "server":" AWS/EC2/i-53f52b67", "message":" The CPU Utilization was high ...", "data": { Optional JSON Object } } """ addAnnotation.return_value = self.annotation response = self.app.post("", app_utils.jsonEncode(self.request), headers=self.headers) self.assertEqual(response.status, 201) actual = json.loads(response.body) # The result should contain new "uid" and "created" fields self.assertIn("uid", actual) self.assertIn("created", actual) # All the other fields should match request self.assertDictContainsSubset(self.request, actual) def testAddAnnotationIncomplete(self, _): """ Test Failed to Create incomplete Annotation Response:: HTTP Status 400 Missing "field" in request """ # Annotation without timestamp badRequest = self.request.copy() del badRequest["timestamp"] with self.assertRaises(AppError) as e: self.app.post("", app_utils.jsonEncode(badRequest), headers=self.headers) error = e.exception self.assertRegexpMatches(error.message, "Missing 'timestamp' in request") # Annotation without device badRequest = self.request.copy() del badRequest["device"] with self.assertRaises(AppError) as e: self.app.post("", app_utils.jsonEncode(badRequest), headers=self.headers) error = e.exception self.assertRegexpMatches(error.message, "Missing 'device' in request") # Annotation without server badRequest = self.request.copy() del badRequest["server"] with self.assertRaises(AppError) as e: self.app.post("", app_utils.jsonEncode(badRequest), headers=self.headers) error = e.exception self.assertRegexpMatches(error.message, "Missing 'server' in request") # Annotation without user badRequest = self.request.copy() del badRequest["user"] with self.assertRaises(AppError) as e: self.app.post("", app_utils.jsonEncode(badRequest), headers=self.headers) error = e.exception self.assertRegexpMatches(error.message, "Missing 'user' in request") # Annotation without data and message badRequest = self.request.copy() del badRequest["message"] del badRequest["data"] with self.assertRaises(AppError) as e: self.app.post("", app_utils.jsonEncode(badRequest), headers=self.headers) error = e.exception self.assertRegexpMatches( error.message, "Annotation must contain either 'message' or 'data'") def testAddAnnotationInvalidJSON(self, _): """ Test failed to create annotation with invalid JSON argument Response:: HTTP Status 400 Invalid JSON in request """ badRequest = "{Not a JSON Request}" with self.assertRaises(AppError) as e: self.app.post("", badRequest, headers=self.headers) error = e.exception self.assertRegexpMatches(error.message, "Invalid JSON in request")
class InstancesApiSingleTest(unittest.TestCase): """ Integration tests methods for single instance """ def setUp(self): self.app = TestApp(instances_api.app.wsgifunc()) self.headers = getDefaultHTTPHeaders(grok.app.config) @ManagedTempRepository("InstancesApiSingleInstance") def testLifecycleForSingleInstance(self): """ Test for Get '/_instances' response is validated for appropriate headers, body and status Make sure app returns empty list at initial step Test for post '/_instances/region/namespace/instanceId' response is validated for appropriate headers, body and status Invoke post with valid instanceId Test for get '/_instances/{instanceId}' response is validated for appropriate headers, body and status Check if you can invoke get on previously post'ed instance Instance Test for delete '/_instances/region/namespace/instanceId' response is validated for appropriate headers, body and status This invokes delete call on previously monitored instance Test for get '/_instances/{instanceId}' response is validated for appropriate headers, body and status This invokes get call with instanceId which is deleted from monitored list """ # check initial empty response with get request initialGetResponse = self.app.get("", headers=self.headers) assertions.assertSuccess(self, initialGetResponse) initialGetResult = app_utils.jsonDecode(initialGetResponse.body) self.assertItemsEqual(initialGetResult, []) # Post single instance details to add under monitor region = VALID_EC2_INSTANCES["jenkins-master"]["region"] namespace = "EC2" instanceId = "%s/AWS/%s/%s" % ( region, namespace, VALID_EC2_INSTANCES["jenkins-master"]["instanceId"]) postResponse = self.app.post("/" + instanceId, headers=self.headers) assertions.assertSuccess(self, postResponse) postResult = app_utils.jsonDecode(postResponse.body) self.assertIsInstance(postResult, dict) self.assertEqual(postResult, {"result": "success"}) # Verify that instance is successfully added under monitor getPostCheckResponse = self.app.get("", headers=self.headers) assertions.assertSuccess(self, getPostCheckResponse) getPostCheckResult = app_utils.jsonDecode(getPostCheckResponse.body) self.assertEqual(len(getPostCheckResult), 1) instanceResult = getPostCheckResult[0] self.assertEqual(region, instanceResult["location"]) self.assertTrue(instanceId, instanceResult["server"]) # Delete instance from monitor deleteResponse = self.app.delete("/", headers=self.headers, params=json.dumps([instanceId])) assertions.assertDeleteSuccessResponse(self, deleteResponse) # Check get reponse to confirm that instance has been deleted successfully getPostDeleteResponse = self.app.get("", headers=self.headers) postResult = app_utils.jsonDecode(getPostDeleteResponse.body) self.assertEqual(postResult, []) # TODO: Assertion pending MER-1170 #assertions.assertNotFound(self, getPostDeleteResponse) #self.assertEqual("Instance %s was not found" % instanceId, # getPostDeleteResponse.body) @ManagedTempRepository("InstancesApiSingleInstance") def testPostWithInvalidRegion(self): """ Test for post '/_instances/region/namespace/instanceId' response is validated for appropriate headers, body and status Invoke Api call with region that does not exists """ region = "fake-region" namespace = "EC2" instanceId = VALID_EC2_INSTANCES["jenkins-master"]["instanceId"] response = self.app.post("/%s/AWS/%s/%s" % (region, namespace, instanceId), headers=self.headers, status="*") assertions.assertBadRequest(self, response, "json") self.assertIn("Not supported.", response.body) @ManagedTempRepository("InstancesApiSingleInstance") def testPostWithInvalidNamespace(self): """ Test for post '/_instances/region/namespace/instanceId' response is validated for appropriate headers, body and status Invoke Api call with namespace that does not exists """ region = "us-west-2" namespace = "foo" instanceId = VALID_EC2_INSTANCES["jenkins-master"]["instanceId"] response = self.app.post("/%s/AWS/%s/%s" % (region, namespace, instanceId), headers=self.headers, status="*") assertions.assertBadRequest(self, response, "json") self.assertIn("Not supported.", response.body) @ManagedTempRepository("InstancesApiSingleInstance") def testPostWithInvalidServiceName(self): """ Test for post '/_instances/region/namespace/instanceId' response is validated for appropriate headers, body and status Invoke Api call with namespace that does not exists. Specifically replace AWS with some invalid string making namespace invalid """ region = "us-west-2" namespace = "EC2" instanceId = VALID_EC2_INSTANCES["jenkins-master"]["instanceId"] response = self.app.post("/%s/foo/%s/%s" % (region, namespace, instanceId), headers=self.headers, status="*") assertions.assertBadRequest(self, response, "json") self.assertIn("Not supported.", response.body) @ManagedTempRepository("InstancesApiSingleInstance") def testPostWithInvalidInstanceId(self): """ Test for post '/_instances/region/namespace/instanceId' response is validated for appropriate headers, body and status Invoke Api call with instanceId that does not exists Expect a 200 OK even when attempting to POST to an invalid instance, this saves the overhead of asking AWS if we're dealing with a valid instance every POST. We expect the CLI user to know what instance ID he/she is looking for. """ region = "us-west-2" namespace = "EC2" instanceId = "abcd1234" response = self.app.post("/%s/AWS/%s/%s" % (region, namespace, instanceId), headers=self.headers, status="*") assertions.assertSuccess(self, response) @ManagedTempRepository("InstancesApiSingleInstance") def testPostInstanceIdToIncorrectNamespace(self): """ Test for post '/_instances/region/namespace/instanceId' response is validated for appropriate headers, body and status Invoke Api call with instance to incorrect namespace. e.g post grok-docs-elb to AWS/EC2 Expect a 200 OK even when attempting to POST an instance to the wrong namespace, this saves the overhead of asking AWS if we're dealing with a valid instance in the given namespace with every POST request. We expect the CLI user to know what instance ID he/she is looking for. """ region = "us-west-2" namespace = "EC2" instanceId = "grok-docs-elb" response = self.app.post("/%s/AWS/%s/%s" % (region, namespace, instanceId), headers=self.headers, status="*") assertions.assertSuccess(self, response) @ManagedTempRepository("InstancesApiSingleInstance") def testPostWithoutInstanceId(self): """ Test for post '/_instances/region/namespace/instanceId' without instanceId response is validated for appropriate headers, body and status This invokes post call with without instanceId """ response = self.app.post("/us-west-2/AWS/EC2/", headers=self.headers, status="*") assertions.assertBadRequest(self, response, "json") self.assertIn("Invalid request", response.body)
class TestModelHandler(unittest.TestCase): """ Integration test for Model Handler API """ def setUp(self): self.app = TestApp(models_api.app.wsgifunc()) self.headers = getDefaultHTTPHeaders(htm.it.app.config) data = open(os.path.join(htm.it.app.HTM_IT_HOME, "tests/py/data/app/webservices/models_api_integration_test.json")).read() self.modelsTestData = json.loads(data) def _checkCreateModelResult(self, postResult, metricSpec): dimensions = metricSpec["dimensions"] expectedRegion = metricSpec["region"] expectedNamespace = metricSpec["namespace"] expectedInstanceId = dimensions["InstanceId"] self.assertItemsEqual(postResult.keys(), self.modelsTestData["create_response"].keys()) self.assertEqual(postResult["server"], "%s/%s/%s" % (expectedRegion, expectedNamespace, expectedInstanceId)) self.assertEqual(postResult["location"], expectedRegion) self.assertEqual(postResult["name"], expectedNamespace + "/" + metricSpec["metric"]) def testCompleteModelsApiLifecycle(self): """ Happy path testing for the route "/_models" """ # get all models in the system when there are no models # expected response is [] response = self.app.get("/", headers=self.headers) assertions.assertSuccess(self, response) allModelsResult = utils.jsonDecode(response.body) self.assertEqual(len(allModelsResult), 0) self.assertIsInstance(allModelsResult, list) data = self.modelsTestData["create_data"] # create a model using PUT; # Any HTTP POST call is forwarded to HTTP PUT in the Model API. # def POST(self): # return self.PUT() # The tests are just calling PUT. # TODO: wouldn't POST be a better method to test in that case, since it # would exercise both POST and PUT? response = self.app.put("/", utils.jsonEncode(data), headers=self.headers) assertions.assertSuccess(self, response, code=201) postResult = utils.jsonDecode(response.body) self.assertEqual(len(postResult), 1) self._checkCreateModelResult(postResult[0], data) # get model that was previously created uid = postResult[0]["uid"] response = self.app.get("/%s" % uid, headers=self.headers) assertions.assertSuccess(self, response) getModelResult = utils.jsonDecode(response.body) self.assertItemsEqual(getModelResult[0].keys(), self.modelsTestData["get_response"].keys()) # get all models in the system response = self.app.get("/", headers=self.headers) assertions.assertSuccess(self, response) allModelsResult = utils.jsonDecode(response.body) self.assertItemsEqual(allModelsResult[0].keys(), self.modelsTestData["get_response"].keys()) self.assertItemsEqual(allModelsResult[0].keys(), self.modelsTestData["get_response"].keys()) self.assertEqual(len(allModelsResult), 1) # Repeat the request to monitor same metric and verify that it returns the # same model uid instead of creating a new one response = self.app.post("/", utils.jsonEncode(data), headers=self.headers) assertions.assertSuccess(self, response, code=201) postResult = utils.jsonDecode(response.body) self.assertEqual(postResult[0]["uid"], uid) self.assertEqual(len(postResult), 1) self._checkCreateModelResult(postResult[0], data) # Compare http and https responses for all models for x in range(3): https_response = requests.get("https://localhost/_models", headers=self.headers, verify=False) http_response = requests.get("http://localhost/_models", headers=self.headers) self.assertEqual(http_response.status_code, 200) self.assertEqual(https_response.status_code, 200) httpsData = json.loads(https_response.text) try: self.assertIsInstance(httpsData, list) self.assertTrue(httpsData) for item in httpsData: self.assertIn("status", item) self.assertIn("last_rowid", item) self.assertIn("display_name", item) self.assertIn("uid", item) self.assertIn("datasource", item) httpData = json.loads(http_response.text) self.assertIsInstance(httpData, list) self.assertTrue(httpData) for item in httpData: self.assertIn("status", item) self.assertIn("last_rowid", item) self.assertIn("display_name", item) self.assertIn("uid", item) self.assertIn("datasource", item) self.assertEqual(http_response.text, https_response.text) break except AssertionError: time.sleep(10) else: self.fail("Unable to synchronize http and https responses.") # Compare http and https response for all models data https_response = requests.get("https://localhost/_models/data", headers=self.headers, verify=False) http_response = requests.get("http://localhost/_models/data", headers=self.headers) self.assertEqual(http_response.status_code, 200) self.assertEqual(https_response.status_code, 200) httpData = json.loads(http_response.text) self.assertIsInstance(httpData, dict) self.assertItemsEqual(httpData.keys(), ["metrics", "names"]) self.assertItemsEqual(httpData["names"], ["timestamp", "value", "anomaly_score", "rowid"]) httpsData = json.loads(https_response.text) self.assertIsInstance(httpsData, dict) self.assertItemsEqual(httpsData.keys(), ["metrics", "names"]) self.assertItemsEqual(httpsData["names"], ["timestamp", "value", "anomaly_score", "rowid"]) # delete the model that was created earlier response = self.app.delete("/%s" % uid, headers=self.headers) assertions.assertDeleteSuccessResponse(self, response) @ManagedTempRepository("TestModelHandler") def testMonitorMetricViaModelSpec(self): """ Happy path testing for the route "/_models" with new modelSpec format """ modelSpec = { "datasource": "cloudwatch", "metricSpec": { "region": "us-west-2", "namespace": "AWS/EC2", "metric": "CPUUtilization", "dimensions": { "InstanceId": "i-12d67826" } }, "modelParams": { "min": 0, # optional "max": 100 # optional } } # create a model response = self.app.post("/", utils.jsonEncode(modelSpec), headers=self.headers) assertions.assertSuccess(self, response, code=201) postResult = utils.jsonDecode(response.body) self.assertEqual(len(postResult), 1) self._checkCreateModelResult(postResult[0], modelSpec["metricSpec"]) # get model that was previously created uid = postResult[0]["uid"] response = self.app.get("/%s" % uid, headers=self.headers) assertions.assertSuccess(self, response) getModelResult = utils.jsonDecode(response.body) self.assertItemsEqual(getModelResult[0].keys(), self.modelsTestData["get_response"].keys()) # get all models in the system response = self.app.get("/", headers=self.headers) assertions.assertSuccess(self, response) allModelsResult = utils.jsonDecode(response.body) self.assertItemsEqual(allModelsResult[0].keys(), self.modelsTestData["get_response"].keys()) self.assertItemsEqual(allModelsResult[0].keys(), self.modelsTestData["get_response"].keys()) self.assertEqual(len(allModelsResult), 1) # Repeat the request to monitor same metric and verify that it returns the # same model uid instead of creating a new one response = self.app.post("/", utils.jsonEncode(modelSpec), headers=self.headers) assertions.assertSuccess(self, response, code=201) postResult = utils.jsonDecode(response.body) self.assertEqual(postResult[0]["uid"], uid) self.assertEqual(len(postResult), 1) self._checkCreateModelResult(postResult[0], modelSpec["metricSpec"]) # Unmonitor the metric response = self.app.delete("/%s" % uid, headers=self.headers) assertions.assertDeleteSuccessResponse(self, response) @ManagedTempRepository("TestModelHandler") def testGetNonExistentModelUID(self): """ Test for the get call with non-existent Model uid. """ response = self.app.get("/f00bar", status="*", headers=self.headers) assertions.assertObjectNotFoundError(self, response) @ManagedTempRepository("TestModelHandler") def testDeleteNonExistentModelUID(self): """ Test for the delete call with non-existent Model uid. """ response = self.app.delete("/f00bar", status="*", headers=self.headers) assertions.assertObjectNotFoundError(self, response) @ManagedTempRepository("TestModelHandler") def testInvalidJsonModelsApi(self): """ Test for the invalid json. """ data = self.modelsTestData["create_data"] response = self.app.put("/", data, status="*", headers=self.headers) self.assertIn("No JSON object could be decoded", response.body) assertions.assertInvalidArgumentsError(self, response, "json") @ManagedTempRepository("TestModelHandler") def testCreateModelWithEmptyRegionArg(self): """ Test for the missing empty datasource field in json. """ data = utils.jsonEncode(self.modelsTestData["create_empty_region"]) response = self.app.put("/", data, status="*", headers=self.headers) assertions.assertInvalidArgumentsError(self, response, "json") @ManagedTempRepository("TestModelHandler") def testCreateModelWithInvalidRegionKey(self): """ Test for the invalid region field in json. """ data = utils.jsonEncode(self.modelsTestData["create_invalid_region_key"]) response = self.app.put("/", data, status="*", headers=self.headers) assertions.assertInvalidArgumentsError(self, response, "json") @ManagedTempRepository("TestModelHandler") def testCreateModelWithEmptyDatasourceArg(self): """ Test for the missing empty datasource field in json. """ data = utils.jsonEncode(self.modelsTestData["create_empty_ds_data"]) response = self.app.put("/", data, status="*", headers=self.headers) assertions.assertInvalidArgumentsError(self, response, "json") @ManagedTempRepository("TestModelHandler") def testCreateModelWithInvalidDatasourceArg(self): """ Test for the invalid metric field in json. """ data = utils.jsonEncode(self.modelsTestData["create_invalid_ds_data"]) response = self.app.put("/", data, status="*", headers=self.headers) assertions.assertInvalidArgumentsError(self, response, "json") @ManagedTempRepository("TestModelHandler") def testCreateModelWithEmptyMetricArg(self): """ Test for the missing empty metric field in json. """ data = utils.jsonEncode(self.modelsTestData["create_empty_metric_data"]) response = self.app.put("/", data, status="*", headers=self.headers) assertions.assertInvalidArgumentsError(self, response, "json") @ManagedTempRepository("TestModelHandler") def testCreateModelWithInvalidMetricArg(self): """ Test for the invalid metric field in json. """ data = utils.jsonEncode(self.modelsTestData["create_invalid_metric_data"]) response = self.app.put("/", data, status="*", headers=self.headers) assertions.assertBadRequest(self, response, "json") response = self.app.get("/", headers=self.headers) self.assertFalse(json.loads(response.body), "Model actually created with invalid metric") @ManagedTempRepository("TestModelHandler") def testCreateModelWithEmptyDimensionsArg(self): """ Test for the missing empty dimension field in json. """ data = utils.jsonEncode(self.modelsTestData["create_empty_dimension_data"]) response = self.app.put("/", data, status="*", headers=self.headers) assertions.assertInvalidArgumentsError(self, response, "json") @ManagedTempRepository("TestModelHandler") def testCreateModelWithInvalidDimensionsArg(self): """ Test for the invalid dimension field in json. """ data = utils.jsonEncode( self.modelsTestData["create_invalid_dimension_data"]) response = self.app.put("/", data, status="*", headers=self.headers) assertions.assertBadRequest(self, response, "json") response = self.app.get("/", headers=self.headers) self.assertFalse(json.loads(response.body), "Model actually created with invalid dimension") @ManagedTempRepository("TestModelHandler") def testCreateModelWithEmptyInstanceIdArg(self): """ Test for the empty dimension field in json. """ data = utils.jsonEncode(self.modelsTestData["create_empty_instanceid_data"]) response = self.app.put("/", data, status="*", headers=self.headers) assertions.assertInvalidArgumentsError(self, response, "json") @ManagedTempRepository("TestModelHandler") def testNoAuthHeaders(self): """ Negative test for authentication guarded route. invoke get request without passing authentication headers response is validated for appropriate headers and body """ response = self.app.get("/", status="*") assertions.assertInvalidAuthenticationResponse(self, response) @ManagedTempRepository("TestModelHandler") def testInvalidAuthHeaders(self): """ Negative test for authentication guarded route. invoke get request with invalid authentication headers response is validated for appropriate headers and body """ invalidHeaders = getInvalidHTTPHeaders() response = self.app.get("/", status="*", headers=invalidHeaders) assertions.assertInvalidAuthenticationResponse(self, response) @ManagedTempRepository("TestModelHandler") def testPutMethodWithNoData(self): """ Test making a PUT call with no data. """ response = self.app.put("/", status="*", headers=self.headers) self.assertIn("Metric data is missing", response.body) assertions.assertBadRequest(self, response)
class TestAutostacksHandler(unittest.TestCase): @classmethod def setUpClass(cls): cls.autostack = Mock(uid="blahblahblah", region="bogus", filters=jsonEncode({"tag:Name": ["Bogus"]})) cls.autostack.name = "Test" cls.jsonAutostack = jsonEncode({ "uid": "blahblahblah", "name": "Test", "region": "bogus", "filters": { "tag:Name": ["Bogus"] } }) def setUp(self): self.headers = getDefaultHTTPHeaders(htm.it.app.config) self.app = TestApp(autostacks_api.app.wsgifunc()) @patch("htm.it.app.webservices.autostacks_api.repository") def testGETAutostacks(self, repositoryMock, *_args): """ Test GETing all autostacks from autostacks API """ repositoryMock.getAutostackList.return_value = [self.autostack] response = self.app.get("/", headers=self.headers) self.assertEqual(response.status, 200) result = json.loads(response.body) self.assertDictEqual(json.loads(self.jsonAutostack), result[0]) @patch("htm.it.app.quota.repository") @patch( "htm.it.app.webservices.autostacks_api.createAutostackDatasourceAdapter" ) def testPOSTAutostacksQuota(self, adapterMock, quotaRepositoryMock, _repositoryMock): quotaRepositoryMock.getInstanceCount.return_value = 0 adapterMock.return_value.createAutostack.side_effect = QuotaError() with self.assertRaises(AppError) as e: self.app.post("/", self.jsonAutostack, headers=self.headers) self.assertIn("Bad response: 403 Forbidden", str(e.exception)) self.assertTrue(adapterMock.return_value.createAutostack.called) @patch("htm.it.app.quota.repository") @patch( "htm.it.app.webservices.autostacks_api.createAutostackDatasourceAdapter" ) def testPOSTAutostacks(self, adapterMock, quotaRepositoryMock, _repositoryMock): name = "Test" region = "Bogus" filters = {"tag:Name": ["Bogus"]} quotaRepositoryMock.getInstanceCount.return_value = 0 autostackMock = Mock() autostackMock.items.return_value = [("name", name), ("region", region), ("filters", filters)] adapterMock.return_value.createAutostack.return_value = autostackMock response = self.app.post("/", app_utils.jsonEncode({ "name": name, "region": region, "filters": filters }), headers=self.headers) self.assertEqual(response.status, 201) result = json.loads(response.body) self.assertEqual(result["name"], "Test") self.assertTrue(adapterMock.return_value.createAutostack.called) @patch( "htm.it.app.webservices.autostacks_api.createAutostackDatasourceAdapter" ) def testPOSTAutostacksNameInUse(self, createAutostackMock, _repositoryMock): createAutostackMock.side_effect = DuplicateRecordError with self.assertRaises(AppError) as cm: self.app.post("/", app_utils.jsonEncode({ "name": "Test", "region": "Bogus", "filters": ({ "tag:Name": ["Bogus"] }) }), headers=self.headers) self.assertIn( "The name you are trying to use, 'Test', is already in use " "in AWS region 'Bogus'. Please enter a unique Autostack " "name.", cm.exception.message)
class TestFluentAPI(unittest.TestCase): def setUp(self): self.app = TestApp(fluent_api.app.wsgifunc()) def _assertCORSHeaders(self, response): self.assertIn("access-control-allow-headers", response.header_dict) self.assertEqual(response.header_dict["access-control-allow-headers"], "accept, access-control-allow-origin, content-type") self.assertIn("access-control-allow-credentials", response.header_dict) self.assertEqual( response.header_dict["access-control-allow-credentials"], "true") self.assertIn("access-control-allow-headers", response.header_dict) self.assertEqual(response.header_dict["access-control-allow-origin"], "*") self.assertIn("access-control-allow-headers", response.header_dict) self.assertEqual(response.header_dict["access-control-allow-methods"], "POST") def _queryAndAssertAPI(self, model=None, dataset=None, query=""): uri = "/fluent" if model: uri = "{}/{}".format(uri, model) if dataset: uri = "{}/{}".format(uri, dataset) response = self.app.post(uri, json.dumps(query)) self.assertEqual(response.status, 200) self._assertCORSHeaders(response) # Make sure the response can be parsed as JSON body = json.loads(response.body) return body def testDefaultResponse(self): responseBody = self._queryAndAssertAPI() # Assert structure of response matches expected pattern for result in responseBody.values(): self.assertIn("text", result) self.assertIn("scores", result) self.assertIn("indices", result) # B/c no query data sent, assert specific response values self.assertEqual([0], result["scores"]) self.assertEqual(0, result["indices"][0][0]) def testQueryAModel(self): # Should use default dataset as declared in ImbuModels. Assume a # corresponding serialized CioDocumentFingerprint model exists. responseBody = self._queryAndAssertAPI(model="CioDocumentFingerprint") # Assert structure of response matches expected pattern for result in responseBody.values(): self.assertIn("text", result) self.assertIn("scores", result) self.assertIn("indices", result) self.assertIn("windowSize", result) def testQueryWithoutAModel(self): # Should use default model and dataset as declared in ImbuModels responseBody = self._queryAndAssertAPI(query="test") # Assert structure of response matches expected pattern for result in responseBody.values(): self.assertIn("text", result) self.assertIn("scores", result) self.assertIn("indices", result) self.assertIn("windowSize", result) def testDatasetList(self): response = self.app.get("/fluent/datasets") self.assertEqual(response.status, 200) self._assertCORSHeaders(response) # Make sure the response can be parsed as JSON datasets = json.loads(response.body) # Assert structure of response matches expected pattern self.assertIsInstance(datasets, list) self.assertGreaterEqual(len(datasets), 1) def testQueryADatasetModel(self): # Assume 'sample_reviews' dataset exists responseBody = self._queryAndAssertAPI(dataset="sample_reviews", model="CioDocumentFingerprint", query="test") # Assert structure of response matches expected pattern for result in responseBody.values(): self.assertIn("text", result) self.assertGreater(len(result["text"]), 0) self.assertIn("scores", result) self.assertIn("indices", result) self.assertIn("windowSize", result)
class TestCode(object): ''' This class contains methods that tests the page views and navigations inside the target page. ''' URL_DEFAULT_LOGIN = '******' URL_DEFAULT_REGISTER = '/register' URL_INDEX = '/' URL_DEFAULT_LOGOUT = '/logout' FORM_USER_LOGIN = '******' FORM_USER_LOGIN_USERNAME_LABEL = '<label for="id">User ID</label>' FORM_USER_LOGIN_USERNAME_FIELD = '<input type="text" class="form-control" ' +\ 'id="id" name="id" pattern="^[a-zA-Z0-9]+$$" ' +\ 'oninput="check(this)" autofocus required>' FORM_USER_LOGIN_PASSWORD_LABEL = '<label for="password">Password</label>' FORM_USER_LOGIN_PASSWORD_FIELD = '<input type="password" class="form-control" ' +\ 'id="password" name="password" ' +\ 'required>' FORM_USER_LOGIN_BUTTON = '<input type="submit" value="Login" ' +\ 'class="btn btn-primary">' FORM_USER_REGISTRATION = '<form id="registerForm" action="/register" method="post">' FORM_USER_REGISTRATION_USERNAME_LABEL = '<label for="id">User ID</label>' FORM_USER_REGISTRATION_USERNAME_FIELD = '<input type="text" class="form-control" ' +\ 'id="id" name="id" pattern="^[a-zA-Z0-9]+$$" ' +\ 'maxlength="9" oninput="check(this)" ' +\ 'autofocus required>' FORM_USER_REGISTRATION_PASSWORD_LABEL = '<label for="password">Password</label>' FORM_USER_REGISTRATION_PASSWORD_FIELD = '<input type="password" class="form-control"' +\ 'id="password" name="password" placeholder=' +\ '"Password" required>' FORM_USER_REGISTRATION_BUTTON = '<input type="submit" value="Create Account"' +\ 'class="btn btn-primary"' HEADER_ALREADY_LOGGED_IN = 'You have already logged in.' BUTTON_ALREADY_LOGGED_IN = '<a class="btn btn-primary" href="/">Enter</a>' SCRIPT_ACCOUNT_CREATE_SUCCESSFUL = "alert('Your account has been " +\ "created successfully. Please proceed to " +\ "login.');" SCRIPT_ACCOUNT_CREATE_UNSUCCESSFUL = "alert('The username has been " +\ "taken. Please register with a different " +\ "username.');" SCRIPT_ACCOUNT_LOGIN_UNSUCCESSFUL = "alert('Login credentials are " +\ "empty or incorrect. Please try again.');" SCRIPT_REDIRECT_TO_LOGIN = "******" SCRIPT_REDIRECT_TO_REGISTER = "window.location = '/register'" VALIDATING_TITLE = "Validating..." def __init__(self): self.middleware = None self.test_app = None def setUp(self): ''' Sets up the 'app.py' fixture, along with the important user accounts states. ''' self.middleware = [] self.test_app = TestApp(APP.wsgifunc(*self.middleware)) model.delete_admin("user") model.delete_admin("user2") self.create_dummy_user() def tearDown(self): ''' Removes any trace of dummy accounts that were present during the invocation of all the test cases and logs out if needed. ''' model.delete_admin("user") model.delete_admin("user2") self.test_app.post(self.URL_DEFAULT_LOGOUT) def create_dummy_user(self): ''' Creates the dummy valid user that will be used in this series of test cases. ''' salt = uuid.uuid4().hex hashed_password = hashlib.sha512("12345678" + salt).hexdigest() model.add_admin("user", salt, hashed_password) def test_login_valid_response(self): ''' Tests whether user can access page for showing fixed module mountings without request errors. ''' root = self.test_app.get(self.URL_DEFAULT_LOGIN) # checks if HTTP response code is 200 (= OK) assert_equal(root.status, 200) def test_redirect_to_login_response(self): ''' Tests whether user WILL be redirected from home page if user has not logged in. ''' root = self.test_app.get(self.URL_INDEX) # checks if HTTP response code is 303 (= See Other) assert_equal(root.status, 303) redirected = root.follow() assert_equal(redirected.status, 200) # Presence of these elements indicates that the request direction is correct. # Checks if page contains 'User Login' title redirected.mustcontain("User Login") def test_valid_login_submission_response(self): ''' Tests if user is redirected to index upon successful login. ''' root = self.test_app.get(self.URL_DEFAULT_LOGIN) login_form = root.forms__get()["loginForm"] login_form.__setitem__("id", "user") login_form.__setitem__("password", "12345678") response = login_form.submit() # checks if HTTP response code is 303 (= See Other) assert_equal(response.status, 303) redirected = response.follow() assert_equal(redirected.status, 200) # Presence of these elements indicates that the request direction is correct. # Checks if page contains home page's title redirected.mustcontain("Welcome to") def test_blank_username_login_submission_response(self): ''' Tests if user should fail to login if username field blank. ''' root = self.test_app.get(self.URL_DEFAULT_LOGIN) login_form = root.forms__get()["loginForm"] login_form.__setitem__("id", None) login_form.__setitem__("password", "12345678") response = login_form.submit() # checks if Validating page loaded response.mustcontain(self.VALIDATING_TITLE) assert_equal(response.status, 200) # Presence of these elements indicates that the request direction is correct. # Checks if page will redirect to /login response.mustcontain(self.SCRIPT_ACCOUNT_LOGIN_UNSUCCESSFUL) response.mustcontain(self.SCRIPT_REDIRECT_TO_LOGIN) def test_blank_password_login_submission_response(self): ''' Tests if user should fail to login if password field is blank. ''' root = self.test_app.get(self.URL_DEFAULT_LOGIN) login_form = root.forms__get()["loginForm"] login_form.__setitem__("id", "user") response = login_form.submit() # checks if Validating page loaded response.mustcontain(self.VALIDATING_TITLE) assert_equal(response.status, 200) # Presence of these elements indicates that the request direction is correct. # Checks if page will redirect to /login response.mustcontain(self.SCRIPT_ACCOUNT_LOGIN_UNSUCCESSFUL) response.mustcontain(self.SCRIPT_REDIRECT_TO_LOGIN) def test_invalid_account_login_submission_response(self): ''' Tests if user should fail to login with non-existent account. ''' root = self.test_app.get(self.URL_DEFAULT_LOGIN) login_form = root.forms__get()["loginForm"] login_form.__setitem__("id", "nonexistent") login_form.__setitem__("password", "12345678") response = login_form.submit() # checks if Validating page loaded response.mustcontain(self.VALIDATING_TITLE) assert_equal(response.status, 200) # Presence of these elements indicates that the request direction is correct. # Checks if page will redirect to /login response.mustcontain(self.SCRIPT_ACCOUNT_LOGIN_UNSUCCESSFUL) response.mustcontain(self.SCRIPT_REDIRECT_TO_LOGIN) def test_already_logged_in_response(self): ''' Tests if user should not see the login form if he has already logged in to the system. ''' root = self.test_app.get(self.URL_DEFAULT_LOGIN) login_form = root.forms__get()["loginForm"] login_form.__setitem__("id", "user") login_form.__setitem__("password", "12345678") response = login_form.submit() # checks if HTTP response code is 303 (= See Other) assert_equal(response.status, 303) redirected = response.follow() assert_equal(redirected.status, 200) # Presence of these elements indicates that the request direction is correct. # Checks if page contains home page's title redirected.mustcontain("Welcome to") login_page = redirected.goto(self.URL_DEFAULT_LOGIN, method="get") assert_equal(login_page.status, 200) login_page.mustcontain(self.HEADER_ALREADY_LOGGED_IN) login_page.mustcontain(self.BUTTON_ALREADY_LOGGED_IN) def test_valid_registration_submission_response(self): ''' Tests if user is redirected correctly upon successful registration. ''' root = self.test_app.get(self.URL_DEFAULT_REGISTER) registration_form = root.forms__get()["registerForm"] registration_form.__setitem__("id", "user2") registration_form.__setitem__("password", "12345678") response = registration_form.submit() # checks if Validating page loaded response.mustcontain(self.VALIDATING_TITLE) assert_equal(response.status, 200) # Presence of these elements indicates that the request direction is correct. # Checks if page will redirect to /login response.mustcontain(self.SCRIPT_REDIRECT_TO_LOGIN) response.mustcontain(self.SCRIPT_ACCOUNT_CREATE_SUCCESSFUL) def test_blank_username_registration_submission_response(self): ''' Tests if account registration with no username triggers validation. ''' root = self.test_app.get(self.URL_DEFAULT_REGISTER) registration_form = root.forms__get()["registerForm"] registration_form.__setitem__("id", None) registration_form.__setitem__("password", "12345678") response = registration_form.submit() # checks if HTTP response code is 303 (= See Other) assert_equal(response.status, 303) redirected = response.follow() assert_equal(redirected.status, 200) # Presence of these elements indicates that the request direction is correct. redirected.mustcontain("Account Registration") def test_blank_password_registration_submission_response(self): ''' Tests if account registration with no password triggers validation. ''' root = self.test_app.get(self.URL_DEFAULT_REGISTER) registration_form = root.forms__get()["registerForm"] registration_form.__setitem__("id", "user2") response = registration_form.submit() # checks if HTTP response code is 303 (= See Other) assert_equal(response.status, 303) redirected = response.follow() assert_equal(redirected.status, 200) # Presence of these elements indicates that the request direction is correct. redirected.mustcontain("Account Registration") def test_duplicate_username_registration_submission_response(self): ''' Tests if account registration with a pre-existing username triggers validation. ''' root = self.test_app.get(self.URL_DEFAULT_REGISTER) registration_form = root.forms__get()["registerForm"] registration_form.__setitem__("id", "user") registration_form.__setitem__("password", "12345678") response = registration_form.submit() # checks if Validating page loaded response.mustcontain(self.VALIDATING_TITLE) assert_equal(response.status, 200) # Presence of these elements indicates that the request direction is correct. # Checks if page will redirect to /login response.mustcontain(self.SCRIPT_REDIRECT_TO_REGISTER) response.mustcontain(self.SCRIPT_ACCOUNT_CREATE_UNSUCCESSFUL)
class TestRestAPI(unittest.TestCase): def setUp(self): middleware = [] self.logger = logging.getLogger('restapi') urls = karesansui.urls.urls app = web.application(urls, globals(), autoreload=False) from karesansui.app import load_sqlalchemy_karesansui,load_sqlalchemy_pysilhouette app.add_processor(load_sqlalchemy_karesansui) app.add_processor(load_sqlalchemy_pysilhouette) self.prefix = "" if karesansui.config['application.url.prefix']: mapping = (karesansui.config['application.url.prefix'], app) app = web.subdir_application(mapping) self.prefix = karesansui.config['application.url.prefix'] self.app = TestApp(app.wsgifunc(*middleware)) self.headers = {} if username != None and password != None: from base64 import b64encode base64string =b64encode("%s:%s" % (username, password)) self.headers = {"Authorization": "Basic %s" % base64string} return True def tearDown(self): return True def test_dummy(self): self.assertEqual(True,True) def test_get_index(self): r = self.app.get("%s/" % self.prefix,headers=self.headers) assert_equal(r.status, 200) r.mustcontain('Now Loading') def test_get_host_1_index(self): r = self.app.get("%s/host/1/" % self.prefix,headers=self.headers) assert_equal(r.status, 200) r.mustcontain('Now Loading') def test_get_host_1_json(self): r = self.app.get("%s/host/1.json" % self.prefix,headers=self.headers) assert_equal(r.status, 200) r.mustcontain('other_url') def test_get_host_1_guest_2_index(self): r = self.app.get("%s/host/1/guest/2/" % self.prefix,headers=self.headers) assert_equal(r.status, 200) r.mustcontain('Now Loading') def test_get_host_1_guest_2_json(self): r = self.app.get("%s/host/1/guest/2.json" % self.prefix,headers=self.headers) assert_equal(r.status, 200) r.mustcontain('other_url') def test_post_host_1_guest(self): params = {} params['domain_name'] = 'foobar' params['m_name'] = 'foobar' params['icon_filename'] = '' params['m_hypervisor'] = '1' params['note_title'] = 'title' params['note_value'] = 'value' params['tags'] = '' params['nic_type'] = 'phydev' params['phydev'] = 'xenbr0' params['virnet'] = 'default' params['xen_disk_size'] = '4096' params['xen_extra'] = '' params['xen_initrd'] = '/var/ftp/images/xen/initrd.img' params['xen_kernel'] = '/var/ftp/images/xen/vmlinuz' params['xen_mac'] = '00:16:3e:4e:4d:e2' params['xen_mem_size'] = '256' params['xen_graphics_port'] = '5910' upload_files=None r = self.app.post("%s/host/1/guest.part" % self.prefix,params=params,headers=self.headers,upload_files=upload_files) assert_equal(r.status, 200) r.mustcontain('other_url') def test_del_host_1_guest_2(self): r = self.app.delete("%s/host/1/guest/2" % self.prefix,headers=self.headers) assert_equal(r.status, 200) r.mustcontain('other_url')
class AnnotationHandlerTest(unittest.TestCase): def _createEC2Instance(self): """ Created EC2 instance to be used by the tests :return: Instance ID :rtype: str """ app = TestApp(instances_api.app.wsgifunc()) response = app.post("/" + self.instanceId, headers=self.headers) assertions.assertSuccess(self, response) result = app_utils.jsonDecode(response.body) self.assertIsInstance(result, dict) self.assertEqual(result, {"result": "success"}) def _deleteInstance(self): """ Delete test EC2 instance created by :py:meth:`_createEC2Instance` """ app = TestApp(instances_api.app.wsgifunc()) response = app.delete("/", params=json.dumps([self.instanceId]), headers=self.headers) assertions.assertSuccess(self, response) result = app_utils.jsonDecode(response.body) self.assertIsInstance(result, dict) self.assertEqual(result, {"result": "success"}) def _deleteOneMetric(self): """ Delete one metric from test EC2 instance """ app = TestApp(models_api.app.wsgifunc()) response = app.get("/", headers=self.headers) assertions.assertSuccess(self, response) result = app_utils.jsonDecode(response.body) self.assertIsInstance(result, list) app.delete("/" + result[0]['uid'], headers=self.headers) def setUp(self): self.headers = getDefaultHTTPHeaders(app_config) self.invalidHeaders = getInvalidHTTPHeaders() self.app = TestApp(annotations_api.app.wsgifunc()) self.annotation = { "uid": "f4aa70b361f04036b0b39530900f38fa", "timestamp": "2014-01-25 05:00:00", "created": "2014-01-25 07:14:06", "device": "device1", "user": "******", "server": "us-west-2/AWS/EC2/i-f52075fe", "message": "My annotation", "data": None } self.instanceId = "%s/AWS/EC2/%s" % ( VALID_EC2_INSTANCES["region"], VALID_EC2_INSTANCES["instanceId"]) # Prepare request as annotation without "uid" or "created" fields self.request = self.annotation.copy() self.request["server"] = self.instanceId del self.request["uid"] del self.request["created"] @ManagedTempRepository("Lifecycle") def testAnnotationLifecycle(self): """ **Happy Path** * Make sure annotation was successfully created and all fields were initialized. * Make sure user can get annotation by ID and fail (Not Found) if he uses the wrong ID * Make sure user can get annotations by device and receive an empty array if he uses the wrong device * Make sure user can get annotations by instance and receive an empty array if he uses the wrong instance * Make sure user can get annotation by date and receive an empty array if he uses dates out of range * Make sure user can delete annotations """ # Create Instance before annotation self._createEC2Instance() # Create Annotation response = self.app.post("", app_utils.jsonEncode(self.request), headers=self.headers) self.assertEqual(response.status, 201) # Use this newly created annotation as expected annotation from now on expectedAnnotation = app_utils.jsonDecode(response.body) # The result should contain new "uid" and "created" fields self.assertIn("uid", expectedAnnotation) self.assertIn("created", expectedAnnotation) # All the other fields should match request self.assertDictContainsSubset(self.request, expectedAnnotation) # Get Annotation By ID response = self.app.get("/" + expectedAnnotation["uid"], headers=self.headers) actual = app_utils.jsonDecode(response.body) self.assertDictEqual(expectedAnnotation, actual[0]) # Get Annotation with wrong ID with self.assertRaises(AppError) as e: response = self.app.get("/dummy", headers=self.headers) self.assertIn("Bad response: 404 Not Found", str(e.exception)) # Get all annotations response = self.app.get("/", headers=self.headers) actual = app_utils.jsonDecode(response.body) self.assertItemsEqual([expectedAnnotation], actual) # Get Annotations by Device response = self.app.get("/", {"device": self.request["device"]}, headers=self.headers) actual = app_utils.jsonDecode(response.body) self.assertDictEqual(expectedAnnotation, actual[0]) # Get Annotations with wrong Device response = self.app.get("/", {"device": "dummy"}, headers=self.headers) actual = app_utils.jsonDecode(response.body) self.assertTrue(len(actual) == 0) # Get Annotations by server response = self.app.get("/", {"server": self.request["server"]}, headers=self.headers) actual = app_utils.jsonDecode(response.body) self.assertDictEqual(expectedAnnotation, actual[0]) # Get Annotations with wrong server response = self.app.get("/", {"server": "dummy"}, headers=self.headers) actual = app_utils.jsonDecode(response.body) self.assertTrue(len(actual) == 0) # Get Annotations by date response = self.app.get("/", {"from": "2014-01-01 00:00:00"}, headers=self.headers) actual = app_utils.jsonDecode(response.body) self.assertDictEqual(expectedAnnotation, actual[0]) response = self.app.get("/", {"from": self.request["timestamp"]}, headers=self.headers) actual = app_utils.jsonDecode(response.body) self.assertDictEqual(expectedAnnotation, actual[0]) response = self.app.get("/", {"to": self.request["timestamp"]}, headers=self.headers) actual = app_utils.jsonDecode(response.body) self.assertDictEqual(expectedAnnotation, actual[0]) response = self.app.get("/", {"from": "2014-01-01 00:00:00", "to": "2014-12-31 00:00:00"}, headers=self.headers) actual = app_utils.jsonDecode(response.body) self.assertDictEqual(expectedAnnotation, actual[0]) # Get Annotations with date out of range response = self.app.get("/", {"from": "2014-12-31 00:00:00"}, headers=self.headers) actual = app_utils.jsonDecode(response.body) self.assertTrue(len(actual) == 0) response = self.app.get("/", {"to": "2014-01-01 00:00:00"}, headers=self.headers) actual = app_utils.jsonDecode(response.body) self.assertTrue(len(actual) == 0) # Delete annotation with wrong ID with self.assertRaises(AppError) as e: self.app.delete("/dummy", headers=self.headers) self.assertIn("Bad response: 404 Not Found", str(e.exception)) # Make sure no annotation was deleted response = self.app.get("/", headers=self.headers) actual = app_utils.jsonDecode(response.body) self.assertItemsEqual([expectedAnnotation], actual) # Delete annotation response = self.app.delete("/" + expectedAnnotation["uid"], headers=self.headers) self.assertEqual(response.status, 204) self.assertFalse(response.body) # Make sure annotation was deleted response = self.app.get("/", headers=self.headers) actual = app_utils.jsonDecode(response.body) self.assertTrue(len(actual) == 0) @ManagedTempRepository("DataIntegrity") def testAnnotationDataIntegrity(self): """ **Test Required Fields** * Make sure user is not allowed to add annotations without device * Make sure user is not allowed to add annotations without timestamp * Make sure user is not allowed to add annotations without instance * Make sure user is not allowed to add annotations with invalid/unknown instance * Do not delete annotations when metric is deleted * Delete annotations when instance is deleted """ # Create Instance before annotation self._createEC2Instance() # Create request without "device" req = self.request.copy() del req["device"] with self.assertRaises(AppError): self.app.post("", app_utils.jsonEncode(req), headers=self.headers) # Create request without "timestamp" req = self.request.copy() del req["timestamp"] with self.assertRaises(AppError): self.app.post("", app_utils.jsonEncode(req), headers=self.headers) # Create request without "instance" req = self.request.copy() del req["server"] with self.assertRaises(AppError): self.app.post("", app_utils.jsonEncode(req), headers=self.headers) # Create request with invalid/unknown "instance" req = self.request.copy() req["server"] = "dummy" with self.assertRaises(AppError): self.app.post("", app_utils.jsonEncode(req), headers=self.headers) # Create request without "message" and "data" req = self.request.copy() del req["message"] del req["data"] with self.assertRaises(AppError): self.app.post("", app_utils.jsonEncode(req), headers=self.headers) # Add annotation response = self.app.post("", app_utils.jsonEncode(self.request), headers=self.headers) self.assertEqual(response.status, 201) # Use this newly created annotation as expected annotation from now on expectedAnnotation = app_utils.jsonDecode(response.body) # Do not delete annotations when metric is deleted # Delete metric self._deleteOneMetric() # Make sure no annotation was deleted response = self.app.get("/", headers=self.headers) actual = app_utils.jsonDecode(response.body) self.assertItemsEqual([expectedAnnotation], actual) # Delete annotations when instance is deleted self._deleteInstance() # Make sure annotation was deleted response = self.app.get("/", headers=self.headers) actual = app_utils.jsonDecode(response.body) self.assertTrue(len(actual) == 0) @ManagedTempRepository("Security") def testAnnotationSecurity(self): """ **Test Security** * Make sure user is unable to add annotation using invalid key * Make sure user is unable to delete annotation using invalid key * Make sure user is unable to get annotation using invalid key """ # Create Instance before annotation self._createEC2Instance() # Create single annotation for testing response = self.app.post("", app_utils.jsonEncode(self.request), headers=self.headers) expectedAnnotation = app_utils.jsonDecode(response.body) # Make sure user is unable to add annotation using invalid key with self.assertRaises(AppError): self.app.post("", app_utils.jsonEncode(self.request), headers=self.invalidHeaders) # Make sure user is unable to get annotation using invalid key with self.assertRaises(AppError): self.app.get("/", headers=self.invalidHeaders) with self.assertRaises(AppError): self.app.get("/", {"device": self.request["device"]}, headers=self.invalidHeaders) with self.assertRaises(AppError): self.app.get("/" + expectedAnnotation["uid"], headers=self.invalidHeaders) # Make sure user is unable to delete annotation using invalid key with self.assertRaises(AppError): self.app.delete("/" + expectedAnnotation["uid"], headers=self.invalidHeaders)
class TestModelHandler(unittest.TestCase): @classmethod def setUpClass(cls): cls.model_list = json.load(open(os.path.join(grok.app.GROK_HOME, "tests/py/data/app/webservices/models_list.json"))) def setUp(self): self.headers = getDefaultHTTPHeaders(grok.app.config) self.app = TestApp(models_api.app.wsgifunc()) metric = Mock(uid="cebe9fab-f416-4845-8dab-02d292244112", datasource="cloudwatch", description="The number of database connections in use by " "Amazon RDS database", server="grokdb2", location="us-east-1", parameters=app_utils.jsonEncode( {"region":"us-east-1", "DBInstanceIdentifier":"grokdb2"}), status=1, message=None, collector_error=None, last_timestamp="2013-08-15 21:25:00", poll_interval=60, tag_name=None, model_params=None, last_rowid=20277) metric.name = "AWS/RDS/DatabaseConnections" self.metric = metric @patch.object(repository, 'getAllModels', autospec=True) def testModelHandlerListModelsEmptyResponse(self, getAllModelsMock, _engineMock, *args): getAllModelsMock.return_value = [] response = self.app.get("", headers=self.headers) assertions.assertSuccess(self, response) result = jsonDecode(response.body) self.assertEqual(result, []) @patch.object(repository, 'getAllModels', autospec=True) def testModelHandlerListModelsWithSlashEmptyResponse(self, getAllModelsMock, _engineMock, *args): getAllModelsMock.return_value = [] response = self.app.get("/", headers=self.headers) assertions.assertSuccess(self, response) result = jsonDecode(response.body) self.assertEqual(result, []) @patch("grok.app.webservices.models_api.repository", autospec=True) @patch("grok.app.webservices.models_api.getMetricDisplayFields") def testModelHandlerListModelsWithSlashValidResponse( self, getMetricDisplayFieldsMock, repositoryMock, _engineMock, *args): cols = [] for key in METRIC_DISPLAY_FIELDS: m = Mock() m.configure_mock(name=key) cols.append(m) getMetricDisplayFieldsMock.return_value=cols metric = Mock(**dict((col, getattr(self.metric, col)) for col in METRIC_DISPLAY_FIELDS)) metric.keys.return_value = [col for col in METRIC_DISPLAY_FIELDS] metric.name = self.metric.name repositoryMock.getAllModels = Mock(return_value=[metric]) response = self.app.get('/', headers=self.headers) assertions.assertSuccess(self, response) self.assertEqual(json.loads(response.body), self.model_list) @patch("grok.app.webservices.models_api.getMetricDisplayFields") @patch.object(models_api.ModelHandler, "createModel", spec_set=models_api.ModelHandler.createModel) def testModelHandlerPOSTModel(self, createModel, getMetricDisplayFieldsMock, _engineMock): cols = [] for key in METRIC_DISPLAY_FIELDS: m = Mock() m.configure_mock(name=key) cols.append(m) getMetricDisplayFieldsMock.return_value=cols metric = Mock(**dict((col, getattr(self.metric, col)) for col in METRIC_DISPLAY_FIELDS)) metric.keys.return_value = [col for col in METRIC_DISPLAY_FIELDS] metric.name = self.metric.name createModel.return_value = metric params = {"type": "metric", "region": "us-east-1", "namespace": "AWS/EC2", "datasource": "cloudwatch", "metric": "CPUUtilization", "dimensions": { "InstanceId": "i-0c149c66" }} response = self.app.post("/", json.dumps(params), headers=self.headers) assertions.assertResponseStatusCode(self, response, 201) assertions.assertResponseHeaders(self, response, "json") self.assertTrue(createModel.called) @patch("grok.app.webservices.models_api.getMetricDisplayFields") @patch.object(models_api.ModelHandler, "createModel", spec_set=models_api.ModelHandler.createModel) def testModelHandlerPUTModelCreate(self, createModel, getMetricDisplayFieldsMock, _engineMock): cols = [] for key in METRIC_DISPLAY_FIELDS: m = Mock() m.configure_mock(name=key) cols.append(m) getMetricDisplayFieldsMock.return_value=cols metric = Mock(**dict((col, getattr(self.metric, col)) for col in METRIC_DISPLAY_FIELDS)) metric.keys.return_value = [col for col in METRIC_DISPLAY_FIELDS] metric.name = self.metric.name createModel.return_value = metric params = {"type": "metric", "region": "us-east-1", "namespace": "AWS/EC2", "datasource": "cloudwatch", "metric": "CPUUtilization", "dimensions": { "InstanceId": "i-0c149c66" }} response = self.app.put("/", json.dumps(params), headers=self.headers) assertions.assertResponseStatusCode(self, response, 201) assertions. assertResponseHeaders(self, response, "json") self.assertTrue(createModel.called) @patch("grok.app.quota.repository") @patch("grok.app.webservices.models_api.getMetricDisplayFields") @patch("grok.app.webservices.models_api.createDatasourceAdapter", autospec=True) @patch("grok.app.webservices.models_api.repository", autospec=True) def testModelHandlerPUTMonitorMetric(self, repositoryMock, createDatasourceAdapterMock, getMetricDisplayFieldsMock, quotaRepositoryMock, engineMock): cols = [] for key in METRIC_DISPLAY_FIELDS: m = Mock() m.configure_mock(name=key) cols.append(m) getMetricDisplayFieldsMock.return_value=cols metric = Mock(**dict((col, getattr(self.metric, col)) for col in METRIC_DISPLAY_FIELDS)) metric.keys.return_value = [col for col in METRIC_DISPLAY_FIELDS] metric.name = self.metric.name quotaRepositoryMock.getInstanceCount.return_value = 0 repositoryMock.getMetric.return_value = metric params = { "region": "us-east-1", "namespace": "AWS/EC2", "datasource": "cloudwatch", "metric": "CPUUtilization", "dimensions": { "InstanceId": "i-0c149c66" } } response = self.app.put("/", json.dumps(params), headers=self.headers) assertions.assertResponseStatusCode(self, response, 201) assertions.assertResponseHeaders(self, response, "json") repositoryMock.getMetric.assert_called_once_with( engineMock.return_value.connect.return_value.__enter__.return_value, createDatasourceAdapterMock.return_value.monitorMetric.return_value) @patch("grok.app.quota.repository") @patch("grok.app.webservices.models_api.getMetricDisplayFields") @patch("grok.app.webservices.models_api.createDatasourceAdapter", autospec=True) @patch("grok.app.webservices.models_api.repository", autospec=True) def testModelHandlerPUTImportModel(self, repositoryMock, createDatasourceAdapterMock, getMetricDisplayFieldsMock, quotaRepositoryMock, engineMock): cols = [] for key in METRIC_DISPLAY_FIELDS: m = Mock() m.configure_mock(name=key) cols.append(m) getMetricDisplayFieldsMock.return_value=cols metric = Mock(**dict((col, getattr(self.metric, col)) for col in METRIC_DISPLAY_FIELDS)) metric.keys.return_value = [col for col in METRIC_DISPLAY_FIELDS] metric.name = self.metric.name quotaRepositoryMock.getInstanceCount.return_value = 0 repositoryMock.getMetric.return_value = metric params = { "type": "metric", "region": "us-east-1", "namespace": "AWS/EC2", "datasource": "cloudwatch", "metric": "CPUUtilization", "dimensions": { "InstanceId": "i-0c149c66" } } response = self.app.put("/", json.dumps(params), headers=self.headers) assertions.assertResponseStatusCode(self, response, 201) assertions.assertResponseHeaders(self, response, "json") repositoryMock.getMetric.assert_called_once_with( engineMock.return_value.connect.return_value.__enter__.return_value, createDatasourceAdapterMock.return_value.importModel.return_value) @patch.object(models_api.ModelHandler, "deleteModel", spec_set=models_api.ModelHandler.deleteModel) def testModelHandlerDELETEModel(self, deleteModel, _engineMock): response = self.app.delete("/12232-jn939", headers=self.headers) self.assertTrue(deleteModel.called) assertions.assertResponseStatusCode(self, response, 200) assertions. assertResponseHeaders(self, response, "json") @patch.object(web, "data", return_value=None, autospec=True) def testCreateModelEmpty(self, data, _engineMock): response = self.app.post("/", {}, headers=self.headers, status="*") assertions.assertBadRequest(self, response) self.assertTrue(data.called) @patch.object(repository, "getMetric", autospec=True) def testDeleteModelInvalid(self, getMetricMock, _engineMock): getMetricMock.side_effect = ObjectNotFoundError("Test") response = self.app.delete("/12232-jn939", headers=self.headers, status="*") assertions.assertNotFound(self, response) self.assertEqual("ObjectNotFoundError Metric not found:" " Metric ID: 12232-jn939", response.body) @patch.object(repository, "deleteModel", autospec=True) @patch.object(repository, "getMetric", autospec=True) @patch.object(model_swapper_utils, "deleteHTMModel", spec_set=model_swapper_utils.deleteHTMModel) @patch("grok.app.webservices.models_api.createDatasourceAdapter", auto_spec=True) def testDeleteModelValid(self, _createDatasourceAdapterMock, _deleteHTMModel, _getMetricMock, _deleteModelMock, _engineMock): response = self.app.delete("/12232-jn939", headers=self.headers) result = jsonDecode(response.body) self.assertEqual(result, {"result": "success"}) @patch("grok.app.quota.repository") @patch("grok.app.webservices.models_api.repository") @patch("web.ctx") @patch("grok.app.webservices.models_api.createDatasourceAdapter", autospec=True) def testCreateModelForMonitorMetric(self, createDatasourceAdapterMock, ctxMock, repositoryMock, quotaRepositoryMock, _engineMock): # pylint: disable=W0613 nativeMetric = { "region": "us-west-2", "namespace": "AWS/EC2", "datasource": "cloudwatch", "metric": "CPUUtilization", "dimensions": { "InstanceId": "i-ab15a19d" } } metricSpec = { "region": nativeMetric["region"], "namespace": nativeMetric["namespace"], "metric": nativeMetric["metric"], "dimensions": nativeMetric["dimensions"] } metricAdapter = AWSResourceAdapterBase.createMetricAdapter(metricSpec) (createDatasourceAdapterMock .return_value .getInstanceNameForModelSpec .return_value) = metricAdapter.getCanonicalResourceName() quotaRepositoryMock.getInstanceCount.return_value = 0 result = models_api.ModelHandler.createModel(nativeMetric) self.assertIs(result, repositoryMock.getMetric.return_value) repositoryMock.getMetric.assert_called_once_with( ctxMock.connFactory.return_value.__enter__.return_value, createDatasourceAdapterMock.return_value.monitorMetric.return_value) @patch("grok.app.quota.repository") @patch("grok.app.webservices.models_api.repository") @patch("web.ctx") @patch("grok.app.webservices.models_api.createDatasourceAdapter", autospec=True) def testCreateModelForImportModel(self, createDatasourceAdapterMock, ctxMock, repositoryMock, quotaRepositoryMock, _engineMock): nativeMetric = { "type": "metric", "region": "us-west-2", "namespace": "AWS/EC2", "datasource": "cloudwatch", "metric": "CPUUtilization", "dimensions": { "InstanceId": "i-ab15a19d" } } metricSpec = { "region": nativeMetric["region"], "namespace": nativeMetric["namespace"], "metric": nativeMetric["metric"], "dimensions": nativeMetric["dimensions"] } metricAdapter = AWSResourceAdapterBase.createMetricAdapter(metricSpec) (createDatasourceAdapterMock .return_value .getInstanceNameForModelSpec .return_value) = metricAdapter.getCanonicalResourceName() quotaRepositoryMock.getInstanceCount.return_value = 0 result = models_api.ModelHandler.createModel(nativeMetric) self.assertIs(result, repositoryMock.getMetric.return_value) repositoryMock.getMetric.assert_called_once_with( ctxMock.connFactory.return_value.__enter__.return_value, createDatasourceAdapterMock.return_value.importModel.return_value) @patch("grok.app.quota.repository") @patch("grok.app.webservices.models_api.repository") @patch("web.ctx") @patch("grok.app.webservices.models_api.createDatasourceAdapter", autospec=True) def testImportModelAutostack(self, adapterMock, ctxMock, repositoryMock, quotaRepositoryMock, _engineMock): nativeMetric = { "type": "autostack", "name": "test1", "region": "us-west-2", "datasource": "cloudwatch", "filters": { "tag:Name": [ "*d*" ] }, "metric": { "metric": "DiskWriteBytes", "namespace": "AWS/EC2" } } quotaRepositoryMock.getInstanceCount.return_value = 0 adapter = createDatasourceAdapter("autostack") importModelMock = create_autospec(adapter.importModel) adapterMock.return_value.importModel = importModelMock result = models_api.ModelHandler.createModel(nativeMetric) self.assertIs(result, repositoryMock.getMetric.return_value) repositoryMock.getMetric.assert_called_once_with( ctxMock.connFactory.return_value.__enter__.return_value, adapterMock.return_value.importModel.return_value) @patch("web.webapi.ctx") @patch("grok.app.webservices.web.ctx") def testCreateModelRaisesBadRequestForEmptyRequest(self, webMock, loggerWebMock, _engineMock): webMock.badrequest = web.badrequest loggerWebMock.env = {'HTTP_HOST':'localhost', 'SCRIPT_NAME':'', 'PATH_INFO':'/_models/test', 'HTTP_USER_AGENT':'test'} with self.assertRaises(web.badrequest) as e: models_api.ModelHandler.createModel() self.assertIsInstance(e.exception, InvalidRequestResponse) self.assertIn("Metric data is missing", e.exception.data) @patch("grok.app.quota.repository") @patch("grok.app.webservices.models_api.repository") @patch("web.ctx") @patch("grok.app.webservices.models_api.createDatasourceAdapter", autospec=True) def testCreateModels(self, # pylint: disable=W0613 createDatasourceAdapterMock, ctxMock, repositoryMock, quotaRepositoryMock, _engineMock): nativeMetric = { "region": "us-west-2", "namespace": "AWS/EC2", "datasource": "cloudwatch", "metric": "CPUUtilization", "dimensions": { "InstanceId": "i-ab15a19d" } } metricSpec = { "region": nativeMetric["region"], "namespace": nativeMetric["namespace"], "metric": nativeMetric["metric"], "dimensions": nativeMetric["dimensions"] } metricAdapter = AWSResourceAdapterBase.createMetricAdapter(metricSpec) (createDatasourceAdapterMock .return_value .getInstanceNameForModelSpec .return_value) = metricAdapter.getCanonicalResourceName() quotaRepositoryMock.getInstanceCount.return_value = 0 result = models_api.ModelHandler.createModels([nativeMetric]) self.assertIsInstance(result, list) self.assertIs(result[0], repositoryMock.getMetric.return_value) repositoryMock.getMetric.assert_called_once_with( ctxMock.connFactory.return_value.__enter__.return_value, createDatasourceAdapterMock.return_value.monitorMetric.return_value) @patch("web.webapi.ctx") @patch("grok.app.webservices.web.ctx") def testCreateModelsRaisesBadRequestForEmptyRequest(self, webMock, loggerWebMock, _engineMock): webMock.data.return_value = None webMock.badrequest = web.badrequest loggerWebMock.env = {'HTTP_HOST':'localhost', 'SCRIPT_NAME':'', 'PATH_INFO':'/_models/test', 'HTTP_USER_AGENT':'test'} with self.assertRaises(web.badrequest) as e: models_api.ModelHandler.createModels() self.assertEqual(e.exception.data, "Metric data is missing")
class SettingsHandlerTest(unittest.TestCase): """ Integration test settings API """ @classmethod def setUpClass(cls): cls.configurable_options = { "aws": set([u"aws_access_key_id", u"aws_secret_access_key"]) } def setUp(self): self.headers = getDefaultHTTPHeaders(htm.it.app.config) self.app = TestApp(settings_api.app.wsgifunc()) def testSettingsHandlerDefault(self): """ Test for GET for '/_settings', List All Settings resoponse is validated for appropriate headers and body """ response = self.app.get("", headers=self.headers) assertions.assertResponseHeaders(self, response) assertions.assertResponseBody(self, response) assertions.assertResponseStatusCode(self, response, 200) result = app_utils.jsonDecode(response.body) self.assertIsInstance(result, dict) for config in self.configurable_options: self.assertTrue(result.has_key(config)) for key in self.configurable_options[config]: if key in settings_api.HIDDEN_SETTINGS[config]: self.assertNotIn(key, result[config]) else: self.assertIn(key, result[config]) def testGETValidSection(self): """ Test for GET for '/_settings/section, List Some Settings resoponse is validated for appropriate headers and body """ response = self.app.get("/aws", headers=self.headers) assertions.assertResponseHeaders(self, response) assertions.assertResponseBody(self, response) assertions.assertResponseStatusCode(self, response, 200) result = app_utils.jsonDecode(response.body) self.assertIsInstance(result, dict) for key in set(self.configurable_options["aws"]): if key in settings_api.HIDDEN_SETTINGS["aws"]: self.assertNotIn(key, result) else: self.assertIn(key, result) def testGETInvalidSection(self): """ Test for GET for '/_settings/section, List Some invalid Settings resoponse is validated for appropriate headers and body """ response = self.app.get("/dddd", headers=self.headers) assertions.assertResponseHeaders(self, response) assertions.assertResponseBody(self, response) assertions.assertResponseStatusCode(self, response, 200) self.assertEqual(app_utils.jsonDecode(response.body), {}) # handling Assertionerror as TestApp throws # AssertionError: Content-Type header found in a 204 response, # which must not return content. def testPOSTSection(self): """ Test for POST for '/_settings', Set some setting resoponse is validated for appropriate headers and body """ # IMPORTANT: functions are executed in reverse order from when they are # added so we need to add config.save first. configBackup = HTMItAppConfig(mode=HTMItAppConfig.MODE_OVERRIDE_ONLY) self.addCleanup(configBackup.save) del configBackup try: self.app.post("/aws", app_utils.jsonEncode( {"aws_access_key_id": "dummy_aws_key1"}), headers=self.headers) except AssertionError, ae: print ae.message finally:
class TestAutostackMetricsHandler(unittest.TestCase): @classmethod def setUpClass(cls): with open( os.path.join(htm.it.app.HTM_IT_HOME, "tests/py/data/app/webservices/models_list.json") ) as fileObj: cls.model_list = json.load(fileObj) cls.autostack = Mock(uid="blahblahblah", region="bogus", filters=jsonEncode({"tag:Name": ["Bogus"]})) cls.autostack.name = "Test" cls.jsonAutostack = jsonEncode({ "uid": "blahblahblah", "name": "Test", "region": "bogus", "filters": { "tag:Name": ["Bogus"] } }) cls.metric = Mock( uid="cebe9fab-f416-4845-8dab-02d292244112", datasource="autostack", description="The number of database connections in use " "by Amazon RDS database", server="htm-itdb2", location="us-east-1", parameters=jsonEncode({ "region": "us-east-1", "DBInstanceIdentifier": "htm-itdb2" }), status=1, message=None, collector_error=None, last_timestamp="2013-08-15 21:25:00", poll_interval=60, tag_name=None, model_params=None, last_rowid=20277) cls.metric.name = "AWS/RDS/DatabaseConnections" cls.jsonMetric = jsonEncode({ "uid": cls.metric.uid, "datasource": cls.metric.datasource, "name": cls.metric.name, "description": cls.metric.description, "server": cls.metric.server, "location": cls.metric.location, "parameters": jsonDecode(cls.metric.parameters), "status": cls.metric.status, "message": cls.metric.message, "last_timestamp": cls.metric.last_timestamp, "poll_interval": cls.metric.poll_interval, "tag_name": cls.metric.tag_name, "last_rowid": cls.metric.last_rowid, "display_name": cls.metric.server }) def setUp(self): self.headers = getDefaultHTTPHeaders(htm.it.app.config) self.app = TestApp(autostacks_api.app.wsgifunc()) @patch("htm.it.app.webservices.autostacks_api.repository") def testGETAutostackMetrics(self, repositoryMock, *_args): repositoryMock.getAutostackMetrics.return_value = iter([self.metric]) response = self.app.get("/" + self.autostack.uid + "/metrics", headers=self.headers) self.assertEqual(response.status, 200) result = json.loads(response.body) self.assertDictEqual(json.loads(self.jsonMetric), result[0]) @patch( "htm.it.app.webservices.autostacks_api.createAutostackDatasourceAdapter" ) @patch("htm.it.app.repository.getMetric", autospec=True) @patch("htm.it.app.repository.addMetric", autospec=True) def testPOSTAutostackMetricsNoMinMax(self, addMetricMock, getMetricMock, adapterMock, *_args): getMetricMock.return_value = self.metric addMetricMock.return_value = self.metric response = self.app.post("/" + self.autostack.uid + "/metrics", app_utils.jsonEncode([{ "metric": "CPUUtilization", "namespace": "AWS/EC2" }, { "metric": "NetworkIn", "namespace": "AWS/EC2" }]), headers=self.headers) self.assertEqual(response.status, 201) self.assertEqual(adapterMock.return_value.monitorMetric.call_count, 2) metricSpec = (adapterMock.return_value.monitorMetric.call_args_list[0] [0][0]["metricSpec"]) self.assertEqual(metricSpec["slaveMetric"]["metric"], "CPUUtilization") self.assertEqual(metricSpec["slaveMetric"]["namespace"], "AWS/EC2") metricSpec = (adapterMock.return_value.monitorMetric.call_args_list[1] [0][0]["metricSpec"]) self.assertEqual(metricSpec["slaveMetric"]["metric"], "NetworkIn") self.assertEqual(metricSpec["slaveMetric"]["namespace"], "AWS/EC2") @patch( "htm.it.app.webservices.autostacks_api.createAutostackDatasourceAdapter" ) @patch("htm.it.app.repository.getMetric", autospec=True) @patch("htm.it.app.repository.addMetric", autospec=True) def testPOSTAutostackMetricsWithMinMax(self, addMetricMock, getMetricMock, adapterMock, *_args): getMetricMock.return_value = self.metric addMetricMock.return_value = self.metric response = self.app.post("/" + self.autostack.uid + "/metrics", app_utils.jsonEncode([{ "metric": "CPUUtilization", "namespace": "AWS/EC2", "min": 0.0, "max": 10.0 }]), headers=self.headers) self.assertEqual(response.status, 201) self.assertTrue(adapterMock.return_value.monitorMetric.called) self.assertEqual( adapterMock.return_value.monitorMetric.call_args_list[0][0][0] ["modelParams"], { 'max': 10.0, 'min': 0.0 }) @patch( "htm.it.app.webservices.autostacks_api.createAutostackDatasourceAdapter" ) @patch("htm.it.app.webservices.models_api.repository.getAutostack") def testPOSTAutostackMetricsHandlesObjectNotFoundError( self, autostackGetMock, adapterMock, _repositoryMock): autostackGetMock.return_value = self.autostack adapterMock.return_value.monitorMetric.side_effect = ( ValueError("Autostack not found.")) with self.assertRaises(AppError) as e: self.app.post("/" + self.autostack.uid + "/metrics", app_utils.jsonEncode([{ "metric": "Foobar", "namespace": "AWS/EC2" }]), headers=self.headers) self.assertIn("400 Bad Request", str(e.exception)) self.assertTrue(adapterMock.return_value.monitorMetric.called) @patch("htmengine.model_swapper.utils.deleteHTMModel") @patch("htm.it.app.webservices.autostacks_api.repository") def testDELETEAutostackMetrics(self, repositoryMock, deleteHTMModelMock, *_args): repositoryMock.getAutostackFromMetric.return_value = Mock( uid=self.autostack.uid) response = self.app.delete("/" + self.autostack.uid + "/metrics/" + self.metric.uid, headers=self.headers) self.assertEqual(response.status, 204) self.assertTrue(repositoryMock.deleteMetric.called) repositoryMock.deleteMetric.assert_called_with(ANY, self.metric.uid) deleteHTMModelMock.assert_called_once_with(self.metric.uid) @patch("htmengine.model_swapper.utils.deleteHTMModel", auto_spec=True) @patch("htm.it.app.webservices.autostacks_api.repository", auto_spec=True) def testDELETEAutostackMetricsWrongAutostack(self, repositoryMock, *_args): repositoryMock.getAutostackFromMetric.return_value = Mock( uid="wrong-autostack-id") with self.assertRaises(AppError) as cm: self.app.delete("/" + self.autostack.uid + "/metrics/" + self.metric.uid, headers=self.headers) self.assertIn("Bad response: 400 Bad Request", str(cm.exception)) self.assertIn( "Metric=cebe9fab-f416-4845-8dab-02d292244112 does not belong to " "autostack=blahblahblah", str(cm.exception)) @patch("htm.it.app.webservices.models_api.repository") def testDELETEAutostackMetricsFromModelsAPI(self, repositoryMock, *_args): repositoryMock.getMetric.return_value = self.metric app = TestApp(models_api.app.wsgifunc()) with self.assertRaises(AppError) as e: app.delete("/" + self.metric.uid, headers=self.headers) self.assertIn("Bad response: 405 Method Not Allowed", str(e.exception))
class WufooTest(unittest.TestCase): def setUp(self): self.headers = getDefaultHTTPHeaders(htm.it.app.config) self.app = TestApp(wufoo_api.app.wsgifunc()) self.instanceData = {"version" : "2010-08-31", "instanceId" : "i-d9e211f6", "billingProducts" : None, "accountId" : "987654321", "kernelId" : "aki-88aa75e1", "ramdiskId" : None, "architecture" : "x86_64", "imageId" : "ami-b56a7fdc", "pendingTime" : "2014-03-20T14:06:46Z", "instanceType" : "m1.medium", "region" : "us-east-1", "devpayProductCodes" : None, "privateIp" : "10.122.242.151", "availabilityZone" : "us-east-1d"} self.postData = data = {"name": "User Schmoozer", "company": "Numenta, inc.", "edition": "Standard", "version": htm.it.__version__.__version__, "build": "0", "email": "*****@*****.**"} @ConfigAttributePatch(htm.it.app.config.CONFIG_NAME, htm.it.app.config.baseConfigDir, (("usertrack", "htm_it_id", "f2fec4a62c76418799e3907f1360e9b7"),)) @patch("htm.it.app.webservices.wufoo_api.log") @patch("htm.it.app.webservices.wufoo_api.requests") @patch("htm.it.app.webservices.wufoo_api.instance_utils") @patch("htm.it.app.webservices.wufoo_api.sendWelcomeEmail") def testWufooHandlerLogsPOSTedData(self, sendWelcomeEmailMock, instance_utilsMock, requestsMock, logMock): """ Wufoo Handler logs POSTed data """ instance_utilsMock.getInstanceData = Mock(return_value=self.instanceData) response = self.app.post("", json.dumps(self.postData), headers=self.headers) logMock.info.assert_any_call("{TAG:WUFOO.CUST.REG} instanceId=i-d9e211f6"), logMock.info.assert_any_call("{TAG:WUFOO.CUST.REG} company=Numenta, inc."), logMock.info.assert_any_call("{TAG:WUFOO.CUST.REG} edition=Standard"), logMock.info.assert_any_call("{TAG:WUFOO.CUST.REG} instanceType=m1.medium"), logMock.info.assert_any_call("{TAG:WUFOO.CUST.REG} accountId=987654321"), logMock.info.assert_any_call("{TAG:WUFOO.CUST.REG} name=User Schmoozer"), logMock.info.assert_any_call("{TAG:WUFOO.CUST.REG} region=us-east-1"), logMock.info.assert_any_call("{TAG:WUFOO.CUST.REG} version=%s" % htm.it.__version__.__version__), logMock.info.assert_any_call("{TAG:WUFOO.CUST.REG} uniqueServerId=f2fec4a62c76418799e3907f1360e9b7"), logMock.info.assert_any_call("{TAG:WUFOO.CUST.REG} [email protected]"), logMock.info.assert_any_call("{TAG:WUFOO.CUST.REG} build=0") sendWelcomeEmailMock.assert_called_once_with("*****@*****.**") @ConfigAttributePatch(htm.it.app.config.CONFIG_NAME, htm.it.app.config.baseConfigDir, (("usertrack", "send_to_wufoo", "no"),)) @patch("htm.it.app.webservices.wufoo_api.requests") @patch("htm.it.app.webservices.wufoo_api.instance_utils") @patch("htm.it.app.webservices.wufoo_api.sendWelcomeEmail") def testWufooConfigFlagDisabled(self, sendWelcomeEmailMock, instance_utilsMock, requestsMock): """ Assert that wufoo handler honors send_to_wufoo configuration directive in the disabled case """ response = self.app.post("", json.dumps(self.postData), headers=self.headers) self.assertFalse(requestsMock.post.called) @ConfigAttributePatch(htm.it.app.config.CONFIG_NAME, htm.it.app.config.baseConfigDir, (("usertrack", "send_to_wufoo", "yes"),)) @patch("htm.it.app.webservices.wufoo_api.requests") @patch("htm.it.app.webservices.wufoo_api.instance_utils") @patch("htm.it.app.webservices.wufoo_api.sendWelcomeEmail") def testWufooConfigFlagEnabled(self, sendWelcomeEmailMock, instance_utilsMock, requestsMock): """ Assert that wufoo handler honors send_to_wufoo configuration directive in the enabled case """ response = self.app.post("", json.dumps(self.postData), headers=self.headers) self.assertTrue(requestsMock.post.called)
def test_unicode_path(): app = TestApp(SimpleApplication()) app.get(u"/?") app.post(u"/?") app.put(u"/?") app.delete(u"/?")
class TestNotificationsHandler(unittest.TestCase): @classmethod def setUpClass(cls): cls.model_list = json.load( open( os.path.join( grok.app.GROK_HOME, "tests/py/data/app/webservices/models_list.json"))) def setUp(self): self.headers = getDefaultHTTPHeaders(grok.app.config) self.app = TestApp(notifications_api.app.wsgifunc()) # Set up dummy notification assets self.deviceId = str(uuid.uuid4()) self.notificationId = str(uuid.uuid4()) metricParams = { u"region": u"us-east-1", u"DBInstanceIdentifier": u"grokdb2" } self.metric = { "uid": u"cebe9fab-f416-4845-8dab-02d292244112", "datasource": u"cloudwatch", "name": u"AWS/RDS/DatabaseConnections", "description": u"The number of database connections in use " u"by Amazon RDS database", "server": u"grokdb2", "location": u"us-east-1", "parameters": app_utils.jsonEncode(metricParams), "status": 1, "message": None, "collector_error": None, "last_timestamp": u"2013-08-15 21:25:00", "poll_interval": 60, "tag_name": None, "model_params": None, "last_rowid": 20277 } self.notification = { "uid": self.deviceId, "metric": self.metric["uid"], "device": self.deviceId, "windowsize": 3600, "timestamp": datetime.datetime.utcnow(), "acknowledged": 0, "seen": 0, "ses_message_id": None, "rowid": 666 } self.settings = { "uid": self.deviceId, "windowsize": 3600, "sensitivity": 0.99999, "email_addr": "*****@*****.**", "last_timestamp": datetime.datetime.utcnow() } @patch.object(repository, "getNotification", autospec=True) def testGETNotification(self, getNotificationMock, _engineMock): """ Test GETing single notification from Notification API """ getNotificationMock.return_value = self.notification response = self.app.get( "/%s/%s" % (self.notification["device"], self.notification["uid"]), headers=self.headers) self.assertEqual(response.status, 200) result = json.loads(response.body) notificationDict = copy.deepcopy(self.notification) del notificationDict["ses_message_id"] del notificationDict["rowid"] jsonNotification = json.loads(app_utils.jsonEncode(notificationDict)) self.assertDictEqual(result, jsonNotification) @patch.object(repository, "batchAcknowledgeNotifications", autospec=True) def testDELETENotification(self, batchAcknowledgeMock, engineMock): """ Test notification DELETE endpoint """ response = self.app.delete( "/%s/%s" % (self.notification["device"], self.notification["uid"]), headers=self.headers) self.assertEqual(response.status, 204) self.assertFalse(response.body) self.assertTrue(batchAcknowledgeMock.called) batchAcknowledgeMock.assert_called_with( engineMock.return_value.connect.return_value.__enter__. return_value, [self.notification["uid"]]) @patch.object(repository, "batchAcknowledgeNotifications", autospec=True) def testDELETENotificationBatch(self, batchAcknowledgeMock, engineMock): """ Test notification DELETE endpoint (batch) """ uids = [self.notification["uid"], self.notification["uid"]] response = self.app.delete("/%s" % self.notification["device"], app_utils.jsonEncode(uids), headers=self.headers) self.assertEqual(response.status, 204) self.assertFalse(response.body) self.assertTrue(batchAcknowledgeMock.called) batchAcknowledgeMock.assert_called_with( engineMock.return_value.connect.return_value.__enter__. return_value, uids) @patch.object(repository, "batchAcknowledgeNotifications", autospec=True) def testAcknowledgeNotificationBatch(self, batchAcknowledgeMock, engineMock): """ Test notification POST endpoint (batch) """ uids = [self.notification["uid"], self.notification["uid"]] response = self.app.post("/%s/acknowledge" % self.notification["device"], app_utils.jsonEncode(uids), headers=self.headers) self.assertEqual(response.status, 204) self.assertFalse(response.body) self.assertTrue(batchAcknowledgeMock.called) batchAcknowledgeMock.assert_called_with( engineMock.return_value.connect.return_value.__enter__. return_value, uids) @patch.object(repository, "batchSeeNotifications", autospec=True) def testSeeNotificationBatch(self, batchaSeeMock, engineMock): """ Test notification POST endpoint (batch) """ uids = [self.notification["uid"], self.notification["uid"]] response = self.app.post("/%s/see" % self.notification["device"], app_utils.jsonEncode(uids), headers=self.headers) self.assertEqual(response.status, 204) self.assertFalse(response.body) self.assertTrue(batchaSeeMock.called) batchaSeeMock.assert_called_with( engineMock.return_value.connect.return_value.__enter__. return_value, uids) @patch("grok.app.webservices.notifications_api.repository", autospec=True) def testGETNotificationHistory(self, repositoryMock, _engineMock): """ Test GET notification history """ repositoryMock.getUnseenNotificationList = Mock( return_value=[self.notification]) response = self.app.get("/%s/history" % self.notification["device"], headers=self.headers) self.assertEqual(response.status, 200) result = json.loads(response.body) notificationDict = copy.deepcopy(self.notification) del notificationDict["ses_message_id"] del notificationDict["rowid"] jsonNotifications = json.loads(app_utils.jsonEncode([notificationDict ])) self.assertSequenceEqual(result, jsonNotifications) @patch("grok.app.webservices.notifications_api.repository", autospec=True) def testGETNotificationSettings(self, repositoryMock, _engineMock): """ Test GET notification settings """ repositoryMock.getDeviceNotificationSettings = Mock( return_value=self.settings) response = self.app.get("/%s/settings" % self.notification["device"], headers=self.headers) self.assertEqual(response.status, 200) result = json.loads(response.body) settingsDict = copy.deepcopy(self.settings) jsonNotificationSettings = json.loads( app_utils.jsonEncode(settingsDict)) self.assertDictEqual(result, jsonNotificationSettings) @patch("grok.app.webservices.notifications_api.repository", autospec=True) def testPUTNotificationSettingsUpdate(self, repositoryMock, engineMock): """ Test PUT notification settings (update) """ repositoryMock.getDeviceNotificationSettings = Mock( return_value=self.settings) update = { "windowsize": 3601, "sensitivity": 0.999999, "email_addr": "*****@*****.**" } response = self.app.put("/%s/settings" % self.notification["device"], app_utils.jsonEncode(update), headers=self.headers) self.assertEqual(response.status, 204) self.assertFalse(response.body) repositoryMock.updateDeviceNotificationSettings.assert_called_with( engineMock.return_value.connect.return_value.__enter__. return_value, self.notification["device"], { "windowsize": 3601, "sensitivity": 0.999999, "email_addr": "*****@*****.**" }) @patch("grok.app.webservices.notifications_api.repository", autospec=True) def testPUTNotificationSettingsCreate(self, repositoryMock, engineMock): """ Test PUT notification settings (create) """ repositoryMock.getDeviceNotificationSettings.side_effect = ( ObjectNotFoundError("No settings yet")) update = { "windowsize": 3601, "sensitivity": 0.999999, "email_addr": "*****@*****.**" } response = self.app.put("/%s/settings" % self.notification["device"], app_utils.jsonEncode(update), headers=self.headers) self.assertEqual(response.status, 201) self.assertFalse(response.body) self.assertTrue(repositoryMock.getDeviceNotificationSettings.called) repositoryMock.addDeviceNotificationSettings.assert_called_with( engineMock.return_value.connect.return_value.__enter__. return_value, self.notification["device"], update["windowsize"], update["sensitivity"], update["email_addr"])
class SettingsHandlerTest(unittest.TestCase): @classmethod def setUpClass(cls): cls.default_aws_access_key = YOMP.app.config.get( "aws", "aws_access_key_id") cls.default_aws_secret_key = YOMP.app.config.get( "aws", "aws_secret_access_key") cls.configurable_options = { "aws": set([u"aws_access_key_id", u"aws_secret_access_key"]) } def setUp(self): self.headers = getDefaultHTTPHeaders(YOMP.app.config) self.app = TestApp(settings_api.app.wsgifunc()) # YOMP.conf is puposefully restored in tearDown considering that # testcases run any order # This will make sure we have clean config for each testcase def tearDown(self): config = YOMPAppConfig(mode=YOMPAppConfig.MODE_OVERRIDE_ONLY) if not config.has_section("aws"): config.add_section("aws") config.set("aws", "aws_secret_access_key", self.default_aws_secret_key) config.set("aws", "aws_access_key_id", self.default_aws_access_key) config.save() def testDefaultGetList(self): response = self.app.get("", headers=self.headers) assertions.assertSuccess(self, response) result = app_utils.jsonDecode(response.body) self.assertIsInstance(result, dict) for config in self.configurable_options: self.assertTrue(result.has_key(config)) for key in self.configurable_options[config]: if key in settings_api.HIDDEN_SETTINGS[config]: self.assertNotIn(key, result[config]) else: self.assertIn(key, result[config]) def testDefaultGetSpecificSection(self): response = self.app.get("/aws", headers=self.headers) assertions.assertSuccess(self, response) result = app_utils.jsonDecode(response.body) self.assertIsInstance(result, dict) for key in set(self.configurable_options["aws"]): if key in settings_api.HIDDEN_SETTINGS["aws"]: self.assertNotIn(key, result) else: self.assertIn(key, result) # handling Assertionerror as TestApp throws # AssertionError: Content-Type header found in a 204 response, # which must not return content. def testPostTSection(self): try: self.app.post("/aws", json.dumps( {"aws_access_key_id": "dummy_value_aws_key"}), headers=self.headers) except AssertionError, ae: print ae.message finally: