Add unit tests for api module

With this patch, distil coverage rate will be 71%

Change-Id: Ie7136b509171d3c3636fa883f4308f5a61cf4bf0
This commit is contained in:
Lingxian Kong 2017-06-12 16:47:22 +12:00
parent ea4c07c57a
commit 0e183ccf0d
7 changed files with 278 additions and 32 deletions

View File

@ -5,6 +5,7 @@ omit =
.tox/*
distil/tests/*
distil/api/web.py
distil/api/helpers.py
distil/auth.py
distil/database.py
distil/helpers.py

View File

@ -88,6 +88,7 @@ def usage_get(project_id, start_at, end_at):
return IMPL.usage_get(project_id, start_at, end_at)
# NOTE(lingxian): This method is not used anywhere but for testing purpose.
def usage_add(project_id, resource_id, samples, unit,
start_at, end_at):
"""If a tenant exists does nothing,
@ -101,9 +102,9 @@ def usages_add(project_id, resources, usage_entries, last_collect):
return IMPL.usages_add(project_id, resources, usage_entries, last_collect)
def resource_add(project_id, resource_id, resource_type, rawdata, metadata):
return IMPL.resource_add(project_id, resource_id, resource_type,
rawdata, metadata)
# NOTE(lingxian): This method is not used anywhere but for testing purpose.
def resource_add(project_id, resource_id, resource_info):
return IMPL.resource_add(project_id, resource_id, resource_info)
def project_add(values, last_collect=None):

View File

@ -207,8 +207,10 @@ def usage_add(project_id, resource_id, samples, unit,
volume=volume,
unit=unit,
resource_id=resource_id,
project_id=project_id,
start_at=start_at, end_at=end_at)
tenant_id=project_id,
start=start_at,
end=end_at,
created=datetime.utcnow())
resource_ref.save(session=session)
except sa.exc.InvalidRequestError as e:
# FIXME(flwang): I assume there should be a DBDuplicateEntry error
@ -271,11 +273,12 @@ def usages_add(project_id, resources, usage_entries, last_collect):
)
def resource_add(project_id, resource_id, resource_type, raw, metadata):
def resource_add(project_id, resource_id, resource_info):
session = get_session()
metadata = _merge_resource_metadata({'type': resource_type}, raw, metadata)
resource_ref = Resource(id=resource_id, project_id=project_id,
resource_type=resource_type, meta_data=metadata)
resource_ref = Resource(
id=resource_id, tenant_id=project_id, info=json.dumps(resource_info),
created=datetime.utcnow()
)
try:
resource_ref.save(session=session)
@ -299,28 +302,6 @@ def resource_get_by_ids(project_id, resource_ids):
return query.all()
def _merge_resource_metadata(md_dict, entry, md_def):
"""Strips metadata from the entry as defined in the config,
and merges it with the given metadata dict.
"""
for field, parameters in md_def.iteritems():
for _, source in enumerate(parameters['sources']):
try:
value = entry['resource_metadata'][source]
if 'template' in parameters:
md_dict[field] = parameters['template'] % value
break
else:
md_dict[field] = value
break
except KeyError:
# Just means we haven't found the right value yet.
# Or value isn't present.
pass
return md_dict
def get_project_locks(project_id):
session = get_session()

View File

@ -0,0 +1,36 @@
# Copyright (C) 2017 Catalyst IT Ltd
#
# 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 flask
from distil.api import v2 as api_v2
from distil.common import api
from distil.tests.unit import base
class APITest(base.DistilWithDbTestCase):
def setUp(self):
super(APITest, self).setUp()
self.app = flask.Flask(__name__)
@self.app.route('/', methods=['GET'])
def version_list():
return api.render({
"versions": [
{"id": "v2", "status": "CURRENT"}
]})
self.app.register_blueprint(api_v2.rest, url_prefix="/v2")
self.client = self.app.test_client()

View File

@ -0,0 +1,226 @@
# Copyright (C) 2017 Catalyst IT Ltd
#
# 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.
from datetime import date
from datetime import datetime
import json
from flask import url_for
import mock
from oslo_policy import policy as cpolicy
from distil.api import acl
from distil.common import constants
from distil.db import api as db_api
from distil.tests.unit.api import base
class TestAPI(base.APITest):
@classmethod
def setUpClass(cls):
acl.setup_policy()
def _setup_policy(self, policy):
rules = cpolicy.Rules.from_dict(policy)
acl.ENFORCER.set_rules(rules, use_conf=False)
self.addCleanup(acl.ENFORCER.clear)
def test_get_versions(self):
ret = self.client.get('/')
self.assertEqual(
{'versions': [{'id': 'v2', 'status': 'CURRENT'}]},
json.loads(ret.data)
)
@mock.patch('distil.erp.drivers.odoo.OdooDriver.get_products')
@mock.patch('odoorpc.ODOO')
def test_products_get_without_regions(self, mock_odoo,
mock_odoo_get_products):
mock_odoo_get_products.return_value = []
ret = self.client.get('/v2/products')
self.assertEqual({'products': []}, json.loads(ret.data))
@mock.patch('distil.erp.drivers.odoo.OdooDriver.get_products')
@mock.patch('odoorpc.ODOO')
@mock.patch('distil.common.openstack.get_regions')
def test_products_get_with_regions(self, mock_regions, mock_odoo,
mock_odoo_get_products):
class Region(object):
def __init__(self, id):
self.id = id
mock_regions.return_value = [Region('nz_1'), Region('nz_2')]
mock_odoo_get_products.return_value = []
ret = self.client.get('/v2/products?regions=nz_1,nz_2')
mock_odoo_get_products.assert_called_once_with(['nz_1', 'nz_2'])
self.assertEqual({'products': []}, json.loads(ret.data))
@mock.patch('distil.common.openstack.get_regions')
def test_products_get_with_invalid_regions(self, mock_regions):
class Region(object):
def __init__(self, id):
self.id = id
mock_regions.return_value = [Region('nz_1'), Region('nz_2')]
ret = self.client.get('/v2/products?regions=nz_1,nz_3')
self.assertEqual(404, ret.status_code)
def test_measurements_get(self):
default_project = 'tenant_1'
start = '2014-06-01T00:00:00'
end = '2014-07-01T00:00:00'
res_id = 'instance_1'
db_api.project_add(
{
'id': default_project,
'name': 'default_project',
'description': 'project for test'
}
)
db_api.resource_add(
default_project, res_id, {'type': 'Virtual Machine'}
)
db_api.usage_add(
default_project, res_id, {'instance': 100}, 'hour',
datetime.strptime(start, constants.iso_time),
datetime.strptime(end, constants.iso_time),
)
with self.app.test_request_context():
url = url_for(
'v2.measurements_get',
project_id=default_project,
start=start,
end=end
)
self._setup_policy({"rating:measurements:get": ""})
ret = self.client.get(url, headers={'X-Tenant-Id': default_project})
self.assertEqual(
{
'measurements': {
'start': '2014-06-01 00:00:00',
'end': '2014-07-01 00:00:00',
'project_name': 'default_project',
'project_id': default_project,
'resources': {
res_id: {
'type': 'Virtual Machine',
'services': [{
'name': 'instance',
'volume': '100.00',
'unit': 'hour'
}]
}
}
}
},
json.loads(ret.data)
)
@mock.patch('distil.erp.drivers.odoo.OdooDriver.get_invoices')
@mock.patch('odoorpc.ODOO')
def test_invoices_get(self, mock_odoo, mock_get_invoices):
default_project = 'tenant_1'
start = '2014-06-01T00:00:00'
end = '2014-07-01T00:00:00'
db_api.project_add(
{
'id': default_project,
'name': 'default_project',
'description': 'project for test'
}
)
mock_get_invoices.return_value = {}
with self.app.test_request_context():
url = url_for(
'v2.invoices_get',
project_id=default_project,
start=start,
end=end
)
self._setup_policy({"rating:invoices:get": ""})
ret = self.client.get(url, headers={'X-Tenant-Id': default_project})
self.assertEqual(
{
'start': '2014-06-01 00:00:00',
'end': '2014-07-01 00:00:00',
'project_name': 'default_project',
'project_id': default_project,
'invoices': {}
},
json.loads(ret.data)
)
@mock.patch('distil.erp.drivers.odoo.OdooDriver.get_quotations')
@mock.patch('odoorpc.ODOO')
def test_quotations_get(self, mock_odoo, mock_get_quotations):
self.override_config('keystone_authtoken', region_name='region-1')
default_project = 'tenant_1'
res_id = 'instance_1'
today = date.today()
datetime_today = datetime(today.year, today.month, today.day)
db_api.project_add(
{
'id': default_project,
'name': 'default_project',
'description': 'project for test'
}
)
db_api.resource_add(
default_project, res_id, {'type': 'Virtual Machine'}
)
db_api.usage_add(
default_project, res_id, {'instance': 100}, 'hour',
datetime_today,
datetime_today,
)
mock_get_quotations.return_value = {}
with self.app.test_request_context():
url = url_for(
'v2.quotations_get',
project_id=default_project,
)
self._setup_policy({"rating:quotations:get": ""})
ret = self.client.get(url, headers={'X-Tenant-Id': default_project})
self.assertEqual(
{
'start': str(datetime(today.year, today.month, 1)),
'end': str(datetime_today),
'project_name': 'default_project',
'project_id': default_project,
'quotations': {str(today): {}}
},
json.loads(ret.data)
)

View File

@ -25,8 +25,8 @@ from distil import context
from distil import config
from distil.db import api as db_api
class DistilTestCase(base.BaseTestCase):
class DistilTestCase(base.BaseTestCase):
config_file = None
def setUp(self):

View File

@ -13,3 +13,4 @@ testscenarios>=0.4
testtools>=0.9.34
WebTest>=2.0 # MIT
mock>=2.0 # BSD
Flask>=0.10,!=0.11,<1.0 # BSD