diff --git a/distil/api/web.py b/distil/api/web.py index b23159c..42927b4 100644 --- a/distil/api/web.py +++ b/distil/api/web.py @@ -38,7 +38,7 @@ from keystonemiddleware import auth_token from .helpers import returns_json, json_must, validate_tenant_id, require_admin from .helpers import require_admin_or_owner -from urlparse import urlparse +from six.moves.urllib import parse as urlparse from oslo_log import log from oslo_config import cfg diff --git a/distil/auth.py b/distil/auth.py index b097391..17f6353 100644 --- a/distil/auth.py +++ b/distil/auth.py @@ -15,7 +15,7 @@ import requests import json import urllib -import config +from distil import config # Provides authentication against Openstack from keystoneclient.v2_0 import client as KeystoneClient diff --git a/distil/database.py b/distil/database.py index d780aa5..42e3ba5 100644 --- a/distil/database.py +++ b/distil/database.py @@ -17,9 +17,9 @@ from .models import Resource, UsageEntry, Tenant, SalesOrder, _Last_Run from distil.constants import dawn_of_time from datetime import timedelta import json -import config +from distil import config import logging as log -import helpers +from distil import helpers class Database(object): diff --git a/distil/erp/drivers/odoo.py b/distil/erp/drivers/odoo.py index ec20a7a..437870f 100644 --- a/distil/erp/drivers/odoo.py +++ b/distil/erp/drivers/odoo.py @@ -433,8 +433,9 @@ class OdooDriver(driver.BaseDriver): price_spec = price_mapping[service_name] # Convert volume according to unit in price definition. - volume = general.convert_to(volume, unit, price_spec['unit']) - cost = (round(volume * Decimal(price_spec['rate']), + volume = float(general.convert_to(volume, unit, + price_spec['unit'])) + cost = (round(volume * price_spec['rate'], constants.PRICE_DIGITS) if price_spec['rate'] else 0) @@ -461,7 +462,8 @@ class OdooDriver(driver.BaseDriver): } ) - result = {'total_cost': round(total_cost, constants.PRICE_DIGITS)} + result = {'total_cost': round(float(total_cost), + constants.PRICE_DIGITS)} if detailed: result.update({'details': cost_details}) diff --git a/distil/helpers.py b/distil/helpers.py index c5c87ae..e1ed207 100644 --- a/distil/helpers.py +++ b/distil/helpers.py @@ -17,7 +17,7 @@ from cinderclient.v2 import client as cinderclient from glanceclient import client as glanceclient from keystoneclient.v2_0 import client as keystoneclient from decimal import Decimal -import config +from distil import config import math import logging as log diff --git a/distil/interface.py b/distil/interface.py index bf77230..16d1071 100644 --- a/distil/interface.py +++ b/distil/interface.py @@ -14,14 +14,14 @@ import requests import json -import auth -from constants import date_format, other_date_format -import config +from distil import auth +from distil import constants +from distil import config from datetime import timedelta, datetime from contextlib import contextmanager import logging as log -import urlparse +from six.moves.urllib import parse as urlparse @contextmanager @@ -85,12 +85,12 @@ def add_dates(start, end): { "field": "timestamp", "op": "ge", - "value": start.strftime(date_format) + "value": start.strftime(constants.date_format) }, { "field": "timestamp", "op": "lt", - "value": end.strftime(date_format) + "value": end.strftime(constants.date_format) } ] @@ -103,10 +103,10 @@ def sort_entries(data): for entry in data: try: entry['timestamp'] = datetime.strptime( - entry['timestamp'], date_format) + entry['timestamp'], constants.date_format) except ValueError: entry['timestamp'] = datetime.strptime( - entry['timestamp'], other_date_format) + entry['timestamp'], constants.other_date_format) return sorted(data, key=lambda x: x['timestamp']) diff --git a/distil/service/api/v2/measurements.py b/distil/service/api/v2/measurements.py index 61b373c..a578918 100644 --- a/distil/service/api/v2/measurements.py +++ b/distil/service/api/v2/measurements.py @@ -35,7 +35,7 @@ def _build_project_dict(project, usage): for entry in usage: service = {'name': entry.get('service'), - 'volume': entry.get('volume'), + 'volume': str(entry.get('volume')), 'unit': entry.get('unit')} resource = project_dict['resources'][entry.get('resource_id')] diff --git a/distil/tests/unit/api/test_api.py b/distil/tests/unit/api/test_api.py index f579718..b24fcdb 100644 --- a/distil/tests/unit/api/test_api.py +++ b/distil/tests/unit/api/test_api.py @@ -44,7 +44,7 @@ class TestAPI(base.APITest): self.assertEqual( {'versions': [{'id': 'v2', 'status': 'CURRENT'}]}, - json.loads(ret.data) + json.loads(ret.get_data(as_text=True)) ) @mock.patch('distil.erp.drivers.odoo.OdooDriver.get_products') @@ -55,7 +55,7 @@ class TestAPI(base.APITest): ret = self.client.get('/v2/products') - self.assertEqual({'products': []}, json.loads(ret.data)) + self.assertEqual({'products': []}, json.loads(ret.get_data(as_text=True))) @mock.patch('distil.erp.drivers.odoo.OdooDriver.get_products') @mock.patch('odoorpc.ODOO') @@ -72,7 +72,7 @@ class TestAPI(base.APITest): 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)) + self.assertEqual({'products': []}, json.loads(ret.get_data(as_text=True))) @mock.patch('distil.common.openstack.get_regions') def test_products_get_with_invalid_regions(self, mock_regions): @@ -138,7 +138,7 @@ class TestAPI(base.APITest): } } }, - json.loads(ret.data) + json.loads(ret.get_data(as_text=True)) ) @mock.patch('distil.erp.drivers.odoo.OdooDriver.get_invoices') @@ -177,7 +177,7 @@ class TestAPI(base.APITest): 'project_id': default_project, 'invoices': {} }, - json.loads(ret.data) + json.loads(ret.get_data(as_text=True)) ) def test_get_other_project_invoice_not_admin(self): @@ -196,7 +196,7 @@ class TestAPI(base.APITest): self._setup_policy({"rating:invoices:get": "rule:admin_or_owner"}) ret = self.client.get(url, headers={'X-Tenant-Id': default_project}) - self.assertEqual(403, json.loads(ret.data).get('error_code')) + self.assertEqual(403, json.loads(ret.get_data(as_text=True)).get('error_code')) @mock.patch('distil.erp.drivers.odoo.OdooDriver.get_quotations') @mock.patch('odoorpc.ODOO') @@ -205,7 +205,7 @@ class TestAPI(base.APITest): default_project = 'tenant_1' res_id = 'instance_1' - today = date.today() + today = datetime.utcnow() datetime_today = datetime(today.year, today.month, today.day) db_api.project_add( @@ -241,7 +241,7 @@ class TestAPI(base.APITest): 'end': str(datetime_today), 'project_name': 'default_project', 'project_id': default_project, - 'quotations': {str(today): {}} + 'quotations': {today.strftime("%Y-%m-%d"): {}} }, - json.loads(ret.data) + json.loads(ret.get_data(as_text=True)) ) diff --git a/distil/tests/unit/common/test_cache.py b/distil/tests/unit/common/test_cache.py index 9ee0b0d..3a2be3e 100644 --- a/distil/tests/unit/common/test_cache.py +++ b/distil/tests/unit/common/test_cache.py @@ -47,5 +47,5 @@ class TestCache(base.DistilTestCase): return "evening, Tom" name = 'Tom' - for x in xrange(0, 2): + for x in range(0, 2): self.assertEqual(test(name), 'hello, Tom') diff --git a/distil/tests/unit/erp/drivers/test_odoo.py b/distil/tests/unit/erp/drivers/test_odoo.py index 535b4a4..66aed13 100644 --- a/distil/tests/unit/erp/drivers/test_odoo.py +++ b/distil/tests/unit/erp/drivers/test_odoo.py @@ -15,7 +15,7 @@ from collections import namedtuple from datetime import datetime - +from decimal import Decimal import mock from distil.erp.drivers import odoo @@ -338,7 +338,7 @@ class TestOdooDriver(base.DistilTestCase): detailed=True ) - self.assertEqual( + self.assertDictEqual( { 'total_cost': 0.03, 'details': { diff --git a/distil/tests/unit/service/api/v2/test_measurements.py b/distil/tests/unit/service/api/v2/test_measurements.py index 0cab70c..9ee56de 100644 --- a/distil/tests/unit/service/api/v2/test_measurements.py +++ b/distil/tests/unit/service/api/v2/test_measurements.py @@ -76,13 +76,13 @@ class MeasurementsTest(base.DistilWithDbTestCase): '111': { 'name': 'resource1', 'services': [ - {'name': 'srv1', 'volume': 10, 'unit': 'byte'} + {'name': 'srv1', 'volume': '10', 'unit': 'byte'} ] }, '222': { 'name': 'resource2', 'services': [ - {'name': 'srv2', 'volume': 20, 'unit': 'byte'} + {'name': 'srv2', 'volume': '20', 'unit': 'byte'} ] } } diff --git a/distil/transformer/arithmetic.py b/distil/transformer/arithmetic.py index 169e590..f9167eb 100644 --- a/distil/transformer/arithmetic.py +++ b/distil/transformer/arithmetic.py @@ -30,7 +30,8 @@ class MaxTransformer(BaseTransformer): """ def _transform_usage(self, meter_name, raw_data, start_at, end_at): - max_vol = max([v["volume"] for v in raw_data]) if len(raw_data) else 0 + max_vol = max([(v["volume"] if v["volume"] else 0) + for v in raw_data]) if len(raw_data) else 0 max_vol = max_vol if max_vol else 0 hours = (end_at - start_at).total_seconds() / 3600.0 @@ -49,7 +50,8 @@ class StorageMaxTransformer(BaseTransformer): if not data: return None - max_vol = max([v["volume"] for v in data]) or 0 + max_vol = max([(v["volume"] if v["volume"] else 0) + for v in data]) or 0 if "volume_type" in data[-1]['metadata']: vtype = data[-1]['metadata']['volume_type'] diff --git a/distil/transformers.py b/distil/transformers.py index 0c3ece2..158d6c9 100644 --- a/distil/transformers.py +++ b/distil/transformers.py @@ -12,9 +12,9 @@ # License for the specific language governing permissions and limitations # under the License. -import constants -import helpers -import config +from distil import constants +from distil import helpers +from distil import config import logging as log from distil.constants import iso_time, iso_date @@ -217,7 +217,8 @@ class GaugeMax(Transformer): """ def _transform_usage(self, name, data, start, end): - max_vol = max([v["counter_volume"] for v in data]) if len(data) else 0 + max_vol = max([(v["counter_volume"] if v["counter_volume"] else 0) + for v in data]) if len(data) else 0 if max_vol is None: max_vol = 0 log.warning("None max_vol value for %s in window: %s - %s " % @@ -239,7 +240,8 @@ class StorageMax(Transformer): if not data: return None - max_vol = max([v["counter_volume"] for v in data]) + max_vol = max([(v["counter_volume"] if v["counter_volume"] else 0) + for v in data]) if max_vol is None: max_vol = 0 diff --git a/tox.ini b/tox.ini index 28df0d5..1fa04a8 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py34,py27,pep8 +envlist = py35,py27,pep8 minversion = 1.6 skipsdist = True @@ -20,10 +20,6 @@ whitelist_externals = rm find -[testenv:py33] -deps = -r{toxinidir}/requirements-py3.txt - -r{toxinidir}/test-requirements-py3.txt - [testenv:cover] commands = python setup.py testr --coverage --testr-args='{posargs}'