Opened 7 years ago

Closed 7 years ago

Last modified 7 years ago

#28361 closed Bug (fixed)

test_was_published_recently_with_old_question test in the tutorial is time dependent

Reported by: marton bognar Owned by: marton bognar
Component: Documentation Version: 1.11
Severity: Normal Keywords: datetime test
Cc: Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: yes UI/UX: no

Description

On my Windows machine the test test_was_published_recently_with_old_question fails. I'm fairly sure I copied every piece of code correctly, but even on a theoretical level I'm not sure why it would succeed.

>python manage.py test polls
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
......F.
======================================================================
FAIL: test_was_published_recently_with_old_question (polls.tests.QuestionModelTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "[...]\polls\tests.py", line 81
, in test_was_published_recently_with_old_question
    self.assertIs(old_question.was_published_recently(), False)
AssertionError: True is not False

----------------------------------------------------------------------
Ran 8 tests in 0.031s

FAILED (failures=1)
Destroying test database for alias 'default'...

The test case in question:

time = timezone.now() - datetime.timedelta(days=1)
old_question = Question(pub_date=time)
self.assertIs(old_question.was_published_recently(), False)

The check used in the function is now - datetime.timedelta(days=1) <= self.pub_date <= now, and the test sets the pub_date to exactly one day before now. Can we be sure that time passes between creating the time variable and checking it against the question's pub_date? This certainly doesn't seem to be the case on my machine (hence the fail).

I think a good and unambiguous solution would be to set time to 1 day and 1 second in the past. This still test the edge case, but it is guaranteed that the check will succeed, even with <=.

I'm not quite sure what the difference is, but an interesting comparison is how python handles the following on this machine:

>>> datetime.now(), datetime.now(), datetime.now(), datetime.now(), datetime.now(), datetime.now()
(datetime.datetime(2017, 7, 4, 17, 28, 20, 132149), datetime.datetime(2017, 7, 4, 17, 28, 20, 132149), datetime.datetime(2017, 7, 4, 17, 28, 20, 132149), datetime.datetime(2017, 7, 4, 17, 28, 20, 132149), datetime.datetime(2017, 7, 4, 17, 28, 20, 132149), datetime.datetime(2017, 7, 4, 17, 28, 20, 132149))

Whereas on my Linux machine every instance has a different value.

System specs:
Windows 8.1 (Version 6.3, Build 9600)
Python 3.6.1
Django 1.11.3

Change History (9)

comment:1 by marton bognar, 7 years ago

Summary: One of the tutorial test cases fail on certain systemsOne of the tutorial test cases fails on certain systems

comment:2 by Tim Graham, 7 years ago

Summary: One of the tutorial test cases fails on certain systemstest_was_published_recently_with_old_question test in the tutorial is time dependent
Triage Stage: UnreviewedReady for checkin

When merging 268a646353c6fa9e5fc3730e13b386ddabb018ef, I thought this could be a problem.

comment:3 by benjaoming, 7 years ago

@martonbognar - what happens if you run:

while True:
    datetime.now()

How often does it change? Might reveal some kind of precision level of said Windows system.

in reply to:  3 comment:4 by marton bognar, 7 years ago

Replying to benjaoming:

@martonbognar - what happens if you run:

while True:
    datetime.now()

How often does it change? Might reveal some kind of precision level of said Windows system.

Here's an excerpt of the output: https://gist.github.com/martonbognar/4de49f322573fc162c1594efd24efe8c
It does not seem very deterministic to me.

in reply to:  2 comment:5 by marton bognar, 7 years ago

Replying to Tim Graham:

When merging 268a646353c6fa9e5fc3730e13b386ddabb018ef, I thought this could be a problem.

So what's the next step? Sorry, I'm new to django issue tracking, should I create a pull request with my proposed changes or will someone more qualified take care of the ticket?

comment:6 by Tim Graham, 7 years ago

You may create a pull request.

comment:7 by marton bognar, 7 years ago

Owner: changed from nobody to marton bognar
Status: newassigned

Thanks, I submitted a pull request, hope it is alright: https://github.com/django/django/pull/8711

comment:8 by Tim Graham <timograham@…>, 7 years ago

Resolution: fixed
Status: assignedclosed

In 82741605:

Fixed #28361 -- Fixed possible time-related failure in was_published_recently() tutorial test.

Regression in 268a646353c6fa9e5fc3730e13b386ddabb018ef.

comment:9 by Tim Graham <timograham@…>, 7 years ago

In 5b450b8:

[1.11.x] Fixed #28361 -- Fixed possible time-related failure in was_published_recently() tutorial test.

Regression in 268a646353c6fa9e5fc3730e13b386ddabb018ef.

Backport of 82741605206382d0afd879c4bce174ef3d6e8aea from master

Note: See TracTickets for help on using tickets.
Back to Top