-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
file testing issue - tmp file cleanup #5285
Conversation
Added cleanup function to address the creation of unnecessary tmp files during testing
Add cleanup function to test files to remove temporary files
Add cleanup function to test files to remove temporary files
Add cleanup function to test files to remove temporary files
Add cleanup function to test files to remove temporary files
Add cleanup function to test files to remove temporary files
Hi @khrystianc , thanks for this! I did a quick test using the same shell command as I mentioned in the issue for fi in test/plugins/*.py; do
print Testing $fi && pytest $fi --no-cov &>/dev/null
drs=(/tmp/tmp*)
if (( $#drs )); then
print -l $drs && rm -r $drs
fi
done
it seems like the situation stays the same? |
|
||
if __name__ == "__main__": | ||
unittest.main(defaultTest="suite") | ||
|
||
# Cleanup temporary files |
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 see that this cleanup only runs when this script is called directly
if __name__ == "__main__":
Since we use pytest
to run tests, I think this logic may not run. Have you tried running, say, pytest test/plugins/test_art.py
and checking whether the files have been removed?
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 the quick response. Let me review and get back to you.
@khrystianc from what I've seen most of the offending tests use inherit from the def setup_beets(self, disk=False):
"""Setup pristine global configuration and library for testing.
Sets ``beets.config`` so we can safely use any functionality
that uses the global configuration. All paths used are
contained in a temporary directory
Sets the following properties on itself.
- ``temp_dir`` Path to a temporary directory containing all
files specific to beets
- ``libdir`` Path to a subfolder of ``temp_dir``, containing the
library's media files. Same as ``config['directory']``.
- ``config`` The global configuration used by beets.
- ``lib`` Library instance created with the settings from
``config``.
Make sure you call ``teardown_beets()`` afterwards.
"""
self.create_temp_dir()
os.environ["BEETSDIR"] = util.py3_path(self.temp_dir)
self.config = beets.config
self.config.clear()
self.config.read()
self.config["plugins"] = []
self.config["verbose"] = 1
self.config["ui"]["color"] = False
self.config["threaded"] = False
self.libdir = os.path.join(self.temp_dir, b"libdir")
os.mkdir(syspath(self.libdir))
self.config["directory"] = util.py3_path(self.libdir)
if disk:
dbpath = util.bytestring_path(self.config["library"].as_filename())
else:
dbpath = ":memory:"
self.lib = Library(dbpath, self.libdir) Note the last sentence in the docstring with the following warning:
I have a feeling that these tests may be misusing this functionality, where |
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'm really worried about this implementation. If the user has other files named /tmp/tmp*
, which is entirely possible, they will get wiped out completely by this. We need a much more sophisticated solution to solve this -- or we should use /tmp/beets-test/*
for all our temporary files. Less importantly, the cleanup_tmp_files()
function has been duplicated to a bunch of test modules -- why not define it once and import it everywhere else?
@bal-e I agree. I see what you mean. If you've got an idea on how to implement this, please give it a shot. If not, I will continue to work this issue and definitely take this observation to into account. Thank you so much |
Fixes #5229, is part of #5361 and relates to #5285. I have to admit thsi was a fairly tough task - I initially assumed that the problem lies with how the tests are setup, and that we're probably missing some `teardown_beets` calls here and there. Unfortunately, it was not so simple. I came across several issues that gave rise to leftover temporary files: 1. `fetchart`, `artresizer` and `play` handling of temporary files. These plugins created isolated temporary files outside of the directories that tests clean up. You will find I added a couple of functions (namely `get_module_tempdir`) that force these plugins to create files in directories determined by their module names. This way we can clean up after them using the new `CleanupModulesMixin`. 2. Tests that ran temporary directories setup twice, running `_common.TestCase.setUp` and `test.helper.TestHelper.setup_beets`. Both of these ran `self.temp_dir = mkdtemp()`, therefore the directories created by the initial setup persisted since those have been overridden and thus unreachable in the teardown. Here, I removed the `setUp` calls, see - `test/plugins/test_embedart.py` - `test/test_importer.py` - and `test/test_plugins.py` where `setup_beets` was called twice 3. `test/test_config_command.py` attempted to manage the temporary directory by itself, where I found that `tearDown` failed to remove the directory for four tests. Could not figure out the cause, and found that delegating this task to `TestHelper` fixed the issue. 4. Mediafile fixture removal depended on calling `remove_mediafile_fixtures` method, which `test/plugins/test_zero.py` failed to do. I made the fixtures to be created within the same `temp_dir` directory that gets removed in the teardown, so now they are taken care of automatically. In summary, see the test modules that left files behind: ``` Temp files created by test/__init__.py Temp files created by test/plugins/__init__.py Temp files created by test/plugins/lyrics_download_samples.py Temp files created by test/plugins/test_acousticbrainz.py Temp files created by test/plugins/test_advancedrewrite.py Temp files created by test/plugins/test_albumtypes.py Temp files created by test/plugins/test_art.py /tmp/tmp11nicahe.jpg /tmp/tmp1bjmodum.png /tmp/tmped7nhls4.jpg /tmp/tmpflnzr9wz.jpg /tmp/tmpjngkauqs.png /tmp/tmpkzy9mn6t.jpg /tmp/tmpph_wmuea.jpg /tmp/tmps6gk58i_.jpg /tmp/tmpz2eji_o4.jpg Temp files created by test/plugins/test_aura.py Temp files created by test/plugins/test_bareasc.py /tmp/tmphl3kzhug /tmp/tmpnh2q6v02 /tmp/tmpppw5qrhz Temp files created by test/plugins/test_beatport.py Temp files created by test/plugins/test_bucket.py Temp files created by test/plugins/test_convert.py Temp files created by test/plugins/test_discogs.py Temp files created by test/plugins/test_edit.py Temp files created by test/plugins/test_embedart.py /tmp/tmp1ayvqzhx /tmp/tmp58k6mdfx.jpg /tmp/tmp64c2lqiv /tmp/tmp6nar4kr5 /tmp/tmp6u0d5dex /tmp/tmpacoq7w_f /tmp/tmpajnr_sxr /tmp/tmpasj16beh /tmp/tmpboyaixb5 /tmp/tmpcrmcyt5r /tmp/tmpdomje5g3 /tmp/tmplu3o6t6g /tmp/tmpns_xvkns /tmp/tmpo87o1h6o.jpg /tmp/tmpqem39h_j /tmp/tmprlzm18pb /tmp/tmpt22v4u6x /tmp/tmptp3rxdgv Temp files created by test/plugins/test_embyupdate.py Temp files created by test/plugins/test_export.py Temp files created by test/plugins/test_fetchart.py Temp files created by test/plugins/test_filefilter.py Temp files created by test/plugins/test_ftintitle.py Temp files created by test/plugins/test_hook.py Temp files created by test/plugins/test_ihate.py Temp files created by test/plugins/test_importadded.py Temp files created by test/plugins/test_importfeeds.py Temp files created by test/plugins/test_info.py Temp files created by test/plugins/test_ipfs.py Temp files created by test/plugins/test_keyfinder.py Temp files created by test/plugins/test_lastgenre.py Temp files created by test/plugins/test_limit.py Temp files created by test/plugins/test_lyrics.py Temp files created by test/plugins/test_mbsubmit.py Temp files created by test/plugins/test_mbsync.py Temp files created by test/plugins/test_mpdstats.py Temp files created by test/plugins/test_parentwork.py Temp files created by test/plugins/test_permissions.py Temp files created by test/plugins/test_player.py Temp files created by test/plugins/test_playlist.py Temp files created by test/plugins/test_play.py /tmp/tmp6ohknmve.m3u /tmp/tmp8rw2z_j4.m3u /tmp/tmp9vi27ypx.m3u /tmp/tmpa_s66jh8.m3u /tmp/tmpb7h3cn3n.m3u /tmp/tmpexbmqvry.m3u /tmp/tmpinbqrt80.m3u /tmp/tmpql02hax5.m3u /tmp/tmpvbdzprsf.m3u /tmp/tmpzipim36x.m3u Temp files created by test/plugins/test_plexupdate.py Temp files created by test/plugins/test_plugin_mediafield.py Temp files created by test/plugins/test_random.py Temp files created by test/plugins/test_replaygain.py Temp files created by test/plugins/test_smartplaylist.py Temp files created by test/plugins/test_spotify.py Temp files created by test/plugins/test_subsonicupdate.py Temp files created by test/plugins/test_the.py Temp files created by test/plugins/test_thumbnails.py Temp files created by test/plugins/test_types_plugin.py Temp files created by test/plugins/test_web.py Temp files created by test/plugins/test_zero.py /tmp/tmp3ub9xmzy Temp files created by test/rsrc/beetsplug/test.py Temp files created by test/rsrc/convert_stub.py Temp files created by test/testall.py Temp files created by test/test_art_resize.py /tmp/tmp3p7p60ih.jpg /tmp/tmp8exclgit.jpg /tmp/tmpkrrjsitl.jpg /tmp/tmpw6n8ee8e.jpg /tmp/tmpygws_0aw.jpg Temp files created by test/test_autotag.py Temp files created by test/test_config_command.py /tmp/tmp333f0r2j /tmp/tmphr356z5r /tmp/tmporp4rag2 /tmp/tmpy7sjqdsw Temp files created by test/test_datequery.py Temp files created by test/test_dbcore.py Temp files created by test/test_files.py Temp files created by test/test_hidden.py Temp files created by test/test_importer.py /tmp/tmp0m363gfb /tmp/tmp2n3i13mc /tmp/tmpxk3v304s Temp files created by test/test_library.py Temp files created by test/test_logging.py Temp files created by test/test_m3ufile.py Temp files created by test/test_mb.py Temp files created by test/test_metasync.py Temp files created by test/test_pipeline.py Temp files created by test/test_plugins.py /tmp/tmp6pxhx67u /tmp/tmpb8pqi9ui /tmp/tmpcx_658g7 /tmp/tmp_giqb9jz /tmp/tmpgm9xk94_ /tmp/tmpk60l6bt3 /tmp/tmpqoj4la68 /tmp/tmptcdu20rp /tmp/tmpvr7k5shn /tmp/tmpwnfnzs91 Temp files created by test/test_query.py Temp files created by test/test_sort.py Temp files created by test/test_template.py Temp files created by test/test_ui_commands.py /tmp/tmpns2u94w6 Temp files created by test/test_ui_importer.py Temp files created by test/test_ui_init.py Temp files created by test/test_ui.py Temp files created by test/test_util.py Temp files created by test/test_vfs.py ``` And that's what we have right now: ``` Temp files created by test/__init__.py Temp files created by test/plugins/__init__.py Temp files created by test/plugins/lyrics_download_samples.py Temp files created by test/plugins/test_acousticbrainz.py Temp files created by test/plugins/test_advancedrewrite.py Temp files created by test/plugins/test_albumtypes.py Temp files created by test/plugins/test_art.py Temp files created by test/plugins/test_aura.py Temp files created by test/plugins/test_bareasc.py Temp files created by test/plugins/test_beatport.py Temp files created by test/plugins/test_bucket.py Temp files created by test/plugins/test_convert.py Temp files created by test/plugins/test_discogs.py Temp files created by test/plugins/test_edit.py Temp files created by test/plugins/test_embedart.py Temp files created by test/plugins/test_embyupdate.py Temp files created by test/plugins/test_export.py Temp files created by test/plugins/test_fetchart.py Temp files created by test/plugins/test_filefilter.py Temp files created by test/plugins/test_ftintitle.py Temp files created by test/plugins/test_hook.py Temp files created by test/plugins/test_ihate.py Temp files created by test/plugins/test_importadded.py Temp files created by test/plugins/test_importfeeds.py Temp files created by test/plugins/test_info.py Temp files created by test/plugins/test_ipfs.py Temp files created by test/plugins/test_keyfinder.py Temp files created by test/plugins/test_lastgenre.py Temp files created by test/plugins/test_limit.py Temp files created by test/plugins/test_lyrics.py Temp files created by test/plugins/test_mbsubmit.py Temp files created by test/plugins/test_mbsync.py Temp files created by test/plugins/test_mpdstats.py Temp files created by test/plugins/test_parentwork.py Temp files created by test/plugins/test_permissions.py Temp files created by test/plugins/test_player.py Temp files created by test/plugins/test_playlist.py Temp files created by test/plugins/test_play.py Temp files created by test/plugins/test_plexupdate.py Temp files created by test/plugins/test_plugin_mediafield.py Temp files created by test/plugins/test_random.py Temp files created by test/plugins/test_replaygain.py Temp files created by test/plugins/test_smartplaylist.py Temp files created by test/plugins/test_spotify.py Temp files created by test/plugins/test_subsonicupdate.py Temp files created by test/plugins/test_the.py Temp files created by test/plugins/test_thumbnails.py Temp files created by test/plugins/test_types_plugin.py Temp files created by test/plugins/test_web.py Temp files created by test/plugins/test_zero.py Temp files created by test/rsrc/beetsplug/test.py Temp files created by test/rsrc/convert_stub.py Temp files created by test/testall.py Temp files created by test/test_art_resize.py Temp files created by test/test_autotag.py Temp files created by test/test_config_command.py Temp files created by test/test_datequery.py Temp files created by test/test_dbcore.py Temp files created by test/test_files.py Temp files created by test/test_hidden.py Temp files created by test/test_importer.py Temp files created by test/test_library.py Temp files created by test/test_logging.py Temp files created by test/test_m3ufile.py Temp files created by test/test_mb.py Temp files created by test/test_metasync.py Temp files created by test/test_pipeline.py Temp files created by test/test_plugins.py Temp files created by test/test_query.py Temp files created by test/test_sort.py Temp files created by test/test_template.py Temp files created by test/test_ui_commands.py Temp files created by test/test_ui_importer.py Temp files created by test/test_ui_init.py Temp files created by test/test_ui.py Temp files created by test/test_util.py Temp files created by test/test_vfs.py ``` Note that the command which provides the output is now available through `poe`.
This got superseded by #5345 |
Description
Fixes #5229
(#5229)
To Do
docs/
to describe it.)docs/changelog.rst
to the bottom of one of the lists near the top of the document.)