Compare commits
6 Commits
unmaintain
...
rocky-em
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
37c6bb0c8b | ||
|
|
1e0ed2f044 | ||
|
|
c1596862ae | ||
|
|
56c5badada | ||
| 97e2a29496 | |||
| ce7aef7912 |
@@ -1,4 +1,5 @@
|
||||
[gerrit]
|
||||
host=review.openstack.org
|
||||
host=review.opendev.org
|
||||
port=29418
|
||||
project=openstack/python-cloudkittyclient.git
|
||||
defaultbranch=stable/rocky
|
||||
|
||||
11
.zuul.yaml
11
.zuul.yaml
@@ -18,15 +18,19 @@
|
||||
- ^releasenotes/.*$
|
||||
vars:
|
||||
devstack_plugins:
|
||||
cloudkitty: https://git.openstack.org/openstack/cloudkitty
|
||||
cloudkitty: https://opendev.org/openstack/cloudkitty
|
||||
devstack_services:
|
||||
ck-api: true
|
||||
horizon: false
|
||||
tox_install_siblings: false
|
||||
zuul_work_dir: src/git.openstack.org/openstack/python-cloudkittyclient
|
||||
zuul_work_dir: src/opendev.org/openstack/python-cloudkittyclient
|
||||
tox_envlist: functional
|
||||
|
||||
- project:
|
||||
templates:
|
||||
- openstack-python-jobs
|
||||
- openstack-python35-jobs
|
||||
- openstackclient-plugin-jobs
|
||||
check:
|
||||
jobs:
|
||||
- cloudkittyclient-devstack-functional:
|
||||
@@ -35,3 +39,6 @@
|
||||
jobs:
|
||||
- cloudkittyclient-devstack-functional:
|
||||
voting: true
|
||||
post:
|
||||
jobs:
|
||||
- openstack-tox-cover
|
||||
|
||||
@@ -35,7 +35,7 @@ class BaseFunctionalTest(utils.BaseTestCase):
|
||||
if p.returncode != 0:
|
||||
raise RuntimeError('"{cmd}" returned {val}: {msg}'.format(
|
||||
cmd=' '.join(cmd), val=p.returncode, msg=stderr))
|
||||
return json.loads(stdout) if has_output else None
|
||||
return json.loads(stdout.decode('ascii')) if has_output else None
|
||||
|
||||
def openstack(self, action,
|
||||
flags='', params='', fmt='-f json', has_output=True):
|
||||
|
||||
48
cloudkittyclient/tests/unit/v1/test_rating.py
Normal file
48
cloudkittyclient/tests/unit/v1/test_rating.py
Normal file
@@ -0,0 +1,48 @@
|
||||
# Copyright 2019 Objectif Libre
|
||||
#
|
||||
# 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 decimal
|
||||
|
||||
from cloudkittyclient import exc
|
||||
from cloudkittyclient.tests.unit.v1 import base
|
||||
|
||||
|
||||
class TestRating(base.BaseAPIEndpointTestCase):
|
||||
|
||||
def test_quote_request(self):
|
||||
res_data = [{'usage': {
|
||||
'instance': [{
|
||||
'vol': {'unit': 'undef', 'qty': '1'},
|
||||
'rating': {'price': decimal.Decimal(1)},
|
||||
'desc': {
|
||||
'disk_total_display': 1,
|
||||
'image_id': 'c43a3e7d-c4e6-45d6-8c8d-e2832a45bc0a',
|
||||
'ram': 64,
|
||||
'ephemeral': 0,
|
||||
'vcpus': 1,
|
||||
'source_type': 'image',
|
||||
'disk_total': 1,
|
||||
'flavor_id': '42',
|
||||
'flavor': 'm1.nano',
|
||||
'disk': 1,
|
||||
'source_val': 'c43a3e7d-c4e6-45d6-8c8d-e2832a45bc0a'}
|
||||
}]
|
||||
}}]
|
||||
|
||||
self.rating.get_quotation(res_data=res_data)
|
||||
self.api_client.post.assert_called_once_with(
|
||||
'/v1/rating/quote/', json={'resources': res_data})
|
||||
|
||||
def test_get_quotation_no_res_data(self):
|
||||
self.assertRaises(exc.ArgumentRequired, self.rating.get_quotation)
|
||||
63
cloudkittyclient/tests/unit/v1/test_report_cli.py
Normal file
63
cloudkittyclient/tests/unit/v1/test_report_cli.py
Normal file
@@ -0,0 +1,63 @@
|
||||
# Copyright 2018 Objectif Libre
|
||||
#
|
||||
# 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 collections
|
||||
import mock
|
||||
|
||||
from cloudkittyclient.tests.unit.v1 import base
|
||||
from cloudkittyclient.v1 import report_cli
|
||||
|
||||
|
||||
class TestReportCli(base.BaseAPIEndpointTestCase):
|
||||
|
||||
def test_report_tenant_list(self):
|
||||
|
||||
class DummyAPIClient(object):
|
||||
def get_tenants(*args, **kwargs):
|
||||
return ['ee530dfc-319a-438f-9d43-346cfef501d6',
|
||||
'91743a9a-688b-4526-b568-7b501531176c',
|
||||
'4468704c-972e-4cfd-a342-9b71c493b79b']
|
||||
|
||||
class ClientWrap(object):
|
||||
report = DummyAPIClient()
|
||||
|
||||
class DummyParsedArgs(object):
|
||||
def __init__(self):
|
||||
self.begin = '2042-01-01T00:00:00'
|
||||
self.end = '2042-12-01T00:00:00'
|
||||
|
||||
class DummyCliTenantList(report_cli.CliTenantList):
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def __get_client_from_osc(*args):
|
||||
return ClientWrap()
|
||||
|
||||
parsed_args = DummyParsedArgs()
|
||||
cli_class_instance = DummyCliTenantList()
|
||||
|
||||
with mock.patch('cloudkittyclient.utils.get_client_from_osc',
|
||||
new=__get_client_from_osc):
|
||||
# NOTE(peschk_l): self is only used used to get a client so just we
|
||||
# just override __init__ in order to skip class instanciation. In
|
||||
# python3 we could just have passed None
|
||||
result = report_cli.CliTenantList.take_action(
|
||||
cli_class_instance, parsed_args)
|
||||
|
||||
assert len(result) == 2
|
||||
assert result[0] == ('Tenant ID', )
|
||||
assert isinstance(result[1], collections.Iterable)
|
||||
|
||||
for res in result[1]:
|
||||
assert isinstance(res, collections.Iterable)
|
||||
@@ -78,8 +78,10 @@ class RatingManager(base.BaseManager):
|
||||
"""
|
||||
if not kwargs.get('res_data', None):
|
||||
raise exc.ArgumentRequired("'res_data' argument is required.")
|
||||
url = self.get_url('quote')
|
||||
return self.api_client.post(url, kwargs['res_data'])
|
||||
url = self.get_url('quote', {})
|
||||
|
||||
body = {'resources': kwargs['res_data']}
|
||||
return self.api_client.post(url, json=body).json()
|
||||
|
||||
|
||||
class CliModuleGet(lister.Lister):
|
||||
|
||||
@@ -114,8 +114,11 @@ class CliTenantList(lister.Lister):
|
||||
raise exc.InvalidArgumentError(
|
||||
'Invalid timestamp "{}"'.format(value))
|
||||
client = utils.get_client_from_osc(self)
|
||||
return (('Tenant ID', ),
|
||||
(client.report.get_tenants(**vars(parsed_args)), ))
|
||||
tenants = client.report.get_tenants(**vars(parsed_args))
|
||||
output = []
|
||||
for tenant in tenants:
|
||||
output.append((tenant, ))
|
||||
return (('Tenant ID', ), output)
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(CliTenantList, self).get_parser(prog_name)
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
fixes:
|
||||
- |
|
||||
The ``rating.get_quotation`` method of the client has been fixed: the json
|
||||
body has been updated to match the API reference.
|
||||
2
tox.ini
2
tox.ini
@@ -5,7 +5,7 @@ skipsdist = True
|
||||
|
||||
[testenv]
|
||||
usedevelop = True
|
||||
install_command = pip install -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt} -U {opts} {packages}
|
||||
install_command = pip install -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt?h=stable/rocky} -U {opts} {packages}
|
||||
setenv =
|
||||
VIRTUAL_ENV={envdir}
|
||||
deps = -r{toxinidir}/requirements.txt
|
||||
|
||||
Reference in New Issue
Block a user