Aufgrund einer Störung des s3 Storage, könnten in nächster Zeit folgende GitLab Funktionen nicht zur Verfügung stehen: LFS, Container Registry, Job Artifacs, Uploads (Wiki, Bilder, Projekt-Exporte). Wir bitten um Verständnis. Es wird mit Hochdruck an der Behebung des Problems gearbeitet. Weitere Informationen zur Störung des Object Storage finden Sie hier: https://maintenance.itc.rwth-aachen.de/ticket/status/messages/59-object-storage-pilot

Commit 1350e6a7 authored by Torben Miny's avatar Torben Miny
Browse files

Merge branch feature/compliance_tool_aasx_extension with refs/heads/master...

Merge branch feature/compliance_tool_aasx_extension with refs/heads/master into refs/merge-requests/53/train
parents 59d2e36d 25c75158
Pipeline #354224 passed with stage
in 59 seconds
......@@ -125,10 +125,12 @@ The PyI40AAS project contains a compliance tool for testing xml and json files i
`aas.compliance_tool`-package. Following functionalities are supported:
* create an xml or json file compliant to the official schema containing example Asset Administration Shell elements
* create an aasx file with xml or json files compliant to the official schema containing example Asset Administration
Shell elements
* check if a given xml or json file is compliant to the official schema
* check if a given xml or json file is deserializable even if it is not compliant to the offical schema
* check if the data in a given xml or json file is the same as the example data
* check if two given xml or json file contain the same Asset Administration Shell elements in any order
* check if a given xml, json or aasx file is readable even if it is not compliant to the offical schema
* check if the data in a given xml, json or aasx file is the same as the example data
* check if two given xml, json or aasx files contain the same Asset Administration Shell elements in any order
Invoking should work with either `python -m aas.compliance_tool.cli` or (when installed correctly and PATH is set
correctly) with `aas_compliance_check` on the command line.
......
......@@ -15,14 +15,20 @@ Command line script which is a compliance tool for creating and checking json an
examples.data.__init__.py
"""
import argparse
import datetime
import logging
import pyecma376_2
from aas import model
from aas.adapter import aasx
from aas.adapter.xml import write_aas_xml_file
from aas.compliance_tool import compliance_check_json as compliance_tool_json
from aas.compliance_tool import compliance_check_xml as compliance_tool_xml
from aas.compliance_tool import compliance_check_aasx as compliance_tool_aasx
from aas.adapter.json import write_aas_json_file
from aas.examples.data import create_example
from aas.examples.data import create_example, create_example_aas_binding, TEST_PDF_FILE
from aas.compliance_tool.state_manager import ComplianceToolStateManager, Status
......@@ -32,11 +38,11 @@ def main():
description='Compliance tool for creating and checking json and xml files in compliance with "Details of the '
'Asset Administration Shell" specification of Plattform Industrie 4.0. \n\n'
'This tool has five features: \n'
'1. create an xml or json file with example aas elements\n'
'1. create a xml or json file or an AASX file using xml or json files with example aas elements\n'
'2. check a given xml or json file if it is compliant with the official json or xml aas schema\n'
'3. check if a given xml or json file is deserializable\n'
'4. check if the data in a given xml or json file is the same as the example data\n'
'5. check if two given xml or json files contain the same aas elements in any order\n\n'
'3. check if a given xml, json or aasx file is deserializable\n'
'4. check if the data in a given xml, json or aasx file is the same as the example data\n'
'5. check if two given xml, json or aasx files contain the same aas elements in any order\n\n'
'As a first argument, the feature must be specified (create, schema, deserialization, example, '
'files) or in short (c, s, d, e or f).\n'
'Depending the chosen feature, different additional arguments must be specified:\n'
......@@ -44,9 +50,11 @@ def main():
'schema or s: file to be checked (file_1)\n'
'deserialization or d: file to be checked (file_1)\n'
'example or e: file to be checked (file_1)\n'
'file_compare or f: files to compare (file_1, file_2)\n'
'file_compare or f: files to compare (file_1, file_2)\n,'
'In any case, it must be specified whether the (given or created) files are json (--json) or '
'xml (--xml).\n\n'
'xml (--xml).\n'
'All features except "schema" support reading/writing AASX packages instead of plain XML or JSON '
'files via the --aasx option.\n\n'
'Additionally, the tool offers some extra features for more convenient usage:\n'
'a. Different levels of verbosity:\n'
' Default output is just the status for each step performed. With -v or --verbose, additional '
......@@ -76,6 +84,7 @@ def main():
group.add_argument('--json', help="Use AAS json format when checking or creating files", action='store_true')
group.add_argument('--xml', help="Use AAS xml format when checking or creating files", action='store_true')
parser.add_argument('-l', '--logfile', help="Log file to be created in addition to output to stdout", default=None)
parser.add_argument('--aasx', help="Create or read AASX files", action='store_true')
args = parser.parse_args()
......@@ -88,11 +97,39 @@ def main():
if args.action == 'create' or args.action == 'c':
manager.add_step('Create example data')
data = create_example()
if args.aasx:
data = create_example_aas_binding()
else:
data = create_example()
manager.set_step_status(Status.SUCCESS)
try:
manager.add_step('Open file')
if args.json:
if args.aasx:
with aasx.AASXWriter(args.file_1) as writer:
manager.set_step_status(Status.SUCCESS)
manager.add_step('Write data to file')
files = aasx.DictSupplementaryFileContainer()
with open(TEST_PDF_FILE, 'rb') as f:
files.add_file("/TestFile.pdf", f, "application/pdf")
# Create OPC/AASX core properties
cp = pyecma376_2.OPCCoreProperties()
cp.created = datetime.datetime(2020, 1, 1, 0, 0, 0)
cp.creator = "PyI40AAS Testing Framework"
cp.description = "Test_Description"
cp.lastModifiedBy = "PyI40AAS Testing Framework Compliance Tool"
cp.modified = datetime.datetime(2020, 1, 1, 0, 0, 1)
cp.revision = "1.0"
cp.version = "2.0.1"
cp.title = "Test Title"
writer.write_aas_objects("/aasx/data.json" if args.json else "/aasx/data.xml",
[obj.identification for obj in data], data, files,
write_json=args.json)
writer.write_core_properties(cp)
manager.set_step_status(Status.SUCCESS)
elif args.json:
with open(args.file_1, 'w', encoding='utf-8-sig') as file:
manager.set_step_status(Status.SUCCESS)
manager.add_step('Write data to file')
......@@ -113,18 +150,24 @@ def main():
if args.xml:
compliance_tool_xml.check_schema(args.file_1, manager)
elif args.action == 'deserialization' or args.action == 'd':
if args.json:
if args.aasx:
compliance_tool_aasx.check_deserialization(args.file_1, manager)
elif args.json:
compliance_tool_json.check_deserialization(args.file_1, manager)
elif args.xml:
compliance_tool_xml.check_deserialization(args.file_1, manager)
elif args.action == 'example' or args.action == 'e':
if args.json:
if args.aasx:
compliance_tool_aasx.check_aas_example(args.file_1, manager)
elif args.json:
compliance_tool_json.check_aas_example(args.file_1, manager)
elif args.xml:
compliance_tool_xml.check_aas_example(args.file_1, manager)
elif args.action == 'files' or args.action == 'f':
if args.file_2:
if args.json:
if args.aasx:
compliance_tool_aasx.check_aasx_files_equivalence(args.file_1, args.file_2, manager)
elif args.json:
compliance_tool_json.check_json_files_equivalence(args.file_1, args.file_2, manager)
elif args.xml:
compliance_tool_xml.check_xml_files_equivalence(args.file_1, args.file_2, manager)
......
# Copyright 2020 PyI40AAS Contributors
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
"""
Module which offers functions to use in a confirmation tool related to AASX files
check_deserialization: Checks if a AASX file can be deserialized
check_aas_example: Checks if a AASX file consist the data of the example data defined in
aas.examples.data.example_aas.py
check_aasx_files_equivalence: Checks if two AASX files have the same data regardless of their order
All functions reports any issues using the given StateManager by adding new steps and associated LogRecords
"""
import datetime
import json
import logging
from typing import Optional, Tuple
import pyecma376_2
from .. import model
from ..adapter import aasx
from ..examples.data import example_aas, create_example_aas_binding
from ..examples.data._helper import AASDataChecker, DataChecker
from .state_manager import ComplianceToolStateManager, Status
def check_deserialization(file_path: str, state_manager: ComplianceToolStateManager,
file_info: Optional[str] = None) \
-> Tuple[model.DictObjectStore, aasx.DictSupplementaryFileContainer, pyecma376_2.OPCCoreProperties]:
"""
Read a AASX file and reports any issues using the given StateManager
add the steps: 'Open {} file' and 'Read {} file'
:param file_path: given file which should be deserialized
:param state_manager: manager to log the steps
:param file_info: additional information about the file for name of the steps
:return: returns the read object store
"""
logger = logging.getLogger('compliance_check')
logger.addHandler(state_manager)
logger.propagate = False
logger.setLevel(logging.INFO)
# create handler to get logger info
logger_deserialization = logging.getLogger(aasx.__name__)
logger_deserialization.addHandler(state_manager)
logger_deserialization.propagate = False
logger_deserialization.setLevel(logging.INFO)
if file_info:
state_manager.add_step('Open {} file'.format(file_info))
else:
state_manager.add_step('Open file')
try:
# open given file
reader = aasx.AASXReader(file_path)
state_manager.set_step_status_from_log()
except ValueError as error:
logger.error(error)
state_manager.set_step_status_from_log()
state_manager.add_step('Read file')
state_manager.set_step_status(Status.NOT_EXECUTED)
return model.DictObjectStore(), aasx.DictSupplementaryFileContainer(), pyecma376_2.OPCCoreProperties()
try:
# read given file
state_manager.add_step('Read file')
obj_store: model.DictObjectStore[model.Identifiable] = model.DictObjectStore()
files = aasx.DictSupplementaryFileContainer()
reader.read_into(obj_store, files)
new_cp = reader.get_core_properties()
state_manager.set_step_status(Status.SUCCESS)
except ValueError as error:
logger.error(error)
state_manager.set_step_status(Status.FAILED)
return model.DictObjectStore(), aasx.DictSupplementaryFileContainer(), pyecma376_2.OPCCoreProperties()
finally:
reader.close()
return obj_store, files, new_cp
def check_aas_example(file_path: str, state_manager: ComplianceToolStateManager) -> None:
"""
Checks if a file contains all elements of the aas example and reports any issues using the given StateManager
calls the check_deserialization and add the steps: 'Check if data is equal to example data'
:param file_path: given file which should be checked
:param state_manager: manager to log the steps
"""
logger = logging.getLogger('compliance_check')
logger.addHandler(state_manager)
logger.propagate = False
logger.setLevel(logging.INFO)
# create handler to get logger info
logger_example = logging.getLogger(example_aas.__name__)
logger_example.addHandler(state_manager)
logger_example.propagate = False
logger_example.setLevel(logging.INFO)
obj_store, files, cp_new = check_deserialization(file_path, state_manager)
if state_manager.status in (Status.FAILED, Status.NOT_EXECUTED):
state_manager.add_step('Check if data is equal to example data')
state_manager.set_step_status(Status.NOT_EXECUTED)
state_manager.add_step('Check if core properties are equal')
state_manager.set_step_status(Status.NOT_EXECUTED)
return
checker = AASDataChecker(raise_immediately=False)
state_manager.add_step('Check if data is equal to example data')
example_data = create_example_aas_binding()
checker.check_object_store(obj_store, example_data)
state_manager.add_log_records_from_data_checker(checker)
if state_manager.status in (Status.FAILED, Status.NOT_EXECUTED):
state_manager.add_step('Check if core properties are equal')
state_manager.set_step_status(Status.NOT_EXECUTED)
return
state_manager.add_step('Check if core properties are equal')
# Create OPC/AASX core properties
cp = pyecma376_2.OPCCoreProperties()
cp.created = datetime.datetime(2020, 1, 1, 0, 0, 0)
cp.creator = "PyI40AAS Testing Framework"
cp.description = "Test_Description"
cp.lastModifiedBy = "PyI40AAS Testing Framework Compliance Tool"
cp.modified = datetime.datetime(2020, 1, 1, 0, 0, 1)
cp.revision = "1.0"
cp.version = "2.0.1"
cp.title = "Test Title"
checker2 = DataChecker(raise_immediately=False)
assert (isinstance(cp_new.created, datetime.datetime))
duration = cp_new.created - cp.created
checker2.check(duration.microseconds < 20, "created must be {}".format(cp.created), created=cp_new.created)
checker2.check(cp_new.creator == cp.creator, "creator must be {}".format(cp.creator), creator=cp_new.creator)
checker2.check(cp_new.description == cp.description, "description must be {}".format(cp.description),
description=cp_new.description)
checker2.check(cp_new.lastModifiedBy == cp.lastModifiedBy, "lastModifiedBy must be {}".format(cp.lastModifiedBy),
lastModifiedBy=cp_new.lastModifiedBy)
assert (isinstance(cp_new.modified, datetime.datetime))
duration = cp_new.modified - cp.modified
checker2.check(duration.microseconds < 20, "modified must be {}".format(cp.modified), modified=cp_new.modified)
checker2.check(cp_new.revision == cp.revision, "revision must be {}".format(cp.revision), revision=cp_new.revision)
checker2.check(cp_new.version == cp.version, "version must be {}".format(cp.version), version=cp_new.version)
checker2.check(cp_new.title == cp.title, "title must be {}".format(cp.title), title=cp_new.title)
# Check if file in file object is the same
list_of_id_shorts = ["ExampleSubmodelCollectionUnordered", "ExampleFile"]
obj = example_data.get_identifiable(model.Identifier("https://acplt.org/Test_Submodel", model.IdentifierType.IRI))
for id_short in list_of_id_shorts:
obj = obj.get_referable(id_short)
obj2 = obj_store.get_identifiable(model.Identifier("https://acplt.org/Test_Submodel", model.IdentifierType.IRI))
for id_short in list_of_id_shorts:
obj2 = obj2.get_referable(id_short)
try:
sha_file = files.get_sha256(obj.value)
except KeyError as error:
state_manager.add_log_records_from_data_checker(checker2)
logger.error(error)
state_manager.set_step_status(Status.FAILED)
return
checker2.check(sha_file == files.get_sha256(obj2.value), "File of {} must be {}.".format(obj.value, obj2.value),
value=obj2.value)
state_manager.add_log_records_from_data_checker(checker2)
if state_manager.status in (Status.FAILED, Status.NOT_EXECUTED):
state_manager.set_step_status(Status.FAILED)
else:
state_manager.set_step_status(Status.SUCCESS)
def check_aasx_files_equivalence(file_path_1: str, file_path_2: str, state_manager: ComplianceToolStateManager) -> None:
"""
Checks if two aasx files contain the same elements in any order and reports any issues using the given StateManager
calls the check_deserialization for ech file and add the steps: 'Check if data in files are equal'
:param file_path_1: given first file which should be checked
:param file_path_2: given second file which should be checked
:param state_manager: manager to log the steps
"""
logger = logging.getLogger('compliance_check')
logger.addHandler(state_manager)
logger.propagate = False
logger.setLevel(logging.INFO)
obj_store_1, files_1, cp_1 = check_deserialization(file_path_1, state_manager, 'first')
obj_store_2, files_2, cp_2 = check_deserialization(file_path_2, state_manager, 'second')
if state_manager.status is Status.FAILED:
state_manager.add_step('Check if data in files are equal')
state_manager.set_step_status(Status.NOT_EXECUTED)
state_manager.add_step('Check if core properties are equal')
state_manager.set_step_status(Status.NOT_EXECUTED)
return
checker = AASDataChecker(raise_immediately=False)
try:
state_manager.add_step('Check if data in files are equal')
checker.check_object_store(obj_store_1, obj_store_2)
except (KeyError, AssertionError) as error:
state_manager.set_step_status(Status.FAILED)
logger.error(error)
state_manager.add_step('Check if core properties are equal')
state_manager.set_step_status(Status.NOT_EXECUTED)
return
state_manager.add_log_records_from_data_checker(checker)
if state_manager.status is Status.FAILED:
state_manager.add_step('Check if core properties are equal')
state_manager.set_step_status(Status.NOT_EXECUTED)
return
state_manager.add_step('Check if core properties are equal')
checker2 = DataChecker(raise_immediately=False)
assert (isinstance(cp_1.created, datetime.datetime))
assert (isinstance(cp_2.created, datetime.datetime))
duration = cp_1.created - cp_2.created
checker2.check(duration.microseconds < 20, "created must be {}".format(cp_1.created), value=cp_2.created)
checker2.check(cp_1.creator == cp_2.creator, "creator must be {}".format(cp_1.creator), value=cp_2.creator)
checker2.check(cp_1.lastModifiedBy == cp_2.lastModifiedBy, "lastModifiedBy must be {}".format(cp_1.lastModifiedBy),
value=cp_2.lastModifiedBy)
state_manager.add_log_records_from_data_checker(checker2)
......@@ -20,14 +20,18 @@ example_submodel_template.py
Module for the creation of an example submodel template containing all kind of submodel elements where the kind is
always TEMPLATE.
"""
import os
from aas import model
from aas.examples.data import example_aas, example_aas_mandatory_attributes, example_aas_missing_attributes, \
example_submodel_template, example_concept_description
TEST_PDF_FILE = os.path.join(os.path.dirname(__file__), 'TestFile.pdf')
def create_example() -> model.DictObjectStore:
"""
creates an object store which is filled with a example assets, submodels, concept descriptions and asset
creates an object store which is filled with example assets, submodels, concept descriptions and asset
administration shells using the functionality of this package
:return: object store
......@@ -39,3 +43,38 @@ def create_example() -> model.DictObjectStore:
obj_store.add(example_submodel_template.create_example_submodel_template())
obj_store.add(example_concept_description.create_iec61360_concept_description())
return obj_store
def create_example_aas_binding() -> model.DictObjectStore:
"""
creates an object store which is filled with example assets, submodels, concept descriptions and asset
administration shells using the functionality of this package where each asset, submodel and concept description is
at least referred by one asset administration shell
:return: object store
"""
obj_store: model.DictObjectStore[model.Identifiable] = model.DictObjectStore()
obj_store.update(example_aas.create_full_example())
obj_store.update(example_aas_mandatory_attributes.create_full_example())
obj_store.update(example_aas_missing_attributes.create_full_example())
obj_store.add(example_submodel_template.create_example_submodel_template())
aas = obj_store.get_identifiable(model.Identifier('https://acplt.org/Test_AssetAdministrationShell',
model.IdentifierType.IRI))
sm = obj_store.get_identifiable(model.Identifier('https://acplt.org/Test_Submodel_Template',
model.IdentifierType.IRI))
assert (isinstance(aas, model.aas.AssetAdministrationShell)) # make mypy happy
assert (isinstance(sm, model.submodel.Submodel)) # make mypy happy
aas.submodel.add(model.AASReference.from_referable(sm))
obj_store.add(example_concept_description.create_iec61360_concept_description())
cd = obj_store.get_identifiable(model.Identifier('http://acplt.org/DataSpecifciations/Example/Identification',
model.IdentifierType.IRI))
assert (isinstance(cd, model.concept.IEC61360ConceptDescription)) # make mypy happy
cdict = aas.concept_dictionary.get_referable("TestConceptDictionary")
cdict.concept_description.add(model.AASReference.from_referable(cd))
cd2 = obj_store.get_identifiable(model.Identifier('https://acplt.org/Test_ConceptDescription_Mandatory',
model.IdentifierType.IRI))
assert (isinstance(cd2, model.concept.ConceptDescription)) # make mypy happy
cdict.concept_description.add(model.AASReference.from_referable(cd2))
return obj_store
......@@ -30,6 +30,7 @@ setuptools.setup(
"aas": ["py.typed"],
"aas.adapter.json": ["aasJSONSchema.json"],
"aas.adapter.xml": ["AAS.xsd", "AAS_ABAC.xsd", "IEC61360.xsd"],
"aas.examples.data": ["TestFile.pdf"],
},
classifiers=[
"Programming Language :: Python :: 3",
......
{
{
"assetAdministrationShells": [
{
"idShort": "TestAssetAdministrationShell",
......@@ -3003,4 +3003,4 @@
]
}
]
}
\ No newline at end of file
}
{
{
"assetAdministrationShells": [
{
"idShort": "TestAssetAdministrationShell123",
......@@ -3003,4 +3003,4 @@
]
}
]
}
\ No newline at end of file
}
......@@ -1784,4 +1784,4 @@
</aas:isCaseOf>
</aas:conceptDescription>
</aas:conceptDescriptions>
</aas:aasenv>
</aas:aasenv>
\ No newline at end of file
......@@ -8,17 +8,24 @@
# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
import datetime
import hashlib
import os
import subprocess
import sys
import unittest
import io
import pyecma376_2
import aas.compliance_tool
import tempfile
from aas import model
from aas.adapter import aasx
from aas.adapter.json import read_aas_json_file, JSON_SCHEMA_FILE
from aas.adapter.xml import read_aas_xml_file, XML_SCHEMA_FILE
from aas.examples.data import create_example
from aas.examples.data import create_example, create_example_aas_binding
from aas.examples.data._helper import AASDataChecker
......@@ -50,6 +57,12 @@ class ComplianceToolTest(unittest.TestCase):
self.assertNotEqual(0, output.returncode)
self.assertIn('error: one of the arguments --json --xml is required', str(output.stderr))
output = subprocess.run(
[sys.executable, file_path, "d", os.path.join(test_file_path, "test_demo_full_example.json"), "--aasx"],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
self.assertNotEqual(0, output.returncode)
self.assertIn('error: one of the arguments --json --xml is required', str(output.stderr))
# test example check
output = subprocess.run([sys.executable, file_path, "e"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
self.assertNotEqual(0, output.returncode)
......@@ -61,6 +74,12 @@ class ComplianceToolTest(unittest.TestCase):
self.assertNotEqual(0, output.returncode)
self.assertIn('error: one of the arguments --json --xml is required', str(output.stderr))
output = subprocess.run(
[sys.executable, file_path, "e", os.path.join(test_file_path, "test_demo_full_example.json"), "--aasx"],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
self.assertNotEqual(0, output.returncode)
self.assertIn('error: one of the arguments --json --xml is required', str(output.stderr))
# test file check
output = subprocess.run([sys.executable, file_path, "f"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
self.assertNotEqual(0, output.returncode)
......@@ -72,6 +91,12 @@ class ComplianceToolTest(unittest.TestCase):
self.assertNotEqual(0, output.returncode)
self.assertIn('error: one of the arguments --json --xml is required', str(output.stderr))
output = subprocess.run(
[sys.executable, file_path, "f", os.path.join(test_file_path, "test_demo_full_example.json"), "--aasx"],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
self.assertNotEqual(0, output.returncode)
self.assertIn('error: one of the arguments --json --xml is required', str(output.stderr))
output = subprocess.run(
[sys.executable, file_path, "f", os.path.join(test_file_path, "test_demo_full_example.json"), "--json"],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
......@@ -128,6 +153,8 @@ class ComplianceToolTest(unittest.TestCase):
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
self.assertEqual(0, output.returncode)
self.assertIn('SUCCESS: Open file', str(output.stdout))
self.assertIn('SUCCESS: Read file and check if it is conform to the json syntax', str(output.stdout))
self.assertIn('SUCCESS: Validate file against official json schema', str(output.stdout))
def test_json_create_example(self) -> None:
file_path = os.path.join(os.path.dirname(aas.compliance_tool.__file__), 'cli.py')
......@@ -157,6 +184,7 @@ class ComplianceToolTest(unittest.TestCase):
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
self.assertEqual(0, output.returncode)
self.assertIn('SUCCESS: Open file', str(output.stdout))
self.assertIn('SUCCESS: Read file and check if it is deserializable', str(output.stdout))
def test_json_example(self) -> None:
file_path = os.path.join(os.path.dirname(aas.compliance_tool.__file__), 'cli.py')
......@@ -167,6 +195,8 @@ class ComplianceToolTest(unittest.TestCase):
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
self.assertEqual(0, output.returncode)
self.assertIn('SUCCESS: Open file', str(output.stdout))