Skip to content

Commit

Permalink
Fix aasx path names on windows (fixes #35)
Browse files Browse the repository at this point in the history
  • Loading branch information
otto-ifak committed Aug 17, 2024
1 parent c1c5f27 commit 4135a2a
Show file tree
Hide file tree
Showing 8 changed files with 209 additions and 5 deletions.
37 changes: 36 additions & 1 deletion aas_test_engines/_util.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Dict, List
from typing import Dict, List, Tuple
import base64


Expand Down Expand Up @@ -60,3 +60,38 @@ def un_group(data: any) -> any:

def b64urlsafe(value: str) -> str:
return base64.urlsafe_b64encode(value.encode()).decode()


def normpath(path: str) -> str:
"""
Normalizes a given path.
E.g. normpath('///a/../b/)') == '/b'
This implementation is platform independent and behaves like os.normpath on a unix system.
See https://docs.python.org/3/library/os.path.html#os.path.normpath for more details.
"""
path = path.strip()
if len(path) == 0:
return ''
result = []
for token in path.split("/"):
if token.strip() == '' or token == '.':
continue
if token == '..':
if result:
result.pop()
else:
result.append(token)
if path.startswith('/'):
return "/" + "/".join(result)
else:
return "/".join(result)


def splitpath(path: str) -> Tuple[str, str]:
"""
Splits a path into a pair (head, tail)
This implementation is platform independent and behaves like os.path.split on a unix system.
See https://docs.python.org/3/library/os.path.html#os.path.split for more details.
"""
prefix, _, suffix = path.rpartition('/')
return prefix, suffix
6 changes: 3 additions & 3 deletions aas_test_engines/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from json_schema_tool.exception import PreprocessorException, PostProcessorException
import zipfile

from ._util import un_group
from ._util import un_group, normpath, splitpath

JSON = Union[str, int, float, bool, None, Dict[str, Any], List[Any]]

Expand Down Expand Up @@ -451,9 +451,9 @@ def _scan_relationships(zipfile: zipfile.ZipFile, parent_rel: Relationship, dir:
target = target[1:]
else:
target = dir + target
target = os.path.normpath(target)
target = normpath(target)

sub_dir, file = os.path.split(target)
sub_dir, file = splitpath(target)
sub_rel = Relationship(type, target)
result.append(AasTestResult(f'Relationship {sub_rel.target} is of type {sub_rel.type}', str(idx), Level.INFO))
parent_rel.sub_rels.append(sub_rel)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
<Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml" />
<Default Extension="xml" ContentType="text/xml" />
<Default Extension="jpeg" ContentType="image/jpeg" />
<Default Extension="png" ContentType="image/png" />
<Default Extension="pdf" ContentType="application/pdf" />
<Default Extension="jpg" ContentType="image/jpeg" />
<Default Extension="zip" ContentType="text/plain" />
<Override PartName="/aasx/aasx-origin" ContentType="text/plain" />
</Types>
4 changes: 4 additions & 0 deletions test/fixtures/aasx/invalid/rel_target_not_exists/_rels/.rels
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
<Relationship Type="http://admin-shell.io/aasx/relationships/aasx-origin" Target="/aasx/aasx-origin"/>
</Relationships>
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
<Relationship Type="http://admin-shell.io/aasx/relationships/aas-spec" Target="/aasx/the_aas.json" />
</Relationships>
96 changes: 96 additions & 0 deletions test/fixtures/aasx/invalid/rel_target_not_exists/aasx/the_aas.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
{
"submodels": [
{
"id": "something_48c66017",
"modelType": "Submodel",
"submodelElements": [
{
"category": "VARIABLE",
"description": [
{
"language": "en",
"text": "something_be9deae0"
}
],
"displayName": [
{
"language": "Tvwqa-500-8EQd-y-8f5-k-vqdMn7-Ohw9-CcA628-DHKP-hPAjUZ-cnr1REUf-S8-p-9X0r-wtCI-KunG3uzI-7dGUsrTu-fY7-C3-hFN-Y-ML69DgnJ-0-Y0H-TLACBVB-Z0HRibbz-yzSf8dvR-zAn-B-6h8VjcKX-jnwR-0Z8l-ghRIZ7mo-wZG7-zXHdSIV-Oy-8dH00A6L-nJY2dA1-57o8dQ-RpxkBTbE-qBJR-M-DyGDA3U-aguRfIhj-x-XmO-1u",
"text": "something_535aeb51"
}
],
"embeddedDataSpecifications": [
{
"dataSpecification": {
"keys": [
{
"type": "Submodel",
"value": "urn:another-company15:2bd0986b"
}
],
"type": "ModelReference"
},
"dataSpecificationContent": {
"modelType": "DataSpecificationIec61360",
"preferredName": [
{
"language": "X-33DQI-g",
"text": "something_7e795ee2"
},
{
"language": "en-UK",
"text": "Something random in English c8512bdf"
}
],
"value": "something_4e9c19b7"
}
}
],
"extensions": [
{
"name": "something_aa1af8b3"
}
],
"idShort": "PiXO1wyHierj",
"modelType": "Property",
"qualifiers": [
{
"type": "something_500f973e",
"valueType": "xs:long"
}
],
"semanticId": {
"keys": [
{
"type": "GlobalReference",
"value": "urn:something00:f4547d0c"
}
],
"type": "ExternalReference"
},
"supplementalSemanticIds": [
{
"keys": [
{
"type": "Submodel",
"value": "urn:another-example10:42487f5a"
}
],
"type": "ModelReference"
}
],
"value": "0061707",
"valueId": {
"keys": [
{
"type": "Submodel",
"value": "urn:some-company12:e40857e0"
}
],
"type": "ModelReference"
},
"valueType": "xs:decimal"
}
]
}
]
}
7 changes: 7 additions & 0 deletions test/test_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,13 @@ def test_unknown_filetype(self):
result.dump()
self.assertEqual(result.level, Level.WARNING)

def test_rel_target_not_exists(self):
z = in_memory_zipfile(os.path.join(script_dir, 'fixtures/aasx/invalid/rel_target_not_exists'))
result = file.check_aasx_data(z)
result.dump()
self.assertEqual(result.level, Level.ERROR)
self.assertTrue(any("Relationship has non-existing target aasx/aasx-origin" in i for i in result.to_lines()))

def test_no_aas(self):
z = in_memory_zipfile(os.path.join(script_dir, 'fixtures/aasx/valid/no_aas1'))
result = file.check_aasx_data(z)
Expand Down
49 changes: 48 additions & 1 deletion test/test_util.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from unittest import TestCase
from aas_test_engines._util import group, un_group
from aas_test_engines._util import group, un_group, normpath, splitpath


class GroupSmcTest(TestCase):
Expand Down Expand Up @@ -75,3 +75,50 @@ def test_nested(self):
]
}
result = group(input)


class NormPathTest(TestCase):

def test_empty(self):
self.assertEqual(normpath(''), '')
self.assertEqual(normpath(' '), '')

def test_double_slashes(self):
self.assertEqual(normpath('//a//b//c'), '/a/b/c')
self.assertEqual(normpath('//'), '/')

def test_dot(self):
self.assertEqual(normpath('.'), '')
self.assertEqual(normpath('a/./b/./c'), 'a/b/c')
self.assertEqual(normpath('a/b/.'), 'a/b')

def test_trailing_slashes(self):
self.assertEqual(normpath('/abc/def/'), '/abc/def')
self.assertEqual(normpath('abc/def// //'), 'abc/def')

def test_double_dot(self):
self.assertEqual(normpath('foo/../bar'), 'bar')
self.assertEqual(normpath('/foo/../bar///'), '/bar')
self.assertEqual(normpath('a/b/../c'), 'a/c')
self.assertEqual(normpath('a/b/../c/..'), 'a')
self.assertEqual(normpath('/a/b/../c/..'), '/a')

def test_illegal_double_dot(self):
self.assertEqual(normpath('..'), '')
self.assertEqual(normpath('/..'), '/')
self.assertEqual(normpath('../x'), 'x')
self.assertEqual(normpath('/../x'), '/x')


class SplitPathTest(TestCase):

def test_empty(self):
self.assertEqual(splitpath(''), ('', ''))

def test_ends_with_slash(self):
self.assertEqual(splitpath('a/b.txt/'), ('a/b.txt', ''))
self.assertEqual(splitpath('/'), ('', ''))
self.assertEqual(splitpath('/a/b/'), ('/a/b', ''))

def test_no_slash(self):
self.assertEqual(splitpath('foo.txt'), ('', 'foo.txt'))

0 comments on commit 4135a2a

Please sign in to comment.