Add ruff
Change-Id: If433b9b73e12f1547ff21e1d4968fac29143f272 Signed-off-by: Stephen Finucane <stephenfin@redhat.com>
This commit is contained in:
28
.pre-commit-config.yaml
Normal file
28
.pre-commit-config.yaml
Normal file
@@ -0,0 +1,28 @@
|
||||
---
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v5.0.0
|
||||
hooks:
|
||||
- id: trailing-whitespace
|
||||
- id: mixed-line-ending
|
||||
args: ['--fix', 'lf']
|
||||
exclude: '.*\.(svg)$'
|
||||
- id: check-byte-order-marker
|
||||
- id: check-executables-have-shebangs
|
||||
- id: check-merge-conflict
|
||||
- id: debug-statements
|
||||
- id: check-yaml
|
||||
files: .*\.(yaml|yml)$
|
||||
exclude: '^zuul.d/.*$'
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
rev: v0.12.1
|
||||
hooks:
|
||||
- id: ruff-check
|
||||
args: ['--fix', '--unsafe-fixes']
|
||||
- id: ruff-format
|
||||
- repo: https://opendev.org/openstack/hacking
|
||||
rev: 7.0.0
|
||||
hooks:
|
||||
- id: hacking
|
||||
exclude: '^(doc|releasenotes|tools)/.*$'
|
||||
additional_dependencies: []
|
||||
28
doc/source/conf.py
Executable file → Normal file
28
doc/source/conf.py
Executable file → Normal file
@@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# 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
|
||||
@@ -16,6 +15,7 @@ import os
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, os.path.abspath('../..'))
|
||||
|
||||
# -- General configuration ----------------------------------------------------
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
@@ -23,13 +23,8 @@ sys.path.insert(0, os.path.abspath('../..'))
|
||||
extensions = [
|
||||
'sphinx.ext.autodoc',
|
||||
'openstackdocstheme',
|
||||
#'sphinx.ext.intersphinx',
|
||||
]
|
||||
|
||||
# autodoc generation is a bit aggressive and a nuisance when doing heavy
|
||||
# text edit cycles.
|
||||
# execute "export SPHINX_DEBUG=1" in your terminal to disable
|
||||
|
||||
# The suffix of source filenames.
|
||||
source_suffix = '.rst'
|
||||
|
||||
@@ -37,8 +32,8 @@ source_suffix = '.rst'
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'os-service-types'
|
||||
copyright = u'2017, OpenStack Developers'
|
||||
project = 'os-service-types'
|
||||
copyright = '2017-, OpenStack Developers'
|
||||
|
||||
# openstackdocstheme options
|
||||
openstackdocs_repo_name = 'openstack/os-service-types'
|
||||
@@ -64,18 +59,15 @@ pygments_style = 'native'
|
||||
# html_static_path = ['static']
|
||||
html_theme = 'openstackdocs'
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = '%sdoc' % project
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title, author, documentclass
|
||||
# [howto/manual]).
|
||||
latex_documents = [
|
||||
('index',
|
||||
'%s.tex' % project,
|
||||
u'%s Documentation' % project,
|
||||
u'OpenStack Foundation', 'manual'),
|
||||
(
|
||||
'index',
|
||||
f'{project}.tex',
|
||||
f'{project} Documentation',
|
||||
'OpenStack Foundation',
|
||||
'manual',
|
||||
),
|
||||
]
|
||||
|
||||
# Example configuration for intersphinx: refer to the Python standard library.
|
||||
#intersphinx_mapping = {'http://docs.python.org/': None}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# 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
|
||||
|
||||
@@ -22,10 +22,8 @@ DATA_DIR = os.path.dirname(__file__)
|
||||
|
||||
|
||||
def read_data(filename):
|
||||
"""Return data that is shipped inside the Python package.
|
||||
|
||||
"""
|
||||
"""Return data that is shipped inside the Python package."""
|
||||
|
||||
filepath = os.path.join(DATA_DIR, filename)
|
||||
with open(filepath, 'r') as fd:
|
||||
with open(filepath) as fd:
|
||||
return json.load(fd)
|
||||
|
||||
@@ -29,7 +29,7 @@ def _normalize_type(service_type):
|
||||
return service_type.replace('_', '-')
|
||||
|
||||
|
||||
class ServiceTypes(object):
|
||||
class ServiceTypes:
|
||||
"""Encapsulation of the OpenStack Service Types Authority data.
|
||||
|
||||
The Service Types Authority data will be either pulled from its remote
|
||||
@@ -57,7 +57,8 @@ class ServiceTypes(object):
|
||||
def __init__(self, session=None, only_remote=False, warn=False):
|
||||
if not session and only_remote:
|
||||
raise ValueError(
|
||||
"only_remote was requested but no Session was provided.")
|
||||
"only_remote was requested but no Session was provided."
|
||||
)
|
||||
self._service_types_data = BUILTIN_DATA
|
||||
self._warn = warn
|
||||
if session:
|
||||
@@ -65,7 +66,7 @@ class ServiceTypes(object):
|
||||
response = session.get(SERVICE_TYPES_URL)
|
||||
response.raise_for_status()
|
||||
self._service_types_data = response.json()
|
||||
except IOError:
|
||||
except OSError:
|
||||
# If we can't fetch, fall backto BUILTIN
|
||||
if only_remote:
|
||||
raise
|
||||
@@ -106,19 +107,22 @@ class ServiceTypes(object):
|
||||
def all_types_by_service_type(self):
|
||||
"Mapping of official service type to official type and aliases."
|
||||
return copy.deepcopy(
|
||||
self._service_types_data['all_types_by_service_type'])
|
||||
self._service_types_data['all_types_by_service_type']
|
||||
)
|
||||
|
||||
@property
|
||||
def primary_service_by_project(self):
|
||||
"Mapping of project name to the primary associated service."
|
||||
return copy.deepcopy(
|
||||
self._service_types_data['primary_service_by_project'])
|
||||
self._service_types_data['primary_service_by_project']
|
||||
)
|
||||
|
||||
@property
|
||||
def service_types_by_project(self):
|
||||
"Mapping of project name to a list of all associated service-types."
|
||||
return copy.deepcopy(
|
||||
self._service_types_data['service_types_by_project'])
|
||||
self._service_types_data['service_types_by_project']
|
||||
)
|
||||
|
||||
def get_official_service_data(self, service_type):
|
||||
"""Get the service data for an official service_type.
|
||||
@@ -224,13 +228,12 @@ class ServiceTypes(object):
|
||||
official = self._service_types_data['reverse'].get(service_type)
|
||||
if permissive and official is None:
|
||||
if self._warn:
|
||||
exc.warn(
|
||||
exc.UnofficialUsageWarning,
|
||||
given=service_type)
|
||||
exc.warn(exc.UnofficialUsageWarning, given=service_type)
|
||||
return service_type
|
||||
if self._warn:
|
||||
exc.warn(
|
||||
exc.AliasUsageWarning, given=service_type, official=official)
|
||||
exc.AliasUsageWarning, given=service_type, official=official
|
||||
)
|
||||
return official
|
||||
|
||||
def get_all_types(self, service_type):
|
||||
@@ -243,7 +246,8 @@ class ServiceTypes(object):
|
||||
if not self.is_known(service_type):
|
||||
return [service_type]
|
||||
return self.all_types_by_service_type[
|
||||
self.get_service_type(service_type)]
|
||||
self.get_service_type(service_type)
|
||||
]
|
||||
|
||||
def get_project_name(self, service_type):
|
||||
"""Return the OpenStack project name for a given service_type.
|
||||
@@ -280,6 +284,7 @@ class ServiceTypes(object):
|
||||
"""
|
||||
data = []
|
||||
for service_type in self.service_types_by_project.get(
|
||||
project_name, []):
|
||||
project_name, []
|
||||
):
|
||||
data.append(self.get_service_data(service_type))
|
||||
return data
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2010-2011 OpenStack Foundation
|
||||
# Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
@@ -29,7 +27,7 @@ class TestCase(base.BaseTestCase):
|
||||
"""Base test case class before singleton protection is added."""
|
||||
|
||||
def setUp(self):
|
||||
super(TestCase, self).setUp()
|
||||
super().setUp()
|
||||
|
||||
self.builtin_content = os_service_types.service_types.BUILTIN_DATA
|
||||
self.builtin_version = self.builtin_content['version']
|
||||
@@ -41,111 +39,214 @@ class TestCase(base.BaseTestCase):
|
||||
self.remote_content['version'] = self.remote_version
|
||||
|
||||
|
||||
class ServiceDataMixin(object):
|
||||
|
||||
class ServiceDataMixin:
|
||||
scenarios = [
|
||||
('compute', dict(
|
||||
service_type='compute', official='compute', aliases=[],
|
||||
all_types=['compute'],
|
||||
api_reference='compute', api_reference_project=None,
|
||||
is_secondary=False, all_services=['compute'],
|
||||
is_known=True, is_alias=False, is_official=True, project='nova')),
|
||||
('volumev2', dict(
|
||||
service_type='volumev2', official='block-storage', aliases=[],
|
||||
all_types=['block-storage', 'volumev3', 'volumev2', 'volume',
|
||||
'block-store'],
|
||||
api_reference='block-storage', api_reference_project=None,
|
||||
is_known=True, is_alias=True, is_official=False,
|
||||
is_secondary=False, all_services=['block-storage'],
|
||||
project='cinder')),
|
||||
('volumev3', dict(
|
||||
service_type='volumev3', official='block-storage', aliases=[],
|
||||
all_types=['block-storage', 'volumev3', 'volumev2', 'volume',
|
||||
'block-store'],
|
||||
api_reference='block-storage', api_reference_project=None,
|
||||
is_known=True, is_alias=True, is_official=False,
|
||||
is_secondary=False, all_services=['block-storage'],
|
||||
project='cinder')),
|
||||
('block-storage', dict(
|
||||
service_type='block-storage', official='block-storage',
|
||||
all_types=['block-storage', 'volumev3', 'volumev2', 'volume',
|
||||
'block-store'],
|
||||
api_reference='block-storage', api_reference_project=None,
|
||||
aliases=['volumev3', 'volumev2', 'volume', 'block-store'],
|
||||
is_known=True, is_alias=False, is_official=True,
|
||||
is_secondary=False, all_services=['block-storage'],
|
||||
project='cinder')),
|
||||
('block_storage', dict(
|
||||
service_type='block_storage', official='block-storage',
|
||||
all_types=['block-storage', 'volumev3', 'volumev2', 'volume',
|
||||
'block-store'],
|
||||
api_reference='block-storage', api_reference_project=None,
|
||||
aliases=['volumev3', 'volumev2', 'volume', 'block-store'],
|
||||
is_known=True, is_alias=False, is_official=True,
|
||||
is_secondary=False, all_services=['block-storage'],
|
||||
project='cinder')),
|
||||
('network', dict(
|
||||
service_type='network', official='network', aliases=[],
|
||||
all_types=['network'],
|
||||
api_reference='network', api_reference_project='neutron-lib',
|
||||
is_known=True, is_alias=False, is_official=True,
|
||||
is_secondary=False, all_services=['network'],
|
||||
project='neutron')),
|
||||
('placement', dict(
|
||||
service_type='placement', official='placement', aliases=[],
|
||||
all_types=['placement'], all_services=['placement'],
|
||||
api_reference='placement', api_reference_project=None,
|
||||
is_known=True, is_alias=False, is_official=True,
|
||||
is_secondary=False, project='placement')),
|
||||
('missing', dict(
|
||||
service_type='missing', official=None,
|
||||
aliases=[], all_services=[],
|
||||
all_types=['missing'],
|
||||
api_reference=None, api_reference_project=None,
|
||||
is_known=False, is_alias=False, is_official=False,
|
||||
is_secondary=False,
|
||||
project=None)),
|
||||
(
|
||||
'compute',
|
||||
dict(
|
||||
service_type='compute',
|
||||
official='compute',
|
||||
aliases=[],
|
||||
all_types=['compute'],
|
||||
api_reference='compute',
|
||||
api_reference_project=None,
|
||||
is_secondary=False,
|
||||
all_services=['compute'],
|
||||
is_known=True,
|
||||
is_alias=False,
|
||||
is_official=True,
|
||||
project='nova',
|
||||
),
|
||||
),
|
||||
(
|
||||
'volumev2',
|
||||
dict(
|
||||
service_type='volumev2',
|
||||
official='block-storage',
|
||||
aliases=[],
|
||||
all_types=[
|
||||
'block-storage',
|
||||
'volumev3',
|
||||
'volumev2',
|
||||
'volume',
|
||||
'block-store',
|
||||
],
|
||||
api_reference='block-storage',
|
||||
api_reference_project=None,
|
||||
is_known=True,
|
||||
is_alias=True,
|
||||
is_official=False,
|
||||
is_secondary=False,
|
||||
all_services=['block-storage'],
|
||||
project='cinder',
|
||||
),
|
||||
),
|
||||
(
|
||||
'volumev3',
|
||||
dict(
|
||||
service_type='volumev3',
|
||||
official='block-storage',
|
||||
aliases=[],
|
||||
all_types=[
|
||||
'block-storage',
|
||||
'volumev3',
|
||||
'volumev2',
|
||||
'volume',
|
||||
'block-store',
|
||||
],
|
||||
api_reference='block-storage',
|
||||
api_reference_project=None,
|
||||
is_known=True,
|
||||
is_alias=True,
|
||||
is_official=False,
|
||||
is_secondary=False,
|
||||
all_services=['block-storage'],
|
||||
project='cinder',
|
||||
),
|
||||
),
|
||||
(
|
||||
'block-storage',
|
||||
dict(
|
||||
service_type='block-storage',
|
||||
official='block-storage',
|
||||
all_types=[
|
||||
'block-storage',
|
||||
'volumev3',
|
||||
'volumev2',
|
||||
'volume',
|
||||
'block-store',
|
||||
],
|
||||
api_reference='block-storage',
|
||||
api_reference_project=None,
|
||||
aliases=['volumev3', 'volumev2', 'volume', 'block-store'],
|
||||
is_known=True,
|
||||
is_alias=False,
|
||||
is_official=True,
|
||||
is_secondary=False,
|
||||
all_services=['block-storage'],
|
||||
project='cinder',
|
||||
),
|
||||
),
|
||||
(
|
||||
'block_storage',
|
||||
dict(
|
||||
service_type='block_storage',
|
||||
official='block-storage',
|
||||
all_types=[
|
||||
'block-storage',
|
||||
'volumev3',
|
||||
'volumev2',
|
||||
'volume',
|
||||
'block-store',
|
||||
],
|
||||
api_reference='block-storage',
|
||||
api_reference_project=None,
|
||||
aliases=['volumev3', 'volumev2', 'volume', 'block-store'],
|
||||
is_known=True,
|
||||
is_alias=False,
|
||||
is_official=True,
|
||||
is_secondary=False,
|
||||
all_services=['block-storage'],
|
||||
project='cinder',
|
||||
),
|
||||
),
|
||||
(
|
||||
'network',
|
||||
dict(
|
||||
service_type='network',
|
||||
official='network',
|
||||
aliases=[],
|
||||
all_types=['network'],
|
||||
api_reference='network',
|
||||
api_reference_project='neutron-lib',
|
||||
is_known=True,
|
||||
is_alias=False,
|
||||
is_official=True,
|
||||
is_secondary=False,
|
||||
all_services=['network'],
|
||||
project='neutron',
|
||||
),
|
||||
),
|
||||
(
|
||||
'placement',
|
||||
dict(
|
||||
service_type='placement',
|
||||
official='placement',
|
||||
aliases=[],
|
||||
all_types=['placement'],
|
||||
all_services=['placement'],
|
||||
api_reference='placement',
|
||||
api_reference_project=None,
|
||||
is_known=True,
|
||||
is_alias=False,
|
||||
is_official=True,
|
||||
is_secondary=False,
|
||||
project='placement',
|
||||
),
|
||||
),
|
||||
(
|
||||
'missing',
|
||||
dict(
|
||||
service_type='missing',
|
||||
official=None,
|
||||
aliases=[],
|
||||
all_services=[],
|
||||
all_types=['missing'],
|
||||
api_reference=None,
|
||||
api_reference_project=None,
|
||||
is_known=False,
|
||||
is_alias=False,
|
||||
is_official=False,
|
||||
is_secondary=False,
|
||||
project=None,
|
||||
),
|
||||
),
|
||||
]
|
||||
|
||||
def test_get_service_type(self):
|
||||
if self.official:
|
||||
self.assertEqual(
|
||||
self.official,
|
||||
self.service_types.get_service_type(self.service_type))
|
||||
self.service_types.get_service_type(self.service_type),
|
||||
)
|
||||
else:
|
||||
self.assertIsNone(
|
||||
self.service_types.get_service_type(self.service_type))
|
||||
self.service_types.get_service_type(self.service_type)
|
||||
)
|
||||
|
||||
def test_get_service_type_permissive(self):
|
||||
self.assertEqual(
|
||||
self.official or self.service_type,
|
||||
self.service_types.get_service_type(
|
||||
self.service_type, permissive=True))
|
||||
self.service_type, permissive=True
|
||||
),
|
||||
)
|
||||
|
||||
def test_get_aliases(self):
|
||||
self.assertEqual(
|
||||
self.aliases,
|
||||
self.service_types.get_aliases(self.service_type))
|
||||
self.aliases, self.service_types.get_aliases(self.service_type)
|
||||
)
|
||||
|
||||
def test_is_known(self):
|
||||
self.assertEqual(
|
||||
self.is_known,
|
||||
self.service_types.is_known(self.service_type))
|
||||
self.is_known, self.service_types.is_known(self.service_type)
|
||||
)
|
||||
|
||||
def test_is_alias(self):
|
||||
self.assertEqual(
|
||||
self.is_alias,
|
||||
self.service_types.is_alias(self.service_type))
|
||||
self.is_alias, self.service_types.is_alias(self.service_type)
|
||||
)
|
||||
|
||||
def test_is_official(self):
|
||||
self.assertEqual(
|
||||
self.is_official,
|
||||
self.service_types.is_official(self.service_type))
|
||||
self.is_official, self.service_types.is_official(self.service_type)
|
||||
)
|
||||
|
||||
def test_get_project_name(self):
|
||||
self.assertEqual(
|
||||
self.project,
|
||||
self.service_types.get_project_name(self.service_type))
|
||||
self.service_types.get_project_name(self.service_type),
|
||||
)
|
||||
|
||||
def test_get_service_data(self):
|
||||
service_data = self.service_types.get_service_data(self.service_type)
|
||||
@@ -163,11 +264,13 @@ class ServiceDataMixin(object):
|
||||
self.assertEqual(self.official, service_data['service_type'])
|
||||
self.assertEqual(
|
||||
api_url.format(api_reference=self.api_reference),
|
||||
service_data['api_reference'])
|
||||
service_data['api_reference'],
|
||||
)
|
||||
|
||||
def test_get_official_service_data(self):
|
||||
service_data = self.service_types.get_official_service_data(
|
||||
self.service_type)
|
||||
self.service_type
|
||||
)
|
||||
# TODO(mordred) Once all the docs have been aligned, remove
|
||||
# self.api_reference and replace with self.service_type
|
||||
api_url = 'https://docs.openstack.org/api-ref/{api_reference}/'
|
||||
@@ -182,14 +285,16 @@ class ServiceDataMixin(object):
|
||||
self.assertEqual(self.official, service_data['service_type'])
|
||||
self.assertEqual(
|
||||
api_url.format(api_reference=self.api_reference),
|
||||
service_data['api_reference'])
|
||||
service_data['api_reference'],
|
||||
)
|
||||
|
||||
def test_empty_project_error(self):
|
||||
if not self.project:
|
||||
self.assertRaises(
|
||||
ValueError,
|
||||
self.service_types.get_service_data_for_project,
|
||||
self.project)
|
||||
self.project,
|
||||
)
|
||||
|
||||
def test_get_service_data_for_project(self):
|
||||
if self.is_secondary:
|
||||
@@ -200,7 +305,8 @@ class ServiceDataMixin(object):
|
||||
return
|
||||
|
||||
service_data = self.service_types.get_service_data_for_project(
|
||||
self.project)
|
||||
self.project
|
||||
)
|
||||
# TODO(mordred) Once all the docs have been aligned, remove
|
||||
# self.api_reference and replace with self.service_type
|
||||
api_url = 'https://docs.openstack.org/api-ref/{api_reference}/'
|
||||
@@ -209,18 +315,20 @@ class ServiceDataMixin(object):
|
||||
if self.api_reference_project:
|
||||
self.assertEqual(
|
||||
self.api_reference_project,
|
||||
service_data['api_reference_project'])
|
||||
service_data['api_reference_project'],
|
||||
)
|
||||
else:
|
||||
self.assertEqual(self.project, service_data['project'])
|
||||
self.assertEqual(self.official, service_data['service_type'])
|
||||
self.assertEqual(
|
||||
api_url.format(api_reference=self.api_reference),
|
||||
service_data['api_reference'])
|
||||
service_data['api_reference'],
|
||||
)
|
||||
|
||||
def test_get_all_types(self):
|
||||
self.assertEqual(
|
||||
self.all_types,
|
||||
self.service_types.get_all_types(self.service_type))
|
||||
self.all_types, self.service_types.get_all_types(self.service_type)
|
||||
)
|
||||
|
||||
def test_all_get_service_data_for_project(self):
|
||||
if not self.project:
|
||||
@@ -228,19 +336,28 @@ class ServiceDataMixin(object):
|
||||
return
|
||||
|
||||
all_data = self.service_types.get_all_service_data_for_project(
|
||||
self.project)
|
||||
for (index, data) in enumerate(all_data):
|
||||
self.project
|
||||
)
|
||||
for index, data in enumerate(all_data):
|
||||
self.assertEqual(
|
||||
data,
|
||||
self.service_types.get_service_data(self.all_services[index]))
|
||||
self.service_types.get_service_data(self.all_services[index]),
|
||||
)
|
||||
|
||||
|
||||
class TemporaryFileMixin(base.BaseTestCase):
|
||||
|
||||
def create_temp_file(self, mode='w', suffix='', prefix='tmp', dir=None,
|
||||
text=False, delete=True):
|
||||
fd, name = tempfile.mkstemp(suffix=suffix, prefix=prefix, dir=dir,
|
||||
text=text)
|
||||
def create_temp_file(
|
||||
self,
|
||||
mode='w',
|
||||
suffix='',
|
||||
prefix='tmp',
|
||||
dir=None,
|
||||
text=False,
|
||||
delete=True,
|
||||
):
|
||||
fd, name = tempfile.mkstemp(
|
||||
suffix=suffix, prefix=prefix, dir=dir, text=text
|
||||
)
|
||||
fd = os.fdopen(fd, mode)
|
||||
if delete:
|
||||
self.addCleanup(self._delete_temp, fd, name)
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# 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
|
||||
@@ -21,6 +19,7 @@ Tests for `ServiceTypes` class builtin data.
|
||||
oslotest sets up a TempHomeDir for us, so there should be no ~/.cache files
|
||||
available in these tests.
|
||||
"""
|
||||
|
||||
from testscenarios import load_tests_apply_scenarios as load_tests # noqa
|
||||
|
||||
import os_service_types
|
||||
@@ -28,9 +27,8 @@ from os_service_types.tests import base
|
||||
|
||||
|
||||
class TestBuiltin(base.TestCase, base.ServiceDataMixin):
|
||||
|
||||
def setUp(self):
|
||||
super(TestBuiltin, self).setUp()
|
||||
super().setUp()
|
||||
# Make an object with no network access
|
||||
self.service_types = os_service_types.ServiceTypes()
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# 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
|
||||
@@ -27,9 +25,8 @@ from os_service_types.tests import base
|
||||
|
||||
|
||||
class TestData(base.TestCase, base.TemporaryFileMixin):
|
||||
|
||||
def setUp(self):
|
||||
super(TestData, self).setUp()
|
||||
super().setUp()
|
||||
|
||||
def test_load(self):
|
||||
json_data = {'some_key': 'some_value'}
|
||||
@@ -39,13 +36,18 @@ class TestData(base.TestCase, base.TemporaryFileMixin):
|
||||
|
||||
def test_load_service_types(self):
|
||||
json_data = data.read_data('service-types.json')
|
||||
for key in ["all_types_by_service_type", "forward",
|
||||
"primary_service_by_project", "reverse"]:
|
||||
for key in [
|
||||
"all_types_by_service_type",
|
||||
"forward",
|
||||
"primary_service_by_project",
|
||||
"reverse",
|
||||
]:
|
||||
self.assertIn(key, json_data)
|
||||
|
||||
def test_load_non_existing(self):
|
||||
self.assertRaises(FileNotFoundError, data.read_data,
|
||||
'/non-existing-file')
|
||||
self.assertRaises(
|
||||
FileNotFoundError, data.read_data, '/non-existing-file'
|
||||
)
|
||||
|
||||
def create_json(self, json_data):
|
||||
fd, name = self.create_temp_file(suffix='.json')
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# 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
|
||||
@@ -21,6 +19,7 @@ Tests for is_match logic
|
||||
oslotest sets up a TempHomeDir for us, so there should be no ~/.cache files
|
||||
available in these tests.
|
||||
"""
|
||||
|
||||
from testscenarios import load_tests_apply_scenarios as load_tests # noqa
|
||||
|
||||
import os_service_types
|
||||
@@ -28,32 +27,48 @@ from os_service_types.tests import base
|
||||
|
||||
|
||||
class TestMatch(base.TestCase):
|
||||
|
||||
scenarios = [
|
||||
('match-official', dict(
|
||||
requested='compute', found='compute', is_match=True)),
|
||||
('direct-match-unknown', dict(
|
||||
requested='unknown', found='unknown', is_match=True)),
|
||||
('volumev2-finds-block', dict(
|
||||
requested='volumev2', found='block-storage', is_match=True)),
|
||||
('volumev3-finds-block', dict(
|
||||
requested='volumev3', found='block-storage', is_match=True)),
|
||||
('block-finds-volumev2', dict(
|
||||
requested='block-storage', found='volumev2', is_match=True)),
|
||||
('block-finds-volumev3', dict(
|
||||
requested='block-storage', found='volumev3', is_match=True)),
|
||||
('volumev2-not-volumev3', dict(
|
||||
requested='volumev2', found='volumev3', is_match=False)),
|
||||
('non-match', dict(
|
||||
requested='unknown', found='compute', is_match=False)),
|
||||
(
|
||||
'match-official',
|
||||
dict(requested='compute', found='compute', is_match=True),
|
||||
),
|
||||
(
|
||||
'direct-match-unknown',
|
||||
dict(requested='unknown', found='unknown', is_match=True),
|
||||
),
|
||||
(
|
||||
'volumev2-finds-block',
|
||||
dict(requested='volumev2', found='block-storage', is_match=True),
|
||||
),
|
||||
(
|
||||
'volumev3-finds-block',
|
||||
dict(requested='volumev3', found='block-storage', is_match=True),
|
||||
),
|
||||
(
|
||||
'block-finds-volumev2',
|
||||
dict(requested='block-storage', found='volumev2', is_match=True),
|
||||
),
|
||||
(
|
||||
'block-finds-volumev3',
|
||||
dict(requested='block-storage', found='volumev3', is_match=True),
|
||||
),
|
||||
(
|
||||
'volumev2-not-volumev3',
|
||||
dict(requested='volumev2', found='volumev3', is_match=False),
|
||||
),
|
||||
(
|
||||
'non-match',
|
||||
dict(requested='unknown', found='compute', is_match=False),
|
||||
),
|
||||
]
|
||||
|
||||
def setUp(self):
|
||||
super(TestMatch, self).setUp()
|
||||
super().setUp()
|
||||
# Make an object with no network access
|
||||
self.service_types = os_service_types.ServiceTypes()
|
||||
|
||||
def test_is_match(self):
|
||||
self.assertEqual(
|
||||
self.is_match,
|
||||
self.service_types.is_match(self.requested, self.found))
|
||||
self.service_types.is_match(self.requested, self.found),
|
||||
)
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# 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
|
||||
@@ -24,7 +22,6 @@ from os_service_types.tests import base
|
||||
|
||||
|
||||
class TestMisc(base.TestCase):
|
||||
|
||||
def test_normalize(self):
|
||||
self.assertEqual('foo-bar', service_types._normalize_type('foo_bar'))
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# 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
|
||||
@@ -21,6 +19,7 @@ Tests for `ServiceTypes` class remote data.
|
||||
oslotest sets up a TempHomeDir for us, so there should be no ~/.cache files
|
||||
available in these tests.
|
||||
"""
|
||||
|
||||
from requests_mock.contrib import fixture as rm_fixture
|
||||
from testscenarios import load_tests_apply_scenarios as load_tests # noqa
|
||||
|
||||
@@ -32,20 +31,22 @@ from os_service_types.tests import base
|
||||
|
||||
|
||||
class TestRemote(base.TestCase, base.ServiceDataMixin):
|
||||
|
||||
def setUp(self):
|
||||
super(TestRemote, self).setUp()
|
||||
super().setUp()
|
||||
# Set up a requests_mock fixture for all HTTP traffic
|
||||
adapter = self.useFixture(rm_fixture.Fixture())
|
||||
adapter.register_uri(
|
||||
'GET', os_service_types.service_types.SERVICE_TYPES_URL,
|
||||
'GET',
|
||||
os_service_types.service_types.SERVICE_TYPES_URL,
|
||||
json=self.remote_content,
|
||||
headers={'etag': self.getUniqueString('etag')})
|
||||
headers={'etag': self.getUniqueString('etag')},
|
||||
)
|
||||
# use keystoneauth1 to get a Sessiom with no auth information
|
||||
self.session = keystoneauth1.session.Session()
|
||||
# Make an object that fetches from the network
|
||||
self.service_types = os_service_types.ServiceTypes(
|
||||
session=self.session)
|
||||
session=self.session
|
||||
)
|
||||
self.assertEqual(1, len(adapter.request_history))
|
||||
|
||||
def test_remote_version(self):
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# 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
|
||||
@@ -18,14 +16,14 @@ test_singleton
|
||||
|
||||
Tests for `get_service_types` singleton factory function.
|
||||
"""
|
||||
|
||||
import os_service_types
|
||||
from os_service_types.tests import base
|
||||
|
||||
|
||||
class TestSingleton(base.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestSingleton, self).setUp()
|
||||
super().setUp()
|
||||
# Make an object with no network access
|
||||
self.service_types = os_service_types.get_service_types()
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# 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
|
||||
@@ -18,6 +16,7 @@ test_warn
|
||||
|
||||
Tests for warnings
|
||||
"""
|
||||
|
||||
import warnings
|
||||
|
||||
import os_service_types
|
||||
@@ -26,9 +25,8 @@ from os_service_types.tests import base
|
||||
|
||||
|
||||
class TestWarnOn(base.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestWarnOn, self).setUp()
|
||||
super().setUp()
|
||||
# Cause all warnings to always be triggered.
|
||||
warnings.simplefilter("always")
|
||||
self.service_types = os_service_types.ServiceTypes(warn=True)
|
||||
@@ -46,9 +44,8 @@ class TestWarnOn(base.TestCase):
|
||||
|
||||
|
||||
class TestWarnOff(base.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestWarnOff, self).setUp()
|
||||
super().setUp()
|
||||
# Cause all warnings to always be triggered.
|
||||
warnings.simplefilter("always")
|
||||
self.service_types = os_service_types.ServiceTypes()
|
||||
|
||||
17
pyproject.toml
Normal file
17
pyproject.toml
Normal file
@@ -0,0 +1,17 @@
|
||||
[tool.ruff]
|
||||
line-length = 79
|
||||
target-version = "py310"
|
||||
|
||||
[tool.ruff.format]
|
||||
quote-style = "preserve"
|
||||
docstring-code-format = true
|
||||
|
||||
[tool.ruff.lint]
|
||||
select = ["E4", "E7", "E9", "F", "S", "U"]
|
||||
ignore = [
|
||||
# we only use asserts for type narrowing
|
||||
"S101",
|
||||
]
|
||||
|
||||
[tool.ruff.lint.per-file-ignores]
|
||||
"os_service_types/tests/*" = ["S"]
|
||||
@@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# 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
|
||||
@@ -52,7 +51,7 @@ source_suffix = '.rst'
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
copyright = u'2017, OpenStack Developers'
|
||||
copyright = '2017, OpenStack Developers'
|
||||
|
||||
# openstackdocstheme options
|
||||
openstackdocs_repo_name = 'openstack/os-service-types'
|
||||
@@ -199,9 +198,13 @@ htmlhelp_basename = 'os_service_typesReleaseNotesdoc'
|
||||
# (source start file, target name, title,
|
||||
# author, documentclass [howto, manual, or own class]).
|
||||
latex_documents = [
|
||||
('index', 'os_service_typesReleaseNotes.tex',
|
||||
u'os_service_types Release Notes Documentation',
|
||||
u'OpenStack Foundation', 'manual'),
|
||||
(
|
||||
'index',
|
||||
'os_service_typesReleaseNotes.tex',
|
||||
'os_service_types Release Notes Documentation',
|
||||
'OpenStack Foundation',
|
||||
'manual',
|
||||
),
|
||||
]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
@@ -230,9 +233,13 @@ latex_documents = [
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
('index', 'os_service_typesrereleasenotes',
|
||||
u'os_service_types Release Notes Documentation',
|
||||
[u'OpenStack Developers'], 1)
|
||||
(
|
||||
'index',
|
||||
'os_service_typesrereleasenotes',
|
||||
'os_service_types Release Notes Documentation',
|
||||
['OpenStack Developers'],
|
||||
1,
|
||||
)
|
||||
]
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
@@ -245,11 +252,15 @@ man_pages = [
|
||||
# (source start file, target name, title, author,
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
('index', 'os_service_types ReleaseNotes',
|
||||
u'os_service_types Release Notes Documentation',
|
||||
u'OpenStack Developers', 'os_service_typesReleaseNotes',
|
||||
'One line description of project.',
|
||||
'Miscellaneous'),
|
||||
(
|
||||
'index',
|
||||
'os_service_types ReleaseNotes',
|
||||
'os_service_types Release Notes Documentation',
|
||||
'OpenStack Developers',
|
||||
'os_service_typesReleaseNotes',
|
||||
'One line description of project.',
|
||||
'Miscellaneous',
|
||||
),
|
||||
]
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
|
||||
4
setup.py
4
setup.py
@@ -16,6 +16,4 @@
|
||||
# THIS FILE IS MANAGED BY THE GLOBAL REQUIREMENTS REPO - DO NOT EDIT
|
||||
import setuptools
|
||||
|
||||
setuptools.setup(
|
||||
setup_requires=['pbr>=2.0.0'],
|
||||
pbr=True)
|
||||
setuptools.setup(setup_requires=['pbr>=2.0.0'], pbr=True)
|
||||
|
||||
Reference in New Issue
Block a user