Skip to content

Commit e5b9218

Browse files
committed
Merge branch 'Auth'
1 parent 9ad2512 commit e5b9218

File tree

8 files changed

+93
-43
lines changed

8 files changed

+93
-43
lines changed

README.md

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,18 @@ You may prefer the HTML output for better readability by running:
119119
```sh
120120
aas_test_engines check_server http://my-server.com/api/v3.0 https://admin-shell.io/aas/API/3/0/AssetAdministrationShellRepositoryServiceSpecification/SSP-002 --output html > result.html
121121
```
122-
122+
123+
### Handling Authorization
124+
In case your server applies some authorization mechanism for security, you need to pass credentials to the Test Engines.
125+
You can use the `--header` option to do so by providing credentials within header fields:
126+
127+
<!-- no-check -->
128+
```sh
129+
aas_test_engines check_server http://my-server.com/api/v3.0 https://admin-shell.io/aas/API/3/0/AssetAdministrationShellRepositoryServiceSpecification/SSP-002 --header 'Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l'
130+
```
131+
132+
If you need a more sophisticated authorization mechanism, you should use the Python module interface and provide your own `aas_test_engines.http.HttpClient` class.
133+
123134
## Python Module Interface
124135
<a name="python-interface"></a>
125136

@@ -199,23 +210,30 @@ result.dump()
199210
Check a running server instance:
200211

201212
```python
202-
from aas_test_engines import api
213+
from aas_test_engines import api, config, http
214+
215+
client = http.HttpClient(
216+
host="http://localhost",
217+
)
218+
conf = config.CheckApiConfig(
219+
suite="https://admin-shell.io/aas/API/3/0/AssetAdministrationShellRepositoryServiceSpecification/SSP-002",
220+
)
203221

204-
conf = api.ExecConf(server="http://localhost")
205-
result, mat = api.execute_tests(conf, "https://admin-shell.io/aas/API/3/0/AssetAdministrationShellRepositoryServiceSpecification/SSP-002")
222+
result, mat = api.execute_tests(client, conf)
206223
result.dump()
207224
```
208225

209-
Checking older versions:
226+
To check older versions pass `version` to the `ApiConfig`:
210227

211228
```python
212-
from aas_test_engines import api
229+
from aas_test_engines import api, config
213230
print(api.supported_versions())
214231
print(api.latest_version())
215232

216-
conf = api.ExecConf(server="http://localhost")
217-
result, mat = api.execute_tests(conf, "https://admin-shell.io/aas/API/3/0/AssetAdministrationShellRepositoryServiceSpecification/SSP-002", "3.0")
218-
result.dump()
233+
conf = config.CheckApiConfig(
234+
suite="https://admin-shell.io/aas/API/3/0/AssetAdministrationShellRepositoryServiceSpecification/SSP-002",
235+
version='3.0'
236+
)
219237
```
220238

221239
### Generating test data for software testing

aas_test_engines/__main__.py

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
import sys
33
import os
44
import json
5-
from aas_test_engines import api, file
5+
from aas_test_engines import api, config, file, http
66
from enum import Enum
7+
from typing import Tuple
78

89
# https://stackoverflow.com/questions/27981545
910
import urllib3
@@ -26,6 +27,14 @@ class OutputFormats(Enum):
2627
HTML = "html"
2728

2829

30+
def _parse_header_value(s: str) -> Tuple[str, str]:
31+
try:
32+
key, value = s.split(":", 1)
33+
return key.strip(), value.strip()
34+
except ValueError:
35+
raise argparse.ArgumentTypeError(f"Invalid format for header:value: '{s}'")
36+
37+
2938
def run_file_test(argv):
3039
parser = argparse.ArgumentParser(description="Checks a file for compliance with the AAS meta-model")
3140
parser.add_argument("file", type=argparse.FileType("rb"), help="the file to check")
@@ -66,6 +75,13 @@ def run_api_test(argv):
6675
parser = argparse.ArgumentParser(description="Checks a server instance for compliance with the AAS api")
6776
parser.add_argument("server", type=str, help="server to run the tests against")
6877
parser.add_argument("suite", type=str, help="test suite (or substring of it)")
78+
parser.add_argument(
79+
"--header",
80+
nargs="+",
81+
default=[],
82+
type=_parse_header_value,
83+
help="Additional headers in the format header:value",
84+
)
6985
parser.add_argument("--dry", action="store_true", help="dry run, do not send requests")
7086
parser.add_argument("--version", type=str, default=api.latest_version())
7187
parser.add_argument("--no-verify", action="store_true", help="do not check TLS certificate")
@@ -100,13 +116,19 @@ def run_api_test(argv):
100116
else:
101117
suite = suites[0]
102118

103-
exec_conf = api.ExecConf(
104-
server=args.server,
105-
dry=args.dry,
119+
client = http.HttpClient(
120+
host=args.server,
106121
verify=not args.no_verify,
107122
remove_path_prefix=args.remove_path_prefix,
123+
additional_headers=dict(args.header),
124+
)
125+
conf = config.CheckApiConfig(
126+
suite=suite,
127+
version=args.version,
128+
dry=args.dry,
108129
)
109-
result, mat = api.execute_tests(exec_conf, suite, args.version)
130+
131+
result, mat = api.execute_tests(client, conf)
110132
if args.output == OutputFormats.TEXT:
111133
result.dump()
112134
elif args.output == OutputFormats.HTML:

aas_test_engines/api.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
from typing import Dict, List, Tuple
2-
from aas_test_engines.test_cases.v3_0.api import ExecConf
32
from aas_test_engines.test_cases.v3_0 import api as v3_0
43
from fences.core.util import ConfusionMatrix
54
from .result import AasTestResult
65
from .exception import AasTestToolsException
6+
from .config import CheckApiConfig
7+
from .http import HttpClient
78

89
_DEFAULT_VERSION = "3.0"
910

@@ -16,7 +17,8 @@ def latest_version():
1617
return _DEFAULT_VERSION
1718

1819

19-
def execute_tests(conf: ExecConf, suite: str, version: str = _DEFAULT_VERSION) -> Tuple[AasTestResult, ConfusionMatrix]:
20+
def execute_tests(client: HttpClient, conf: CheckApiConfig) -> Tuple[AasTestResult, ConfusionMatrix]:
21+
version = conf.version or _DEFAULT_VERSION
2022
if version != _DEFAULT_VERSION:
2123
raise AasTestToolsException(f"Unknown version {version}, must be one of {supported_versions()}")
22-
return v3_0.execute_tests(conf, suite)
24+
return v3_0.execute_tests(client, conf)

aas_test_engines/config.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from typing import Optional
2+
from dataclasses import dataclass
3+
4+
5+
@dataclass
6+
class CheckApiConfig:
7+
suite: str
8+
version: Optional[str] = None
9+
dry: bool = False

aas_test_engines/http.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Tuple, Optional, List
1+
from typing import Tuple, Optional, List, Dict
22
import requests
33
from requests.models import Response
44
from dataclasses import dataclass, field
@@ -35,14 +35,17 @@ def dump(self, body_max_chars=80):
3535

3636
class HttpClient:
3737

38-
def __init__(self, host: str, verify: bool, remove_path_prefix: str):
38+
def __init__(
39+
self, host: str, verify: bool = False, remove_path_prefix: str = "", additional_headers: Dict[str, str] = {}
40+
):
3941
self.host = host
4042
self.verify = verify
4143
self.remove_path_prefix = remove_path_prefix
4244
self.prefixes: List[str] = []
45+
self.additional_headers = additional_headers
4346

4447
def descend(self, prefix: str):
45-
result = HttpClient(self.host, self.verify, self.remove_path_prefix)
48+
result = HttpClient(self.host, self.verify, self.remove_path_prefix, self.additional_headers)
4649
result.prefixes.append(prefix)
4750
return result
4851

aas_test_engines/test_cases/v3_0/api.py

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from aas_test_engines.reflect import reflect_function
66
from aas_test_engines.result import write, start, abort, Level, AasTestResult
77
from aas_test_engines.http import HttpClient, Request
8+
from aas_test_engines.config import CheckApiConfig
89
import requests
910
from .interfaces import (
1011
aas,
@@ -18,14 +19,6 @@
1819
from .generate import generate_calls
1920

2021

21-
@dataclass
22-
class ExecConf:
23-
server: str
24-
dry: bool = False
25-
verify: bool = True
26-
remove_path_prefix: str = ""
27-
28-
2922
SSP_PREFIX = "https://admin-shell.io/aas/API/3/0/"
3023

3124

@@ -224,17 +217,16 @@ def _execute(suite: ApiTestSuite) -> ConfusionMatrix:
224217
return mat
225218

226219

227-
def execute_tests(conf: ExecConf, suite: str) -> Tuple[AasTestResult, ConfusionMatrix]:
220+
def execute_tests(client: HttpClient, conf: CheckApiConfig) -> Tuple[AasTestResult, ConfusionMatrix]:
228221
try:
229-
test_suites = available_suites[suite]
222+
test_suites = available_suites[conf.suite]
230223
except KeyError:
231224
all_suites = "\n".join(sorted(available_suites.keys()))
232-
raise AasTestToolsException(f"Unknown suite {suite}, must be one of:\n{all_suites}")
225+
raise AasTestToolsException(f"Unknown suite {conf.suite}, must be one of:\n{all_suites}")
233226

234227
mat = ConfusionMatrix()
235-
client = HttpClient(conf.server, conf.verify, conf.remove_path_prefix)
236228

237-
with start(f"Checking compliance to {suite}") as result_root:
229+
with start(f"Checking compliance to {conf.suite}") as result_root:
238230

239231
# Initial connection check
240232
if not _check_server(conf.dry, client):
@@ -253,7 +245,7 @@ def execute_tests(conf: ExecConf, suite: str) -> Tuple[AasTestResult, ConfusionM
253245
with start("Setup") as result_setup:
254246
prefix = prefix_provider(client)
255247
sub_client = client.descend(prefix)
256-
test_suite: ApiTestSuite = test_suite_class(sub_client, suite)
248+
test_suite: ApiTestSuite = test_suite_class(sub_client, conf.suite)
257249
test_suite.setup()
258250

259251
if result_setup.ok():

bin/check_servers.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from dataclasses import dataclass, field
99
import base64
1010

11-
from aas_test_engines.api import execute_tests, ExecConf
11+
from aas_test_engines.api import execute_tests, CheckApiConfig, HttpClient
1212
import requests
1313
from fences.core.util import ConfusionMatrix, Table, print_table
1414

@@ -129,12 +129,15 @@ def main():
129129

130130
docker_compose(server_dir, 'up', '-d')
131131
wait_for_server(server.url + "/shells")
132-
conf = ExecConf(
133-
server=server.url + profile.url_suffix,
132+
client = HttpClient(
133+
host=server.url + profile.url_suffix,
134+
remove_path_prefix=profile.discard_prefix,
134135
verify=False,
135-
remove_path_prefix=profile.discard_prefix
136136
)
137-
result, mat = execute_tests(conf, profile.spec_name)
137+
conf = CheckApiConfig(
138+
suite=profile.spec_name,
139+
)
140+
result, mat = execute_tests(client, conf)
138141
with open(result_file, "w") as f:
139142
f.write(result.to_html())
140143
profile.mats.append(mat)

test/acceptance/server.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#! /usr/bin/env python3
22

3-
from aas_test_engines import api
3+
from aas_test_engines import api, config, http
44
import os
55
import shutil
66
import subprocess
@@ -107,11 +107,12 @@ class Params:
107107
for param in params:
108108
print("-" * 10)
109109
print(f"Checking {param.suite}")
110-
conf = api.ExecConf(
111-
server=f"{HOST}{param.url}",
110+
client = http.HttpClient(
111+
host=f"{HOST}{param.url}",
112112
remove_path_prefix=param.remove_path_prefix,
113113
)
114-
result, mat = api.execute_tests(conf, param.suite)
114+
conf = config.CheckApiConfig(param.suite)
115+
result, mat = api.execute_tests(client, conf)
115116
mat.print()
116117
with open("output.html", "w") as f:
117118
f.write(result.to_html())

0 commit comments

Comments
 (0)