You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@libcloud.apache.org by to...@apache.org on 2011/03/08 00:44:12 UTC

svn commit: r1079029 [13/13] - in /incubator/libcloud/trunk: ./ demos/ dist/ libcloud/ libcloud/common/ libcloud/compute/ libcloud/compute/drivers/ libcloud/drivers/ libcloud/storage/ libcloud/storage/drivers/ test/ test/compute/ test/compute/fixtures/...

Added: incubator/libcloud/trunk/test/compute/test_vpsnet.py
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/compute/test_vpsnet.py?rev=1079029&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/compute/test_vpsnet.py (added)
+++ incubator/libcloud/trunk/test/compute/test_vpsnet.py Mon Mar  7 23:44:06 2011
@@ -0,0 +1,209 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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 sys
+import unittest
+import exceptions
+import httplib
+
+from libcloud.compute.drivers.vpsnet import VPSNetNodeDriver
+from libcloud.compute.base import Node
+from libcloud.compute.types import NodeState
+
+from test import MockHttp
+from test.compute import TestCaseMixin
+
+from test.secrets import VPSNET_USER, VPSNET_KEY
+
+class VPSNetTests(unittest.TestCase, TestCaseMixin):
+
+    def setUp(self):
+        VPSNetNodeDriver.connectionCls.conn_classes = (None, VPSNetMockHttp)
+        self.driver = VPSNetNodeDriver(VPSNET_USER, VPSNET_KEY)
+
+    def test_create_node(self):
+        VPSNetMockHttp.type = 'create'
+        image = self.driver.list_images()[0]
+        size = self.driver.list_sizes()[0]
+        node = self.driver.create_node('foo', image, size)
+        self.assertEqual(node.name, 'foo')
+
+    def test_list_nodes(self):
+        VPSNetMockHttp.type = 'virtual_machines'
+        node = self.driver.list_nodes()[0]
+        self.assertEqual(node.id, '1384')
+        self.assertEqual(node.state, NodeState.RUNNING)
+
+    def test_reboot_node(self):
+        VPSNetMockHttp.type = 'virtual_machines'
+        node = self.driver.list_nodes()[0]
+
+        VPSNetMockHttp.type = 'reboot'
+        ret = self.driver.reboot_node(node)
+        self.assertEqual(ret, True)
+
+    def test_destroy_node(self):
+        VPSNetMockHttp.type = 'delete'
+        node = Node('2222', None, None, None, None, self.driver)
+        ret = self.driver.destroy_node(node)
+        self.assertTrue(ret)
+        VPSNetMockHttp.type = 'delete_fail'
+        node = Node('2223', None, None, None, None, self.driver)
+        self.assertRaises(exceptions.Exception, self.driver.destroy_node, node)
+
+    def test_list_images(self):
+        VPSNetMockHttp.type = 'templates'
+        ret = self.driver.list_images()
+        self.assertEqual(ret[0].id, '9')
+        self.assertEqual(ret[-1].id, '160')
+
+    def test_list_sizes(self):
+        VPSNetMockHttp.type = 'sizes'
+        ret = self.driver.list_sizes()
+        self.assertEqual(len(ret), 1)
+        self.assertEqual(ret[0].id, '1')
+        self.assertEqual(ret[0].name, '1 Node')
+
+    def test_destroy_node_response(self):
+        # should return a node object
+        node = Node('2222', None, None, None, None, self.driver)
+        VPSNetMockHttp.type = 'delete'
+        ret = self.driver.destroy_node(node)
+        self.assertTrue(isinstance(ret, bool))
+
+    def test_reboot_node_response(self):
+        # should return a node object
+        VPSNetMockHttp.type = 'virtual_machines'
+        node = self.driver.list_nodes()[0]
+        VPSNetMockHttp.type = 'reboot'
+        ret = self.driver.reboot_node(node)
+        self.assertTrue(isinstance(ret, bool))
+
+
+
+class VPSNetMockHttp(MockHttp):
+
+
+    def _nodes_api10json_sizes(self, method, url, body, headers):
+        body = """[{"slice":{"virtual_machine_id":8592,"id":12256,"consumer_id":0}},
+                   {"slice":{"virtual_machine_id":null,"id":12258,"consumer_id":0}},
+                   {"slice":{"virtual_machine_id":null,"id":12434,"consumer_id":0}}]"""
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _nodes_api10json_create(self, method, url, body, headers):
+        body = """[{"slice":{"virtual_machine_id":8592,"id":12256,"consumer_id":0}},
+                   {"slice":{"virtual_machine_id":null,"id":12258,"consumer_id":0}},
+                   {"slice":{"virtual_machine_id":null,"id":12434,"consumer_id":0}}]"""
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _virtual_machines_2222_api10json_delete_fail(self, method, url, body, headers):
+        return (httplib.FORBIDDEN, '', {}, httplib.responses[httplib.FORBIDDEN])
+
+    def _virtual_machines_2222_api10json_delete(self, method, url, body, headers):
+        return (httplib.OK, '', {}, httplib.responses[httplib.OK])
+
+    def _virtual_machines_1384_reboot_api10json_reboot(self, method, url, body, headers):
+        body = """{
+              "virtual_machine":
+                {
+                  "running": true,
+                  "updated_at": "2009-05-15T06:55:02-04:00",
+                  "power_action_pending": false,
+                  "system_template_id": 41,
+                  "id": 1384,
+                  "cloud_id": 3,
+                  "domain_name": "demodomain.com",
+                  "hostname": "web01",
+                  "consumer_id": 0,
+                  "backups_enabled": false,
+                  "password": "a8hjsjnbs91",
+                  "label": "foo",
+                  "slices_count": null,
+                  "created_at": "2009-04-16T08:17:39-04:00"
+                }
+              }"""
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _virtual_machines_api10json_create(self, method, url, body, headers):
+        body = """{
+              "virtual_machine":
+                {
+                  "running": true,
+                  "updated_at": "2009-05-15T06:55:02-04:00",
+                  "power_action_pending": false,
+                  "system_template_id": 41,
+                  "id": 1384,
+                  "cloud_id": 3,
+                  "domain_name": "demodomain.com",
+                  "hostname": "web01",
+                  "consumer_id": 0,
+                  "backups_enabled": false,
+                  "password": "a8hjsjnbs91",
+                  "label": "foo",
+                  "slices_count": null,
+                  "created_at": "2009-04-16T08:17:39-04:00"
+                }
+              }"""
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _virtual_machines_api10json_virtual_machines(self, method, url, body, headers):
+        body = """     [{
+              "virtual_machine":
+                {
+                  "running": true,
+                  "updated_at": "2009-05-15T06:55:02-04:00",
+                  "power_action_pending": false,
+                  "system_template_id": 41,
+                  "id": 1384,
+                  "cloud_id": 3,
+                  "domain_name": "demodomain.com",
+                  "hostname": "web01",
+                  "consumer_id": 0,
+                  "backups_enabled": false,
+                  "password": "a8hjsjnbs91",
+                  "label": "Web Server 01",
+                  "slices_count": null,
+                  "created_at": "2009-04-16T08:17:39-04:00"
+                }
+              },
+              {
+                "virtual_machine":
+                  {
+                    "running": true,
+                    "updated_at": "2009-05-15T06:55:02-04:00",
+                    "power_action_pending": false,
+                    "system_template_id": 41,
+                    "id": 1385,
+                    "cloud_id": 3,
+                    "domain_name": "demodomain.com",
+                    "hostname": "mysql01",
+                    "consumer_id": 0,
+                    "backups_enabled": false,
+                    "password": "dsi8h38hd2s",
+                    "label": "MySQL Server 01",
+                    "slices_count": null,
+                    "created_at": "2009-04-16T08:17:39-04:00"
+                  }
+                }]"""
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _available_clouds_api10json_templates(self, method, url, body, headers):
+        body = """[{"cloud":{"system_templates":[{"id":9,"label":"Ubuntu 8.04 x64"},{"id":10,"label":"CentOS 5.2 x64"},{"id":11,"label":"Gentoo 2008.0 x64"},{"id":18,"label":"Ubuntu 8.04 x64 LAMP"},{"id":19,"label":"Ubuntu 8.04 x64 MySQL"},{"id":20,"label":"Ubuntu 8.04 x64 Postfix"},{"id":21,"label":"Ubuntu 8.04 x64 Apache"},{"id":22,"label":"CentOS 5.2 x64 MySQL"},{"id":23,"label":"CentOS 5.2 x64 LAMP"},{"id":24,"label":"CentOS 5.2 x64 HAProxy"},{"id":25,"label":"CentOS 5.2 x64 Postfix"},{"id":26,"label":"CentOS 5.2 x64 Varnish"},{"id":27,"label":"CentOS 5.2 x64 Shoutcast"},{"id":28,"label":"CentOS 5.2 x64 Apache"},{"id":40,"label":"cPanel"},{"id":42,"label":"Debian 5.0 (Lenny) x64"},{"id":58,"label":"Django on Ubuntu 8.04 (x86)"},{"id":59,"label":"Drupal 5 on Ubuntu 8.04 (x86)"},{"id":60,"label":"Drupal 6 on Ubuntu 8.04 (x86)"},{"id":61,"label":"Google App Engine on Ubuntu 8.04 (x86)"},{"id":62,"label":"LAMP on Ubuntu 8.04 (x86)"},{"id":63,"label":"LAPP on Ubuntu 8.04 (x86
 )"},{"id":64,"label":"MediaWiki on Ubuntu 8.04 (x86)"},{"id":65,"label":"MySQL on Ubuntu 8.04 (x86)"},{"id":66,"label":"phpBB on Ubuntu 8.04 (x86)"},{"id":67,"label":"PostgreSQL on Ubuntu 8.04 (x86)"},{"id":68,"label":"Rails on Ubuntu 8.04 (x86)"},{"id":69,"label":"Tomcat on Ubuntu 8.04 (x86)"},{"id":70,"label":"Wordpress on Ubuntu 8.04 (x86)"},{"id":71,"label":"Joomla on Ubuntu 8.04 (x86)"},{"id":72,"label":"Ubuntu 8.04 Default Install (turnkey)"},{"id":128,"label":"CentOS Optimised"},{"id":129,"label":"Optimised CentOS + Apache + MySQL + PHP"},{"id":130,"label":"Optimised CentOS + Apache + MySQL + Ruby"},{"id":131,"label":"Optimised CentOS + Apache + MySQL + Ruby + PHP"},{"id":132,"label":"Debian Optimised"},{"id":133,"label":"Optimised Debian + Apache + MySQL + PHP"},{"id":134,"label":"Optimised Debian + NGINX + MySQL + PHP"},{"id":135,"label":"Optimised Debian + Lighttpd + MySQL + PHP"},{"id":136,"label":"Optimised Debian + Apache + MySQL + Ruby + PHP"},{"id":137,"label"
 :"Optimised Debian + Apache + MySQL + Ruby"},{"id":138,"label":"Optimised Debian + NGINX + MySQL + Ruby + PHP"},{"id":139,"label":"Optimised Debian + NGINX + MySQL + Ruby"},{"id":140,"label":"Optimised Debian + Apache + MySQL + PHP + Magento"},{"id":141,"label":"Optimised Debian + NGINX + MySQL + PHP + Magento"},{"id":142,"label":"Optimised Debian + Lighttpd + MySQL + PHP + Wordpress"}],"id":2,"label":"USA VPS Cloud"}},{"cloud":{"system_templates":[{"id":15,"label":"Ubuntu 8.04 x64"},{"id":16,"label":"CentOS 5.2 x64"},{"id":17,"label":"Gentoo 2008.0 x64"},{"id":29,"label":"Ubuntu 8.04 x64 LAMP"},{"id":30,"label":"Ubuntu 8.04 x64 MySQL"},{"id":31,"label":"Ubuntu 8.04 x64 Postfix"},{"id":32,"label":"Ubuntu 8.04 x64 Apache"},{"id":33,"label":"CentOS 5.2 x64 MySQL"},{"id":34,"label":"CentOS 5.2 x64 LAMP"},{"id":35,"label":"CentOS 5.2 x64 HAProxy"},{"id":36,"label":"CentOS 5.2 x64 Postfix"},{"id":37,"label":"CentOS 5.2 x64 Varnish"},{"id":38,"label":"CentOS 5.2 x64 Shoutcast"},{"
 id":39,"label":"CentOS 5.2 x64 Apache"},{"id":41,"label":"cPanel"},{"id":43,"label":"Debian 5.0 (Lenny) x64"},{"id":44,"label":"Django on Ubuntu 8.04 (x86)"},{"id":45,"label":"Drupal 5 on Ubuntu 8.04 (x86)"},{"id":46,"label":"Drupal 6 on Ubuntu 8.04 (x86)"},{"id":47,"label":"Google App Engine on Ubuntu 8.04 (x86)"},{"id":48,"label":"LAMP on Ubuntu 8.04 (x86)"},{"id":49,"label":"LAPP on Ubuntu 8.04 (x86)"},{"id":50,"label":"MediaWiki on Ubuntu 8.04 (x86)"},{"id":51,"label":"MySQL on Ubuntu 8.04 (x86)"},{"id":52,"label":"phpBB on Ubuntu 8.04 (x86)"},{"id":53,"label":"PostgreSQL on Ubuntu 8.04 (x86)"},{"id":54,"label":"Rails on Ubuntu 8.04 (x86)"},{"id":55,"label":"Tomcat on Ubuntu 8.04 (x86)"},{"id":56,"label":"Wordpress on Ubuntu 8.04 (x86)"},{"id":57,"label":"Joomla on Ubuntu 8.04 (x86)"},{"id":73,"label":"Ubuntu 8.04 Default Install (turnkey)"},{"id":148,"label":"CentOS Optimised"},{"id":149,"label":"Optimised CentOS + Apache + MySQL + PHP"},{"id":150,"label":"Optimised Cen
 tOS + Apache + MySQL + Ruby"},{"id":151,"label":"Optimised CentOS + Apache + MySQL + Ruby + PHP"},{"id":152,"label":"Debian Optimised"},{"id":153,"label":"Optimised Debian + Apache + MySQL + PHP"},{"id":154,"label":"Optimised Debian + NGINX + MySQL + PHP"},{"id":155,"label":"Optimised Debian + Lighttpd + MySQL + PHP"},{"id":156,"label":"Optimised Debian + Apache + MySQL + Ruby + PHP"},{"id":157,"label":"Optimised Debian + Apache + MySQL + Ruby"},{"id":158,"label":"Optimised Debian + NGINX + MySQL + Ruby + PHP"},{"id":159,"label":"Optimised Debian + NGINX + MySQL + Ruby"},{"id":160,"label":"Optimised Debian + Lighttpd + MySQL + PHP + Wordpress"}],"id":3,"label":"UK VPS Cloud"}}]"""
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+    def _available_clouds_api10json_create(self, method, url, body, headers):
+        body = """[{"cloud":{"system_templates":[{"id":9,"label":"Ubuntu 8.04 x64"}],"id":2,"label":"USA VPS Cloud"}}]"""
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+if __name__ == '__main__':
+    sys.exit(unittest.main())

Added: incubator/libcloud/trunk/test/file_fixtures.py
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/file_fixtures.py?rev=1079029&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/file_fixtures.py (added)
+++ incubator/libcloud/trunk/test/file_fixtures.py Mon Mar  7 23:44:06 2011
@@ -0,0 +1,46 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+# Helper class for loading large fixture data
+
+import os
+
+FIXTURES_ROOT = {
+    'compute': 'compute/fixtures',
+    'storage': 'storage/fixtures'
+}
+
+class FileFixtures(object):
+    def __init__(self, fixtures_type, sub_dir=''):
+        script_dir = os.path.abspath(os.path.split(__file__)[0])
+        self.root = os.path.join(script_dir, FIXTURES_ROOT[fixtures_type], 
+                                 sub_dir)
+
+    def load(self, file):
+        path = os.path.join(self.root, file)
+        if os.path.exists(path):
+            return open(path, 'r').read()
+        else:
+            raise IOError
+
+class ComputeFileFixtures(FileFixtures):
+    def __init__(self, sub_dir=''):
+        super(ComputeFileFixtures, self).__init__(fixtures_type='compute',
+                                                  sub_dir=sub_dir)
+
+class StorageFileFixtures(FileFixtures):
+    def __init__(self, sub_dir=''):
+        super(StorageFileFixtures, self).__init__(fixtures_type='storage',
+                                                  sub_dir=sub_dir)

Added: incubator/libcloud/trunk/test/secrets.py
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/secrets.py?rev=1079029&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/secrets.py (added)
+++ incubator/libcloud/trunk/test/secrets.py Mon Mar  7 23:44:06 2011
@@ -0,0 +1,64 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+# Make a copy of this file named 'secrets.py' and add your credentials there.
+# Note you can run unit tests without setting your credentials.
+
+# for test_ec2.py
+EC2_ACCESS_ID='YoUR K3Y'
+EC2_SECRET='secr3t'
+
+ELASTICHOSTS_USER=''
+ELASTICHOSTS_KEY=''
+
+BRIGHTBOX_CLIENT_ID=''
+BRIGHTBOX_CLIENT_SECRET=''
+
+
+RACKSPACE_USER=''
+RACKSPACE_KEY=''
+
+SLICEHOST_KEY=''
+
+VPSNET_USER=''
+VPSNET_KEY=''
+
+GOGRID_API_KEY=''
+GOGRID_SECRET=''
+
+LINODE_KEY=''
+
+HOSTINGCOM_USER=''
+HOSTINGCOM_SECRET=''
+
+TERREMARK_USER=''
+TERREMARK_SECRET=''
+
+SOFTLAYER_USER=''
+SOFTLAYER_APIKEY=''
+
+VOXEL_KEY=''
+VOXEL_SECRET=''
+
+ECP_USER_NAME=''
+ECP_PASSWORD=''
+
+IBM_USER=''
+IBM_SECRET=''
+
+OPENNEBULA_USER=''
+OPENNEBULA_KEY=''
+
+DREAMHOST_KEY=''

Added: incubator/libcloud/trunk/test/secrets.py-dist
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/secrets.py-dist?rev=1079029&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/secrets.py-dist (added)
+++ incubator/libcloud/trunk/test/secrets.py-dist Mon Mar  7 23:44:06 2011
@@ -0,0 +1,60 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+# Make a copy of this file named 'secrets.py' and add your credentials there.
+# Note you can run unit tests without setting your credentials.
+
+# for test_ec2.py
+EC2_ACCESS_ID='YoUR K3Y'
+EC2_SECRET='secr3t'
+
+BRIGHTBOX_CLIENT_ID=''
+BRIGHTBOX_CLIENT_SECRET=''
+
+RACKSPACE_USER=''
+RACKSPACE_KEY=''
+
+SLICEHOST_KEY=''
+
+VPSNET_USER=''
+VPSNET_KEY=''
+
+GOGRID_API_KEY=''
+GOGRID_SECRET=''
+
+LINODE_KEY=''
+
+HOSTINGCOM_USER=''
+HOSTINGCOM_SECRET=''
+
+TERREMARK_USER=''
+TERREMARK_SECRET=''
+
+SOFTLAYER_USER=''
+SOFTLAYER_APIKEY=''
+
+VOXEL_KEY=''
+VOXEL_SECRET=''
+
+ECP_USER_NAME=''
+ECP_PASSWORD=''
+
+IBM_USER=''
+IBM_SECRET=''
+
+OPENNEBULA_USER=''
+OPENNEBULA_KEY=''
+
+DREAMHOST_KEY=''

Added: incubator/libcloud/trunk/test/storage/__init__.py
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/storage/__init__.py?rev=1079029&view=auto
==============================================================================
    (empty)

Added: incubator/libcloud/trunk/test/storage/fixtures/cloudfiles/list_container_objects.json
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/storage/fixtures/cloudfiles/list_container_objects.json?rev=1079029&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/storage/fixtures/cloudfiles/list_container_objects.json (added)
+++ incubator/libcloud/trunk/test/storage/fixtures/cloudfiles/list_container_objects.json Mon Mar  7 23:44:06 2011
@@ -0,0 +1,14 @@
+[
+    {"name":"foo test 1","hash":"16265549b5bda64ecdaa5156de4c97cc",
+     "bytes":1160520,"content_type":"application/zip",
+     "last_modified":"2011-01-25T22:01:50.351810"},
+     {"name":"foo test 2","hash":"16265549b5bda64ecdaa5156de4c97bb",
+     "bytes":1160520,"content_type":"application/zip",
+     "last_modified":"2011-01-25T22:01:50.351810"},
+    {"name":"foo tes 3","hash":"16265549b5bda64ecdaa5156de4c97ee",
+      "bytes":1160520,"content_type":"application/zip",
+      "last_modified":"2011-01-25T22:01:46.549890"},
+    {"name":"foo test 3","hash":"16265549b5bda64ecdaa5156de4c97ff",
+     "bytes":1160520,"content_type":"application/text",
+     "last_modified":"2011-01-25T22:01:50.351810"}
+]

Added: incubator/libcloud/trunk/test/storage/fixtures/cloudfiles/list_container_objects_empty.json
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/storage/fixtures/cloudfiles/list_container_objects_empty.json?rev=1079029&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/storage/fixtures/cloudfiles/list_container_objects_empty.json (added)
+++ incubator/libcloud/trunk/test/storage/fixtures/cloudfiles/list_container_objects_empty.json Mon Mar  7 23:44:06 2011
@@ -0,0 +1 @@
+{}

Added: incubator/libcloud/trunk/test/storage/fixtures/cloudfiles/list_containers.json
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/storage/fixtures/cloudfiles/list_containers.json?rev=1079029&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/storage/fixtures/cloudfiles/list_containers.json (added)
+++ incubator/libcloud/trunk/test/storage/fixtures/cloudfiles/list_containers.json Mon Mar  7 23:44:06 2011
@@ -0,0 +1,5 @@
+[
+    {"name":"container1","count":4,"bytes":3484450},
+    {"name":"container2","count":120,"bytes":340084450},
+    {"name":"container3","count":0,"bytes":0}
+]

Added: incubator/libcloud/trunk/test/storage/fixtures/cloudfiles/list_containers_empty.json
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/storage/fixtures/cloudfiles/list_containers_empty.json?rev=1079029&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/storage/fixtures/cloudfiles/list_containers_empty.json (added)
+++ incubator/libcloud/trunk/test/storage/fixtures/cloudfiles/list_containers_empty.json Mon Mar  7 23:44:06 2011
@@ -0,0 +1 @@
+{}

Added: incubator/libcloud/trunk/test/storage/fixtures/cloudfiles/meta_data.json
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/storage/fixtures/cloudfiles/meta_data.json?rev=1079029&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/storage/fixtures/cloudfiles/meta_data.json (added)
+++ incubator/libcloud/trunk/test/storage/fixtures/cloudfiles/meta_data.json Mon Mar  7 23:44:06 2011
@@ -0,0 +1 @@
+{"bytes_used": 1234567, "container_count": 10, "object_count": 400}

Added: incubator/libcloud/trunk/test/storage/test_cloudfiles.py
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/storage/test_cloudfiles.py?rev=1079029&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/storage/test_cloudfiles.py (added)
+++ incubator/libcloud/trunk/test/storage/test_cloudfiles.py Mon Mar  7 23:44:06 2011
@@ -0,0 +1,529 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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 os
+import os.path
+import random
+import sys
+import copy
+import unittest
+import httplib
+
+import libcloud.utils
+
+from libcloud.common.types import LibcloudError
+from libcloud.storage.base import Container, Object
+from libcloud.storage.types import ContainerAlreadyExistsError
+from libcloud.storage.types import ContainerDoesNotExistError
+from libcloud.storage.types import ContainerIsNotEmptyError
+from libcloud.storage.types import ObjectDoesNotExistError
+from libcloud.storage.types import ObjectHashMismatchError
+from libcloud.storage.drivers.cloudfiles import CloudFilesStorageDriver
+from libcloud.storage.drivers.dummy import DummyFileObject, DummyIterator
+
+from test import MockHttp, MockRawResponse
+from test.file_fixtures import StorageFileFixtures
+
+class CloudFilesTests(unittest.TestCase):
+
+    def setUp(self):
+        CloudFilesStorageDriver.connectionCls.conn_classes = (None,
+                                                              CloudFilesMockHttp)
+        CloudFilesStorageDriver.connectionCls.rawResponseCls = CloudFilesMockRawResponse
+        CloudFilesMockHttp.type = None
+        CloudFilesMockRawResponse.type = None
+        self.driver = CloudFilesStorageDriver('dummy', 'dummy')
+        self._remove_test_file()
+
+    def tearDown(self):
+        self._remove_test_file()
+
+    def test_get_meta_data(self):
+        meta_data = self.driver.get_meta_data()
+
+    def test_list_containers(self):
+        CloudFilesMockHttp.type = 'EMPTY'
+        containers = self.driver.list_containers()
+        self.assertEqual(len(containers), 0)
+
+        CloudFilesMockHttp.type = None
+        containers = self.driver.list_containers()
+        self.assertEqual(len(containers), 3)
+
+        container = [c for c in containers if c.name == 'container2'][0]
+        self.assertEqual(container.extra['object_count'], 120)
+        self.assertEqual(container.extra['size'], 340084450)
+
+    def test_list_container_objects(self):
+        CloudFilesMockHttp.type = 'EMPTY'
+        container = Container(name='test_container', extra={}, driver=self.driver)
+        objects = self.driver.list_container_objects(container=container)
+        self.assertEqual(len(objects), 0)
+
+        CloudFilesMockHttp.type = None
+        objects = self.driver.list_container_objects(container=container)
+        self.assertEqual(len(objects), 4)
+
+        obj = [o for o in objects if o.name == 'foo test 1'][0]
+        self.assertEqual(obj.hash, '16265549b5bda64ecdaa5156de4c97cc')
+        self.assertEqual(obj.size, 1160520)
+        self.assertEqual(obj.container.name, 'test_container')
+
+    def test_get_container(self):
+        container = self.driver.get_container(container_name='test_container')
+        self.assertEqual(container.name, 'test_container')
+        self.assertEqual(container.extra['object_count'], 800)
+        self.assertEqual(container.extra['size'], 1234568)
+
+    def test_get_object(self):
+        obj = self.driver.get_object(container_name='test_container',
+                                     object_name='test_object')
+        self.assertEqual(obj.container.name, 'test_container')
+        self.assertEqual(obj.size, 555)
+        self.assertEqual(obj.extra['content_type'], 'application/zip')
+        self.assertEqual(obj.extra['etag'], '6b21c4a111ac178feacf9ec9d0c71f17')
+        self.assertEqual(obj.extra['last_modified'], 'Tue, 25 Jan 2011 22:01:49 GMT')
+        self.assertEqual(obj.meta_data['foo-bar'], 'test 1')
+        self.assertEqual(obj.meta_data['bar-foo'], 'test 2')
+
+    def test_create_container_success(self):
+        container = self.driver.create_container(container_name='test_create_container')
+        self.assertTrue(isinstance(container, Container))
+        self.assertEqual(container.name, 'test_create_container')
+        self.assertEqual(container.extra['object_count'], 0)
+
+    def test_create_container_already_exists(self):
+        CloudFilesMockHttp.type = 'ALREADY_EXISTS'
+
+        try:
+            container = self.driver.create_container(container_name='test_create_container')
+        except ContainerAlreadyExistsError:
+            pass
+        else:
+            self.fail('Container already exists but an exception was not thrown')
+
+    def test_create_container_invalid_name(self):
+        try:
+            container = self.driver.create_container(container_name='invalid//name/')
+        except:
+            pass
+        else:
+            self.fail('Invalid name was provided (name contains slashes), but exception was not thrown')
+
+    def test_create_container_invalid_name(self):
+        name = ''.join([ 'x' for x in range(0, 257)])
+        try:
+            container = self.driver.create_container(container_name=name)
+        except:
+            pass
+        else:
+            self.fail('Invalid name was provided (name is too long), but exception was not thrown')
+
+    def test_delete_container_success(self):
+        container = Container(name='foo_bar_container', extra={}, driver=self)
+        result = self.driver.delete_container(container=container)
+        self.assertTrue(result)
+
+    def test_delete_container_not_found(self):
+        CloudFilesMockHttp.type = 'NOT_FOUND'
+        container = Container(name='foo_bar_container', extra={}, driver=self)
+        try:
+            result = self.driver.delete_container(container=container)
+        except ContainerDoesNotExistError:
+            pass
+        else:
+            self.fail('Container does not exist but an exception was not thrown')
+
+    def test_delete_container_not_empty(self):
+        CloudFilesMockHttp.type = 'NOT_EMPTY'
+        container = Container(name='foo_bar_container', extra={}, driver=self)
+        try:
+            result = self.driver.delete_container(container=container)
+        except ContainerIsNotEmptyError:
+            pass
+        else:
+            self.fail('Container is not empty but an exception was not thrown')
+
+    def test_download_object_success(self):
+        container = Container(name='foo_bar_container', extra={}, driver=self)
+        obj = Object(name='foo_bar_object', size=1000, hash=None, extra={},
+                     container=container, meta_data=None,
+                     driver=CloudFilesStorageDriver)
+        destination_path = os.path.abspath(__file__) + '.temp'
+        result = self.driver.download_object(obj=obj,
+                                             destination_path=destination_path,
+                                             overwrite_existing=False,
+                                             delete_on_failure=True)
+        self.assertTrue(result)
+
+    def test_download_object_invalid_file_size(self):
+        CloudFilesMockRawResponse.type = 'INVALID_SIZE'
+        container = Container(name='foo_bar_container', extra={}, driver=self)
+        obj = Object(name='foo_bar_object', size=1000, hash=None, extra={},
+                     container=container, meta_data=None,
+                     driver=CloudFilesStorageDriver)
+        destination_path = os.path.abspath(__file__) + '.temp'
+        result = self.driver.download_object(obj=obj,
+                                             destination_path=destination_path,
+                                             overwrite_existing=False,
+                                             delete_on_failure=True)
+        self.assertFalse(result)
+
+    def download_object_success_not_found(self):
+        CloudFilesMockHttp.type = 'NOT_FOUND'
+        obj = Object(name='foo_bar_object', size=1000, hash=None, extra={},
+                     container=container, meta_data=None,
+                     driver=CloudFilesStorageDriver)
+        destination_path = os.path.abspath(__file__)
+        try:
+            result = self.driver.download_object(obj=obj,
+                                                 destination_path=destination_path,
+                                                 overwrite_existing=False,
+                                                 delete_on_failure=True)
+        except ObjectDoesNotExistError:
+            pass
+        else:
+            self.fail('Object does not exist but an exception was not thrown')
+
+    def object_as_stream(self):
+        pass
+
+    def test_upload_object_success(self):
+        def upload_file(self, response, file_path, chunked=False,
+                     calculate_hash=True):
+            return True, 'hash343hhash89h932439jsaa89', 1000
+
+        old_func = CloudFilesStorageDriver._upload_file
+        CloudFilesStorageDriver._upload_file = upload_file
+        file_path = os.path.abspath(__file__)
+        container = Container(name='foo_bar_container', extra={}, driver=self)
+        object_name = 'foo_test_upload'
+        obj = self.driver.upload_object(file_path=file_path, container=container,
+                                        object_name=object_name)
+        self.assertEqual(obj.name, 'foo_test_upload')
+        self.assertEqual(obj.size, 1000)
+        CloudFilesStorageDriver._upload_file = old_func
+
+    def test_upload_object_invalid_hash(self):
+        def upload_file(self, response, file_path, chunked=False,
+                     calculate_hash=True):
+            return True, 'hash343hhash89h932439jsaa89', 1000
+
+        CloudFilesMockRawResponse.type = 'INVALID_HASH'
+
+        old_func = CloudFilesStorageDriver._upload_file
+        CloudFilesStorageDriver._upload_file = upload_file
+        file_path = os.path.abspath(__file__)
+        container = Container(name='foo_bar_container', extra={}, driver=self)
+        object_name = 'foo_test_upload'
+        try:
+            obj = self.driver.upload_object(file_path=file_path, container=container,
+                                            object_name=object_name,
+                                            file_hash='footest123')
+        except ObjectHashMismatchError:
+            pass
+        else:
+            self.fail('Invalid hash was returned but an exception was not thrown')
+        finally:
+            CloudFilesStorageDriver._upload_file = old_func
+
+    def test_upload_object_no_content_type(self):
+        def no_content_type(name):
+            return None, None
+
+        old_func = libcloud.utils.guess_file_mime_type
+        libcloud.utils.guess_file_mime_type = no_content_type
+        file_path = os.path.abspath(__file__)
+        container = Container(name='foo_bar_container', extra={}, driver=self)
+        object_name = 'foo_test_upload'
+        try:
+            obj = self.driver.upload_object(file_path=file_path, container=container,
+                                            object_name=object_name)
+        except AttributeError:
+            pass
+        else:
+            self.fail('File content type not provided but an exception was not thrown')
+        finally:
+            libcloud.utils.guess_file_mime_type = old_func
+
+    # TODO: Add test for upload_object throwing a LibcloudError
+
+    def test_upload_object_inexistent_file(self):
+        def dummy_content_type(name):
+            return 'application/zip', None
+
+        old_func = libcloud.utils.guess_file_mime_type
+        libcloud.utils.guess_file_mime_type = dummy_content_type
+
+        file_path = os.path.abspath(__file__ + '.inexistent')
+        container = Container(name='foo_bar_container', extra={}, driver=self)
+        object_name = 'foo_test_upload'
+        try:
+            obj = self.driver.upload_object(file_path=file_path, container=container,
+                                            object_name=object_name)
+        except OSError:
+            pass
+        else:
+            self.fail('Timeout while uploading but an exception was not thrown')
+        finally:
+            libcloud.utils.guess_file_mime_type = old_func
+
+    def test_stream_object_data(self):
+        def dummy_content_type(name):
+            return 'application/zip', None
+
+        old_func = libcloud.utils.guess_file_mime_type
+        libcloud.utils.guess_file_mime_type = dummy_content_type
+
+        container = Container(name='foo_bar_container', extra={}, driver=self)
+        object_name = 'foo_test_stream_data'
+        iterator = DummyIterator(data=['2', '3', '5'])
+        try:
+            obj = self.driver.stream_object_data(container=container,
+                                                 object_name=object_name,
+                                                 iterator=iterator)
+        finally:
+            libcloud.utils.guess_file_mime_type = old_func
+
+    def test_delete_object_success(self):
+        container = Container(name='foo_bar_container', extra={}, driver=self)
+        obj = Object(name='foo_bar_object', size=1000, hash=None, extra={},
+                     container=container, meta_data=None,
+                     driver=CloudFilesStorageDriver)
+        result = self.driver.delete_object(obj=obj)
+        self.assertTrue(result)
+
+    def test_delete_object_success(self):
+        CloudFilesMockHttp.type = 'NOT_FOUND'
+        container = Container(name='foo_bar_container', extra={}, driver=self)
+        obj = Object(name='foo_bar_object', size=1000, hash=None, extra={},
+                     container=container, meta_data=None,
+                     driver=CloudFilesStorageDriver)
+        try:
+            result = self.driver.delete_object(obj=obj)
+        except ObjectDoesNotExistError:
+            pass
+        else:
+            self.fail('Object does not exist but an exception was not thrown')
+
+    def _remove_test_file(self):
+        file_path = os.path.abspath(__file__) + '.temp'
+
+        try:
+            os.unlink(file_path)
+        except OSError:
+            pass
+
+class CloudFilesMockHttp(MockHttp):
+
+    fixtures = StorageFileFixtures('cloudfiles')
+    base_headers = { 'content-type': 'application/json; charset=UTF-8'}
+
+    def putrequest(self, method, action):
+        pass
+
+    def putheader(self, key, value):
+        pass
+
+    def endheaders(self):
+        pass
+
+    def send(self, data):
+      pass
+
+    # fake auth token response
+    def _v1_0(self, method, url, body, headers):
+        headers = copy.deepcopy(self.base_headers)
+        headers.update({ 'x-server-management-url': 'https://servers.api.rackspacecloud.com/v1.0/slug',
+                         'x-auth-token': 'FE011C19',
+                         'x-cdn-management-url': 'https://cdn.clouddrive.com/v1/MossoCloudFS',
+                         'x-storage-token': 'FE011C19',
+                         'x-storage-url': 'https://storage4.clouddrive.com/v1/MossoCloudFS'})
+        return (httplib.NO_CONTENT, "", headers, httplib.responses[httplib.NO_CONTENT])
+
+    def _v1_MossoCloudFS_EMPTY(self, method, url, body, headers):
+        body = self.fixtures.load('list_containers_empty.json')
+        return (httplib.OK, body, self.base_headers, httplib.responses[httplib.OK])
+
+    def _v1_MossoCloudFS(self, method, url, body, headers):
+        if method == 'GET':
+            # list_containers
+            body = self.fixtures.load('list_containers.json')
+            status_code = httplib.OK
+            headers = copy.deepcopy(self.base_headers)
+        elif method == 'HEAD':
+            # get_meta_data
+            body = self.fixtures.load('meta_data.json')
+            status_code = httplib.NO_CONTENT
+            headers = copy.deepcopy(self.base_headers)
+            headers.update({ 'x-account-container-count': 10,
+                             'x-account-object-count': 400,
+                             'x-account-bytes-used': 1234567
+                           })
+        return (status_code, body, headers, httplib.responses[httplib.OK])
+
+    def _v1_MossoCloudFS_test_container_EMPTY(self, method, url, body, headers):
+        body = self.fixtures.load('list_container_objects_empty.json')
+        return (httplib.OK, body, self.base_headers, httplib.responses[httplib.OK])
+
+    def _v1_MossoCloudFS_test_container(self, method, url, body, headers):
+        if method == 'GET':
+            # list_container_objects
+            body = self.fixtures.load('list_container_objects.json')
+            status_code = httplib.OK
+            headers = copy.deepcopy(self.base_headers)
+        elif method == 'HEAD':
+            # get_container
+            body = self.fixtures.load('list_container_objects_empty.json')
+            status_code = httplib.NO_CONTENT
+            headers = copy.deepcopy(self.base_headers)
+            headers.update({ 'x-container-object-count': 800,
+                             'x-container-bytes-used': 1234568
+                           })
+        return (status_code, body, headers, httplib.responses[httplib.OK])
+
+    def _v1_MossoCloudFS_test_container_test_object(self, method, url, body,
+                                                    headers):
+        if method == 'HEAD':
+            # get_object
+            body = self.fixtures.load('list_container_objects_empty.json')
+            status_code = httplib.NO_CONTENT
+            headers = self.base_headers
+            headers.update({ 'content-length': 555,
+                             'last-modified': 'Tue, 25 Jan 2011 22:01:49 GMT',
+                             'etag': '6b21c4a111ac178feacf9ec9d0c71f17',
+                             'x-object-meta-foo-bar': 'test 1',
+                             'x-object-meta-bar-foo': 'test 2',
+                             'content-type': 'application/zip'})
+        return (status_code, body, headers, httplib.responses[httplib.OK])
+
+    def _v1_MossoCloudFS_test_create_container(self, method, url, body, headers):
+        # test_create_container_success
+        body = self.fixtures.load('list_container_objects_empty.json')
+        headers = self.base_headers
+        headers.update({ 'content-length': 18,
+                         'date': 'Mon, 28 Feb 2011 07:52:57 GMT'
+                       })
+        status_code = httplib.CREATED
+        return (status_code, body, headers, httplib.responses[httplib.OK])
+
+    def _v1_MossoCloudFS_test_create_container_ALREADY_EXISTS(self, method, url, body, headers):
+        # test_create_container_already_exists
+        body = self.fixtures.load('list_container_objects_empty.json')
+        headers = self.base_headers
+        headers.update({ 'content-type': 'text/plain' })
+        status_code = httplib.ACCEPTED
+        return (status_code, body, headers, httplib.responses[httplib.OK])
+
+    def _v1_MossoCloudFS_foo_bar_container(self, method, url, body, headers):
+        if method == 'DELETE':
+            # test_delete_container_success
+            body = self.fixtures.load('list_container_objects_empty.json')
+            headers = self.base_headers
+            status_code = httplib.NO_CONTENT
+        return (status_code, body, headers, httplib.responses[httplib.OK])
+
+    def _v1_MossoCloudFS_foo_bar_container_NOT_FOUND(self, method, url, body, headers):
+        if method == 'DELETE':
+            # test_delete_container_not_found
+            body = self.fixtures.load('list_container_objects_empty.json')
+            headers = self.base_headers
+            status_code = httplib.NOT_FOUND
+        return (status_code, body, headers, httplib.responses[httplib.OK])
+
+    def _v1_MossoCloudFS_foo_bar_container_NOT_EMPTY(self, method, url, body, headers):
+        if method == 'DELETE':
+            # test_delete_container_not_empty
+            body = self.fixtures.load('list_container_objects_empty.json')
+            headers = self.base_headers
+            status_code = httplib.CONFLICT
+        return (status_code, body, headers, httplib.responses[httplib.OK])
+
+    def _v1_MossoCloudFS_foo_bar_container_foo_bar_object(self, method, url, body, headers):
+        if method == 'DELETE':
+            # test_delete_object_success
+            body = self.fixtures.load('list_container_objects_empty.json')
+            headers = self.base_headers
+            status_code = httplib.NO_CONTENT
+        return (status_code, body, headers, httplib.responses[httplib.OK])
+
+    def _v1_MossoCloudFS_foo_bar_container_foo_bar_object_NOT_FOUND(self, method, url, body, headers):
+        if method == 'DELETE':
+            # test_delete_object_success
+            body = self.fixtures.load('list_container_objects_empty.json')
+            headers = self.base_headers
+            status_code = httplib.NOT_FOUND
+        return (status_code, body, headers, httplib.responses[httplib.OK])
+
+class CloudFilesMockRawResponse(MockRawResponse):
+
+    fixtures = StorageFileFixtures('cloudfiles')
+    base_headers = { 'content-type': 'application/json; charset=UTF-8'}
+
+    def __init__(self, *args, **kwargs):
+      super(CloudFilesMockRawResponse, self).__init__(*args, **kwargs)
+      self._data = []
+      self._current_item = 0
+
+    def next(self):
+        if self._current_item == len(self._data):
+          raise StopIteration
+
+        value = self._data[self._current_item]
+        self._current_item += 1
+        return value
+
+    def _generate_random_data(self, size):
+      data = []
+      current_size = 0
+      while current_size < size:
+        value = str(random.randint(0, 9))
+        value_size = len(value)
+        data.append(value)
+        current_size += value_size
+
+      return data
+
+    def  _v1_MossoCloudFS_foo_bar_container_foo_test_upload(self, method, url, body, headers):
+        # test_object_upload_success
+        body = ''
+        header = copy.deepcopy(self.base_headers)
+        return (httplib.CREATED, body, headers, httplib.responses[httplib.OK])
+
+    def  _v1_MossoCloudFS_foo_bar_container_foo_test_upload_INVALID_HASH(self, method, url, body, headers):
+        # test_object_upload_invalid_hash
+        body = ''
+        headers = self.base_headers
+        return (httplib.UNPROCESSABLE_ENTITY, body, headers,
+                httplib.responses[httplib.OK])
+
+    def _v1_MossoCloudFS_foo_bar_container_foo_bar_object(self, method, url, body, headers):
+        # test_download_object_success
+        body = 'test'
+        self._data = self._generate_random_data(1000)
+        return (httplib.OK, body, self.base_headers, httplib.responses[httplib.OK])
+
+    def _v1_MossoCloudFS_foo_bar_container_foo_bar_object_INVALID_SIZE(self, method, url, body, headers):
+        # test_download_object_invalid_file_size
+        body = 'test'
+        self._data = self._generate_random_data(100)
+        return (httplib.OK, body, self.base_headers, httplib.responses[httplib.OK])
+
+    def _v1_MossoCloudFS_foo_bar_container_foo_test_stream_data(self, method, url, body, headers):
+        # test_stream_object_data_success
+        body = 'test'
+        return (httplib.OK, body, self.base_headers, httplib.responses[httplib.OK])
+
+if __name__ == '__main__':
+    sys.exit(unittest.main())

Added: incubator/libcloud/trunk/test/test_file_fixtures.py
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/test_file_fixtures.py?rev=1079029&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/test_file_fixtures.py (added)
+++ incubator/libcloud/trunk/test/test_file_fixtures.py Mon Mar  7 23:44:06 2011
@@ -0,0 +1,31 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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 sys
+import unittest
+
+from test.file_fixtures import ComputeFileFixtures
+
+class FileFixturesTests(unittest.TestCase):
+
+    def test_success(self):
+        f = ComputeFileFixtures('meta')
+        self.assertEqual("Hello, World!", f.load('helloworld.txt'))
+
+    def test_failure(self):
+        f = ComputeFileFixtures('meta')
+        self.assertRaises(IOError, f.load, 'nil')
+
+if __name__ == '__main__':
+    sys.exit(unittest.main())