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())