# -*- coding: utf-8 -*- # # Author: François Rossigneux <francois.rossigneux@inria.fr> # # 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 uuid from climate.db.sqlalchemy import api as db_api from climate.db.sqlalchemy import utils as db_utils from climate.openstack.common import context from climate import tests def _get_fake_random_uuid(): return unicode(str(uuid.uuid4())) def _get_fake_lease_uuid(): """Returns a fake uuid.""" return 'aaaaaaaa-1111-bbbb-2222-cccccccccccc' def _get_fake_phys_reservation_values(lease_id=_get_fake_lease_uuid(), resource_id=None): return {'lease_id': lease_id, 'resource_id': '1234' if not resource_id else resource_id, 'resource_type': 'physical:host'} def _get_datetime(value='2030-01-01 00:00'): return datetime.datetime.strptime(value, '%Y-%m-%d %H:%M') def _get_fake_phys_lease_values(id=_get_fake_lease_uuid(), name='fake_phys_lease', start_date=_get_datetime('2030-01-01 00:00'), end_date=_get_datetime('2030-01-02 00:00'), resource_id=None): return {'id': id, 'name': name, 'start_date': start_date, 'end_date': end_date, 'trust': 'trust', 'reservations': [_get_fake_phys_reservation_values( lease_id=id, resource_id=resource_id)], 'events': [] } def _create_physical_lease(values=_get_fake_phys_lease_values(), random=False): """Creating fake lease having a single physical resource.""" if random is True: values = _get_fake_phys_lease_values(id=_get_fake_random_uuid(), name=_get_fake_random_uuid()) lease = db_api.lease_create(values) for reservation in db_api.reservation_get_all_by_lease_id(lease['id']): allocation_values = { 'id': _get_fake_random_uuid(), 'compute_host_id': values['reservations'][0]['resource_id'], 'reservation_id': reservation['id'] } db_api.host_allocation_create(allocation_values) return lease class SQLAlchemyDBUtilsTestCase(tests.DBTestCase): """Test case for SQLAlchemy DB utils.""" def setUp(self): super(SQLAlchemyDBUtilsTestCase, self).setUp() self.set_context(context.get_admin_context()) def _setup_leases(self): """Setup some leases.""" r1 = _get_fake_phys_lease_values( id='lease1', name='fake_phys_lease_r1', start_date=_get_datetime('2030-01-01 09:00'), end_date=_get_datetime('2030-01-01 10:30'), resource_id='r1') r2 = _get_fake_phys_lease_values( id='lease2', name='fake_phys_lease_r2', start_date=_get_datetime('2030-01-01 11:00'), end_date=_get_datetime('2030-01-01 12:45'), resource_id='r2') r3 = _get_fake_phys_lease_values( id='lease3', name='fake_phys_lease_r3', start_date=_get_datetime('2030-01-01 13:00'), end_date=_get_datetime('2030-01-01 14:00'), resource_id='r1') _create_physical_lease(values=r1) _create_physical_lease(values=r2) _create_physical_lease(values=r3) def test_get_free_periods(self): """Find the free periods.""" self._setup_leases() start_date = datetime.datetime.strptime('2028-01-01 08:00', '%Y-%m-%d %H:%M') end_date = datetime.datetime.strptime('2099-01-01 00:00', '%Y-%m-%d %H:%M') duration = datetime.timedelta(hours=1) free_periods = db_utils.get_free_periods('r1', start_date, end_date, duration) self.assertEqual(len(free_periods), 3) self.assertEqual(free_periods[0][0].strftime('%Y-%m-%d %H:%M'), '2028-01-01 08:00') self.assertEqual(free_periods[0][1].strftime('%Y-%m-%d %H:%M'), '2030-01-01 09:00') self.assertEqual(free_periods[1][0].strftime('%Y-%m-%d %H:%M'), '2030-01-01 10:30') self.assertEqual(free_periods[1][1].strftime('%Y-%m-%d %H:%M'), '2030-01-01 13:00') self.assertEqual(free_periods[2][0].strftime('%Y-%m-%d %H:%M'), '2030-01-01 14:00') self.assertEqual(free_periods[2][1].strftime('%Y-%m-%d %H:%M'), '2099-01-01 00:00') duration = datetime.timedelta(hours=3) free_periods = db_utils.get_free_periods('r1', start_date, end_date, duration) self.assertEqual(len(free_periods), 2) self.assertEqual(free_periods[0][0].strftime('%Y-%m-%d %H:%M'), '2028-01-01 08:00') self.assertEqual(free_periods[0][1].strftime('%Y-%m-%d %H:%M'), '2030-01-01 09:00') self.assertEqual(free_periods[1][0].strftime('%Y-%m-%d %H:%M'), '2030-01-01 14:00') self.assertEqual(free_periods[1][1].strftime('%Y-%m-%d %H:%M'), '2099-01-01 00:00') def test_get_full_periods(self): """Find the full periods.""" self._setup_leases() start_date = datetime.datetime.strptime('2028-01-01 08:00', '%Y-%m-%d %H:%M') end_date = datetime.datetime.strptime('2099-01-01 00:00', '%Y-%m-%d %H:%M') duration = datetime.timedelta(hours=1) full_periods = db_utils.get_full_periods('r1', start_date, end_date, duration) self.assertEqual(len(full_periods), 2) self.assertEqual(full_periods[0][0].strftime('%Y-%m-%d %H:%M'), '2030-01-01 09:00') self.assertEqual(full_periods[0][1].strftime('%Y-%m-%d %H:%M'), '2030-01-01 10:30') self.assertEqual(full_periods[1][0].strftime('%Y-%m-%d %H:%M'), '2030-01-01 13:00') self.assertEqual(full_periods[1][1].strftime('%Y-%m-%d %H:%M'), '2030-01-01 14:00') duration = datetime.timedelta(hours=3) full_periods = db_utils.get_full_periods('r1', start_date, end_date, duration) self.assertEqual(len(full_periods), 1) self.assertEqual(full_periods[0][0].strftime('%Y-%m-%d %H:%M'), '2030-01-01 09:00') self.assertEqual(full_periods[0][1].strftime('%Y-%m-%d %H:%M'), '2030-01-01 14:00') def test_availability_time(self): """Find the total availability time.""" self._setup_leases() start_date = datetime.datetime.strptime('2030-01-01 09:15', '%Y-%m-%d %H:%M') end_date = datetime.datetime.strptime('2030-01-01 10:15', '%Y-%m-%d %H:%M') availability_time = db_utils.availability_time('r1', start_date, end_date) self.assertEqual(availability_time.seconds, 0 * 60) start_date = datetime.datetime.strptime('2030-01-01 09:15', '%Y-%m-%d %H:%M') end_date = datetime.datetime.strptime('2030-01-01 13:45', '%Y-%m-%d %H:%M') availability_time = db_utils.availability_time('r1', start_date, end_date) self.assertEqual(availability_time.seconds, 150 * 60) start_date = datetime.datetime.strptime('2030-01-01 08:00', '%Y-%m-%d %H:%M') end_date = datetime.datetime.strptime('2030-01-01 15:00', '%Y-%m-%d %H:%M') availability_time = db_utils.availability_time('r1', start_date, end_date) self.assertEqual(availability_time.seconds, 270 * 60) def test_reservation_time(self): """Find the total reserved time.""" self._setup_leases() start_date = datetime.datetime.strptime('2030-01-01 09:15', '%Y-%m-%d %H:%M') end_date = datetime.datetime.strptime('2030-01-01 10:15', '%Y-%m-%d %H:%M') reservation_time = db_utils.reservation_time('r1', start_date, end_date) self.assertEqual(reservation_time.seconds, 60 * 60) start_date = datetime.datetime.strptime('2030-01-01 09:15', '%Y-%m-%d %H:%M') end_date = datetime.datetime.strptime('2030-01-01 13:45', '%Y-%m-%d %H:%M') reservation_time = db_utils.reservation_time('r1', start_date, end_date) self.assertEqual(reservation_time.seconds, 120 * 60) start_date = datetime.datetime.strptime('2030-01-01 08:00', '%Y-%m-%d %H:%M') end_date = datetime.datetime.strptime('2030-01-01 15:00', '%Y-%m-%d %H:%M') reservation_time = db_utils.reservation_time('r1', start_date, end_date) self.assertEqual(reservation_time.seconds, 150 * 60) def test_reservation_ratio(self): """Find the reservation ratio.""" self._setup_leases() start_date = datetime.datetime.strptime('2030-01-01 09:15', '%Y-%m-%d %H:%M') end_date = datetime.datetime.strptime('2030-01-01 14:30', '%Y-%m-%d %H:%M') reservation_time = db_utils.reservation_time('r1', start_date, end_date) availability_time = db_utils.availability_time('r1', start_date, end_date) reservation_ratio = db_utils.reservation_ratio('r1', start_date, end_date) self.assertEqual(reservation_ratio, float(reservation_time.seconds) / (end_date - start_date).seconds) self.assertEqual( reservation_ratio, float((end_date - start_date - availability_time).seconds) / (end_date - start_date).seconds) def test_number_of_reservations(self): """Find the number of reservations.""" self._setup_leases() start_date = datetime.datetime.strptime('2030-01-01 09:15', '%Y-%m-%d %H:%M') end_date = datetime.datetime.strptime('2030-01-01 14:30', '%Y-%m-%d %H:%M') self.assertEqual( db_utils.number_of_reservations('r1', start_date, end_date), 2) def test_longest_lease(self): """Find the longest lease.""" self._setup_leases() self.assertEqual( db_utils.longest_lease( 'r1', start_date=_get_datetime('2030-01-01 08:00'), end_date=_get_datetime('2099-01-01 10:00')), 'lease1') self.assertEqual( db_utils.longest_lease( 'r1', start_date=_get_datetime('2030-01-01 10:00'), end_date=_get_datetime('2099-01-01 00:00')), 'lease3') self.assertEqual( db_utils.longest_lease( 'r1', start_date=_get_datetime('2030-01-01 08:00'), end_date=_get_datetime('2030-01-01 11:00')), 'lease1') self.assertIsNone( db_utils.longest_lease( 'r1', start_date=_get_datetime('2030-01-01 10:15'), end_date=_get_datetime('2030-01-01 13:00')), 'lease1') def test_shortest_lease(self): """Find the shortest lease.""" self._setup_leases() self.assertEqual( db_utils.shortest_lease( 'r1', start_date=_get_datetime('2030-01-01 08:00'), end_date=_get_datetime('2099-01-01 10:00')), 'lease3') self.assertEqual( db_utils.shortest_lease( 'r1', start_date=_get_datetime('2030-01-01 10:00'), end_date=_get_datetime('2099-01-01 00:00')), 'lease3') self.assertEqual( db_utils.shortest_lease( 'r1', start_date=_get_datetime('2030-01-01 08:00'), end_date=_get_datetime('2030-01-01 11:00')), 'lease1') self.assertIsNone( db_utils.shortest_lease( 'r1', start_date=_get_datetime('2030-01-01 10:15'), end_date=_get_datetime('2030-01-01 13:00')), 'lease1') # TODO(frossigneux) longest_availability # TODO(frossigneux) shortest_availability