[tracker-miners/sam/cuesheet-testcase: 2/2] functional-tests: Add a test for the cuesheet extractor
- From: Sam Thursfield <sthursfield src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [tracker-miners/sam/cuesheet-testcase: 2/2] functional-tests: Add a test for the cuesheet extractor
- Date: Mon, 1 Apr 2019 11:43:06 +0000 (UTC)
commit 3ffda3860a10ae971eb6c6c105000f370ea1169b
Author: Sam Thursfield <sam afuera me uk>
Date: Mon Apr 1 13:40:03 2019 +0200
functional-tests: Add a test for the cuesheet extractor
We recently discovered a long standing regression in this feature:
https://gitlab.gnome.org/GNOME/tracker-miners/issues/60
As the saying goes: "if it's not tested, it doesn't work"[1].
Depends on https://gitlab.gnome.org/GNOME/tracker/merge_requests/85
1. https://yakking.branchable.com/posts/truism-4-if-it-is-not-tested/
.../401-extractor-flac-cuesheet.py | 101 +++++++++++++++++++++
tests/functional-tests/common/utils/extractor.py | 53 ++++++++++-
tests/functional-tests/meson.build | 1 +
3 files changed, 154 insertions(+), 1 deletion(-)
---
diff --git a/tests/functional-tests/401-extractor-flac-cuesheet.py
b/tests/functional-tests/401-extractor-flac-cuesheet.py
new file mode 100755
index 000000000..fc2df05a4
--- /dev/null
+++ b/tests/functional-tests/401-extractor-flac-cuesheet.py
@@ -0,0 +1,101 @@
+#!/usr/bin/env python3
+
+# Copyright (C) 2019, Sam Thursfield (sam afuera me uk)
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the
+# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+
+"""
+Tests the FLAC+cuesheet extraction feature.
+"""
+
+
+import os
+import shutil
+import tempfile
+import unittest as ut
+
+import common.utils.configuration as cfg
+from common.utils.helpers import log
+from common.utils.extractor import get_tracker_extract_jsonld_output, create_test_flac,
TrackerExtractTestCase
+
+
+class FlacCuesheetTest(TrackerExtractTestCase):
+ def spec(self, audio_path):
+ audio_uri = 'file://' + audio_path
+ return {
+ '@type': ['nfo:Audio'],
+ 'nie:url': audio_uri,
+ 'nfo:duration': 360,
+ 'nfo:sampleRate': 44100,
+ 'nie:hasLogicalPart': [
+ {
+ '@type': ['nmm:MusicPiece', 'nfo:Audio'],
+ 'nfo:audioOffset': 0.0,
+ 'nfo:duration': 257,
+ 'nie:isLogicalPartOf': audio_uri,
+ 'nie:isStoredAs': audio_uri,
+ 'nie:title': 'Only Shallow',
+ 'nmm:trackNumber': 1,
+ 'nmm:musicAlbum': {
+ '@id': 'urn:album:Loveless:My%20Bloody%20Valentine',
+ '@type': 'nmm:MusicAlbum',
+ 'nmm:albumTrackCount': 2,
+ 'nmm:albumArtist': ['urn:artist:My%20Bloody%20Valentine'],
+ 'nie:title': 'Loveless',
+ },
+ 'nmm:musicAlbumDisc': {
+ '@id': 'urn:album-disc:Loveless:My%20Bloody%20Valentine:Disc1',
+ '@type': 'nmm:MusicAlbumDisc',
+ 'nmm:setNumber': 1,
+ 'nmm:albumDiscAlbum': 'urn:album:Loveless:My%20Bloody%20Valentine',
+ },
+ 'nmm:performer': {
+ '@id': 'urn:artist:My%20Bloody%20Valentine',
+ '@type': 'nmm:Artist',
+ 'nmm:artistName': 'My Bloody Valentine',
+ },
+ },
+ {
+ '@type': ['nmm:MusicPiece', 'nfo:Audio'],
+ 'nfo:audioOffset': 257.6933333333333,
+ 'nfo:duration': 102,
+ 'nie:isLogicalPartOf': audio_uri,
+ 'nie:isStoredAs': audio_uri,
+ 'nmm:musicAlbum': 'urn:album:Loveless:My%20Bloody%20Valentine',
+ 'nmm:musicAlbumDisc': 'urn:album-disc:Loveless:My%20Bloody%20Valentine:Disc1',
+ 'nmm:performer': 'urn:artist:My%20Bloody%20Valentine',
+ 'nie:title': 'Loomer',
+ 'nmm:trackNumber': 2,
+ }
+ ],
+ }
+
+ def test_external_cue_sheet(self):
+ with tempfile.TemporaryDirectory() as tmpdir:
+ datadir = os.path.join(os.getcwd() + "/test-extraction-data")
+ shutil.copy(os.path.join(datadir, 'audio', 'cuesheet-test.cue'), tmpdir)
+
+ audio_path = os.path.join(tmpdir, 'cuesheet-test.flac')
+ create_test_flac(audio_path, duration=6*60)
+
+ result = get_tracker_extract_jsonld_output(audio_path)
+
+ self.assert_extract_result_matches_spec(
+ self.spec(audio_path), result, audio_path, __file__)
+
+
+if __name__ == '__main__':
+ ut.main()
diff --git a/tests/functional-tests/common/utils/extractor.py
b/tests/functional-tests/common/utils/extractor.py
index 85a1df940..17148b948 100644
--- a/tests/functional-tests/common/utils/extractor.py
+++ b/tests/functional-tests/common/utils/extractor.py
@@ -23,11 +23,16 @@ from common.utils import configuration as cfg
from common.utils.helpers import log
import errno
import json
+import math
import os
import re
import subprocess
import unittest as ut
+import gi
+gi.require_version('Gst', '1.0')
+from gi.repository import GLib, Gst
+
def get_tracker_extract_jsonld_output(filename, mime_type=None):
"""
@@ -139,7 +144,11 @@ class TrackerExtractTestCase(ut.TestCase):
error_wrong_length % (prop, filename, spec_filename))
for i in range(0, len(expected_value)):
- self.assert_extract_result_matches_spec(spec[prop][i], result[prop][i], filename,
spec_filename)
+ if isinstance(expected_value[i], dict):
+ self.assert_extract_result_matches_spec(expected_value[i], result[prop][i],
filename, spec_filename)
+ else:
+ self.assertEqual(str(expected_value[i]), str(result[prop][i]),
+ error_wrong_value % (prop, filename, spec_filename))
elif isinstance(expected_value, dict):
self.assert_extract_result_matches_spec(expected_value, result[prop], filename,
spec_filename)
else:
@@ -162,3 +171,45 @@ class TrackerExtractTestCase(ut.TestCase):
for prop in expected_keys:
self.assertDictHasKey(result, prop,
error_missing_prop % (prop, filename, spec_filename))
+
+
+def create_test_flac(path, duration, timeout=10):
+ """
+ Create a .flac audio file for testing purposes.
+
+ FLAC audio doesn't compress test data particularly efficiently, so
+ committing an audio file more than a few seconds long to Git is not
+ practical. This function creates a .flac file containing a test tone.
+ The 'duration' parameter sets the length in seconds of the time.
+
+ The function is guaranteed to return or raise an exception within the
+ number of seconds given in the 'timeout' parameter.
+ """
+
+ Gst.init([])
+
+ num_buffers = math.ceil(duration * 44100 / 1024.0)
+
+ pipeline_src = ' ! '.join([
+ 'audiotestsrc num-buffers=%s samplesperbuffer=1024' % num_buffers,
+ 'capsfilter caps="audio/x-raw,rate=44100"',
+ 'flacenc',
+ 'filesink location=%s' % path,
+ ])
+
+ log("Running pipeline: %s" % pipeline_src)
+ pipeline = Gst.parse_launch(pipeline_src)
+ ret = pipeline.set_state(Gst.State.PLAYING)
+
+ msg = pipeline.get_bus().poll(Gst.MessageType.ERROR | Gst.MessageType.EOS,
+ timeout * Gst.SECOND)
+ if msg and msg.type == Gst.MessageType.EOS:
+ pass
+ elif msg and msg.type == Gst.MessageType.ERROR:
+ raise RuntimeError(msg.parse_error())
+ elif msg:
+ raise RuntimeError("Got unexpected GStreamer message %s" % msg.type)
+ else:
+ raise RuntimeError("Timeout generating test audio file after %i seconds" % timeout)
+
+ pipeline.set_state(Gst.State.NULL)
diff --git a/tests/functional-tests/meson.build b/tests/functional-tests/meson.build
index a24cfe491..df7c0009b 100644
--- a/tests/functional-tests/meson.build
+++ b/tests/functional-tests/meson.build
@@ -24,6 +24,7 @@ functional_tests = [
'310-fts-basic',
'311-fts-file-operations',
'312-fts-stopwords',
+ '401-extractor-flac-cuesheet',
'410-extractor-decorator',
'500-writeback',
'501-writeback-details',
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]