Repository: mopidy/mopidy
Issue: Refresh of tag cache doesn't remove deleted files

If I update my tag_cache file using mopidy-scan, then force a reload by calling the HTTP API at mopidy.library.refresh(), it will reload the tag cache and newly-added files will be found, but deleted files will still be there if I search for them. I have to restart mopidy for the deleted files to disappear from mopidy's search results.

The debug output in the console even says that the expected number of files have been loaded from the tag cache, but the search results contain more than that.

Mopidy 0.14.2 on OSX.


Changed files:
tests/backends/local/library_test.py, mopidy/backends/local/library.py

diff --git a/mopidy/backends/local/library.py b/mopidy/backends/local/library.py
index 0de63faf..f21ac81a 100644
--- a/mopidy/backends/local/library.py
+++ b/mopidy/backends/local/library.py
@@ -27,9 +27,14 @@ class LocalLibraryProvider(base.BaseLibraryProvider):
             self._media_dir, self._tag_cache_file)
 
         tracks = parse_mpd_tag_cache(self._tag_cache_file, self._media_dir)
+        uris_to_remove = set(self._uri_mapping)
 
         for track in tracks:
             self._uri_mapping[track.uri] = track
+            uris_to_remove.discard(track.uri)
+
+        for uri in uris_to_remove:
+            del self._uri_mapping[uri]
 
         logger.info(
             'Loaded %d local tracks from %s using %s',
diff --git a/tests/backends/local/library_test.py b/tests/backends/local/library_test.py
index 6b0cd6f6..09b3febb 100644
--- a/tests/backends/local/library_test.py
+++ b/tests/backends/local/library_test.py
@@ -1,5 +1,6 @@
 from __future__ import unicode_literals
 
+import tempfile
 import unittest
 
 import pykka
@@ -11,6 +12,8 @@ from mopidy.models import Track, Album, Artist
 from tests import path_to_data_dir
 
 
+# TODO: update tests to only use backend, not core. we need a seperate
+# core test that does this integration test.
 class LocalLibraryProviderTest(unittest.TestCase):
     artists = [
         Artist(name='artist1'),
@@ -49,7 +52,6 @@ class LocalLibraryProviderTest(unittest.TestCase):
     }
 
     def setUp(self):
-
         self.backend = actor.LocalBackend.start(
             config=self.config, audio=None).proxy()
         self.core = core.Core(backends=[self.backend])
@@ -65,9 +67,31 @@ class LocalLibraryProviderTest(unittest.TestCase):
     def test_refresh_uri(self):
         pass
 
-    @unittest.SkipTest
     def test_refresh_missing_uri(self):
-        pass
+        # Verifies that https://github.com/mopidy/mopidy/issues/500
+        # has been fixed.
+
+        tag_cache = tempfile.NamedTemporaryFile()
+        with open(self.config['local']['tag_cache_file']) as fh:
+            tag_cache.write(fh.read())
+        tag_cache.flush()
+
+        config = {'local': self.config['local'].copy()}
+        config['local']['tag_cache_file'] = tag_cache.name
+        backend = actor.LocalBackend(config=config, audio=None)
+
+        # Sanity check that value is in tag cache
+        result = backend.library.lookup(self.tracks[0].uri)
+        self.assertEqual(result, self.tracks[0:1])
+
+        # Clear tag cache and refresh
+        tag_cache.seek(0)
+        tag_cache.truncate()
+        backend.library.refresh()
+
+        # Now it should be gone.
+        result = backend.library.lookup(self.tracks[0].uri)
+        self.assertEqual(result, [])
 
     def test_lookup(self):
         tracks = self.library.lookup(self.tracks[0].uri)