aplos-nca-saas-sdk 0.0.14__py3-none-any.whl → 0.0.16__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- aplos_nca_saas_sdk/integration_testing/configs/app_settings_config.py +2 -0
- aplos_nca_saas_sdk/integration_testing/configs/file_upload_config.py +4 -1
- aplos_nca_saas_sdk/integration_testing/configs/login_config.py +3 -0
- aplos_nca_saas_sdk/integration_testing/configs/nca_execution_config.py +6 -2
- aplos_nca_saas_sdk/integration_testing/configs/nca_validation_config.py +95 -0
- aplos_nca_saas_sdk/integration_testing/{main.py → example_main.py} +15 -7
- aplos_nca_saas_sdk/integration_testing/integration_test_configurations.py +6 -0
- aplos_nca_saas_sdk/integration_testing/integration_test_suite.py +9 -9
- aplos_nca_saas_sdk/integration_testing/readme.md +193 -6
- aplos_nca_saas_sdk/integration_testing/tests/nca_analysis_validation_test.py +62 -0
- aplos_nca_saas_sdk/nca_resources/nca_analysis.py +1 -1
- aplos_nca_saas_sdk/nca_resources/nca_authenticator.py +5 -0
- aplos_nca_saas_sdk/nca_resources/nca_endpoints.py +4 -0
- aplos_nca_saas_sdk/nca_resources/nca_validations.py +76 -9
- aplos_nca_saas_sdk/version.py +1 -1
- {aplos_nca_saas_sdk-0.0.14.dist-info → aplos_nca_saas_sdk-0.0.16.dist-info}/METADATA +1 -1
- {aplos_nca_saas_sdk-0.0.14.dist-info → aplos_nca_saas_sdk-0.0.16.dist-info}/RECORD +19 -18
- aplos_nca_saas_sdk/integration_testing/tests/validation_test.py +0 -5
- {aplos_nca_saas_sdk-0.0.14.dist-info → aplos_nca_saas_sdk-0.0.16.dist-info}/WHEEL +0 -0
- {aplos_nca_saas_sdk-0.0.14.dist-info → aplos_nca_saas_sdk-0.0.16.dist-info}/licenses/LICENSE +0 -0
@@ -11,7 +11,7 @@ from aplos_nca_saas_sdk.integration_testing.configs.login_config import (
|
|
11
11
|
LoginConfig,
|
12
12
|
LoginConfigs,
|
13
13
|
)
|
14
|
-
|
14
|
+
|
15
15
|
from aplos_nca_saas_sdk.utilities.file_utility import FileUtility
|
16
16
|
|
17
17
|
|
@@ -71,6 +71,9 @@ class FileUploadConfigs(ConfigBase):
|
|
71
71
|
"""Load the file uploads from a list of dictionaries"""
|
72
72
|
|
73
73
|
super().load(test_config)
|
74
|
+
if not self.enabled:
|
75
|
+
return
|
76
|
+
|
74
77
|
test_config_login: LoginConfig | None = LoginConfigs.try_load_login(
|
75
78
|
test_config.get("login", None)
|
76
79
|
)
|
@@ -98,6 +98,9 @@ class LoginConfigs(ConfigBase):
|
|
98
98
|
"""Load the logins from a list of dictionaries"""
|
99
99
|
|
100
100
|
super().load(test_config)
|
101
|
+
if not self.enabled:
|
102
|
+
return
|
103
|
+
|
101
104
|
logins: List[Dict[str, str]] = test_config.get("logins", [])
|
102
105
|
for login in logins:
|
103
106
|
login_config = LoginConfigs.try_load_login(login)
|
@@ -4,16 +4,18 @@ All Rights Reserved. www.aplosanalytics.com LICENSED MATERIALS
|
|
4
4
|
Property of Aplos Analytics, Utah, USA
|
5
5
|
"""
|
6
6
|
|
7
|
-
import os
|
8
7
|
import json
|
8
|
+
import os
|
9
9
|
from typing import Any, Dict, List
|
10
|
+
|
11
|
+
from aws_lambda_powertools import Logger
|
12
|
+
|
10
13
|
from aplos_nca_saas_sdk.integration_testing.configs._config_base import ConfigBase
|
11
14
|
from aplos_nca_saas_sdk.integration_testing.configs.login_config import (
|
12
15
|
LoginConfig,
|
13
16
|
LoginConfigs,
|
14
17
|
)
|
15
18
|
from aplos_nca_saas_sdk.utilities.file_utility import FileUtility
|
16
|
-
from aws_lambda_powertools import Logger
|
17
19
|
|
18
20
|
logger = Logger(service="NCAExecutionConfig")
|
19
21
|
|
@@ -124,6 +126,8 @@ class NCAExecutionConfigs(ConfigBase):
|
|
124
126
|
"""Loads the NCA Execution configs from a list of dictionaries"""
|
125
127
|
|
126
128
|
super().load(test_config)
|
129
|
+
if not self.enabled:
|
130
|
+
return
|
127
131
|
|
128
132
|
base_login: LoginConfig | None = LoginConfigs.try_load_login(
|
129
133
|
test_config.get("login", None)
|
@@ -0,0 +1,95 @@
|
|
1
|
+
"""
|
2
|
+
Copyright 2024-2025 Aplos Analytics
|
3
|
+
All Rights Reserved. www.aplosanalytics.com LICENSED MATERIALS
|
4
|
+
Property of Aplos Analytics, Utah, USA
|
5
|
+
"""
|
6
|
+
|
7
|
+
from typing import Any, Dict, List
|
8
|
+
|
9
|
+
from aws_lambda_powertools import Logger
|
10
|
+
|
11
|
+
from aplos_nca_saas_sdk.integration_testing.configs._config_base import ConfigBase
|
12
|
+
from aplos_nca_saas_sdk.integration_testing.configs.login_config import (
|
13
|
+
LoginConfig,
|
14
|
+
LoginConfigs,
|
15
|
+
)
|
16
|
+
|
17
|
+
|
18
|
+
logger = Logger(service="NCAValidationConfig")
|
19
|
+
|
20
|
+
|
21
|
+
class NCAValidationConfig(ConfigBase):
|
22
|
+
"""
|
23
|
+
NCA Validation Config: Defines an NCA Validation configuration that the application tests will check against
|
24
|
+
|
25
|
+
"""
|
26
|
+
|
27
|
+
def __init__(
|
28
|
+
self,
|
29
|
+
login: LoginConfig,
|
30
|
+
):
|
31
|
+
super().__init__()
|
32
|
+
|
33
|
+
if login is None:
|
34
|
+
raise RuntimeError("login is required")
|
35
|
+
self.__login = login
|
36
|
+
|
37
|
+
@property
|
38
|
+
def login(self) -> LoginConfig:
|
39
|
+
"""Login Configuration"""
|
40
|
+
return self.__login
|
41
|
+
|
42
|
+
|
43
|
+
class NCAValidationConfigs(ConfigBase):
|
44
|
+
"""
|
45
|
+
NCA Validation Configs: Defines the configurations that the application NCA Engine tests will check against
|
46
|
+
|
47
|
+
"""
|
48
|
+
|
49
|
+
def __init__(self):
|
50
|
+
super().__init__()
|
51
|
+
self.__list: List[NCAValidationConfig] = []
|
52
|
+
|
53
|
+
@property
|
54
|
+
def list(self) -> List[NCAValidationConfig]:
|
55
|
+
"""List the nca validation configurations"""
|
56
|
+
return list(filter(lambda x: x.enabled, self.__list))
|
57
|
+
|
58
|
+
def add(
|
59
|
+
self,
|
60
|
+
*,
|
61
|
+
login: LoginConfig,
|
62
|
+
enabled: bool = True,
|
63
|
+
):
|
64
|
+
"""Add an NCA Validation Config"""
|
65
|
+
config = NCAValidationConfig(login)
|
66
|
+
config.enabled = enabled
|
67
|
+
self.__list.append(config)
|
68
|
+
|
69
|
+
def load(self, test_config: Dict[str, Any]):
|
70
|
+
"""Loads the NCA Validation configs from a list of dictionaries"""
|
71
|
+
|
72
|
+
super().load(test_config)
|
73
|
+
if not self.enabled:
|
74
|
+
return
|
75
|
+
|
76
|
+
base_login: LoginConfig | None = LoginConfigs.try_load_login(
|
77
|
+
test_config.get("login", None)
|
78
|
+
)
|
79
|
+
|
80
|
+
validations: List[Dict[str, Any]] = test_config.get("validations", [])
|
81
|
+
for validation in validations:
|
82
|
+
enabled = bool(validation.get("enabled", True))
|
83
|
+
login: LoginConfig | None = None
|
84
|
+
if "login" in validation:
|
85
|
+
login = LoginConfigs.try_load_login(validation["login"])
|
86
|
+
else:
|
87
|
+
login = base_login
|
88
|
+
|
89
|
+
if not login:
|
90
|
+
raise RuntimeError("Failed to load the login configuration")
|
91
|
+
|
92
|
+
self.add(
|
93
|
+
login=login,
|
94
|
+
enabled=enabled,
|
95
|
+
)
|
@@ -16,19 +16,25 @@ from aplos_nca_saas_sdk.integration_testing.integration_test_configurations impo
|
|
16
16
|
|
17
17
|
|
18
18
|
def main():
|
19
|
-
"""
|
19
|
+
"""This is an example on how you can run the unit tests"""
|
20
20
|
|
21
|
+
# Optionally use our convient Environment Services loader
|
22
|
+
# which can help during intial testings.
|
21
23
|
evs: EnvironmentServices = EnvironmentServices()
|
24
|
+
# see if we have a local .env, .env.uat, etc configured to look up
|
22
25
|
env_file = os.getenv("ENV_FILE")
|
23
26
|
if env_file:
|
24
27
|
# if we have an environment file defined, let's load it
|
25
28
|
evs.load_environment(starting_path=__file__, file_name=env_file)
|
26
29
|
|
30
|
+
# this is where the work begins
|
27
31
|
its: IntegrationTestSuite = IntegrationTestSuite()
|
28
32
|
config: TestConfiguration = TestConfiguration()
|
29
33
|
|
30
|
-
#
|
31
|
-
#
|
34
|
+
# here were going to load a config file that is local, for security purpose
|
35
|
+
# you should store this in SecretsManager, Parameter Store, a secure S3 bucket etc.
|
36
|
+
# the configs typically contain sensitive information like usernames & passwords
|
37
|
+
# so be careful where you store it!
|
32
38
|
config_file = os.path.join(
|
33
39
|
Path(__file__).parent,
|
34
40
|
"configs",
|
@@ -37,14 +43,16 @@ def main():
|
|
37
43
|
# load it so we can see what it looks like
|
38
44
|
config.load(file_path=config_file)
|
39
45
|
|
40
|
-
#
|
41
|
-
# override_config(config)
|
42
|
-
|
46
|
+
# run the tests
|
43
47
|
its.test(test_config=config)
|
44
48
|
|
45
49
|
|
46
50
|
def override_config(config: TestConfiguration):
|
47
|
-
"""
|
51
|
+
"""
|
52
|
+
Override the configuration for the tests.
|
53
|
+
This is some sample code how you can use a combination of a config file
|
54
|
+
and then override the username/password combos using environment vars.
|
55
|
+
"""
|
48
56
|
username = os.getenv("TEST_USERNAME")
|
49
57
|
password = os.getenv("TEST_PASSWORD")
|
50
58
|
host = os.getenv("TEST_HOST")
|
@@ -17,6 +17,10 @@ from aplos_nca_saas_sdk.integration_testing.configs.nca_execution_config import
|
|
17
17
|
NCAExecutionConfigs,
|
18
18
|
)
|
19
19
|
|
20
|
+
from aplos_nca_saas_sdk.integration_testing.configs.nca_validation_config import (
|
21
|
+
NCAValidationConfigs,
|
22
|
+
)
|
23
|
+
|
20
24
|
|
21
25
|
class TestConfiguration:
|
22
26
|
"""
|
@@ -29,6 +33,7 @@ class TestConfiguration:
|
|
29
33
|
self.logins: LoginConfigs = LoginConfigs()
|
30
34
|
self.file_uploads: FileUploadConfigs = FileUploadConfigs()
|
31
35
|
self.nca_executions: NCAExecutionConfigs = NCAExecutionConfigs()
|
36
|
+
self.nca_validations: NCAValidationConfigs = NCAValidationConfigs()
|
32
37
|
|
33
38
|
def load(self, file_path: str):
|
34
39
|
"""
|
@@ -46,3 +51,4 @@ class TestConfiguration:
|
|
46
51
|
self.app_config.load(config.get("application_config_test", {}))
|
47
52
|
self.file_uploads.load(config.get("file_upload_test", {}))
|
48
53
|
self.nca_executions.load(config.get("analysis_execution_test", {}))
|
54
|
+
self.nca_validations.load(config.get("analysis_validation_test", {}))
|
@@ -70,15 +70,15 @@ class IntegrationTestSuite:
|
|
70
70
|
if self.fail_fast:
|
71
71
|
# just break and let the failure routine handle it
|
72
72
|
break
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
73
|
+
finally:
|
74
|
+
test_result["end_time_utc"] = datetime.now(UTC)
|
75
|
+
self.test_results.append(test_result)
|
76
|
+
|
77
|
+
if test_result["success"]:
|
78
|
+
logger.info(f"Test {test.name} succeeded")
|
79
|
+
logger.debug(test_result)
|
80
|
+
else:
|
81
|
+
logger.error(test_result)
|
82
82
|
# find the failures
|
83
83
|
failures = [test for test in self.test_results if len(test["errors"]) > 0]
|
84
84
|
self.__print_results(start_time, failures)
|
@@ -5,14 +5,201 @@ However you can also use this as a learning tool or a base on how to use our API
|
|
5
5
|
|
6
6
|
## Requirements
|
7
7
|
The integration tests will require the following:
|
8
|
-
|
9
|
-
|
10
|
-
|Variable Name|Description|
|
11
|
-
|--|--|
|
12
|
-
|APLOS_host|The full host name. e.g. app.aplos-nca.com|
|
8
|
+
- A valid user Aplos NCA User Account
|
9
|
+
- A valid subscription
|
13
10
|
|
14
11
|
|
15
12
|
### Users
|
16
13
|
You will need valid user accounts with the appropriate permissions for the endpoints they are executing.
|
17
14
|
|
18
|
-
If you are testing permission bounderies then you should set up multiple users with different permissions.
|
15
|
+
If you are testing permission bounderies then you should set up multiple users with different permissions.
|
16
|
+
|
17
|
+
|
18
|
+
### Subscriptions
|
19
|
+
Your subscription will control how may executions are allowed for user or tenancy. Make sure you have enough executions. If you need
|
20
|
+
additional executions, please reach-out to your support contact.
|
21
|
+
|
22
|
+
## Running the test
|
23
|
+
See the `example_main.py` for updated examples, but in general you follow the code below to run tests. Also, see the `configs` section below
|
24
|
+
for guidance on defining what is tested.
|
25
|
+
|
26
|
+
```python
|
27
|
+
"""
|
28
|
+
Copyright 2024-2025 Aplos Analytics
|
29
|
+
All Rights Reserved. www.aplosanalytics.com LICENSED MATERIALS
|
30
|
+
Property of Aplos Analytics, Utah, USA
|
31
|
+
"""
|
32
|
+
|
33
|
+
import os
|
34
|
+
from pathlib import Path
|
35
|
+
from aplos_nca_saas_sdk.utilities.environment_services import EnvironmentServices
|
36
|
+
from aplos_nca_saas_sdk.integration_testing.integration_test_suite import (
|
37
|
+
IntegrationTestSuite,
|
38
|
+
)
|
39
|
+
from aplos_nca_saas_sdk.integration_testing.integration_test_configurations import (
|
40
|
+
TestConfiguration,
|
41
|
+
)
|
42
|
+
|
43
|
+
|
44
|
+
def main():
|
45
|
+
"""This is an example on how you can run the unit tests"""
|
46
|
+
|
47
|
+
# Optionally use our convient Environment Services loader
|
48
|
+
# which can help during intial testings.
|
49
|
+
evs: EnvironmentServices = EnvironmentServices()
|
50
|
+
# See if we have a local .env, .env.uat, etc configured to look up
|
51
|
+
# for local configuration settings
|
52
|
+
#
|
53
|
+
# Use local .env files when testing locally. As a best practice
|
54
|
+
# you should avoid adding these to source control or deployments.
|
55
|
+
env_file = os.getenv("ENV_FILE")
|
56
|
+
if env_file:
|
57
|
+
# if we have an environment file defined, let's load it
|
58
|
+
# this will prep our environment with local values.
|
59
|
+
evs.load_environment(starting_path=__file__, file_name=env_file)
|
60
|
+
|
61
|
+
# this is where the work begins
|
62
|
+
its: IntegrationTestSuite = IntegrationTestSuite()
|
63
|
+
config: TestConfiguration = TestConfiguration()
|
64
|
+
|
65
|
+
# here were going to load a config file that is local, for security purpose
|
66
|
+
# you should store this in SecretsManager, Parameter Store, a secure S3 bucket etc.
|
67
|
+
# the configs typically contain sensitive information like usernames & passwords
|
68
|
+
# so be careful where you store it!
|
69
|
+
config_file = os.path.join(
|
70
|
+
Path(__file__).parent,
|
71
|
+
"configs",
|
72
|
+
os.getenv("TEST_CONFIG_FILE") or "config_sample.json",
|
73
|
+
)
|
74
|
+
# load it so we can see what it looks like
|
75
|
+
config.load(file_path=config_file)
|
76
|
+
|
77
|
+
# run the tests
|
78
|
+
its.test(test_config=config)
|
79
|
+
|
80
|
+
|
81
|
+
```
|
82
|
+
|
83
|
+
### Configs
|
84
|
+
Tests are run based on configurations. The following is an example of supported configurations:
|
85
|
+
|
86
|
+
- Appliction Configuration Settings
|
87
|
+
- Logins & Access
|
88
|
+
- Executing an Analysis
|
89
|
+
- Running a Validation
|
90
|
+
|
91
|
+
```json
|
92
|
+
{
|
93
|
+
"application_config_test": {
|
94
|
+
"purpose": "Tests the application configuration endpoints",
|
95
|
+
"hosts": [
|
96
|
+
{
|
97
|
+
"host": "api.example.com",
|
98
|
+
"expected_results": {
|
99
|
+
"status_code": 200
|
100
|
+
},
|
101
|
+
"enabled": true
|
102
|
+
},
|
103
|
+
{
|
104
|
+
"host": "XXXXXXXXXXXXXXXXXXXXX",
|
105
|
+
"expected_results": {
|
106
|
+
"status_code": 403
|
107
|
+
},
|
108
|
+
"enabled": false
|
109
|
+
}
|
110
|
+
]
|
111
|
+
},
|
112
|
+
"login_test": {
|
113
|
+
"purpose": "Tests the login endpoints",
|
114
|
+
"logins": [
|
115
|
+
{
|
116
|
+
"username": "foo",
|
117
|
+
"password": "barr",
|
118
|
+
"host": "api.example.com",
|
119
|
+
"roles": []
|
120
|
+
},
|
121
|
+
{
|
122
|
+
"username": "XXXXXXXXXXXXXXXXXXXXX",
|
123
|
+
"password": "XXXXXXXXXXXXXXXXXXXXX",
|
124
|
+
"host": "XXXXXXXXXXXXXXXXXXXXX",
|
125
|
+
"roles": [
|
126
|
+
"XXXXXXXXXXXXXXXXXXXXX"
|
127
|
+
],
|
128
|
+
"enabled": false,
|
129
|
+
"expected_results": {
|
130
|
+
"exception": "InvalidCredentialsException"
|
131
|
+
}
|
132
|
+
}
|
133
|
+
]
|
134
|
+
},
|
135
|
+
"file_upload_test": {
|
136
|
+
"purpose": "Tests the file upload endpoints.",
|
137
|
+
"notes": "a file can be on the local drive or pulled from a public https source.",
|
138
|
+
"login": {
|
139
|
+
"purpose": "optional: if present this login is used, unless a specific login is defined for the test",
|
140
|
+
"username": "foo",
|
141
|
+
"password": "bar",
|
142
|
+
"host": "api.example.com"
|
143
|
+
},
|
144
|
+
"files": [
|
145
|
+
{
|
146
|
+
"file": "XXXXXXXXXXXXXXXXXXXXX"
|
147
|
+
},
|
148
|
+
{
|
149
|
+
"file": "XXXXXXXXXXXXXXXXXXXXX",
|
150
|
+
"login": {
|
151
|
+
"purpose": "optional: if present tests an upload for a specific user",
|
152
|
+
"username": "XXXXXXXXXXXXXXXXXXXXX",
|
153
|
+
"password": "XXXXXXXXXXXXXXXXXXXXX",
|
154
|
+
"host": "XXXXXXXXXXXXXXXXXXXXX"
|
155
|
+
}
|
156
|
+
}
|
157
|
+
]
|
158
|
+
},
|
159
|
+
"analysis_execution_test": {
|
160
|
+
"purpose": "Tests the analysis execution endpoints.",
|
161
|
+
"login": {
|
162
|
+
"username": "XXXXXXXXXXXXXXXXXXXXX",
|
163
|
+
"password": "XXXXXXXXXXXXXXXXXXXXX",
|
164
|
+
"host": "XXXXXXXXXXXXXXXXXXXXX"
|
165
|
+
},
|
166
|
+
"output_dir": "XXXXXXXXXXXXXXXXXXXXX",
|
167
|
+
"analyses": [
|
168
|
+
{
|
169
|
+
"file": "XXXXXXXXXXXXXXXXXXXXX",
|
170
|
+
"meta": {},
|
171
|
+
"config": {},
|
172
|
+
"expected_results": {
|
173
|
+
"status_code": 200
|
174
|
+
},
|
175
|
+
"output_dir": "XXXXXXXXXXXXXXXXXXXXX"
|
176
|
+
},
|
177
|
+
{
|
178
|
+
"file": "XXXXXXXXXXXXXXXXXXXXX",
|
179
|
+
"meta": {},
|
180
|
+
"config": {},
|
181
|
+
"login": {
|
182
|
+
"username": "XXXXXXXXXXXXXXXXXXXXX",
|
183
|
+
"password": "XXXXXXXXXXXXXXXXXXXXX",
|
184
|
+
"host": "XXXXXXXXXXXXXXXXXXXXX"
|
185
|
+
},
|
186
|
+
"expected_results": {
|
187
|
+
"status_code": 200
|
188
|
+
}
|
189
|
+
}
|
190
|
+
]
|
191
|
+
},
|
192
|
+
"validation_test": {
|
193
|
+
"purpose": "Tests the validation execution.",
|
194
|
+
"login": {
|
195
|
+
"username": "XXXXXXXXXXXXXXXXXXXXX",
|
196
|
+
"password": "XXXXXXXXXXXXXXXXXXXXX",
|
197
|
+
"host": "XXXXXXXXXXXXXXXXXXXXX"
|
198
|
+
},
|
199
|
+
"expected_results": {
|
200
|
+
"status_code": 200
|
201
|
+
}
|
202
|
+
}
|
203
|
+
}
|
204
|
+
|
205
|
+
```
|
@@ -0,0 +1,62 @@
|
|
1
|
+
"""
|
2
|
+
Copyright 2024-2025 Aplos Analytics
|
3
|
+
All Rights Reserved. www.aplosanalytics.com LICENSED MATERIALS
|
4
|
+
Property of Aplos Analytics, Utah, USA
|
5
|
+
"""
|
6
|
+
|
7
|
+
from aws_lambda_powertools import Logger
|
8
|
+
|
9
|
+
from aplos_nca_saas_sdk.integration_testing.integration_test_base import (
|
10
|
+
IntegrationTestBase,
|
11
|
+
)
|
12
|
+
from aplos_nca_saas_sdk.integration_testing.integration_test_response import (
|
13
|
+
IntegrationTestResponse,
|
14
|
+
)
|
15
|
+
from aplos_nca_saas_sdk.nca_resources.nca_validations import NCAValidation
|
16
|
+
|
17
|
+
|
18
|
+
logger = Logger(service="NCAAnalysisValidationTest")
|
19
|
+
|
20
|
+
|
21
|
+
class NCAAnalysisValidationTest(IntegrationTestBase):
|
22
|
+
"""NCA Validation Test Container"""
|
23
|
+
|
24
|
+
def __init__(self):
|
25
|
+
super().__init__("nca-validation")
|
26
|
+
|
27
|
+
def test(self) -> bool:
|
28
|
+
"""Test Engine Validation"""
|
29
|
+
|
30
|
+
self.results.clear()
|
31
|
+
|
32
|
+
for config in self.config.nca_validations.list:
|
33
|
+
test_response: IntegrationTestResponse = IntegrationTestResponse()
|
34
|
+
test_response.name = self.name
|
35
|
+
|
36
|
+
try:
|
37
|
+
# Create new NCA Execution
|
38
|
+
nca_validation: NCAValidation = NCAValidation(config.login.host)
|
39
|
+
|
40
|
+
# Initialize Configuration Data
|
41
|
+
|
42
|
+
# Execute, the execution should raise errors that will fail the test
|
43
|
+
logger.info({"message": "Invoking Execution"})
|
44
|
+
execution_response = nca_validation.execute(
|
45
|
+
username=config.login.username,
|
46
|
+
password=config.login.password,
|
47
|
+
wait_for_results=True,
|
48
|
+
)
|
49
|
+
|
50
|
+
# Verify Download
|
51
|
+
logger.info({"message": "Validation complete. Verifying results."})
|
52
|
+
|
53
|
+
pass_fail = execution_response.get("results", {}).get("pass_fail")
|
54
|
+
if pass_fail != "pass":
|
55
|
+
raise RuntimeError("One or more validations failed.")
|
56
|
+
|
57
|
+
except Exception as e: # pylint: disable=w0718
|
58
|
+
test_response.error = str(e)
|
59
|
+
|
60
|
+
self.results.append(test_response)
|
61
|
+
|
62
|
+
return self.success()
|
@@ -150,7 +150,7 @@ class NCAAnalysis(NCAApiBaseClass):
|
|
150
150
|
raise ValueError(
|
151
151
|
"Missing config_data. Please provide a valid config_data."
|
152
152
|
)
|
153
|
-
headers =
|
153
|
+
headers = self.authenticator.get_jwt_http_headers()
|
154
154
|
# to start a new execution we need the location of the file (s3 bucket and object key)
|
155
155
|
# you basic configuration
|
156
156
|
# optional meta data
|
@@ -9,6 +9,7 @@ from aplos_nca_saas_sdk.nca_resources.aws_cognito import CognitoAuthentication
|
|
9
9
|
from aplos_nca_saas_sdk.nca_resources.nca_app_configuration import (
|
10
10
|
NCAAppConfiguration,
|
11
11
|
)
|
12
|
+
from aplos_nca_saas_sdk.utilities.http_utility import HttpUtilities
|
12
13
|
|
13
14
|
|
14
15
|
class NCAAuthenticator:
|
@@ -105,3 +106,7 @@ class NCAAuthenticator:
|
|
105
106
|
self.cognito.login(username=username, password=password)
|
106
107
|
|
107
108
|
return self.cognito.jwt
|
109
|
+
|
110
|
+
def get_jwt_http_headers(self) -> str:
|
111
|
+
"""Get the formatted http headers for the JWT"""
|
112
|
+
return HttpUtilities.get_headers(self.cognito.jwt)
|
@@ -70,6 +70,10 @@ class NCAEndpoints:
|
|
70
70
|
"""Returns the validations endpoint"""
|
71
71
|
return f"{self.user_path}/nca/validations"
|
72
72
|
|
73
|
+
def validation(self, batch_id: str) -> str:
|
74
|
+
"""Returns the validations endpoint for a specific batch"""
|
75
|
+
return f"{self.validations}/{batch_id}"
|
76
|
+
|
73
77
|
@property
|
74
78
|
def files(self) -> str:
|
75
79
|
"""Returns the files endpoint"""
|
@@ -4,10 +4,16 @@ All Rights Reserved. www.aplosanalytics.com LICENSED MATERIALS
|
|
4
4
|
Property of Aplos Analytics, Utah, USA
|
5
5
|
"""
|
6
6
|
|
7
|
-
import
|
7
|
+
import time
|
8
|
+
from datetime import datetime, timedelta
|
9
|
+
from typing import Any, Dict
|
8
10
|
|
11
|
+
import requests
|
12
|
+
from aws_lambda_powertools import Logger
|
9
13
|
from aplos_nca_saas_sdk.nca_resources._api_base import NCAApiBaseClass
|
10
14
|
|
15
|
+
logger = Logger(service="nca-validations")
|
16
|
+
|
11
17
|
|
12
18
|
class NCAValidation(NCAApiBaseClass):
|
13
19
|
"""NCA Analysis Validation API"""
|
@@ -15,20 +21,81 @@ class NCAValidation(NCAApiBaseClass):
|
|
15
21
|
def __init__(self, host: str) -> None:
|
16
22
|
super().__init__(host)
|
17
23
|
|
18
|
-
def
|
24
|
+
def execute(
|
25
|
+
self,
|
26
|
+
username: str,
|
27
|
+
password: str,
|
28
|
+
wait_for_results: bool = True,
|
29
|
+
max_wait_in_seconds: int = 900,
|
30
|
+
) -> Dict[str, Any]:
|
19
31
|
"""
|
20
|
-
|
32
|
+
Runs a validation
|
21
33
|
|
22
34
|
Args:
|
23
|
-
|
35
|
+
username (str): username
|
36
|
+
password (str): password
|
24
37
|
|
25
38
|
Returns:
|
26
|
-
|
39
|
+
Dict[str, Any]: response object
|
27
40
|
"""
|
41
|
+
|
42
|
+
self.authenticator.authenticate(username=username, password=password)
|
28
43
|
url = self.endpoints.validations
|
29
|
-
|
44
|
+
# no payload required
|
45
|
+
headers = self.authenticator.get_jwt_http_headers()
|
46
|
+
validation_post_response = requests.post(url, headers=headers, timeout=30)
|
47
|
+
|
48
|
+
if validation_post_response.status_code != 200:
|
49
|
+
raise RuntimeError(
|
50
|
+
f"Failed to execution a validation batch. Status Code: {validation_post_response.status_code}"
|
51
|
+
f"Reason: {validation_post_response.reason}"
|
52
|
+
)
|
53
|
+
|
54
|
+
response = {
|
55
|
+
"queued": validation_post_response.json(),
|
56
|
+
"results": None,
|
57
|
+
}
|
58
|
+
|
59
|
+
if wait_for_results:
|
60
|
+
batch_id = (
|
61
|
+
validation_post_response.json().get("validation_batch", {}).get("id")
|
62
|
+
)
|
63
|
+
|
64
|
+
if not batch_id:
|
65
|
+
raise RuntimeError(
|
66
|
+
"Failed to get the validation batch id from the response."
|
67
|
+
)
|
68
|
+
completed = False
|
69
|
+
current_time = datetime.now()
|
70
|
+
# Create a timedelta object representing 15 minutes
|
71
|
+
time_delta = timedelta(seconds=max_wait_in_seconds)
|
72
|
+
# Add the timedelta to the current time
|
73
|
+
max_time = current_time + time_delta
|
74
|
+
while not completed:
|
75
|
+
validation_get_response = requests.get(
|
76
|
+
self.endpoints.validation(batch_id=batch_id),
|
77
|
+
timeout=30,
|
78
|
+
headers=self.authenticator.get_jwt_http_headers(),
|
79
|
+
)
|
80
|
+
if validation_get_response.status_code != 200:
|
81
|
+
raise RuntimeError(
|
82
|
+
f"Failed to get validation results. Status Code: {validation_get_response.status_code}"
|
83
|
+
f"Reason: {validation_get_response.reason}"
|
84
|
+
)
|
85
|
+
status = validation_get_response.json().get("status")
|
86
|
+
completed = status == "complete"
|
30
87
|
|
31
|
-
|
32
|
-
|
88
|
+
if not completed:
|
89
|
+
if datetime.now() > max_time:
|
90
|
+
raise RuntimeError(
|
91
|
+
"Timeout attempting to get validation results. "
|
92
|
+
f"The current timeout limit is {max_wait_in_seconds} seconds. "
|
93
|
+
"You may need to up the timeout period, or check for errors. "
|
94
|
+
)
|
95
|
+
logger.info(f"waiting for results.... {status}")
|
96
|
+
time.sleep(15)
|
97
|
+
else:
|
98
|
+
response["results"] = validation_get_response.json()
|
33
99
|
|
34
|
-
|
100
|
+
logger.info("Validation complete.")
|
101
|
+
return response
|
aplos_nca_saas_sdk/version.py
CHANGED
@@ -1,19 +1,20 @@
|
|
1
1
|
aplos_nca_saas_sdk/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
2
|
aplos_nca_saas_sdk/run_analysis_execution.py,sha256=cYzGdAHOriDI7UHNFwzeaR6sHhiwNysx3__eMze8hZc,4445
|
3
|
-
aplos_nca_saas_sdk/version.py,sha256=
|
3
|
+
aplos_nca_saas_sdk/version.py,sha256=qLmk1u7bUFK0wkguJfyocxrKzrkxB9N02lZrHkT4ViQ,172
|
4
|
+
aplos_nca_saas_sdk/integration_testing/example_main.py,sha256=4vQHarGLrzhxBgfvHUt9f8Ce94DAzP3VaWqdGCUJXZg,2497
|
4
5
|
aplos_nca_saas_sdk/integration_testing/integration_test_base.py,sha256=ci3oOfz_McdDKGSrqOHF7F_vrvgTWo7HzxydNdPSHLs,2787
|
5
|
-
aplos_nca_saas_sdk/integration_testing/integration_test_configurations.py,sha256=
|
6
|
+
aplos_nca_saas_sdk/integration_testing/integration_test_configurations.py,sha256=GRDHSy0ZiAJtZQvL7uPlYG2oYVo9nWlP7hNZbNnrz7U,1900
|
6
7
|
aplos_nca_saas_sdk/integration_testing/integration_test_factory.py,sha256=HdcGQycsBNv-cLGXfL3yVpRjLaj-QkAv1ih0L8yVXA0,2203
|
7
8
|
aplos_nca_saas_sdk/integration_testing/integration_test_response.py,sha256=Ocn2q_kdgEJB-4Ol-V3dh8MEkf6CJdrIiQVURUeM62o,819
|
8
|
-
aplos_nca_saas_sdk/integration_testing/integration_test_suite.py,sha256=
|
9
|
-
aplos_nca_saas_sdk/integration_testing/
|
10
|
-
aplos_nca_saas_sdk/integration_testing/readme.md,sha256=USg_Z8C3hYgOGgmDsv7DNR2IxRV0Xg6NvOYrwTBqZRE,626
|
9
|
+
aplos_nca_saas_sdk/integration_testing/integration_test_suite.py,sha256=tgataONHn3Ob_QHT03npbuarOOE6Z3xeUiAXd4-z_mE,4461
|
10
|
+
aplos_nca_saas_sdk/integration_testing/readme.md,sha256=-4L-Tp1-oF9rk6-rOapcU5uLDATTOnQ-7nRoVEz6mv8,6762
|
11
11
|
aplos_nca_saas_sdk/integration_testing/configs/_config_base.py,sha256=PyXCiEbvM5usN8sbtVSEL0g1iqGh9bdE31kPORMJBIs,480
|
12
|
-
aplos_nca_saas_sdk/integration_testing/configs/app_settings_config.py,sha256=
|
12
|
+
aplos_nca_saas_sdk/integration_testing/configs/app_settings_config.py,sha256=F2gylnuJ9CHvoLwpNEPWZiojVQZIDqC8pCCbcMFXZmU,2631
|
13
13
|
aplos_nca_saas_sdk/integration_testing/configs/config_sample.json,sha256=zeflEvdtpknGjk42FXHGG3cBbvLcbSnj1_99o21JiDc,3566
|
14
|
-
aplos_nca_saas_sdk/integration_testing/configs/file_upload_config.py,sha256=
|
15
|
-
aplos_nca_saas_sdk/integration_testing/configs/login_config.py,sha256=
|
16
|
-
aplos_nca_saas_sdk/integration_testing/configs/nca_execution_config.py,sha256=
|
14
|
+
aplos_nca_saas_sdk/integration_testing/configs/file_upload_config.py,sha256=NZsE7n9bkZOVEDFC8jDEO4XAIb5Vzsd62_CnSDLNDj8,3034
|
15
|
+
aplos_nca_saas_sdk/integration_testing/configs/login_config.py,sha256=PYUXQZN_2rI16iSbeZf5zebVjOUqL0fWUv1ha3Gbszs,3609
|
16
|
+
aplos_nca_saas_sdk/integration_testing/configs/nca_execution_config.py,sha256=SDHMG3pQlz-XhF7yBemb-OmGRlaLZnUgWbebNRaVkQM,5819
|
17
|
+
aplos_nca_saas_sdk/integration_testing/configs/nca_validation_config.py,sha256=veqCTMsRTailuP-P5JX8JU7BkRMzC4-sxZM9tYG52ug,2595
|
17
18
|
aplos_nca_saas_sdk/integration_testing/files/executions/config1.json,sha256=m6-wSzfrB-7w4CgIGpmT9y0_zevp-Q6So9eXU9HsVpQ,945
|
18
19
|
aplos_nca_saas_sdk/integration_testing/files/uploads/input1.csv,sha256=9TGDiMkft7ltFFKk_8RyzuhuloIpe_fZs0Nw0PN3BkM,263
|
19
20
|
aplos_nca_saas_sdk/integration_testing/files/uploads/input1.dat,sha256=9TGDiMkft7ltFFKk_8RyzuhuloIpe_fZs0Nw0PN3BkM,263
|
@@ -25,18 +26,18 @@ aplos_nca_saas_sdk/integration_testing/tests/app_configuration_test.py,sha256=f5
|
|
25
26
|
aplos_nca_saas_sdk/integration_testing/tests/app_login_test.py,sha256=NLI4DUICspa_uZi-w2Q3XufDL0ERLVvn1DavNpYDK7I,1650
|
26
27
|
aplos_nca_saas_sdk/integration_testing/tests/file_upload_test.py,sha256=v3-5vEVPVREQDBColJeAGg2grG3c8A4WTxZnE3_ki9c,3936
|
27
28
|
aplos_nca_saas_sdk/integration_testing/tests/nca_analysis_test.py,sha256=RIxarfp_ggD4HgVb8xnMynIDZG2HZ0hmv6sZj1-T73c,3261
|
28
|
-
aplos_nca_saas_sdk/integration_testing/tests/
|
29
|
+
aplos_nca_saas_sdk/integration_testing/tests/nca_analysis_validation_test.py,sha256=IlnkaO_KSrm0tch0gxM0rZP59m1PHzUow4kZm9CiBqY,2042
|
29
30
|
aplos_nca_saas_sdk/nca_resources/_api_base.py,sha256=qxMSiHV4014L733ii4EJ2JUwQwKkuHi5Rm6cPEdS3cA,1278
|
30
31
|
aplos_nca_saas_sdk/nca_resources/aws_cognito.py,sha256=lc6GCvoTBx_Dmezoxt80xksiuxXjSwkynj-1Sg0vzwY,6576
|
31
32
|
aplos_nca_saas_sdk/nca_resources/aws_s3_presigned_payload.py,sha256=S9LvUEjzJqLYob-JmNXdIe0Uj__fVtcF4LDQB5538vk,2001
|
32
33
|
aplos_nca_saas_sdk/nca_resources/aws_s3_presigned_upload.py,sha256=ExZUjJ4Yyu-oQyVMNtyl7KqxFfr4hIwIN31RFxg6EfM,4476
|
33
|
-
aplos_nca_saas_sdk/nca_resources/nca_analysis.py,sha256=
|
34
|
+
aplos_nca_saas_sdk/nca_resources/nca_analysis.py,sha256=cNGUpCEbMtcKCgUFgB7xrJG1-31Mlzt1qk1diZBfSgM,10614
|
34
35
|
aplos_nca_saas_sdk/nca_resources/nca_app_configuration.py,sha256=VZNZi0_NV4QjNgBSM9csq5qedc6-qvzaXwXyLfymB6M,1845
|
35
|
-
aplos_nca_saas_sdk/nca_resources/nca_authenticator.py,sha256=
|
36
|
-
aplos_nca_saas_sdk/nca_resources/nca_endpoints.py,sha256=
|
36
|
+
aplos_nca_saas_sdk/nca_resources/nca_authenticator.py,sha256=tyhAHrf4PlLYarYXtY4ARCtSdGAL9GciqifDDck1KSQ,3354
|
37
|
+
aplos_nca_saas_sdk/nca_resources/nca_endpoints.py,sha256=4nAh6JD-EUZj-Zv4EGv-W1Lgf3ww5OAQqqZu56IkPuw,2538
|
37
38
|
aplos_nca_saas_sdk/nca_resources/nca_file_download.py,sha256=_ryJta9f6CBOh0OsE6P4FMGZggjYWu_kj1ZuzVVuruc,4190
|
38
39
|
aplos_nca_saas_sdk/nca_resources/nca_file_upload.py,sha256=dqETMtnzYZilPlFfLKW7o3DrrBLObeIGgILWPyD-3ZI,1653
|
39
|
-
aplos_nca_saas_sdk/nca_resources/nca_validations.py,sha256=
|
40
|
+
aplos_nca_saas_sdk/nca_resources/nca_validations.py,sha256=b9i-kXH52tXezgzOCwi9DWgVDfABSHHpVdXKZrf6HVc,3628
|
40
41
|
aplos_nca_saas_sdk/sample_files/analysis_files/single_ev/config.json,sha256=lLnRV0jwzaSn32D8NlOekOF5oGFfUwugUlvlwoKz540,986
|
41
42
|
aplos_nca_saas_sdk/sample_files/analysis_files/single_ev/input.csv,sha256=qFSAlgLOmERsabMmp1X6PAZa-8yFthZlHacM_f7_AOY,6528
|
42
43
|
aplos_nca_saas_sdk/sample_files/analysis_files/single_ev/meta_data.json,sha256=p1KYOAe5Cl3rjtfF1t96oRG-QtFJJCo9otReRPNtvIk,447
|
@@ -45,7 +46,7 @@ aplos_nca_saas_sdk/utilities/environment_services.py,sha256=eKlaz-3VAPHUe-MN0rc_
|
|
45
46
|
aplos_nca_saas_sdk/utilities/environment_vars.py,sha256=aXheFXg6FVMaSYLe2LmoWRF5Ks9vwxDazO4XYb4vLjc,1132
|
46
47
|
aplos_nca_saas_sdk/utilities/file_utility.py,sha256=EUvQ65aXN6OdILniuiDQ2rPRA9sFmvUoAehifEjRgUY,1025
|
47
48
|
aplos_nca_saas_sdk/utilities/http_utility.py,sha256=DQ-ClLOmNoyPn5vhrSh4q-2wi4ViP_gplJD9asEKDM8,464
|
48
|
-
aplos_nca_saas_sdk-0.0.
|
49
|
-
aplos_nca_saas_sdk-0.0.
|
50
|
-
aplos_nca_saas_sdk-0.0.
|
51
|
-
aplos_nca_saas_sdk-0.0.
|
49
|
+
aplos_nca_saas_sdk-0.0.16.dist-info/METADATA,sha256=-MSLEhLFa95ZPNMzEgC2RchbQ5KAHxaxQMh2636KnLY,3792
|
50
|
+
aplos_nca_saas_sdk-0.0.16.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
51
|
+
aplos_nca_saas_sdk-0.0.16.dist-info/licenses/LICENSE,sha256=JQMpBrnqu_m2tISmyh6_dTgb8-m3HNnA51fuOh2TzkE,1076
|
52
|
+
aplos_nca_saas_sdk-0.0.16.dist-info/RECORD,,
|
File without changes
|
{aplos_nca_saas_sdk-0.0.14.dist-info → aplos_nca_saas_sdk-0.0.16.dist-info}/licenses/LICENSE
RENAMED
File without changes
|