Merge remote-tracking branch 'origin/github-728' into github-728
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/193e0e0b Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/193e0e0b Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/193e0e0b Branch: refs/heads/trunk Commit: 193e0e0b85dfc159de5abbe7afeaea7ccdaf59bd Parents: b823179 da4327a Author: Anthony Shaw <anthonys...@apache.org> Authored: Tue Jan 3 12:07:01 2017 +1100 Committer: Anthony Shaw <anthonys...@apache.org> Committed: Tue Jan 3 12:07:01 2017 +1100 ---------------------------------------------------------------------- libcloud/__init__.py | 12 +- libcloud/common/base.py | 2186 ++++++++---------- libcloud/common/exceptions.py | 1 - libcloud/common/openstack_identity.py | 2 +- libcloud/common/ovh.py | 4 +- libcloud/httplib_ssl.py | 279 +-- libcloud/test/__init__.py | 30 +- libcloud/test/backup/test_dimensiondata_v2_3.py | 1006 ++++---- libcloud/test/common/test_cloudstack.py | 2 +- libcloud/test/common/test_digitalocean_v2.py | 8 +- libcloud/test/common/test_google.py | 9 +- libcloud/test/common/test_nfsn.py | 2 +- libcloud/test/common/test_openstack.py | 6 +- libcloud/test/common/test_openstack_identity.py | 10 +- libcloud/test/common/test_retry_limit.py | 26 - libcloud/test/compute/test_abiquo.py | 4 +- libcloud/test/compute/test_azure.py | 2 +- libcloud/test/compute/test_bluebox.py | 2 +- libcloud/test/compute/test_brightbox.py | 52 +- libcloud/test/compute/test_cloudsigma_v1_0.py | 5 +- libcloud/test/compute/test_cloudsigma_v2_0.py | 3 +- libcloud/test/compute/test_cloudstack.py | 3 +- libcloud/test/compute/test_deployment.py | 2 +- libcloud/test/compute/test_digitalocean_v2.py | 4 +- .../test/compute/test_dimensiondata_v2_3.py | 2 +- libcloud/test/compute/test_ec2.py | 10 +- libcloud/test/compute/test_ecp.py | 3 +- libcloud/test/compute/test_ecs.py | 2 +- libcloud/test/compute/test_elasticstack.py | 9 +- libcloud/test/compute/test_gandi.py | 6 +- libcloud/test/compute/test_gce.py | 14 +- libcloud/test/compute/test_gogrid.py | 2 +- libcloud/test/compute/test_gridspot.py | 5 +- libcloud/test/compute/test_hostvirtual.py | 3 +- libcloud/test/compute/test_joyent.py | 2 +- libcloud/test/compute/test_ktucloud.py | 3 +- libcloud/test/compute/test_linode.py | 2 +- libcloud/test/compute/test_nephoscale.py | 3 +- libcloud/test/compute/test_onapp.py | 3 +- libcloud/test/compute/test_opennebula.py | 18 +- libcloud/test/compute/test_openstack.py | 30 +- libcloud/test/compute/test_ovh.py | 3 +- libcloud/test/compute/test_packet.py | 2 +- libcloud/test/compute/test_profitbricks.py | 2 +- libcloud/test/compute/test_rackspace.py | 9 +- libcloud/test/compute/test_rimuhosting.py | 3 +- libcloud/test/compute/test_softlayer.py | 3 +- libcloud/test/compute/test_vcl.py | 3 +- libcloud/test/compute/test_vcloud.py | 11 +- libcloud/test/compute/test_voxel.py | 2 +- libcloud/test/compute/test_vpsnet.py | 2 +- libcloud/test/compute/test_vultr.py | 3 +- libcloud/test/container/test_docker.py | 4 +- libcloud/test/container/test_docker_utils.py | 3 +- libcloud/test/container/test_ecs.py | 6 +- libcloud/test/container/test_kubernetes.py | 3 +- libcloud/test/container/test_rancher.py | 4 +- libcloud/test/dns/fixtures/route53/get_zone.xml | 1 - libcloud/test/dns/test_auroradns.py | 3 +- libcloud/test/dns/test_buddyns.py | 2 +- libcloud/test/dns/test_cloudflare.py | 3 +- libcloud/test/dns/test_digitalocean.py | 73 +- libcloud/test/dns/test_dnsimple.py | 3 +- libcloud/test/dns/test_dnspod.py | 2 +- libcloud/test/dns/test_durabledns.py | 3 +- libcloud/test/dns/test_gandi.py | 3 +- libcloud/test/dns/test_godaddy.py | 3 +- libcloud/test/dns/test_google.py | 6 +- libcloud/test/dns/test_hostvirtual.py | 3 +- libcloud/test/dns/test_linode.py | 3 +- libcloud/test/dns/test_liquidweb.py | 3 +- libcloud/test/dns/test_luadns.py | 3 +- libcloud/test/dns/test_nfsn.py | 2 +- libcloud/test/dns/test_nsone.py | 2 +- libcloud/test/dns/test_pointdns.py | 3 +- libcloud/test/dns/test_powerdns.py | 3 +- libcloud/test/dns/test_rackspace.py | 3 +- libcloud/test/dns/test_route53.py | 3 +- libcloud/test/dns/test_softlayer.py | 3 +- libcloud/test/dns/test_vultr.py | 3 +- libcloud/test/dns/test_worldwidedns.py | 3 +- libcloud/test/dns/test_zerigo.py | 3 +- libcloud/test/dns/test_zonomi.py | 2 +- libcloud/test/loadbalancer/test_brightbox.py | 29 +- libcloud/test/loadbalancer/test_cloudstack.py | 3 +- .../loadbalancer/test_dimensiondata_v2_3.py | 2 +- libcloud/test/loadbalancer/test_elb.py | 3 +- libcloud/test/loadbalancer/test_gce.py | 7 +- libcloud/test/loadbalancer/test_gogrid.py | 3 +- libcloud/test/loadbalancer/test_rackspace.py | 9 +- libcloud/test/loadbalancer/test_slb.py | 3 +- libcloud/test/loadbalancer/test_softlayer.py | 3 +- libcloud/test/storage/test_atmos.py | 2 +- libcloud/test/storage/test_azure_blobs.py | 3 +- libcloud/test/storage/test_backblaze_b2.py | 476 ++-- libcloud/test/storage/test_base.py | 2 +- libcloud/test/storage/test_cloudfiles.py | 3 +- libcloud/test/storage/test_google_storage.py | 3 +- libcloud/test/storage/test_oss.py | 3 +- libcloud/test/storage/test_s3.py | 3 +- libcloud/test/test_connection.py | 33 +- libcloud/test/test_httplib_ssl.py | 20 +- libcloud/test/test_init.py | 10 +- libcloud/test/test_response_classes.py | 144 +- libcloud/utils/loggingconnection.py | 196 ++ requirements-tests.txt | 4 +- setup.py | 5 +- 107 files changed, 2295 insertions(+), 2658 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/libcloud/blob/193e0e0b/libcloud/__init__.py ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/libcloud/blob/193e0e0b/libcloud/common/openstack_identity.py ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/libcloud/blob/193e0e0b/libcloud/test/backup/test_dimensiondata_v2_3.py ---------------------------------------------------------------------- diff --cc libcloud/test/backup/test_dimensiondata_v2_3.py index b0e581a,0000000..d269f7e mode 100644,000000..100644 --- a/libcloud/test/backup/test_dimensiondata_v2_3.py +++ b/libcloud/test/backup/test_dimensiondata_v2_3.py @@@ -1,503 -1,0 +1,503 @@@ - # 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. - - try: - from lxml import etree as ET - except ImportError: - from xml.etree import ElementTree as ET - - import sys - from libcloud.utils.py3 import httplib - - from libcloud.common.dimensiondata import DimensionDataAPIException - from libcloud.common.types import InvalidCredsError - from libcloud.backup.base import BackupTargetJob - from libcloud.backup.drivers.dimensiondata import DimensionDataBackupDriver as DimensionData - from libcloud.backup.drivers.dimensiondata import DEFAULT_BACKUP_PLAN - - from libcloud.test import MockHttp, unittest - from libcloud.test.backup import TestCaseMixin - from libcloud.test.file_fixtures import BackupFileFixtures - - from libcloud.test.secrets import DIMENSIONDATA_PARAMS - - - class DimensionData_v2_3_Tests(unittest.TestCase, TestCaseMixin): - - def setUp(self): - DimensionData.connectionCls.active_api_version = '2.3' - DimensionData.connectionCls.conn_classes = (None, DimensionDataMockHttp) - DimensionDataMockHttp.type = None - self.driver = DimensionData(*DIMENSIONDATA_PARAMS) - - def test_invalid_region(self): - with self.assertRaises(ValueError): - self.driver = DimensionData(*DIMENSIONDATA_PARAMS, region='blah') - - def test_invalid_creds(self): - DimensionDataMockHttp.type = 'UNAUTHORIZED' - with self.assertRaises(InvalidCredsError): - self.driver.list_targets() - - def test_list_targets(self): - targets = self.driver.list_targets() - self.assertEqual(len(targets), 2) - self.assertEqual(targets[0].id, '5579f3a7-4c32-4cf5-8a7e-b45c36a35c10') - self.assertEqual(targets[0].address, 'e75ead52-692f-4314-8725-c8a4f4d13a87') - self.assertEqual(targets[0].extra['servicePlan'], 'Enterprise') - - def test_create_target(self): - target = self.driver.create_target( - 'name', - 'e75ead52-692f-4314-8725-c8a4f4d13a87', - extra={'servicePlan': 'Enterprise'}) - self.assertEqual(target.id, 'ee7c4b64-f7af-4a4f-8384-be362273530f') - self.assertEqual(target.address, 'e75ead52-692f-4314-8725-c8a4f4d13a87') - self.assertEqual(target.extra['servicePlan'], 'Enterprise') - - def test_create_target_DEFAULT(self): - DimensionDataMockHttp.type = 'DEFAULT' - target = self.driver.create_target( - 'name', - 'e75ead52-692f-4314-8725-c8a4f4d13a87') - self.assertEqual(target.id, 'ee7c4b64-f7af-4a4f-8384-be362273530f') - self.assertEqual(target.address, 'e75ead52-692f-4314-8725-c8a4f4d13a87') - - def test_create_target_EXISTS(self): - DimensionDataMockHttp.type = 'EXISTS' - with self.assertRaises(DimensionDataAPIException) as context: - self.driver.create_target( - 'name', - 'e75ead52-692f-4314-8725-c8a4f4d13a87', - extra={'servicePlan': 'Enterprise'}) - self.assertEqual(context.exception.code, 'ERROR') - self.assertEqual(context.exception.msg, 'Cloud backup for this server is already enabled or being enabled (state: NORMAL).') - - def test_update_target(self): - target = self.driver.list_targets()[0] - extra = {'servicePlan': 'Essentials'} - new_target = self.driver.update_target(target, extra=extra) - self.assertEqual(new_target.extra['servicePlan'], 'Essentials') - - def test_update_target_DEFAULT(self): - DimensionDataMockHttp.type = 'DEFAULT' - target = 'e75ead52-692f-4314-8725-c8a4f4d13a87' - self.driver.update_target(target) - - def test_update_target_STR(self): - target = 'e75ead52-692f-4314-8725-c8a4f4d13a87' - extra = {'servicePlan': 'Essentials'} - new_target = self.driver.update_target(target, extra=extra) - self.assertEqual(new_target.extra['servicePlan'], 'Essentials') - - def test_delete_target(self): - target = self.driver.list_targets()[0] - self.assertTrue(self.driver.delete_target(target)) - - def test_ex_add_client_to_target(self): - target = self.driver.list_targets()[0] - client = self.driver.ex_list_available_client_types(target)[0] - storage_policy = self.driver.ex_list_available_storage_policies(target)[0] - schedule_policy = self.driver.ex_list_available_schedule_policies(target)[0] - self.assertTrue( - self.driver.ex_add_client_to_target(target, client, storage_policy, - schedule_policy, 'ON_FAILURE', 'nob...@example.com') - ) - - def test_ex_add_client_to_target_STR(self): - self.assertTrue( - self.driver.ex_add_client_to_target('e75ead52-692f-4314-8725-c8a4f4d13a87', 'FA.Linux', '14 Day Storage Policy', - '12AM - 6AM', 'ON_FAILURE', 'nob...@example.com') - ) - - def test_ex_get_backup_details_for_target(self): - target = self.driver.list_targets()[0] - response = self.driver.ex_get_backup_details_for_target(target) - self.assertEqual(response.service_plan, 'Enterprise') - client = response.clients[0] - self.assertEqual(client.id, '30b1ff76-c76d-4d7c-b39d-3b72be0384c8') - self.assertEqual(client.type.type, 'FA.Linux') - self.assertEqual(client.running_job.progress, 5) - self.assertTrue(isinstance(client.running_job, BackupTargetJob)) - self.assertEqual(len(client.alert.notify_list), 2) - self.assertTrue(isinstance(client.alert.notify_list, list)) - - def test_ex_get_backup_details_for_target_NOBACKUP(self): - target = self.driver.list_targets()[0].address - DimensionDataMockHttp.type = 'NOBACKUP' - response = self.driver.ex_get_backup_details_for_target(target) - self.assertTrue(response is None) - - def test_ex_cancel_target_job(self): - target = self.driver.list_targets()[0] - response = self.driver.ex_get_backup_details_for_target(target) - client = response.clients[0] - self.assertTrue(isinstance(client.running_job, BackupTargetJob)) - success = client.running_job.cancel() - self.assertTrue(success) - - def test_ex_cancel_target_job_with_extras(self): - success = self.driver.cancel_target_job( - None, - ex_client='30b1ff76_c76d_4d7c_b39d_3b72be0384c8', - ex_target='e75ead52_692f_4314_8725_c8a4f4d13a87' - ) - self.assertTrue(success) - - def test_ex_cancel_target_job_FAIL(self): - DimensionDataMockHttp.type = 'FAIL' - with self.assertRaises(DimensionDataAPIException) as context: - self.driver.cancel_target_job( - None, - ex_client='30b1ff76_c76d_4d7c_b39d_3b72be0384c8', - ex_target='e75ead52_692f_4314_8725_c8a4f4d13a87' - ) - self.assertEqual(context.exception.code, 'ERROR') - - """Test a backup info for a target that does not have a client""" - def test_ex_get_backup_details_for_target_NO_CLIENT(self): - DimensionDataMockHttp.type = 'NOCLIENT' - response = self.driver.ex_get_backup_details_for_target('e75ead52-692f-4314-8725-c8a4f4d13a87') - self.assertEqual(response.service_plan, 'Essentials') - self.assertEqual(len(response.clients), 0) - - """Test a backup details that has a client, but no alerting or running jobs""" - def test_ex_get_backup_details_for_target_NO_JOB_OR_ALERT(self): - DimensionDataMockHttp.type = 'NOJOB' - response = self.driver.ex_get_backup_details_for_target('e75ead52-692f-4314_8725-c8a4f4d13a87') - self.assertEqual(response.service_plan, 'Enterprise') - self.assertTrue(isinstance(response.clients, list)) - self.assertEqual(len(response.clients), 1) - client = response.clients[0] - self.assertEqual(client.id, '30b1ff76-c76d-4d7c-b39d-3b72be0384c8') - self.assertEqual(client.type.type, 'FA.Linux') - self.assertIsNone(client.running_job) - self.assertIsNone(client.alert) - - """Test getting backup info for a server that doesn't exist""" - def test_ex_get_backup_details_for_target_DISABLED(self): - DimensionDataMockHttp.type = 'DISABLED' - with self.assertRaises(DimensionDataAPIException) as context: - self.driver.ex_get_backup_details_for_target('e75ead52-692f-4314-8725-c8a4f4d13a87') - self.assertEqual(context.exception.code, 'ERROR') - self.assertEqual(context.exception.msg, 'Server e75ead52-692f-4314-8725-c8a4f4d13a87 has not been provisioned for backup') - - def test_ex_list_available_client_types(self): - target = self.driver.list_targets()[0] - answer = self.driver.ex_list_available_client_types(target) - self.assertEqual(len(answer), 1) - self.assertEqual(answer[0].type, 'FA.Linux') - self.assertEqual(answer[0].is_file_system, True) - self.assertEqual(answer[0].description, 'Linux File system') - - def test_ex_list_available_storage_policies(self): - target = self.driver.list_targets()[0] - answer = self.driver.ex_list_available_storage_policies(target) - self.assertEqual(len(answer), 1) - self.assertEqual(answer[0].name, - '30 Day Storage Policy + Secondary Copy') - self.assertEqual(answer[0].retention_period, 30) - self.assertEqual(answer[0].secondary_location, 'Primary') - - def test_ex_list_available_schedule_policies(self): - target = self.driver.list_targets()[0] - answer = self.driver.ex_list_available_schedule_policies(target) - self.assertEqual(len(answer), 1) - self.assertEqual(answer[0].name, '12AM - 6AM') - self.assertEqual(answer[0].description, 'Daily backup will start between 12AM - 6AM') - - def test_ex_remove_client_from_target(self): - target = self.driver.list_targets()[0] - client = self.driver.ex_get_backup_details_for_target('e75ead52-692f-4314-8725-c8a4f4d13a87').clients[0] - self.assertTrue(self.driver.ex_remove_client_from_target(target, client)) - - def test_ex_remove_client_from_target_STR(self): - self.assertTrue( - self.driver.ex_remove_client_from_target( - 'e75ead52-692f-4314-8725-c8a4f4d13a87', - '30b1ff76-c76d-4d7c-b39d-3b72be0384c8' - ) - ) - - def test_ex_remove_client_from_target_FAIL(self): - DimensionDataMockHttp.type = 'FAIL' - with self.assertRaises(DimensionDataAPIException) as context: - self.driver.ex_remove_client_from_target( - 'e75ead52-692f-4314-8725-c8a4f4d13a87', - '30b1ff76-c76d-4d7c-b39d-3b72be0384c8' - ) - self.assertEqual(context.exception.code, 'ERROR') - self.assertTrue('Backup Client is currently performing another operation' in context.exception.msg) - - def test_priv_target_to_target_address(self): - target = self.driver.list_targets()[0] - self.assertEqual( - self.driver._target_to_target_address(target), - 'e75ead52-692f-4314-8725-c8a4f4d13a87' - ) - - def test_priv_target_to_target_address_STR(self): - self.assertEqual( - self.driver._target_to_target_address('e75ead52-692f-4314-8725-c8a4f4d13a87'), - 'e75ead52-692f-4314-8725-c8a4f4d13a87' - ) - - def test_priv_target_to_target_address_TYPEERROR(self): - with self.assertRaises(TypeError): - self.driver._target_to_target_address([1, 2, 3]) - - def test_priv_client_to_client_id(self): - client = self.driver.ex_get_backup_details_for_target('e75ead52-692f-4314-8725-c8a4f4d13a87').clients[0] - self.assertEqual( - self.driver._client_to_client_id(client), - '30b1ff76-c76d-4d7c-b39d-3b72be0384c8' - ) - - def test_priv_client_to_client_id_STR(self): - self.assertEqual( - self.driver._client_to_client_id('30b1ff76-c76d-4d7c-b39d-3b72be0384c8'), - '30b1ff76-c76d-4d7c-b39d-3b72be0384c8' - ) - - def test_priv_client_to_client_id_TYPEERROR(self): - with self.assertRaises(TypeError): - self.driver._client_to_client_id([1, 2, 3]) - - - class InvalidRequestError(Exception): - def __init__(self, tag): - super(InvalidRequestError, self).__init__("Invalid Request - %s" % tag) - - - class DimensionDataMockHttp(MockHttp): - - fixtures = BackupFileFixtures('dimensiondata') - - def _oec_0_9_myaccount_UNAUTHORIZED(self, method, url, body, headers): - return (httplib.UNAUTHORIZED, "", {}, httplib.responses[httplib.UNAUTHORIZED]) - - def _oec_0_9_myaccount(self, method, url, body, headers): - body = self.fixtures.load('oec_0_9_myaccount.xml') - return (httplib.OK, body, {}, httplib.responses[httplib.OK]) - - def _oec_0_9_myaccount_EXISTS(self, method, url, body, headers): - body = self.fixtures.load('oec_0_9_myaccount.xml') - return (httplib.OK, body, {}, httplib.responses[httplib.OK]) - - def _oec_0_9_myaccount_DEFAULT(self, method, url, body, headers): - body = self.fixtures.load('oec_0_9_myaccount.xml') - return (httplib.OK, body, {}, httplib.responses[httplib.OK]) - - def _oec_0_9_myaccount_INPROGRESS(self, method, url, body, headers): - body = self.fixtures.load('oec_0_9_myaccount.xml') - return (httplib.OK, body, {}, httplib.responses[httplib.OK]) - - def _oec_0_9_myaccount_FAIL(self, method, url, body, headers): - body = self.fixtures.load('oec_0_9_myaccount.xml') - return (httplib.OK, body, {}, httplib.responses[httplib.OK]) - - def _oec_0_9_myaccount_NOCLIENT(self, method, url, body, headers): - body = self.fixtures.load('oec_0_9_myaccount.xml') - return (httplib.OK, body, {}, httplib.responses[httplib.OK]) - - def _oec_0_9_myaccount_DISABLED(self, method, url, body, headers): - body = self.fixtures.load('oec_0_9_myaccount.xml') - return (httplib.OK, body, {}, httplib.responses[httplib.OK]) - - def _oec_0_9_myaccount_NOJOB(self, method, url, body, headers): - body = self.fixtures.load('oec_0_9_myaccount.xml') - return (httplib.OK, body, {}, httplib.responses[httplib.OK]) - - def _caas_2_3_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server_e75ead52_692f_4314_8725_c8a4f4d13a87(self, method, url, body, headers): - body = self.fixtures.load( - 'server_server_e75ead52_692f_4314_8725_c8a4f4d13a87.xml') - return (httplib.OK, body, {}, httplib.responses[httplib.OK]) - - def _caas_2_3_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server_e75ead52_692f_4314_8725_c8a4f4d13a87_DEFAULT(self, method, url, body, headers): - body = self.fixtures.load( - 'server_server_e75ead52_692f_4314_8725_c8a4f4d13a87_DEFAULT.xml') - return (httplib.OK, body, {}, httplib.responses[httplib.OK]) - - def _caas_2_3_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server_e75ead52_692f_4314_8725_c8a4f4d13a87_NOCLIENT(self, method, url, body, headers): - body = self.fixtures.load( - 'server_server_e75ead52_692f_4314_8725_c8a4f4d13a87_DEFAULT.xml') - return (httplib.OK, body, {}, httplib.responses[httplib.OK]) - - def _caas_2_3_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server_e75ead52_692f_4314_8725_c8a4f4d13a87_NOJOB(self, method, url, body, headers): - body = self.fixtures.load( - 'server_server_e75ead52_692f_4314_8725_c8a4f4d13a87_DEFAULT.xml') - return (httplib.OK, body, {}, httplib.responses[httplib.OK]) - - def _caas_2_3_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server_e75ead52_692f_4314_8725_c8a4f4d13a87_DISABLED(self, method, url, body, headers): - body = self.fixtures.load( - 'server_server_e75ead52_692f_4314_8725_c8a4f4d13a87_DEFAULT.xml') - return (httplib.OK, body, {}, httplib.responses[httplib.OK]) - - def _caas_2_3_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server(self, method, url, body, headers): - body = self.fixtures.load( - 'server_server.xml') - return (httplib.OK, body, {}, httplib.responses[httplib.OK]) - - def _oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_client_type(self, method, url, body, headers): - body = self.fixtures.load( - '_backup_client_type.xml') - return (httplib.OK, body, {}, httplib.responses[httplib.OK]) - - def _oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_client_storagePolicy( - self, method, url, body, headers): - body = self.fixtures.load( - '_backup_client_storagePolicy.xml') - return (httplib.OK, body, {}, httplib.responses[httplib.OK]) - - def _oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_client_schedulePolicy( - self, method, url, body, headers): - body = self.fixtures.load( - '_backup_client_schedulePolicy.xml') - return (httplib.OK, body, {}, httplib.responses[httplib.OK]) - - def _oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_client( - self, method, url, body, headers): - if method == 'POST': - body = self.fixtures.load( - '_backup_client_SUCCESS_PUT.xml') - return (httplib.OK, body, {}, httplib.responses[httplib.OK]) - else: - raise ValueError("Unknown Method {0}".format(method)) - - def _oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_NOCLIENT( - self, method, url, body, headers): - # only gets here are implemented - # If we get any other method something has gone wrong - assert(method == 'GET') - body = self.fixtures.load( - '_backup_INFO_NOCLIENT.xml') - return (httplib.OK, body, {}, httplib.responses[httplib.OK]) - - def _oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_DISABLED( - self, method, url, body, headers): - # only gets here are implemented - # If we get any other method something has gone wrong - assert(method == 'GET') - body = self.fixtures.load( - '_backup_INFO_DISABLED.xml') - return (httplib.BAD_REQUEST, body, {}, httplib.responses[httplib.OK]) - - def _oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_NOJOB( - self, method, url, body, headers): - # only gets here are implemented - # If we get any other method something has gone wrong - assert(method == 'GET') - body = self.fixtures.load( - '_backup_INFO_NOJOB.xml') - return (httplib.OK, body, {}, httplib.responses[httplib.OK]) - - def _oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_DEFAULT( - self, method, url, body, headers): - if method != 'POST': - raise InvalidRequestError('Only POST is accepted for this test') - request = ET.fromstring(body) - service_plan = request.get('servicePlan') - if service_plan != DEFAULT_BACKUP_PLAN: - raise InvalidRequestError('The default plan %s should have been passed in. Not %s' % (DEFAULT_BACKUP_PLAN, service_plan)) - body = self.fixtures.load( - '_backup_ENABLE.xml') - return (httplib.OK, body, {}, httplib.responses[httplib.OK]) - - def _oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup( - self, method, url, body, headers): - if method == 'POST': - body = self.fixtures.load( - '_backup_ENABLE.xml') - return (httplib.OK, body, {}, httplib.responses[httplib.OK]) - elif method == 'GET': - if url.endswith('disable'): - body = self.fixtures.load( - '_backup_DISABLE.xml') - return (httplib.OK, body, {}, httplib.responses[httplib.OK]) - body = self.fixtures.load( - '_backup_INFO.xml') - return (httplib.OK, body, {}, httplib.responses[httplib.OK]) - - else: - raise ValueError("Unknown Method {0}".format(method)) - - def _caas_2_3_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server_e75ead52_692f_4314_8725_c8a4f4d13a87_NOBACKUP( - self, method, url, body, headers): - assert(method == 'GET') - body = self.fixtures.load('server_server_NOBACKUP.xml') - return (httplib.OK, body, {}, httplib.responses[httplib.OK]) - - def _oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_EXISTS( - self, method, url, body, headers): - # only POSTs are implemented - # If we get any other method something has gone wrong - assert(method == 'POST') - body = self.fixtures.load( - '_backup_EXISTS.xml') - return (httplib.BAD_REQUEST, body, {}, httplib.responses[httplib.OK]) - - def _oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_modify( - self, method, url, body, headers): - request = ET.fromstring(body) - service_plan = request.get('servicePlan') - if service_plan != 'Essentials': - raise InvalidRequestError("Expected Essentials backup plan in request") - body = self.fixtures.load('_backup_modify.xml') - - return (httplib.OK, body, {}, httplib.responses[httplib.OK]) - - def _oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_modify_DEFAULT( - self, method, url, body, headers): - request = ET.fromstring(body) - service_plan = request.get('servicePlan') - if service_plan != DEFAULT_BACKUP_PLAN: - raise InvalidRequestError("Expected % backup plan in test" % DEFAULT_BACKUP_PLAN) - body = self.fixtures.load('_backup_modify.xml') - - return (httplib.OK, body, {}, httplib.responses[httplib.OK]) - - def _oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_client_30b1ff76_c76d_4d7c_b39d_3b72be0384c8( - self, method, url, body, headers): - if url.endswith('disable'): - body = self.fixtures.load( - ('_remove_backup_client.xml') - ) - elif url.endswith('cancelJob'): - body = self.fixtures.load( - ('' - '_backup_client_30b1ff76_c76d_4d7c_b39d_3b72be0384c8_cancelJob.xml') - ) - else: - raise ValueError("Unknown URL: %s" % url) - return (httplib.OK, body, {}, httplib.responses[httplib.OK]) - - def _oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_client_30b1ff76_c76d_4d7c_b39d_3b72be0384c8_FAIL( - self, method, url, body, headers): - if url.endswith('disable'): - body = self.fixtures.load( - ('_remove_backup_client_FAIL.xml') - ) - elif url.endswith('cancelJob'): - body = self.fixtures.load( - ('' - '_backup_client_30b1ff76_c76d_4d7c_b39d_3b72be0384c8_cancelJob_FAIL.xml') - ) - else: - raise ValueError("Unknown URL: %s" % url) - return (httplib.BAD_REQUEST, body, {}, httplib.responses[httplib.OK]) - - - if __name__ == '__main__': - sys.exit(unittest.main()) ++# 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. ++ ++try: ++ from lxml import etree as ET ++except ImportError: ++ from xml.etree import ElementTree as ET ++ ++import sys ++from libcloud.utils.py3 import httplib ++ ++from libcloud.common.dimensiondata import DimensionDataAPIException ++from libcloud.common.types import InvalidCredsError ++from libcloud.backup.base import BackupTargetJob ++from libcloud.backup.drivers.dimensiondata import DimensionDataBackupDriver as DimensionData ++from libcloud.backup.drivers.dimensiondata import DEFAULT_BACKUP_PLAN ++ ++from libcloud.test import MockHttp, unittest ++from libcloud.test.backup import TestCaseMixin ++from libcloud.test.file_fixtures import BackupFileFixtures ++ ++from libcloud.test.secrets import DIMENSIONDATA_PARAMS ++ ++ ++class DimensionData_v2_3_Tests(unittest.TestCase, TestCaseMixin): ++ ++ def setUp(self): ++ DimensionData.connectionCls.active_api_version = '2.3' ++ DimensionData.connectionCls.conn_class = DimensionDataMockHttp ++ DimensionDataMockHttp.type = None ++ self.driver = DimensionData(*DIMENSIONDATA_PARAMS) ++ ++ def test_invalid_region(self): ++ with self.assertRaises(ValueError): ++ self.driver = DimensionData(*DIMENSIONDATA_PARAMS, region='blah') ++ ++ def test_invalid_creds(self): ++ DimensionDataMockHttp.type = 'UNAUTHORIZED' ++ with self.assertRaises(InvalidCredsError): ++ self.driver.list_targets() ++ ++ def test_list_targets(self): ++ targets = self.driver.list_targets() ++ self.assertEqual(len(targets), 2) ++ self.assertEqual(targets[0].id, '5579f3a7-4c32-4cf5-8a7e-b45c36a35c10') ++ self.assertEqual(targets[0].address, 'e75ead52-692f-4314-8725-c8a4f4d13a87') ++ self.assertEqual(targets[0].extra['servicePlan'], 'Enterprise') ++ ++ def test_create_target(self): ++ target = self.driver.create_target( ++ 'name', ++ 'e75ead52-692f-4314-8725-c8a4f4d13a87', ++ extra={'servicePlan': 'Enterprise'}) ++ self.assertEqual(target.id, 'ee7c4b64-f7af-4a4f-8384-be362273530f') ++ self.assertEqual(target.address, 'e75ead52-692f-4314-8725-c8a4f4d13a87') ++ self.assertEqual(target.extra['servicePlan'], 'Enterprise') ++ ++ def test_create_target_DEFAULT(self): ++ DimensionDataMockHttp.type = 'DEFAULT' ++ target = self.driver.create_target( ++ 'name', ++ 'e75ead52-692f-4314-8725-c8a4f4d13a87') ++ self.assertEqual(target.id, 'ee7c4b64-f7af-4a4f-8384-be362273530f') ++ self.assertEqual(target.address, 'e75ead52-692f-4314-8725-c8a4f4d13a87') ++ ++ def test_create_target_EXISTS(self): ++ DimensionDataMockHttp.type = 'EXISTS' ++ with self.assertRaises(DimensionDataAPIException) as context: ++ self.driver.create_target( ++ 'name', ++ 'e75ead52-692f-4314-8725-c8a4f4d13a87', ++ extra={'servicePlan': 'Enterprise'}) ++ self.assertEqual(context.exception.code, 'ERROR') ++ self.assertEqual(context.exception.msg, 'Cloud backup for this server is already enabled or being enabled (state: NORMAL).') ++ ++ def test_update_target(self): ++ target = self.driver.list_targets()[0] ++ extra = {'servicePlan': 'Essentials'} ++ new_target = self.driver.update_target(target, extra=extra) ++ self.assertEqual(new_target.extra['servicePlan'], 'Essentials') ++ ++ def test_update_target_DEFAULT(self): ++ DimensionDataMockHttp.type = 'DEFAULT' ++ target = 'e75ead52-692f-4314-8725-c8a4f4d13a87' ++ self.driver.update_target(target) ++ ++ def test_update_target_STR(self): ++ target = 'e75ead52-692f-4314-8725-c8a4f4d13a87' ++ extra = {'servicePlan': 'Essentials'} ++ new_target = self.driver.update_target(target, extra=extra) ++ self.assertEqual(new_target.extra['servicePlan'], 'Essentials') ++ ++ def test_delete_target(self): ++ target = self.driver.list_targets()[0] ++ self.assertTrue(self.driver.delete_target(target)) ++ ++ def test_ex_add_client_to_target(self): ++ target = self.driver.list_targets()[0] ++ client = self.driver.ex_list_available_client_types(target)[0] ++ storage_policy = self.driver.ex_list_available_storage_policies(target)[0] ++ schedule_policy = self.driver.ex_list_available_schedule_policies(target)[0] ++ self.assertTrue( ++ self.driver.ex_add_client_to_target(target, client, storage_policy, ++ schedule_policy, 'ON_FAILURE', 'nob...@example.com') ++ ) ++ ++ def test_ex_add_client_to_target_STR(self): ++ self.assertTrue( ++ self.driver.ex_add_client_to_target('e75ead52-692f-4314-8725-c8a4f4d13a87', 'FA.Linux', '14 Day Storage Policy', ++ '12AM - 6AM', 'ON_FAILURE', 'nob...@example.com') ++ ) ++ ++ def test_ex_get_backup_details_for_target(self): ++ target = self.driver.list_targets()[0] ++ response = self.driver.ex_get_backup_details_for_target(target) ++ self.assertEqual(response.service_plan, 'Enterprise') ++ client = response.clients[0] ++ self.assertEqual(client.id, '30b1ff76-c76d-4d7c-b39d-3b72be0384c8') ++ self.assertEqual(client.type.type, 'FA.Linux') ++ self.assertEqual(client.running_job.progress, 5) ++ self.assertTrue(isinstance(client.running_job, BackupTargetJob)) ++ self.assertEqual(len(client.alert.notify_list), 2) ++ self.assertTrue(isinstance(client.alert.notify_list, list)) ++ ++ def test_ex_get_backup_details_for_target_NOBACKUP(self): ++ target = self.driver.list_targets()[0].address ++ DimensionDataMockHttp.type = 'NOBACKUP' ++ response = self.driver.ex_get_backup_details_for_target(target) ++ self.assertTrue(response is None) ++ ++ def test_ex_cancel_target_job(self): ++ target = self.driver.list_targets()[0] ++ response = self.driver.ex_get_backup_details_for_target(target) ++ client = response.clients[0] ++ self.assertTrue(isinstance(client.running_job, BackupTargetJob)) ++ success = client.running_job.cancel() ++ self.assertTrue(success) ++ ++ def test_ex_cancel_target_job_with_extras(self): ++ success = self.driver.cancel_target_job( ++ None, ++ ex_client='30b1ff76_c76d_4d7c_b39d_3b72be0384c8', ++ ex_target='e75ead52_692f_4314_8725_c8a4f4d13a87' ++ ) ++ self.assertTrue(success) ++ ++ def test_ex_cancel_target_job_FAIL(self): ++ DimensionDataMockHttp.type = 'FAIL' ++ with self.assertRaises(DimensionDataAPIException) as context: ++ self.driver.cancel_target_job( ++ None, ++ ex_client='30b1ff76_c76d_4d7c_b39d_3b72be0384c8', ++ ex_target='e75ead52_692f_4314_8725_c8a4f4d13a87' ++ ) ++ self.assertEqual(context.exception.code, 'ERROR') ++ ++ """Test a backup info for a target that does not have a client""" ++ def test_ex_get_backup_details_for_target_NO_CLIENT(self): ++ DimensionDataMockHttp.type = 'NOCLIENT' ++ response = self.driver.ex_get_backup_details_for_target('e75ead52-692f-4314-8725-c8a4f4d13a87') ++ self.assertEqual(response.service_plan, 'Essentials') ++ self.assertEqual(len(response.clients), 0) ++ ++ """Test a backup details that has a client, but no alerting or running jobs""" ++ def test_ex_get_backup_details_for_target_NO_JOB_OR_ALERT(self): ++ DimensionDataMockHttp.type = 'NOJOB' ++ response = self.driver.ex_get_backup_details_for_target('e75ead52-692f-4314_8725-c8a4f4d13a87') ++ self.assertEqual(response.service_plan, 'Enterprise') ++ self.assertTrue(isinstance(response.clients, list)) ++ self.assertEqual(len(response.clients), 1) ++ client = response.clients[0] ++ self.assertEqual(client.id, '30b1ff76-c76d-4d7c-b39d-3b72be0384c8') ++ self.assertEqual(client.type.type, 'FA.Linux') ++ self.assertIsNone(client.running_job) ++ self.assertIsNone(client.alert) ++ ++ """Test getting backup info for a server that doesn't exist""" ++ def test_ex_get_backup_details_for_target_DISABLED(self): ++ DimensionDataMockHttp.type = 'DISABLED' ++ with self.assertRaises(DimensionDataAPIException) as context: ++ self.driver.ex_get_backup_details_for_target('e75ead52-692f-4314-8725-c8a4f4d13a87') ++ self.assertEqual(context.exception.code, 'ERROR') ++ self.assertEqual(context.exception.msg, 'Server e75ead52-692f-4314-8725-c8a4f4d13a87 has not been provisioned for backup') ++ ++ def test_ex_list_available_client_types(self): ++ target = self.driver.list_targets()[0] ++ answer = self.driver.ex_list_available_client_types(target) ++ self.assertEqual(len(answer), 1) ++ self.assertEqual(answer[0].type, 'FA.Linux') ++ self.assertEqual(answer[0].is_file_system, True) ++ self.assertEqual(answer[0].description, 'Linux File system') ++ ++ def test_ex_list_available_storage_policies(self): ++ target = self.driver.list_targets()[0] ++ answer = self.driver.ex_list_available_storage_policies(target) ++ self.assertEqual(len(answer), 1) ++ self.assertEqual(answer[0].name, ++ '30 Day Storage Policy + Secondary Copy') ++ self.assertEqual(answer[0].retention_period, 30) ++ self.assertEqual(answer[0].secondary_location, 'Primary') ++ ++ def test_ex_list_available_schedule_policies(self): ++ target = self.driver.list_targets()[0] ++ answer = self.driver.ex_list_available_schedule_policies(target) ++ self.assertEqual(len(answer), 1) ++ self.assertEqual(answer[0].name, '12AM - 6AM') ++ self.assertEqual(answer[0].description, 'Daily backup will start between 12AM - 6AM') ++ ++ def test_ex_remove_client_from_target(self): ++ target = self.driver.list_targets()[0] ++ client = self.driver.ex_get_backup_details_for_target('e75ead52-692f-4314-8725-c8a4f4d13a87').clients[0] ++ self.assertTrue(self.driver.ex_remove_client_from_target(target, client)) ++ ++ def test_ex_remove_client_from_target_STR(self): ++ self.assertTrue( ++ self.driver.ex_remove_client_from_target( ++ 'e75ead52-692f-4314-8725-c8a4f4d13a87', ++ '30b1ff76-c76d-4d7c-b39d-3b72be0384c8' ++ ) ++ ) ++ ++ def test_ex_remove_client_from_target_FAIL(self): ++ DimensionDataMockHttp.type = 'FAIL' ++ with self.assertRaises(DimensionDataAPIException) as context: ++ self.driver.ex_remove_client_from_target( ++ 'e75ead52-692f-4314-8725-c8a4f4d13a87', ++ '30b1ff76-c76d-4d7c-b39d-3b72be0384c8' ++ ) ++ self.assertEqual(context.exception.code, 'ERROR') ++ self.assertTrue('Backup Client is currently performing another operation' in context.exception.msg) ++ ++ def test_priv_target_to_target_address(self): ++ target = self.driver.list_targets()[0] ++ self.assertEqual( ++ self.driver._target_to_target_address(target), ++ 'e75ead52-692f-4314-8725-c8a4f4d13a87' ++ ) ++ ++ def test_priv_target_to_target_address_STR(self): ++ self.assertEqual( ++ self.driver._target_to_target_address('e75ead52-692f-4314-8725-c8a4f4d13a87'), ++ 'e75ead52-692f-4314-8725-c8a4f4d13a87' ++ ) ++ ++ def test_priv_target_to_target_address_TYPEERROR(self): ++ with self.assertRaises(TypeError): ++ self.driver._target_to_target_address([1, 2, 3]) ++ ++ def test_priv_client_to_client_id(self): ++ client = self.driver.ex_get_backup_details_for_target('e75ead52-692f-4314-8725-c8a4f4d13a87').clients[0] ++ self.assertEqual( ++ self.driver._client_to_client_id(client), ++ '30b1ff76-c76d-4d7c-b39d-3b72be0384c8' ++ ) ++ ++ def test_priv_client_to_client_id_STR(self): ++ self.assertEqual( ++ self.driver._client_to_client_id('30b1ff76-c76d-4d7c-b39d-3b72be0384c8'), ++ '30b1ff76-c76d-4d7c-b39d-3b72be0384c8' ++ ) ++ ++ def test_priv_client_to_client_id_TYPEERROR(self): ++ with self.assertRaises(TypeError): ++ self.driver._client_to_client_id([1, 2, 3]) ++ ++ ++class InvalidRequestError(Exception): ++ def __init__(self, tag): ++ super(InvalidRequestError, self).__init__("Invalid Request - %s" % tag) ++ ++ ++class DimensionDataMockHttp(MockHttp): ++ ++ fixtures = BackupFileFixtures('dimensiondata') ++ ++ def _oec_0_9_myaccount_UNAUTHORIZED(self, method, url, body, headers): ++ return (httplib.UNAUTHORIZED, "", {}, httplib.responses[httplib.UNAUTHORIZED]) ++ ++ def _oec_0_9_myaccount(self, method, url, body, headers): ++ body = self.fixtures.load('oec_0_9_myaccount.xml') ++ return (httplib.OK, body, {}, httplib.responses[httplib.OK]) ++ ++ def _oec_0_9_myaccount_EXISTS(self, method, url, body, headers): ++ body = self.fixtures.load('oec_0_9_myaccount.xml') ++ return (httplib.OK, body, {}, httplib.responses[httplib.OK]) ++ ++ def _oec_0_9_myaccount_DEFAULT(self, method, url, body, headers): ++ body = self.fixtures.load('oec_0_9_myaccount.xml') ++ return (httplib.OK, body, {}, httplib.responses[httplib.OK]) ++ ++ def _oec_0_9_myaccount_INPROGRESS(self, method, url, body, headers): ++ body = self.fixtures.load('oec_0_9_myaccount.xml') ++ return (httplib.OK, body, {}, httplib.responses[httplib.OK]) ++ ++ def _oec_0_9_myaccount_FAIL(self, method, url, body, headers): ++ body = self.fixtures.load('oec_0_9_myaccount.xml') ++ return (httplib.OK, body, {}, httplib.responses[httplib.OK]) ++ ++ def _oec_0_9_myaccount_NOCLIENT(self, method, url, body, headers): ++ body = self.fixtures.load('oec_0_9_myaccount.xml') ++ return (httplib.OK, body, {}, httplib.responses[httplib.OK]) ++ ++ def _oec_0_9_myaccount_DISABLED(self, method, url, body, headers): ++ body = self.fixtures.load('oec_0_9_myaccount.xml') ++ return (httplib.OK, body, {}, httplib.responses[httplib.OK]) ++ ++ def _oec_0_9_myaccount_NOJOB(self, method, url, body, headers): ++ body = self.fixtures.load('oec_0_9_myaccount.xml') ++ return (httplib.OK, body, {}, httplib.responses[httplib.OK]) ++ ++ def _caas_2_3_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server_e75ead52_692f_4314_8725_c8a4f4d13a87(self, method, url, body, headers): ++ body = self.fixtures.load( ++ 'server_server_e75ead52_692f_4314_8725_c8a4f4d13a87.xml') ++ return (httplib.OK, body, {}, httplib.responses[httplib.OK]) ++ ++ def _caas_2_3_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server_e75ead52_692f_4314_8725_c8a4f4d13a87_DEFAULT(self, method, url, body, headers): ++ body = self.fixtures.load( ++ 'server_server_e75ead52_692f_4314_8725_c8a4f4d13a87_DEFAULT.xml') ++ return (httplib.OK, body, {}, httplib.responses[httplib.OK]) ++ ++ def _caas_2_3_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server_e75ead52_692f_4314_8725_c8a4f4d13a87_NOCLIENT(self, method, url, body, headers): ++ body = self.fixtures.load( ++ 'server_server_e75ead52_692f_4314_8725_c8a4f4d13a87_DEFAULT.xml') ++ return (httplib.OK, body, {}, httplib.responses[httplib.OK]) ++ ++ def _caas_2_3_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server_e75ead52_692f_4314_8725_c8a4f4d13a87_NOJOB(self, method, url, body, headers): ++ body = self.fixtures.load( ++ 'server_server_e75ead52_692f_4314_8725_c8a4f4d13a87_DEFAULT.xml') ++ return (httplib.OK, body, {}, httplib.responses[httplib.OK]) ++ ++ def _caas_2_3_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server_e75ead52_692f_4314_8725_c8a4f4d13a87_DISABLED(self, method, url, body, headers): ++ body = self.fixtures.load( ++ 'server_server_e75ead52_692f_4314_8725_c8a4f4d13a87_DEFAULT.xml') ++ return (httplib.OK, body, {}, httplib.responses[httplib.OK]) ++ ++ def _caas_2_3_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server(self, method, url, body, headers): ++ body = self.fixtures.load( ++ 'server_server.xml') ++ return (httplib.OK, body, {}, httplib.responses[httplib.OK]) ++ ++ def _oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_client_type(self, method, url, body, headers): ++ body = self.fixtures.load( ++ '_backup_client_type.xml') ++ return (httplib.OK, body, {}, httplib.responses[httplib.OK]) ++ ++ def _oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_client_storagePolicy( ++ self, method, url, body, headers): ++ body = self.fixtures.load( ++ '_backup_client_storagePolicy.xml') ++ return (httplib.OK, body, {}, httplib.responses[httplib.OK]) ++ ++ def _oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_client_schedulePolicy( ++ self, method, url, body, headers): ++ body = self.fixtures.load( ++ '_backup_client_schedulePolicy.xml') ++ return (httplib.OK, body, {}, httplib.responses[httplib.OK]) ++ ++ def _oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_client( ++ self, method, url, body, headers): ++ if method == 'POST': ++ body = self.fixtures.load( ++ '_backup_client_SUCCESS_PUT.xml') ++ return (httplib.OK, body, {}, httplib.responses[httplib.OK]) ++ else: ++ raise ValueError("Unknown Method {0}".format(method)) ++ ++ def _oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_NOCLIENT( ++ self, method, url, body, headers): ++ # only gets here are implemented ++ # If we get any other method something has gone wrong ++ assert(method == 'GET') ++ body = self.fixtures.load( ++ '_backup_INFO_NOCLIENT.xml') ++ return (httplib.OK, body, {}, httplib.responses[httplib.OK]) ++ ++ def _oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_DISABLED( ++ self, method, url, body, headers): ++ # only gets here are implemented ++ # If we get any other method something has gone wrong ++ assert(method == 'GET') ++ body = self.fixtures.load( ++ '_backup_INFO_DISABLED.xml') ++ return (httplib.BAD_REQUEST, body, {}, httplib.responses[httplib.OK]) ++ ++ def _oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_NOJOB( ++ self, method, url, body, headers): ++ # only gets here are implemented ++ # If we get any other method something has gone wrong ++ assert(method == 'GET') ++ body = self.fixtures.load( ++ '_backup_INFO_NOJOB.xml') ++ return (httplib.OK, body, {}, httplib.responses[httplib.OK]) ++ ++ def _oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_DEFAULT( ++ self, method, url, body, headers): ++ if method != 'POST': ++ raise InvalidRequestError('Only POST is accepted for this test') ++ request = ET.fromstring(body) ++ service_plan = request.get('servicePlan') ++ if service_plan != DEFAULT_BACKUP_PLAN: ++ raise InvalidRequestError('The default plan %s should have been passed in. Not %s' % (DEFAULT_BACKUP_PLAN, service_plan)) ++ body = self.fixtures.load( ++ '_backup_ENABLE.xml') ++ return (httplib.OK, body, {}, httplib.responses[httplib.OK]) ++ ++ def _oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup( ++ self, method, url, body, headers): ++ if method == 'POST': ++ body = self.fixtures.load( ++ '_backup_ENABLE.xml') ++ return (httplib.OK, body, {}, httplib.responses[httplib.OK]) ++ elif method == 'GET': ++ if url.endswith('disable'): ++ body = self.fixtures.load( ++ '_backup_DISABLE.xml') ++ return (httplib.OK, body, {}, httplib.responses[httplib.OK]) ++ body = self.fixtures.load( ++ '_backup_INFO.xml') ++ return (httplib.OK, body, {}, httplib.responses[httplib.OK]) ++ ++ else: ++ raise ValueError("Unknown Method {0}".format(method)) ++ ++ def _caas_2_3_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server_e75ead52_692f_4314_8725_c8a4f4d13a87_NOBACKUP( ++ self, method, url, body, headers): ++ assert(method == 'GET') ++ body = self.fixtures.load('server_server_NOBACKUP.xml') ++ return (httplib.OK, body, {}, httplib.responses[httplib.OK]) ++ ++ def _oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_EXISTS( ++ self, method, url, body, headers): ++ # only POSTs are implemented ++ # If we get any other method something has gone wrong ++ assert(method == 'POST') ++ body = self.fixtures.load( ++ '_backup_EXISTS.xml') ++ return (httplib.BAD_REQUEST, body, {}, httplib.responses[httplib.OK]) ++ ++ def _oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_modify( ++ self, method, url, body, headers): ++ request = ET.fromstring(body) ++ service_plan = request.get('servicePlan') ++ if service_plan != 'Essentials': ++ raise InvalidRequestError("Expected Essentials backup plan in request") ++ body = self.fixtures.load('_backup_modify.xml') ++ ++ return (httplib.OK, body, {}, httplib.responses[httplib.OK]) ++ ++ def _oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_modify_DEFAULT( ++ self, method, url, body, headers): ++ request = ET.fromstring(body) ++ service_plan = request.get('servicePlan') ++ if service_plan != DEFAULT_BACKUP_PLAN: ++ raise InvalidRequestError("Expected % backup plan in test" % DEFAULT_BACKUP_PLAN) ++ body = self.fixtures.load('_backup_modify.xml') ++ ++ return (httplib.OK, body, {}, httplib.responses[httplib.OK]) ++ ++ def _oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_client_30b1ff76_c76d_4d7c_b39d_3b72be0384c8( ++ self, method, url, body, headers): ++ if url.endswith('disable'): ++ body = self.fixtures.load( ++ ('_remove_backup_client.xml') ++ ) ++ elif url.endswith('cancelJob'): ++ body = self.fixtures.load( ++ ('' ++ '_backup_client_30b1ff76_c76d_4d7c_b39d_3b72be0384c8_cancelJob.xml') ++ ) ++ else: ++ raise ValueError("Unknown URL: %s" % url) ++ return (httplib.OK, body, {}, httplib.responses[httplib.OK]) ++ ++ def _oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_client_30b1ff76_c76d_4d7c_b39d_3b72be0384c8_FAIL( ++ self, method, url, body, headers): ++ if url.endswith('disable'): ++ body = self.fixtures.load( ++ ('_remove_backup_client_FAIL.xml') ++ ) ++ elif url.endswith('cancelJob'): ++ body = self.fixtures.load( ++ ('' ++ '_backup_client_30b1ff76_c76d_4d7c_b39d_3b72be0384c8_cancelJob_FAIL.xml') ++ ) ++ else: ++ raise ValueError("Unknown URL: %s" % url) ++ return (httplib.BAD_REQUEST, body, {}, httplib.responses[httplib.OK]) ++ ++ ++if __name__ == '__main__': ++ sys.exit(unittest.main()) http://git-wip-us.apache.org/repos/asf/libcloud/blob/193e0e0b/libcloud/test/common/test_openstack_identity.py ----------------------------------------------------------------------