Round the elapsed time to the nearest second
The db truncates the microseconds so this can end up being negative. Closes-Bug: #1493166 Change-Id: I5169821e7465e483b8379ee7f614ca08877973e7
This commit is contained in:
parent
69e44dbb17
commit
0bc4de65e3
@ -15,6 +15,7 @@
|
||||
Utilities for handling ISO 8601 duration format.
|
||||
"""
|
||||
|
||||
import datetime
|
||||
import random
|
||||
import re
|
||||
import time
|
||||
@ -80,3 +81,12 @@ def retry_backoff_delay(attempt, scale_factor=1.0, jitter_max=0.0):
|
||||
if jitter_max == 0.0:
|
||||
return exp
|
||||
return exp + random.random() * jitter_max
|
||||
|
||||
|
||||
def round_to_seconds(dt):
|
||||
"""Round a datetime to the nearest second."""
|
||||
rounding = 0
|
||||
if dt.microsecond >= 500000:
|
||||
rounding = 1
|
||||
return dt + datetime.timedelta(0, rounding,
|
||||
-dt.microsecond)
|
||||
|
@ -33,6 +33,7 @@ from heat.common.i18n import _LI
|
||||
from heat.common.i18n import _LW
|
||||
from heat.common import identifier
|
||||
from heat.common import lifecycle_plugin_utils
|
||||
from heat.common import timeutils
|
||||
from heat.engine import dependencies
|
||||
from heat.engine import environment
|
||||
from heat.engine import event
|
||||
@ -1688,8 +1689,10 @@ class Stack(collections.Mapping):
|
||||
'''
|
||||
Time elapsed in seconds since the stack operation started.
|
||||
'''
|
||||
start_time = self.updated_time or self.created_time
|
||||
return (datetime.datetime.utcnow() - start_time).seconds
|
||||
start_time = timeutils.round_to_seconds(self.updated_time or
|
||||
self.created_time)
|
||||
nowish = timeutils.round_to_seconds(datetime.datetime.utcnow())
|
||||
return (nowish - start_time).seconds
|
||||
|
||||
def time_remaining(self):
|
||||
'''
|
||||
|
@ -111,6 +111,17 @@ class StackTest(common.HeatTestCase):
|
||||
10, 10, 0)
|
||||
self.assertEqual(600, self.stack.time_elapsed())
|
||||
|
||||
@mock.patch.object(stack, 'datetime')
|
||||
def test_time_elapsed_ms(self, mock_dt):
|
||||
self.stack = stack.Stack(self.ctx, 'test_stack', self.tmpl)
|
||||
# dummy create time 10:00:00
|
||||
self.stack.created_time = datetime.datetime(2015, 7, 27, 10, 5, 0)
|
||||
# mock utcnow set to microsecond offset
|
||||
mock_dt.datetime.utcnow.return_value = datetime.datetime(2015, 7, 27,
|
||||
10, 4, 59,
|
||||
750000)
|
||||
self.assertEqual(0, self.stack.time_elapsed())
|
||||
|
||||
@mock.patch.object(stack, 'datetime')
|
||||
def test_time_elapsed_with_updated_time(self, mock_dt):
|
||||
self.stack = stack.Stack(self.ctx, 'test_stack', self.tmpl)
|
||||
|
@ -11,6 +11,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import datetime
|
||||
from testtools import matchers
|
||||
|
||||
from heat.common import timeutils as util
|
||||
@ -157,3 +158,17 @@ class RetryBackoffJitterTest(common.HeatTestCase):
|
||||
self.attempt, self.scale_factor, self.jitter_max)
|
||||
self.assertThat(delay, matchers.GreaterThan(self.delay_from))
|
||||
self.assertThat(delay, matchers.LessThan(self.delay_to))
|
||||
|
||||
|
||||
class RoundToSecondsTest(common.HeatTestCase):
|
||||
|
||||
scenarios = [('down', dict(in_secs=5, in_ms=12345, out_secs=5)),
|
||||
('up', dict(in_secs=5, in_ms=501000, out_secs=6)),
|
||||
('same', dict(in_secs=5, in_ms=0, out_secs=5))]
|
||||
|
||||
def test_rounding(self):
|
||||
inp = datetime.datetime(2015, 7, 27, 4,
|
||||
34, self.in_secs, self.in_ms)
|
||||
exp = datetime.datetime(2015, 7, 27, 4,
|
||||
34, self.out_secs, 0)
|
||||
self.assertEqual(exp, util.round_to_seconds(inp))
|
||||
|
Loading…
x
Reference in New Issue
Block a user