diff options
| author | Monsyne Dragon <mdragon@rackspace.com> | 2012-03-07 00:49:57 +0000 |
|---|---|---|
| committer | Monsyne Dragon <mdragon@rackspace.com> | 2012-03-07 16:32:47 +0000 |
| commit | 6de3fe69f64fd0c304ee3f8e4bdcafada0d48117 (patch) | |
| tree | 133a10ea4da550d60d78b836a7c9735d30644957 | |
| parent | d8324bb3d089acd444bd1639a3efc07e89556f69 (diff) | |
| download | nova-6de3fe69f64fd0c304ee3f8e4bdcafada0d48117.tar.gz nova-6de3fe69f64fd0c304ee3f8e4bdcafada0d48117.tar.xz nova-6de3fe69f64fd0c304ee3f8e4bdcafada0d48117.zip | |
Add adjustable offset to audit_period.
Allows audit periods to be offset, so daily periods can begin at local
midnight, instead of UTC, monthly periods can begin on the 15th
instead of the 1st, etc.
Fixes bug 948601
Change-Id: I38f6af0a5a513f888b791a4b9ca39467030105f2
| -rw-r--r-- | nova/tests/test_utils.py | 164 | ||||
| -rw-r--r-- | nova/utils.py | 83 |
2 files changed, 230 insertions, 17 deletions
diff --git a/nova/tests/test_utils.py b/nova/tests/test_utils.py index e3457dd2d..15b618d8e 100644 --- a/nova/tests/test_utils.py +++ b/nova/tests/test_utils.py @@ -965,3 +965,167 @@ class TestLockCleanup(test.TestCase): self.assertTrue(os.path.exists(lock3)) os.unlink(lock3) + + +class AuditPeriodTest(test.TestCase): + + def setUp(self): + super(AuditPeriodTest, self).setUp() + #a fairly random time to test with + self.test_time = datetime.datetime(second=23, + minute=12, + hour=8, + day=5, + month=3, + year=2012) + utils.set_time_override(override_time=self.test_time) + + def tearDown(self): + utils.clear_time_override() + super(AuditPeriodTest, self).tearDown() + + def test_hour(self): + begin, end = utils.current_audit_period(unit='hour') + self.assertEquals(begin, datetime.datetime( + hour=7, + day=5, + month=3, + year=2012)) + self.assertEquals(end, datetime.datetime( + hour=8, + day=5, + month=3, + year=2012)) + + def test_hour_with_offset_before_current(self): + begin, end = utils.current_audit_period(unit='hour@10') + self.assertEquals(begin, datetime.datetime( + minute=10, + hour=7, + day=5, + month=3, + year=2012)) + self.assertEquals(end, datetime.datetime( + minute=10, + hour=8, + day=5, + month=3, + year=2012)) + + def test_hour_with_offset_after_current(self): + begin, end = utils.current_audit_period(unit='hour@30') + self.assertEquals(begin, datetime.datetime( + minute=30, + hour=6, + day=5, + month=3, + year=2012)) + self.assertEquals(end, datetime.datetime( + minute=30, + hour=7, + day=5, + month=3, + year=2012)) + + def test_day(self): + begin, end = utils.current_audit_period(unit='day') + self.assertEquals(begin, datetime.datetime( + day=4, + month=3, + year=2012)) + self.assertEquals(end, datetime.datetime( + day=5, + month=3, + year=2012)) + + def test_day_with_offset_before_current(self): + begin, end = utils.current_audit_period(unit='day@6') + self.assertEquals(begin, datetime.datetime( + hour=6, + day=4, + month=3, + year=2012)) + self.assertEquals(end, datetime.datetime( + hour=6, + day=5, + month=3, + year=2012)) + + def test_day_with_offset_after_current(self): + begin, end = utils.current_audit_period(unit='day@10') + self.assertEquals(begin, datetime.datetime( + hour=10, + day=3, + month=3, + year=2012)) + self.assertEquals(end, datetime.datetime( + hour=10, + day=4, + month=3, + year=2012)) + + def test_month(self): + begin, end = utils.current_audit_period(unit='month') + self.assertEquals(begin, datetime.datetime( + day=1, + month=2, + year=2012)) + self.assertEquals(end, datetime.datetime( + day=1, + month=3, + year=2012)) + + def test_month_with_offset_before_current(self): + begin, end = utils.current_audit_period(unit='month@2') + self.assertEquals(begin, datetime.datetime( + day=2, + month=2, + year=2012)) + self.assertEquals(end, datetime.datetime( + day=2, + month=3, + year=2012)) + + def test_month_with_offset_after_current(self): + begin, end = utils.current_audit_period(unit='month@15') + self.assertEquals(begin, datetime.datetime( + day=15, + month=1, + year=2012)) + self.assertEquals(end, datetime.datetime( + day=15, + month=2, + year=2012)) + + def test_year(self): + begin, end = utils.current_audit_period(unit='year') + self.assertEquals(begin, datetime.datetime( + day=1, + month=1, + year=2011)) + self.assertEquals(end, datetime.datetime( + day=1, + month=1, + year=2012)) + + def test_year_with_offset_before_current(self): + begin, end = utils.current_audit_period(unit='year@2') + self.assertEquals(begin, datetime.datetime( + day=1, + month=2, + year=2011)) + self.assertEquals(end, datetime.datetime( + day=1, + month=2, + year=2012)) + + def test_year_with_offset_after_current(self): + begin, end = utils.current_audit_period(unit='year@6') + self.assertEquals(begin, datetime.datetime( + day=1, + month=6, + year=2010)) + self.assertEquals(end, datetime.datetime( + day=1, + month=6, + year=2011)) diff --git a/nova/utils.py b/nova/utils.py index 712242fd5..5b8eda012 100644 --- a/nova/utils.py +++ b/nova/utils.py @@ -373,38 +373,87 @@ EASIER_PASSWORD_SYMBOLS = ('23456789', # Removed: 0, 1 def current_audit_period(unit=None): + """This method gives you the most recently *completed* audit period. + + arguments: + units: string, one of 'hour', 'day', 'month', 'year' + Periods normally begin at the beginning (UTC) of the + period unit (So a 'day' period begins at midnight UTC, + a 'month' unit on the 1st, a 'year' on Jan, 1) + unit string may be appended with an optional offset + like so: 'day@18' This will begin the period at 18:00 + UTC. 'month@15' starts a monthly period on the 15th, + and year@3 begins a yearly one on March 1st. + + + returns: 2 tuple of datetimes (begin, end) + The begin timestamp of this audit period is the same as the + end of the previous.""" if not unit: unit = FLAGS.instance_usage_audit_period + + offset = 0 + if '@' in unit: + unit, offset = unit.split("@", 1) + offset = int(offset) + rightnow = utcnow() if unit not in ('month', 'day', 'year', 'hour'): raise ValueError('Time period must be hour, day, month or year') - n = 1 # we are currently only using multiples of 1 unit (mdragon) if unit == 'month': - year = rightnow.year - (n // 12) - n = n % 12 - if n >= rightnow.month: - year -= 1 - month = 12 + (rightnow.month - n) - else: - month = rightnow.month - n - begin = datetime.datetime(day=1, month=month, year=year) - end = datetime.datetime(day=1, + if offset == 0: + offset = 1 + end = datetime.datetime(day=offset, month=rightnow.month, year=rightnow.year) + if end >= rightnow: + year = rightnow.year + if 1 >= rightnow.month: + year -= 1 + month = 12 + (rightnow.month - 1) + else: + month = rightnow.month - 1 + end = datetime.datetime(day=offset, + month=month, + year=year) + year = end.year + if 1 >= end.month: + year -= 1 + month = 12 + (end.month - 1) + else: + month = end.month - 1 + begin = datetime.datetime(day=offset, month=month, year=year) elif unit == 'year': - begin = datetime.datetime(day=1, month=1, year=rightnow.year - n) - end = datetime.datetime(day=1, month=1, year=rightnow.year) + if offset == 0: + offset = 1 + end = datetime.datetime(day=1, month=offset, year=rightnow.year) + if end >= rightnow: + end = datetime.datetime(day=1, + month=offset, + year=rightnow.year - 1) + begin = datetime.datetime(day=1, + month=offset, + year=rightnow.year - 2) + else: + begin = datetime.datetime(day=1, + month=offset, + year=rightnow.year - 1) elif unit == 'day': - b = rightnow - datetime.timedelta(days=n) - begin = datetime.datetime(day=b.day, month=b.month, year=b.year) - end = datetime.datetime(day=rightnow.day, + end = datetime.datetime(hour=offset, + day=rightnow.day, month=rightnow.month, year=rightnow.year) + if end >= rightnow: + end = end - datetime.timedelta(days=1) + begin = end - datetime.timedelta(days=1) + elif unit == 'hour': - end = rightnow.replace(minute=0, second=0, microsecond=0) - begin = end - datetime.timedelta(hours=n) + end = rightnow.replace(minute=offset, second=0, microsecond=0) + if end >= rightnow: + end = end - datetime.timedelta(hours=1) + begin = end - datetime.timedelta(hours=1) return (begin, end) |
