diff --git a/dashboard/decorators.py b/dashboard/decorators.py index a98d6fadb..daff6a225 100644 --- a/dashboard/decorators.py +++ b/dashboard/decorators.py @@ -57,27 +57,49 @@ def record_filter(ignore=None, use_default=True): ignore = [] def decorator(f): + def _filter_records_by_modules(memory_storage_inst, modules, releases): + selected = set([]) + for m, r in vault.resolve_modules(modules, releases): + y = memory_storage_inst.get_record_ids_by_modules([m]) + if r: + x = memory_storage_inst.get_record_ids_by_releases([r]) + selected |= x & y + else: + selected |= y + return selected + @functools.wraps(f) def record_filter_decorated_function(*args, **kwargs): memory_storage_inst = vault.get_memory_storage() record_ids = set(memory_storage_inst.get_record_ids()) # a copy - if 'module' not in ignore: - param = parameters.get_parameter(kwargs, 'module', 'modules', - use_default) - if param: - record_ids &= ( - memory_storage_inst.get_record_ids_by_modules( - vault.resolve_modules(param))) + releases = [] + if 'release' not in ignore: + releases = parameters.get_parameter(kwargs, 'release', + 'releases', use_default) + if releases: + if 'all' not in releases: + record_ids &= ( + memory_storage_inst.get_record_ids_by_releases( + c.lower() for c in releases)) + + modules = parameters.get_parameter(kwargs, 'module', 'modules', + use_default) if 'project_type' not in ignore: param = parameters.get_parameter(kwargs, 'project_type', 'project_types', use_default) if param: - record_ids &= ( - memory_storage_inst.get_record_ids_by_modules( - vault.resolve_project_types(param))) + record_ids &= _filter_records_by_modules( + memory_storage_inst, + vault.resolve_project_types(param), + releases) + + if 'module' not in ignore: + if modules: + record_ids &= _filter_records_by_modules( + memory_storage_inst, modules, releases) if 'user_id' not in ignore: param = parameters.get_parameter(kwargs, 'user_id', 'user_ids') @@ -94,15 +116,6 @@ def record_filter(ignore=None, use_default=True): record_ids &= ( memory_storage_inst.get_record_ids_by_companies(param)) - if 'release' not in ignore: - param = parameters.get_parameter(kwargs, 'release', 'releases', - use_default) - if param: - if 'all' not in param: - record_ids &= ( - memory_storage_inst.get_record_ids_by_releases( - c.lower() for c in param)) - if 'metric' not in ignore: metrics = parameters.get_parameter(kwargs, 'metric') if 'all' not in metrics: diff --git a/dashboard/vault.py b/dashboard/vault.py index c53187e67..65d20a3b1 100644 --- a/dashboard/vault.py +++ b/dashboard/vault.py @@ -13,11 +13,11 @@ # See the License for the specific language governing permissions and # limitations under the License. -import collections import os import flask from oslo.config import cfg +import six from dashboard import memory_storage from stackalytics.openstack.common import log as logging @@ -84,40 +84,11 @@ def _init_releases(vault): vault['releases'] = releases_map -def _make_module(module_id, text, modules, tag): - return {'id': module_id, 'text': text, - 'modules': set(modules), 'tag': tag} - - def _init_module_groups(vault): runtime_storage_inst = vault['runtime_storage'] - memory_storage_inst = vault['memory_storage'] - - module_group_index = collections.defaultdict(set) - module_id_index = {} module_groups = runtime_storage_inst.get_by_key('module_groups') or {} - for module_group in module_groups.values(): - module_group_name = module_group['module_group_name'] - module_group_id = module_group.get('id') or module_group_name.lower() - - module_id_index[module_group_id] = _make_module( - module_group_id, module_group_name, module_group['modules'], - module_group.get('tag') or 'group') - - for module in module_group['modules']: - module_group_index[module].add(module_group_id) - - for module in memory_storage_inst.get_modules(): - module_id_index[module] = _make_module(module.lower(), module, - [module.lower()], 'module') - - module_id_index['all'] = _make_module('all', 'All', - memory_storage_inst.get_modules(), - 'project_type') - - vault['module_group_index'] = module_group_index - vault['module_id_index'] = module_id_index + vault['module_id_index'] = module_groups def _init_project_types(vault): @@ -184,20 +155,37 @@ def get_user_from_runtime_storage(user_id): return user_index[user_id] -def resolve_modules(module_ids): +def resolve_modules(module_ids, releases): module_id_index = get_vault().get('module_id_index') or {} - modules = set() + for module_id in module_ids: if module_id in module_id_index: - modules |= set(module_id_index[module_id]['modules']) - return modules + module_group = module_id_index[module_id] + + if not releases or 'all' in releases: + if 'releases' in module_group: + for release, modules in six.iteritems( + module_group['releases']): + for module in modules: + yield module, release + if 'modules' in module_group: + for module in module_group['modules']: + yield module, None + else: + for release in releases: + if 'releases' in module_group: + for module in module_group['releases'][release]: + yield module, release + if 'modules' in module_group: + for module in module_group['modules']: + yield module, release def resolve_project_types(project_types): modules = set() + project_types_index = get_vault()['project_types_index'] for pt in project_types: pt = pt.lower() - if is_project_type_valid(pt): - modules |= resolve_modules( - get_vault()['project_types_index'][pt]['modules']) + if pt in project_types_index: + modules |= set(project_types_index[pt]['modules']) return modules diff --git a/dashboard/web.py b/dashboard/web.py index 4636eec04..b7c29f0fe 100644 --- a/dashboard/web.py +++ b/dashboard/web.py @@ -21,7 +21,6 @@ import time import flask from flask.ext import gravatar as gravatar_ext -import itertools from oslo.config import cfg import six @@ -136,7 +135,7 @@ def get_core_engineer_branch(user, modules): def get_engineers(records, metric_filter, finalize_handler): modules_names = parameters.get_parameter({}, 'module', 'modules') - modules = vault.resolve_modules(modules_names) + modules = set([m for m, r in vault.resolve_modules(modules_names, [''])]) def postprocessing(record): if finalize_handler: @@ -157,7 +156,7 @@ def get_engineers(records, metric_filter, finalize_handler): @decorators.record_filter(ignore='metric') def get_engineers_extended(records): modules_names = parameters.get_parameter({}, 'module', 'modules') - modules = vault.resolve_modules(modules_names) + modules = set([m for m, r in vault.resolve_modules(modules_names, [''])]) def postprocessing(record): record = decorators.mark_finalize(record) @@ -257,26 +256,24 @@ def get_companies_json(records): @decorators.exception_handler() @decorators.record_filter(ignore='module') def get_modules_json(records): - module_group_index = vault.get_vault()['module_group_index'] module_id_index = vault.get_vault()['module_id_index'] tags = parameters.get_parameter({}, 'tag', 'tags') # all modules mentioned in records - module_ids = set(record['module'] for record in records) - # plus all module groups that hold these modules - module_ids |= set(itertools.chain.from_iterable( - module_group_index.get(module, []) for module in module_ids)) + module_ids = set(record['module'] for record in records + if record['module'] in module_id_index) + + add_modules = set([]) + for module in six.itervalues(module_id_index): + if set(module['modules']) <= module_ids: + add_modules.add(module['id']) + module_ids |= add_modules + # keep only modules with specified tags if tags: module_ids = set(module_id for module_id in module_ids if module_id_index[module_id].get('tag') in tags) - # keep only modules that are in project type completely - pts = parameters.get_parameter({}, 'project_type', 'project_types') - if pts: - m = set(vault.resolve_project_types(pts)) - module_ids = set(module_id for module_id in module_ids - if module_id_index[module_id]['modules'] <= m) query = (flask.request.args.get('query') or '').lower() matched = [] @@ -286,6 +283,8 @@ def get_modules_json(records): module = dict([(k, v) for k, v in six.iteritems(module_id_index[module_id]) if k not in ['modules']]) + module['text'] = module['module_group_name'] + del module['module_group_name'] matched.append(module) return sorted(matched, key=operator.itemgetter('text')) @@ -312,7 +311,7 @@ def get_module(module): module = module.lower() if module in module_id_index: return {'id': module_id_index[module]['id'], - 'text': module_id_index[module]['text'], + 'text': module_id_index[module]['module_group_name'], 'tag': module_id_index[module]['tag']} flask.abort(404) diff --git a/etc/copy_of_programs.yaml b/etc/copy_of_programs.yaml new file mode 100644 index 000000000..aa0ebdff7 --- /dev/null +++ b/etc/copy_of_programs.yaml @@ -0,0 +1,326 @@ +Compute: + codename: Nova + ptl: Michael Still (mikal) + mission: + To implement services and associated libraries to provide massively scalable, + on demand, self service access to compute resources, including bare metal, + virtual machines, and containers. + url: https://wiki.openstack.org/wiki/Nova + projects: + - repo: openstack/nova + integrated-since: austin + - repo: openstack/python-novaclient + - repo: openstack/nova-specs + +Object Storage: + codename: Swift + ptl: John Dickinson (notmyname) + url: https://wiki.openstack.org/wiki/Swift + projects: + - repo: openstack/swift + integrated-since: austin + - repo: openstack/python-swiftclient + - repo: openstack/swift-bench + +Image Service: + codename: Glance + ptl: Mark Washenberger (markwash) + url: https://wiki.openstack.org/wiki/Glance + projects: + - repo: openstack/glance + integrated-since: bexar + - repo: openstack/python-glanceclient + +Identity: + codename: Keystone + ptl: Dolph Mathews (dolphm) + mission: + To facilitate API client authentication, service discovery, and distributed + multi-tenant authorization. + url: https://wiki.openstack.org/wiki/Keystone + projects: + - repo: openstack/keystone + integrated-since: essex + - repo: openstack/python-keystoneclient + +Dashboard: + codename: Horizon + ptl: David Lyle (david-lyle) + url: https://wiki.openstack.org/wiki/Horizon + projects: + - repo: openstack/horizon + integrated-since: essex + - repo: openstack/django_openstack_auth + - repo: openstack/tuskar-ui + +Networking: + codename: Neutron + ptl: Kyle Mestery (mestery) + mission: + To implement services and associated libraries to provide on-demand, + scalable, and technology-agnostic network abstraction. + + url: https://wiki.openstack.org/wiki/Neutron + projects: + - repo: openstack/neutron + integrated-since: folsom + - repo: openstack/python-neutronclient + - repo: openstack/neutron-specs + +Block Storage: + codename: Cinder + ptl: John Griffith (jgriffith) + mission: + To implement services and libraries to provide on-demand, + self-service access to Block Storage resources via abstraction + and automation on top of other block storage devices. + url: https://wiki.openstack.org/wiki/Cinder + projects: + - repo: openstack/cinder + integrated-since: folsom + - repo: openstack/python-cinderclient + +Telemetry: + codename: Ceilometer + ptl : Eoghan Glynn (eglynn) + url: https://wiki.openstack.org/wiki/Ceilometer + projects: + - repo: openstack/ceilometer + incubated-since: grizzly + integrated-since: havana + - repo: openstack/python-ceilometerclient + +Orchestration: + codename: Heat + ptl: Zane Bitter (zaneb) + url: https://wiki.openstack.org/wiki/Heat + projects: + - repo: openstack/heat + incubated-since: grizzly + integrated-since: havana + - repo: openstack/python-heatclient + - repo: openstack/heat-cfntools + - repo: openstack/heat-templates + - repo: openstack-dev/heat-cfnclient + +Database Service: + codename: Trove + ptl: Nikhil Manchanda (SlickNik) + mission: + To provide scalable and reliable Cloud Database as a Service + functionality for both relational and non-relational database + engines, and to continue to improve its fully-featured and + extensible open source framework. + url: https://wiki.openstack.org/wiki/Trove + projects: + - repo: openstack/trove + incubated-since: havana + integrated-since: icehouse + - repo: openstack/python-troveclient + - repo: openstack/trove-integration + +Bare metal: + codename: Ironic + ptl: Devananda van der Veen (devananda) + mission: + To produce an OpenStack service and associated python libraries capable + of managing and provisioning physical machines, and to do this in a + security-aware and fault-tolerant manner. + url: https://wiki.openstack.org/wiki/Ironic + projects: + - repo: openstack/ironic + incubated-since: havana + - repo: openstack/python-ironicclient + - repo: openstack/ironic-python-agent + +Common Libraries: + codename: Oslo + ptl: Doug Hellmann (dhellmann) + mission: + To produce a set of python libraries containing code shared by OpenStack + projects. The APIs provided by these libraries should be high quality, + stable, consistent, documented and generally applicable. + url: https://wiki.openstack.org/wiki/Oslo + projects: + - repo: openstack/cliff + - repo: openstack/oslo.config + - repo: openstack/oslo-incubator + - repo: openstack/oslo.messaging + - repo: openstack/oslo.rootwrap + - repo: openstack/oslosphinx + - repo: openstack/oslo.test + - repo: openstack/oslo.version + - repo: openstack/oslo.vmware + - repo: openstack/pycadf + - repo: openstack/stevedore + - repo: openstack/taskflow + - repo: openstack-dev/cookiecutter + - repo: openstack-dev/oslo-cookiecutter + - repo: openstack-dev/hacking + - repo: openstack-dev/pbr + +Infrastructure: + ptl: James E. Blair (jeblair) + url: https://wiki.openstack.org/wiki/Infrastructure + mission: + Develop and maintain the tooling and infrastructure needed to + support the development process and general operation of the + OpenStack project. + projects: + - repo: openstack-dev/openstack-nose + - repo: openstack-infra/activity-board + - repo: openstack-infra/askbot-theme + - repo: openstack-infra/config + - repo: openstack-infra/devstack-gate + - repo: openstack-infra/elastic-recheck + - repo: openstack-infra/gear + - repo: openstack-infra/gearman-plugin + - repo: openstack-infra/gerrit + - repo: openstack-infra/gerritbot + - repo: openstack-infra/gerritlib + - repo: openstack-infra/git-review + - repo: openstack-infra/gitdm + - repo: openstack-infra/groups + - repo: openstack-infra/jeepyb + - repo: openstack-infra/jenkins-job-builder + - repo: openstack-infra/lodgeit + - repo: openstack-infra/meetbot + - repo: openstack-infra/nodepool + - repo: openstack-infra/nose-html-output + - repo: openstack-infra/odsreg + - repo: openstack-infra/openstackid + - repo: openstack-infra/os-loganalyze + - repo: openstack-infra/publications + - repo: openstack-infra/puppet-apparmor + - repo: openstack-infra/puppet-dashboard + - repo: openstack-infra/puppet-vcsrepo + - repo: openstack-infra/pypi-mirror + - repo: openstack-infra/releasestatus + - repo: openstack-infra/reviewday + - repo: openstack-infra/reviewstats + - repo: openstack-infra/statusbot + - repo: openstack-infra/storyboard + - repo: openstack-infra/storyboard-webclient + - repo: openstack-infra/tripleo-ci + - repo: openstack-infra/zmq-event-publisher + - repo: openstack-infra/zuul + - repo: openstack-infra/zuul-packaging + - repo: openstack/openstack-planet + +Documentation: + ptl: Anne Gentle (annegentle) + mission: + Provide documentation for core OpenStack projects to promote OpenStack. + Develop and maintain tools and processes to ensure quality, accurate + documentation. Treat documentation like OpenStack code. + url: https://wiki.openstack.org/wiki/Documentation + projects: + - repo: openstack/api-site + - repo: openstack/compute-api + - repo: openstack/database-api + - repo: openstack/identity-api + - repo: openstack/image-api + - repo: openstack/netconn-api + - repo: openstack/object-api + - repo: openstack/openstack-doc-tools + - repo: openstack/openstack-manuals + - repo: openstack/operations-guide + - repo: openstack/volume-api + +Quality Assurance: + codename: QA + ptl: Matthew Treinish (mtreinish) + mission: + Develop, maintain, and initiate tools and plans to ensure the upstream + stability and quality of OpenStack, and its release readiness at any + point during the release cycle. + url: https://wiki.openstack.org/wiki/QA + projects: + - repo: openstack/tempest + - repo: openstack-dev/grenade + - repo: openstack/qa-specs + +Deployment: + codename: TripleO + ptl: Robert Collins (lifeless) + mission: + Develop and maintain tooling and infrastructure able to deploy OpenStack + in production, using OpenStack itself wherever possible. + url: https://wiki.openstack.org/wiki/TripleO + projects: + - repo: openstack/diskimage-builder + - repo: openstack/os-apply-config + - repo: openstack/os-cloud-config + - repo: openstack/os-collect-config + - repo: openstack/os-refresh-config + - repo: openstack/tripleo-heat-templates + - repo: openstack/tripleo-image-elements + - repo: openstack/tripleo-incubator + - repo: openstack/tuskar + - repo: openstack/python-tuskarclient + +Devstack: + ptl: Dean Troyer (dtroyer) + mission: + To provide an installation of OpenStack from git repository master, or + specific branches, suitable for development and operational testing. + It also attempts to document the process and provide examples of command + line usage. + url: https://wiki.openstack.org/wiki/DevStack + projects: + - repo: openstack-dev/devstack + +Release cycle management: + ptl: Thierry Carrez (ttx) + mission: + To organize the release cycle and the work necessary to produce + coordinated releases of the integrated components of OpenStack. + To collect bugfix backports and produce stable point releases for the + previously-released branch. To coordinate the publication of security + patches and advisories (OSSA) for security-supported branches. + url: https://wiki.openstack.org/wiki/Release_Cycle_Management + projects: + - repo: openstack/requirements + - repo: openstack-infra/release-tools + +Queue service: + codename: Marconi + ptl: Kurt Griffiths (kgriffs) + mission: + To produce an OpenStack message queueing API and service that affords + a variety of distributed application messaging patterns in an efficient, + scalable and highly-available manner, and to create and maintain + associated Python libraries and documentation. + url: https://wiki.openstack.org/wiki/Marconi + projects: + - repo: openstack/marconi + incubated-since: icehouse + - repo: openstack/python-marconiclient + +Data processing service: + codename: Sahara + ptl: Sergey Lukjanov (SergeyLukjanov) + mission: + To provide a scalable data processing stack and associated management + interfaces. + url: https://wiki.openstack.org/wiki/Sahara + projects: + - repo: openstack/sahara + incubated-since: icehouse + integrated-since: juno + - repo: openstack/python-saharaclient + - repo: openstack/sahara-dashboard + - repo: openstack/sahara-extra + - repo: openstack/sahara-image-elements + +Key management service: + codename: Barbican + ptl: Jarret Raim (jraim) + mission: + To produce a secret storage and generation system capable of providing key + management for services wishing to enable encryption features. + url: https://wiki.openstack.org/wiki/Barbican + projects: + - repo: stackforge/barbican + incubated-since: juno + - repo: stackforge/python-barbicanclient diff --git a/etc/default_data.json b/etc/default_data.json index 1961baca8..78b4165be 100644 --- a/etc/default_data.json +++ b/etc/default_data.json @@ -7376,11 +7376,23 @@ "releases": [ { "release_name": "prehistory", - "end_date": "2011-Apr-21" + "end_date": "2010-Jan-01" + }, + { + "release_name": "Austin", + "end_date": "2010-Oct-21" + }, + { + "release_name": "Bexar", + "end_date": "2011-Feb-03" + }, + { + "release_name": "Cactus", + "end_date": "2011-Apr-15" }, { "release_name": "Diablo", - "end_date": "2011-Sep-08" + "end_date": "2011-Sep-22" }, { "release_name": "Essex", diff --git a/etc/test_programs.yaml b/etc/test_programs.yaml index 9e6c828a3..0d9ea0f54 100644 --- a/etc/test_programs.yaml +++ b/etc/test_programs.yaml @@ -3,7 +3,7 @@ Image Service: ptl: Mark Washenberger (markwash) url: https://wiki.openstack.org/wiki/Glance projects: - integrated: - - openstack/glance - other: - - openstack/python-glanceclient + - repo: openstack/glance + integrated-since: havana + incubated-since: grizzly + - repo: openstack/python-glanceclient diff --git a/stackalytics/processor/default_data_processor.py b/stackalytics/processor/default_data_processor.py index 412ce4bec..d76ed4698 100644 --- a/stackalytics/processor/default_data_processor.py +++ b/stackalytics/processor/default_data_processor.py @@ -138,7 +138,8 @@ def _store_companies(runtime_storage_inst, companies): def _store_module_groups(runtime_storage_inst, module_groups): stored_mg = runtime_storage_inst.get_by_key('module_groups') or {} for mg in module_groups: - stored_mg[mg['module_group_name']] = mg + mg['id'] = mg['module_group_name'] + stored_mg[mg['id']] = mg runtime_storage_inst.set_by_key('module_groups', stored_mg) diff --git a/stackalytics/processor/main.py b/stackalytics/processor/main.py index 5745f5065..a23aebf77 100644 --- a/stackalytics/processor/main.py +++ b/stackalytics/processor/main.py @@ -194,42 +194,86 @@ def _make_module_group(group_id, name, modules, tag=None): return module_group -def _read_module_groups(program_list_uri): +def _read_official_programs_yaml(program_list_uri, release_names): LOG.debug('Process list of programs from uri: %s', program_list_uri) content = yaml.safe_load(utils.read_uri(program_list_uri)) - module_groups = [] - modules_by_types = collections.defaultdict(list) + module_groups = collections.defaultdict( + lambda: {'modules': [], 'releases': collections.defaultdict(list)}) + + official_integrated = module_groups['official-integrated'] + official_integrated['tag'] = 'project_type' + official_integrated['module_group_name'] = 'official-integrated' + official_incubated = module_groups['official-incubated'] + official_incubated['tag'] = 'project_type' + official_incubated['module_group_name'] = 'official-incubated' + official_other = module_groups['official-other'] + official_other['tag'] = 'project_type' + official_other['module_group_name'] = 'official-other' + for name, info in six.iteritems(content): + # for one program group_id = name.lower() if 'codename' in info: name = '%s (%s)' % (info['codename'], name) group_id = '%s-group' % info['codename'].lower() - all_modules = [] - for project_type, project_list in six.iteritems(info['projects']): - module_list = [s.split('/')[1] for s in project_list] - modules_by_types[project_type] += module_list - all_modules += module_list + module_groups[group_id]['module_group_name'] = name + module_groups[group_id]['tag'] = 'program' - module_groups.append(_make_module_group( - group_id, name, all_modules, 'program')) + for module in info['projects']: + module_name = module['repo'].split('/')[1] + + module_groups[group_id]['modules'].append(module_name) + + if ('integrated-since' in module) or ('incubated-since' in module): + project_type = 'official-other' + for release_name in release_names: + if release_name == module.get('incubated-since'): + project_type = 'official-incubated' + elif release_name == module.get('integrated-since'): + project_type = 'official-integrated' + + module_groups[project_type]['releases'][ + release_name].append(module_name) + else: + module_groups['official-other']['modules'].append(module_name) + + # set ids for module groups + for group_id, group in six.iteritems(module_groups): + group['id'] = group_id - all_modules = [] - for project_type, modules_list in six.iteritems(modules_by_types): - all_modules += modules_list - module_groups.append( - _make_module_group( - 'official-%s' % project_type, project_type.capitalize(), - modules_list, 'project_type')) - module_groups.append(_make_module_group( - 'official-all', 'OpenStack', all_modules, 'project_type')) return module_groups def process_program_list(runtime_storage_inst, program_list_uri): module_groups = runtime_storage_inst.get_by_key('module_groups') or {} - for mg in _read_module_groups(program_list_uri): - module_groups[mg['module_group_name']] = mg + release_names = [r['release_name'].lower() + for r in runtime_storage_inst.get_by_key('releases')[1:]] + + official_module_groups = _read_official_programs_yaml( + program_list_uri, release_names) + LOG.debug('Update module groups with official: %s', official_module_groups) + module_groups.update(official_module_groups) + + # register modules as module groups + repos = runtime_storage_inst.get_by_key('repos') or [] + for repo in repos: + module = repo['module'] + module_groups[module] = { + 'id': module, + 'module_group_name': module, + 'modules': [module], + 'tag': 'module' + } + + # register module 'unknown' - used for emails not mapped to any module + module_groups['unknown'] = { + 'id': 'unknown', + 'module_group_name': 'unknown', + 'modules': ['unknown'], + 'tag': 'module' + } + runtime_storage_inst.set_by_key('module_groups', module_groups) diff --git a/tests/api/test_api.py b/tests/api/test_api.py index c6dbc9d5e..eb57cdae1 100644 --- a/tests/api/test_api.py +++ b/tests/api/test_api.py @@ -66,6 +66,13 @@ def make_records(**kwargs): return generate_records +def make_module(module_name): + return {'id': module_name, + 'module_group_name': module_name, + 'modules': [module_name], + 'tag': 'module'} + + class TestStorage(runtime_storage.RuntimeStorage): def __init__(self, data): diff --git a/tests/api/test_companies.py b/tests/api/test_companies.py index 10402601e..c4927cace 100644 --- a/tests/api/test_companies.py +++ b/tests/api/test_companies.py @@ -34,7 +34,11 @@ class TestAPICompanies(test_api.TestAPI): ], 'module_groups': { 'openstack': {'module_group_name': 'openstack', - 'modules': ['nova', 'glance']} + 'modules': ['nova', 'glance']}, + 'nova': {'module_group_name': 'nova', + 'modules': ['nova']}, + 'glance': {'module_group_name': 'glance', + 'modules': ['glance']}, }}, test_api.make_records(record_type=['commit'], loc=[10, 20, 30], diff --git a/tests/api/test_modules.py b/tests/api/test_modules.py index d1fe0e753..74ba2661a 100644 --- a/tests/api/test_modules.py +++ b/tests/api/test_modules.py @@ -26,9 +26,15 @@ class TestAPIModules(test_api.TestAPI): 'uri': 'git://github.com/openstack/nova.git'}, {'module': 'glance', 'organization': 'openstack', 'uri': 'git://github.com/openstack/glance.git'}], - 'module_groups': {'nova-group': { - 'module_group_name': 'nova-group', - 'modules': ['nova', 'nova-cli']}}, + 'module_groups': { + 'nova-group': {'id': 'nova-group', + 'module_group_name': 'nova-group', + 'modules': ['nova', 'nova-cli'], + 'tag': 'group'}, + 'nova': test_api.make_module('nova'), + 'nova-cli': test_api.make_module('nova-cli'), + 'glance': test_api.make_module('glance'), + }, 'project_types': [ {'id': 'all', 'title': 'All', 'modules': ['nova', 'glance', 'nova-cli']}, @@ -73,9 +79,14 @@ class TestAPIModules(test_api.TestAPI): with test_api.make_runtime_storage( {'repos': [{'module': 'nova', 'organization': 'openstack', 'uri': 'git://github.com/openstack/nova.git'}], - 'module_groups': {'nova-group': { - 'module_group_name': 'nova-group', - 'modules': ['nova', 'python-novaclient']}}}, + 'module_groups': { + 'nova-group': {'id': 'nova-group', + 'module_group_name': 'nova-group', + 'modules': ['nova', 'nova-cli'], + 'tag': 'group'}, + 'nova': test_api.make_module('nova'), + 'nova-cli': test_api.make_module('nova-cli'), + }}, test_api.make_records(record_type=['commit'])): response = self.app.get('/api/1.0/modules/nova') diff --git a/tests/api/test_stats.py b/tests/api/test_stats.py index 244e018c6..a753e366e 100644 --- a/tests/api/test_stats.py +++ b/tests/api/test_stats.py @@ -26,9 +26,14 @@ class TestAPIStats(test_api.TestAPI): 'uri': 'git://github.com/openstack/nova.git'}, {'module': 'glance', 'organization': 'openstack', 'uri': 'git://github.com/openstack/glance.git'}], - 'module_groups': {'openstack': { - 'module_group_name': 'openstack', - 'modules': ['nova', 'glance']}}, + 'module_groups': { + 'openstack': {'id': 'openstack', + 'module_group_name': 'openstack', + 'modules': ['nova', 'glance'], + 'tag': 'group'}, + 'nova': test_api.make_module('nova'), + 'glance': test_api.make_module('glance'), + }, 'project_types': [ {'id': 'all', 'title': 'All', 'modules': ['nova', 'glance']}]}, @@ -55,9 +60,14 @@ class TestAPIStats(test_api.TestAPI): {'module': 'glance', 'project_type': 'openstack', 'organization': 'openstack', 'uri': 'git://github.com/openstack/glance.git'}], - 'module_groups': {'openstack': { - 'module_group_name': 'openstack', - 'modules': ['nova', 'glance']}}, + 'module_groups': { + 'openstack': {'id': 'openstack', + 'module_group_name': 'openstack', + 'modules': ['nova', 'glance'], + 'tag': 'group'}, + 'nova': test_api.make_module('nova'), + 'glance': test_api.make_module('glance'), + }, 'project_types': [ {'id': 'all', 'title': 'All', 'modules': ['nova', 'glance']}], @@ -98,9 +108,14 @@ class TestAPIStats(test_api.TestAPI): {'module': 'glance', 'project_type': 'openstack', 'organization': 'openstack', 'uri': 'git://github.com/openstack/glance.git'}], - 'module_groups': {'openstack': { - 'module_group_name': 'openstack', - 'modules': ['nova', 'glance']}}, + 'module_groups': { + 'openstack': {'id': 'openstack', + 'module_group_name': 'openstack', + 'modules': ['nova', 'glance'], + 'tag': 'group'}, + 'nova': test_api.make_module('nova'), + 'glance': test_api.make_module('glance'), + }, 'project_types': [ {'id': 'all', 'title': 'All', 'modules': ['nova', 'glance']}], diff --git a/tests/api/test_users.py b/tests/api/test_users.py index 0a05c0867..89d035c5c 100644 --- a/tests/api/test_users.py +++ b/tests/api/test_users.py @@ -20,18 +20,16 @@ from tests.api import test_api class TestAPIUsers(test_api.TestAPI): - def test_users_empty(self): - with test_api.make_runtime_storage({}): - response = self.app.get('/api/1.0/users') - self.assertEqual(200, response.status_code) - def test_users(self): with test_api.make_runtime_storage( {'repos': [{'module': 'nova', 'organization': 'openstack', 'uri': 'git://github.com/openstack/nova.git'}], 'project_types': [ {'id': 'openstack', 'title': 'openstack', - 'modules': ['nova', 'glance']}]}, + 'modules': ['nova', 'glance']}], + 'module_groups': { + 'nova': test_api.make_module('nova'), + 'glance': test_api.make_module('glance')}}, test_api.make_records(record_type=['commit'], module=['nova'], user_id=['john_doe', 'bill_smith'])): response = self.app.get('/api/1.0/users?' @@ -47,7 +45,10 @@ class TestAPIUsers(test_api.TestAPI): 'uri': 'git://github.com/openstack/nova.git'}], 'project_types': [ {'id': 'openstack', 'title': 'openstack', - 'modules': ['nova', 'glance']}]}, + 'modules': ['nova', 'glance']}], + 'module_groups': { + 'nova': test_api.make_module('nova'), + 'glance': test_api.make_module('glance')}}, test_api.make_records(record_type=['commit'], module=['nova'], user_name=['John Doe', 'Bill Smith'])): response = self.app.get('/api/1.0/users?'