diff options
| author | Soren Hansen <soren.hansen@rackspace.com> | 2010-07-27 17:42:41 +0000 |
|---|---|---|
| committer | Tarmac <> | 2010-07-27 17:42:41 +0000 |
| commit | a5f4a865b537d95acf5f02458824f95d30aac261 (patch) | |
| tree | 83267302ef3792aa5f0273beff3e5257cda4bf7f /nova/tests | |
| parent | fae70b1a769f52cc4730e04fcec8fe82cc8bd1c6 (diff) | |
| parent | c4ffa57d4076b4aa5ed6262cdc2fece731b6875d (diff) | |
Makes the objectstore require authorization, checks it properly, and makes nova-compute provide it when fetching images.
Diffstat (limited to 'nova/tests')
| -rw-r--r-- | nova/tests/objectstore_unittest.py | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/nova/tests/objectstore_unittest.py b/nova/tests/objectstore_unittest.py index 8c6d866cd..c90120a6e 100644 --- a/nova/tests/objectstore_unittest.py +++ b/nova/tests/objectstore_unittest.py @@ -16,6 +16,7 @@ # License for the specific language governing permissions and limitations # under the License. +import boto import glob import hashlib import logging @@ -27,8 +28,12 @@ from nova import flags from nova import objectstore from nova import test from nova.auth import manager +from nova.objectstore.handler import S3 from nova.exception import NotEmpty, NotFound, NotAuthorized +from boto.s3.connection import S3Connection, OrdinaryCallingFormat +from twisted.internet import reactor, threads, defer +from twisted.web import http, server FLAGS = flags.FLAGS @@ -156,3 +161,107 @@ class ObjectStoreTestCase(test.BaseTestCase): self.context.user = self.um.get_user('user2') self.context.project = self.um.get_project('proj2') self.assertFalse(my_img.is_authorized(self.context)) + + +class TestHTTPChannel(http.HTTPChannel): + # Otherwise we end up with an unclean reactor + def checkPersistence(self, _, __): + return False + + +class TestSite(server.Site): + protocol = TestHTTPChannel + + +class S3APITestCase(test.TrialTestCase): + def setUp(self): + super(S3APITestCase, self).setUp() + + FLAGS.auth_driver='nova.auth.ldapdriver.FakeLdapDriver', + FLAGS.buckets_path = os.path.join(oss_tempdir, 'buckets') + + self.um = manager.AuthManager() + self.admin_user = self.um.create_user('admin', admin=True) + self.admin_project = self.um.create_project('admin', self.admin_user) + + shutil.rmtree(FLAGS.buckets_path) + os.mkdir(FLAGS.buckets_path) + + root = S3() + self.site = TestSite(root) + self.listening_port = reactor.listenTCP(0, self.site, interface='127.0.0.1') + self.tcp_port = self.listening_port.getHost().port + + + if not boto.config.has_section('Boto'): + boto.config.add_section('Boto') + boto.config.set('Boto', 'num_retries', '0') + self.conn = S3Connection(aws_access_key_id=self.admin_user.access, + aws_secret_access_key=self.admin_user.secret, + host='127.0.0.1', + port=self.tcp_port, + is_secure=False, + calling_format=OrdinaryCallingFormat()) + + # Don't attempt to reuse connections + def get_http_connection(host, is_secure): + return self.conn.new_http_connection(host, is_secure) + self.conn.get_http_connection = get_http_connection + + def _ensure_empty_list(self, l): + self.assertEquals(len(l), 0, "List was not empty") + return True + + def _ensure_only_bucket(self, l, name): + self.assertEquals(len(l), 1, "List didn't have exactly one element in it") + self.assertEquals(l[0].name, name, "Wrong name") + + def test_000_list_buckets(self): + d = threads.deferToThread(self.conn.get_all_buckets) + d.addCallback(self._ensure_empty_list) + return d + + def test_001_create_and_delete_bucket(self): + bucket_name = 'testbucket' + + d = threads.deferToThread(self.conn.create_bucket, bucket_name) + d.addCallback(lambda _:threads.deferToThread(self.conn.get_all_buckets)) + + def ensure_only_bucket(l, name): + self.assertEquals(len(l), 1, "List didn't have exactly one element in it") + self.assertEquals(l[0].name, name, "Wrong name") + d.addCallback(ensure_only_bucket, bucket_name) + + d.addCallback(lambda _:threads.deferToThread(self.conn.delete_bucket, bucket_name)) + d.addCallback(lambda _:threads.deferToThread(self.conn.get_all_buckets)) + d.addCallback(self._ensure_empty_list) + return d + + def test_002_create_bucket_and_key_and_delete_key_again(self): + bucket_name = 'testbucket' + key_name = 'somekey' + key_contents = 'somekey' + + d = threads.deferToThread(self.conn.create_bucket, bucket_name) + d.addCallback(lambda b:threads.deferToThread(b.new_key, key_name)) + d.addCallback(lambda k:threads.deferToThread(k.set_contents_from_string, key_contents)) + def ensure_key_contents(bucket_name, key_name, contents): + bucket = self.conn.get_bucket(bucket_name) + key = bucket.get_key(key_name) + self.assertEquals(key.get_contents_as_string(), contents, "Bad contents") + d.addCallback(lambda _:threads.deferToThread(ensure_key_contents, bucket_name, key_name, key_contents)) + def delete_key(bucket_name, key_name): + bucket = self.conn.get_bucket(bucket_name) + key = bucket.get_key(key_name) + key.delete() + d.addCallback(lambda _:threads.deferToThread(delete_key, bucket_name, key_name)) + d.addCallback(lambda _:threads.deferToThread(self.conn.get_bucket, bucket_name)) + d.addCallback(lambda b:threads.deferToThread(b.get_all_keys)) + d.addCallback(self._ensure_empty_list) + return d + + def tearDown(self): + self.um.delete_user('admin') + self.um.delete_project('admin') + return defer.DeferredList([defer.maybeDeferred(self.listening_port.stopListening)]) + super(S3APITestCase, self).tearDown() |
