# 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 datetime import mock from distil_ui.api import distil_v2 from freezegun import freeze_time from openstack_dashboard.test import helpers as test regionOne = mock.Mock(id='RegionOne') regionTwo = mock.Mock(id='RegionTwo') region_list = [regionOne, regionTwo] fake_keystoneclient = mock.MagicMock() fake_keystoneclient.regions.list = mock.Mock(return_value=region_list) get_fake_keystoneclient = mock.Mock(return_value=fake_keystoneclient) class FakeUser(object): roles = [{'name': 'admin'}] token = mock.MagicMock() tenant_id = "fake" services_region = "fake" available_services_regions = ["RegionOne", "RegionTwo"] class FakeRequest(object): user = FakeUser() class FakeDistilClient(mock.MagicMock): def __init__(self, *args, **kwargs): super(FakeDistilClient, self).__init__(*args, **kwargs) self.region_id = kwargs.get('region_id') self.quotations = mock.MagicMock() if self.region_id == 'RegionOne': self.quotations.list = mock.Mock(return_value={ "quotations": {"2017-07-10": {"details": { "Object Storage": { "breakdown": { "REGIONONE.o1.standard": [ { "cost": 13.5, "quantity": 50000.0, "rate": 0.00027, "resource_id": "1", "resource_name": "my_container", "unit": "gigabyte" } ] }, "total_cost": 13.5 }, "Virtual Machine": { "breakdown": { "REGIONONE.c1.c2r2": [ { "cost": 15.0, "quantity": 30000.0, "rate": 0.0005, "resource_id": "22", "resource_name": "new_instance", "unit": "second" } ] }, "total_cost": 15.0 } }, "total_cost": 28.5}}}) elif self.region_id == 'RegionTwo': self.quotations.list = mock.Mock(return_value={ "quotations": {"2017-07-10": {"details": { "Network": {"breakdown": {"REGIONTWO.b1.standard": [ {"cost": 2, "quantity": 200, "rate": 0.01, "resource_id": "8", "resource_name": "my_block", "unit": "hour"}]}, "total_cost": 2 }, "Object Storage": {"breakdown": {"REGIONTWO.o1.standard": [ {"cost": 13.5, "quantity": 50000.0, "rate": 0.00027, "resource_id": "1", "resource_name": "my_container", "unit": "gigabyte"}]}, "total_cost": 13.5}, "Virtual Machine": {"breakdown": { "REGIONTWO.c1.c1r1": [ {"cost": 15.0, "quantity": 30000.0, "rate": 0.0005, "resource_id": "2", "resource_name": "my_instance", "unit": "second"}, {"cost": 15.0, "quantity": 30000.0, "rate": 0.0005, "resource_id": "3", "resource_name": "other_instance", "unit": "second"}] }, "total_cost": 30.0 } }, "total_cost": 45.5 }} }) self.invoices = mock.MagicMock() self.invoices.list = mock.Mock(return_value={ "start": "2016-08-31 00:00:00", "end": "2017-07-01 00:00:00", "invoices": { "2017-06-30": { "total_cost": 689.0, "status": "paid", "details": {'Compute': {'total_cost': 767.06, 'breakdown': {'NZ-POR-1.c1.c4r8': [{'rate': 0.248, 'resource_name': 'postgresql', 'cost': 184.51, 'unit': 'Hour(s)', 'quantity': 744.0}], # noqa 'NZ-POR-1.c1.c8r32': [{'rate': 0.783, 'resource_name': 'docker', 'cost': 582.55, 'unit': 'Hour(s)', 'quantity': 744.0}]} # noqa } } }, "2017-05-31": { "total_cost": 653.0, "status": "paid", "details": {'Block Storage': {'total_cost': 75.88, 'breakdown': {'NZ-POR-1.b1.standard': [{'rate': 0.0005, 'resource_name': 'docker - root disk', 'cost': 3.72, 'unit': 'Gigabyte-hour(s)', 'quantity': 7440.0}, {'rate': 0.0005, 'resource_name': 'docker_tmp', 'cost': 11.9, 'unit': 'Gigabyte-hour(s)', 'quantity': 23808.0}, # noqa {'rate': 0.0005, 'resource_name': 'postgresql - root disk', 'cost': 3.72, 'unit': 'Gigabyte-hour(s)', 'quantity': 7440.0}, {'rate': 0.0005, 'resource_name': 'dbserver_dbvol', 'cost': 7.44, 'unit': 'Gigabyte-hour(s)', 'quantity': 14880.0}, # noqa {'rate': 0.0005, 'resource_name': 'server_dockervol', 'cost': 18.6, 'unit': 'Gigabyte-hour(s)', 'quantity': 37200.0}, {'rate': 0.0005, 'resource_name': 'docker_uservol', 'cost': 18.6, 'unit': 'Gigabyte-hour(s)', 'quantity': 37200.0}, # noqa {'rate': 0.0005, 'resource_name': 'docker_swap', 'cost': 11.9, 'unit': 'Gigabyte-hour(s)', 'quantity': 23808.0}]}}, # noqa } }, "2017-04-30": {"total_cost": 0, "details": {}}, "2017-03-31": {"total_cost": 0, "details": {}}, "2017-02-28": {"total_cost": 0, "details": {}}, "2017-01-31": {"total_cost": 0, "details": {}}, "2016-12-31": {"total_cost": 0, "details": {}}, "2016-11-30": {"total_cost": 0, "details": {}}, "2016-10-31": {"total_cost": 0, "details": {}}, "2016-09-30": {"total_cost": 0, "details": {}}, "2016-08-31": { "total_cost": 617.0, "status": "open", "details": {'Network': {'total_cost': 9.64, 'breakdown': {'NZ-POR-1.n1.ipv4': [{'rate': 0.006, 'resource_name': '150.242.40.138', 'cost': 4.46, 'unit': 'Hour(s)', 'quantity': 744.0}, {'rate': 0.006, 'resource_name': '150.242.40.139', 'cost': 4.46, 'unit': 'Hour(s)', 'quantity': 744.0}]}} # noqa } } }, "project_id": "093551df28e545eba9ba676dbd56bfa7", "project_name": "default_project", }) self.credits = mock.MagicMock() self.credits.list = mock.Mock(return_value={'credits': [{'code': 'abcdefg', 'type': 'Cloud Trial Credit', 'expiry_date': '2017-09-30', 'balance': 300.0, 'recurring': False, 'start_date': '2017-08-02 22:16:28'}]}) # noqa @mock.patch('distil_ui.api.distil_v2.distilclient', FakeDistilClient) class V2BillingTests(test.TestCase): """Ensure the V2 api changes work. """ def setUp(self): super(V2BillingTests, self).setUp() region_list[:] = [] region_list.append(regionOne) region_list.append(regionTwo) @mock.patch("openstack_dashboard.api.base.url_for") def test_init_distilclient(self, mock_url_for): request = FakeRequest() distilclient = distil_v2.distilclient(request) self.assertIsNotNone(distilclient) def test_calculate_start_date(self): today = datetime.date(2017, 1, 1) start = distil_v2._calculate_start_date(today) self.assertEqual((start.year, start.month, start.day), (2016, 2, 1)) today = datetime.date(2017, 7, 1) start = distil_v2._calculate_start_date(today) self.assertEqual((start.year, start.month, start.day), (2016, 8, 1)) today = datetime.date(2017, 12, 31) start = distil_v2._calculate_start_date(today) self.assertEqual((start.year, start.month, start.day), (2017, 1, 1)) def test_calculate_end_date(self): start = datetime.date(2015, 1, 1) end = distil_v2._calculate_end_date(start) self.assertEqual((end.year, end.month, end.day), (2015, 2, 1)) start = datetime.date(2015, 6, 6) end = distil_v2._calculate_end_date(start) self.assertEqual((end.year, end.month, end.day), (2015, 7, 1)) start = datetime.date(2015, 12, 31) end = distil_v2._calculate_end_date(start) self.assertEqual((end.year, end.month, end.day), (2016, 1, 1)) @freeze_time("2017-07-10") @mock.patch('openstack_dashboard.api.keystone.keystoneclient', get_fake_keystoneclient) def test_get_cost(self): cost = distil_v2.get_cost(FakeRequest()) self.assertEqual(cost[11]["total_cost"], 60.5) self.assertEqual(cost[10]["total_cost"], 689.0) self.assertEqual(cost[9]["total_cost"], 653.0) self.assertEqual(cost[8]["total_cost"], 0) self.assertEqual(cost[0]["total_cost"], 617) def test_get_credit(self): credits = distil_v2.get_credits(mock.MagicMock()) expect = {'credits': [{'code': 'abcdefg', 'type': 'Cloud Trial Credit', 'expiry_date': '2017-09-30', 'balance': 300.0, 'recurring': False, 'start_date': '2017-08-02 22:16:28'}]} self.assertDictEqual(credits, expect)