Skip to content

Commit

Permalink
Validate: add RDF graph comparison
Browse files Browse the repository at this point in the history
Check if 2 RDF graphs are isomorphic after execution of RML mappings.
  • Loading branch information
DylanVanAssche committed Feb 22, 2024
1 parent dbc2eec commit f40ad12
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 0 deletions.
81 changes: 81 additions & 0 deletions bench_executor/validate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#!/usr/bin/env python3

"""
Validate the RDF graph output by comparing it with an expected graph.
"""

import os
from rdflib import Graph
from rdflib.compare import to_isomorphic
from bench_executor.logger import Logger


class Validate():
"""Validate the RDF graph by comparing it with an expected graph"""
def __init__(self, data_path: str, config_path: str, directory: str,
verbose: bool):
"""Creates an instance of the Validate class.
Parameters
----------
data_path : str
Path to the data directory of the case.
config_path : str
Path to the config directory of the case.
directory : str
Path to the directory to store logs.
verbose : bool
Enable verbose logs.
"""
self._data_path = os.path.abspath(data_path)
self._config_path = os.path.abspath(config_path)
self._logger = Logger(__name__, directory, verbose)

os.umask(0)
os.makedirs(os.path.join(self._data_path, 'validate'), exist_ok=True)

@property
def name(self):
"""Name of the class: Validate"""
return __name__

@property
def root_mount_directory(self) -> str:
"""Subdirectory in the root directory of the case for Validate.
Returns
-------
subdirectory : str
Subdirectory of the root directory for Validate.
"""
return __name__.lower()

def compare_graphs(self, graph_file: str,
expected_graph_file: str) -> bool:
"""Compare a graph against an expected graph.
Parameters
----------
graph_file : str
Path of the RDF graph file inside shared folder.
expected_graph_file : str
Path of the expected RDF graph file inside shared folder.
Returns
-------
success : bool
Whether the graphs match or not.
"""
path = os.path.join(self._data_path, 'shared')
os.umask(0)
os.makedirs(path, exist_ok=True)

self._logger.debug(f'Comparing {graph_path} against '
f'{expected_graph_path}')
g1 = Graph().parse(os.path.join(path, graph_path))
g2 = Graph().parse(os.path.join(path, expected_graph_path))
iso1 = to_isomorphic(g1)
iso2 = to_isomorphic(g2)

return iso1 == iso2
12 changes: 12 additions & 0 deletions tests/unit_tests
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ from bench_executor.mysql import MySQL # noqa: E402
from bench_executor.collector import Collector, METRICS_FILE_NAME # noqa: E402
from bench_executor.stats import Stats, METRICS_AGGREGATED_FILE_NAME, \
METRICS_SUMMARY_FILE_NAME # noqa: E402
from bench_executor.validate import Validate # noqa: E402

LOG_DIR = os.path.join(os.path.dirname(__file__), '..', 'bench_executor',
'log')
Expand Down Expand Up @@ -251,6 +252,17 @@ class UnitTests(unittest.TestCase):
f2 = metrics_summary_expected_file
self.assertTrue(filecmp.cmp(f1, f2, shallow=False))

def test_validate(self):
graph_file = os.path.join(DATA_DIR, 'validate', 'graph.nq')
expected_graph_file = os.path.join(DATA_DIR, 'validate',
'expected.ttl')
unexpected_graph_file = os.path.join(DATA_DIR, 'validate',
'unexpected.nt')

v = Validate(DATA_DIR, CONFIG_DIR, LOG_DIR, False)
self.assertTrue(v.compare_graphs(graph_file, expected_graph_file))
self.assertFalse(v.compare_graphs(graph_file, unexpected_graph_file))


if __name__ == '__main__':
# SELinux causes weird permission denied issues, warn users
Expand Down

0 comments on commit f40ad12

Please sign in to comment.