From 9330ebc110aeb7591567c66939b39f4345b5778d Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Fri, 10 Sep 2010 04:52:48 -0700 Subject: added modify project command to allow project manager and description to be updated --- nova/tests/auth_unittest.py | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'nova/tests') diff --git a/nova/tests/auth_unittest.py b/nova/tests/auth_unittest.py index 0b404bfdc..2fc780640 100644 --- a/nova/tests/auth_unittest.py +++ b/nova/tests/auth_unittest.py @@ -206,6 +206,12 @@ class AuthTestCase(test.BaseTestCase): self.assert_(len(self.manager.get_projects()) > 1) self.assertEqual(len(self.manager.get_projects('test2')), 1) + def test_220_can_modify_project(self): + self.manager.modify_project('testproj', 'test2', 'new description') + project = self.manager.get_project('testproj') + self.assertEqual(project.project_manager_id, 'test2') + self.assertEqual(project.description, 'new description') + def test_299_can_delete_project(self): self.manager.delete_project('testproj') self.assertFalse(filter(lambda p: p.name == 'testproj', self.manager.get_projects())) -- cgit From 8e834931087c54585a7aa2716c7a0708fd658f30 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Fri, 10 Sep 2010 22:13:36 -0700 Subject: move keypair generation out of auth and fix tests --- nova/tests/api_unittest.py | 7 +++--- nova/tests/auth_unittest.py | 31 -------------------------- nova/tests/cloud_unittest.py | 53 +++++++++++++++++++++++++++++++++++++------- 3 files changed, 49 insertions(+), 42 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/api_unittest.py b/nova/tests/api_unittest.py index 462d1b295..fdb9e21d8 100644 --- a/nova/tests/api_unittest.py +++ b/nova/tests/api_unittest.py @@ -41,8 +41,8 @@ FLAGS = flags.FLAGS # it's pretty damn circuitous so apologies if you have to fix # a bug in it # NOTE(jaypipes) The pylint disables here are for R0913 (too many args) which -# isn't controllable since boto's HTTPRequest needs that many -# args, and for the version-differentiated import of tornado's +# isn't controllable since boto's HTTPRequest needs that many +# args, and for the version-differentiated import of tornado's # httputil. # NOTE(jaypipes): The disable-msg=E1101 and E1103 below is because pylint is # unable to introspect the deferred's return value properly @@ -224,7 +224,8 @@ class ApiEc2TestCase(test.BaseTestCase): for x in range(random.randint(4, 8))) user = self.manager.create_user('fake', 'fake', 'fake') project = self.manager.create_project('fake', 'fake', 'fake') - self.manager.generate_key_pair(user.id, keyname) + # NOTE(vish): create depends on pool, so call helper directly + cloud._gen_key(None, user.id, keyname) rv = self.ec2.get_all_key_pairs() results = [k for k in rv if k.name == keyname] diff --git a/nova/tests/auth_unittest.py b/nova/tests/auth_unittest.py index b54e68274..1b4e12677 100644 --- a/nova/tests/auth_unittest.py +++ b/nova/tests/auth_unittest.py @@ -17,8 +17,6 @@ # under the License. import logging -from M2Crypto import BIO -from M2Crypto import RSA from M2Crypto import X509 import unittest @@ -65,35 +63,6 @@ class AuthTestCase(test.BaseTestCase): 'export S3_URL="http://127.0.0.1:3333/"\n' + 'export EC2_USER_ID="test1"\n') - def test_006_test_key_storage(self): - user = self.manager.get_user('test1') - user.create_key_pair('public', 'key', 'fingerprint') - key = user.get_key_pair('public') - self.assertEqual('key', key.public_key) - self.assertEqual('fingerprint', key.fingerprint) - - def test_007_test_key_generation(self): - user = self.manager.get_user('test1') - private_key, fingerprint = user.generate_key_pair('public2') - key = RSA.load_key_string(private_key, callback=lambda: None) - bio = BIO.MemoryBuffer() - public_key = user.get_key_pair('public2').public_key - key.save_pub_key_bio(bio) - converted = crypto.ssl_pub_to_ssh_pub(bio.read()) - # assert key fields are equal - self.assertEqual(public_key.split(" ")[1].strip(), - converted.split(" ")[1].strip()) - - def test_008_can_list_key_pairs(self): - keys = self.manager.get_user('test1').get_key_pairs() - self.assertTrue(filter(lambda k: k.name == 'public', keys)) - self.assertTrue(filter(lambda k: k.name == 'public2', keys)) - - def test_009_can_delete_key_pair(self): - self.manager.get_user('test1').delete_key_pair('public') - keys = self.manager.get_user('test1').get_key_pairs() - self.assertFalse(filter(lambda k: k.name == 'public', keys)) - def test_010_can_list_users(self): users = self.manager.get_users() logging.warn(users) diff --git a/nova/tests/cloud_unittest.py b/nova/tests/cloud_unittest.py index 29947e03c..4bad25c2b 100644 --- a/nova/tests/cloud_unittest.py +++ b/nova/tests/cloud_unittest.py @@ -17,13 +17,18 @@ # under the License. import logging +from M2Crypto import BIO +from M2Crypto import RSA import StringIO import time + from tornado import ioloop from twisted.internet import defer import unittest from xml.etree import ElementTree +from nova import crypto +from nova import db from nova import flags from nova import rpc from nova import test @@ -54,16 +59,21 @@ class CloudTestCase(test.BaseTestCase): proxy=self.compute) self.injected.append(self.compute_consumer.attach_to_tornado(self.ioloop)) - try: - manager.AuthManager().create_user('admin', 'admin', 'admin') - except: pass - admin = manager.AuthManager().get_user('admin') - project = manager.AuthManager().create_project('proj', 'admin', 'proj') - self.context = api.APIRequestContext(handler=None,project=project,user=admin) + self.manager = manager.AuthManager() + self.user = self.manager.create_user('admin', 'admin', 'admin', True) + self.project = self.manager.create_project('proj', 'admin', 'proj') + self.context = api.APIRequestContext(handler=None, + user=self.user, + project=self.project) def tearDown(self): - manager.AuthManager().delete_project('proj') - manager.AuthManager().delete_user('admin') + self.manager.delete_project(self.project) + self.manager.delete_user(self.user) + super(CloudTestCase, self).setUp() + + def _create_key(self, name): + # NOTE(vish): create depends on pool, so just call helper directly + return cloud._gen_key(self.context, self.context.user.id, name) def test_console_output(self): if FLAGS.connection_type == 'fake': @@ -76,6 +86,33 @@ class CloudTestCase(test.BaseTestCase): self.assert_(output) rv = yield self.compute.terminate_instance(instance_id) + + def test_key_generation(self): + result = self._create_key('test') + private_key = result['private_key'] + key = RSA.load_key_string(private_key, callback=lambda: None) + bio = BIO.MemoryBuffer() + public_key = db.keypair_get(self.context, + self.context.user.id, + 'test')['public_key'] + key.save_pub_key_bio(bio) + converted = crypto.ssl_pub_to_ssh_pub(bio.read()) + # assert key fields are equal + self.assertEqual(public_key.split(" ")[1].strip(), + converted.split(" ")[1].strip()) + + def test_describe_key_pairs(self): + self._create_key('test1') + self._create_key('test2') + result = self.cloud.describe_key_pairs(self.context) + keys = result["keypairsSet"] + self.assertTrue(filter(lambda k: k['keyName'] == 'test1', keys)) + self.assertTrue(filter(lambda k: k['keyName'] == 'test2', keys)) + + def test_delete_key_pair(self): + self._create_key('test') + self.cloud.delete_key_pair(self.context, 'test') + def test_run_instances(self): if FLAGS.connection_type == 'fake': logging.debug("Can't test instances without a real virtual env.") -- cgit From 66c583b1883af6e3452271df4b302fd32d1ee25d Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Sat, 11 Sep 2010 04:18:30 -0700 Subject: fixed old key reference and made keypair name constistent -> key_pair --- nova/tests/cloud_unittest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova/tests') diff --git a/nova/tests/cloud_unittest.py b/nova/tests/cloud_unittest.py index 4bad25c2b..e56ea6ac2 100644 --- a/nova/tests/cloud_unittest.py +++ b/nova/tests/cloud_unittest.py @@ -92,7 +92,7 @@ class CloudTestCase(test.BaseTestCase): private_key = result['private_key'] key = RSA.load_key_string(private_key, callback=lambda: None) bio = BIO.MemoryBuffer() - public_key = db.keypair_get(self.context, + public_key = db.key_pair_get(self.context, self.context.user.id, 'test')['public_key'] key.save_pub_key_bio(bio) -- cgit From 8138a35d3672e08640762b7533c1c527568d0b4f Mon Sep 17 00:00:00 2001 From: Michael Gundlach Date: Tue, 14 Sep 2010 18:59:02 -0400 Subject: RateLimitingMiddleware --- nova/tests/api/rackspace/__init__.py | 56 ++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) (limited to 'nova/tests') diff --git a/nova/tests/api/rackspace/__init__.py b/nova/tests/api/rackspace/__init__.py index e69de29bb..f7537a4e7 100644 --- a/nova/tests/api/rackspace/__init__.py +++ b/nova/tests/api/rackspace/__init__.py @@ -0,0 +1,56 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2010 OpenStack LLC. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import unittest + +from nova.api.rackspace.ratelimiting import RateLimitingMiddleware +from nova.tests.api.test_helper import * +from webob import Request + +class RateLimitingMiddlewareTest(unittest.TestCase): + def setUp(self): + self.middleware = RateLimitingMiddleware(APIStub()) + self.stubs = stubout.StubOutForTesting() + + def tearDown(self): + self.stubs.UnsetAll() + + def test_get_action_name(self): + middleware = RateLimitingMiddleware(APIStub()) + def verify(method, url, action_name): + req = Request(url) + req.method = method + action = middleware.get_action_name(req) + self.assertEqual(action, action_name) + verify('PUT', '/servers/4', 'PUT') + verify('DELETE', '/servers/4', 'DELETE') + verify('POST', '/images/4', 'POST') + verify('POST', '/servers/4', 'POST servers') + verify('GET', '/foo?a=4&changes-since=never&b=5', 'GET changes-since') + verify('GET', '/foo?a=4&monkeys-since=never&b=5', None) + verify('GET', '/servers/4', None) + verify('HEAD', '/servers/4', None) + + def TODO_test_call(self): + pass + #mw = make_middleware() + #req = build_request('DELETE', '/servers/4') + #for i in range(5): + # resp = req.get_response(mw) + # assert resp is OK + #resp = req.get_response(mw) + #assert resp is rate limited -- cgit From 63ad073efd0b20f59f02bc37182c0180cac3f405 Mon Sep 17 00:00:00 2001 From: Michael Gundlach Date: Wed, 15 Sep 2010 09:25:53 -0400 Subject: RateLimitingMiddleware tests --- nova/tests/api/rackspace/__init__.py | 51 +++++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 18 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/api/rackspace/__init__.py b/nova/tests/api/rackspace/__init__.py index f7537a4e7..2fab1a4da 100644 --- a/nova/tests/api/rackspace/__init__.py +++ b/nova/tests/api/rackspace/__init__.py @@ -17,22 +17,15 @@ import unittest -from nova.api.rackspace.ratelimiting import RateLimitingMiddleware +from nova.api.rackspace import RateLimitingMiddleware from nova.tests.api.test_helper import * from webob import Request class RateLimitingMiddlewareTest(unittest.TestCase): - def setUp(self): - self.middleware = RateLimitingMiddleware(APIStub()) - self.stubs = stubout.StubOutForTesting() - - def tearDown(self): - self.stubs.UnsetAll() - def test_get_action_name(self): middleware = RateLimitingMiddleware(APIStub()) def verify(method, url, action_name): - req = Request(url) + req = Request.blank(url) req.method = method action = middleware.get_action_name(req) self.assertEqual(action, action_name) @@ -45,12 +38,34 @@ class RateLimitingMiddlewareTest(unittest.TestCase): verify('GET', '/servers/4', None) verify('HEAD', '/servers/4', None) - def TODO_test_call(self): - pass - #mw = make_middleware() - #req = build_request('DELETE', '/servers/4') - #for i in range(5): - # resp = req.get_response(mw) - # assert resp is OK - #resp = req.get_response(mw) - #assert resp is rate limited + def exhaust(self, middleware, method, url, username, times): + req = Request.blank(url, dict(REQUEST_METHOD=method), + headers={'X-Auth-User': username}) + for i in range(times): + resp = req.get_response(middleware) + self.assertEqual(resp.status_int, 200) + resp = req.get_response(middleware) + self.assertEqual(resp.status_int, 413) + self.assertTrue('Retry-After' in resp.headers) + + def test_single_action(self): + middleware = RateLimitingMiddleware(APIStub()) + self.exhaust(middleware, 'DELETE', '/servers/4', 'usr1', 100) + self.exhaust(middleware, 'DELETE', '/servers/4', 'usr2', 100) + + def test_POST_servers_action_implies_POST_action(self): + middleware = RateLimitingMiddleware(APIStub()) + self.exhaust(middleware, 'POST', '/servers/4', 'usr1', 10) + self.exhaust(middleware, 'POST', '/images/4', 'usr2', 10) + self.assertTrue(set(middleware.limiter._levels) == + set(['usr1:POST', 'usr1:POST servers', 'usr2:POST'])) + + def test_POST_servers_action_correctly_ratelimited(self): + middleware = RateLimitingMiddleware(APIStub()) + # Use up all of our "POST" allowance for the minute, 5 times + for i in range(5): + self.exhaust(middleware, 'POST', '/servers/4', 'usr1', 10) + # Reset the 'POST' action counter. + del middleware.limiter._levels['usr1:POST'] + # All 50 daily "POST servers" actions should be all used up + self.exhaust(middleware, 'POST', '/servers/4', 'usr1', 0) -- cgit From f200587ce068482ab94e777154de3ac777269fa0 Mon Sep 17 00:00:00 2001 From: Michael Gundlach Date: Wed, 15 Sep 2010 13:54:38 -0400 Subject: Add support for middleware proxying to a ratelimiting.WSGIApp, for deployments that use more than one API Server and thus can't store ratelimiting counters in memory. --- nova/tests/api/rackspace/__init__.py | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'nova/tests') diff --git a/nova/tests/api/rackspace/__init__.py b/nova/tests/api/rackspace/__init__.py index 2fab1a4da..622cb4335 100644 --- a/nova/tests/api/rackspace/__init__.py +++ b/nova/tests/api/rackspace/__init__.py @@ -21,7 +21,9 @@ from nova.api.rackspace import RateLimitingMiddleware from nova.tests.api.test_helper import * from webob import Request + class RateLimitingMiddlewareTest(unittest.TestCase): + def test_get_action_name(self): middleware = RateLimitingMiddleware(APIStub()) def verify(method, url, action_name): @@ -69,3 +71,9 @@ class RateLimitingMiddlewareTest(unittest.TestCase): del middleware.limiter._levels['usr1:POST'] # All 50 daily "POST servers" actions should be all used up self.exhaust(middleware, 'POST', '/servers/4', 'usr1', 0) + + def test_proxy_ctor_works(self): + middleware = RateLimitingMiddleware(APIStub()) + self.assertEqual(middleware.limiter.__class__.__name__, "Limiter") + middleware = RateLimitingMiddleware(APIStub(), service_host='foobar') + self.assertEqual(middleware.limiter.__class__.__name__, "WSGIAppProxy") -- cgit From 7437df558f3277e21a4c34a5b517a1cae5dd5a74 Mon Sep 17 00:00:00 2001 From: Michael Gundlach Date: Wed, 15 Sep 2010 17:17:20 -0400 Subject: Support querying version list --- nova/tests/api/__init__.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/api/__init__.py b/nova/tests/api/__init__.py index 59c4adc3d..4682c094e 100644 --- a/nova/tests/api/__init__.py +++ b/nova/tests/api/__init__.py @@ -52,8 +52,9 @@ class Test(unittest.TestCase): result = webob.Request.blank('/test/cloud').get_response(api.API()) self.assertNotEqual(result.body, "/cloud") - def test_query_api_version(self): - pass + def test_query_api_versions(self): + result = webob.Request.blank('/').get_response(api.API()) + self.assertTrue('CURRENT' in result.body) if __name__ == '__main__': unittest.main() -- cgit