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 [12/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_elastichosts.py
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/compute/test_elastichosts.py?rev=1079029&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/compute/test_elastichosts.py (added)
+++ incubator/libcloud/trunk/test/compute/test_elastichosts.py Mon Mar 7 23:44:06 2011
@@ -0,0 +1,106 @@
+# 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.
+# Copyright 2009 RedRata Ltd
+
+import sys
+import unittest
+import httplib
+
+from libcloud.compute.drivers.elastichosts import ElasticHostsBaseNodeDriver
+
+from test import MockHttp
+from test.compute import TestCaseMixin
+from test.file_fixtures import ComputeFileFixtures
+
+class ElasticHostsTestCase(unittest.TestCase, TestCaseMixin):
+ def setUp(self):
+ ElasticHostsBaseNodeDriver.connectionCls.conn_classes = (None,
+ ElasticHostsHttp)
+ self.driver = ElasticHostsBaseNodeDriver('foo', 'bar')
+
+ def test_list_nodes(self):
+ nodes = self.driver.list_nodes()
+ self.assertTrue(isinstance(nodes, list))
+ self.assertEqual(len(nodes), 1)
+
+ node = nodes[0]
+ self.assertEqual(node.public_ip[0], "1.2.3.4")
+ self.assertEqual(node.public_ip[1], "1.2.3.5")
+ self.assertEqual(node.extra['smp'], 1)
+
+ def test_list_sizes(self):
+ images = self.driver.list_sizes()
+ self.assertEqual(len(images), 5)
+ image = images[0]
+ self.assertEqual(image.id, 'small')
+ self.assertEqual(image.name, 'Small instance')
+ self.assertEqual(image.cpu, 2000)
+ self.assertEqual(image.ram, 1700)
+ self.assertEqual(image.disk, 160)
+
+ def test_list_images(self):
+ sizes = self.driver.list_images()
+ self.assertEqual(len(sizes), 8)
+ size = sizes[0]
+ self.assertEqual(size.id, '38df0986-4d85-4b76-b502-3878ffc80161')
+ self.assertEqual(size.name, 'CentOS Linux 5.5')
+
+ def test_list_locations_response(self):
+ pass
+
+ def test_reboot_node(self):
+ node = self.driver.list_nodes()[0]
+ self.assertTrue(self.driver.reboot_node(node))
+
+ def test_destroy_node(self):
+ node = self.driver.list_nodes()[0]
+ self.assertTrue(self.driver.destroy_node(node))
+
+ def test_create_node(self):
+ size = self.driver.list_sizes()[0]
+ image = self.driver.list_images()[0]
+ self.assertTrue(self.driver.create_node(name="api.ivan.net.nz", image=image, size=size))
+
+class ElasticHostsHttp(MockHttp):
+
+ fixtures = ComputeFileFixtures('elastichosts')
+
+ def _servers_b605ca90_c3e6_4cee_85f8_a8ebdf8f9903_reset(self, method, url, body, headers):
+ return (httplib.NO_CONTENT, body, {}, httplib.responses[httplib.NO_CONTENT])
+
+ def _servers_b605ca90_c3e6_4cee_85f8_a8ebdf8f9903_destroy(self, method, url, body, headers):
+ return (httplib.NO_CONTENT, body, {}, httplib.responses[httplib.NO_CONTENT])
+
+ def _drives_create(self, method, url, body, headers):
+ body = self.fixtures.load('drives_create.json')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _drives_0012e24a_6eae_4279_9912_3432f698cec8_image_38df0986_4d85_4b76_b502_3878ffc80161_gunzip(self, method, url, body, headers):
+ return (httplib.NO_CONTENT, body, {}, httplib.responses[httplib.NO_CONTENT])
+
+ def _drives_0012e24a_6eae_4279_9912_3432f698cec8_info(self, method, url, body, headers):
+ body = self.fixtures.load('drives_info.json')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _servers_create(self, method, url, body, headers):
+ body = self.fixtures.load('servers_create.json')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _servers_info(self, method, url, body, headers):
+ body = self.fixtures.load('servers_info.json')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+if __name__ == '__main__':
+ sys.exit(unittest.main())
Added: incubator/libcloud/trunk/test/compute/test_gogrid.py
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/compute/test_gogrid.py?rev=1079029&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/compute/test_gogrid.py (added)
+++ incubator/libcloud/trunk/test/compute/test_gogrid.py Mon Mar 7 23:44:06 2011
@@ -0,0 +1,242 @@
+# 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 httplib
+import sys
+import unittest
+import urlparse
+
+try:
+ import json
+except ImportError:
+ import simplejson as json
+
+from libcloud.common.types import LibcloudError, InvalidCredsError
+from libcloud.compute.drivers.gogrid import GoGridNodeDriver, GoGridIpAddress
+from libcloud.compute.base import Node, NodeImage, NodeSize, NodeLocation
+
+from test import MockHttp
+from test.compute import TestCaseMixin
+from test.file_fixtures import ComputeFileFixtures
+
+class GoGridTests(unittest.TestCase, TestCaseMixin):
+
+ def setUp(self):
+ GoGridNodeDriver.connectionCls.conn_classes = (None, GoGridMockHttp)
+ GoGridMockHttp.type = None
+ self.driver = GoGridNodeDriver("foo", "bar")
+
+ def test_create_node(self):
+ image = NodeImage(1531, None, self.driver)
+ size = NodeSize('512Mb', None, None, None, None, None, driver=self.driver)
+
+ node = self.driver.create_node(name='test1', image=image, size=size)
+ self.assertEqual(node.name, 'test1')
+ self.assertTrue(node.id is not None)
+ self.assertEqual(node.extra['password'], 'bebebe')
+
+ def test_list_nodes(self):
+ node = self.driver.list_nodes()[0]
+
+ self.assertEqual(node.id, '90967')
+ self.assertEqual(node.extra['password'], 'bebebe')
+ self.assertEqual(node.extra['isSandbox'], False)
+
+ def test_reboot_node(self):
+ node = Node(90967, None, None, None, None, self.driver)
+ ret = self.driver.reboot_node(node)
+ self.assertTrue(ret)
+
+ def test_destroy_node(self):
+ node = Node(90967, None, None, None, None, self.driver)
+ ret = self.driver.destroy_node(node)
+ self.assertTrue(ret)
+
+ def test_list_images(self):
+ images = self.driver.list_images()
+ image = images[0]
+ self.assertEqual(len(images), 4)
+ self.assertEqual(image.name, 'CentOS 5.3 (32-bit) w/ None')
+ self.assertEqual(image.id, '1531')
+
+ def test_malformed_reply(self):
+ GoGridMockHttp.type = 'FAIL'
+ try:
+ images = self.driver.list_images()
+ except LibcloudError, e:
+ self.assertTrue(isinstance(e, LibcloudError))
+ else:
+ self.fail("test should have thrown")
+
+ def test_invalid_creds(self):
+ GoGridMockHttp.type = 'FAIL'
+ try:
+ nodes = self.driver.list_nodes()
+ except InvalidCredsError, e:
+ self.assertTrue(e.driver is not None)
+ self.assertEqual(e.driver.name, self.driver.name)
+ else:
+ self.fail("test should have thrown")
+
+ def test_node_creation_without_free_public_ips(self):
+ GoGridMockHttp.type = 'NOPUBIPS'
+ try:
+ image = NodeImage(1531, None, self.driver)
+ size = NodeSize('512Mb', None, None, None, None, None, driver=self.driver)
+
+ node = self.driver.create_node(name='test1', image=image, size=size)
+ except LibcloudError, e:
+ self.assertTrue(isinstance(e, LibcloudError))
+ self.assertTrue(e.driver is not None)
+ self.assertEqual(e.driver.name, self.driver.name)
+ else:
+ self.fail("test should have thrown")
+
+ def test_list_locations(self):
+ locations = self.driver.list_locations()
+ location_names = [location.name for location in locations]
+
+ self.assertEqual(len(locations), 2)
+ for i in 0, 1:
+ self.assertTrue(isinstance(locations[i], NodeLocation))
+ self.assertTrue("US-West-1" in location_names)
+ self.assertTrue("US-East-1" in location_names)
+
+ def test_ex_save_image(self):
+ node = self.driver.list_nodes()[0]
+ image = self.driver.ex_save_image(node, "testimage")
+ self.assertEqual(image.name, "testimage")
+
+ def test_ex_edit_image(self):
+ image = self.driver.list_images()[0]
+ ret = self.driver.ex_edit_image(image=image, public=False,
+ ex_description="test", name="testname")
+
+ self.assertTrue(isinstance(ret, NodeImage))
+
+ def test_ex_edit_node(self):
+ node = Node(90967, None, None, None, None, self.driver)
+ size = NodeSize('512Mb', None, None, None, None, None, driver=self.driver)
+ ret = self.driver.ex_edit_node(node=node, size=size)
+
+ self.assertTrue(isinstance(ret, Node))
+
+ def test_ex_list_ips(self):
+ ips = self.driver.ex_list_ips()
+
+ expected_ips = {"192.168.75.66": GoGridIpAddress(id="5348099",
+ ip="192.168.75.66", public=True, state="Unassigned",
+ subnet="192.168.75.64/255.255.255.240"),
+ "192.168.75.67": GoGridIpAddress(id="5348100",
+ ip="192.168.75.67", public=True, state="Assigned",
+ subnet="192.168.75.64/255.255.255.240"),
+ "192.168.75.68": GoGridIpAddress(id="5348101",
+ ip="192.168.75.68", public=False, state="Unassigned",
+ subnet="192.168.75.64/255.255.255.240")}
+
+ self.assertEqual(len(expected_ips), 3)
+
+ for ip in ips:
+ self.assertTrue(ip.ip in expected_ips)
+ self.assertEqual(ip.public, expected_ips[ip.ip].public)
+ self.assertEqual(ip.state, expected_ips[ip.ip].state)
+ self.assertEqual(ip.subnet, expected_ips[ip.ip].subnet)
+
+ del expected_ips[ip.ip]
+
+ self.assertEqual(len(expected_ips), 0)
+
+class GoGridMockHttp(MockHttp):
+
+ fixtures = ComputeFileFixtures('gogrid')
+
+ def _api_grid_image_list(self, method, url, body, headers):
+ body = self.fixtures.load('image_list.json')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _api_grid_image_list_FAIL(self, method, url, body, headers):
+ body = "<h3>some non valid json here</h3>"
+ return (httplib.SERVICE_UNAVAILABLE, body, {},
+ httplib.responses[httplib.SERVICE_UNAVAILABLE])
+
+ def _api_grid_server_list(self, method, url, body, headers):
+ body = self.fixtures.load('server_list.json')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ _api_grid_server_list_NOPUBIPS = _api_grid_server_list
+
+ def _api_grid_server_list_FAIL(self, method, url, body, headers):
+ return (httplib.FORBIDDEN, "123", {}, httplib.responses[httplib.FORBIDDEN])
+
+ def _api_grid_ip_list(self, method, url, body, headers):
+ body = self.fixtures.load('ip_list.json')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _api_grid_ip_list_NOPUBIPS(self, method, url, body, headers):
+ body = self.fixtures.load('ip_list_empty.json')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _api_grid_server_power(self, method, url, body, headers):
+ body = self.fixtures.load('server_power.json')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _api_grid_server_add(self, method, url, body, headers):
+ body = self.fixtures.load('server_add.json')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ _api_grid_server_add_NOPUBIPS = _api_grid_server_add
+
+ def _api_grid_server_delete(self, method, url, body, headers):
+ body = self.fixtures.load('server_delete.json')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _api_grid_server_edit(self, method, url, body, headers):
+ body = self.fixtures.load('server_edit.json')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _api_support_password_list(self, method, url, body, headers):
+ body = self.fixtures.load('password_list.json')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ _api_support_password_list_NOPUBIPS = _api_support_password_list
+
+ def _api_grid_image_save(self, method, url, body, headers):
+ body = self.fixtures.load('image_save.json')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _api_grid_image_edit(self, method, url, body, headers):
+ # edit method is quite similar to save method from the response
+ # perspective
+ body = self.fixtures.load('image_save.json')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _api_common_lookup_list(self, method, url, body, headers):
+ _valid_lookups = ("ip.datacenter",)
+
+ try:
+ from urlparse import parse_qs
+ except ImportError:
+ from cgi import parse_qs
+
+ lookup = parse_qs(urlparse.urlparse(url).query)["lookup"][0]
+ if lookup in _valid_lookups:
+ fixture_path = "lookup_list_%s.json" % \
+ (lookup.replace(".", "_"))
+ else:
+ raise NotImplementedError
+ body = self.fixtures.load(fixture_path)
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+if __name__ == '__main__':
+ sys.exit(unittest.main())
Added: incubator/libcloud/trunk/test/compute/test_ibm_sbc.py
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/compute/test_ibm_sbc.py?rev=1079029&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/compute/test_ibm_sbc.py (added)
+++ incubator/libcloud/trunk/test/compute/test_ibm_sbc.py Mon Mar 7 23:44:06 2011
@@ -0,0 +1,206 @@
+# 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
+import unittest
+import httplib
+import sys
+
+from libcloud.compute.types import InvalidCredsError
+from libcloud.compute.drivers.ibm_sbc import IBMNodeDriver as IBM
+from libcloud.compute.base import Node, NodeImage, NodeSize, NodeLocation
+
+from test import MockHttp
+from test.compute import TestCaseMixin
+from test.file_fixtures import ComputeFileFixtures
+from test.secrets import IBM_USER, IBM_SECRET
+
+class IBMTests(unittest.TestCase, TestCaseMixin):
+ """
+ Tests the IBM Developer Cloud driver.
+ """
+
+ def setUp(self):
+ IBM.connectionCls.conn_classes = (None, IBMMockHttp)
+ IBMMockHttp.type = None
+ self.driver = IBM(IBM_USER, IBM_SECRET)
+
+ def test_auth(self):
+ IBMMockHttp.type = 'UNAUTHORIZED'
+
+ try:
+ self.driver.list_nodes()
+ except InvalidCredsError, e:
+ self.assertTrue(isinstance(e, InvalidCredsError))
+ self.assertEquals(e.value, '401: Unauthorized')
+ else:
+ self.fail('test should have thrown')
+
+ def test_list_nodes(self):
+ ret = self.driver.list_nodes()
+ self.assertEquals(len(ret), 3)
+ self.assertEquals(ret[0].id, '26557')
+ self.assertEquals(ret[0].name, 'Insight Instance')
+ self.assertEquals(ret[0].public_ip, '129.33.196.128')
+ self.assertEquals(ret[0].private_ip, None) # Private IPs not supported
+ self.assertEquals(ret[1].public_ip, None) # Node is non-active (no IP)
+ self.assertEquals(ret[1].private_ip, None)
+ self.assertEquals(ret[1].id, '28193')
+
+ def test_list_sizes(self):
+ ret = self.driver.list_sizes()
+ self.assertEquals(len(ret), 9) # 9 instance configurations supported
+ self.assertEquals(ret[0].id, 'BRZ32.1/2048/60*175')
+ self.assertEquals(ret[1].id, 'BRZ64.2/4096/60*500*350')
+ self.assertEquals(ret[2].id, 'COP32.1/2048/60')
+ self.assertEquals(ret[0].name, 'Bronze 32 bit')
+ self.assertEquals(ret[0].disk, None)
+
+ def test_list_images(self):
+ ret = self.driver.list_images()
+ self.assertEqual(len(ret), 21)
+ self.assertEqual(ret[10].name, "Rational Asset Manager 7.2.0.1")
+ self.assertEqual(ret[9].id, '10002573')
+
+ def test_list_locations(self):
+ ret = self.driver.list_locations()
+ self.assertEquals(len(ret), 1)
+ self.assertEquals(ret[0].id, '1')
+ self.assertEquals(ret[0].name, 'US North East: Poughkeepsie, NY')
+ self.assertEquals(ret[0].country, 'US')
+
+ def test_create_node(self):
+ # Test creation of node
+ IBMMockHttp.type = 'CREATE'
+ image = NodeImage(id=11, name='Rational Insight', driver=self.driver)
+ size = NodeSize('LARGE', 'LARGE', None, None, None, None, self.driver)
+ location = NodeLocation('1', 'POK', 'US', driver=self.driver)
+ ret = self.driver.create_node(name='RationalInsight4',
+ image=image,
+ size=size,
+ location=location,
+ publicKey='MyPublicKey',
+ configurationData = {
+ 'insight_admin_password': 'myPassword1',
+ 'db2_admin_password': 'myPassword2',
+ 'report_user_password': 'myPassword3'})
+ self.assertTrue(isinstance(ret, Node))
+ self.assertEquals(ret.name, 'RationalInsight4')
+
+ # Test creation attempt with invalid location
+ IBMMockHttp.type = 'CREATE_INVALID'
+ location = NodeLocation('3', 'DOESNOTEXIST', 'US', driver=self.driver)
+ try:
+ ret = self.driver.create_node(name='RationalInsight5',
+ image=image,
+ size=size,
+ location=location,
+ publicKey='MyPublicKey',
+ configurationData = {
+ 'insight_admin_password': 'myPassword1',
+ 'db2_admin_password': 'myPassword2',
+ 'report_user_password': 'myPassword3'})
+ except Exception, e:
+ self.assertEquals(e.args[0], 'Error 412: No DataCenter with id: 3')
+ else:
+ self.fail('test should have thrown')
+
+ def test_destroy_node(self):
+ # Delete existant node
+ nodes = self.driver.list_nodes() # retrieves 3 nodes
+ self.assertEquals(len(nodes), 3)
+ IBMMockHttp.type = 'DELETE'
+ toDelete = nodes[1]
+ ret = self.driver.destroy_node(toDelete)
+ self.assertTrue(ret)
+
+ # Delete non-existant node
+ IBMMockHttp.type = 'DELETED'
+ nodes = self.driver.list_nodes() # retrieves 2 nodes
+ self.assertEquals(len(nodes), 2)
+ try:
+ self.driver.destroy_node(toDelete) # delete non-existent node
+ except Exception, e:
+ self.assertEquals(e.args[0], 'Error 404: Invalid Instance ID 28193')
+ else:
+ self.fail('test should have thrown')
+
+ def test_reboot_node(self):
+ nodes = self.driver.list_nodes()
+ IBMMockHttp.type = 'REBOOT'
+
+ # Reboot active node
+ self.assertEquals(len(nodes), 3)
+ ret = self.driver.reboot_node(nodes[0])
+ self.assertTrue(ret)
+
+ # Reboot inactive node
+ try:
+ ret = self.driver.reboot_node(nodes[1])
+ except Exception, e:
+ self.assertEquals(e.args[0], 'Error 412: Instance must be in the Active state')
+ else:
+ self.fail('test should have thrown')
+
+class IBMMockHttp(MockHttp):
+ fixtures = ComputeFileFixtures('ibm_sbc')
+
+ def _computecloud_enterprise_api_rest_20100331_instances(self, method, url, body, headers):
+ body = self.fixtures.load('instances.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _computecloud_enterprise_api_rest_20100331_instances_DELETED(self, method, url, body, headers):
+ body = self.fixtures.load('instances_deleted.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _computecloud_enterprise_api_rest_20100331_instances_UNAUTHORIZED(self, method, url, body, headers):
+ return (httplib.UNAUTHORIZED, body, {}, httplib.responses[httplib.UNAUTHORIZED])
+
+ def _computecloud_enterprise_api_rest_20100331_offerings_image(self, method, url, body, headers):
+ body = self.fixtures.load('images.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _computecloud_enterprise_api_rest_20100331_locations(self, method, url, body, headers):
+ body = self.fixtures.load('locations.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _computecloud_enterprise_api_rest_20100331_instances_26557_REBOOT(self, method, url, body, headers):
+ body = self.fixtures.load('reboot_active.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _computecloud_enterprise_api_rest_20100331_instances_28193_REBOOT(self, method, url, body, headers):
+ return (412, 'Error 412: Instance must be in the Active state', {}, 'Precondition Failed')
+
+ def _computecloud_enterprise_api_rest_20100331_instances_28193_DELETE(self, method, url, body, headers):
+ body = self.fixtures.load('delete.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _computecloud_enterprise_api_rest_20100331_instances_28193_DELETED(self, method, url, body, headers):
+ return (404, 'Error 404: Invalid Instance ID 28193', {}, 'Precondition Failed')
+
+ def _computecloud_enterprise_api_rest_20100331_instances_CREATE(self, method, url, body, headers):
+ body = self.fixtures.load('create.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _computecloud_enterprise_api_rest_20100331_instances_CREATE_INVALID(self, method, url, body, headers):
+ return (412, 'Error 412: No DataCenter with id: 3', {}, 'Precondition Failed')
+
+ # This is only to accomodate the response tests built into test\__init__.py
+ def _computecloud_enterprise_api_rest_20100331_instances_26557(self, method, url, body, headers):
+ if method == 'DELETE':
+ body = self.fixtures.load('delete.xml')
+ else:
+ body = self.fixtures.load('reboot_active.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+if __name__ == '__main__':
+ sys.exit(unittest.main())
Added: incubator/libcloud/trunk/test/compute/test_linode.py
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/compute/test_linode.py?rev=1079029&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/compute/test_linode.py (added)
+++ incubator/libcloud/trunk/test/compute/test_linode.py Mon Mar 7 23:44:06 2011
@@ -0,0 +1,148 @@
+# 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.
+#
+# Maintainer: Jed Smith <je...@linode.com>
+# Based upon code written by Alex Polvi <po...@cloudkick.com>
+#
+
+import sys
+import unittest
+import httplib
+
+from libcloud.compute.drivers.linode import LinodeNodeDriver
+from libcloud.compute.base import Node, NodeAuthPassword
+
+from test import MockHttp
+from test.compute import TestCaseMixin
+
+class LinodeTest(unittest.TestCase, TestCaseMixin):
+ # The Linode test suite
+
+ def setUp(self):
+ LinodeNodeDriver.connectionCls.conn_classes = (None, LinodeMockHttp)
+ LinodeMockHttp.use_param = 'api_action'
+ self.driver = LinodeNodeDriver('foo')
+
+ def test_list_nodes(self):
+ nodes = self.driver.list_nodes()
+ self.assertEqual(len(nodes), 1)
+ node = nodes[0]
+ self.assertEqual(node.id, "8098")
+ self.assertEqual(node.name, 'api-node3')
+ self.assertTrue('75.127.96.245' in node.public_ip)
+ self.assertEqual(node.private_ip, [])
+
+ def test_reboot_node(self):
+ # An exception would indicate failure
+ node = self.driver.list_nodes()[0]
+ self.driver.reboot_node(node)
+
+ def test_destroy_node(self):
+ # An exception would indicate failure
+ node = self.driver.list_nodes()[0]
+ self.driver.destroy_node(node)
+
+ def test_create_node(self):
+ # Will exception on failure
+ self.driver.create_node(name="Test",
+ location=self.driver.list_locations()[0],
+ size=self.driver.list_sizes()[0],
+ image=self.driver.list_images()[6],
+ auth=NodeAuthPassword("test123"))
+
+ def test_list_sizes(self):
+ sizes = self.driver.list_sizes()
+ self.assertEqual(len(sizes), 10)
+ for size in sizes:
+ self.assertEqual(size.ram, int(size.name.split(" ")[1]))
+
+ def test_list_images(self):
+ images = self.driver.list_images()
+ self.assertEqual(len(images), 22)
+
+ def test_create_node_response(self):
+ # should return a node object
+ node = self.driver.create_node(name="node-name",
+ location=self.driver.list_locations()[0],
+ size=self.driver.list_sizes()[0],
+ image=self.driver.list_images()[0],
+ auth=NodeAuthPassword("foobar"))
+ self.assertTrue(isinstance(node[0], Node))
+
+
+class LinodeMockHttp(MockHttp):
+ def _avail_datacenters(self, method, url, body, headers):
+ body = '{"ERRORARRAY":[],"ACTION":"avail.datacenters","DATA":[{"DATACENTERID":2,"LOCATION":"Dallas, TX, USA"},{"DATACENTERID":3,"LOCATION":"Fremont, CA, USA"},{"DATACENTERID":4,"LOCATION":"Atlanta, GA, USA"},{"DATACENTERID":6,"LOCATION":"Newark, NJ, USA"}]}'
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _avail_linodeplans(self, method, url, body, headers):
+ body = '{"ERRORARRAY":[],"ACTION":"avail.linodeplans","DATA":[{"AVAIL":{"2":27,"3":0,"4":0,"6":0},"DISK":16,"PRICE":19.95,"PLANID":1,"LABEL":"Linode 360","RAM":360,"XFER":200},{"AVAIL":{"2":0,"3":0,"4":0,"6":0},"DISK":24,"PRICE":29.95,"PLANID":2,"LABEL":"Linode 540","RAM":540,"XFER":300},{"AVAIL":{"2":0,"3":0,"4":0,"6":0},"DISK":32,"PRICE":39.95,"PLANID":3,"LABEL":"Linode 720","RAM":720,"XFER":400},{"AVAIL":{"2":0,"3":0,"4":0,"6":0},"DISK":48,"PRICE":59.95,"PLANID":4,"LABEL":"Linode 1080","RAM":1080,"XFER":600},{"AVAIL":{"2":0,"3":0,"4":0,"6":0},"DISK":64,"PRICE":79.95,"PLANID":5,"LABEL":"Linode 1440","RAM":1440,"XFER":800},{"AVAIL":{"2":0,"3":0,"4":0,"6":0},"DISK":128,"PRICE":159.95,"PLANID":6,"LABEL":"Linode 2880","RAM":2880,"XFER":1600},{"AVAIL":{"2":0,"3":0,"4":0,"6":0},"DISK":256,"PRICE":319.95,"PLANID":7,"LABEL":"Linode 5760","RAM":5760,"XFER":2000},{"AVAIL":{"2":0,"3":0,"4":0,"6":0},"DISK":384,"PRICE":479.95,"PLANID":8,"LABEL":"Linode 8640","RAM":8640,"XFER":2
000},{"AVAIL":{"2":0,"3":0,"4":0,"6":0},"DISK":512,"PRICE":639.95,"PLANID":9,"LABEL":"Linode 11520","RAM":11520,"XFER":2000},{"AVAIL":{"2":0,"3":0,"4":0,"6":0},"DISK":640,"PRICE":799.95,"PLANID":10,"LABEL":"Linode 14400","RAM":14400,"XFER":2000}]}'
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _avail_distributions(self, method, url, body, headers):
+ body = '{"ERRORARRAY":[],"ACTION":"avail.distributions","DATA":[{"REQUIRESPVOPSKERNEL":0,"IS64BIT":0,"LABEL":"Arch Linux 2007.08","MINIMAGESIZE":436,"DISTRIBUTIONID":38,"CREATE_DT":"2007-10-24 00:00:00.0"},{"REQUIRESPVOPSKERNEL":0,"IS64BIT":0,"LABEL":"Centos 5.0","MINIMAGESIZE":594,"DISTRIBUTIONID":32,"CREATE_DT":"2007-04-27 00:00:00.0"},{"REQUIRESPVOPSKERNEL":0,"IS64BIT":0,"LABEL":"Centos 5.2","MINIMAGESIZE":950,"DISTRIBUTIONID":46,"CREATE_DT":"2008-11-30 00:00:00.0"},{"REQUIRESPVOPSKERNEL":1,"IS64BIT":1,"LABEL":"Centos 5.2 64bit","MINIMAGESIZE":980,"DISTRIBUTIONID":47,"CREATE_DT":"2008-11-30 00:00:00.0"},{"REQUIRESPVOPSKERNEL":1,"IS64BIT":0,"LABEL":"Debian 4.0","MINIMAGESIZE":200,"DISTRIBUTIONID":28,"CREATE_DT":"2007-04-18 00:00:00.0"},{"REQUIRESPVOPSKERNEL":0,"IS64BIT":1,"LABEL":"Debian 4.0 64bit","MINIMAGESIZE":220,"DISTRIBUTIONID":48,"CREATE_DT":"2008-12-02 00:00:00.0"},{"REQUIRESPVOPSKERNEL":0,"IS64BIT":0,"LABEL":"Debian 5.0","MINIMAGESIZE":200,"DISTRIBUTIONID"
:50,"CREATE_DT":"2009-02-19 00:00:00.0"},{"REQUIRESPVOPSKERNEL":0,"IS64BIT":1,"LABEL":"Debian 5.0 64bit","MINIMAGESIZE":300,"DISTRIBUTIONID":51,"CREATE_DT":"2009-02-19 00:00:00.0"},{"REQUIRESPVOPSKERNEL":1,"IS64BIT":0,"LABEL":"Fedora 8","MINIMAGESIZE":740,"DISTRIBUTIONID":40,"CREATE_DT":"2007-11-09 00:00:00.0"},{"REQUIRESPVOPSKERNEL":0,"IS64BIT":0,"LABEL":"Fedora 9","MINIMAGESIZE":1175,"DISTRIBUTIONID":43,"CREATE_DT":"2008-06-09 15:15:21.0"},{"REQUIRESPVOPSKERNEL":1,"IS64BIT":0,"LABEL":"Gentoo 2007.0","MINIMAGESIZE":1800,"DISTRIBUTIONID":35,"CREATE_DT":"2007-08-29 00:00:00.0"},{"REQUIRESPVOPSKERNEL":0,"IS64BIT":0,"LABEL":"Gentoo 2008.0","MINIMAGESIZE":1500,"DISTRIBUTIONID":52,"CREATE_DT":"2009-03-20 00:00:00.0"},{"REQUIRESPVOPSKERNEL":1,"IS64BIT":1,"LABEL":"Gentoo 2008.0 64bit","MINIMAGESIZE":2500,"DISTRIBUTIONID":53,"CREATE_DT":"2009-04-04 00:00:00.0"},{"REQUIRESPVOPSKERNEL":0,"IS64BIT":0,"LABEL":"OpenSUSE 11.0","MINIMAGESIZE":850,"DISTRIBUTIONID":44,"CREATE_DT":"2008-08-21
08:32:16.0"},{"REQUIRESPVOPSKERNEL":0,"IS64BIT":0,"LABEL":"Slackware 12.0","MINIMAGESIZE":315,"DISTRIBUTIONID":34,"CREATE_DT":"2007-07-16 00:00:00.0"},{"REQUIRESPVOPSKERNEL":1,"IS64BIT":0,"LABEL":"Slackware 12.2","MINIMAGESIZE":500,"DISTRIBUTIONID":54,"CREATE_DT":"2009-04-04 00:00:00.0"},{"REQUIRESPVOPSKERNEL":0,"IS64BIT":0,"LABEL":"Ubuntu 8.04 LTS","MINIMAGESIZE":400,"DISTRIBUTIONID":41,"CREATE_DT":"2008-04-23 15:11:29.0"},{"REQUIRESPVOPSKERNEL":0,"IS64BIT":1,"LABEL":"Ubuntu 8.04 LTS 64bit","MINIMAGESIZE":350,"DISTRIBUTIONID":42,"CREATE_DT":"2008-06-03 12:51:11.0"},{"REQUIRESPVOPSKERNEL":0,"IS64BIT":0,"LABEL":"Ubuntu 8.10","MINIMAGESIZE":220,"DISTRIBUTIONID":45,"CREATE_DT":"2008-10-30 23:23:03.0"},{"REQUIRESPVOPSKERNEL":1,"IS64BIT":1,"LABEL":"Ubuntu 8.10 64bit","MINIMAGESIZE":230,"DISTRIBUTIONID":49,"CREATE_DT":"2008-12-02 00:00:00.0"},{"REQUIRESPVOPSKERNEL":0,"IS64BIT":0,"LABEL":"Ubuntu 9.04","MINIMAGESIZE":350,"DISTRIBUTIONID":55,"CREATE_DT":"2009-04-23 00:00:00.0"},{"RE
QUIRESPVOPSKERNEL":0,"IS64BIT":1,"LABEL":"Ubuntu 9.04 64bit","MINIMAGESIZE":350,"DISTRIBUTIONID":56,"CREATE_DT":"2009-04-23 00:00:00.0"}]}'
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _linode_create(self, method, url, body, headers):
+ body = '{"ERRORARRAY":[],"ACTION":"linode.create","DATA":{"LinodeID":8098}}'
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _linode_disk_createfromdistribution(self, method, url, body, headers):
+ body = '{"ERRORARRAY":[],"ACTION":"linode.disk.createFromDistribution","DATA":{"JobID":1298,"DiskID":55647}}'
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _linode_delete(self, method, url, body, headers):
+ body = '{"ERRORARRAY":[],"ACTION":"linode.delete","DATA":{"LinodeID":8098}}'
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _linode_update(self, method, url, body, headers):
+ body = '{"ERRORARRAY":[],"ACTION":"linode.update","DATA":{"LinodeID":8098}}'
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _linode_reboot(self, method, url, body, headers):
+ body = '{"ERRORARRAY":[],"ACTION":"linode.reboot","DATA":{"JobID":1305}}'
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _avail_kernels(self, method, url, body, headers):
+ body = '{"ERRORARRAY":[],"ACTION":"avail.kernels","DATA":[{"LABEL":"Latest 2.6 Stable (2.6.18.8-linode19)","ISXEN":1,"KERNELID":60},{"LABEL":"2.6.18.8-linode19","ISXEN":1,"KERNELID":103},{"LABEL":"2.6.30.5-linode20","ISXEN":1,"KERNELID":105},{"LABEL":"Latest 2.6 Stable (2.6.18.8-x86_64-linode7)","ISXEN":1,"KERNELID":107},{"LABEL":"2.6.18.8-x86_64-linode7","ISXEN":1,"KERNELID":104},{"LABEL":"2.6.30.5-x86_64-linode8","ISXEN":1,"KERNELID":106},{"LABEL":"pv-grub-x86_32","ISXEN":1,"KERNELID":92},{"LABEL":"pv-grub-x86_64","ISXEN":1,"KERNELID":95},{"LABEL":"Recovery - Finnix (kernel)","ISXEN":1,"KERNELID":61},{"LABEL":"2.6.18.8-domU-linode7","ISXEN":1,"KERNELID":81},{"LABEL":"2.6.18.8-linode10","ISXEN":1,"KERNELID":89},{"LABEL":"2.6.18.8-linode16","ISXEN":1,"KERNELID":98},{"LABEL":"2.6.24.4-linode8","ISXEN":1,"KERNELID":84},{"LABEL":"2.6.25-linode9","ISXEN":1,"KERNELID":88},{"LABEL":"2.6.25.10-linode12","ISXEN":1,"KERNELID":90},{"LABEL":"2.6.26-linode13","ISXEN":1,"KERNELID
":91},{"LABEL":"2.6.27.4-linode14","ISXEN":1,"KERNELID":93},{"LABEL":"2.6.28-linode15","ISXEN":1,"KERNELID":96},{"LABEL":"2.6.28.3-linode17","ISXEN":1,"KERNELID":99},{"LABEL":"2.6.29-linode18","ISXEN":1,"KERNELID":101},{"LABEL":"2.6.16.38-x86_64-linode2","ISXEN":1,"KERNELID":85},{"LABEL":"2.6.18.8-x86_64-linode1","ISXEN":1,"KERNELID":86},{"LABEL":"2.6.27.4-x86_64-linode3","ISXEN":1,"KERNELID":94},{"LABEL":"2.6.28-x86_64-linode4","ISXEN":1,"KERNELID":97},{"LABEL":"2.6.28.3-x86_64-linode5","ISXEN":1,"KERNELID":100},{"LABEL":"2.6.29-x86_64-linode6","ISXEN":1,"KERNELID":102}]}'
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _linode_disk_create(self, method, url, body, headers):
+ body = '{"ERRORARRAY":[],"ACTION":"linode.disk.create","DATA":{"JobID":1299,"DiskID":55648}}'
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _linode_boot(self, method, url, body, headers):
+ body = '{"ERRORARRAY":[],"ACTION":"linode.boot","DATA":{"JobID":1300}}'
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _linode_config_create(self, method, url, body, headers):
+ body = '{"ERRORARRAY":[],"ACTION":"linode.config.create","DATA":{"ConfigID":31239}}'
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _linode_list(self, method, url, body, headers):
+ body = '{"ACTION": "linode.list", "DATA": [{"ALERT_DISKIO_ENABLED": 1, "BACKUPWEEKLYDAY": 0, "LABEL": "api-node3", "DATACENTERID": 5, "ALERT_BWOUT_ENABLED": 1, "ALERT_CPU_THRESHOLD": 10, "TOTALHD": 100, "ALERT_BWQUOTA_THRESHOLD": 81, "ALERT_BWQUOTA_ENABLED": 1, "TOTALXFER": 200, "STATUS": 2, "ALERT_BWIN_ENABLED": 1, "ALERT_BWIN_THRESHOLD": 5, "ALERT_DISKIO_THRESHOLD": 200, "WATCHDOG": 1, "LINODEID": 8098, "BACKUPWINDOW": 1, "TOTALRAM": 540, "LPM_DISPLAYGROUP": "", "ALERT_BWOUT_THRESHOLD": 5, "BACKUPSENABLED": 1, "ALERT_CPU_ENABLED": 1}], "ERRORARRAY": []}'
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _linode_ip_list(self, method, url, body, headers):
+ body = '{"ACTION": "linode.ip.list", "DATA": [{"RDNS_NAME": "li22-54.members.linode.com", "ISPUBLIC": 1, "IPADDRESS": "75.127.96.54", "IPADDRESSID": 5384, "LINODEID": 8098}, {"RDNS_NAME": "li22-245.members.linode.com", "ISPUBLIC": 1, "IPADDRESS": "75.127.96.245", "IPADDRESSID": 5575, "LINODEID": 8098}], "ERRORARRAY": []}'
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _batch(self, method, url, body, headers):
+ body = '[{"ACTION": "linode.ip.list", "DATA": [{"RDNS_NAME": "li22-54.members.linode.com", "ISPUBLIC": 1, "IPADDRESS": "75.127.96.54", "IPADDRESSID": 5384, "LINODEID": 8098}, {"RDNS_NAME": "li22-245.members.linode.com", "ISPUBLIC": 1, "IPADDRESS": "75.127.96.245", "IPADDRESSID": 5575, "LINODEID": 8098}], "ERRORARRAY": []}]'
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+
+if __name__ == '__main__':
+ sys.exit(unittest.main())
Added: incubator/libcloud/trunk/test/compute/test_opennebula.py
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/compute/test_opennebula.py?rev=1079029&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/compute/test_opennebula.py (added)
+++ incubator/libcloud/trunk/test/compute/test_opennebula.py Mon Mar 7 23:44:06 2011
@@ -0,0 +1,122 @@
+# Copyright 2002-2009, Distributed Systems Architecture Group, Universidad
+# Complutense de Madrid (dsa-research.org)
+#
+# 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 httplib
+
+from libcloud.compute.drivers.opennebula import OpenNebulaNodeDriver
+from libcloud.compute.base import Node, NodeImage, NodeSize
+
+from test import MockHttp
+from test.compute import TestCaseMixin
+from test.file_fixtures import ComputeFileFixtures
+
+from test.secrets import OPENNEBULA_USER, OPENNEBULA_KEY
+
+class OpenNebulaTests(unittest.TestCase, TestCaseMixin):
+
+ def setUp(self):
+ OpenNebulaNodeDriver.connectionCls.conn_classes = (None, OpenNebulaMockHttp)
+ self.driver = OpenNebulaNodeDriver(OPENNEBULA_USER, OPENNEBULA_KEY)
+
+ def test_create_node(self):
+ image = NodeImage(id=1, name='UbuntuServer9.04-Contextualized', driver=self.driver)
+ size = NodeSize(1, 'small', None, None, None, None, driver=self.driver)
+ node = self.driver.create_node(name='MyCompute', image=image, size=size)
+ self.assertEqual(node.id, '5')
+ self.assertEqual(node.name, 'MyCompute')
+
+ def test_list_nodes(self):
+ nodes = self.driver.list_nodes()
+ self.assertEqual(len(nodes), 2)
+ node = nodes[0]
+ self.assertEqual(node.id, '5')
+ self.assertEqual(node.name, 'MyCompute')
+
+ def test_reboot_node(self):
+ node = Node(5, None, None, None, None, self.driver)
+ ret = self.driver.reboot_node(node)
+ self.assertTrue(ret)
+
+ def test_destroy_node(self):
+ node = Node(5, None, None, None, None, self.driver)
+ ret = self.driver.destroy_node(node)
+ self.assertTrue(ret)
+
+ def test_list_sizes(self):
+ sizes = self.driver.list_sizes()
+ self.assertEqual(len(sizes), 3)
+ self.assertTrue('small' in [ s.name for s in sizes])
+ self.assertTrue('medium' in [ s.name for s in sizes])
+ self.assertTrue('large' in [ s.name for s in sizes])
+
+ def test_list_images(self):
+ images = self.driver.list_images()
+ self.assertEqual(len(images), 2)
+ image = images[0]
+ self.assertEqual(image.id, '1')
+ self.assertEqual(image.name, 'UbuntuServer9.04-Contextualized')
+
+class OpenNebulaMockHttp(MockHttp):
+
+ fixtures = ComputeFileFixtures('opennebula')
+
+ def _compute(self, method, url, body, headers):
+ if method == 'GET':
+ body = self.fixtures.load('computes.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ if method == 'POST':
+ body = self.fixtures.load('compute.xml')
+ return (httplib.CREATED, body, {}, httplib.responses[httplib.CREATED])
+
+ def _storage(self, method, url, body, headers):
+ if method == 'GET':
+ body = self.fixtures.load('storage.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _compute_5(self, method, url, body, headers):
+ if method == 'GET':
+ body = self.fixtures.load('compute.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ if method == 'PUT':
+ body = ""
+ return (httplib.ACCEPTED, body, {}, httplib.responses[httplib.ACCEPTED])
+
+ if method == 'DELETE':
+ body = ""
+ return (httplib.NO_CONTENT, body, {}, httplib.responses[httplib.NO_CONTENT])
+
+ def _compute_15(self, method, url, body, headers):
+ if method == 'GET':
+ body = self.fixtures.load('compute.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _storage_1(self, method, url, body, headers):
+ if method == 'GET':
+ body = self.fixtures.load('disk.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _storage_8(self, method, url, body, headers):
+ if method == 'GET':
+ body = self.fixtures.load('disk.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+if __name__ == '__main__':
+ sys.exit(unittest.main())
Added: incubator/libcloud/trunk/test/compute/test_rackspace.py
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/compute/test_rackspace.py?rev=1079029&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/compute/test_rackspace.py (added)
+++ incubator/libcloud/trunk/test/compute/test_rackspace.py Mon Mar 7 23:44:06 2011
@@ -0,0 +1,267 @@
+# 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 httplib
+
+from libcloud.common.types import InvalidCredsError
+from libcloud.compute.drivers.rackspace import RackspaceNodeDriver as Rackspace
+from libcloud.compute.base import Node, NodeImage, NodeSize
+
+from test import MockHttp
+from test.compute import TestCaseMixin
+from test.file_fixtures import ComputeFileFixtures
+
+from test.secrets import RACKSPACE_USER, RACKSPACE_KEY
+
+class RackspaceTests(unittest.TestCase, TestCaseMixin):
+
+ def setUp(self):
+ Rackspace.connectionCls.conn_classes = (None, RackspaceMockHttp)
+ RackspaceMockHttp.type = None
+ self.driver = Rackspace(RACKSPACE_USER, RACKSPACE_KEY)
+
+ def test_auth(self):
+ RackspaceMockHttp.type = 'UNAUTHORIZED'
+ try:
+ self.driver = Rackspace(RACKSPACE_USER, RACKSPACE_KEY)
+ except InvalidCredsError, e:
+ self.assertEqual(True, isinstance(e, InvalidCredsError))
+ else:
+ self.fail('test should have thrown')
+
+ def test_list_nodes(self):
+ RackspaceMockHttp.type = 'EMPTY'
+ ret = self.driver.list_nodes()
+ self.assertEqual(len(ret), 0)
+ RackspaceMockHttp.type = None
+ ret = self.driver.list_nodes()
+ self.assertEqual(len(ret), 1)
+ node = ret[0]
+ self.assertEqual('67.23.21.33', node.public_ip[0])
+ self.assertEqual('10.176.168.218', node.private_ip[0])
+ self.assertEqual(node.extra.get('flavorId'), '1')
+ self.assertEqual(node.extra.get('imageId'), '11')
+ self.assertEqual(type(node.extra.get('metadata')), type(dict()))
+ RackspaceMockHttp.type = 'METADATA'
+ ret = self.driver.list_nodes()
+ self.assertEqual(len(ret), 1)
+ node = ret[0]
+ self.assertEqual(type(node.extra.get('metadata')), type(dict()))
+ self.assertEqual(node.extra.get('metadata').get('somekey'), 'somevalue')
+ RackspaceMockHttp.type = None
+
+ def test_list_sizes(self):
+ ret = self.driver.list_sizes()
+ self.assertEqual(len(ret), 7)
+ size = ret[0]
+ self.assertEqual(size.name, '256 slice')
+
+ def test_list_images(self):
+ ret = self.driver.list_images()
+ self.assertEqual(ret[10].extra['serverId'], None)
+ self.assertEqual(ret[11].extra['serverId'], '91221')
+
+ def test_create_node(self):
+ image = NodeImage(id=11, name='Ubuntu 8.10 (intrepid)', driver=self.driver)
+ size = NodeSize(1, '256 slice', None, None, None, None, driver=self.driver)
+ node = self.driver.create_node(name='racktest', image=image, size=size, shared_ip_group='group1')
+ self.assertEqual(node.name, 'racktest')
+ self.assertEqual(node.extra.get('password'), 'racktestvJq7d3')
+
+ def test_create_node_with_metadata(self):
+ RackspaceMockHttp.type = 'METADATA'
+ image = NodeImage(id=11, name='Ubuntu 8.10 (intrepid)', driver=self.driver)
+ size = NodeSize(1, '256 slice', None, None, None, None, driver=self.driver)
+ metadata = { 'a': 'b', 'c': 'd' }
+ files = { '/file1': 'content1', '/file2': 'content2' }
+ node = self.driver.create_node(name='racktest', image=image, size=size, metadata=metadata, files=files)
+ self.assertEqual(node.name, 'racktest')
+ self.assertEqual(node.extra.get('password'), 'racktestvJq7d3')
+ self.assertEqual(node.extra.get('metadata'), metadata)
+
+ def test_reboot_node(self):
+ node = Node(id=72258, name=None, state=None, public_ip=None, private_ip=None,
+ driver=self.driver)
+ ret = node.reboot()
+ self.assertTrue(ret is True)
+
+ def test_destroy_node(self):
+ node = Node(id=72258, name=None, state=None, public_ip=None, private_ip=None,
+ driver=self.driver)
+ ret = node.destroy()
+ self.assertTrue(ret is True)
+
+ def test_ex_limits(self):
+ limits = self.driver.ex_limits()
+ self.assertTrue("rate" in limits)
+ self.assertTrue("absolute" in limits)
+
+ def test_ex_save_image(self):
+ node = Node(id=444222, name=None, state=None, public_ip=None, private_ip=None,
+ driver=self.driver)
+ image = self.driver.ex_save_image(node, "imgtest")
+ self.assertEqual(image.name, "imgtest")
+ self.assertEqual(image.id, "12345")
+
+ def test_ex_list_ip_addresses(self):
+ ret = self.driver.ex_list_ip_addresses(node_id=72258)
+ self.assertEquals(2, len(ret.public_addresses))
+ self.assertTrue('67.23.10.131' in ret.public_addresses)
+ self.assertTrue('67.23.10.132' in ret.public_addresses)
+ self.assertEquals(1, len(ret.private_addresses))
+ self.assertTrue('10.176.42.16' in ret.private_addresses)
+
+ def test_ex_list_ip_groups(self):
+ ret = self.driver.ex_list_ip_groups()
+ self.assertEquals(2, len(ret))
+ self.assertEquals('1234', ret[0].id)
+ self.assertEquals('Shared IP Group 1', ret[0].name)
+ self.assertEquals('5678', ret[1].id)
+ self.assertEquals('Shared IP Group 2', ret[1].name)
+ self.assertTrue(ret[0].servers is None)
+
+ def test_ex_list_ip_groups_detail(self):
+ ret = self.driver.ex_list_ip_groups(details=True)
+
+ self.assertEquals(2, len(ret))
+
+ self.assertEquals('1234', ret[0].id)
+ self.assertEquals('Shared IP Group 1', ret[0].name)
+ self.assertEquals(2, len(ret[0].servers))
+ self.assertEquals('422', ret[0].servers[0])
+ self.assertEquals('3445', ret[0].servers[1])
+
+ self.assertEquals('5678', ret[1].id)
+ self.assertEquals('Shared IP Group 2', ret[1].name)
+ self.assertEquals(3, len(ret[1].servers))
+ self.assertEquals('23203', ret[1].servers[0])
+ self.assertEquals('2456', ret[1].servers[1])
+ self.assertEquals('9891', ret[1].servers[2])
+
+ def test_ex_create_ip_group(self):
+ ret = self.driver.ex_create_ip_group('Shared IP Group 1', '5467')
+ self.assertEquals('1234', ret.id)
+ self.assertEquals('Shared IP Group 1', ret.name)
+ self.assertEquals(1, len(ret.servers))
+ self.assertEquals('422', ret.servers[0])
+
+ def test_ex_delete_ip_group(self):
+ ret = self.driver.ex_delete_ip_group('5467')
+ self.assertEquals(True, ret)
+
+ def test_ex_share_ip(self):
+ ret = self.driver.ex_share_ip('1234', '3445', '67.23.21.133')
+ self.assertEquals(True, ret)
+
+ def test_ex_unshare_ip(self):
+ ret = self.driver.ex_unshare_ip('3445', '67.23.21.133')
+ self.assertEquals(True, ret)
+
+
+class RackspaceMockHttp(MockHttp):
+
+ fixtures = ComputeFileFixtures('rackspace')
+
+ # fake auth token response
+ def _v1_0(self, method, url, body, headers):
+ headers = {'x-server-management-url': 'https://servers.api.rackspacecloud.com/v1.0/slug',
+ 'x-auth-token': 'FE011C19-CF86-4F87-BE5D-9229145D7A06',
+ 'x-cdn-management-url': 'https://cdn.clouddrive.com/v1/MossoCloudFS_FE011C19-CF86-4F87-BE5D-9229145D7A06',
+ 'x-storage-token': 'FE011C19-CF86-4F87-BE5D-9229145D7A06',
+ 'x-storage-url': 'https://storage4.clouddrive.com/v1/MossoCloudFS_FE011C19-CF86-4F87-BE5D-9229145D7A06'}
+ return (httplib.NO_CONTENT, "", headers, httplib.responses[httplib.NO_CONTENT])
+
+ def _v1_0_UNAUTHORIZED(self, method, url, body, headers):
+ return (httplib.UNAUTHORIZED, "", {}, httplib.responses[httplib.UNAUTHORIZED])
+
+ def _v1_0_slug_servers_detail_EMPTY(self, method, url, body, headers):
+ body = self.fixtures.load('v1_slug_servers_detail_empty.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _v1_0_slug_servers_detail(self, method, url, body, headers):
+ body = self.fixtures.load('v1_slug_servers_detail.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _v1_0_slug_servers_detail_METADATA(self, method, url, body, headers):
+ body = self.fixtures.load('v1_slug_servers_detail_metadata.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _v1_0_slug_flavors_detail(self, method, url, body, headers):
+ body = self.fixtures.load('v1_slug_flavors_detail.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _v1_0_slug_images(self, method, url, body, headers):
+ if method != "POST":
+ raise NotImplemented
+ # this is currently used for creation of new image with
+ # POST request, don't handle GET to avoid possible confusion
+ body = self.fixtures.load('v1_slug_images_post.xml')
+ return (httplib.ACCEPTED, body, {}, httplib.responses[httplib.ACCEPTED])
+
+ def _v1_0_slug_images_detail(self, method, url, body, headers):
+ body = self.fixtures.load('v1_slug_images_detail.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _v1_0_slug_servers(self, method, url, body, headers):
+ body = self.fixtures.load('v1_slug_servers.xml')
+ return (httplib.ACCEPTED, body, {}, httplib.responses[httplib.ACCEPTED])
+
+ def _v1_0_slug_servers_METADATA(self, method, url, body, headers):
+ body = self.fixtures.load('v1_slug_servers_metadata.xml')
+ return (httplib.ACCEPTED, body, {}, httplib.responses[httplib.ACCEPTED])
+
+ def _v1_0_slug_servers_72258_action(self, method, url, body, headers):
+ if method != "POST" or body[:8] != "<reboot ":
+ raise NotImplemented
+ # only used by reboot() right now, but we will need to parse body someday !!!!
+ return (httplib.ACCEPTED, "", {}, httplib.responses[httplib.ACCEPTED])
+
+ def _v1_0_slug_limits(self, method, url, body, headers):
+ body = self.fixtures.load('v1_slug_limits.xml')
+ return (httplib.ACCEPTED, body, {}, httplib.responses[httplib.ACCEPTED])
+
+ def _v1_0_slug_servers_72258(self, method, url, body, headers):
+ if method != "DELETE":
+ raise NotImplemented
+ # only used by destroy node()
+ return (httplib.ACCEPTED, "", {}, httplib.responses[httplib.ACCEPTED])
+
+ def _v1_0_slug_servers_72258_ips(self, method, url, body, headers):
+ body = self.fixtures.load('v1_slug_servers_ips.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _v1_0_slug_shared_ip_groups_5467(self, method, url, body, headers):
+ if method != 'DELETE':
+ raise NotImplemented
+ return (httplib.NO_CONTENT, "", {}, httplib.responses[httplib.NO_CONTENT])
+
+ def _v1_0_slug_shared_ip_groups(self, method, url, body, headers):
+
+ fixture = 'v1_slug_shared_ip_group.xml' if method == 'POST' else 'v1_slug_shared_ip_groups.xml'
+ body = self.fixtures.load(fixture)
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _v1_0_slug_shared_ip_groups_detail(self, method, url, body, headers):
+ body = self.fixtures.load('v1_slug_shared_ip_groups_detail.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _v1_0_slug_servers_3445_ips_public_67_23_21_133(self, method, url, body, headers):
+ return (httplib.ACCEPTED, "", {}, httplib.responses[httplib.ACCEPTED])
+
+
+
+if __name__ == '__main__':
+ sys.exit(unittest.main())
Added: incubator/libcloud/trunk/test/compute/test_rimuhosting.py
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/compute/test_rimuhosting.py?rev=1079029&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/compute/test_rimuhosting.py (added)
+++ incubator/libcloud/trunk/test/compute/test_rimuhosting.py Mon Mar 7 23:44:06 2011
@@ -0,0 +1,107 @@
+# 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.
+# Copyright 2009 RedRata Ltd
+
+import sys
+import unittest
+import httplib
+
+from libcloud.compute.drivers.rimuhosting import RimuHostingNodeDriver
+
+from test import MockHttp
+from test.compute import TestCaseMixin
+from test.file_fixtures import ComputeFileFixtures
+
+class RimuHostingTest(unittest.TestCase, TestCaseMixin):
+ def setUp(self):
+ RimuHostingNodeDriver.connectionCls.conn_classes = (None,
+ RimuHostingMockHttp)
+ self.driver = RimuHostingNodeDriver('foo')
+
+ def test_list_nodes(self):
+ nodes = self.driver.list_nodes()
+ self.assertEqual(len(nodes),1)
+ node = nodes[0]
+ self.assertEqual(node.public_ip[0], "1.2.3.4")
+ self.assertEqual(node.public_ip[1], "1.2.3.5")
+ self.assertEqual(node.extra['order_oid'], 88833465)
+ self.assertEqual(node.id, "order-88833465-api-ivan-net-nz")
+
+ def test_list_sizes(self):
+ sizes = self.driver.list_sizes()
+ self.assertEqual(len(sizes),1)
+ size = sizes[0]
+ self.assertEqual(size.ram,950)
+ self.assertEqual(size.disk,20)
+ self.assertEqual(size.bandwidth,75)
+ self.assertEqual(size.price,32.54)
+
+ def test_list_images(self):
+ images = self.driver.list_images()
+ self.assertEqual(len(images),6)
+ image = images[0]
+ self.assertEqual(image.name,"Debian 5.0 (aka Lenny, RimuHosting"\
+ " recommended distro)")
+ self.assertEqual(image.id, "lenny")
+
+ def test_reboot_node(self):
+ # Raises exception on failure
+ node = self.driver.list_nodes()[0]
+ self.driver.reboot_node(node)
+
+ def test_destroy_node(self):
+ # Raises exception on failure
+ node = self.driver.list_nodes()[0]
+ self.driver.destroy_node(node)
+
+ def test_create_node(self):
+ # Raises exception on failure
+ size = self.driver.list_sizes()[0]
+ image = self.driver.list_images()[0]
+ self.driver.create_node(name="api.ivan.net.nz", image=image, size=size)
+
+class RimuHostingMockHttp(MockHttp):
+
+ fixtures = ComputeFileFixtures('rimuhosting')
+
+ def _r_orders(self,method,url,body,headers):
+ body = self.fixtures.load('r_orders.json')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _r_pricing_plans(self,method,url,body,headers):
+ body = self.fixtures.load('r_pricing_plans.json')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _r_distributions(self, method, url, body, headers):
+ body = self.fixtures.load('r_distributions.json')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _r_orders_new_vps(self, method, url, body, headers):
+ body = self.fixtures.load('r_orders_new_vps.json')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _r_orders_order_88833465_api_ivan_net_nz_vps(self, method, url, body, headers):
+ body = self.fixtures.load('r_orders_order_88833465_api_ivan_net_nz_vps.json')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _r_orders_order_88833465_api_ivan_net_nz_vps_running_state(self, method,
+ url, body,
+ headers):
+ body = self.fixtures.load('r_orders_order_88833465_api_ivan_net_nz_vps_running_state.json')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+
+if __name__ == '__main__':
+ sys.exit(unittest.main())
Added: incubator/libcloud/trunk/test/compute/test_slicehost.py
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/compute/test_slicehost.py?rev=1079029&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/compute/test_slicehost.py (added)
+++ incubator/libcloud/trunk/test/compute/test_slicehost.py Mon Mar 7 23:44:06 2011
@@ -0,0 +1,155 @@
+# 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 httplib
+
+from xml.etree import ElementTree as ET
+
+from libcloud.compute.drivers.slicehost import SlicehostNodeDriver as Slicehost
+from libcloud.compute.types import NodeState, InvalidCredsError
+from libcloud.compute.base import Node, NodeImage, NodeSize
+
+from test import MockHttp
+from test.compute import TestCaseMixin
+from test.file_fixtures import ComputeFileFixtures
+from test.secrets import SLICEHOST_KEY
+
+class SlicehostTest(unittest.TestCase, TestCaseMixin):
+
+ def setUp(self):
+
+ Slicehost.connectionCls.conn_classes = (None, SlicehostMockHttp)
+ SlicehostMockHttp.type = None
+ self.driver = Slicehost(SLICEHOST_KEY)
+
+ def test_list_nodes(self):
+ ret = self.driver.list_nodes()
+ self.assertEqual(len(ret), 1)
+ node = ret[0]
+ self.assertTrue('174.143.212.229' in node.public_ip)
+ self.assertTrue('10.176.164.199' in node.private_ip)
+ self.assertEqual(node.state, NodeState.PENDING)
+
+ SlicehostMockHttp.type = 'UNAUTHORIZED'
+ try:
+ ret = self.driver.list_nodes()
+ except InvalidCredsError, e:
+ self.assertEqual(e.value, 'HTTP Basic: Access denied.')
+ else:
+ self.fail('test should have thrown')
+
+ def test_list_sizes(self):
+ ret = self.driver.list_sizes()
+ self.assertEqual(len(ret), 7)
+ size = ret[0]
+ self.assertEqual(size.name, '256 slice')
+
+ def test_list_images(self):
+ ret = self.driver.list_images()
+ self.assertEqual(len(ret), 11)
+ image = ret[0]
+ self.assertEqual(image.name, 'CentOS 5.2')
+ self.assertEqual(image.id, '2')
+
+ def test_reboot_node(self):
+ node = Node(id=1, name=None, state=None, public_ip=None, private_ip=None,
+ driver=self.driver)
+
+ ret = node.reboot()
+ self.assertTrue(ret is True)
+
+ ret = self.driver.reboot_node(node)
+ self.assertTrue(ret is True)
+
+ SlicehostMockHttp.type = 'FORBIDDEN'
+ try:
+ ret = self.driver.reboot_node(node)
+ except Exception, e:
+ self.assertEqual(e.args[0], 'Permission denied')
+ else:
+ self.fail('test should have thrown')
+
+ def test_destroy_node(self):
+ node = Node(id=1, name=None, state=None, public_ip=None, private_ip=None,
+ driver=self.driver)
+
+ ret = node.destroy()
+ self.assertTrue(ret is True)
+
+ ret = self.driver.destroy_node(node)
+ self.assertTrue(ret is True)
+
+ def test_create_node(self):
+ image = NodeImage(id=11, name='ubuntu 8.10', driver=self.driver)
+ size = NodeSize(1, '256 slice', None, None, None, None, driver=self.driver)
+ node = self.driver.create_node(name='slicetest', image=image, size=size)
+ self.assertEqual(node.name, 'slicetest')
+ self.assertEqual(node.extra.get('password'), 'fooadfa1231')
+
+class SlicehostMockHttp(MockHttp):
+
+ fixtures = ComputeFileFixtures('slicehost')
+
+ def _slices_xml(self, method, url, body, headers):
+ if method == 'POST':
+ tree = ET.XML(body)
+ name = tree.findtext('name')
+ image_id = int(tree.findtext('image-id'))
+ flavor_id = int(tree.findtext('flavor-id'))
+
+ # TODO: would be awesome to get the slicehost api developers to fill in the
+ # the correct validation logic
+ if not (name and image_id and flavor_id) \
+ or tree.tag != 'slice' \
+ or not headers.has_key('Content-Type') \
+ or headers['Content-Type'] != 'application/xml':
+
+ err_body = self.fixtures.load('slices_error.xml')
+ return (httplib.UNPROCESSABLE_ENTITY, err_body, {}, '')
+
+ body = self.fixtures.load('slices_post.xml')
+ return (httplib.CREATED, body, {}, '')
+ else:
+ body = self.fixtures.load('slices_get.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _slices_xml_UNAUTHORIZED(self, method, url, body, headers):
+ err_body = 'HTTP Basic: Access denied.'
+ return (httplib.UNAUTHORIZED, err_body, {},
+ httplib.responses[httplib.UNAUTHORIZED])
+
+ def _flavors_xml(self, method, url, body, headers):
+ body = self.fixtures.load('flavors.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _images_xml(self, method, url, body, headers):
+ body = self.fixtures.load('images.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _slices_1_reboot_xml(self, method, url, body, headers):
+ body = self.fixtures.load('slices_1_reboot.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _slices_1_reboot_xml_FORBIDDEN(self, method, url, body, headers):
+ body = self.fixtures.load('slices_1_reboot_forbidden.xml')
+ return (httplib.FORBIDDEN, body, {}, httplib.responses[httplib.FORBIDDEN])
+
+ def _slices_1_destroy_xml(self, method, url, body, headers):
+ body = ''
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+if __name__ == '__main__':
+ sys.exit(unittest.main())
Added: incubator/libcloud/trunk/test/compute/test_softlayer.py
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/compute/test_softlayer.py?rev=1079029&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/compute/test_softlayer.py (added)
+++ incubator/libcloud/trunk/test/compute/test_softlayer.py Mon Mar 7 23:44:06 2011
@@ -0,0 +1,83 @@
+# 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 httplib
+import unittest
+import sys
+
+from xml.etree import ElementTree as ET
+import xmlrpclib
+
+from libcloud.compute.drivers.softlayer import SoftLayerNodeDriver as SoftLayer
+from libcloud.compute.types import NodeState
+
+from test import MockHttp
+from test.compute import TestCaseMixin
+from test.file_fixtures import ComputeFileFixtures
+
+from test.secrets import SOFTLAYER_USER, SOFTLAYER_APIKEY
+
+class MockSoftLayerTransport(xmlrpclib.Transport):
+
+ def request(self, host, handler, request_body, verbose=0):
+ self.verbose = 0
+ method = ET.XML(request_body).find('methodName').text
+ mock = SoftLayerMockHttp(host, 80)
+ mock.request('POST', "%s/%s" % (handler, method))
+ resp = mock.getresponse()
+
+ return self._parse_response(resp.body, None)
+
+class SoftLayerTests(unittest.TestCase):
+
+ def setUp(self):
+ SoftLayer.connectionCls.proxyCls.transportCls = [MockSoftLayerTransport, MockSoftLayerTransport]
+ self.driver = SoftLayer(SOFTLAYER_USER, SOFTLAYER_APIKEY)
+
+ def test_list_nodes(self):
+ node = self.driver.list_nodes()[0]
+ self.assertEqual(node.name, 'test1')
+ self.assertEqual(node.state, NodeState.RUNNING)
+ self.assertEqual(node.extra['password'], 'TEST')
+
+ def test_list_locations(self):
+ locations = self.driver.list_locations()
+ seattle = (l for l in locations if l.name == 'sea01').next()
+ self.assertEqual(seattle.country, 'US')
+ self.assertEqual(seattle.id, '18171')
+
+ def test_list_images(self):
+ images = self.driver.list_images()
+ image = images[0]
+ self.assertEqual(image.id, '1684')
+
+ def test_list_sizes(self):
+ sizes = self.driver.list_sizes()
+ self.assertEqual(len(sizes), 2)
+ self.assertEqual(sizes[0].id, 'sl1')
+
+class SoftLayerMockHttp(MockHttp):
+ fixtures = ComputeFileFixtures('softlayer')
+
+ def _xmlrpc_v3_SoftLayer_Account_getVirtualGuests(self, method, url, body, headers):
+ body = self.fixtures.load('v3_SoftLayer_Account_getVirtualGuests.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _xmlrpc_v3_SoftLayer_Location_Datacenter_getDatacenters(self, method, url, body, headers):
+ body = self.fixtures.load('v3_SoftLayer_Location_Datacenter_getDatacenters.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+if __name__ == '__main__':
+ sys.exit(unittest.main())
Added: incubator/libcloud/trunk/test/compute/test_vcloud.py
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/compute/test_vcloud.py?rev=1079029&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/compute/test_vcloud.py (added)
+++ incubator/libcloud/trunk/test/compute/test_vcloud.py Mon Mar 7 23:44:06 2011
@@ -0,0 +1,142 @@
+# 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 httplib
+
+from libcloud.compute.drivers.vcloud import TerremarkDriver
+from libcloud.compute.drivers.vcloud import VCloudNodeDriver
+from libcloud.compute.base import Node
+from libcloud.compute.types import NodeState
+
+from test import MockHttp
+from test.compute import TestCaseMixin
+from test.file_fixtures import ComputeFileFixtures
+
+from test.secrets import TERREMARK_USER, TERREMARK_SECRET
+
+class TerremarkTests(unittest.TestCase, TestCaseMixin):
+
+ def setUp(self):
+ VCloudNodeDriver.connectionCls.host = "test"
+ VCloudNodeDriver.connectionCls.conn_classes = (None, TerremarkMockHttp)
+ TerremarkMockHttp.type = None
+ self.driver = TerremarkDriver(TERREMARK_USER, TERREMARK_SECRET)
+
+ def test_list_images(self):
+ ret = self.driver.list_images()
+ self.assertEqual(ret[0].id,'https://services.vcloudexpress.terremark.com/api/v0.8/vAppTemplate/5')
+
+ def test_list_sizes(self):
+ ret = self.driver.list_sizes()
+ self.assertEqual(ret[0].ram, 512)
+
+ def test_create_node(self):
+ image = self.driver.list_images()[0]
+ size = self.driver.list_sizes()[0]
+ node = self.driver.create_node(
+ name='testerpart2',
+ image=image,
+ size=size,
+ vdc='https://services.vcloudexpress.terremark.com/api/v0.8/vdc/224',
+ network='https://services.vcloudexpress.terremark.com/api/v0.8/network/725',
+ cpus=2,
+ )
+ self.assertTrue(isinstance(node, Node))
+ self.assertEqual(node.id, 'https://services.vcloudexpress.terremark.com/api/v0.8/vapp/14031')
+ self.assertEqual(node.name, 'testerpart2')
+
+ def test_list_nodes(self):
+ ret = self.driver.list_nodes()
+ node = ret[0]
+ self.assertEqual(node.id, 'https://services.vcloudexpress.terremark.com/api/v0.8/vapp/14031')
+ self.assertEqual(node.name, 'testerpart2')
+ self.assertEqual(node.state, NodeState.RUNNING)
+ self.assertEqual(node.public_ip, [])
+ self.assertEqual(node.private_ip, ['10.112.78.69'])
+
+ def test_reboot_node(self):
+ node = self.driver.list_nodes()[0]
+ ret = self.driver.reboot_node(node)
+ self.assertTrue(ret)
+
+ def test_destroy_node(self):
+ node = self.driver.list_nodes()[0]
+ ret = self.driver.destroy_node(node)
+ self.assertTrue(ret)
+
+
+class TerremarkMockHttp(MockHttp):
+
+ fixtures = ComputeFileFixtures('terremark')
+
+ def _api_v0_8_login(self, method, url, body, headers):
+ headers['set-cookie'] = 'vcloud-token=testtoken'
+ body = self.fixtures.load('api_v0_8_login.xml')
+ return (httplib.OK, body, headers, httplib.responses[httplib.OK])
+
+ def _api_v0_8_org_240(self, method, url, body, headers):
+ body = self.fixtures.load('api_v0_8_org_240.xml')
+ return (httplib.OK, body, headers, httplib.responses[httplib.OK])
+
+ def _api_v0_8_vdc_224(self, method, url, body, headers):
+ body = self.fixtures.load('api_v0_8_vdc_224.xml')
+ return (httplib.OK, body, headers, httplib.responses[httplib.OK])
+
+ def _api_v0_8_vdc_224_catalog(self, method, url, body, headers):
+ body = self.fixtures.load('api_v0_8_vdc_224_catalog.xml')
+ return (httplib.OK, body, headers, httplib.responses[httplib.OK])
+
+ def _api_v0_8_catalogItem_5(self, method, url, body, headers):
+ body = self.fixtures.load('api_v0_8_catalogItem_5.xml')
+ return (httplib.OK, body, headers, httplib.responses[httplib.OK])
+
+ def _api_v0_8_vdc_224_action_instantiateVAppTemplate(self, method, url, body, headers):
+ body = self.fixtures.load('api_v0_8_vdc_224_action_instantiateVAppTemplate.xml')
+ return (httplib.OK, body, headers, httplib.responses[httplib.OK])
+
+ def _api_v0_8_vapp_14031_action_deploy(self, method, url, body, headers):
+ body = self.fixtures.load('api_v0_8_vapp_14031_action_deploy.xml')
+ return (httplib.ACCEPTED, body, headers, httplib.responses[httplib.ACCEPTED])
+
+ def _api_v0_8_task_10496(self, method, url, body, headers):
+ body = self.fixtures.load('api_v0_8_task_10496.xml')
+ return (httplib.ACCEPTED, body, headers, httplib.responses[httplib.ACCEPTED])
+
+ def _api_v0_8_vapp_14031_power_action_powerOn(self, method, url, body, headers):
+ body = self.fixtures.load('api_v0_8_vapp_14031_power_action_powerOn.xml')
+ return (httplib.ACCEPTED, body, headers, httplib.responses[httplib.ACCEPTED])
+
+ def _api_v0_8_vapp_14031(self, method, url, body, headers):
+ if method == 'GET':
+ body = self.fixtures.load('api_v0_8_vapp_14031_get.xml')
+ elif method == 'DELETE':
+ body = ''
+ return (httplib.ACCEPTED, body, headers, httplib.responses[httplib.ACCEPTED])
+
+ def _api_v0_8_vapp_14031_power_action_reset(self, method, url, body, headers):
+ body = self.fixtures.load('api_v0_8_vapp_14031_power_action_reset.xml')
+ return (httplib.ACCEPTED, body, headers, httplib.responses[httplib.ACCEPTED])
+
+ def _api_v0_8_vapp_14031_power_action_poweroff(self, method, url, body, headers):
+ body = self.fixtures.load('api_v0_8_vapp_14031_power_action_poweroff.xml')
+ return (httplib.ACCEPTED, body, headers, httplib.responses[httplib.ACCEPTED])
+
+ def _api_v0_8_task_11001(self, method, url, body, headers):
+ body = self.fixtures.load('api_v0_8_task_11001.xml')
+ return (httplib.ACCEPTED, body, headers, httplib.responses[httplib.ACCEPTED])
+
+if __name__ == '__main__':
+ sys.exit(unittest.main())
Added: incubator/libcloud/trunk/test/compute/test_voxel.py
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/compute/test_voxel.py?rev=1079029&view=auto
==============================================================================
--- incubator/libcloud/trunk/test/compute/test_voxel.py (added)
+++ incubator/libcloud/trunk/test/compute/test_voxel.py Mon Mar 7 23:44:06 2011
@@ -0,0 +1,53 @@
+# 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 httplib
+
+from libcloud.compute.drivers.voxel import VoxelNodeDriver as Voxel
+from libcloud.compute.types import InvalidCredsError
+
+from test import MockHttp
+from test.file_fixtures import ComputeFileFixtures
+
+from test.secrets import VOXEL_KEY, VOXEL_SECRET
+
+class VoxelTest(unittest.TestCase):
+
+ def setUp(self):
+
+ Voxel.connectionCls.conn_classes = (None, VoxelMockHttp)
+ VoxelMockHttp.type = None
+ self.driver = Voxel(VOXEL_KEY, VOXEL_SECRET)
+
+ def test_auth_failed(self):
+ VoxelMockHttp.type = 'UNAUTHORIZED'
+ try:
+ self.driver.list_nodes()
+ except Exception, e:
+ self.assertTrue(isinstance(e, InvalidCredsError))
+ else:
+ self.fail('test should have thrown')
+
+class VoxelMockHttp(MockHttp):
+
+ fixtures = ComputeFileFixtures('voxel')
+
+ def _UNAUTHORIZED(self, method, url, body, headers):
+ body = self.fixtures.load('unauthorized.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+if __name__ == '__main__':
+ sys.exit(unittest.main())