Commit fc281ca8 authored by Sam Thursfield's avatar Sam Thursfield

functional-tests: Seperate extraction test helper into utils module

parent afb0d921
......@@ -25,14 +25,14 @@ directory (containing xxx.expected files)
"""
from common.utils import configuration as cfg
from common.utils.extractor import get_tracker_extract_jsonld_output
from common.utils.extractor import get_tracker_extract_jsonld_output, TrackerExtractTestCase
import unittest as ut
import json
import os
import sys
class ExtractionTestCase (ut.TestCase):
class GenericExtractionTestCase(TrackerExtractTestCase):
"""
Test checks if the tracker extractor is able to retrieve metadata
"""
......@@ -41,7 +41,7 @@ class ExtractionTestCase (ut.TestCase):
"""
Descfile is the description file in a relative path
"""
ut.TestCase.__init__(self, methodName)
super(GenericExtractionTestCase, self).__init__(methodName)
self.descfile = descfile
try:
......@@ -94,106 +94,11 @@ class ExtractionTestCase (ut.TestCase):
else:
raise Exception("Unexpected success. Check " + self.rel_description)
def assertDictHasKey(self, d, key, msg=None):
if not isinstance(d, dict):
self.fail("Expected dict, got %s" % d)
if key not in d:
standardMsg = "Missing: %s\n" % (key)
self.fail(self._formatMessage(msg, standardMsg))
else:
return
def assertIsURN(self, supposed_uuid, msg=None):
import uuid
try:
if (supposed_uuid.startswith("<") and supposed_uuid.endswith(">")):
supposed_uuid = supposed_uuid[1:-1]
uuid.UUID(supposed_uuid)
except ValueError:
standardMsg = "'%s' is not a valid UUID" % (supposed_uuid)
self.fail(self._formatMessage(msg, standardMsg))
def __assert_extraction_ok(self, result):
try:
self.__check(self.spec['metadata'], result)
self.assert_extract_result_matches_spec(self.spec['metadata'], result, self.file_to_extract, self.descfile)
except AssertionError as e:
print("\ntracker-extract returned: %s" % json.dumps(result, indent=4))
raise
def __check(self, spec, result):
error_missing_prop = "Property '%s' hasn't been extracted from file \n'%s'\n (requested on '%s')"
error_wrong_value = "on property '%s' from file %s\n (requested on: '%s')"
error_wrong_length = "Length mismatch on property '%s' from file %s\n (requested on: '%s')"
error_extra_prop = "Property '%s' was explicitely banned for file \n'%s'\n (requested on '%s')"
error_extra_prop_v = "Property '%s' with value '%s' was explicitely banned for file \n'%s'\n (requested on %s')"
expected_pairs = [] # List of expected (key, value)
unexpected_pairs = [] # List of unexpected (key, value)
expected_keys = [] # List of expected keys (the key must be there, value doesnt matter)
for k, v in list(spec.items()):
if k.startswith("!"):
unexpected_pairs.append((k[1:], v))
elif k == '@type':
expected_keys.append('@type')
else:
expected_pairs.append((k, v))
for prop, expected_value in expected_pairs:
self.assertDictHasKey(result, prop,
error_missing_prop % (prop,
self.file_to_extract,
self.descfile))
if expected_value == "@URNUUID@":
self.assertIsURN(result[prop][0]['@id'],
error_wrong_value % (prop,
self.file_to_extract,
self.descfile))
else:
if isinstance(expected_value, list):
if not isinstance(result[prop], list):
raise AssertionError("Expected a list property for %s, but got a %s: %s" % (
prop, type(result[prop]).__name__, result[prop]))
self.assertEqual(len(expected_value), len(result[prop]),
error_wrong_length % (prop,
self.file_to_extract,
self.descfile))
for i in range(0, len(expected_value)):
self.__check(spec[prop][i], result[prop][i])
elif isinstance(expected_value, dict):
self.__check(expected_value, result[prop])
else:
self.assertEqual(str(spec[prop]), str(result[prop]),
error_wrong_value % (prop,
self.file_to_extract,
self.descfile))
for (prop, value) in unexpected_pairs:
# There is no prop, or it is but not with that value
if (value == ""):
self.assertFalse(prop in result, error_extra_prop % (prop,
self.file_to_extract,
self.descfile))
else:
if (value == "@URNUUID@"):
self.assertIsURN(result[prop][0], error_extra_prop % (prop,
self.file_to_extract,
self.descfile))
else:
self.assertNotIn(value, result[prop], error_extra_prop_v % (prop,
value,
self.file_to_extract,
self.descfile))
for prop in expected_keys:
self.assertDictHasKey(result, prop,
error_missing_prop % (prop,
self.file_to_extract,
self.descfile))
def run_all():
......@@ -215,7 +120,7 @@ def run_all():
for root, dirs, files in os.walk(TEST_DATA_PATH):
descriptions = [os.path.join(root, f) for f in files if f.endswith("expected")]
for descfile in descriptions:
tc = ExtractionTestCase(descfile=descfile)
tc = GenericExtractionTestCase(descfile=descfile)
extractionTestSuite.addTest(tc)
result = ut.TextTestRunner(verbosity=1).run(extractionTestSuite)
sys.exit(not result.wasSuccessful())
......@@ -228,7 +133,7 @@ def run_one(filename):
description = os.path.join(os.getcwd(), filename)
extractionTestSuite = ut.TestSuite()
tc = ExtractionTestCase(descfile=description)
tc = GenericExtractionTestCase(descfile=description)
extractionTestSuite.addTest(tc)
result = ut.TextTestRunner(verbosity=2).run(extractionTestSuite)
......
#!/usr/bin/env python3
#
# Copyright (C) 2010, Nokia <ivan.frade@nokia.com>
# Copyright (C) 2018, Sam Thursfield <sam@afuera.me.uk>
# Copyright (C) 2018-2019, Sam Thursfield <sam@afuera.me.uk>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
......@@ -26,6 +26,7 @@ import json
import os
import re
import subprocess
import unittest as ut
def get_tracker_extract_jsonld_output(filename, mime_type=None):
......@@ -70,3 +71,94 @@ def get_tracker_extract_jsonld_output(filename, mime_type=None):
"Output was: %s" % (e, output))
return data
class TrackerExtractTestCase(ut.TestCase):
def assertDictHasKey(self, d, key, msg=None):
if not isinstance(d, dict):
self.fail("Expected dict, got %s" % d)
if key not in d:
standardMsg = "Missing: %s\n" % (key)
self.fail(self._formatMessage(msg, standardMsg))
else:
return
def assertIsURN(self, supposed_uuid, msg=None):
import uuid
try:
if (supposed_uuid.startswith("<") and supposed_uuid.endswith(">")):
supposed_uuid = supposed_uuid[1:-1]
uuid.UUID(supposed_uuid)
except ValueError:
standardMsg = "'%s' is not a valid UUID" % (supposed_uuid)
self.fail(self._formatMessage(msg, standardMsg))
def assert_extract_result_matches_spec(self, spec, result, filename, spec_filename):
"""
Checks tracker-extract json-ld output against the expected result.
Use get_tracker_extract_jsonld_output() to get the extractor output.
Look in test-extraction-data/*/*.expected.json for examples of the spec
format.
"""
error_missing_prop = "Property '%s' hasn't been extracted from file \n'%s'\n (requested on '%s')"
error_wrong_value = "on property '%s' from file %s\n (requested on: '%s')"
error_wrong_length = "Length mismatch on property '%s' from file %s\n (requested on: '%s')"
error_extra_prop = "Property '%s' was explicitely banned for file \n'%s'\n (requested on '%s')"
error_extra_prop_v = "Property '%s' with value '%s' was explicitely banned for file \n'%s'\n (requested on %s')"
expected_pairs = [] # List of expected (key, value)
unexpected_pairs = [] # List of unexpected (key, value)
expected_keys = [] # List of expected keys (the key must be there, value doesnt matter)
for k, v in list(spec.items()):
if k.startswith("!"):
unexpected_pairs.append((k[1:], v))
elif k == '@type':
expected_keys.append('@type')
else:
expected_pairs.append((k, v))
for prop, expected_value in expected_pairs:
self.assertDictHasKey(result, prop,
error_missing_prop % (prop, filename, spec_filename))
if expected_value == "@URNUUID@":
self.assertIsURN(result[prop][0]['@id'],
error_wrong_value % (prop, filename, spec_filename))
else:
if isinstance(expected_value, list):
if not isinstance(result[prop], list):
raise AssertionError("Expected a list property for %s, but got a %s: %s" % (
prop, type(result[prop]).__name__, result[prop]))
self.assertEqual(len(expected_value), len(result[prop]),
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)
elif isinstance(expected_value, dict):
self.assert_extract_result_matches_spec(expected_value, result[prop], filename, spec_filename)
else:
self.assertEqual(str(spec[prop]), str(result[prop]),
error_wrong_value % (prop, filename, spec_filename))
for (prop, value) in unexpected_pairs:
# There is no prop, or it is but not with that value
if (value == ""):
self.assertFalse(prop in result,
error_extra_prop % (prop, filename, spec_filename))
else:
if (value == "@URNUUID@"):
self.assertIsURN(result[prop][0],
error_extra_prop % (prop, filename, spec_filename))
else:
self.assertNotIn(value, result[prop],
error_extra_prop_v % (prop, value, filename, spec_filename))
for prop in expected_keys:
self.assertDictHasKey(result, prop,
error_missing_prop % (prop, filename, spec_filename))
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment