commit
ca830c05b2
@ -22,7 +22,7 @@ from flask import Blueprint, Response, request
|
||||
from werkzeug.wrappers import BaseResponse
|
||||
|
||||
from almanach import config
|
||||
from almanach.common.DateFormatException import DateFormatException
|
||||
from almanach.common.date_format_exception import DateFormatException
|
||||
|
||||
api = Blueprint("api", __name__)
|
||||
controller = None
|
||||
|
@ -17,8 +17,8 @@ import pymongo
|
||||
|
||||
from pymongo.errors import ConfigurationError
|
||||
from almanach import config
|
||||
from almanach.common.AlmanachException import AlmanachException
|
||||
from almanach.common.VolumeTypeNotFoundException import VolumeTypeNotFoundException
|
||||
from almanach.common.almanach_exception import AlmanachException
|
||||
from almanach.common.volume_type_not_found_exception import VolumeTypeNotFoundException
|
||||
from almanach.core.model import build_entity_from_dict, VolumeType
|
||||
from pymongomodem.utils import decode_output, encode_input
|
||||
|
||||
@ -55,6 +55,7 @@ def ensureindex(db):
|
||||
|
||||
|
||||
class DatabaseAdapter(object):
|
||||
|
||||
def __init__(self):
|
||||
self.db = None
|
||||
|
||||
|
@ -20,6 +20,7 @@ from almanach import config
|
||||
|
||||
|
||||
class RetryAdapter:
|
||||
|
||||
def __init__(self, connection):
|
||||
self.connection = connection
|
||||
retry_exchange = self._configure_retry_exchanges(self.connection)
|
||||
@ -87,7 +88,8 @@ class RetryAdapter:
|
||||
return dead_exchange
|
||||
|
||||
def error_callback(exception, interval):
|
||||
logging.error('Failed to declare dead queue and exchange, retrying in %d seconds. %r' % (interval, exception))
|
||||
logging.error('Failed to declare dead queue and exchange, retrying in %d seconds. %r' %
|
||||
(interval, exception))
|
||||
|
||||
declare_dead_queue = connection.ensure(connection, declare_dead_queue, errback=error_callback,
|
||||
interval_start=0, interval_step=5, interval_max=30)
|
||||
|
@ -25,6 +25,7 @@ from almanach.core.controller import Controller
|
||||
|
||||
|
||||
class AlmanachApi(Application):
|
||||
|
||||
def __init__(self):
|
||||
super(AlmanachApi, self).__init__()
|
||||
|
||||
|
@ -26,6 +26,7 @@ from almanach.core.controller import Controller
|
||||
|
||||
|
||||
class AlmanachCollector(object):
|
||||
|
||||
def __init__(self):
|
||||
log_bootstrap.configure()
|
||||
config.read(sys.argv)
|
||||
|
@ -1 +0,0 @@
|
||||
|
@ -12,5 +12,6 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
class AlmanachException(Exception):
|
||||
pass
|
@ -12,7 +12,9 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
class DateFormatException(Exception):
|
||||
|
||||
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, " \
|
@ -12,7 +12,9 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
class VolumeTypeNotFoundException(Exception):
|
||||
|
||||
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)
|
@ -16,7 +16,7 @@ import ConfigParser
|
||||
import pkg_resources
|
||||
import os.path as Path
|
||||
|
||||
from almanach.common.AlmanachException import AlmanachException
|
||||
from almanach.common.almanach_exception import AlmanachException
|
||||
|
||||
configuration = ConfigParser.RawConfigParser()
|
||||
|
||||
@ -98,12 +98,15 @@ def rabbitmq_retry_return_exchange():
|
||||
def rabbitmq_retry_queue():
|
||||
return get("RABBITMQ", "retry.queue", default=None)
|
||||
|
||||
|
||||
def rabbitmq_dead_queue():
|
||||
return get("RABBITMQ", "dead.queue", default=None)
|
||||
|
||||
|
||||
def rabbitmq_dead_exchange():
|
||||
return get("RABBITMQ", "dead.exchange", default=None)
|
||||
|
||||
|
||||
def rabbitmq_time_to_live():
|
||||
return int(get("RABBITMQ", "retry.time.to.live", default=None))
|
||||
|
||||
|
@ -19,12 +19,13 @@ from datetime import timedelta
|
||||
from dateutil import parser as date_parser
|
||||
from pkg_resources import get_distribution
|
||||
|
||||
from almanach.common.DateFormatException import DateFormatException
|
||||
from almanach.common.date_format_exception import DateFormatException
|
||||
from almanach.core.model import Instance, Volume, VolumeType
|
||||
from almanach import config
|
||||
|
||||
|
||||
class Controller(object):
|
||||
|
||||
def __init__(self, database_adapter):
|
||||
self.database_adapter = database_adapter
|
||||
self.metadata_whitelist = config.device_metadata_whitelist()
|
||||
|
@ -12,7 +12,9 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
class Entity(object):
|
||||
|
||||
def __init__(self, entity_id, project_id, start, end, last_event, name, entity_type):
|
||||
self.entity_id = entity_id
|
||||
self.project_id = project_id
|
||||
@ -52,6 +54,7 @@ class Instance(Entity):
|
||||
|
||||
|
||||
class OS(object):
|
||||
|
||||
def __init__(self, os_type, distro, version):
|
||||
self.os_type = os_type
|
||||
self.distro = distro
|
||||
@ -80,6 +83,7 @@ class Volume(Entity):
|
||||
|
||||
|
||||
class VolumeType(object):
|
||||
|
||||
def __init__(self, volume_type_id, volume_type_name):
|
||||
self.volume_type_id = volume_type_id
|
||||
self.volume_type_name = volume_type_name
|
||||
|
@ -23,6 +23,7 @@ from almanach.adapters.bus_adapter import BusAdapter
|
||||
|
||||
|
||||
class BusAdapterTest(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.controller = flexmock()
|
||||
self.retry = flexmock()
|
||||
|
@ -21,14 +21,15 @@ from hamcrest import assert_that, contains_inanyorder
|
||||
from pymongo import MongoClient
|
||||
|
||||
from almanach.adapters.database_adapter import DatabaseAdapter
|
||||
from almanach.common.VolumeTypeNotFoundException import VolumeTypeNotFoundException
|
||||
from almanach.common.AlmanachException import AlmanachException
|
||||
from almanach.common.volume_type_not_found_exception import VolumeTypeNotFoundException
|
||||
from almanach.common.almanach_exception import AlmanachException
|
||||
from almanach import config
|
||||
from almanach.core.model import todict
|
||||
from tests.builder import a, instance, volume, volume_type
|
||||
|
||||
|
||||
class DatabaseAdapterTest(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
config.read(config_file="resources/config/test.cfg")
|
||||
mongo_connection = mongomock.Connection()
|
||||
@ -103,18 +104,23 @@ class DatabaseAdapterTest(unittest.TestCase):
|
||||
|
||||
def test_list_instances(self):
|
||||
fake_instances = [
|
||||
a(instance().with_id("id1").with_start(2014, 1, 1, 7, 0, 0).with_end(2014, 1, 1, 8, 0, 0).with_project_id("project_id").with_metadata({})),
|
||||
a(instance().with_id("id2").with_start(2014, 1, 1, 1, 0, 0).with_no_end().with_project_id("project_id").with_metadata({})),
|
||||
a(instance().with_id("id3").with_start(2014, 1, 1, 8, 0, 0).with_no_end().with_project_id("project_id").with_metadata({})),
|
||||
a(instance().with_id("id1").with_start(2014, 1, 1, 7, 0, 0).with_end(
|
||||
2014, 1, 1, 8, 0, 0).with_project_id("project_id").with_metadata({})),
|
||||
a(instance().with_id("id2").with_start(2014, 1, 1, 1, 0,
|
||||
0).with_no_end().with_project_id("project_id").with_metadata({})),
|
||||
a(instance().with_id("id3").with_start(2014, 1, 1, 8, 0,
|
||||
0).with_no_end().with_project_id("project_id").with_metadata({})),
|
||||
]
|
||||
fake_volumes = [
|
||||
a(volume().with_id("id1").with_start(2014, 1, 1, 7, 0, 0).with_end(2014, 1, 1, 8, 0, 0).with_project_id("project_id")),
|
||||
a(volume().with_id("id1").with_start(2014, 1, 1, 7, 0, 0).with_end(
|
||||
2014, 1, 1, 8, 0, 0).with_project_id("project_id")),
|
||||
a(volume().with_id("id2").with_start(2014, 1, 1, 1, 0, 0).with_no_end().with_project_id("project_id")),
|
||||
a(volume().with_id("id3").with_start(2014, 1, 1, 8, 0, 0).with_no_end().with_project_id("project_id")),
|
||||
]
|
||||
[self.db.entity.insert(todict(fake_entity)) for fake_entity in fake_instances + fake_volumes]
|
||||
|
||||
entities = self.adapter.list_entities("project_id", datetime(2014, 1, 1, 0, 0, 0), datetime(2014, 1, 1, 12, 0, 0), "instance")
|
||||
entities = self.adapter.list_entities("project_id", datetime(
|
||||
2014, 1, 1, 0, 0, 0), datetime(2014, 1, 1, 12, 0, 0), "instance")
|
||||
assert_that(entities, contains_inanyorder(*fake_instances))
|
||||
|
||||
def test_list_instances_with_decode_output(self):
|
||||
@ -152,24 +158,33 @@ class DatabaseAdapterTest(unittest.TestCase):
|
||||
|
||||
[self.db.entity.insert(todict(fake_entity)) for fake_entity in fake_instances]
|
||||
|
||||
entities = self.adapter.list_entities("project_id", datetime(2014, 1, 1, 0, 0, 0), datetime(2014, 1, 1, 12, 0, 0), "instance")
|
||||
entities = self.adapter.list_entities("project_id", datetime(
|
||||
2014, 1, 1, 0, 0, 0), datetime(2014, 1, 1, 12, 0, 0), "instance")
|
||||
assert_that(entities, contains_inanyorder(*expected_instances))
|
||||
self.assert_entities_metadata_have_been_sanitize(entities)
|
||||
|
||||
def test_list_entities_in_period(self):
|
||||
fake_entities_in_period = [
|
||||
a(instance().with_id("in_the_period").with_start(2014, 1, 1, 7, 0, 0).with_end(2014, 1, 1, 8, 0, 0).with_project_id("project_id")),
|
||||
a(instance().with_id("running_has_started_before").with_start(2014, 1, 1, 1, 0, 0).with_no_end().with_project_id("project_id")),
|
||||
a(instance().with_id("running_has_started_during").with_start(2014, 1, 1, 8, 0, 0).with_no_end().with_project_id("project_id")),
|
||||
a(instance().with_id("in_the_period").with_start(2014, 1, 1, 7, 0,
|
||||
0).with_end(2014, 1, 1, 8, 0, 0).with_project_id("project_id")),
|
||||
a(instance().with_id("running_has_started_before").with_start(
|
||||
2014, 1, 1, 1, 0, 0).with_no_end().with_project_id("project_id")),
|
||||
a(instance().with_id("running_has_started_during").with_start(
|
||||
2014, 1, 1, 8, 0, 0).with_no_end().with_project_id("project_id")),
|
||||
]
|
||||
fake_entities_out_period = [
|
||||
a(instance().with_id("before_the_period").with_start(2014, 1, 1, 0, 0, 0).with_end(2014, 1, 1, 1, 0, 0).with_project_id("project_id")),
|
||||
a(instance().with_id("after_the_period").with_start(2014, 1, 1, 10, 0, 0).with_end(2014, 1, 1, 11, 0, 0).with_project_id("project_id")),
|
||||
a(instance().with_id("running_has_started_after").with_start(2014, 1, 1, 10, 0, 0).with_no_end().with_project_id("project_id")),
|
||||
a(instance().with_id("before_the_period").with_start(2014, 1, 1, 0,
|
||||
0, 0).with_end(2014, 1, 1, 1, 0, 0).with_project_id("project_id")),
|
||||
a(instance().with_id("after_the_period").with_start(2014, 1, 1, 10,
|
||||
0, 0).with_end(2014, 1, 1, 11, 0, 0).with_project_id("project_id")),
|
||||
a(instance().with_id("running_has_started_after").with_start(
|
||||
2014, 1, 1, 10, 0, 0).with_no_end().with_project_id("project_id")),
|
||||
]
|
||||
[self.db.entity.insert(todict(fake_entity)) for fake_entity in fake_entities_in_period + fake_entities_out_period]
|
||||
[self.db.entity.insert(todict(fake_entity))
|
||||
for fake_entity in fake_entities_in_period + fake_entities_out_period]
|
||||
|
||||
entities = self.adapter.list_entities("project_id", datetime(2014, 1, 1, 6, 0, 0), datetime(2014, 1, 1, 9, 0, 0))
|
||||
entities = self.adapter.list_entities("project_id", datetime(
|
||||
2014, 1, 1, 6, 0, 0), datetime(2014, 1, 1, 9, 0, 0))
|
||||
assert_that(entities, contains_inanyorder(*fake_entities_in_period))
|
||||
|
||||
def test_update_entity(self):
|
||||
@ -190,7 +205,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()
|
||||
@ -259,4 +275,3 @@ class DatabaseAdapterTest(unittest.TestCase):
|
||||
for key in entity.metadata:
|
||||
self.assertTrue(key.find("^") == -1,
|
||||
"The metadata key %s contains carret" % (key))
|
||||
|
||||
|
@ -24,6 +24,7 @@ from almanach.adapters.retry_adapter import RetryAdapter
|
||||
|
||||
|
||||
class BusAdapterTest(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.setup_connection_mock()
|
||||
self.setup_config_mock()
|
||||
|
@ -22,14 +22,15 @@ from flexmock import flexmock, flexmock_teardown
|
||||
from hamcrest import assert_that, has_key, equal_to, has_length, has_entry, has_entries
|
||||
|
||||
from almanach import config
|
||||
from almanach.common.DateFormatException import DateFormatException
|
||||
from almanach.common.AlmanachException import AlmanachException
|
||||
from almanach.common.date_format_exception import DateFormatException
|
||||
from almanach.common.almanach_exception import AlmanachException
|
||||
from almanach.adapters import api_route_v1 as api_route
|
||||
|
||||
from tests.builder import a, instance, volume_type
|
||||
|
||||
|
||||
class ApiTest(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.controller = flexmock()
|
||||
api_route.controller = self.controller
|
||||
@ -891,6 +892,7 @@ class ApiTest(TestCase):
|
||||
|
||||
|
||||
class DateMatcher(object):
|
||||
|
||||
def __init__(self, date):
|
||||
self.date = date
|
||||
|
||||
|
@ -22,11 +22,13 @@ from almanach.core.model import build_entity_from_dict, Instance, Volume, Volume
|
||||
|
||||
|
||||
class Builder(object):
|
||||
|
||||
def __init__(self, dict_object):
|
||||
self.dict_object = dict_object
|
||||
|
||||
|
||||
class EntityBuilder(Builder):
|
||||
|
||||
def build(self):
|
||||
return build_entity_from_dict(self.dict_object)
|
||||
|
||||
@ -73,6 +75,7 @@ class EntityBuilder(Builder):
|
||||
|
||||
|
||||
class VolumeBuilder(EntityBuilder):
|
||||
|
||||
def with_attached_to(self, attached_to):
|
||||
self.dict_object["attached_to"] = attached_to
|
||||
return self
|
||||
@ -91,6 +94,7 @@ class VolumeBuilder(EntityBuilder):
|
||||
|
||||
|
||||
class VolumeTypeBuilder(Builder):
|
||||
|
||||
def build(self):
|
||||
return VolumeType(**self.dict_object)
|
||||
|
||||
|
@ -21,7 +21,7 @@ from flexmock import flexmock, flexmock_teardown
|
||||
from nose.tools import assert_raises
|
||||
|
||||
from almanach import config
|
||||
from almanach.common.DateFormatException import DateFormatException
|
||||
from almanach.common.date_format_exception import DateFormatException
|
||||
from almanach.core.controller import Controller
|
||||
from almanach.core.model import Instance, Volume
|
||||
from tests.builder import a, instance, volume, volume_type
|
||||
@ -250,7 +250,8 @@ class ControllerTest(unittest.TestCase):
|
||||
.with_args("project_id", "start", "end")
|
||||
.and_return(["volume2", "volume3", "instance1"]))
|
||||
|
||||
self.assertEqual(self.controller.list_entities("project_id", "start", "end"), ["volume2", "volume3", "instance1"])
|
||||
self.assertEqual(self.controller.list_entities(
|
||||
"project_id", "start", "end"), ["volume2", "volume3", "instance1"])
|
||||
|
||||
def test_create_volume(self):
|
||||
some_volume_type = a(volume_type().with_volume_type_name("some_volume_type_name"))
|
||||
@ -631,4 +632,3 @@ class ControllerTest(unittest.TestCase):
|
||||
.once())
|
||||
|
||||
self.assertEqual(len(self.controller.list_volume_types()), 2)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user