1#!/usr/bin/env python3
2
3# Copyright (C) 2016, Sam Thursfield (sam@afuera.me.uk)
4#
5# This library is free software; you can redistribute it and/or
6# modify it under the terms of the GNU Lesser General Public
7# License as published by the Free Software Foundation; either
8# version 2.1 of the License, or (at your option) any later version.
9#
10# This library is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13# Lesser General Public License for more details.
14#
15# You should have received a copy of the GNU Lesser General Public
16# License along with this library; if not, write to the
17# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18# Boston, MA  02110-1301, USA.
19
20"""
21Tests failure cases of tracker-extract.
22"""
23
24import unittest as ut
25
26from gi.repository import GLib
27
28import os
29import shutil
30import tempfile
31import time
32
33import common.utils.configuration as cfg
34from common.utils.helpers import log
35from common.utils.system import TrackerSystemAbstraction
36
37
38CORRUPT_FILE = os.path.join(
39    os.path.dirname(__file__), 'test-extraction-data', 'audio',
40    'audio-corrupt.mp3')
41
42VALID_FILE = os.path.join(
43    os.path.dirname(__file__), 'test-extraction-data', 'audio',
44    'audio-test-1.mp3')
45VALID_FILE_CLASS = 'http://www.tracker-project.org/temp/nmm#MusicPiece'
46VALID_FILE_TITLE = 'Simply Juvenile'
47
48TRACKER_EXTRACT_FAILURE_DATA_SOURCE = 'tracker:extractor-failure-data-source'
49
50
51class ExtractorDecoratorTest(ut.TestCase):
52    def setUp(self):
53        self.datadir = cfg.create_monitored_test_dir()
54
55        config = {
56            cfg.DCONF_MINER_SCHEMA: {
57                'enable-writeback': GLib.Variant.new_boolean(False),
58                'index-recursive-directories': GLib.Variant.new_strv([]),
59                'index-single-directories': GLib.Variant.new_strv([self.datadir]),
60                'index-optical-discs': GLib.Variant.new_boolean(False),
61                'index-removable-devices': GLib.Variant.new_boolean(False),
62            },
63            'org.freedesktop.Tracker.Store': {
64                'graphupdated-delay': GLib.Variant('i', 100)
65            }
66        }
67
68        self.system = TrackerSystemAbstraction(config)
69        self.system.tracker_miner_fs_testing_start()
70
71    def tearDown(self):
72        self.system.finish()
73
74        cfg.remove_monitored_test_dir(self.datadir)
75
76    def test_reextraction(self):
77        """Tests whether known files are still re-extracted on user request."""
78        miner_fs = self.system.miner_fs
79        store = self.system.store
80
81        # Insert a valid file and wait extraction of its metadata.
82        file_path = os.path.join(self.datadir, os.path.basename(VALID_FILE))
83        shutil.copy(VALID_FILE, file_path)
84        try:
85            file_id, file_urn = store.await_resource_inserted(
86                VALID_FILE_CLASS, title=VALID_FILE_TITLE)
87
88            # Remove a key piece of metadata.
89            #   (Writeback must be disabled in the config so that the file
90            #   itself is not changed).
91            store.update(
92                'DELETE { <%s> nie:title ?title }'
93                ' WHERE { <%s> nie:title ?title }' % (file_urn, file_urn))
94            store.await_property_changed(VALID_FILE_CLASS, file_id, 'nie:title')
95            assert not store.ask('ASK { <%s> nie:title ?title }' % file_urn)
96
97            log("Sending re-index request")
98            # Request re-indexing (same as `tracker index --file ...`)
99            miner_fs.index_file('file://' + os.path.join(self.datadir, file_path))
100
101            # The extractor should reindex the file and re-add the metadata that we
102            # deleted, so we should see the nie:title property change.
103            store.await_property_changed(VALID_FILE_CLASS, file_id, 'nie:title')
104
105            title_result = store.query('SELECT ?title { <%s> nie:title ?title }' % file_urn)
106            assert len(title_result) == 1
107            self.assertEqual(title_result[0][0], VALID_FILE_TITLE)
108        finally:
109            os.remove(file_path)
110
111
112if __name__ == '__main__':
113    ut.main()
114