我正在使用Django应用Pyroven并正在对其功能进行一些重大的重新设计。作为其中的一部分,我已经开始为它编写测试框架,因为目前它没有单元测试。作为后台,它使用University of Cambridge Raven service进行身份验证,并为Django提供身份验证后端以利用此服务。
我遇到的问题是测试来自Raven的WLS-Response令牌。这会形成一个!
个分隔值的字符串,其中包含以下格式的时间字段:
%Y%m%dT%H%M%SZ
在我的测试代码中,我将其创建为:
raven_issue = datetime.now().strftime('%Y%m%dT%H%M%SZ')
然后将其返回到测试URL以供视图处理。问题在于验证过去这次对于响应的验证并不太远。验证它的代码使用:
def parse_time(t):
"""Converts a time of the form '20110729T123456Z' to a number of seconds
since the epoch.
@exception ValueError if the time is not a valid Raven time"""
time_struct = time.strptime(t, "%Y%m%dT%H%M%SZ")
return calendar.timegm(time_struct)
现在,当它从datetime.now()构造函数传递上面的字符串时,对此解析值的验证失败:
# Check that the issue time is not in the future or too far in the past:
if self.issue > time.time() + PYROVEN_MAX_CLOCK_SKEW:
raise InvalidResponseError("The timestamp on the response is in the future")
if self.issue < time.time() - PYROVEN_MAX_CLOCK_SKEW - PYROVEN_TIMEOUT:
raise InvalidResponseError("The response has timed out")
此代码因我的测试失败,声称响应已超时。 PYROVEN_MAX_CLOCK_SKEW
和PYROVEN_TIMEOUT
的值分别为2和10。
这引出了一个问题,即处理时间有些变化我不明白?如果我将datetime.now()
生成的值放在未来2小时datetime.timedelta
的情况下,将其转换为字符串并将其传递给验证,尽管时间戳在将来,但不会失败,什么时候应该。为什么这样,因为代码的逻辑读数表明它应该?
答案 0 :(得分:2)
您在当地时间(由datetime.now()
和GMT返回(由calendar.timegm()
解析)之间感到困惑:
>>> t = datetime.now().strftime('%Y%m%dT%H%M%SZ')
>>> t
'20120910T232358Z'
>>> calendar.timegm(time.strptime(t, "%Y%m%dT%H%M%SZ"))
1347319438
>>> time.mktime(time.localtime())
1347312258.0
>>> time.mktime(time.strptime(t, "%Y%m%dT%H%M%SZ"))
1347312238.0
结论:使用time.mktime
代替calendar.timegm
将您的值转换为时间戳。