summaryrefslogtreecommitdiffstats
path: root/nova/tests
diff options
context:
space:
mode:
authorSoren Hansen <soren.hansen@rackspace.com>2010-07-27 17:42:41 +0000
committerTarmac <>2010-07-27 17:42:41 +0000
commita5f4a865b537d95acf5f02458824f95d30aac261 (patch)
tree83267302ef3792aa5f0273beff3e5257cda4bf7f /nova/tests
parentfae70b1a769f52cc4730e04fcec8fe82cc8bd1c6 (diff)
parentc4ffa57d4076b4aa5ed6262cdc2fece731b6875d (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.py109
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()