Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/ted 661 #239

Merged
merged 24 commits into from
Aug 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
fa84a8f
Updated Validation Summary Report
Aug 19, 2022
4603582
Added index_notice_native service for XPATHs extract using native pyt…
Aug 23, 2022
302e2d8
Refactor: replace metadata reader where suitable
Aug 23, 2022
9afa08a
Merge remote-tracking branch 'origin/main' into feature/TED-661
Aug 26, 2022
7c7b39f
Updated jinja template external resoutrce protocol
Aug 26, 2022
74b7c01
Changed notice_indexer to native one
Aug 30, 2022
4898484
Merge branch 'main' into feature/TED-661
CaptainOfHacks Aug 30, 2022
dec7407
Update unit-tests-hermes.yml
CaptainOfHacks Aug 30, 2022
1751669
Merge branch 'main' into feature/TED-661
CaptainOfHacks Aug 30, 2022
485a8a3
Update unit-tests-hermes.yml
CaptainOfHacks Aug 30, 2022
5c8bd59
updated install-allure make target
Aug 30, 2022
3d8e9e9
Merge branch 'feature/TED-661' of github.com:meaningfy-ws/ted-sws int…
Aug 30, 2022
6566cf0
updated install-allure make target
Aug 30, 2022
eb285e1
updated install-allure make target
Aug 30, 2022
fab1279
updated install-allure make target
Aug 30, 2022
d9fb872
updated install-allure make target
Aug 30, 2022
d5887a2
updated install-allure make target
Aug 30, 2022
77aa9e1
updated install-allure make target
Aug 30, 2022
5faaeec
updated install-allure make target
Aug 30, 2022
909ae56
updated install-allure make target
Aug 30, 2022
29be085
saxon step moved in job
Dragos0000 Aug 31, 2022
4adc6df
testing without allure
Dragos0000 Aug 31, 2022
71cdec7
testing with allure
Dragos0000 Aug 31, 2022
14b86ee
removing allure
Dragos0000 Aug 31, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions .github/workflows/unit-tests-hermes.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,22 @@ jobs:
runs-on: self-hosted

steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2

- name: Make envfile
run: make staging-dotenv-file

- name: Get RML mapper
run: make init-rml-mapper

- name: Get Saxon
run: make init-saxon

- name: Get Allure
run: make install-allure
- name: Run command
run: echo "Echo"

- name: Get RML mapper
run: make init-rml-mapper

# - name: Get Allure
# run: make install-allure

# - name: Start staging infra
# run: make start-project-services
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -374,5 +374,5 @@ restore-mongodb:

install-allure:
@ echo -e "Start install Allure commandline."
@ apt install npm
@ npm install -g allure-commandline
@ sudo apt -y install npm
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why we need sudo for this command ?

@ sudo npm install -g allure-commandline
1 change: 1 addition & 0 deletions ted_sws/core/model/manifestation.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ class RDFManifestationValidationSummaryReport(PropertyBaseModel):


class ValidationSummaryReport(ValidationManifestation):
notice_id: Optional[List[str]] = []
xml_manifestation: Optional[XMLManifestationValidationSummaryReport] = XMLManifestationValidationSummaryReport()
rdf_manifestation: Optional[RDFManifestationValidationSummaryReport] = RDFManifestationValidationSummaryReport()
distilled_rdf_manifestation: Optional[
Expand Down
49 changes: 48 additions & 1 deletion ted_sws/data_sampler/services/notice_xml_indexer.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
from ted_sws.core.model.notice import Notice
from ted_sws.data_manager.adapters.notice_repository import NoticeRepository
from ted_sws.resources import XSLT_FILES_PATH
import xml.etree.ElementTree as XMLElementTree
import re

UNIQUE_XPATHS_XSLT_FILE_PATH = "get_unique_xpaths.xsl"
XSLT_PREFIX_RESULT = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
Expand All @@ -28,7 +30,7 @@ def index_notice_by_id(notice_id: str, mongodb_client: MongoClient):
notice_repository.update(notice=notice)


def index_notice(notice: Notice, xslt_transformer=None) -> Notice:
def index_notice_xslt(notice: Notice, xslt_transformer=None) -> Notice:
"""
This function selects unique XPath from XMlManifestation from a notice and indexes notices with these unique XPath.
:param notice:
Expand Down Expand Up @@ -56,6 +58,51 @@ def index_notice(notice: Notice, xslt_transformer=None) -> Notice:
return notice


def index_notice(notice: Notice, base_xpath="") -> Notice:
def _notice_namespaces(xml_file) -> dict:
_namespaces = dict([node for _, node in XMLElementTree.iterparse(xml_file, events=['start-ns'])])
return {v: k for k, v in _namespaces.items()}

def _ns_tag(ns_tag):
tag = ns_tag[1]
ns = ns_tag[0]
if ns:
ns_alias = namespaces[ns]
if ns_alias:
return ns_alias + ":" + tag
return tag

def _xpath_generator(xml_file):
path = []
it = XMLElementTree.iterparse(xml_file, events=('start', 'end'))
for evt, el in it:
if evt == 'start':
ns_tag = re.split('[{}]', el.tag, 2)[1:]
path.append(_ns_tag(ns_tag) if len(ns_tag) > 1 else el.tag)

xpath = "/" + '/'.join(path)

if xpath.startswith(base_xpath + "/"):
attributes = list(el.attrib.keys())
if len(attributes) > 0:
for attr in attributes:
yield xpath + "/@" + attr
yield xpath
else:
path.pop()

with tempfile.NamedTemporaryFile() as fp:
fp.write(notice.xml_manifestation.object_data.encode("utf-8"))

namespaces = _notice_namespaces(fp.name)
xpaths = list(set(_xpath_generator(fp.name)))
xml_metadata = XMLMetadata()
xml_metadata.unique_xpaths = xpaths
notice.set_xml_metadata(xml_metadata=xml_metadata)

return notice


def get_unique_xpaths_from_notice_repository(mongodb_client: MongoClient) -> List[str]:
"""
This function returns all unique XPaths in notice_repository.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import pandas as pd

from ted_sws.mapping_suite_processor import CONCEPTUAL_MAPPINGS_METADATA_SHEET_NAME
from ted_sws.mapping_suite_processor.services.conceptual_mapping_reader import mapping_suite_read_metadata

VERSION_FIELD = 'Mapping Version'
EPO_VERSION_FIELD = 'EPO version'
Expand Down Expand Up @@ -70,10 +71,7 @@ def mapping_suite_processor_generate_metadata(conceptual_mappings_file_path: pat
:param output_metadata_file_path:
:return:
"""
with open(conceptual_mappings_file_path, 'rb') as excel_file:
conceptual_mappings_metadata_df = pd.read_excel(excel_file, sheet_name=CONCEPTUAL_MAPPINGS_METADATA_SHEET_NAME)
raw_metadata = conceptual_mappings_metadata_df.set_index('Field').T.to_dict('list')
metadata = generate_metadata(raw_metadata=raw_metadata)
metadata = generate_metadata(raw_metadata=mapping_suite_read_metadata(conceptual_mappings_file_path))

with open(output_metadata_file_path, 'w') as metadata_file:
metadata_file.write(metadata)
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ def validation_summary(cls, notices: List[Notice]) -> ValidationSummaryReport:
report: ValidationSummaryReport = ValidationSummaryReport(
object_data="ValidationSummaryReport"
)
report.notice_id = list(map(lambda notice: notice.ted_id, notices))

xml_manifestation_runner = XMLManifestationValidationSummaryRunner(notices)
report.xml_manifestation = xml_manifestation_runner.validation_summary()
Expand Down
5 changes: 2 additions & 3 deletions ted_sws/notice_validator/adapters/xpath_coverage_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,10 @@ class CoverageRunner:
base_xpath: str
mapping_suite_id: str

def __init__(self, mapping_suite_id: str, conceptual_mappings_file_path: PATH_TYPE = None, xslt_transformer=None,
def __init__(self, mapping_suite_id: str, conceptual_mappings_file_path: PATH_TYPE = None,
mongodb_client: MongoClient = None):
self.mapping_suite_id = mapping_suite_id
self.mongodb_client = mongodb_client
self.xslt_transformer = xslt_transformer

conceptual_mapping: ConceptualMapping
if self._db_readable():
Expand Down Expand Up @@ -124,7 +123,7 @@ def coverage_notice_xpath(self, notices: List[Notice], mapping_suite_id) -> XPAT
if self._db_readable():
xpaths = get_unique_xpaths_covered_by_notices([notice.ted_id], self.mongodb_client)
else:
notice = index_notice(notice, self.xslt_transformer)
notice = index_notice(notice)

if notice.xml_metadata and notice.xml_metadata.unique_xpaths:
xpaths = notice.xml_metadata.unique_xpaths
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,12 @@ def __init__(
self,
mapping_suite_id,
conceptual_mappings_file,
mappings_path,
xslt_transformer
mappings_path
):
super().__init__(name=CMD_NAME)
self.mapping_suite_id = mapping_suite_id
self.mappings_path = mappings_path
self.conceptual_mappings_file_path = Path(os.path.realpath(conceptual_mappings_file))
self.xslt_transformer = xslt_transformer
self.output_folder = OUTPUT_FOLDER.format(mappings_path=self.mappings_path,
mapping_suite_id=self.mapping_suite_id)

Expand Down Expand Up @@ -79,8 +77,7 @@ def coverage_report(self, notices: List[Notice], output_path: Path, label: str):
report = coverage_notice_xpath_report(notices,
self.mapping_suite_id,
self.conceptual_mappings_file_path,
self.coverage_runner,
self.xslt_transformer)
self.coverage_runner)
self.save_json_report(Path(str(output_path) + ".json"), xpath_coverage_json_report(report))
self.save_html_report(Path(str(output_path) + ".html"), xpath_coverage_html_report(report))

Expand All @@ -101,8 +98,7 @@ def run_cmd(self):
return self.run_cmd_result()


def run(mapping_suite_id=None, opt_conceptual_mappings_file=None, opt_mappings_folder=DEFAULT_MAPPINGS_PATH,
xslt_transformer=None):
def run(mapping_suite_id=None, opt_conceptual_mappings_file=None, opt_mappings_folder=DEFAULT_MAPPINGS_PATH):
if opt_conceptual_mappings_file:
conceptual_mappings_file = opt_conceptual_mappings_file
else:
Expand All @@ -114,8 +110,7 @@ def run(mapping_suite_id=None, opt_conceptual_mappings_file=None, opt_mappings_f
cmd = CmdRunner(
mapping_suite_id=mapping_suite_id,
conceptual_mappings_file=conceptual_mappings_file,
mappings_path=opt_mappings_folder,
xslt_transformer=xslt_transformer
mappings_path=opt_mappings_folder
)
cmd.run()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>HTML report for SPARQL Validation</title>
<link href="https://cdn.datatables.net/1.10.22/css/jquery.dataTables.min.css" rel="stylesheet" type="text/css">
<link rel="stylesheet" href="//code.jquery.com/ui/1.13.2/themes/base/jquery-ui.css">
<link rel="stylesheet" href="https://code.jquery.com/ui/1.13.2/themes/base/jquery-ui.css">
<style type="text/css">
body {
font-family: Arial, sans-serif;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,38 @@
table.display thead th {
padding-left: 10px;
}
[data-role=collapsible].collapsible-wrapper {
padding: 10px 0;
}
[data-role=collapsible] h4 {
margin: 0;
}
[data-role=collapsible] h4 a {
padding: 3px 10px;
background: #ccc;
width: 100%;
box-sizing: border-box;
display: block;
color: #111;
text-decoration: none;
margin: -3px 0;
}

[data-role=collapsible][data-state=collapsed] h4 a:before {
content: '+ expand';
}
[data-role=collapsible] h4 a:before {
content: '- collapse';
}
[data-role=collapsible][data-state=collapsed] .ui-collapsible-content {
visibility: hidden;
height: 0;
padding: 0 10px;;
}

[data-role=collapsible] .ui-collapsible-content {
padding: 10px;
}
</style>
</head>
<body>
Expand All @@ -32,6 +64,19 @@
<h2>Report details: </h2>
<ul>
<li>Date created: {{ created }}</li>
<li><div><hr></div>Notice identifier(s):
<div data-role="collapsible" data-state="{% if notice_id|length > 1 %}collapsed{% endif %}"
class="collapsible-wrapper">
<h4><a href="#"></a></h4>
<div class="ui-collapsible-content">
{% if notice_id|length == 1 %}
{{ notice_id[0] }}
{% else %}
{{ notice_id | tojson(indent=2) | replace('\n', '<br>') }}
{% endif %}
</div>
</div>
</li>
</ul>
<hr>
<h2>XML Manifestation</h2>
Expand Down Expand Up @@ -191,7 +236,7 @@
</table>
{% endfor %}
<p>-------</p>
<h3>SPARQL Summary</h3>
<h3>SHACL Summary</h3>
<h4>Result severity: </h4>
<ul>
<li>Info: {{ manifestation.shacl_summary.result_severity.aggregate.info }}</li>
Expand Down Expand Up @@ -246,6 +291,13 @@
<script type="text/javascript" src="https://cdn.datatables.net/buttons/1.6.4/js/buttons.print.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$("[data-role=collapsible] h4 a").on("click", function(e) {
$p = $(this).closest("[data-role=collapsible]");
$p.attr("data-state", $p.attr("data-state") == "collapsed" ? "expanded" : "collapsed");
$c = $p.find('.ui-collapsible-content');
$c.attr("data-state", $c.attr("data-state") == "collapsed" ? "expanded" : "collapsed");
return false;
});
$("table.display").DataTable({
dom: 'B<"clear">t',
buttons: [],
Expand Down
5 changes: 2 additions & 3 deletions ted_sws/notice_validator/services/xpath_coverage_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,10 @@ def generate_report(self) -> XPATHCoverageValidationReport:

def coverage_notice_xpath_report(notices: List[Notice], mapping_suite_id,
conceptual_mappings_file_path: PATH_TYPE = None,
coverage_runner: CoverageRunner = None, xslt_transformer=None,
coverage_runner: CoverageRunner = None,
mongodb_client: MongoClient = None) -> XPATHCoverageValidationReport:
if not coverage_runner:
coverage_runner = CoverageRunner(mapping_suite_id, conceptual_mappings_file_path, xslt_transformer,
mongodb_client)
coverage_runner = CoverageRunner(mapping_suite_id, conceptual_mappings_file_path, mongodb_client)
report: XPATHCoverageValidationReport = coverage_runner.coverage_notice_xpath(notices, mapping_suite_id)
return report

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def validate_and_update_daily_supra_notice(notice_publication_day: day_type, mon
repo.update(daily_supra_notice=supra_notice)


def validate_and_update_daily_supra_notice_manifestation(notice_publication_day: day_type, mongodb_client: MongoClient):
def summary_validation_for_daily_supra_notice(notice_publication_day: day_type, mongodb_client: MongoClient):
if isinstance(notice_publication_day, date):
notice_publication_day = datetime.combine(notice_publication_day, time())

Expand All @@ -61,4 +61,5 @@ def validate_and_update_daily_supra_notice_manifestation(notice_publication_day:
notices.append(notice)

supra_notice.validation_summary = generate_validation_summary_report_notices(notices)
supra_notice.validation_summary.notice_id = [] # no notice_ids needed to be stored for supra_notice
repo.update(daily_supra_notice=supra_notice)
7 changes: 6 additions & 1 deletion tests/e2e/data_sampler/test_unique_xpaths_from_xml.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from ted_sws.data_manager.adapters.notice_repository import NoticeRepository
from ted_sws.data_sampler.services.notice_selectors import get_notice_ids_by_form_number, \
get_notice_ids_by_eforms_subtype
from ted_sws.data_sampler.services.notice_xml_indexer import index_notice, index_notice_by_id, \
from ted_sws.data_sampler.services.notice_xml_indexer import index_notice, index_notice_xslt, index_notice_by_id, \
get_unique_xpaths_from_notice_repository, get_unique_notice_id_from_notice_repository, \
get_minimal_set_of_notices_for_coverage_xpaths, get_minimal_set_of_xpaths_for_coverage_notices, \
get_unique_notices_id_covered_by_xpaths, get_unique_xpaths_covered_by_notices, get_most_representative_notices
Expand All @@ -12,6 +12,11 @@ def test_index_notice(notice_2016):
assert len(result_notice.xml_metadata.unique_xpaths) == 112


def test_index_notice_xslt(notice_2016):
result_notice = index_notice_xslt(notice=notice_2016)
assert len(result_notice.xml_metadata.unique_xpaths) == 112


def test_index_notice_by_id(notice_2016, mongodb_client):
notice_repository = NoticeRepository(mongodb_client=mongodb_client)
notice_repository.add(notice=notice_2016)
Expand Down
12 changes: 0 additions & 12 deletions tests/fakes/fake_xslt_transformer.py

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -30,26 +30,22 @@ def post_process(fake_repository_path, fake_mapping_suite_id):
assert len(report_files) == 2


def test_cmd_xpath_coverage_runner(caplog, fake_mapping_suite_F03_id, fake_repository_path,
fake_xslt_transformer):
def test_cmd_xpath_coverage_runner(caplog, fake_mapping_suite_F03_id, fake_repository_path):
cli_run(
mapping_suite_id=fake_mapping_suite_F03_id,
opt_mappings_folder=fake_repository_path,
xslt_transformer=fake_xslt_transformer
opt_mappings_folder=fake_repository_path
)

assert "SUCCESS" in caplog.text

post_process(fake_repository_path, fake_mapping_suite_F03_id)


def test_cmd_xpath_coverage_runner_with_invalid_input(caplog, fake_repository_path, invalid_mapping_suite_id,
fake_xslt_transformer):
def test_cmd_xpath_coverage_runner_with_invalid_input(caplog, fake_repository_path, invalid_mapping_suite_id):
with pytest.raises(FileNotFoundError):
cli_run(
mapping_suite_id=invalid_mapping_suite_id,
opt_mappings_folder=fake_repository_path,
opt_conceptual_mappings_file="invalid",
xslt_transformer=fake_xslt_transformer
opt_conceptual_mappings_file="invalid"
)
assert "FAILED" in caplog.text
Loading