Clean imports in code

In some part in the code we import objects.
In the Openstack style guidelines they recommend to import only
modules.

http://docs.openstack.org/developer/hacking/#imports

Change-Id: I58b2dab1a46128893648630edba615e2592040ac
This commit is contained in:
Nguyen Hung Phuong 2016-08-24 10:24:03 +07:00 committed by Marc Aubry
parent 451191f843
commit 90bb67ffb6
70 changed files with 712 additions and 534 deletions

View File

@ -12,25 +12,23 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import logging
from datetime import datetime
from functools import wraps
import logging
import flask
import jsonpickle
from flask import Blueprint, Response, request
from oslo_serialization import jsonutils
from werkzeug import wrappers
from werkzeug.wrappers import BaseResponse
from almanach.common.exceptions import almanach_entity_not_found_exception
from almanach.common.exceptions import almanach_exception
from almanach.common.exceptions import authentication_failure_exception
from almanach.common.exceptions import date_format_exception
from almanach.common.exceptions import multiple_entities_matching_query
from almanach.common.exceptions import validation_exception
from almanach.common.exceptions.almanach_exception import AlmanachException
from almanach.common.exceptions.almanach_entity_not_found_exception import AlmanachEntityNotFoundException
from almanach.common.exceptions.authentication_failure_exception import AuthenticationFailureException
from almanach.common.exceptions.multiple_entities_matching_query import MultipleEntitiesMatchingQuery
from almanach.common.exceptions.validation_exception import InvalidAttributeException
from almanach.common.exceptions.date_format_exception import DateFormatException
api = Blueprint("api", __name__)
api = flask.Blueprint("api", __name__)
controller = None
auth_adapter = None
@ -43,11 +41,11 @@ def to_json(api_call):
def decorator(*args, **kwargs):
try:
result = api_call(*args, **kwargs)
return result if isinstance(result, BaseResponse) \
else Response(encode(result), 200, {"Content-Type": "application/json"})
except DateFormatException as e:
return result if isinstance(result, wrappers.BaseResponse) \
else flask.Response(encode(result), 200, {"Content-Type": "application/json"})
except date_format_exception.DateFormatException as e:
logging.warning(e.message)
return Response(encode({"error": e.message}), 400, {"Content-Type": "application/json"})
return flask.Response(encode({"error": e.message}), 400, {"Content-Type": "application/json"})
except KeyError as e:
message = "The {param} param is mandatory for the request you have made.".format(param=e)
logging.warning(message)
@ -56,22 +54,22 @@ def to_json(api_call):
message = "The request you have made must have data. None was given."
logging.warning(message)
return encode({"error": message}), 400, {"Content-Type": "application/json"}
except InvalidAttributeException as e:
except validation_exception.InvalidAttributeException as e:
logging.warning(e.get_error_message())
return encode({"error": e.get_error_message()}), 400, {"Content-Type": "application/json"}
except MultipleEntitiesMatchingQuery as e:
except multiple_entities_matching_query.MultipleEntitiesMatchingQuery as e:
logging.warning(e.message)
return encode({"error": "Multiple entities found while updating closed"}), 400, {
"Content-Type": "application/json"}
except AlmanachEntityNotFoundException as e:
except almanach_entity_not_found_exception.AlmanachEntityNotFoundException as e:
logging.warning(e.message)
return encode({"error": "Entity not found"}), 404, {"Content-Type": "application/json"}
except AlmanachException as e:
except almanach_exception.AlmanachException as e:
logging.exception(e)
return Response(encode({"error": e.message}), 500, {"Content-Type": "application/json"})
return flask.Response(encode({"error": e.message}), 500, {"Content-Type": "application/json"})
except Exception as e:
logging.exception(e)
return Response(encode({"error": e}), 500, {"Content-Type": "application/json"})
return flask.Response(encode({"error": e}), 500, {"Content-Type": "application/json"})
return decorator
@ -80,11 +78,11 @@ def authenticated(api_call):
@wraps(api_call)
def decorator(*args, **kwargs):
try:
auth_adapter.validate(request.headers.get('X-Auth-Token'))
auth_adapter.validate(flask.request.headers.get('X-Auth-Token'))
return api_call(*args, **kwargs)
except AuthenticationFailureException as e:
except authentication_failure_exception.AuthenticationFailureException as e:
logging.error("Authentication failure: {0}".format(e))
return Response('Unauthorized', 401)
return flask.Response('Unauthorized', 401)
return decorator
@ -100,7 +98,7 @@ def get_info():
@authenticated
@to_json
def create_instance(project_id):
instance = jsonutils.loads(request.data)
instance = jsonutils.loads(flask.request.data)
logging.info("Creating instance for tenant %s with data %s", project_id, instance)
controller.create_instance(
tenant_id=project_id,
@ -114,28 +112,28 @@ def create_instance(project_id):
metadata={}
)
return Response(status=201)
return flask.Response(status=201)
@api.route("/instance/<instance_id>", methods=["DELETE"])
@authenticated
@to_json
def delete_instance(instance_id):
data = jsonutils.loads(request.data)
data = jsonutils.loads(flask.request.data)
logging.info("Deleting instance with id %s with data %s", instance_id, data)
controller.delete_instance(
instance_id=instance_id,
delete_date=data['date']
)
return Response(status=202)
return flask.Response(status=202)
@api.route("/instance/<instance_id>/resize", methods=["PUT"])
@authenticated
@to_json
def resize_instance(instance_id):
instance = jsonutils.loads(request.data)
instance = jsonutils.loads(flask.request.data)
logging.info("Resizing instance with id %s with data %s", instance_id, instance)
controller.resize_instance(
instance_id=instance_id,
@ -143,14 +141,14 @@ def resize_instance(instance_id):
flavor=instance['flavor']
)
return Response(status=200)
return flask.Response(status=200)
@api.route("/instance/<instance_id>/rebuild", methods=["PUT"])
@authenticated
@to_json
def rebuild_instance(instance_id):
instance = jsonutils.loads(request.data)
instance = jsonutils.loads(flask.request.data)
logging.info("Rebuilding instance with id %s with data %s", instance_id, instance)
controller.rebuild_instance(
instance_id=instance_id,
@ -160,7 +158,7 @@ def rebuild_instance(instance_id):
rebuild_date=instance['rebuild_date'],
)
return Response(status=200)
return flask.Response(status=200)
@api.route("/project/<project_id>/instances", methods=["GET"])
@ -176,7 +174,7 @@ def list_instances(project_id):
@authenticated
@to_json
def create_volume(project_id):
volume = jsonutils.loads(request.data)
volume = jsonutils.loads(flask.request.data)
logging.info("Creating volume for tenant %s with data %s", project_id, volume)
controller.create_volume(
project_id=project_id,
@ -188,28 +186,28 @@ def create_volume(project_id):
attached_to=volume['attached_to']
)
return Response(status=201)
return flask.Response(status=201)
@api.route("/volume/<volume_id>", methods=["DELETE"])
@authenticated
@to_json
def delete_volume(volume_id):
data = jsonutils.loads(request.data)
data = jsonutils.loads(flask.request.data)
logging.info("Deleting volume with id %s with data %s", volume_id, data)
controller.delete_volume(
volume_id=volume_id,
delete_date=data['date']
)
return Response(status=202)
return flask.Response(status=202)
@api.route("/volume/<volume_id>/resize", methods=["PUT"])
@authenticated
@to_json
def resize_volume(volume_id):
volume = jsonutils.loads(request.data)
volume = jsonutils.loads(flask.request.data)
logging.info("Resizing volume with id %s with data %s", volume_id, volume)
controller.resize_volume(
volume_id=volume_id,
@ -217,14 +215,14 @@ def resize_volume(volume_id):
update_date=volume['date']
)
return Response(status=200)
return flask.Response(status=200)
@api.route("/volume/<volume_id>/attach", methods=["PUT"])
@authenticated
@to_json
def attach_volume(volume_id):
volume = jsonutils.loads(request.data)
volume = jsonutils.loads(flask.request.data)
logging.info("Attaching volume with id %s with data %s", volume_id, volume)
controller.attach_volume(
volume_id=volume_id,
@ -232,14 +230,14 @@ def attach_volume(volume_id):
attachments=volume['attachments']
)
return Response(status=200)
return flask.Response(status=200)
@api.route("/volume/<volume_id>/detach", methods=["PUT"])
@authenticated
@to_json
def detach_volume(volume_id):
volume = jsonutils.loads(request.data)
volume = jsonutils.loads(flask.request.data)
logging.info("Detaching volume with id %s with data %s", volume_id, volume)
controller.detach_volume(
volume_id=volume_id,
@ -247,7 +245,7 @@ def detach_volume(volume_id):
attachments=volume['attachments']
)
return Response(status=200)
return flask.Response(status=200)
@api.route("/project/<project_id>/volumes", methods=["GET"])
@ -272,9 +270,9 @@ def list_entity(project_id):
@authenticated
@to_json
def update_instance_entity(instance_id):
data = jsonutils.loads(request.data)
data = jsonutils.loads(flask.request.data)
logging.info("Updating instance entity with id %s with data %s", instance_id, data)
if 'start' in request.args:
if 'start' in flask.request.args:
start, end = get_period()
result = controller.update_inactive_entity(instance_id=instance_id, start=start, end=end, **data)
else:
@ -286,9 +284,9 @@ def update_instance_entity(instance_id):
@authenticated
def entity_exists(entity_id):
logging.info("Does entity with id %s exists", entity_id)
response = Response('', 404)
response = flask.Response('', 404)
if controller.entity_exists(entity_id=entity_id):
response = Response('', 200)
response = flask.Response('', 200)
return response
@ -319,13 +317,13 @@ def get_volume_type(type_id):
@authenticated
@to_json
def create_volume_type():
volume_type = jsonutils.loads(request.data)
volume_type = jsonutils.loads(flask.request.data)
logging.info("Creating volume type with data '%s'", volume_type)
controller.create_volume_type(
volume_type_id=volume_type['type_id'],
volume_type_name=volume_type['type_name']
)
return Response(status=201)
return flask.Response(status=201)
@api.route("/volume_type/<type_id>", methods=["DELETE"])
@ -334,13 +332,13 @@ def create_volume_type():
def delete_volume_type(type_id):
logging.info("Deleting volume type with id '%s'", type_id)
controller.delete_volume_type(type_id)
return Response(status=202)
return flask.Response(status=202)
def get_period():
start = datetime.strptime(request.args["start"], "%Y-%m-%d %H:%M:%S.%f")
if "end" not in request.args:
start = datetime.strptime(flask.request.args["start"], "%Y-%m-%d %H:%M:%S.%f")
if "end" not in flask.request.args:
end = datetime.now()
else:
end = datetime.strptime(request.args["end"], "%Y-%m-%d %H:%M:%S.%f")
end = datetime.strptime(flask.request.args["end"], "%Y-%m-%d %H:%M:%S.%f")
return start, end

View File

@ -14,19 +14,18 @@
import logging
from almanach.auth import keystone_auth
from almanach.auth import mixed_auth
from almanach.auth import private_key_auth
from almanach import config
from almanach.auth.mixed_auth import MixedAuthentication
from almanach.auth.keystone_auth import KeystoneAuthentication, KeystoneTokenManagerFactory
from almanach.auth.private_key_auth import PrivateKeyAuthentication
class AuthenticationAdapter(object):
@staticmethod
def factory():
if config.auth_strategy() == "keystone":
logging.info("Loading Keystone authentication backend")
return KeystoneAuthentication(KeystoneTokenManagerFactory(
return keystone_auth.KeystoneAuthentication(keystone_auth.KeystoneTokenManagerFactory(
username=config.keystone_username(),
password=config.keystone_password(),
auth_url=config.keystone_url(),
@ -34,14 +33,14 @@ class AuthenticationAdapter(object):
))
elif all(auth_method in config.auth_strategy() for auth_method in ['token', 'keystone']):
logging.info("Loading Keystone authentication backend")
auths = [PrivateKeyAuthentication(config.auth_private_key()),
KeystoneAuthentication(KeystoneTokenManagerFactory(
auths = [private_key_auth.PrivateKeyAuthentication(config.auth_private_key()),
keystone_auth.KeystoneAuthentication(keystone_auth.KeystoneTokenManagerFactory(
username=config.keystone_username(),
password=config.keystone_password(),
auth_url=config.keystone_url(),
tenant_name=config.keystone_tenant_name()
))]
return MixedAuthentication(auths)
return mixed_auth.MixedAuthentication(auths)
else:
logging.info("Loading PrivateKey authentication backend")
return PrivateKeyAuthentication(config.auth_private_key())
return private_key_auth.PrivateKeyAuthentication(config.auth_private_key())

View File

@ -12,20 +12,19 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import logging
import kombu
import logging
import six
from kombu.mixins import ConsumerMixin
from kombu import mixins
from oslo_serialization import jsonutils
from almanach.adapters import instance_bus_adapter
from almanach.adapters import volume_bus_adapter
from almanach import config
from almanach.adapters.instance_bus_adapter import InstanceBusAdapter
from almanach.adapters.volume_bus_adapter import VolumeBusAdapter
class BusAdapter(ConsumerMixin):
class BusAdapter(mixins.ConsumerMixin):
def __init__(self, controller, connection, retry_adapter):
super(BusAdapter, self).__init__()
self.controller = controller
@ -47,8 +46,8 @@ class BusAdapter(ConsumerMixin):
event_type = notification.get("event_type")
logging.info("Received event: '{0}'".format(event_type))
InstanceBusAdapter(self.controller).handle_events(event_type, notification)
VolumeBusAdapter(self.controller).handle_events(event_type, notification)
instance_bus_adapter.InstanceBusAdapter(self.controller).handle_events(event_type, notification)
volume_bus_adapter.VolumeBusAdapter(self.controller).handle_events(event_type, notification)
def get_consumers(self, consumer, channel):
queue = kombu.Queue(config.rabbitmq_queue(), routing_key=config.rabbitmq_routing_key())

View File

@ -15,12 +15,13 @@
import logging
import pymongo
from pymongo.errors import ConfigurationError
from pymongo import errors
from almanach.common.exceptions import almanach_exception
from almanach.common.exceptions import volume_type_not_found_exception
from almanach import config
from almanach.common.exceptions.almanach_exception import AlmanachException
from almanach.common.exceptions.volume_type_not_found_exception import VolumeTypeNotFoundException
from almanach.core.model import build_entity_from_dict, VolumeType
from almanach.core import model
from almanach.core.model import build_entity_from_dict
def database(function):
@ -33,11 +34,11 @@ def database(function):
return function(self, *args, **kwargs)
except KeyError as e:
raise e
except VolumeTypeNotFoundException as e:
except volume_type_not_found_exception.VolumeTypeNotFoundException as e:
raise e
except NotImplementedError as e:
raise e
except ConfigurationError as e:
except errors.ConfigurationError as e:
logging.exception("DB Connection, make sure username and password doesn't contain the following :+&/ "
"character")
raise e
@ -101,7 +102,7 @@ class DatabaseAdapter(object):
"$and": [
{"end": {"$ne": None}},
{"end": {"$lte": end}}
]
]
}, {"_id": 0})
return [build_entity_from_dict(entity) for entity in entities]
@ -123,30 +124,30 @@ class DatabaseAdapter(object):
volume_type = self.db.volume_type.find_one({"volume_type_id": volume_type_id})
if not volume_type:
logging.error("Trying to get a volume type not in the database.")
raise VolumeTypeNotFoundException(volume_type_id=volume_type_id)
raise volume_type_not_found_exception.VolumeTypeNotFoundException(volume_type_id=volume_type_id)
return VolumeType(volume_type_id=volume_type["volume_type_id"],
volume_type_name=volume_type["volume_type_name"])
return model.VolumeType(volume_type_id=volume_type["volume_type_id"],
volume_type_name=volume_type["volume_type_name"])
@database
def delete_volume_type(self, volume_type_id):
if volume_type_id is None:
error = "Trying to delete all volume types which is not permitted."
logging.error(error)
raise AlmanachException(error)
raise almanach_exception.AlmanachException(error)
returned_value = self.db.volume_type.remove({"volume_type_id": volume_type_id})
if returned_value['n'] == 1:
logging.info("Deleted volume type with id '%s' successfully." % volume_type_id)
else:
error = "Volume type with id '%s' doesn't exist in the database." % volume_type_id
logging.error(error)
raise AlmanachException(error)
raise almanach_exception.AlmanachException(error)
@database
def list_volume_types(self):
volume_types = self.db.volume_type.find()
return [VolumeType(volume_type_id=volume_type["volume_type_id"],
volume_type_name=volume_type["volume_type_name"]) for volume_type in volume_types]
return [model.VolumeType(volume_type_id=volume_type["volume_type_id"],
volume_type_name=volume_type["volume_type_name"]) for volume_type in volume_types]
@database
def close_active_entity(self, entity_id, end):

View File

@ -14,20 +14,19 @@
import logging
from kombu import Exchange, Queue, Producer
import kombu
from oslo_serialization import jsonutils
from almanach import config
class RetryAdapter:
class RetryAdapter(object):
def __init__(self, connection):
self.connection = connection
retry_exchange = self._configure_retry_exchanges(self.connection)
dead_exchange = self._configure_dead_exchange(self.connection)
self._retry_producer = Producer(self.connection, exchange=retry_exchange)
self._dead_producer = Producer(self.connection, exchange=dead_exchange)
self._retry_producer = kombu.Producer(self.connection, exchange=retry_exchange)
self._dead_producer = kombu.Producer(self.connection, exchange=dead_exchange)
def publish_to_dead_letter(self, message):
death_count = self._rejected_count(message)
@ -44,22 +43,22 @@ class RetryAdapter:
def _configure_retry_exchanges(self, connection):
def declare_queues():
channel = connection.channel()
almanach_exchange = Exchange(name=config.rabbitmq_retry_return_exchange(),
type='direct',
channel=channel)
retry_exchange = Exchange(name=config.rabbitmq_retry_exchange(),
type='direct',
almanach_exchange = kombu.Exchange(name=config.rabbitmq_retry_return_exchange(),
type='direct',
channel=channel)
retry_exchange = kombu.Exchange(name=config.rabbitmq_retry_exchange(),
type='direct',
channel=channel)
retry_queue = kombu.Queue(name=config.rabbitmq_retry_queue(),
exchange=retry_exchange,
routing_key=config.rabbitmq_routing_key(),
queue_arguments=self._get_queue_arguments(),
channel=channel)
retry_queue = Queue(name=config.rabbitmq_retry_queue(),
exchange=retry_exchange,
routing_key=config.rabbitmq_routing_key(),
queue_arguments=self._get_queue_arguments(),
channel=channel)
almanach_queue = Queue(name=config.rabbitmq_queue(),
exchange=almanach_exchange,
durable=False,
routing_key=config.rabbitmq_routing_key(),
channel=channel)
almanach_queue = kombu.Queue(name=config.rabbitmq_queue(),
exchange=almanach_exchange,
durable=False,
routing_key=config.rabbitmq_routing_key(),
channel=channel)
retry_queue.declare()
almanach_queue.declare()
@ -76,13 +75,13 @@ class RetryAdapter:
def _configure_dead_exchange(self, connection):
def declare_dead_queue():
channel = connection.channel()
dead_exchange = Exchange(name=config.rabbitmq_dead_exchange(),
type='direct',
dead_exchange = kombu.Exchange(name=config.rabbitmq_dead_exchange(),
type='direct',
channel=channel)
dead_queue = kombu.Queue(name=config.rabbitmq_dead_queue(),
routing_key=config.rabbitmq_routing_key(),
exchange=dead_exchange,
channel=channel)
dead_queue = Queue(name=config.rabbitmq_dead_queue(),
routing_key=config.rabbitmq_routing_key(),
exchange=dead_exchange,
channel=channel)
dead_queue.declare()

View File

@ -15,16 +15,15 @@
from flask import Flask
from almanach.adapters import api_route_v1 as api_route
from almanach.adapters.auth_adapter import AuthenticationAdapter
from almanach.adapters.database_adapter import DatabaseAdapter
from almanach.core.controller import Controller
from almanach.adapters import auth_adapter
from almanach.adapters import database_adapter
from almanach.core import controller
class AlmanachApi(object):
def run(self, host, port):
api_route.controller = Controller(DatabaseAdapter())
api_route.auth_adapter = AuthenticationAdapter().factory()
api_route.controller = controller.Controller(database_adapter.DatabaseAdapter())
api_route.auth_adapter = auth_adapter.AuthenticationAdapter().factory()
app = Flask("almanach")
app.register_blueprint(api_route.api)

View File

@ -16,7 +16,6 @@ import abc
class BaseAuth(object):
@abc.abstractmethod
def validate(self, token):
return True

View File

@ -13,10 +13,10 @@
# limitations under the License.
from keystoneclient.v2_0 import client as keystone_client
from keystoneclient.v2_0.tokens import TokenManager
from keystoneclient.v2_0 import tokens
from almanach.auth.base_auth import BaseAuth
from almanach.common.exceptions.authentication_failure_exception import AuthenticationFailureException
from almanach.auth import base_auth
from almanach.common.exceptions import authentication_failure_exception
class KeystoneTokenManagerFactory(object):
@ -27,7 +27,7 @@ class KeystoneTokenManagerFactory(object):
self.username = username
def get_manager(self):
return TokenManager(keystone_client.Client(
return tokens.TokenManager(keystone_client.Client(
username=self.username,
password=self.password,
auth_url=self.auth_url,
@ -35,17 +35,17 @@ class KeystoneTokenManagerFactory(object):
)
class KeystoneAuthentication(BaseAuth):
class KeystoneAuthentication(base_auth.BaseAuth):
def __init__(self, token_manager_factory):
self.token_manager_factory = token_manager_factory
def validate(self, token):
if token is None:
raise AuthenticationFailureException("No token provided")
raise authentication_failure_exception.AuthenticationFailureException("No token provided")
try:
self.token_manager_factory.get_manager().validate(token)
except Exception as e:
raise AuthenticationFailureException(e)
raise authentication_failure_exception.AuthenticationFailureException(e)
return True

View File

@ -12,11 +12,12 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import logging
from almanach.auth.base_auth import BaseAuth
from almanach.common.exceptions.authentication_failure_exception import AuthenticationFailureException
from almanach.auth import base_auth
from almanach.common.exceptions import authentication_failure_exception
class MixedAuthentication(BaseAuth):
class MixedAuthentication(base_auth.BaseAuth):
def __init__(self, authentication_methods):
self.authentication_methods = authentication_methods
@ -27,6 +28,6 @@ class MixedAuthentication(BaseAuth):
if valid:
logging.debug('Validated token with auth {0}'.format(method.__class__))
return True
except AuthenticationFailureException:
except authentication_failure_exception.AuthenticationFailureException:
logging.debug('Failed to validate with auth {0}'.format(method.__class__))
raise AuthenticationFailureException('No valid auth method matching token')
raise authentication_failure_exception.AuthenticationFailureException('No valid auth method matching token')

View File

@ -12,15 +12,15 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from almanach.auth.base_auth import BaseAuth
from almanach.common.exceptions.authentication_failure_exception import AuthenticationFailureException
from almanach.auth import base_auth
from almanach.common.exceptions import authentication_failure_exception
class PrivateKeyAuthentication(BaseAuth):
class PrivateKeyAuthentication(base_auth.BaseAuth):
def __init__(self, private_key):
self.private_key = private_key
def validate(self, token):
if token is None or self.private_key != token:
raise AuthenticationFailureException("Invalid Token")
raise authentication_failure_exception.AuthenticationFailureException("Invalid Token")
return True

View File

@ -13,13 +13,13 @@
# limitations under the License.
import argparse
import sys
import logging
import logging.config as logging_config
import sys
from almanach import api
from almanach import collector
from almanach import config
from almanach.api import AlmanachApi
from almanach.collector import AlmanachCollector
def run():
@ -41,10 +41,10 @@ def run():
logging.debug("Logging to stdout")
if args.service == "api":
almanach_api = AlmanachApi()
almanach_api = api.AlmanachApi()
almanach_api.run(host=args.host, port=args.port)
else:
almanach_collector = AlmanachCollector()
almanach_collector = collector.AlmanachCollector()
almanach_collector.run()

View File

@ -14,22 +14,22 @@
import logging
from kombu import Connection
import kombu
from almanach.adapters import bus_adapter
from almanach.adapters import database_adapter
from almanach.adapters import retry_adapter
from almanach import config
from almanach.adapters.bus_adapter import BusAdapter
from almanach.adapters.database_adapter import DatabaseAdapter
from almanach.adapters.retry_adapter import RetryAdapter
from almanach.core.controller import Controller
from almanach.core import controller
class AlmanachCollector(object):
def __init__(self):
self._controller = Controller(DatabaseAdapter())
_connection = Connection(config.rabbitmq_url(), heartbeat=540)
retry_adapter = RetryAdapter(_connection)
self._busAdapter = BusAdapter(self._controller, _connection, retry_adapter)
self._controller = controller.Controller(database_adapter.DatabaseAdapter())
_connection = kombu.Connection(config.rabbitmq_url(), heartbeat=540)
retry_adapter_instance = retry_adapter.RetryAdapter(_connection)
self._busAdapter = bus_adapter.BusAdapter(self._controller, _connection,
retry_adapter_instance)
def run(self):
logging.info("Listening for incoming events")

View File

@ -11,8 +11,8 @@
# 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 almanach.common.exceptions.almanach_exception import AlmanachException
from almanach.common.exceptions import almanach_exception
class AlmanachEntityNotFoundException(AlmanachException):
class AlmanachEntityNotFoundException(almanach_exception.AlmanachException):
pass

View File

@ -11,11 +11,10 @@
# 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 almanach.common.exceptions.almanach_exception import AlmanachException
from almanach.common.exceptions import almanach_exception
class DateFormatException(AlmanachException):
class DateFormatException(almanach_exception.AlmanachException):
def __init__(self, message=None):
if not message:
message = "The provided date has an invalid format. Format should be of yyyy-mm-ddThh:mm:ss.msZ, " \

View File

@ -11,8 +11,8 @@
# 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 almanach.common.exceptions.almanach_exception import AlmanachException
from almanach.common.exceptions import almanach_exception
class MultipleEntitiesMatchingQuery(AlmanachException):
class MultipleEntitiesMatchingQuery(almanach_exception.AlmanachException):
pass

View File

@ -11,10 +11,10 @@
# 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 almanach.common.exceptions.almanach_exception import AlmanachException
from almanach.common.exceptions import almanach_exception
class InvalidAttributeException(AlmanachException):
class InvalidAttributeException(almanach_exception.AlmanachException):
def __init__(self, errors):
self.errors = errors

View File

@ -11,11 +11,10 @@
# 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 almanach.common.exceptions.almanach_exception import AlmanachException
from almanach.common.exceptions import almanach_exception
class VolumeTypeNotFoundException(AlmanachException):
class VolumeTypeNotFoundException(almanach_exception.AlmanachException):
def __init__(self, volume_type_id, message=None):
if not message:
message = "Unable to find volume_type id '{volume_type_id}'".format(volume_type_id=volume_type_id)

View File

@ -16,7 +16,7 @@ import os
import os.path as os_path
import six
from almanach.common.exceptions.almanach_exception import AlmanachException
from almanach.common.exceptions import almanach_exception
if six.PY2:
from ConfigParser import RawConfigParser
@ -28,7 +28,7 @@ configuration = RawConfigParser()
def read(filename):
if not os_path.isfile(filename):
raise AlmanachException("Config file '{0}' not found".format(filename))
raise almanach_exception.AlmanachException("Config file '{0}' not found".format(filename))
print("Loading configuration file {0}".format(filename))
configuration.read(filename)
@ -42,7 +42,7 @@ def get(section, option, default=None):
try:
return configuration.get(section, option)
except:
except Exception:
return default

View File

@ -12,20 +12,19 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import logging
from datetime import timedelta
import pytz
from dateutil import parser as date_parser
import logging
from pkg_resources import get_distribution
from almanach.common.exceptions.almanach_entity_not_found_exception import AlmanachEntityNotFoundException
from almanach.common.exceptions.date_format_exception import DateFormatException
from almanach.common.exceptions.multiple_entities_matching_query import MultipleEntitiesMatchingQuery
from almanach.core.model import Instance, Volume, VolumeType
from almanach.validators.instance_validator import InstanceValidator
import pytz
from almanach.common.exceptions import almanach_entity_not_found_exception
from almanach.common.exceptions import date_format_exception
from almanach.common.exceptions import multiple_entities_matching_query
from almanach import config
from almanach.core import model
from almanach.validators import instance_validator
class Controller(object):
@ -52,14 +51,16 @@ class Controller(object):
filtered_metadata = self._filter_metadata_with_whitelist(metadata)
entity = Instance(instance_id, tenant_id, create_date, None, flavor, {"os_type": os_type, "distro": distro,
"version": version},
create_date, name, filtered_metadata)
entity = model.Instance(instance_id, tenant_id, create_date, None, flavor,
{"os_type": os_type, "distro": distro,
"version": version},
create_date, name, filtered_metadata)
self.database_adapter.insert_entity(entity)
def delete_instance(self, instance_id, delete_date):
if not self.database_adapter.has_active_entity(instance_id):
raise AlmanachEntityNotFoundException("InstanceId: {0} Not Found".format(instance_id))
raise almanach_entity_not_found_exception.AlmanachEntityNotFoundException(
"InstanceId: {0} Not Found".format(instance_id))
delete_date = self._validate_and_parse_date(delete_date)
logging.info("instance %s deleted on %s" % (instance_id, delete_date))
@ -101,9 +102,10 @@ class Controller(object):
def update_inactive_entity(self, instance_id, start, end, **kwargs):
inactive_entities = self.database_adapter.list_entities_by_id(instance_id, start, end)
if len(inactive_entities) > 1:
raise MultipleEntitiesMatchingQuery()
raise multiple_entities_matching_query.MultipleEntitiesMatchingQuery()
if len(inactive_entities) < 1:
raise AlmanachEntityNotFoundException("InstanceId: {0} Not Found with start".format(instance_id))
raise almanach_entity_not_found_exception.AlmanachEntityNotFoundException(
"InstanceId: {0} Not Found with start".format(instance_id))
entity = inactive_entities[0]
entity_update = self._transform_attribute_to_match_entity_attribute(**kwargs)
self.database_adapter.update_closed_entity(entity=entity, data=entity_update)
@ -113,7 +115,7 @@ class Controller(object):
def update_active_instance_entity(self, instance_id, **kwargs):
try:
InstanceValidator().validate_update(kwargs)
instance_validator.InstanceValidator().validate_update(kwargs)
instance = self.database_adapter.get_active_entity(instance_id)
self._update_instance_object(instance, **kwargs)
self.database_adapter.update_active_entity(instance)
@ -127,7 +129,7 @@ class Controller(object):
def get_all_entities_by_id(self, entity_id):
if not self.entity_exists(entity_id=entity_id):
raise AlmanachEntityNotFoundException("Entity not found")
raise almanach_entity_not_found_exception.AlmanachEntityNotFoundException("Entity not found")
return self.database_adapter.get_all_entities_by_id(entity_id=entity_id)
def attach_volume(self, volume_id, date, attachments):
@ -147,7 +149,8 @@ class Controller(object):
volume_type_name = self._get_volume_type_name(volume_type)
entity = Volume(volume_id, project_id, start, None, volume_type_name, size, start, volume_name, attached_to)
entity = model.Volume(volume_id, project_id, start, None, volume_type_name, size, start, volume_name,
attached_to)
self.database_adapter.insert_entity(entity)
def detach_volume(self, volume_id, date, attachments):
@ -202,17 +205,17 @@ class Controller(object):
def create_volume_type(self, volume_type_id, volume_type_name):
logging.info("volume type %s with name %s created" % (volume_type_id, volume_type_name))
volume_type = VolumeType(volume_type_id, volume_type_name)
volume_type = model.VolumeType(volume_type_id, volume_type_name)
self.database_adapter.insert_volume_type(volume_type)
def list_entities(self, project_id, start, end):
return self.database_adapter.list_entities(project_id, start, end)
def list_instances(self, project_id, start, end):
return self.database_adapter.list_entities(project_id, start, end, Instance.TYPE)
return self.database_adapter.list_entities(project_id, start, end, model.Instance.TYPE)
def list_volumes(self, project_id, start, end):
return self.database_adapter.list_entities(project_id, start, end, Volume.TYPE)
return self.database_adapter.list_entities(project_id, start, end, model.Volume.TYPE)
def get_volume_type(self, type_id):
return self.database_adapter.get_volume_type(type_id)
@ -297,7 +300,7 @@ class Controller(object):
date = date_parser.parse(date)
return self._localize_date(date)
except TypeError:
raise DateFormatException()
raise date_format_exception.DateFormatException()
@staticmethod
def _localize_date(date):

View File

@ -1,26 +1,39 @@
# Copyright 2016 Internap.
#
# 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 six
from voluptuous import Schema, MultipleInvalid, Datetime, Required
import voluptuous
from almanach.common.exceptions.validation_exception import InvalidAttributeException
from almanach.common.exceptions import validation_exception
class InstanceValidator(object):
def __init__(self):
self.schema = Schema({
self.schema = voluptuous.Schema({
'name': six.text_type,
'flavor': six.text_type,
'os': {
Required('distro'): six.text_type,
Required('version'): six.text_type,
Required('os_type'): six.text_type,
voluptuous.Required('distro'): six.text_type,
voluptuous.Required('version'): six.text_type,
voluptuous.Required('os_type'): six.text_type,
},
'metadata': dict,
'start_date': Datetime(),
'end_date': Datetime(),
'start_date': voluptuous.Datetime(),
'end_date': voluptuous.Datetime(),
})
def validate_update(self, payload):
try:
return self.schema(payload)
except MultipleInvalid as e:
raise InvalidAttributeException(e.errors)
except voluptuous.MultipleInvalid as e:
raise validation_exception.InvalidAttributeException(e.errors)

View File

@ -13,13 +13,15 @@
# limitations under the License.
import unittest
from retry import retry
from uuid import uuid4
from hamcrest import equal_to, assert_that, has_entry
from helpers.rabbit_mq_helper import RabbitMqHelper
from hamcrest import assert_that
from hamcrest import equal_to
from hamcrest import has_entry
from retry import retry
from helpers.almanach_helper import AlmanachHelper
from helpers.rabbit_mq_helper import RabbitMqHelper
class BaseApiTestCase(unittest.TestCase):

View File

@ -18,7 +18,6 @@ from helpers.mongo_helper import MongoHelper
class BaseApiVolumeTestCase(BaseApiTestCase):
@classmethod
def setUpClass(cls):
cls.setup_volume_type()
@ -30,7 +29,7 @@ class BaseApiVolumeTestCase(BaseApiTestCase):
@classmethod
def setup_volume_type(cls):
cls.rabbitMqHelper.push(
message=messages.get_volume_type_create_sample(volume_type_id=messages.DEFAULT_VOLUME_TYPE,
volume_type_name=messages.DEFAULT_VOLUME_TYPE),
message=messages.get_volume_type_create_sample(volume_type_id=messages.DEFAULT_VOLUME_TYPE,
volume_type_name=messages.DEFAULT_VOLUME_TYPE),
)
cls._wait_until_volume_type_is_created(volume_type_id=messages.DEFAULT_VOLUME_TYPE)

View File

@ -12,11 +12,12 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from datetime import datetime, timedelta
import dateutil.parser
import pytz
from datetime import datetime
from datetime import timedelta
import dateutil.parser
DEFAULT_VOLUME_TYPE = "my_block_storage_type"
DEFAULT_VOLUME_NAME = "my_block_storage_name"

View File

@ -15,9 +15,9 @@
import os
from kombu import BrokerConnection
from kombu.common import maybe_declare
from kombu import Exchange
from kombu.pools import producers
from kombu.common import maybe_declare
class RabbitMqHelper(object):

View File

@ -12,7 +12,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from hamcrest import assert_that, equal_to
from hamcrest import assert_that
from hamcrest import equal_to
from base_api_testcase import BaseApiTestCase

View File

@ -1,4 +1,19 @@
from hamcrest import assert_that, equal_to
# Copyright 2016 Internap.
#
# 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 hamcrest import assert_that
from hamcrest import equal_to
from base_api_testcase import BaseApiTestCase

View File

@ -13,13 +13,16 @@
# limitations under the License.
from uuid import uuid4
from hamcrest import assert_that, equal_to, has_item, has_entry
from hamcrest import assert_that
from hamcrest import equal_to
from hamcrest import has_entry
from hamcrest import has_item
from base_api_testcase import BaseApiTestCase
class ApiInstanceCreateTest(BaseApiTestCase):
def test_instance_create(self):
instance_create_query = "{url}/project/{project}/instance"
project_id = "my_test_project_id"
@ -71,9 +74,9 @@ class ApiInstanceCreateTest(BaseApiTestCase):
assert_that(response.status_code, equal_to(400))
assert_that(response.json(), has_entry(
'error',
'The provided date has an invalid format. Format should be of yyyy-mm-ddThh:mm:ss.msZ, '
'ex: 2015-01-31T18:24:34.1523Z'
'error',
'The provided date has an invalid format. Format should be of yyyy-mm-ddThh:mm:ss.msZ, '
'ex: 2015-01-31T18:24:34.1523Z'
))
def test_instance_create_missing_flavor_param(self):
@ -91,21 +94,21 @@ class ApiInstanceCreateTest(BaseApiTestCase):
assert_that(response.status_code, equal_to(400))
assert_that(response.json(), has_entry(
"error",
"The 'flavor' param is mandatory for the request you have made."
"error",
"The 'flavor' param is mandatory for the request you have made."
))
def test_instance_create_missing_type_name_param(self):
volume_type_query = "{url}/volume_type"
volume_type_id = str(uuid4())
data = dict(
type_id=volume_type_id
type_id=volume_type_id
)
response = self.almanachHelper.post(url=volume_type_query, data=data)
assert_that(response.status_code, equal_to(400))
assert_that(response.json(), has_entry(
"error",
"The 'type_name' param is mandatory for the request you have made."
"error",
"The 'type_name' param is mandatory for the request you have made."
))

View File

@ -13,13 +13,16 @@
# limitations under the License.
from uuid import uuid4
from hamcrest import assert_that, equal_to, has_item, has_entry
from hamcrest import assert_that
from hamcrest import equal_to
from hamcrest import has_entry
from hamcrest import has_item
from base_api_testcase import BaseApiTestCase
class ApiInstanceDelete(BaseApiTestCase):
def test_instance_delete(self):
instance_create_query = "{url}/project/{project}/instance"
project_id = "my_test_project_id"
@ -83,9 +86,9 @@ class ApiInstanceDelete(BaseApiTestCase):
response = self.almanachHelper.delete(url=instance_delete_query, data=delete_data, instance_id=instance_id)
assert_that(response.status_code, equal_to(400))
assert_that(response.json(), has_entry(
'error',
'The provided date has an invalid format. Format should be of yyyy-mm-ddThh:mm:ss.msZ, '
'ex: 2015-01-31T18:24:34.1523Z'
'error',
'The provided date has an invalid format. Format should be of yyyy-mm-ddThh:mm:ss.msZ, '
'ex: 2015-01-31T18:24:34.1523Z'
))
def test_instance_delete_missing_param(self):
@ -94,6 +97,6 @@ class ApiInstanceDelete(BaseApiTestCase):
response = self.almanachHelper.delete(url=instance_delete_query, data=dict(), instance_id="my_instance_id")
assert_that(response.status_code, equal_to(400))
assert_that(response.json(), has_entry(
"error",
"The 'date' param is mandatory for the request you have made."
"error",
"The 'date' param is mandatory for the request you have made."
))

View File

@ -13,7 +13,10 @@
# limitations under the License.
from uuid import uuid4
from hamcrest import assert_that, has_entry, equal_to
from hamcrest import assert_that
from hamcrest import equal_to
from hamcrest import has_entry
from base_api_testcase import BaseApiTestCase
@ -92,7 +95,7 @@ class ApiInstanceEntityTest(BaseApiTestCase):
assert_that(response.status_code, equal_to(400))
assert_that(response.json(), equal_to(
{"error": {"start_date": "value does not match expected format %Y-%m-%dT%H:%M:%S.%fZ"}}
{"error": {"start_date": "value does not match expected format %Y-%m-%dT%H:%M:%S.%fZ"}}
))
def test_update_entity_change_flavor_of_closed(self):

View File

@ -13,13 +13,16 @@
# limitations under the License.
from uuid import uuid4
from hamcrest import assert_that, equal_to, has_item, has_entry
from hamcrest import assert_that
from hamcrest import equal_to
from hamcrest import has_entry
from hamcrest import has_item
from base_api_testcase import BaseApiTestCase
class ApiInstanceRebuildTest(BaseApiTestCase):
def test_instance_rebuild(self):
instance_create_query = "{url}/project/{project}/instance"
project_id = "my_test_project_id"
@ -82,9 +85,9 @@ class ApiInstanceRebuildTest(BaseApiTestCase):
instance_id=instance_id)
assert_that(response.status_code, equal_to(400))
assert_that(response.json(), has_entry(
'error',
'The provided date has an invalid format. Format should be of yyyy-mm-ddThh:mm:ss.msZ, '
'ex: 2015-01-31T18:24:34.1523Z'
'error',
'The provided date has an invalid format. Format should be of yyyy-mm-ddThh:mm:ss.msZ, '
'ex: 2015-01-31T18:24:34.1523Z'
))
def test_instance_rebuild_missing_param(self):
@ -100,6 +103,6 @@ class ApiInstanceRebuildTest(BaseApiTestCase):
instance_id=instance_id)
assert_that(response.status_code, equal_to(400))
assert_that(response.json(), has_entry(
"error",
"The 'version' param is mandatory for the request you have made."
"error",
"The 'version' param is mandatory for the request you have made."
))

View File

@ -13,13 +13,16 @@
# limitations under the License.
from uuid import uuid4
from hamcrest import assert_that, equal_to, has_item, has_entry
from hamcrest import assert_that
from hamcrest import equal_to
from hamcrest import has_entry
from hamcrest import has_item
from base_api_testcase import BaseApiTestCase
class ApiInstanceDelete(BaseApiTestCase):
def test_instance_resize(self):
instance_create_query = "{url}/project/{project}/instance"
project_id = "my_test_project_id"
@ -72,9 +75,9 @@ class ApiInstanceDelete(BaseApiTestCase):
response = self.almanachHelper.put(url=instance_resize_query, data=resize_data, instance_id="my_instance_id")
assert_that(response.status_code, equal_to(400))
assert_that(response.json(), has_entry(
'error',
'The provided date has an invalid format. Format should be of yyyy-mm-ddThh:mm:ss.msZ, '
'ex: 2015-01-31T18:24:34.1523Z'
'error',
'The provided date has an invalid format. Format should be of yyyy-mm-ddThh:mm:ss.msZ, '
'ex: 2015-01-31T18:24:34.1523Z'
))
def test_instance_resize_missing_param(self):
@ -84,6 +87,6 @@ class ApiInstanceDelete(BaseApiTestCase):
response = self.almanachHelper.put(url=instance_resize_query, data=resize_data, instance_id="my_instance_id")
assert_that(response.status_code, equal_to(400))
assert_that(response.json(), has_entry(
"error",
"The 'date' param is mandatory for the request you have made."
"error",
"The 'date' param is mandatory for the request you have made."
))

View File

@ -13,14 +13,17 @@
# limitations under the License.
from uuid import uuid4
from hamcrest import equal_to, assert_that, has_entry, has_item
from hamcrest import assert_that
from hamcrest import equal_to
from hamcrest import has_entry
from hamcrest import has_item
from base_api_volume_testcase import BaseApiVolumeTestCase
from builders import messages
class ApiVolumeTest(BaseApiVolumeTestCase):
def test_volume_attach(self):
instance_create_query = "{url}/project/{project}/instance"
project_id = "my_test_project_id"
@ -80,9 +83,9 @@ class ApiVolumeTest(BaseApiVolumeTestCase):
response = self.almanachHelper.put(url=volume_attach_query, data=attach_data)
assert_that(response.status_code, equal_to(400))
assert_that(response.json(), has_entry(
'error',
'The provided date has an invalid format. Format should be of yyyy-mm-ddThh:mm:ss.msZ, '
'ex: 2015-01-31T18:24:34.1523Z'
'error',
'The provided date has an invalid format. Format should be of yyyy-mm-ddThh:mm:ss.msZ, '
'ex: 2015-01-31T18:24:34.1523Z'
))
def test_volume_attach_missing_param(self):
@ -92,6 +95,6 @@ class ApiVolumeTest(BaseApiVolumeTestCase):
response = self.almanachHelper.put(url=volume_attach_query, data=attach_data)
assert_that(response.status_code, equal_to(400))
assert_that(response.json(), has_entry(
"error",
"The 'date' param is mandatory for the request you have made."
"error",
"The 'date' param is mandatory for the request you have made."
))

View File

@ -13,14 +13,17 @@
# limitations under the License.
from uuid import uuid4
from hamcrest import equal_to, assert_that, has_entry, has_item
from hamcrest import assert_that
from hamcrest import equal_to
from hamcrest import has_entry
from hamcrest import has_item
from base_api_volume_testcase import BaseApiVolumeTestCase
from builders import messages
class ApiVolumeTest(BaseApiVolumeTestCase):
def test_volume_create(self):
volume_create_query = "{url}/project/{project}/volume"
project_id = "my_test_project_id"
@ -67,9 +70,9 @@ class ApiVolumeTest(BaseApiVolumeTestCase):
assert_that(response.status_code, equal_to(400))
assert_that(response.json(), has_entry(
'error',
'The provided date has an invalid format. Format should be of yyyy-mm-ddThh:mm:ss.msZ, '
'ex: 2015-01-31T18:24:34.1523Z'
'error',
'The provided date has an invalid format. Format should be of yyyy-mm-ddThh:mm:ss.msZ, '
'ex: 2015-01-31T18:24:34.1523Z'
))
def test_volume_create_missing_param(self):
@ -86,6 +89,6 @@ class ApiVolumeTest(BaseApiVolumeTestCase):
assert_that(response.status_code, equal_to(400))
assert_that(response.json(), has_entry(
"error",
"The 'start' param is mandatory for the request you have made."
"error",
"The 'start' param is mandatory for the request you have made."
))

View File

@ -13,14 +13,17 @@
# limitations under the License.
from uuid import uuid4
from hamcrest import equal_to, assert_that, has_entry, has_item
from hamcrest import assert_that
from hamcrest import equal_to
from hamcrest import has_entry
from hamcrest import has_item
from base_api_volume_testcase import BaseApiVolumeTestCase
from builders import messages
class ApiVolumeTest(BaseApiVolumeTestCase):
def test_volume_delete(self):
volume_create_query = "{url}/project/{project}/volume"
project_id = "my_test_project_id"
@ -63,9 +66,9 @@ class ApiVolumeTest(BaseApiVolumeTestCase):
response = self.almanachHelper.delete(url=volume_delete_query, data=delete_data, volume_id="my_test_volume_id")
assert_that(response.status_code, equal_to(400))
assert_that(response.json(), has_entry(
'error',
'The provided date has an invalid format. Format should be of yyyy-mm-ddThh:mm:ss.msZ, '
'ex: 2015-01-31T18:24:34.1523Z'
'error',
'The provided date has an invalid format. Format should be of yyyy-mm-ddThh:mm:ss.msZ, '
'ex: 2015-01-31T18:24:34.1523Z'
))
def test_volume_delete_missing_param(self):
@ -74,6 +77,6 @@ class ApiVolumeTest(BaseApiVolumeTestCase):
response = self.almanachHelper.delete(url=instance_delete_query, data=dict(), volume_id="my_test_volume_id")
assert_that(response.status_code, equal_to(400))
assert_that(response.json(), has_entry(
"error",
"The 'date' param is mandatory for the request you have made."
"error",
"The 'date' param is mandatory for the request you have made."
))

View File

@ -13,14 +13,17 @@
# limitations under the License.
from uuid import uuid4
from hamcrest import equal_to, assert_that, has_entry, has_item
from hamcrest import assert_that
from hamcrest import equal_to
from hamcrest import has_entry
from hamcrest import has_item
from base_api_volume_testcase import BaseApiVolumeTestCase
from builders import messages
class ApiVolumeTest(BaseApiVolumeTestCase):
def test_volume_detach(self):
instance_create_query = "{url}/project/{project}/instance"
project_id = "my_test_project_id"
@ -82,9 +85,9 @@ class ApiVolumeTest(BaseApiVolumeTestCase):
response = self.almanachHelper.put(url=volume_detach_query, data=attach_data)
assert_that(response.status_code, equal_to(400))
assert_that(response.json(), has_entry(
'error',
'The provided date has an invalid format. Format should be of yyyy-mm-ddThh:mm:ss.msZ, '
'ex: 2015-01-31T18:24:34.1523Z'
'error',
'The provided date has an invalid format. Format should be of yyyy-mm-ddThh:mm:ss.msZ, '
'ex: 2015-01-31T18:24:34.1523Z'
))
def test_volume_detach_missing_param(self):
@ -94,6 +97,6 @@ class ApiVolumeTest(BaseApiVolumeTestCase):
response = self.almanachHelper.put(url=volume_detach_query, data=attach_data)
assert_that(response.status_code, equal_to(400))
assert_that(response.json(), has_entry(
"error",
"The 'date' param is mandatory for the request you have made."
"error",
"The 'date' param is mandatory for the request you have made."
))

View File

@ -13,14 +13,17 @@
# limitations under the License.
from uuid import uuid4
from hamcrest import equal_to, assert_that, has_entry, has_item
from hamcrest import assert_that
from hamcrest import equal_to
from hamcrest import has_entry
from hamcrest import has_item
from base_api_volume_testcase import BaseApiVolumeTestCase
from builders import messages
class ApiVolumeTest(BaseApiVolumeTestCase):
def test_volume_resize(self):
volume_create_query = "{url}/project/{project}/volume"
project_id = "my_test_project_id"
@ -68,9 +71,9 @@ class ApiVolumeTest(BaseApiVolumeTestCase):
response = self.almanachHelper.put(url=volume_resize_query, data=resize_data)
assert_that(response.status_code, equal_to(400))
assert_that(response.json(), has_entry(
'error',
'The provided date has an invalid format. Format should be of yyyy-mm-ddThh:mm:ss.msZ, '
'ex: 2015-01-31T18:24:34.1523Z'
'error',
'The provided date has an invalid format. Format should be of yyyy-mm-ddThh:mm:ss.msZ, '
'ex: 2015-01-31T18:24:34.1523Z'
))
def test_volume_resize_missing_param(self):
@ -80,6 +83,6 @@ class ApiVolumeTest(BaseApiVolumeTestCase):
response = self.almanachHelper.put(url=volume_resize_query, data=resize_data, instance_id="my_instance_id")
assert_that(response.status_code, equal_to(400))
assert_that(response.json(), has_entry(
"error",
"The 'date' param is mandatory for the request you have made."
"error",
"The 'date' param is mandatory for the request you have made."
))

View File

@ -13,7 +13,9 @@
# limitations under the License.
from uuid import uuid4
from hamcrest import assert_that, equal_to
from hamcrest import assert_that
from hamcrest import equal_to
from base_api_volume_testcase import BaseApiVolumeTestCase
from builders import messages
@ -24,8 +26,8 @@ class ApiVolumeTypeTest(BaseApiVolumeTestCase):
volume_type_query = "{url}/volume_type"
volume_type_id = str(uuid4())
data = dict(
type_id=volume_type_id,
type_name=messages.DEFAULT_VOLUME_NAME
type_id=volume_type_id,
type_name=messages.DEFAULT_VOLUME_NAME
)
response = self.almanachHelper.post(url=volume_type_query, data=data)

View File

@ -12,12 +12,14 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from uuid import uuid4
from datetime import datetime
from retry import retry
from uuid import uuid4
from hamcrest import assert_that
from hamcrest import equal_to
from hamcrest import has_entry
import pytz
from hamcrest import assert_that, equal_to, has_entry
from base_api_testcase import BaseApiTestCase
from builders.messages import get_instance_create_end_sample
@ -30,9 +32,9 @@ class CollectorInstanceCreateTest(BaseApiTestCase):
self.rabbitMqHelper.push(
get_instance_create_end_sample(
instance_id=instance_id,
tenant_id=tenant_id,
creation_timestamp=datetime(2016, 2, 1, 9, 0, 0, tzinfo=pytz.utc)
instance_id=instance_id,
tenant_id=tenant_id,
creation_timestamp=datetime(2016, 2, 1, 9, 0, 0, tzinfo=pytz.utc)
))
self.assert_that_instance_entity_is_created(instance_id, tenant_id)

View File

@ -12,14 +12,19 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import pytz
import uuid
from datetime import datetime
from hamcrest import has_entry, is_not, assert_that, equal_to
import uuid
from hamcrest import assert_that
from hamcrest import equal_to
from hamcrest import has_entry
from hamcrest import is_not
import pytz
from retry import retry
from base_api_testcase import BaseApiTestCase
from builders.messages import get_instance_delete_end_sample, get_instance_create_end_sample
from builders.messages import get_instance_create_end_sample
from builders.messages import get_instance_delete_end_sample
class CollectorInstanceDeleteTest(BaseApiTestCase):
@ -28,18 +33,18 @@ class CollectorInstanceDeleteTest(BaseApiTestCase):
instance_id = str(uuid.uuid4())
self.rabbitMqHelper.push(
get_instance_create_end_sample(
instance_id=instance_id,
tenant_id=tenant_id,
creation_timestamp=datetime(2016, 2, 1, 9, 0, 0, tzinfo=pytz.utc)
))
get_instance_create_end_sample(
instance_id=instance_id,
tenant_id=tenant_id,
creation_timestamp=datetime(2016, 2, 1, 9, 0, 0, tzinfo=pytz.utc)
))
self.rabbitMqHelper.push(
get_instance_delete_end_sample(
instance_id=instance_id,
tenant_id=tenant_id,
deletion_timestamp=datetime(2016, 2, 1, 10, 0, 0, tzinfo=pytz.utc)
))
get_instance_delete_end_sample(
instance_id=instance_id,
tenant_id=tenant_id,
deletion_timestamp=datetime(2016, 2, 1, 10, 0, 0, tzinfo=pytz.utc)
))
self.assert_instance_entity_is_closed(tenant_id)

View File

@ -12,14 +12,18 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import pytz
import uuid
from datetime import datetime
from hamcrest import has_entry, is_not, assert_that
import uuid
from hamcrest import assert_that
from hamcrest import has_entry
from hamcrest import is_not
import pytz
from retry import retry
from base_api_testcase import BaseApiTestCase
from builders.messages import get_instance_delete_end_sample, get_instance_create_end_sample
from builders.messages import get_instance_create_end_sample
from builders.messages import get_instance_delete_end_sample
class CollectorInstanceDeleteBeforeCreateTest(BaseApiTestCase):
@ -28,18 +32,18 @@ class CollectorInstanceDeleteBeforeCreateTest(BaseApiTestCase):
instance_id = str(uuid.uuid4())
self.rabbitMqHelper.push(
get_instance_delete_end_sample(
instance_id=instance_id,
tenant_id=tenant_id,
deletion_timestamp=datetime(2016, 2, 1, 10, 0, 0, tzinfo=pytz.utc)
))
get_instance_delete_end_sample(
instance_id=instance_id,
tenant_id=tenant_id,
deletion_timestamp=datetime(2016, 2, 1, 10, 0, 0, tzinfo=pytz.utc)
))
self.rabbitMqHelper.push(
get_instance_create_end_sample(
instance_id=instance_id,
tenant_id=tenant_id,
creation_timestamp=datetime(2016, 2, 1, 9, 0, 0, tzinfo=pytz.utc)
))
get_instance_create_end_sample(
instance_id=instance_id,
tenant_id=tenant_id,
creation_timestamp=datetime(2016, 2, 1, 9, 0, 0, tzinfo=pytz.utc)
))
self.assert_instance_delete_received_before_instance_create(tenant_id)

View File

@ -14,7 +14,9 @@
import uuid
from hamcrest import has_entry, assert_that, equal_to
from hamcrest import assert_that
from hamcrest import equal_to
from hamcrest import has_entry
from retry import retry
from base_api_volume_testcase import BaseApiVolumeTestCase
@ -28,10 +30,10 @@ class CollectorVolumeAttachTest(BaseApiVolumeTestCase):
volume_id = str(uuid.uuid4())
self.rabbitMqHelper.push(message=messages.get_volume_create_end_sample(
volume_id=volume_id, tenant_id=tenant_id, volume_type=messages.DEFAULT_VOLUME_TYPE))
volume_id=volume_id, tenant_id=tenant_id, volume_type=messages.DEFAULT_VOLUME_TYPE))
self.rabbitMqHelper.push(message=messages.get_volume_attach_kilo_end_sample(
volume_id=volume_id, tenant_id=tenant_id, attached_to=[instance_id]))
volume_id=volume_id, tenant_id=tenant_id, attached_to=[instance_id]))
self.assert_that_volume_entity_has_instance_attached(tenant_id, instance_id)

View File

@ -14,7 +14,9 @@
import uuid
from hamcrest import has_entry, assert_that, equal_to
from hamcrest import assert_that
from hamcrest import equal_to
from hamcrest import has_entry
from retry import retry
from base_api_volume_testcase import BaseApiVolumeTestCase
@ -27,7 +29,7 @@ class CollectorVolumeCreateTest(BaseApiVolumeTestCase):
volume_id = str(uuid.uuid4())
self.rabbitMqHelper.push(message=messages.get_volume_create_end_sample(
volume_id=volume_id, tenant_id=tenant_id, volume_type=messages.DEFAULT_VOLUME_TYPE))
volume_id=volume_id, tenant_id=tenant_id, volume_type=messages.DEFAULT_VOLUME_TYPE))
self.assert_that_volume_entity_is_created(tenant_id)

View File

@ -12,11 +12,14 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from datetime import datetime
import uuid
from hamcrest import assert_that
from hamcrest import equal_to
from hamcrest import has_entry
from hamcrest import is_not
import pytz
from datetime import datetime
from hamcrest import has_entry, assert_that, equal_to, is_not
from retry import retry
from base_api_volume_testcase import BaseApiVolumeTestCase

View File

@ -14,7 +14,9 @@
import uuid
from hamcrest import has_entry, assert_that, equal_to
from hamcrest import assert_that
from hamcrest import equal_to
from hamcrest import has_entry
from retry import retry
from base_api_volume_testcase import BaseApiVolumeTestCase
@ -28,13 +30,13 @@ class CollectorVolumeDetachTest(BaseApiVolumeTestCase):
volume_id = str(uuid.uuid4())
self.rabbitMqHelper.push(message=messages.get_volume_create_end_sample(
volume_id=volume_id, tenant_id=tenant_id, volume_type=messages.DEFAULT_VOLUME_TYPE))
volume_id=volume_id, tenant_id=tenant_id, volume_type=messages.DEFAULT_VOLUME_TYPE))
self.rabbitMqHelper.push(message=messages.get_volume_attach_kilo_end_sample(
volume_id=volume_id, tenant_id=tenant_id, attached_to=[instance_id]))
volume_id=volume_id, tenant_id=tenant_id, attached_to=[instance_id]))
self.rabbitMqHelper.push(message=messages.get_volume_detach_kilo_end_sample(
volume_id=volume_id, tenant_id=tenant_id, attached_to=[instance_id]))
volume_id=volume_id, tenant_id=tenant_id, attached_to=[instance_id]))
self.assert_that_volume_entity_has_instance_detached(tenant_id)

View File

@ -14,7 +14,9 @@
import uuid
from hamcrest import has_entry, assert_that, equal_to
from hamcrest import assert_that
from hamcrest import equal_to
from hamcrest import has_entry
from retry import retry
from base_api_volume_testcase import BaseApiVolumeTestCase
@ -29,10 +31,10 @@ class CollectorVolumeMultiAttachTest(BaseApiVolumeTestCase):
volume_id = str(uuid.uuid4())
self.rabbitMqHelper.push(message=messages.get_volume_create_end_sample(
volume_id=volume_id, tenant_id=tenant_id, volume_type=messages.DEFAULT_VOLUME_TYPE))
volume_id=volume_id, tenant_id=tenant_id, volume_type=messages.DEFAULT_VOLUME_TYPE))
self.rabbitMqHelper.push(message=messages.get_volume_attach_kilo_end_sample(
volume_id=volume_id, tenant_id=tenant_id, attached_to=[instance_id1, instance_id2]))
volume_id=volume_id, tenant_id=tenant_id, attached_to=[instance_id1, instance_id2]))
self.assert_that_volume_entity_has_multiple_instances_attached(tenant_id, instance_id1, instance_id2)

View File

@ -14,7 +14,9 @@
import uuid
from hamcrest import has_entry, assert_that, equal_to
from hamcrest import assert_that
from hamcrest import equal_to
from hamcrest import has_entry
from retry import retry
from base_api_volume_testcase import BaseApiVolumeTestCase
@ -29,13 +31,13 @@ class CollectorVolumeMultiDetachTest(BaseApiVolumeTestCase):
volume_id = str(uuid.uuid4())
self.rabbitMqHelper.push(message=messages.get_volume_create_end_sample(
volume_id=volume_id, tenant_id=tenant_id, volume_type=messages.DEFAULT_VOLUME_TYPE))
volume_id=volume_id, tenant_id=tenant_id, volume_type=messages.DEFAULT_VOLUME_TYPE))
self.rabbitMqHelper.push(message=messages.get_volume_attach_kilo_end_sample(
volume_id=volume_id, tenant_id=tenant_id, attached_to=[instance_id1, instance_id2]))
volume_id=volume_id, tenant_id=tenant_id, attached_to=[instance_id1, instance_id2]))
self.rabbitMqHelper.push(message=messages.get_volume_attach_kilo_end_sample(
volume_id=volume_id, tenant_id=tenant_id, attached_to=[instance_id2]))
volume_id=volume_id, tenant_id=tenant_id, attached_to=[instance_id2]))
self.assert_that_volume_entity_has_only_one_instance_attached(tenant_id, instance_id2)

View File

@ -12,11 +12,14 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from datetime import datetime
import uuid
from hamcrest import assert_that
from hamcrest import equal_to
from hamcrest import has_entry
from hamcrest import is_not
import pytz
from datetime import datetime
from hamcrest import has_entry, assert_that, equal_to, is_not
from retry import retry
from base_api_volume_testcase import BaseApiVolumeTestCase

View File

@ -13,7 +13,9 @@
# limitations under the License.
from uuid import uuid4
from hamcrest import assert_that, equal_to
from hamcrest import assert_that
from hamcrest import equal_to
from base_api_volume_testcase import BaseApiVolumeTestCase
from builders import messages
@ -25,7 +27,7 @@ class ApiVolumeTypeTest(BaseApiVolumeTestCase):
volume_type_name = str(uuid4())
self.rabbitMqHelper.push(message=messages.get_volume_type_create_sample(
volume_type_id=volume_type_id, volume_type_name=volume_type_name)
volume_type_id=volume_type_id, volume_type_name=volume_type_name)
)
self._wait_until_volume_type_is_created(volume_type_id=volume_type_id)

View File

@ -1,10 +1,27 @@
from uuid import uuid4
# Copyright 2016 Internap.
#
# 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 datetime import datetime
from hamcrest import assert_that, has_entry
from uuid import uuid4
from hamcrest import assert_that
from hamcrest import equal_to
from hamcrest import has_entry
import pytz
from integration_tests.base_api_testcase import BaseApiTestCase
from integration_tests.builders.messages import get_instance_create_end_sample
import pytz
class MetadataInstanceCreateTest(BaseApiTestCase):

View File

@ -9,3 +9,4 @@ mongomock==2.0.0
PyHamcrest==1.8.5
sphinx>=1.2.1,!=1.3b1,<1.3 # BSD
flake8>=2.5.4,<2.6.0 # MIT
hacking<0.12,>=0.11.0 # Apache-2.0

View File

@ -14,14 +14,16 @@
import unittest
from flexmock import flexmock, flexmock_teardown
from hamcrest import instance_of, assert_that
from flexmock import flexmock
from flexmock import flexmock_teardown
from hamcrest import assert_that
from hamcrest import instance_of
from almanach import config
from almanach.adapters.auth_adapter import AuthenticationAdapter
from almanach.auth.keystone_auth import KeystoneAuthentication
from almanach.auth.mixed_auth import MixedAuthentication
from almanach.auth.private_key_auth import PrivateKeyAuthentication
from almanach import config
class AuthenticationAdapterTest(unittest.TestCase):

View File

@ -12,10 +12,12 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import pytz
import unittest
from datetime import datetime
from flexmock import flexmock, flexmock_teardown
import unittest
from flexmock import flexmock
from flexmock import flexmock_teardown
import pytz
from almanach.adapters.bus_adapter import BusAdapter
from almanach.common.exceptions.almanach_entity_not_found_exception import AlmanachEntityNotFoundException

View File

@ -12,23 +12,27 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import unittest
from datetime import datetime
import pkg_resources
import mongomock
from flexmock import flexmock, flexmock_teardown
from hamcrest import assert_that, contains_inanyorder
import unittest
from flexmock import flexmock
from flexmock import flexmock_teardown
from hamcrest import assert_that
from hamcrest import contains_inanyorder
import mongomock
from pymongo import MongoClient
import pytz
from almanach.adapters.database_adapter import DatabaseAdapter
from almanach.common.exceptions.volume_type_not_found_exception import VolumeTypeNotFoundException
from almanach.common.exceptions.almanach_exception import AlmanachException
from almanach.common.exceptions.volume_type_not_found_exception import VolumeTypeNotFoundException
from almanach import config
from almanach.core.model import todict
from tests.builder import a, instance, volume, volume_type
from tests.builder import a
from tests.builder import instance
from tests.builder import volume
from tests.builder import volume_type
class DatabaseAdapterTest(unittest.TestCase):
@ -257,8 +261,8 @@ class DatabaseAdapterTest(unittest.TestCase):
self.adapter.update_active_entity(fake_entity)
self.assertEqual(self.db.entity.find_one({"entity_id": fake_entity.entity_id})[
"os"]["distro"], fake_entity.os.distro)
self.assertEqual(self.db.entity.find_one({"entity_id": fake_entity.entity_id})["os"]["distro"],
fake_entity.os.distro)
def test_insert_volume(self):
count = self.db.entity.count()

View File

@ -14,7 +14,8 @@
import unittest
from flexmock import flexmock, flexmock_teardown
from flexmock import flexmock
from flexmock import flexmock_teardown
from almanach.adapters.instance_bus_adapter import InstanceBusAdapter
from integration_tests.builders import messages

View File

@ -14,13 +14,14 @@
import unittest
from flexmock import flexmock
from flexmock import flexmock_teardown
from kombu import Connection
from kombu.tests import mocks
from kombu.transport import pyamqp
from flexmock import flexmock, flexmock_teardown
from almanach import config
from almanach.adapters.retry_adapter import RetryAdapter
from almanach import config
class BusAdapterTest(unittest.TestCase):

View File

@ -12,19 +12,18 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from datetime import datetime
import unittest
from datetime import datetime
from flexmock import flexmock
from flexmock import flexmock_teardown
import pytz
from flexmock import flexmock, flexmock_teardown
from almanach.adapters.volume_bus_adapter import VolumeBusAdapter
from integration_tests.builders import messages
class VolumeBusAdapterTest(unittest.TestCase):
def setUp(self):
self.controller = flexmock()
self.retry = flexmock()
@ -53,9 +52,9 @@ class VolumeBusAdapterTest(unittest.TestCase):
def test_attach_volume_with_kilo_payload_and_empty_attachments(self):
notification = messages.get_volume_attach_kilo_end_sample(
volume_id="my-volume-id",
timestamp=datetime(2014, 2, 14, 17, 18, 35, tzinfo=pytz.utc),
attached_to=[]
volume_id="my-volume-id",
timestamp=datetime(2014, 2, 14, 17, 18, 35, tzinfo=pytz.utc),
attached_to=[]
)
self.controller \
@ -91,8 +90,8 @@ class VolumeBusAdapterTest(unittest.TestCase):
def test_attach_volume_with_icehouse_payload(self):
notification = messages.get_volume_attach_icehouse_end_sample(
volume_id="my-volume-id",
creation_timestamp=datetime(2014, 2, 14, 17, 18, 35, tzinfo=pytz.utc), attached_to="my-instance-id"
volume_id="my-volume-id",
creation_timestamp=datetime(2014, 2, 14, 17, 18, 35, tzinfo=pytz.utc), attached_to="my-instance-id"
)
self.controller \
@ -104,9 +103,9 @@ class VolumeBusAdapterTest(unittest.TestCase):
def test_attach_volume_with_kilo_payload(self):
notification = messages.get_volume_attach_kilo_end_sample(
volume_id="my-volume-id",
timestamp=datetime(2014, 2, 14, 17, 18, 35, tzinfo=pytz.utc),
attached_to=["I1"]
volume_id="my-volume-id",
timestamp=datetime(2014, 2, 14, 17, 18, 35, tzinfo=pytz.utc),
attached_to=["I1"]
)
self.controller \
@ -121,13 +120,13 @@ class VolumeBusAdapterTest(unittest.TestCase):
self.assertEqual([], self.volume_bus_adapter._get_attached_instances({"instance_uuid": None}))
self.assertEqual([], self.volume_bus_adapter._get_attached_instances({}))
self.assertEqual(
["a", "b"],
self.volume_bus_adapter._get_attached_instances(
{"volume_attachment": [{"instance_uuid": "a"}, {"instance_uuid": "b"}]}
)
["a", "b"],
self.volume_bus_adapter._get_attached_instances(
{"volume_attachment": [{"instance_uuid": "a"}, {"instance_uuid": "b"}]}
)
)
self.assertEqual(
["a"],
self.volume_bus_adapter._get_attached_instances({"volume_attachment": [{"instance_uuid": "a"}]})
["a"],
self.volume_bus_adapter._get_attached_instances({"volume_attachment": [{"instance_uuid": "a"}]})
)
self.assertEqual([], self.volume_bus_adapter._get_attached_instances({"volume_attachment": []}))

View File

@ -12,17 +12,18 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import json
import flask
from unittest import TestCase
from datetime import datetime
from flexmock import flexmock, flexmock_teardown
import json
from unittest import TestCase
import flask
from flexmock import flexmock
from flexmock import flexmock_teardown
import oslo_serialization
from almanach import config
from almanach.adapters import api_route_v1 as api_route
from almanach.common.exceptions.authentication_failure_exception import AuthenticationFailureException
from almanach import config
class BaseApi(TestCase):

View File

@ -12,7 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from hamcrest import assert_that, equal_to
from hamcrest import assert_that
from hamcrest import equal_to
from tests.api.base_api import BaseApi

View File

@ -12,16 +12,20 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from hamcrest import assert_that, equal_to, has_entries, has_key, is_
from hamcrest import assert_that
from hamcrest import equal_to
from hamcrest import has_entries
from hamcrest import has_key
from hamcrest import is_
from voluptuous import Invalid
from almanach.common.exceptions.validation_exception import InvalidAttributeException
from tests.builder import instance, a
from tests.api.base_api import BaseApi
from tests.builder import a
from tests.builder import instance
class ApiEntityTest(BaseApi):
def test_update_instance_entity_with_a_new_start_date(self):
data = {
"start_date": "2014-01-01 00:00:00.0000",
@ -29,14 +33,14 @@ class ApiEntityTest(BaseApi):
self.controller.should_receive('update_active_instance_entity') \
.with_args(
instance_id="INSTANCE_ID",
start_date=data["start_date"],
instance_id="INSTANCE_ID",
start_date=data["start_date"],
).and_return(a(instance().with_id('INSTANCE_ID').with_start(2014, 1, 1, 0, 0, 0)))
code, result = self.api_put(
'/entity/instance/INSTANCE_ID',
headers={'X-Auth-Token': 'some token value'},
data=data,
'/entity/instance/INSTANCE_ID',
headers={'X-Auth-Token': 'some token value'},
data=data,
)
assert_that(code, equal_to(200))
@ -67,9 +71,9 @@ class ApiEntityTest(BaseApi):
.and_raise(InvalidAttributeException(errors))
code, result = self.api_put(
'/entity/instance/INSTANCE_ID',
data=data,
headers={'X-Auth-Token': 'some token value'}
'/entity/instance/INSTANCE_ID',
data=data,
headers={'X-Auth-Token': 'some token value'}
)
assert_that(result, has_entries({
"error": formatted_errors

View File

@ -12,7 +12,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from hamcrest import assert_that, equal_to, has_key
from hamcrest import assert_that
from hamcrest import equal_to
from hamcrest import has_key
from tests.api.base_api import BaseApi

View File

@ -12,15 +12,21 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from hamcrest import assert_that, equal_to, has_key, has_length, has_entries, is_
from hamcrest import assert_that
from hamcrest import equal_to
from hamcrest import has_entries
from hamcrest import has_key
from hamcrest import has_length
from hamcrest import is_
from almanach.common.exceptions.date_format_exception import DateFormatException
from tests.builder import instance, a
from tests.api.base_api import BaseApi, a_date_matching
from tests.api.base_api import a_date_matching
from tests.api.base_api import BaseApi
from tests.builder import a
from tests.builder import instance
class ApiInstanceTest(BaseApi):
def test_get_instances(self):
self.controller.should_receive('list_instances') \
.with_args('TENANT_ID', a_date_matching("2014-01-01 00:00:00.0000"),
@ -47,26 +53,26 @@ class ApiInstanceTest(BaseApi):
self.controller.should_receive('update_inactive_entity') \
.with_args(
instance_id="INSTANCE_ID",
start=a_date_matching(start),
end=a_date_matching(end),
flavor=some_new_flavor,
instance_id="INSTANCE_ID",
start=a_date_matching(start),
end=a_date_matching(end),
flavor=some_new_flavor,
).and_return(a(
instance().
with_id('INSTANCE_ID').
with_start(2016, 3, 1, 0, 0, 0).
with_end(2016, 3, 3, 0, 0, 0).
with_flavor(some_new_flavor))
instance().
with_id('INSTANCE_ID').
with_start(2016, 3, 1, 0, 0, 0).
with_end(2016, 3, 3, 0, 0, 0).
with_flavor(some_new_flavor))
)
code, result = self.api_put(
'/entity/instance/INSTANCE_ID',
headers={'X-Auth-Token': 'some token value'},
query_string={
'start': start,
'end': end,
},
data=data,
'/entity/instance/INSTANCE_ID',
headers={'X-Auth-Token': 'some token value'},
query_string={
'start': start,
'end': end,
},
data=data,
)
assert_that(code, equal_to(200))
assert_that(result, has_key('entity_id'))
@ -96,9 +102,9 @@ class ApiInstanceTest(BaseApi):
.once()
code, result = self.api_post(
'/project/PROJECT_ID/instance',
data=data,
headers={'X-Auth-Token': 'some token value'}
'/project/PROJECT_ID/instance',
data=data,
headers={'X-Auth-Token': 'some token value'}
)
assert_that(code, equal_to(201))
@ -115,9 +121,9 @@ class ApiInstanceTest(BaseApi):
.never()
code, result = self.api_post(
'/project/PROJECT_ID/instance',
data=data,
headers={'X-Auth-Token': 'some token value'}
'/project/PROJECT_ID/instance',
data=data,
headers={'X-Auth-Token': 'some token value'}
)
assert_that(result, has_entries({"error": "The 'os_distro' param is mandatory for the request you have made."}))
assert_that(code, equal_to(400))
@ -146,15 +152,15 @@ class ApiInstanceTest(BaseApi):
.and_raise(DateFormatException)
code, result = self.api_post(
'/project/PROJECT_ID/instance',
data=data,
headers={'X-Auth-Token': 'some token value'}
'/project/PROJECT_ID/instance',
data=data,
headers={'X-Auth-Token': 'some token value'}
)
assert_that(result, has_entries(
{
"error": "The provided date has an invalid format. "
"Format should be of yyyy-mm-ddThh:mm:ss.msZ, ex: 2015-01-31T18:24:34.1523Z"
}
{
"error": "The provided date has an invalid format. "
"Format should be of yyyy-mm-ddThh:mm:ss.msZ, ex: 2015-01-31T18:24:34.1523Z"
}
))
assert_that(code, equal_to(400))
@ -169,9 +175,9 @@ class ApiInstanceTest(BaseApi):
.once()
code, result = self.api_put(
'/instance/INSTANCE_ID/resize',
data=data,
headers={'X-Auth-Token': 'some token value'}
'/instance/INSTANCE_ID/resize',
data=data,
headers={'X-Auth-Token': 'some token value'}
)
assert_that(code, equal_to(200))
@ -191,9 +197,9 @@ class ApiInstanceTest(BaseApi):
.never()
code, result = self.api_delete(
'/instance/INSTANCE_ID',
data=dict(),
headers={'X-Auth-Token': 'some token value'}
'/instance/INSTANCE_ID',
data=dict(),
headers={'X-Auth-Token': 'some token value'}
)
assert_that(result, has_entries({"error": "The 'date' param is mandatory for the request you have made."}))
assert_that(code, equal_to(400))
@ -217,10 +223,10 @@ class ApiInstanceTest(BaseApi):
code, result = self.api_delete('/instance/INSTANCE_ID', data=data, headers={'X-Auth-Token': 'some token value'})
assert_that(result, has_entries(
{
"error": "The provided date has an invalid format. "
"Format should be of yyyy-mm-ddThh:mm:ss.msZ, ex: 2015-01-31T18:24:34.1523Z"
}
{
"error": "The provided date has an invalid format. "
"Format should be of yyyy-mm-ddThh:mm:ss.msZ, ex: 2015-01-31T18:24:34.1523Z"
}
))
assert_that(code, equal_to(400))
@ -231,9 +237,9 @@ class ApiInstanceTest(BaseApi):
.never()
code, result = self.api_put(
'/instance/INSTANCE_ID/resize',
data=data,
headers={'X-Auth-Token': 'some token value'}
'/instance/INSTANCE_ID/resize',
data=data,
headers={'X-Auth-Token': 'some token value'}
)
assert_that(result, has_entries({"error": "The 'flavor' param is mandatory for the request you have made."}))
assert_that(code, equal_to(400))
@ -250,15 +256,15 @@ class ApiInstanceTest(BaseApi):
.and_raise(DateFormatException)
code, result = self.api_put(
'/instance/INSTANCE_ID/resize',
data=data,
headers={'X-Auth-Token': 'some token value'}
'/instance/INSTANCE_ID/resize',
data=data,
headers={'X-Auth-Token': 'some token value'}
)
assert_that(result, has_entries(
{
"error": "The provided date has an invalid format. "
"Format should be of yyyy-mm-ddThh:mm:ss.msZ, ex: 2015-01-31T18:24:34.1523Z"
}
{
"error": "The provided date has an invalid format. "
"Format should be of yyyy-mm-ddThh:mm:ss.msZ, ex: 2015-01-31T18:24:34.1523Z"
}
))
assert_that(code, equal_to(400))
@ -272,17 +278,17 @@ class ApiInstanceTest(BaseApi):
}
self.controller.should_receive('rebuild_instance') \
.with_args(
instance_id=instance_id,
distro=data.get('distro'),
version=data.get('version'),
os_type=data.get('os_type'),
rebuild_date=data.get('rebuild_date')) \
instance_id=instance_id,
distro=data.get('distro'),
version=data.get('version'),
os_type=data.get('os_type'),
rebuild_date=data.get('rebuild_date')) \
.once()
code, result = self.api_put(
'/instance/INSTANCE_ID/rebuild',
data=data,
headers={'X-Auth-Token': 'some token value'}
'/instance/INSTANCE_ID/rebuild',
data=data,
headers={'X-Auth-Token': 'some token value'}
)
assert_that(code, equal_to(200))
@ -297,9 +303,9 @@ class ApiInstanceTest(BaseApi):
.never()
code, result = self.api_put(
'/instance/INSTANCE_ID/rebuild',
data=data,
headers={'X-Auth-Token': 'some token value'}
'/instance/INSTANCE_ID/rebuild',
data=data,
headers={'X-Auth-Token': 'some token value'}
)
assert_that(result, has_entries({"error": "The 'version' param is mandatory for the request you have made."}))
assert_that(code, equal_to(400))
@ -319,13 +325,13 @@ class ApiInstanceTest(BaseApi):
.and_raise(DateFormatException)
code, result = self.api_put(
'/instance/INSTANCE_ID/rebuild',
data=data,
headers={'X-Auth-Token': 'some token value'}
'/instance/INSTANCE_ID/rebuild',
data=data,
headers={'X-Auth-Token': 'some token value'}
)
assert_that(result, has_entries(
{
"error": "The provided date has an invalid format. "
"Format should be of yyyy-mm-ddThh:mm:ss.msZ, ex: 2015-01-31T18:24:34.1523Z"
}
{
"error": "The provided date has an invalid format. "
"Format should be of yyyy-mm-ddThh:mm:ss.msZ, ex: 2015-01-31T18:24:34.1523Z"
}
))

View File

@ -13,14 +13,16 @@
# limitations under the License.
from uuid import uuid4
from hamcrest import assert_that, equal_to, has_entries
from hamcrest import assert_that
from hamcrest import equal_to
from hamcrest import has_entries
from almanach.common.exceptions.date_format_exception import DateFormatException
from tests.api.base_api import BaseApi
class ApiVolumeTest(BaseApi):
def test_successful_volume_create(self):
data = dict(volume_id="VOLUME_ID",
start="START_DATE",
@ -35,9 +37,9 @@ class ApiVolumeTest(BaseApi):
.once()
code, result = self.api_post(
'/project/PROJECT_ID/volume',
data=data,
headers={'X-Auth-Token': 'some token value'}
'/project/PROJECT_ID/volume',
data=data,
headers={'X-Auth-Token': 'some token value'}
)
assert_that(code, equal_to(201))
@ -52,13 +54,13 @@ class ApiVolumeTest(BaseApi):
.never()
code, result = self.api_post(
'/project/PROJECT_ID/volume',
data=data,
headers={'X-Auth-Token': 'some token value'}
'/project/PROJECT_ID/volume',
data=data,
headers={'X-Auth-Token': 'some token value'}
)
assert_that(
result,
has_entries({"error": "The 'volume_type' param is mandatory for the request you have made."})
result,
has_entries({"error": "The 'volume_type' param is mandatory for the request you have made."})
)
assert_that(code, equal_to(400))
@ -77,15 +79,15 @@ class ApiVolumeTest(BaseApi):
.and_raise(DateFormatException)
code, result = self.api_post(
'/project/PROJECT_ID/volume',
data=data,
headers={'X-Auth-Token': 'some token value'}
'/project/PROJECT_ID/volume',
data=data,
headers={'X-Auth-Token': 'some token value'}
)
assert_that(result, has_entries(
{
"error": "The provided date has an invalid format. "
"Format should be of yyyy-mm-ddThh:mm:ss.msZ, ex: 2015-01-31T18:24:34.1523Z"
}
{
"error": "The provided date has an invalid format. "
"Format should be of yyyy-mm-ddThh:mm:ss.msZ, ex: 2015-01-31T18:24:34.1523Z"
}
))
assert_that(code, equal_to(400))
@ -101,7 +103,6 @@ class ApiVolumeTest(BaseApi):
assert_that(code, equal_to(202))
def test_volume_delete_missing_a_param_returns_bad_request_code(self):
self.controller.should_receive('delete_volume') \
.never()
@ -128,10 +129,10 @@ class ApiVolumeTest(BaseApi):
code, result = self.api_delete('/volume/VOLUME_ID', data=data, headers={'X-Auth-Token': 'some token value'})
assert_that(result, has_entries(
{
"error": "The provided date has an invalid format. "
"Format should be of yyyy-mm-ddThh:mm:ss.msZ, ex: 2015-01-31T18:24:34.1523Z"
}
{
"error": "The provided date has an invalid format. "
"Format should be of yyyy-mm-ddThh:mm:ss.msZ, ex: 2015-01-31T18:24:34.1523Z"
}
))
assert_that(code, equal_to(400))
@ -171,10 +172,10 @@ class ApiVolumeTest(BaseApi):
code, result = self.api_put('/volume/VOLUME_ID/resize', data=data, headers={'X-Auth-Token': 'some token value'})
assert_that(result, has_entries(
{
"error": "The provided date has an invalid format. "
"Format should be of yyyy-mm-ddThh:mm:ss.msZ, ex: 2015-01-31T18:24:34.1523Z"
}
{
"error": "The provided date has an invalid format. "
"Format should be of yyyy-mm-ddThh:mm:ss.msZ, ex: 2015-01-31T18:24:34.1523Z"
}
))
assert_that(code, equal_to(400))
@ -198,13 +199,13 @@ class ApiVolumeTest(BaseApi):
.never()
code, result = self.api_put(
'/volume/VOLUME_ID/attach',
data=data,
headers={'X-Auth-Token': 'some token value'}
'/volume/VOLUME_ID/attach',
data=data,
headers={'X-Auth-Token': 'some token value'}
)
assert_that(
result,
has_entries({"error": "The 'attachments' param is mandatory for the request you have made."})
result,
has_entries({"error": "The 'attachments' param is mandatory for the request you have made."})
)
assert_that(code, equal_to(400))
@ -221,10 +222,10 @@ class ApiVolumeTest(BaseApi):
code, result = self.api_put('/volume/VOLUME_ID/attach', data=data, headers={'X-Auth-Token': 'some token value'})
assert_that(result, has_entries(
{
"error": "The provided date has an invalid format. "
"Format should be of yyyy-mm-ddThh:mm:ss.msZ, ex: 2015-01-31T18:24:34.1523Z"
}
{
"error": "The provided date has an invalid format. "
"Format should be of yyyy-mm-ddThh:mm:ss.msZ, ex: 2015-01-31T18:24:34.1523Z"
}
))
assert_that(code, equal_to(400))
@ -249,8 +250,8 @@ class ApiVolumeTest(BaseApi):
code, result = self.api_put('/volume/VOLUME_ID/detach', data=data, headers={'X-Auth-Token': 'some token value'})
assert_that(
result,
has_entries({"error": "The 'attachments' param is mandatory for the request you have made."})
result,
has_entries({"error": "The 'attachments' param is mandatory for the request you have made."})
)
assert_that(code, equal_to(400))
@ -267,9 +268,9 @@ class ApiVolumeTest(BaseApi):
code, result = self.api_put('/volume/VOLUME_ID/detach', data=data, headers={'X-Auth-Token': 'some token value'})
assert_that(result, has_entries(
{
"error": "The provided date has an invalid format. "
"Format should be of yyyy-mm-ddThh:mm:ss.msZ, ex: 2015-01-31T18:24:34.1523Z"
}
{
"error": "The provided date has an invalid format. "
"Format should be of yyyy-mm-ddThh:mm:ss.msZ, ex: 2015-01-31T18:24:34.1523Z"
}
))
assert_that(code, equal_to(400))

View File

@ -12,15 +12,20 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from hamcrest import assert_that, equal_to, has_entries, has_length, has_key, has_entry
from hamcrest import assert_that
from hamcrest import equal_to
from hamcrest import has_entries
from hamcrest import has_entry
from hamcrest import has_key
from hamcrest import has_length
from almanach.common.exceptions.almanach_exception import AlmanachException
from tests.builder import volume_type, a
from tests.api.base_api import BaseApi
from tests.builder import a
from tests.builder import volume_type
class ApiVolumeTypeTest(BaseApi):
def test_get_volume_types(self):
self.controller.should_receive('list_volume_types') \
.and_return([a(volume_type().with_volume_type_name('some_volume_type_name'))]) \
@ -35,14 +40,14 @@ class ApiVolumeTypeTest(BaseApi):
def test_successful_volume_type_create(self):
data = dict(
type_id='A_VOLUME_TYPE_ID',
type_name="A_VOLUME_TYPE_NAME"
type_id='A_VOLUME_TYPE_ID',
type_name="A_VOLUME_TYPE_NAME"
)
self.controller.should_receive('create_volume_type') \
.with_args(
volume_type_id=data['type_id'],
volume_type_name=data['type_name']) \
volume_type_id=data['type_id'],
volume_type_name=data['type_name']) \
.once()
code, result = self.api_post('/volume_type', data=data, headers={'X-Auth-Token': 'some token value'})

View File

@ -14,8 +14,12 @@
import unittest
from flexmock import flexmock, flexmock_teardown
from hamcrest import raises, assert_that, calling, equal_to
from flexmock import flexmock
from flexmock import flexmock_teardown
from hamcrest import assert_that
from hamcrest import calling
from hamcrest import equal_to
from hamcrest import raises
from almanach.auth.keystone_auth import KeystoneAuthentication
from almanach.common.exceptions.authentication_failure_exception import AuthenticationFailureException

View File

@ -14,8 +14,12 @@
import unittest
from flexmock import flexmock, flexmock_teardown
from hamcrest import raises, assert_that, calling, equal_to
from flexmock import flexmock
from flexmock import flexmock_teardown
from hamcrest import assert_that
from hamcrest import calling
from hamcrest import equal_to
from hamcrest import raises
from almanach.auth.mixed_auth import MixedAuthentication
from almanach.common.exceptions.authentication_failure_exception import AuthenticationFailureException

View File

@ -13,7 +13,11 @@
# limitations under the License.
import unittest
from hamcrest import raises, assert_that, calling, equal_to
from hamcrest import assert_that
from hamcrest import calling
from hamcrest import equal_to
from hamcrest import raises
from almanach.auth.private_key_auth import PrivateKeyAuthentication
from almanach.common.exceptions.authentication_failure_exception import AuthenticationFailureException

View File

@ -12,13 +12,16 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import pytz
from copy import copy
from datetime import datetime
from uuid import uuid4
from almanach.core.model import build_entity_from_dict, Instance, Volume, VolumeType
import pytz
from almanach.core.model import build_entity_from_dict
from almanach.core.model import Instance
from almanach.core.model import Volume
from almanach.core.model import VolumeType
class Builder(object):

View File

@ -12,26 +12,35 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import sys
import logging
import unittest
from copy import copy
from datetime import datetime, timedelta
import pytz
from datetime import datetime
from datetime import timedelta
from dateutil.parser import parse
from hamcrest import raises, calling, assert_that, equal_to
from flexmock import flexmock, flexmock_teardown
import logging
import sys
import unittest
from flexmock import flexmock
from flexmock import flexmock_teardown
from hamcrest import assert_that
from hamcrest import calling
from hamcrest import equal_to
from hamcrest import raises
from nose.tools import assert_raises
import pytz
from almanach.common.exceptions.almanach_entity_not_found_exception import AlmanachEntityNotFoundException
from almanach.common.exceptions.multiple_entities_matching_query import MultipleEntitiesMatchingQuery
from tests.builder import a, instance, volume, volume_type
from almanach import config
from almanach.common.exceptions.date_format_exception import DateFormatException
from almanach.common.exceptions.multiple_entities_matching_query import MultipleEntitiesMatchingQuery
from almanach.common.exceptions.validation_exception import InvalidAttributeException
from almanach import config
from almanach.core.controller import Controller
from almanach.core.model import Instance, Volume
from almanach.core.model import Instance
from almanach.core.model import Volume
from tests.builder import a
from tests.builder import instance
from tests.builder import volume
from tests.builder import volume_type
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)

View File

@ -14,9 +14,10 @@
import os
import pkg_resources
from unittest import TestCase
from hamcrest import assert_that, equal_to
from hamcrest import assert_that
from hamcrest import equal_to
from almanach import config

View File

@ -1,6 +1,23 @@
# Copyright 2016 Internap.
#
# 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 unittest
from hamcrest import assert_that, calling, raises, is_
from hamcrest import assert_that
from hamcrest import calling
from hamcrest import is_
from hamcrest import raises
from almanach.common.exceptions.validation_exception import InvalidAttributeException
from almanach.validators.instance_validator import InstanceValidator