-
-
Notifications
You must be signed in to change notification settings - Fork 32.5k
bpo-25872: Add unit tests for linecache and threading #25913
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 6 commits
5143e74
fc1f92d
fc4df5d
a977922
759de2b
5666a1d
4513859
8376d21
708e348
f021de2
a396fad
833c9b9
bcc20ab
ba62b83
420a638
2c8269b
8efe040
240eb9a
f66a050
78897e7
ac550ef
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,6 +37,13 @@ def f(): | |
def f(): | ||
return 3''' # No ending newline | ||
|
||
SOURCE_4 = ''' | ||
raise OSError | ||
''' | ||
|
||
def raise_oserror(*args, **kwargs): | ||
raise OSError | ||
|
||
|
||
class TempFile: | ||
|
||
|
@@ -181,6 +188,37 @@ def test_checkcache(self): | |
self.assertEqual(line, getline(source_name, index + 1)) | ||
source_list.append(line) | ||
|
||
def test_checkcache_oserror(self): | ||
linecache.clearcache() | ||
_ = linecache.getlines(FILENAME) | ||
self.assertTrue(_) | ||
self.assertEqual(1, len(linecache.cache.keys())) | ||
|
||
with support.swap_attr(os, 'stat', raise_oserror): | ||
# pop all cache | ||
_ = linecache.checkcache() | ||
self.assertEqual(0, len(linecache.cache.keys())) | ||
|
||
def test_updatecache_oserror(self): | ||
linecache.clearcache() | ||
source_name = os_helper.TESTFN | ||
self.addCleanup(os_helper.unlink, os_helper.TESTFN) | ||
|
||
with open(source_name, 'w', encoding='utf-8') as source: | ||
source.write(SOURCE_4) | ||
_ = linecache.getlines(source_name) | ||
self.assertEqual(1, len(linecache.cache.keys())) | ||
|
||
with support.swap_attr(os, 'stat', raise_oserror): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As above - delete/modify the file instead of mocking os.stat. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As shown above, I write delete/modify test. |
||
# Trace OSError with no pop cache | ||
_ = linecache.updatecache('dummy') | ||
self.assertEqual(1, len(linecache.cache.keys())) | ||
|
||
with support.swap_attr(os, 'stat', raise_oserror): | ||
# Trace OSError with pop cache | ||
_ = linecache.updatecache(source_name) | ||
self.assertEqual(0, len(linecache.cache.keys())) | ||
|
||
def test_lazycache_no_globals(self): | ||
lines = linecache.getlines(FILENAME) | ||
linecache.clearcache() | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1338,6 +1338,25 @@ def run(self): | |
# explicitly break the reference cycle to not leak a dangling thread | ||
thread.exc = None | ||
|
||
def test_multithread_modify_file_noerror(self): | ||
uniocto marked this conversation as resolved.
Show resolved
Hide resolved
|
||
import traceback | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe PEP-8 asks for imports to be at module scope There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hi @iritkatriel
|
||
def modify_file(): | ||
with open(__file__, 'a') as fp: | ||
iritkatriel marked this conversation as resolved.
Show resolved
Hide resolved
|
||
fp.write(' ') | ||
iritkatriel marked this conversation as resolved.
Show resolved
Hide resolved
|
||
traceback.format_stack() | ||
|
||
threads = [ | ||
threading.Thread(target=modify_file) | ||
for i in range(100) | ||
] | ||
try: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Which exceptions are you trying to ignore here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nothing, sorry. I removed |
||
for t in threads: | ||
t.start() | ||
for t in threads: | ||
t.join() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a reason why you don't do
? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nothing, sorry. |
||
finally: | ||
pass | ||
|
||
|
||
class ThreadRunFail(threading.Thread): | ||
def run(self): | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fact that os.stat is used in checkcache is an implementation detail, not a part of that's function's external API, so I don't think the unit test should depend on that.
I would write this as a black-box test. And also test that the cache clearing is selective. Note that there are two cases in checkcache() where the cache is popped: OSError from stat, or size/timestamp don't match.
So, create three files f1, f2, f3 and load them into the cache. Then delete f1, modify f2 and call checkcache. Ensure that the cache entries for f1 and f2 were removed from the cache but the entries for f3 are still there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for your feedback.
As you said, other tests are written in such a way that they do not depend on the internal implementation.
I will try to write them in a black box as you suggested, so I would appreciate it if you could take look again !!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I write a black box test, and would be happy if you could check it out.