diff --git a/dashboard/memory_storage.py b/dashboard/memory_storage.py index e01537452..f9a208f1a 100644 --- a/dashboard/memory_storage.py +++ b/dashboard/memory_storage.py @@ -34,6 +34,7 @@ class CachedMemoryStorage(MemoryStorage): self.company_index = {} self.release_index = {} self.blueprint_id_index = {} + self.company_name_mapping = {} self.indexes = { 'primary_key': self.primary_key_index, diff --git a/dashboard/vault.py b/dashboard/vault.py index e9c4e3a25..cafd833ad 100644 --- a/dashboard/vault.py +++ b/dashboard/vault.py @@ -67,16 +67,19 @@ def get_memory_storage(): def init_releases(vault): runtime_storage_inst = vault['runtime_storage'] releases = runtime_storage_inst.get_by_key('releases') - if not releases: - raise Exception('Releases are missing in runtime storage') - vault['start_date'] = releases[0]['end_date'] - vault['end_date'] = releases[-1]['end_date'] - start_date = releases[0]['end_date'] - for r in releases[1:]: - r['start_date'] = start_date - start_date = r['end_date'] - vault['releases'] = dict((r['release_name'].lower(), r) - for r in releases[1:]) + releases_map = {} + + if releases: + vault['start_date'] = releases[0]['end_date'] + vault['end_date'] = releases[-1]['end_date'] + start_date = releases[0]['end_date'] + for r in releases[1:]: + r['start_date'] = start_date + start_date = r['end_date'] + releases_map = dict((r['release_name'].lower(), r) + for r in releases[1:]) + + vault['releases'] = releases_map def init_project_types(vault): @@ -160,7 +163,7 @@ def get_project_type_options(): def get_release_options(): runtime_storage_inst = get_vault()['runtime_storage'] - releases = runtime_storage_inst.get_by_key('releases')[1:] + releases = (runtime_storage_inst.get_by_key('releases') or [None])[1:] releases.append({'release_name': 'all'}) releases.reverse() return releases diff --git a/dashboard/web.py b/dashboard/web.py index 32d569156..8846fd59c 100644 --- a/dashboard/web.py +++ b/dashboard/web.py @@ -53,7 +53,7 @@ if conf_file and os.path.isfile(conf_file): conf(default_config_files=[conf_file]) app.config['DEBUG'] = cfg.CONF.debug else: - LOG.warn('Conf file is empty or not exist') + LOG.info('Conf file is empty or not exist') # Handlers --------- diff --git a/tests/api/__init__.py b/tests/api/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/api/test_api.py b/tests/api/test_api.py new file mode 100644 index 000000000..5dcceb5d9 --- /dev/null +++ b/tests/api/test_api.py @@ -0,0 +1,50 @@ +# Copyright (c) 2013 Mirantis Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import contextlib +import mock +import testtools + +from dashboard import web +from stackalytics.processor import runtime_storage + + +class TestAPI(testtools.TestCase): + + def setUp(self): + super(TestAPI, self).setUp() + self.app = web.app.test_client() + + +@contextlib.contextmanager +def make_runtime_storage(data): + def get_by_key(key): + return data.get(key) + + def get_update(pid): + return [] + + setattr(web.app, 'stackalytics_vault', None) + runtime_storage_inst = mock.Mock(runtime_storage.RuntimeStorage) + runtime_storage_inst.get_by_key = get_by_key + runtime_storage_inst.get_update = get_update + + with mock.patch('stackalytics.processor.runtime_storage.' + 'get_runtime_storage') as get_runtime_storage_mock: + get_runtime_storage_mock.return_value = runtime_storage_inst + try: + yield runtime_storage_inst + finally: + pass diff --git a/tests/api/test_releases.py b/tests/api/test_releases.py new file mode 100644 index 000000000..c777dc16e --- /dev/null +++ b/tests/api/test_releases.py @@ -0,0 +1,58 @@ +# Copyright (c) 2013 Mirantis Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import json + +from tests.api import test_api + + +class TestAPIReleases(test_api.TestAPI): + + def test_releases_empty(self): + with test_api.make_runtime_storage({}): + response = self.app.get('/api/1.0/releases') + self.assertEqual(200, response.status_code) + + def test_releases(self): + with test_api.make_runtime_storage( + {'releases': [ + {'release_name': 'prehistory', 'end_date': 1365033600}, + {'release_name': 'havana', 'end_date': 1381968000}, + {'release_name': 'icehouse', 'end_date': 1397692800}]}): + response = self.app.get('/api/1.0/releases') + releases = json.loads(response.data)['releases'] + self.assertEqual(3, len(releases)) + self.assertIn({'id': 'all', 'text': 'All'}, releases) + self.assertIn({'id': 'icehouse', 'text': 'Icehouse'}, releases) + + def test_releases_search(self): + with test_api.make_runtime_storage( + {'releases': [ + {'release_name': 'prehistory', 'end_date': 1365033600}, + {'release_name': 'havana', 'end_date': 1381968000}, + {'release_name': 'icehouse', 'end_date': 1397692800}]}): + response = self.app.get('/api/1.0/releases?query=hav') + releases = json.loads(response.data)['releases'] + self.assertEqual(1, len(releases)) + self.assertIn({'id': 'havana', 'text': 'Havana'}, releases) + + def test_release_details(self): + with test_api.make_runtime_storage( + {'releases': [ + {'release_name': 'prehistory', 'end_date': 1365033600}, + {'release_name': 'icehouse', 'end_date': 1397692800}]}): + response = self.app.get('/api/1.0/releases/icehouse') + release = json.loads(response.data)['release'] + self.assertEqual({'id': 'icehouse', 'text': 'Icehouse'}, release)