Improve test coverage
Change-Id: Iad45bf241db7a38efbb4c38b00f8f955f9810be7
This commit is contained in:
parent
b1aad7dd19
commit
8fad6419b8
|
@ -1,4 +1,4 @@
|
||||||
# Copyright (c) 2014 Catalyst IT Ltd.
|
# Copyright (c) 2017 Catalyst IT Ltd.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
|
@ -12,34 +12,45 @@
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
import collections
|
||||||
import datetime
|
import datetime
|
||||||
import math
|
import mock
|
||||||
import time
|
|
||||||
|
|
||||||
from mox3 import mox
|
from mox3 import mox
|
||||||
|
|
||||||
from distil_ui.api import distil
|
from distil_ui.content.billing import base
|
||||||
|
from distil_ui.content.billing import views
|
||||||
|
from django.utils import timezone
|
||||||
|
from horizon import forms
|
||||||
from openstack_dashboard.test import helpers as test
|
from openstack_dashboard.test import helpers as test
|
||||||
|
|
||||||
|
BILLITEM = collections.namedtuple('BillItem',
|
||||||
|
['id', 'resource', 'count', 'cost'])
|
||||||
|
|
||||||
|
|
||||||
class FakeUser(object):
|
class FakeUser(object):
|
||||||
roles = [{'name': 'admin'}]
|
roles = [{'name': 'admin'}]
|
||||||
|
authorized_tenants = ["tenant_name"]
|
||||||
|
|
||||||
|
def is_authenticated(self):
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
class FakeRequest(object):
|
class FakeRequest(object):
|
||||||
|
def _get(x, y):
|
||||||
|
if x == 'format' and y == 'html':
|
||||||
|
return 'csv'
|
||||||
|
return None
|
||||||
|
|
||||||
|
def is_ajax(self):
|
||||||
|
return False
|
||||||
|
|
||||||
user = FakeUser()
|
user = FakeUser()
|
||||||
|
session = mock.MagicMock()
|
||||||
|
GET = mock.MagicMock()
|
||||||
|
GET.get = _get
|
||||||
|
|
||||||
|
|
||||||
class FakeDistilClient(object):
|
class BaseBillingTests(test.TestCase):
|
||||||
"""A fake distil client for unit test."""
|
|
||||||
endpoint = 'http://localhost:8788'
|
|
||||||
request = FakeRequest()
|
|
||||||
|
|
||||||
def get_rated(self, tenant, start, end):
|
|
||||||
raise NotImplemented()
|
|
||||||
|
|
||||||
|
|
||||||
class BillingTests(test.TestCase):
|
|
||||||
"""FIXME(flwang): Move this test to rest_api_tests.py
|
"""FIXME(flwang): Move this test to rest_api_tests.py
|
||||||
|
|
||||||
Now we're putting the api test at here, since we don't want to hack
|
Now we're putting the api test at here, since we don't want to hack
|
||||||
|
@ -48,240 +59,118 @@ class BillingTests(test.TestCase):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(BillingTests, self).setUp()
|
super(BaseBillingTests, self).setUp()
|
||||||
self.mocker = mox.Mox()
|
self.mocker = mox.Mox()
|
||||||
|
self.billing = base.BaseBilling(FakeRequest(), 'my_project_id')
|
||||||
|
self.year = 2017
|
||||||
|
self.month = 1
|
||||||
|
self.day = 30
|
||||||
|
|
||||||
def test_calculate_end_date(self):
|
def test_today(self):
|
||||||
start = datetime.date(2015, 1, 1)
|
delta = datetime.timedelta(seconds=1)
|
||||||
end = distil._calculate_end_date(start)
|
self.assertTrue(self.billing.today - timezone.now() < delta)
|
||||||
self.assertEqual((end.year, end.month, end.day), (2015, 2, 1))
|
|
||||||
|
|
||||||
start = datetime.date(2015, 6, 1)
|
def test_get_start(self):
|
||||||
end = distil._calculate_end_date(start)
|
start = datetime.datetime(self.year, self.month, self.day, 0, 0, 0)
|
||||||
self.assertEqual((end.year, end.month, end.day), (2015, 7, 1))
|
self.assertEqual(self.billing.get_start(self.year, self.month,
|
||||||
|
self.day),
|
||||||
|
timezone.make_aware(start, timezone.utc))
|
||||||
|
|
||||||
start = datetime.date(2015, 12, 1)
|
def test_get_end(self):
|
||||||
end = distil._calculate_end_date(start)
|
end = datetime.datetime(self.year, self.month, self.day, 23, 59, 59)
|
||||||
self.assertEqual((end.year, end.month, end.day), (2016, 1, 1))
|
self.assertEqual(self.billing.get_end(self.year, self.month, self.day),
|
||||||
|
timezone.make_aware(end, timezone.utc))
|
||||||
|
|
||||||
def test_get_month_cost(self):
|
def test_get_date_range(self):
|
||||||
distilclient = self.mocker.CreateMock(FakeDistilClient)
|
args_start = (self.billing.today.year, self.billing.today.month, 1)
|
||||||
|
args_end = (self.billing.today.year, self.billing.today.month,
|
||||||
|
self.billing.today.day)
|
||||||
|
start = self.billing.get_start(*args_start)
|
||||||
|
end = self.billing.get_end(*args_end)
|
||||||
|
self.assertEqual(self.billing.get_date_range(),
|
||||||
|
(start, end))
|
||||||
|
|
||||||
resources = {"fake_uuid_1": {"services": [{
|
@mock.patch('distil_ui.content.billing.base.BaseBilling.get_form')
|
||||||
"volume": 2100,
|
def test_get_date_range_valid_form(self, mock_get_form):
|
||||||
"rate": 0.0005,
|
start = datetime.datetime(self.year, self.month, self.day, 0, 0, 0)
|
||||||
"cost": 1.05,
|
end = datetime.datetime(self.year, self.month, self.day, 23, 59, 59)
|
||||||
"name": "b1.standard",
|
myform = forms.DateForm({'start': start, 'end': end})
|
||||||
"unit": "gigabyte"}],
|
myform.data = {'start': start, 'end': end}
|
||||||
"total_cost": 1.05,
|
myform.cleaned_data = {'start': start, 'end': end}
|
||||||
"type": "Image",
|
mock_get_form.return_value = myform
|
||||||
"name": "cirros"},
|
self.assertEqual(self.billing.get_date_range(),
|
||||||
"fake_uuid_2": {"services": [{
|
(timezone.make_aware(start, timezone.utc),
|
||||||
"volume": 122,
|
timezone.make_aware(end, timezone.utc)))
|
||||||
"rate": 0.048,
|
|
||||||
"cost": 5.86,
|
|
||||||
"name": "m1.tiny",
|
|
||||||
"unit": "hour"}],
|
|
||||||
"total_cost": 5.86,
|
|
||||||
"type": "Virtual Machine",
|
|
||||||
"name": "dfgh"},
|
|
||||||
"fake_uuid_3": {"services": [{
|
|
||||||
"volume": 200,
|
|
||||||
"rate": 0.048,
|
|
||||||
"cost": 9.60,
|
|
||||||
"name": "m1.tiny",
|
|
||||||
"unit": "hour"}],
|
|
||||||
"total_cost": 9.60,
|
|
||||||
"type": "Virtual Machine",
|
|
||||||
"name": "abcd"},
|
|
||||||
"fake_uuid_4": {"services": [{"volume": 20.00,
|
|
||||||
"rate": 0.016,
|
|
||||||
"cost": 0.32,
|
|
||||||
"name": "n1.network",
|
|
||||||
"unit": "hour"},
|
|
||||||
{"volume": 10.00,
|
|
||||||
"rate": 0.016,
|
|
||||||
"cost": 0.16,
|
|
||||||
"name": "n1.network",
|
|
||||||
"unit": "hour"}],
|
|
||||||
"total_cost": 0.48,
|
|
||||||
"type": "Network",
|
|
||||||
"name": "public"}
|
|
||||||
}
|
|
||||||
|
|
||||||
result = {'usage': {"end": "2011-03-01 00:00:00", "name": "openstack",
|
def test_init_form(self):
|
||||||
"total_cost": 7.23,
|
start = datetime.date(self.billing.today.year,
|
||||||
"tenant_id": "7c3c506ad4b943f5bb12b9fb69478084",
|
self.billing.today.month, 1)
|
||||||
"start": "2011-02-01 00:00:00",
|
end = datetime.date.today()
|
||||||
"resources": resources
|
self.assertEqual(self.billing.init_form(), (start, end))
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
distilclient.get_rated([self.tenant.id],
|
def test_get_form(self):
|
||||||
'2011-02-01T00:00:00',
|
start = datetime.date(self.billing.today.year,
|
||||||
'2011-03-01T00:00:00').AndReturn(result)
|
self.billing.today.month, 1).strftime("%Y-%m-%d")
|
||||||
self.mocker.ReplayAll()
|
end = datetime.date.today().strftime("%Y-%m-%d")
|
||||||
|
self.assertEqual(self.billing.get_form().initial,
|
||||||
|
{"start": start, "end": end})
|
||||||
|
|
||||||
cost = [()]
|
def test_get_billing_list(self):
|
||||||
distil._get_month_cost(distilclient,
|
self.assertEqual(self.billing.get_billing_list(None, None), [])
|
||||||
self.tenant.id,
|
|
||||||
'2011-02-01T00:00:00',
|
|
||||||
'2011-03-01T00:00:00',
|
|
||||||
cost, 0)
|
|
||||||
self.assertEqual(16.99, cost[0][0])
|
|
||||||
self.assertEqual(3, len(cost[0][1]))
|
|
||||||
bill_items = {}
|
|
||||||
for b in cost[0][1]:
|
|
||||||
# Convert cost to string make sure the floating number is right
|
|
||||||
bill_items[b.resource] = (b.count, str(b.cost))
|
|
||||||
|
|
||||||
self.assertEqual((2, '0.48'), bill_items['Network'])
|
def test_csv_link(self):
|
||||||
self.assertEqual((2, '15.46'), bill_items['Compute'])
|
start = self.billing.today.strftime("%Y-%m-%d")
|
||||||
self.assertEqual((1, '1.05'), bill_items['Image'])
|
end = self.billing.today.strftime("%Y-%m-%d")
|
||||||
|
link = "?start={0}&end={1}&format=csv".format(start, end)
|
||||||
|
self.assertEqual(self.billing.csv_link(), link)
|
||||||
|
|
||||||
def test_calculate_history_date(self):
|
|
||||||
"""Using the same algorithm to calculate the history date."""
|
|
||||||
today = datetime.date(2015, 2, 17)
|
|
||||||
start = distil._calculate_start_date(datetime.date(2015, 2, 17))
|
|
||||||
end = distil._calculate_end_date(start)
|
|
||||||
final_end = datetime.datetime(today.year, today.month + 1, 1)
|
|
||||||
|
|
||||||
history_date = [None for i in range(12)]
|
class IndexCsvRendererTest(test.TestCase):
|
||||||
for i in range(12):
|
def setUp(self):
|
||||||
start_str = start.strftime("%Y-%m-%dT00:00:00")
|
super(IndexCsvRendererTest, self).setUp()
|
||||||
end_str = end.strftime("%Y-%m-%dT00:00:00")
|
request = FakeRequest()
|
||||||
history_date[i] = (start_str, end_str)
|
template = ""
|
||||||
start = end
|
context = {"current_month": [BILLITEM(id=1, resource='N/A',
|
||||||
end = distil._calculate_end_date(start)
|
count=1, cost=2)]}
|
||||||
if end > final_end:
|
content_type = "text/csv"
|
||||||
break
|
self.csvRenderer = views.IndexCsvRenderer(request=request,
|
||||||
|
template=template,
|
||||||
|
context=context,
|
||||||
|
content_type=content_type)
|
||||||
|
|
||||||
self.assertEqual(('2014-03-01T00:00:00', '2014-04-01T00:00:00'),
|
def test_get_row_data(self):
|
||||||
history_date[0])
|
data = list(self.csvRenderer.get_row_data())
|
||||||
self.assertEqual(('2014-04-01T00:00:00', '2014-05-01T00:00:00'),
|
self.assertEqual(data, [('N/A', 1, u'2.00')])
|
||||||
history_date[1])
|
|
||||||
self.assertEqual(('2014-05-01T00:00:00', '2014-06-01T00:00:00'),
|
|
||||||
history_date[2])
|
|
||||||
self.assertEqual(('2014-06-01T00:00:00', '2014-07-01T00:00:00'),
|
|
||||||
history_date[3])
|
|
||||||
self.assertEqual(('2014-07-01T00:00:00', '2014-08-01T00:00:00'),
|
|
||||||
history_date[4])
|
|
||||||
self.assertEqual(('2014-08-01T00:00:00', '2014-09-01T00:00:00'),
|
|
||||||
history_date[5])
|
|
||||||
self.assertEqual(('2014-09-01T00:00:00', '2014-10-01T00:00:00'),
|
|
||||||
history_date[6])
|
|
||||||
self.assertEqual(('2014-10-01T00:00:00', '2014-11-01T00:00:00'),
|
|
||||||
history_date[7])
|
|
||||||
self.assertEqual(('2014-11-01T00:00:00', '2014-12-01T00:00:00'),
|
|
||||||
history_date[8])
|
|
||||||
self.assertEqual(('2014-12-01T00:00:00', '2015-01-01T00:00:00'),
|
|
||||||
history_date[9])
|
|
||||||
self.assertEqual(('2015-01-01T00:00:00', '2015-02-01T00:00:00'),
|
|
||||||
history_date[10])
|
|
||||||
self.assertEqual(('2015-02-01T00:00:00', '2015-03-01T00:00:00'),
|
|
||||||
history_date[11])
|
|
||||||
|
|
||||||
def test_get_cost(self):
|
|
||||||
distilclient = self.mocker.CreateMock(FakeDistilClient)
|
|
||||||
|
|
||||||
today = datetime.date.today()
|
class ViewsTests(test.TestCase):
|
||||||
start = distil._calculate_start_date(datetime.date.today())
|
def setUp(self):
|
||||||
end = distil._calculate_end_date(start)
|
super(ViewsTests, self).setUp()
|
||||||
final_end = datetime.datetime(today.year, today.month + 1, 1)
|
project_id = "fake_project_id"
|
||||||
|
self.view = views.IndexView()
|
||||||
|
self.view.request = FakeRequest()
|
||||||
|
self.view.billing = base.BaseBilling(self.request, project_id)
|
||||||
|
|
||||||
for i in range(12):
|
def test_get_template_names(self):
|
||||||
result = {'usage': {'total_cost': (i + 1) * 100,
|
self.assertEqual(self.view.get_template_names(),
|
||||||
'resources': {'uuid': {"services": [{
|
"management/billing/billing.csv")
|
||||||
"volume": 2100,
|
|
||||||
"rate": 0.0005,
|
|
||||||
"cost": 1.05,
|
|
||||||
"name": "b1.standard",
|
|
||||||
"unit": "gigabyte"}],
|
|
||||||
"total_cost": 1.05,
|
|
||||||
"type": "Image",
|
|
||||||
"name": "cirros"}}}}
|
|
||||||
start_str = start.strftime("%Y-%m-%dT00:00:00")
|
|
||||||
end_str = end.strftime("%Y-%m-%dT00:00:00")
|
|
||||||
distilclient.get_rated([self.tenant.id],
|
|
||||||
start_str,
|
|
||||||
end_str).AndReturn(result)
|
|
||||||
|
|
||||||
start = end
|
def test_get_content_type(self):
|
||||||
end = distil._calculate_end_date(start)
|
self.assertEqual(self.view.get_content_type(), "text/csv")
|
||||||
if end > final_end:
|
|
||||||
break
|
|
||||||
|
|
||||||
self.mocker.ReplayAll()
|
def test_get_data(self):
|
||||||
setattr(self.request.user, 'tenant_id', self.tenant.id)
|
# TODO(flwang): Will add in next patch
|
||||||
history_cost = distil.get_cost(self.request,
|
pass
|
||||||
distil_client=distilclient,
|
|
||||||
enable_eventlet=False)
|
|
||||||
# 2 = math.ceil(1.05)
|
|
||||||
self.assertEqual([1.05 for i in range(12)],
|
|
||||||
[c[0] for c in history_cost])
|
|
||||||
|
|
||||||
def test_apply_discount(self):
|
@mock.patch('horizon.tables.DataTableView.get_context_data')
|
||||||
# There are 3 scenarios for current month.
|
def test_get_context_data(self, mock_get_context_data):
|
||||||
cost = (47.54,
|
# TODO(flwang): Will add in next patch
|
||||||
[distil.BILLITEM(id=1, resource='Compute', count=9,
|
pass
|
||||||
cost=31.76),
|
|
||||||
distil.BILLITEM(id=2, resource=u'Network', count=3, cost=1.5),
|
|
||||||
distil.BILLITEM(id=3, resource=u'Image', count=35, cost=3.82),
|
|
||||||
distil.BILLITEM(id=4, resource=u'Router', count=2, cost=0.96),
|
|
||||||
distil.BILLITEM(id=5, resource=u'Floating IP', count=21,
|
|
||||||
cost=3.57),
|
|
||||||
distil.BILLITEM(id=6, resource='Block Storage', count=22,
|
|
||||||
cost=6.08)
|
|
||||||
], [])
|
|
||||||
prices = {u'Virtual Machine': 0.044, u'Network': 0.016,
|
|
||||||
u'Image': 0.0005, u'Volume': 0.0005,
|
|
||||||
u'Router': 0.017, u'Floating IP': 0.006}
|
|
||||||
start_str = '2015-07-01T00:00:00'
|
|
||||||
end_str = '2015-07-02T04:00:00'
|
|
||||||
|
|
||||||
cost_after_discount = distil._apply_discount(cost, start_str, end_str,
|
def test_render_to_response(self):
|
||||||
prices)
|
self.view.start = datetime.datetime.now()
|
||||||
start = time.mktime(time.strptime(start_str, '%Y-%m-%dT%H:%M:%S'))
|
self.view.end = datetime.datetime.now()
|
||||||
end = time.mktime(time.strptime(end_str, '%Y-%m-%dT%H:%M:%S'))
|
context = {"current_month": [BILLITEM(id=1, resource='N/A',
|
||||||
free_hours = math.floor((end - start) / 3600)
|
count=1, cost=2)]}
|
||||||
|
self.assertIsInstance(self.view.render_to_response(context),
|
||||||
free_network_cost = round(0.016 * free_hours, 2)
|
views.IndexCsvRenderer)
|
||||||
free_router_cost = round(0.017 * free_hours, 2)
|
|
||||||
|
|
||||||
self.assertEqual(cost[0] - free_network_cost - free_router_cost,
|
|
||||||
cost_after_discount[0])
|
|
||||||
|
|
||||||
self.assertIn(distil.BILLITEM(id=2, resource=u'Network', count=3,
|
|
||||||
cost=1.05),
|
|
||||||
cost_after_discount[1])
|
|
||||||
self.assertIn(distil.BILLITEM(id=4, resource=u'Router', count=2,
|
|
||||||
cost=0.48),
|
|
||||||
cost_after_discount[1])
|
|
||||||
|
|
||||||
def test_get_month_cost_with_cache(self):
|
|
||||||
distil.CACHE.clear()
|
|
||||||
distilclient = self.mocker.CreateMock(FakeDistilClient)
|
|
||||||
result = {'usage': {'total_cost': 5.05,
|
|
||||||
'resources': {'uuid':
|
|
||||||
{"services": [{"volume": 2100,
|
|
||||||
"rate": 0.0005,
|
|
||||||
"cost": 5.05,
|
|
||||||
"name": "b1.standard",
|
|
||||||
"unit": "gigabyte"}],
|
|
||||||
"total_cost": 5.05,
|
|
||||||
"type": "Image",
|
|
||||||
"name": "cirros"}}}}
|
|
||||||
distilclient.get_rated([self.tenant.id],
|
|
||||||
'2011-02-01T00:00:00',
|
|
||||||
'2011-03-01T00:00:00').AndReturn(result)
|
|
||||||
self.mocker.ReplayAll()
|
|
||||||
|
|
||||||
cost = [()]
|
|
||||||
distil._get_month_cost(distilclient,
|
|
||||||
self.tenant.id,
|
|
||||||
'2011-02-01T00:00:00',
|
|
||||||
'2011-03-01T00:00:00',
|
|
||||||
cost, 0)
|
|
||||||
key = 'http://localhost:8788_1_2011-02-01T00:00:00_2011-03-01T00:00:00'
|
|
||||||
self.assertIn(key, distil.CACHE)
|
|
||||||
self.assertEqual(distil.CACHE[key][0], 5.05)
|
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
|
# Copyright (c) 2014 Catalyst IT Ltd.
|
||||||
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
# You may obtain a copy of the License at
|
# You may obtain a copy of the License at
|
||||||
#
|
#
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
#
|
#
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@ -10,19 +12,286 @@
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
import datetime
|
||||||
|
import math
|
||||||
import mock
|
import mock
|
||||||
|
import time
|
||||||
|
|
||||||
from openstack_dashboard.test.test_data import utils
|
from mox3 import mox
|
||||||
|
|
||||||
from distil_ui.test import test_data
|
from distil_ui.api import distil
|
||||||
|
from openstack_dashboard.test import helpers as test
|
||||||
TEST = utils.TestData(test_data.data)
|
|
||||||
|
|
||||||
|
|
||||||
def mock_resource(resource):
|
class FakeUser(object):
|
||||||
"""Utility function to make mocking more DRY"""
|
roles = [{'name': 'admin'}]
|
||||||
|
token = mock.MagicMock()
|
||||||
|
tenant_id = "fake"
|
||||||
|
services_region = "fake"
|
||||||
|
|
||||||
mocked_data = \
|
|
||||||
[mock.Mock(**{'to_dict.return_value': item}) for item in resource]
|
|
||||||
|
|
||||||
return mocked_data
|
class FakeRequest(object):
|
||||||
|
user = FakeUser()
|
||||||
|
|
||||||
|
|
||||||
|
class FakeDistilClient(object):
|
||||||
|
"""A fake distil client for unit test."""
|
||||||
|
endpoint = 'http://localhost:8788'
|
||||||
|
request = FakeRequest()
|
||||||
|
|
||||||
|
def get_rated(self, tenant, start, end):
|
||||||
|
raise NotImplemented()
|
||||||
|
|
||||||
|
|
||||||
|
class BillingTests(test.TestCase):
|
||||||
|
"""FIXME(flwang): Move this test to rest_api_tests.py
|
||||||
|
|
||||||
|
Now we're putting the api test at here, since we don't want to hack
|
||||||
|
horizon too much. That means we don't want to put the api.py under /api
|
||||||
|
folder, at least for now.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(BillingTests, self).setUp()
|
||||||
|
self.mocker = mox.Mox()
|
||||||
|
|
||||||
|
@mock.patch("openstack_dashboard.api.base.url_for")
|
||||||
|
def test_init_distilclient(self, mock_url_for):
|
||||||
|
request = FakeRequest()
|
||||||
|
distilclient = distil.distilclient(request)
|
||||||
|
self.assertIsNotNone(distilclient)
|
||||||
|
|
||||||
|
def test_calculate_end_date(self):
|
||||||
|
start = datetime.date(2015, 1, 1)
|
||||||
|
end = distil._calculate_end_date(start)
|
||||||
|
self.assertEqual((end.year, end.month, end.day), (2015, 2, 1))
|
||||||
|
|
||||||
|
start = datetime.date(2015, 6, 1)
|
||||||
|
end = distil._calculate_end_date(start)
|
||||||
|
self.assertEqual((end.year, end.month, end.day), (2015, 7, 1))
|
||||||
|
|
||||||
|
start = datetime.date(2015, 12, 1)
|
||||||
|
end = distil._calculate_end_date(start)
|
||||||
|
self.assertEqual((end.year, end.month, end.day), (2016, 1, 1))
|
||||||
|
|
||||||
|
def test_get_month_cost(self):
|
||||||
|
distilclient = self.mocker.CreateMock(FakeDistilClient)
|
||||||
|
|
||||||
|
resources = {"fake_uuid_1": {"services": [{
|
||||||
|
"volume": 2100,
|
||||||
|
"rate": 0.0005,
|
||||||
|
"cost": 1.05,
|
||||||
|
"name": "b1.standard",
|
||||||
|
"unit": "gigabyte"}],
|
||||||
|
"total_cost": 1.05,
|
||||||
|
"type": "Image",
|
||||||
|
"name": "cirros"},
|
||||||
|
"fake_uuid_2": {"services": [{
|
||||||
|
"volume": 122,
|
||||||
|
"rate": 0.048,
|
||||||
|
"cost": 5.86,
|
||||||
|
"name": "m1.tiny",
|
||||||
|
"unit": "hour"}],
|
||||||
|
"total_cost": 5.86,
|
||||||
|
"type": "Virtual Machine",
|
||||||
|
"name": "dfgh"},
|
||||||
|
"fake_uuid_3": {"services": [{
|
||||||
|
"volume": 200,
|
||||||
|
"rate": 0.048,
|
||||||
|
"cost": 9.60,
|
||||||
|
"name": "m1.tiny",
|
||||||
|
"unit": "hour"}],
|
||||||
|
"total_cost": 9.60,
|
||||||
|
"type": "Virtual Machine",
|
||||||
|
"name": "abcd"},
|
||||||
|
"fake_uuid_4": {"services": [{"volume": 20.00,
|
||||||
|
"rate": 0.016,
|
||||||
|
"cost": 0.32,
|
||||||
|
"name": "n1.network",
|
||||||
|
"unit": "hour"},
|
||||||
|
{"volume": 10.00,
|
||||||
|
"rate": 0.016,
|
||||||
|
"cost": 0.16,
|
||||||
|
"name": "n1.network",
|
||||||
|
"unit": "hour"}],
|
||||||
|
"total_cost": 0.48,
|
||||||
|
"type": "Network",
|
||||||
|
"name": "public"}
|
||||||
|
}
|
||||||
|
|
||||||
|
result = {'usage': {"end": "2011-03-01 00:00:00", "name": "openstack",
|
||||||
|
"total_cost": 7.23,
|
||||||
|
"tenant_id": "7c3c506ad4b943f5bb12b9fb69478084",
|
||||||
|
"start": "2011-02-01 00:00:00",
|
||||||
|
"resources": resources
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
distilclient.get_rated([self.tenant.id],
|
||||||
|
'2011-02-01T00:00:00',
|
||||||
|
'2011-03-01T00:00:00').AndReturn(result)
|
||||||
|
self.mocker.ReplayAll()
|
||||||
|
|
||||||
|
cost = [()]
|
||||||
|
distil._get_month_cost(distilclient,
|
||||||
|
self.tenant.id,
|
||||||
|
'2011-02-01T00:00:00',
|
||||||
|
'2011-03-01T00:00:00',
|
||||||
|
cost, 0)
|
||||||
|
self.assertEqual(16.99, cost[0][0])
|
||||||
|
self.assertEqual(3, len(cost[0][1]))
|
||||||
|
bill_items = {}
|
||||||
|
for b in cost[0][1]:
|
||||||
|
# Convert cost to string make sure the floating number is right
|
||||||
|
bill_items[b.resource] = (b.count, str(b.cost))
|
||||||
|
|
||||||
|
self.assertEqual((2, '0.48'), bill_items['Network'])
|
||||||
|
self.assertEqual((2, '15.46'), bill_items['Compute'])
|
||||||
|
self.assertEqual((1, '1.05'), bill_items['Image'])
|
||||||
|
|
||||||
|
def test_calculate_history_date(self):
|
||||||
|
"""Using the same algorithm to calculate the history date."""
|
||||||
|
today = datetime.date(2015, 2, 17)
|
||||||
|
start = distil._calculate_start_date(datetime.date(2015, 2, 17))
|
||||||
|
end = distil._calculate_end_date(start)
|
||||||
|
final_end = datetime.datetime(today.year, today.month + 1, 1)
|
||||||
|
|
||||||
|
history_date = [None for i in range(12)]
|
||||||
|
for i in range(12):
|
||||||
|
start_str = start.strftime("%Y-%m-%dT00:00:00")
|
||||||
|
end_str = end.strftime("%Y-%m-%dT00:00:00")
|
||||||
|
history_date[i] = (start_str, end_str)
|
||||||
|
start = end
|
||||||
|
end = distil._calculate_end_date(start)
|
||||||
|
if end > final_end:
|
||||||
|
break
|
||||||
|
|
||||||
|
self.assertEqual(('2014-03-01T00:00:00', '2014-04-01T00:00:00'),
|
||||||
|
history_date[0])
|
||||||
|
self.assertEqual(('2014-04-01T00:00:00', '2014-05-01T00:00:00'),
|
||||||
|
history_date[1])
|
||||||
|
self.assertEqual(('2014-05-01T00:00:00', '2014-06-01T00:00:00'),
|
||||||
|
history_date[2])
|
||||||
|
self.assertEqual(('2014-06-01T00:00:00', '2014-07-01T00:00:00'),
|
||||||
|
history_date[3])
|
||||||
|
self.assertEqual(('2014-07-01T00:00:00', '2014-08-01T00:00:00'),
|
||||||
|
history_date[4])
|
||||||
|
self.assertEqual(('2014-08-01T00:00:00', '2014-09-01T00:00:00'),
|
||||||
|
history_date[5])
|
||||||
|
self.assertEqual(('2014-09-01T00:00:00', '2014-10-01T00:00:00'),
|
||||||
|
history_date[6])
|
||||||
|
self.assertEqual(('2014-10-01T00:00:00', '2014-11-01T00:00:00'),
|
||||||
|
history_date[7])
|
||||||
|
self.assertEqual(('2014-11-01T00:00:00', '2014-12-01T00:00:00'),
|
||||||
|
history_date[8])
|
||||||
|
self.assertEqual(('2014-12-01T00:00:00', '2015-01-01T00:00:00'),
|
||||||
|
history_date[9])
|
||||||
|
self.assertEqual(('2015-01-01T00:00:00', '2015-02-01T00:00:00'),
|
||||||
|
history_date[10])
|
||||||
|
self.assertEqual(('2015-02-01T00:00:00', '2015-03-01T00:00:00'),
|
||||||
|
history_date[11])
|
||||||
|
|
||||||
|
def test_get_cost(self):
|
||||||
|
distilclient = self.mocker.CreateMock(FakeDistilClient)
|
||||||
|
|
||||||
|
today = datetime.date.today()
|
||||||
|
start = distil._calculate_start_date(datetime.date.today())
|
||||||
|
end = distil._calculate_end_date(start)
|
||||||
|
final_end = datetime.datetime(today.year, today.month + 1, 1)
|
||||||
|
|
||||||
|
for i in range(12):
|
||||||
|
result = {'usage': {'total_cost': (i + 1) * 100,
|
||||||
|
'resources': {'uuid': {"services": [{
|
||||||
|
"volume": 2100,
|
||||||
|
"rate": 0.0005,
|
||||||
|
"cost": 1.05,
|
||||||
|
"name": "b1.standard",
|
||||||
|
"unit": "gigabyte"}],
|
||||||
|
"total_cost": 1.05,
|
||||||
|
"type": "Image",
|
||||||
|
"name": "cirros"}}}}
|
||||||
|
start_str = start.strftime("%Y-%m-%dT00:00:00")
|
||||||
|
end_str = end.strftime("%Y-%m-%dT00:00:00")
|
||||||
|
distilclient.get_rated([self.tenant.id],
|
||||||
|
start_str,
|
||||||
|
end_str).AndReturn(result)
|
||||||
|
|
||||||
|
start = end
|
||||||
|
end = distil._calculate_end_date(start)
|
||||||
|
if end > final_end:
|
||||||
|
break
|
||||||
|
|
||||||
|
self.mocker.ReplayAll()
|
||||||
|
setattr(self.request.user, 'tenant_id', self.tenant.id)
|
||||||
|
history_cost = distil.get_cost(self.request,
|
||||||
|
distil_client=distilclient,
|
||||||
|
enable_eventlet=False)
|
||||||
|
# 2 = math.ceil(1.05)
|
||||||
|
self.assertEqual([1.05 for i in range(12)],
|
||||||
|
[c[0] for c in history_cost])
|
||||||
|
|
||||||
|
def test_apply_discount(self):
|
||||||
|
# There are 3 scenarios for current month.
|
||||||
|
cost = (47.54,
|
||||||
|
[distil.BILLITEM(id=1, resource='Compute', count=9,
|
||||||
|
cost=31.76),
|
||||||
|
distil.BILLITEM(id=2, resource=u'Network', count=3, cost=1.5),
|
||||||
|
distil.BILLITEM(id=3, resource=u'Image', count=35, cost=3.82),
|
||||||
|
distil.BILLITEM(id=4, resource=u'Router', count=2, cost=0.96),
|
||||||
|
distil.BILLITEM(id=5, resource=u'Floating IP', count=21,
|
||||||
|
cost=3.57),
|
||||||
|
distil.BILLITEM(id=6, resource='Block Storage', count=22,
|
||||||
|
cost=6.08)
|
||||||
|
], [])
|
||||||
|
prices = {u'Virtual Machine': 0.044, u'Network': 0.016,
|
||||||
|
u'Image': 0.0005, u'Volume': 0.0005,
|
||||||
|
u'Router': 0.017, u'Floating IP': 0.006}
|
||||||
|
start_str = '2015-07-01T00:00:00'
|
||||||
|
end_str = '2015-07-02T04:00:00'
|
||||||
|
|
||||||
|
cost_after_discount = distil._apply_discount(cost, start_str, end_str,
|
||||||
|
prices)
|
||||||
|
start = time.mktime(time.strptime(start_str, '%Y-%m-%dT%H:%M:%S'))
|
||||||
|
end = time.mktime(time.strptime(end_str, '%Y-%m-%dT%H:%M:%S'))
|
||||||
|
free_hours = math.floor((end - start) / 3600)
|
||||||
|
|
||||||
|
free_network_cost = round(0.016 * free_hours, 2)
|
||||||
|
free_router_cost = round(0.017 * free_hours, 2)
|
||||||
|
|
||||||
|
self.assertEqual(cost[0] - free_network_cost - free_router_cost,
|
||||||
|
cost_after_discount[0])
|
||||||
|
|
||||||
|
self.assertIn(distil.BILLITEM(id=2, resource=u'Network', count=3,
|
||||||
|
cost=1.05),
|
||||||
|
cost_after_discount[1])
|
||||||
|
self.assertIn(distil.BILLITEM(id=4, resource=u'Router', count=2,
|
||||||
|
cost=0.48),
|
||||||
|
cost_after_discount[1])
|
||||||
|
|
||||||
|
def test_get_month_cost_with_cache(self):
|
||||||
|
distil.CACHE.clear()
|
||||||
|
distilclient = self.mocker.CreateMock(FakeDistilClient)
|
||||||
|
result = {'usage': {'total_cost': 5.05,
|
||||||
|
'resources': {'uuid':
|
||||||
|
{"services": [{"volume": 2100,
|
||||||
|
"rate": 0.0005,
|
||||||
|
"cost": 5.05,
|
||||||
|
"name": "b1.standard",
|
||||||
|
"unit": "gigabyte"}],
|
||||||
|
"total_cost": 5.05,
|
||||||
|
"type": "Image",
|
||||||
|
"name": "cirros"}}}}
|
||||||
|
distilclient.get_rated([self.tenant.id],
|
||||||
|
'2011-02-01T00:00:00',
|
||||||
|
'2011-03-01T00:00:00').AndReturn(result)
|
||||||
|
self.mocker.ReplayAll()
|
||||||
|
|
||||||
|
cost = [()]
|
||||||
|
distil._get_month_cost(distilclient,
|
||||||
|
self.tenant.id,
|
||||||
|
'2011-02-01T00:00:00',
|
||||||
|
'2011-03-01T00:00:00',
|
||||||
|
cost, 0)
|
||||||
|
key = 'http://localhost:8788_1_2011-02-01T00:00:00_2011-03-01T00:00:00'
|
||||||
|
self.assertIn(key, distil.CACHE)
|
||||||
|
self.assertEqual(distil.CACHE[key][0], 5.05)
|
||||||
|
|
|
@ -15,6 +15,3 @@ from openstack_dashboard.test import helpers
|
||||||
|
|
||||||
class APITestCase(helpers.APITestCase):
|
class APITestCase(helpers.APITestCase):
|
||||||
"""Extends the base Horizon APITestCase for distilclient"""
|
"""Extends the base Horizon APITestCase for distilclient"""
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
super(APITestCase, self).setUp()
|
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
# 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 openstack_dashboard.test.test_data import utils
|
|
||||||
|
|
||||||
|
|
||||||
def data(TEST):
|
|
||||||
# Test Data Container in Horizon
|
|
||||||
TEST.queues = utils.TestDataContainer()
|
|
|
@ -26,4 +26,5 @@ testtools>=1.4.0 # MIT
|
||||||
# This also needs xvfb library installed on your OS
|
# This also needs xvfb library installed on your OS
|
||||||
xvfbwrapper>=0.1.3 #license: MIT
|
xvfbwrapper>=0.1.3 #license: MIT
|
||||||
# Include horizon as test requirement
|
# Include horizon as test requirement
|
||||||
http://tarballs.openstack.org/horizon/horizon-master.tar.gz#egg=horizon
|
http://tarballs.openstack.org/horizon/horizon-master.tar.gz#egg=horizon
|
||||||
|
|
||||||
|
|
13
tox.ini
13
tox.ini
|
@ -25,6 +25,7 @@ commands = {posargs}
|
||||||
|
|
||||||
[testenv:cover]
|
[testenv:cover]
|
||||||
commands =
|
commands =
|
||||||
|
pip install git+https://github.com/openstack/python-distilclient.git
|
||||||
coverage erase
|
coverage erase
|
||||||
coverage run {toxinidir}/manage.py test distil_ui
|
coverage run {toxinidir}/manage.py test distil_ui
|
||||||
coverage xml --omit '.tox/cover/*' -o 'cover/coverage.xml'
|
coverage xml --omit '.tox/cover/*' -o 'cover/coverage.xml'
|
||||||
|
@ -36,6 +37,18 @@ commands =
|
||||||
pip install git+https://github.com/openstack/python-distilclient.git
|
pip install git+https://github.com/openstack/python-distilclient.git
|
||||||
python manage.py test {posargs}
|
python manage.py test {posargs}
|
||||||
|
|
||||||
|
[testenv:py27]
|
||||||
|
basepython = python2.7
|
||||||
|
commands =
|
||||||
|
pip install git+https://github.com/openstack/python-distilclient.git
|
||||||
|
python manage.py test {posargs}
|
||||||
|
|
||||||
|
[testenv:py35]
|
||||||
|
basepython = python3.5
|
||||||
|
commands =
|
||||||
|
pip install git+https://github.com/openstack/python-distilclient.git
|
||||||
|
python manage.py test {posargs}
|
||||||
|
|
||||||
[testenv:eslint]
|
[testenv:eslint]
|
||||||
whitelist_externals = npm
|
whitelist_externals = npm
|
||||||
commands =
|
commands =
|
||||||
|
|
Loading…
Reference in New Issue