Add MaxCDN driver && unittest
Change-Id: I4b1b51c994cf918b3de898c702869dae475eda95
This commit is contained in:
parent
1f2960cf2f
commit
2ea3f39221
|
@ -0,0 +1,21 @@
|
||||||
|
# Copyright (c) 2013 Rackspace, Inc.
|
||||||
|
#
|
||||||
|
# Licensed 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.
|
||||||
|
|
||||||
|
"""MaxCDN Provider Extension for CDN"""
|
||||||
|
|
||||||
|
from poppy.provider.maxcdn import driver
|
||||||
|
|
||||||
|
# Hoist classes into package namespace
|
||||||
|
Driver = driver.CDNProvider
|
|
@ -0,0 +1,27 @@
|
||||||
|
# Copyright (c) 2013 Rackspace, Inc.
|
||||||
|
#
|
||||||
|
# Licensed 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.
|
||||||
|
|
||||||
|
"""Exports MaxCDN poppy controllers.
|
||||||
|
|
||||||
|
Field Mappings:
|
||||||
|
In order to reduce the disk / memory space used,
|
||||||
|
fields name will be, most of the time, the first
|
||||||
|
letter of their long name. Fields mapping will be
|
||||||
|
updated and documented in each controller class.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from poppy.provider.maxcdn import services
|
||||||
|
|
||||||
|
ServiceController = services.ServiceController
|
|
@ -0,0 +1,68 @@
|
||||||
|
# Copyright (c) 2014 Rackspace, Inc.
|
||||||
|
#
|
||||||
|
# Licensed 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.
|
||||||
|
|
||||||
|
"""Max CDN Provider implementation."""
|
||||||
|
|
||||||
|
import maxcdn
|
||||||
|
from oslo.config import cfg
|
||||||
|
|
||||||
|
from poppy.openstack.common import log as logging
|
||||||
|
from poppy.provider import base
|
||||||
|
from poppy.provider.maxcdn import controllers
|
||||||
|
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
MAXCDN_OPTIONS = [
|
||||||
|
cfg.StrOpt('alias', help='MAXCDN API account alias'),
|
||||||
|
cfg.StrOpt('consumer_key', help='MAXCDN API consumer key'),
|
||||||
|
cfg.StrOpt('consumer_secret', help='MAXCDN API consumer secret'),
|
||||||
|
]
|
||||||
|
|
||||||
|
MAXCDN_GROUP = 'drivers:provider:maxcdn'
|
||||||
|
|
||||||
|
|
||||||
|
class CDNProvider(base.Driver):
|
||||||
|
|
||||||
|
def __init__(self, conf):
|
||||||
|
"""Init constructor."""
|
||||||
|
super(CDNProvider, self).__init__(conf)
|
||||||
|
|
||||||
|
self._conf.register_opts(MAXCDN_OPTIONS,
|
||||||
|
group=MAXCDN_GROUP)
|
||||||
|
self.maxcdn_conf = self._conf[MAXCDN_GROUP]
|
||||||
|
|
||||||
|
self.maxcdn_client = maxcdn.MaxCDN(self.maxcdn_conf.alias,
|
||||||
|
self.maxcdn_conf.consumer_key,
|
||||||
|
self.maxcdn_conf.consumer_secret)
|
||||||
|
|
||||||
|
def is_alive(self):
|
||||||
|
"""For health state."""
|
||||||
|
return True
|
||||||
|
|
||||||
|
@property
|
||||||
|
def provider_name(self):
|
||||||
|
"""For name."""
|
||||||
|
return "MaxCDN"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def client(self):
|
||||||
|
"""client to this provider."""
|
||||||
|
return self.maxcdn_client
|
||||||
|
|
||||||
|
@property
|
||||||
|
def service_controller(self):
|
||||||
|
"""Hook for service controller."""
|
||||||
|
return controllers.ServiceController(self)
|
|
@ -0,0 +1,110 @@
|
||||||
|
# Copyright (c) 2013 Rackspace, Inc.
|
||||||
|
#
|
||||||
|
# Licensed 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.
|
||||||
|
|
||||||
|
from poppy.provider import base
|
||||||
|
|
||||||
|
|
||||||
|
class ServiceController(base.ServiceBase):
|
||||||
|
|
||||||
|
'''MaxCDN Service Controller.
|
||||||
|
|
||||||
|
'''
|
||||||
|
|
||||||
|
@property
|
||||||
|
def client(self):
|
||||||
|
return self.driver.client
|
||||||
|
|
||||||
|
def __init__(self, driver):
|
||||||
|
'''Initialize a service controller object.'''
|
||||||
|
super(ServiceController, self).__init__(driver)
|
||||||
|
|
||||||
|
self.driver = driver
|
||||||
|
|
||||||
|
# This returns the current customer account info
|
||||||
|
account_info_return = self.client.get('/account.json')
|
||||||
|
if account_info_return['code'] != 200:
|
||||||
|
raise RuntimeError(account_info_return['error'])
|
||||||
|
self.current_customer = account_info_return['data']['account']
|
||||||
|
|
||||||
|
def update(self, pullzone_id, service_json):
|
||||||
|
'''MaxCDN update.
|
||||||
|
|
||||||
|
manager needs to pass in pullzone id to delete.
|
||||||
|
'''
|
||||||
|
try:
|
||||||
|
update_response = self.client.put('/zones/pull.json/%s'
|
||||||
|
% pullzone_id,
|
||||||
|
params=service_json)
|
||||||
|
if update_response['code'] != 200:
|
||||||
|
return self.responder.failed('failed to update service')
|
||||||
|
return self.responder.updated(
|
||||||
|
update_response['data']['pullzone']['id'])
|
||||||
|
except Exception:
|
||||||
|
# this exception branch will most likely for a network failure
|
||||||
|
return self.responder.failed('failed to update service')
|
||||||
|
|
||||||
|
def create(self, service_name, service_json):
|
||||||
|
'''MaxCDN create.
|
||||||
|
|
||||||
|
manager needs to pass in a service name to create.
|
||||||
|
'''
|
||||||
|
try:
|
||||||
|
# Create a new pull zone: maxcdn only supports 1 origin
|
||||||
|
origin = service_json['origins'][0]
|
||||||
|
create_response = self.client.post('/zones/pull.json', data={
|
||||||
|
'name': service_name,
|
||||||
|
'url': origin['origin'],
|
||||||
|
'port': origin.get('port', 80),
|
||||||
|
'sslshared': 1 if origin['ssl'] else 0,
|
||||||
|
})
|
||||||
|
|
||||||
|
if create_response['code'] != 201:
|
||||||
|
return self.responder.failed('failed to create service')
|
||||||
|
|
||||||
|
created_zone_info = create_response['data']['pullzone']
|
||||||
|
|
||||||
|
# Add custom domains to this service
|
||||||
|
links = []
|
||||||
|
for domain in service_json['domains']:
|
||||||
|
custom_domain_response = self.client.post(
|
||||||
|
'/zones/pull/%s/customdomains.json'
|
||||||
|
% created_zone_info['id'],
|
||||||
|
{'custom_domain': domain['domain']})
|
||||||
|
links.append(custom_domain_response)
|
||||||
|
# TODO(tonytan4ever): What if it fails during add domains ?
|
||||||
|
return self.responder.created(created_zone_info['id'], links)
|
||||||
|
except Exception:
|
||||||
|
# this exception branch will most likely for a network failure
|
||||||
|
return self.responder.failed('failed to create service')
|
||||||
|
|
||||||
|
def delete(self, pullzone_id):
|
||||||
|
'''MaxCDN create.
|
||||||
|
|
||||||
|
manager needs to pass in a service name to delete.
|
||||||
|
'''
|
||||||
|
try:
|
||||||
|
delete_response = self.client.delete('/zones/pull.json/%s'
|
||||||
|
% pullzone_id)
|
||||||
|
if delete_response['code'] != 200:
|
||||||
|
return self.responder.failed('failed to delete service')
|
||||||
|
return self.responder.deleted(pullzone_id)
|
||||||
|
except Exception:
|
||||||
|
# this exception branch will most likely for a network failure
|
||||||
|
return self.responder.failed('failed to delete service')
|
||||||
|
|
||||||
|
# TODO(tonytan4ever): get service
|
||||||
|
def get(self, service_name):
|
||||||
|
'''Get details of the service, as stored by the provider.'''
|
||||||
|
return {'domains': [], 'origins': [], 'caching': []}
|
|
@ -0,0 +1 @@
|
||||||
|
# official max-cdn is not working for python33 yet. add it later
|
|
@ -3,3 +3,4 @@
|
||||||
-r storage/cassandra.txt
|
-r storage/cassandra.txt
|
||||||
-r transport/pecan.txt
|
-r transport/pecan.txt
|
||||||
-r provider/fastly.txt
|
-r provider/fastly.txt
|
||||||
|
-r provider/maxcdn.txt
|
||||||
|
|
|
@ -5,4 +5,9 @@ manager = default
|
||||||
storage = mockdb
|
storage = mockdb
|
||||||
|
|
||||||
[drivers:provider:fastly]
|
[drivers:provider:fastly]
|
||||||
apikey = "MYAPIKEY"
|
apikey = "MYAPIKEY"
|
||||||
|
|
||||||
|
[drivers:provider:maxcdn]
|
||||||
|
alias = "MYALIAS"
|
||||||
|
consumer_secret = "MYCONSUMER_SECRET"
|
||||||
|
consumer_key = "MYCONSUMERKEY"
|
||||||
|
|
|
@ -25,7 +25,7 @@ log_file = poppy.log
|
||||||
|
|
||||||
[drivers]
|
[drivers]
|
||||||
# Transport driver module (e.g., falcon, pecan)
|
# Transport driver module (e.g., falcon, pecan)
|
||||||
transport = falcon
|
transport = pecan
|
||||||
|
|
||||||
# Manager driver module (e.g. default)
|
# Manager driver module (e.g. default)
|
||||||
manager = default
|
manager = default
|
||||||
|
|
|
@ -27,7 +27,7 @@ log_file = poppy.log
|
||||||
|
|
||||||
[drivers]
|
[drivers]
|
||||||
# Transport driver module (e.g., falcon, pecan)
|
# Transport driver module (e.g., falcon, pecan)
|
||||||
transport = falcon
|
transport = pecan
|
||||||
|
|
||||||
# Manager driver module (e.g. default)
|
# Manager driver module (e.g. default)
|
||||||
manager = default
|
manager = default
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"service_json": {
|
||||||
|
"domains": [
|
||||||
|
{"domain": "parsely.sage.com"},
|
||||||
|
{"domain": "rosemary.thyme.net"}
|
||||||
|
],
|
||||||
|
"origins": [
|
||||||
|
{"origin": "mockdomain.com", "ssl": false, "port": 80}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,70 @@
|
||||||
|
# Copyright (c) 2014 Rackspace, Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
# implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
import mock
|
||||||
|
from oslo.config import cfg
|
||||||
|
|
||||||
|
from poppy.provider.maxcdn import driver
|
||||||
|
from tests.unit import base
|
||||||
|
|
||||||
|
|
||||||
|
MAXCDN_OPTIONS = [
|
||||||
|
cfg.StrOpt('alias', help='MAXCDN API account alias'),
|
||||||
|
cfg.StrOpt('consumer_key', help='MAXCDN API consumer key'),
|
||||||
|
cfg.StrOpt('consumer_secret', help='MAXCDN API consumer secret'),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class TestDriver(base.TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestDriver, self).setUp()
|
||||||
|
|
||||||
|
tests_path = os.path.abspath(os.path.dirname(
|
||||||
|
os.path.dirname(
|
||||||
|
os.path.dirname(os.path.dirname(__file__)
|
||||||
|
))))
|
||||||
|
conf_path = os.path.join(tests_path, 'etc', 'default_functional.conf')
|
||||||
|
cfg.CONF(args=[], default_config_files=[conf_path])
|
||||||
|
|
||||||
|
self.conf = cfg.CONF
|
||||||
|
|
||||||
|
@mock.patch('maxcdn.MaxCDN')
|
||||||
|
@mock.patch.object(driver, 'MAXCDN_OPTIONS', new=MAXCDN_OPTIONS)
|
||||||
|
def test_init(self, mock_connect):
|
||||||
|
provider = driver.CDNProvider(self.conf)
|
||||||
|
mock_connect.assert_called_once_with(
|
||||||
|
provider._conf['drivers:provider:maxcdn'].alias,
|
||||||
|
provider._conf['drivers:provider:maxcdn'].consumer_key,
|
||||||
|
provider._conf['drivers:provider:maxcdn'].consumer_secret)
|
||||||
|
|
||||||
|
@mock.patch.object(driver, 'MAXCDN_OPTIONS', new=MAXCDN_OPTIONS)
|
||||||
|
def test_is_alive(self):
|
||||||
|
provider = driver.CDNProvider(self.conf)
|
||||||
|
self.assertEqual(provider.is_alive(), True)
|
||||||
|
|
||||||
|
@mock.patch.object(driver, 'MAXCDN_OPTIONS', new=MAXCDN_OPTIONS)
|
||||||
|
def test_get_client(self):
|
||||||
|
provider = driver.CDNProvider(self.conf)
|
||||||
|
client = provider.client
|
||||||
|
self.assertNotEqual(client, None)
|
||||||
|
|
||||||
|
@mock.patch('poppy.provider.maxcdn.controllers.ServiceController')
|
||||||
|
@mock.patch.object(driver, 'MAXCDN_OPTIONS', new=MAXCDN_OPTIONS)
|
||||||
|
def test_service_controller(self, MockController):
|
||||||
|
provider = driver.CDNProvider(self.conf)
|
||||||
|
self.assertNotEqual(provider.service_controller, None)
|
|
@ -0,0 +1,239 @@
|
||||||
|
# Copyright (c) 2014 Rackspace, Inc.
|
||||||
|
#
|
||||||
|
# Licensed 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 ddt
|
||||||
|
import mock
|
||||||
|
from oslo.config import cfg
|
||||||
|
|
||||||
|
from poppy.provider.maxcdn import driver
|
||||||
|
from poppy.provider.maxcdn import services
|
||||||
|
from tests.unit import base
|
||||||
|
|
||||||
|
|
||||||
|
MAXCDN_OPTIONS = [
|
||||||
|
cfg.StrOpt('alias',
|
||||||
|
default='no_good_alias',
|
||||||
|
help='MAXCDN API account alias'),
|
||||||
|
cfg.StrOpt('consumer_key',
|
||||||
|
default='a_consumer_key',
|
||||||
|
help='MAXCDN API consumer key'),
|
||||||
|
cfg.StrOpt('consumer_secret',
|
||||||
|
default='a_consumer_secret',
|
||||||
|
help='MAXCDN API consumer secret'),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
fake_maxcdn_client_get_return_value = {u'code': 200,
|
||||||
|
u'data':
|
||||||
|
{u'account':
|
||||||
|
{u'status': u'2',
|
||||||
|
u'name': u'<My_fake_company_alias>',
|
||||||
|
u'id': u'32811'
|
||||||
|
}}}
|
||||||
|
|
||||||
|
fake_maxcdn_client_400_return_value = {
|
||||||
|
u'code': 400,
|
||||||
|
u'message': "operation PUT/GET/POST failed due to technical difficulties.."
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class fake_maxcdn_api_client:
|
||||||
|
|
||||||
|
def get(self, url='/account.json'):
|
||||||
|
return {u'code': 200,
|
||||||
|
u'data':
|
||||||
|
{u'account':
|
||||||
|
{u'status': u'2',
|
||||||
|
u'name': u'<My_fake_company_alias>',
|
||||||
|
u'id': u'32811'
|
||||||
|
}}}
|
||||||
|
|
||||||
|
def post(self, url=None, data=None):
|
||||||
|
return {u'code': 201,
|
||||||
|
u'data': {
|
||||||
|
u"pullzone": {
|
||||||
|
u"cdn_url": u"newpullzone1.alias.netdna-cdn.com",
|
||||||
|
u'name': u'newpullzone1',
|
||||||
|
u'id': u'97312'
|
||||||
|
}}}
|
||||||
|
|
||||||
|
def put(self, url=None, params=None):
|
||||||
|
return {u'code': 200,
|
||||||
|
u'data': {
|
||||||
|
u"pullzone": {
|
||||||
|
u"cdn_url": u"newpullzone1.alias.netdna-cdn.com",
|
||||||
|
u'name': u'newpullzone1',
|
||||||
|
u'id': u'97312'
|
||||||
|
}}}
|
||||||
|
|
||||||
|
def delete(self, url=None):
|
||||||
|
return {u'code': 200,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ddt.ddt
|
||||||
|
class TestServices(base.TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestServices, self).setUp()
|
||||||
|
|
||||||
|
self.conf = cfg.ConfigOpts()
|
||||||
|
|
||||||
|
@mock.patch.object(driver, 'MAXCDN_OPTIONS', new=MAXCDN_OPTIONS)
|
||||||
|
def test_init(self):
|
||||||
|
provider = driver.CDNProvider(self.conf)
|
||||||
|
# instantiate will get
|
||||||
|
self.assertRaises(RuntimeError, services.ServiceController, provider)
|
||||||
|
|
||||||
|
@mock.patch.object(driver.CDNProvider, 'client',
|
||||||
|
new=fake_maxcdn_api_client())
|
||||||
|
def test_get(self):
|
||||||
|
new_driver = driver.CDNProvider(self.conf)
|
||||||
|
# instantiate
|
||||||
|
controller = services.ServiceController(new_driver)
|
||||||
|
service_name = "test_service_name"
|
||||||
|
self.assertTrue(controller.get(service_name) is not None)
|
||||||
|
|
||||||
|
@ddt.file_data('data_service.json')
|
||||||
|
@mock.patch.object(driver.CDNProvider, 'client',
|
||||||
|
new=fake_maxcdn_api_client())
|
||||||
|
def test_create(self, service_json):
|
||||||
|
new_driver = driver.CDNProvider(self.conf)
|
||||||
|
# instantiate
|
||||||
|
controller = services.ServiceController(new_driver)
|
||||||
|
# test create, everything goes through successfully
|
||||||
|
service_name = "test_service_name"
|
||||||
|
resp = controller.create(service_name, service_json)
|
||||||
|
self.assertIn('id', resp[new_driver.provider_name])
|
||||||
|
self.assertIn('links', resp[new_driver.provider_name])
|
||||||
|
|
||||||
|
@ddt.file_data('data_service.json')
|
||||||
|
@mock.patch('poppy.provider.maxcdn.driver.CDNProvider.client')
|
||||||
|
@mock.patch('poppy.provider.maxcdn.driver.CDNProvider')
|
||||||
|
def test_create_with_exception(self, service_json, mock_controllerclient,
|
||||||
|
mock_driver):
|
||||||
|
# test create with exceptions
|
||||||
|
driver = mock_driver()
|
||||||
|
driver.attach_mock(mock_controllerclient, 'client')
|
||||||
|
driver.client.configure_mock(**{'get.return_value':
|
||||||
|
fake_maxcdn_client_get_return_value
|
||||||
|
})
|
||||||
|
|
||||||
|
service_name = "test_service_name"
|
||||||
|
|
||||||
|
controller_with_create_exception = services.ServiceController(driver)
|
||||||
|
controller_with_create_exception.client.configure_mock(**{
|
||||||
|
"post.side_effect":
|
||||||
|
RuntimeError('Creating service mysteriously failed.')})
|
||||||
|
resp = controller_with_create_exception.create(
|
||||||
|
service_name,
|
||||||
|
service_json)
|
||||||
|
self.assertIn('error', resp[driver.provider_name])
|
||||||
|
|
||||||
|
controller_with_create_exception.client.reset_mock()
|
||||||
|
controller_with_create_exception.client.configure_mock(**{
|
||||||
|
'post.side_effect': None,
|
||||||
|
"post.return_value": fake_maxcdn_client_400_return_value
|
||||||
|
})
|
||||||
|
resp = controller_with_create_exception.create(
|
||||||
|
service_name,
|
||||||
|
service_json)
|
||||||
|
self.assertIn('error', resp[driver.provider_name])
|
||||||
|
|
||||||
|
@ddt.file_data('data_service.json')
|
||||||
|
@mock.patch.object(driver.CDNProvider, 'client',
|
||||||
|
new=fake_maxcdn_api_client())
|
||||||
|
def test_update(self, service_json):
|
||||||
|
new_driver = driver.CDNProvider(self.conf)
|
||||||
|
# instantiate
|
||||||
|
controller = services.ServiceController(new_driver)
|
||||||
|
# test create, everything goes through successfully
|
||||||
|
service_name = "test_service_name"
|
||||||
|
resp = controller.update(service_name, service_json)
|
||||||
|
self.assertIn('id', resp[new_driver.provider_name])
|
||||||
|
|
||||||
|
@ddt.file_data('data_service.json')
|
||||||
|
@mock.patch('poppy.provider.maxcdn.driver.CDNProvider.client')
|
||||||
|
@mock.patch('poppy.provider.maxcdn.driver.CDNProvider')
|
||||||
|
def test_update_with_exception(self, service_json, mock_controllerclient,
|
||||||
|
mock_driver):
|
||||||
|
# test create with exceptions
|
||||||
|
driver = mock_driver()
|
||||||
|
driver.attach_mock(mock_controllerclient, 'client')
|
||||||
|
driver.client.configure_mock(**{'get.return_value':
|
||||||
|
fake_maxcdn_client_get_return_value
|
||||||
|
})
|
||||||
|
|
||||||
|
service_name = "test_service_name"
|
||||||
|
|
||||||
|
controller_with_update_exception = services.ServiceController(driver)
|
||||||
|
controller_with_update_exception.client.configure_mock(**{
|
||||||
|
"put.side_effect":
|
||||||
|
RuntimeError('Updating service mysteriously failed.')})
|
||||||
|
resp = controller_with_update_exception.update(
|
||||||
|
service_name,
|
||||||
|
service_json)
|
||||||
|
self.assertIn('error', resp[driver.provider_name])
|
||||||
|
|
||||||
|
controller_with_update_exception.client.reset_mock()
|
||||||
|
controller_with_update_exception.client.configure_mock(**{
|
||||||
|
"put.side_effect": None,
|
||||||
|
"put.return_value": fake_maxcdn_client_400_return_value
|
||||||
|
})
|
||||||
|
resp = controller_with_update_exception.update(
|
||||||
|
service_name,
|
||||||
|
service_json)
|
||||||
|
self.assertIn('error', resp[driver.provider_name])
|
||||||
|
|
||||||
|
@mock.patch.object(driver.CDNProvider, 'client',
|
||||||
|
new=fake_maxcdn_api_client())
|
||||||
|
def test_delete(self):
|
||||||
|
new_driver = driver.CDNProvider(self.conf)
|
||||||
|
# instantiate
|
||||||
|
controller = services.ServiceController(new_driver)
|
||||||
|
# test create, everything goes through successfully
|
||||||
|
service_name = "test_service_name"
|
||||||
|
resp = controller.delete(service_name)
|
||||||
|
self.assertIn('id', resp[new_driver.provider_name])
|
||||||
|
|
||||||
|
@mock.patch('poppy.provider.maxcdn.driver.CDNProvider.client')
|
||||||
|
@mock.patch('poppy.provider.maxcdn.driver.CDNProvider')
|
||||||
|
def test_delete_with_exception(self, mock_controllerclient,
|
||||||
|
mock_driver):
|
||||||
|
# test create with exceptions
|
||||||
|
driver = mock_driver()
|
||||||
|
driver.attach_mock(mock_controllerclient, 'client')
|
||||||
|
driver.client.configure_mock(**{'get.return_value':
|
||||||
|
fake_maxcdn_client_get_return_value
|
||||||
|
})
|
||||||
|
|
||||||
|
service_name = "test_service_name"
|
||||||
|
|
||||||
|
controller_with_delete_exception = services.ServiceController(driver)
|
||||||
|
controller_with_delete_exception.client.configure_mock(**{
|
||||||
|
"delete.side_effect":
|
||||||
|
RuntimeError('Deleting service mysteriously failed.')})
|
||||||
|
resp = controller_with_delete_exception.delete(service_name)
|
||||||
|
self.assertEqual(resp[driver.provider_name]['error'],
|
||||||
|
'failed to delete service')
|
||||||
|
|
||||||
|
controller_with_delete_exception.client.reset_mock()
|
||||||
|
controller_with_delete_exception.client.configure_mock(**{
|
||||||
|
"delete.side_effect": None,
|
||||||
|
"delete.return_value": fake_maxcdn_client_400_return_value
|
||||||
|
})
|
||||||
|
resp = controller_with_delete_exception.delete(service_name)
|
||||||
|
self.assertEqual(resp[driver.provider_name]['error'],
|
||||||
|
'failed to delete service')
|
1
tox.ini
1
tox.ini
|
@ -17,6 +17,7 @@ setenv = VIRTUAL_ENV={envdir}
|
||||||
deps = -r{toxinidir}/requirements/requirements.txt
|
deps = -r{toxinidir}/requirements/requirements.txt
|
||||||
-r{toxinidir}/tests/test-requirements.txt
|
-r{toxinidir}/tests/test-requirements.txt
|
||||||
commands = pip install git+https://github.com/malini-kamalambal/opencafe.git#egg=cafe
|
commands = pip install git+https://github.com/malini-kamalambal/opencafe.git#egg=cafe
|
||||||
|
pip install git+https://github.com/tonytan4ever/python-maxcdn.git#egg=maxcdn
|
||||||
nosetests {posargs}
|
nosetests {posargs}
|
||||||
|
|
||||||
[tox:jenkins]
|
[tox:jenkins]
|
||||||
|
|
Loading…
Reference in New Issue