http://git-wip-us.apache.org/repos/asf/libcloud/blob/04fa0666/libcloud/test/backup/test_dimensiondata.py ---------------------------------------------------------------------- diff --cc libcloud/test/backup/test_dimensiondata.py index 285c777,b2f599c..5cbbdf5 --- a/libcloud/test/backup/test_dimensiondata.py +++ b/libcloud/test/backup/test_dimensiondata.py @@@ -1,431 -1,502 +1,502 @@@ -# 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 DimensionDataTests(unittest.TestCase, TestCaseMixin): - - def setUp(self): - 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 DimensionDataTests(unittest.TestCase, TestCaseMixin): + + def setUp(self): + 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.percentage, 5) ++ 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_BUSY(self): - DimensionDataMockHttp.type = 'BUSY' ++ 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_BUSY(self, method, url, body, headers): ++ 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_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server_e75ead52_692f_4314_8725_c8a4f4d13a87(self, method, url, body, headers): ++ 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( - 'caas_2_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server_e75ead52_692f_4314_8725_c8a4f4d13a87.xml') ++ 'server_server_e75ead52_692f_4314_8725_c8a4f4d13a87_DEFAULT.xml') + return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + - def _caas_2_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server_e75ead52_692f_4314_8725_c8a4f4d13a87_DEFAULT(self, method, url, body, headers): ++ 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( - 'caas_2_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server_e75ead52_692f_4314_8725_c8a4f4d13a87_DEFAULT.xml') ++ 'server_server_e75ead52_692f_4314_8725_c8a4f4d13a87_DEFAULT.xml') + return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + - def _caas_2_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server(self, method, url, body, headers): ++ def _caas_2_3_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server(self, method, url, body, headers): + body = self.fixtures.load( - 'caas_2_1_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_server.xml') ++ '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( - 'oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_client_type.xml') ++ '_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( - 'oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_client_storagePolicy.xml') ++ '_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( - 'oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_client_schedulePolicy.xml') ++ '_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( - 'oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_client_SUCCESS_PUT.xml') ++ '_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( - 'oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_INFO_NOCLIENT.xml') ++ '_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( - 'oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_INFO_DISABLED.xml') ++ '_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( - 'oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_INFO_NOJOB.xml') ++ '_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( - 'oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_ENABLE.xml') ++ '_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( - 'oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_ENABLE.xml') ++ '_backup_ENABLE.xml') + return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + elif method == 'GET': + if url.endswith('disable'): + body = self.fixtures.load( - 'oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_DISABLE.xml') ++ '_backup_DISABLE.xml') + return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + body = self.fixtures.load( - 'oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_INFO.xml') ++ '_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( - 'oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_EXISTS.xml') ++ '_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('oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_modify.xml') ++ 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('oec_0_9_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_server_e75ead52_692f_4314_8725_c8a4f4d13a87_backup_modify.xml') ++ 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): - body = self.fixtures.load( - ('_remove_backup_client.xml') - ) ++ 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_BUSY( ++ 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): - body = self.fixtures.load( - ('_remove_backup_client_BUSY.xml') - ) ++ 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/04fa0666/libcloud/test/common/test_nfsn.py ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/libcloud/blob/04fa0666/libcloud/test/common/test_openstack_identity.py ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/libcloud/blob/04fa0666/libcloud/test/compute/test_cloudstack.py ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/libcloud/blob/04fa0666/libcloud/test/compute/test_digitalocean_v2.py ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/libcloud/blob/04fa0666/libcloud/test/compute/test_dimensiondata.py ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/libcloud/blob/04fa0666/libcloud/test/compute/test_ec2.py ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/libcloud/blob/04fa0666/libcloud/test/compute/test_ecs.py ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/libcloud/blob/04fa0666/libcloud/test/compute/test_gce.py ---------------------------------------------------------------------- diff --cc libcloud/test/compute/test_gce.py index 90699ef,9ec97e0..bdcd30c --- a/libcloud/test/compute/test_gce.py +++ b/libcloud/test/compute/test_gce.py @@@ -15,22 -15,20 +15,20 @@@ """ Tests for Google Compute Engine Driver """ + import datetime + import mock import sys import unittest - import datetime from libcloud.utils.py3 import httplib - from libcloud.compute.drivers.gce import (GCENodeDriver, API_VERSION, - timestamp_to_datetime, - GCEAddress, GCEBackendService, - GCEFirewall, GCEForwardingRule, - GCEHealthCheck, GCENetwork, - GCENodeImage, GCERoute, - GCETargetHttpProxy, GCEUrlMap, - GCEZone) + from libcloud.compute.drivers.gce import ( + GCENodeDriver, API_VERSION, timestamp_to_datetime, GCEAddress, GCEBackend, + GCEBackendService, GCEFirewall, GCEForwardingRule, GCEHealthCheck, + GCENetwork, GCENodeImage, GCERoute, GCERegion, GCETargetHttpProxy, + GCEUrlMap, GCEZone, GCESubnetwork) from libcloud.common.google import (GoogleBaseAuthConnection, ResourceNotFoundError, ResourceExistsError, - InvalidRequestError, GoogleBaseError) + GoogleBaseError) from libcloud.test.common.test_google import GoogleAuthMockHttp, GoogleTestCase from libcloud.compute.base import Node, StorageVolume http://git-wip-us.apache.org/repos/asf/libcloud/blob/04fa0666/libcloud/test/compute/test_openstack.py ---------------------------------------------------------------------- diff --cc libcloud/test/compute/test_openstack.py index 2474b49,c6cc76b..2d63f6b --- a/libcloud/test/compute/test_openstack.py +++ b/libcloud/test/compute/test_openstack.py @@@ -1471,9 -1530,23 +1523,22 @@@ class OpenStack_1_1_Tests(unittest.Test force=True) self.assertEqual(ret.id, '3fbbcccf-d058-4502-8844-6feeffdf4cb5') + def test_ex_create_snapshot_does_not_post_optional_parameters_if_none(self): + volume = self.driver.list_volumes()[0] + with patch.object(self.driver, '_to_snapshot'): + with patch.object(self.driver.connection, 'request') as mock_request: + self.driver.create_volume_snapshot(volume, + name=None, + ex_description=None, + ex_force=True) + + name, args, kwargs = mock_request.mock_calls[0] + self.assertFalse("display_name" in kwargs["data"]["snapshot"]) + self.assertFalse("display_description" in kwargs["data"]["snapshot"]) + def test_destroy_volume_snapshot(self): if self.driver_type.type == 'rackspace': - self.conn_classes[0].type = 'RACKSPACE' - self.conn_classes[1].type = 'RACKSPACE' + self.conn_class.type = 'RACKSPACE' snapshot = self.driver.ex_list_snapshots()[0] ret = self.driver.destroy_volume_snapshot(snapshot) http://git-wip-us.apache.org/repos/asf/libcloud/blob/04fa0666/libcloud/test/compute/test_ovh.py ---------------------------------------------------------------------- diff --cc libcloud/test/compute/test_ovh.py index 0000000,f434f7a..77394e5 mode 000000,100644..100644 --- a/libcloud/test/compute/test_ovh.py +++ b/libcloud/test/compute/test_ovh.py @@@ -1,0 -1,243 +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 sys + import unittest + from mock import patch + + from libcloud.utils.py3 import httplib + + from libcloud.compute.drivers.ovh import OvhNodeDriver + + from libcloud.test.common.test_ovh import BaseOvhMockHttp + from libcloud.test.secrets import OVH_PARAMS + from libcloud.test.file_fixtures import ComputeFileFixtures + + + class OvhMockHttp(BaseOvhMockHttp): + """Fixtures needed for tests related to rating model""" + fixtures = ComputeFileFixtures('ovh') + + def _json_1_0_auth_time_get(self, method, url, body, headers): + body = self.fixtures.load('auth_time_get.json') + return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + + def _json_1_0_cloud_project_project_id_region_get(self, method, url, body, headers): + body = self.fixtures.load('region_get.json') + return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + + def _json_1_0_cloud_project_project_id_flavor_get(self, method, url, body, headers): + body = self.fixtures.load('flavor_get.json') + return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + + def _json_1_0_cloud_project_project_id_flavor_region_SBG1_get(self, method, url, body, headers): + body = self.fixtures.load('flavor_get.json') + return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + + def _json_1_0_cloud_project_project_id_flavor_foo_id_get(self, method, url, body, headers): + body = self.fixtures.load('flavor_get_detail.json') + return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + + def _json_1_0_cloud_project_project_id_image_get(self, method, url, body, headers): + body = self.fixtures.load('image_get.json') + return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + + def _json_1_0_cloud_project_project_id_image_foo_id_get(self, method, url, body, headers): + body = self.fixtures.load('image_get_detail.json') + return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + + def _json_1_0_cloud_project_project_id_sshkey_region_SBG1_get(self, method, url, body, headers): + body = self.fixtures.load('ssh_get.json') + return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + + def _json_1_0_cloud_project_project_id_sshkey_post(self, method, url, body, headers): + body = self.fixtures.load('ssh_get_detail.json') + return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + + def _json_1_0_ssh_mykey_get(self, method, url, body, headers): + body = self.fixtures.load('ssh_get_detail.json') + return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + + def _json_1_0_cloud_project_project_id_instance_get(self, method, url, body, headers): + body = self.fixtures.load('instance_get.json') + return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + + def _json_1_0_cloud_project_project_id_instance_foo_get(self, method, url, body, headers): + body = self.fixtures.load('instance_get_detail.json') + return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + + def _json_1_0_cloud_project_project_id_instance_foo_delete(self, method, url, body, headers): + return (httplib.OK, '', {}, httplib.responses[httplib.OK]) + + def _json_1_0_cloud_project_project_id_instance_post(self, method, url, body, headers): + body = self.fixtures.load('instance_get_detail.json') + return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + + def _json_1_0_cloud_project_project_id_volume_get(self, method, url, body, headers): + body = self.fixtures.load('volume_get.json') + return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + + def _json_1_0_cloud_project_project_id_volume_post(self, method, url, body, headers): + body = self.fixtures.load('volume_get_detail.json') + return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + + def _json_1_0_cloud_project_project_id_volume_foo_get(self, method, url, body, headers): + body = self.fixtures.load('volume_get_detail.json') + return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + + def _json_1_0_cloud_project_project_id_volume_foo_delete(self, method, url, body, headers): + return (httplib.OK, '', {}, httplib.responses[httplib.OK]) + + def _json_1_0_cloud_project_project_id_volume_foo_attach_post(self, method, url, body, headers): + body = self.fixtures.load('volume_get_detail.json') + return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + + def _json_1_0_cloud_project_project_id_volume_foo_detach_post(self, method, url, body, headers): + body = self.fixtures.load('volume_get_detail.json') + return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + + def _json_1_0_cloud_project_project_id_volume_snapshot_region_SBG_1_get(self, method, url, body, headers): + body = self.fixtures.load('volume_snapshot_get.json') + return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + + def _json_1_0_cloud_project_project_id_volume_snapshot_get(self, method, url, body, headers): + body = self.fixtures.load('volume_snapshot_get.json') + return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + + def _json_1_0_cloud_project_project_id_volume_snapshot_foo_get(self, method, url, body, headers): + body = self.fixtures.load('volume_snapshot_get_details.json') + return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + + def _json_1_0_cloud_project_project_id_volume_snapshot_foo_snap_delete(self, method, url, body, headers): + return (httplib.OK, None, {}, httplib.responses[httplib.OK]) + + def _json_1_0_cloud_project_project_id_volume_foo_snapshot__post(self, method, url, body, headers): + body = self.fixtures.load('volume_snapshot_get_details.json') + return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + + + @patch('libcloud.common.ovh.OvhConnection._timedelta', 42) + class OvhTests(unittest.TestCase): + def setUp(self): - OvhNodeDriver.connectionCls.conn_classes = ( - OvhMockHttp, OvhMockHttp) ++ OvhNodeDriver.connectionCls.conn_class = OvhMockHttp + OvhMockHttp.type = None + self.driver = OvhNodeDriver(*OVH_PARAMS) + + def test_list_locations(self): + images = self.driver.list_locations() + self.assertTrue(len(images) > 0) + + def test_list_images(self): + images = self.driver.list_images() + self.assertTrue(len(images) > 0) + + def test_get_image(self): + image = self.driver.get_image('foo-id') + self.assertEqual(image.id, 'foo-id') + + def test_list_sizes(self): + sizes = self.driver.list_sizes() + self.assertTrue(len(sizes) > 0) + + def test_get_size(self): + size = self.driver.ex_get_size('foo-id') + self.assertEqual(size.id, 'foo-id') + + def test_list_key_pairs(self): + keys = self.driver.list_sizes() + self.assertTrue(len(keys) > 0) + + def test_get_key_pair(self): + location = self.driver.list_locations()[0] + key = self.driver.get_key_pair('mykey', location) + self.assertEqual(key.name, 'mykey') + + def test_import_key_pair_from_string(self): + location = self.driver.list_locations()[0] + key = self.driver.import_key_pair_from_string('mykey', 'material', + location) + self.assertEqual(key.name, 'mykey') + + def test_list_nodes(self): + nodes = self.driver.list_nodes() + self.assertTrue(len(nodes) > 0) + + def test_get_node(self): + node = self.driver.ex_get_node('foo') + self.assertEqual(node.name, 'test_vm') + + def test_create_node(self): + location = self.driver.list_locations()[0] + image = self.driver.list_sizes(location)[0] + size = self.driver.list_sizes(location)[0] + node = self.driver.create_node(name='test_vm', image=image, size=size, + location=location) + self.assertEqual(node.name, 'test_vm') + + def test_destroy_node(self): + node = self.driver.list_nodes()[0] + self.driver.destroy_node(node) + + def test_list_volumes(self): + volumes = self.driver.list_volumes() + self.assertTrue(len(volumes) > 0) + + def test_get_volume(self): + volume = self.driver.ex_get_volume('foo') + self.assertEqual(volume.name, 'testvol') + + def test_create_volume(self): + location = self.driver.list_locations()[0] + volume = self.driver.create_volume(size=10, name='testvol', + location=location) + self.assertEqual(volume.name, 'testvol') + + def test_destroy_volume(self): + volume = self.driver.list_volumes()[0] + self.driver.destroy_volume(volume) + + def test_attach_volume(self): + node = self.driver.list_nodes()[0] + volume = self.driver.ex_get_volume('foo') + response = self.driver.attach_volume(node=node, volume=volume) + self.assertTrue(response) + + def test_detach_volume(self): + node = self.driver.list_nodes()[0] + volume = self.driver.ex_get_volume('foo') + response = self.driver.detach_volume(ex_node=node, volume=volume) + self.assertTrue(response) + + def test_ex_list_snapshots(self): + self.driver.ex_list_snapshots() + + def test_ex_get_volume_snapshot(self): + self.driver.ex_get_volume_snapshot('foo') + + def test_list_volume_snapshots(self): + volume = self.driver.ex_get_volume('foo') + self.driver.list_volume_snapshots(volume) + + def test_create_volume_snapshot(self): + volume = self.driver.ex_get_volume('foo') + self.driver.create_volume_snapshot(volume) + + def test_destroy_volume_snapshot(self): + snapshot = self.driver.ex_get_volume_snapshot('foo') + result = self.driver.destroy_volume_snapshot(snapshot) + self.assertTrue(result) + + if __name__ == '__main__': + sys.exit(unittest.main()) http://git-wip-us.apache.org/repos/asf/libcloud/blob/04fa0666/libcloud/test/compute/test_rackspace.py ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/libcloud/blob/04fa0666/libcloud/test/compute/test_vcloud.py ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/libcloud/blob/04fa0666/libcloud/test/compute/test_vultr.py ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/libcloud/blob/04fa0666/libcloud/test/container/test_docker.py ---------------------------------------------------------------------- diff --cc libcloud/test/container/test_docker.py index ba2f29a,32c7127..95011e9 --- a/libcloud/test/container/test_docker.py +++ b/libcloud/test/container/test_docker.py @@@ -30,72 -30,91 +30,91 @@@ from libcloud.test import MockHtt class DockerContainerDriverTestCase(unittest.TestCase): def setUp(self): - DockerContainerDriver.connectionCls.conn_class = DockerMockHttp - DockerMockHttp.type = None - DockerMockHttp.use_param = 'a' - self.driver = DockerContainerDriver(*CONTAINER_PARAMS_DOCKER) + # Create a test driver for each version + versions = ('linux_124', 'mac_124') + self.drivers = [] + for version in versions: - DockerContainerDriver.connectionCls.conn_classes = ( - DockerMockHttp, DockerMockHttp) ++ DockerContainerDriver.connectionCls.conn_class = \ ++ DockerMockHttp + DockerMockHttp.type = None + DockerMockHttp.use_param = 'a' + driver = DockerContainerDriver(*CONTAINER_PARAMS_DOCKER) + driver.version = version + self.drivers.append(driver) def test_list_images(self): - images = self.driver.list_images() - self.assertEqual(len(images), 4) - self.assertIsInstance(images[0], ContainerImage) - self.assertEqual(images[0].id, - 'cf55d61f5307b7a18a45980971d6cfd40b737dd661879c4a6b3f2aecc3bc37b0') - self.assertEqual(images[0].name, 'mongo:latest') + for driver in self.drivers: + images = driver.list_images() + self.assertEqual(len(images), 4) + self.assertIsInstance(images[0], ContainerImage) + self.assertEqual(images[0].id, + 'cf55d61f5307b7a18a45980971d6cfd40b737dd661879c4a6b3f2aecc3bc37b0') + self.assertEqual(images[0].name, 'mongo:latest') def test_install_image(self): - image = self.driver.install_image('ubuntu:12.04') - self.assertTrue(image is not None) - self.assertEqual(image.id, 'cf55d61f5307b7a18a45980971d6cfd40b737dd661879c4a6b3f2aecc3bc37b0') + for driver in self.drivers: + image = driver.install_image('ubuntu:12.04') + self.assertTrue(image is not None) + self.assertEqual(image.id, '992069aee4016783df6345315302fa59681aae51a8eeb2f889dea59290f21787') def test_list_containers(self): - containers = self.driver.list_containers(all=True) - self.assertEqual(len(containers), 6) - self.assertEqual(containers[0].id, - '160936dc54fe8c332095676d9379003534b8cddd7565fa63018996e06dae1b6b') - self.assertEqual(containers[0].name, 'hubot') - self.assertEqual(containers[0].image.name, 'stackstorm/hubot') + for driver in self.drivers: + containers = driver.list_containers(all=True) + self.assertEqual(len(containers), 6) + self.assertEqual(containers[0].id, + '160936dc54fe8c332095676d9379003534b8cddd7565fa63018996e06dae1b6b') + self.assertEqual(containers[0].name, 'hubot') + self.assertEqual(containers[0].image.name, 'stackstorm/hubot') def test_deploy_container(self): - image = self.driver.list_images()[0] - container = self.driver.deploy_container(image=image, name='test') - self.assertEqual(container.id, 'a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303') - self.assertEqual(container.name, 'gigantic_goldberg') + for driver in self.drivers: + image = driver.list_images()[0] + container = driver.deploy_container(image=image, name='test') + self.assertEqual(container.id, 'a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303') + self.assertEqual(container.name, 'gigantic_goldberg') def test_get_container(self): - container = self.driver.get_container('a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303') - self.assertEqual(container.id, 'a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303') - self.assertEqual(container.name, 'gigantic_goldberg') + for driver in self.drivers: + container = driver.get_container('a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303') + self.assertEqual(container.id, 'a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303') + self.assertEqual(container.name, 'gigantic_goldberg') def test_start_container(self): - container = self.driver.get_container('a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303') - container.start() + for driver in self.drivers: + container = driver.get_container('a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303') + container.start() def test_stop_container(self): - container = self.driver.get_container('a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303') - container.stop() + for driver in self.drivers: + container = driver.get_container('a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303') + container.stop() def test_restart_container(self): - container = self.driver.get_container('a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303') - container.restart() + for driver in self.drivers: + container = driver.get_container('a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303') + container.restart() def test_delete_container(self): - container = self.driver.get_container('a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303') - container.destroy() + for driver in self.drivers: + container = driver.get_container('a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303') + container.destroy() def test_ex_rename_container(self): - container = self.driver.get_container('a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303') - self.driver.ex_rename_container(container, 'bob') + for driver in self.drivers: + container = driver.get_container('a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303') + driver.ex_rename_container(container, 'bob') def test_ex_get_logs(self): - container = self.driver.get_container('a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303') - logs = self.driver.ex_get_logs(container) - self.assertTrue(logs is not None) + for driver in self.drivers: + container = driver.get_container('a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303') + logs = driver.ex_get_logs(container) + self.assertTrue(logs is not None) def test_ex_search_images(self): - images = self.driver.ex_search_images('mysql') - self.assertEqual(len(images), 25) - self.assertEqual(images[0].name, 'mysql') + for driver in self.drivers: + images = driver.ex_search_images('mysql') + self.assertEqual(len(images), 25) + self.assertEqual(images[0].name, 'mysql') class DockerMockHttp(MockHttp): http://git-wip-us.apache.org/repos/asf/libcloud/blob/04fa0666/libcloud/test/dns/test_auroradns.py ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/libcloud/blob/04fa0666/libcloud/test/dns/test_rackspace.py ---------------------------------------------------------------------- diff --cc libcloud/test/dns/test_rackspace.py index 6140987,0679f05..ba5159d --- a/libcloud/test/dns/test_rackspace.py +++ b/libcloud/test/dns/test_rackspace.py @@@ -47,13 -46,17 +46,16 @@@ RDNS_LB = LoadBalancer('370b0ff8-3f57-4 class RackspaceUSTests(unittest.TestCase): - klass = RackspaceUSDNSDriver + klass = RackspaceDNSDriver endpoint_url = 'https://dns.api.rackspacecloud.com/v1.0/11111' + region = 'us' def setUp(self): - self.klass.connectionCls.conn_classes = ( - None, RackspaceMockHttp) + self.klass.connectionCls.conn_class = RackspaceMockHttp RackspaceMockHttp.type = None - self.driver = self.klass(*DNS_PARAMS_RACKSPACE) + + driver_kwargs = {'region': self.region} + self.driver = self.klass(*DNS_PARAMS_RACKSPACE, **driver_kwargs) self.driver.connection.poll_interval = 0.0 # normally authentication happens lazily, but we force it here self.driver.connection._populate_hosts_and_request_paths() http://git-wip-us.apache.org/repos/asf/libcloud/blob/04fa0666/libcloud/test/loadbalancer/test_dimensiondata.py ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/libcloud/blob/04fa0666/libcloud/test/loadbalancer/test_elb.py ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/libcloud/blob/04fa0666/libcloud/test/loadbalancer/test_rackspace.py ---------------------------------------------------------------------- diff --cc libcloud/test/loadbalancer/test_rackspace.py index 1eefeb8,15ba54c..112d825 --- a/libcloud/test/loadbalancer/test_rackspace.py +++ b/libcloud/test/loadbalancer/test_rackspace.py @@@ -917,9 -918,10 +916,9 @@@ class RackspaceLBTests(unittest.TestCas class RackspaceUKLBTests(RackspaceLBTests): def setUp(self): - RackspaceLBDriver.connectionCls.conn_classes = (None, - RackspaceLBMockHttp) + RackspaceLBDriver.connectionCls.conn_class = RackspaceLBMockHttp RackspaceLBMockHttp.type = None - self.driver = RackspaceUKLBDriver('user', 'key') + self.driver = RackspaceLBDriver('user', 'key', region='lon') # normally authentication happens lazily, but we force it here self.driver.connection._populate_hosts_and_request_paths()