cornflow 1.1.0a2__py3-none-any.whl → 1.1.1a1__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.
- cornflow/app.py +4 -0
- cornflow/cli/utils.py +1 -1
- cornflow/config.py +10 -2
- cornflow/endpoints/__init__.py +14 -0
- cornflow/endpoints/execution.py +1 -1
- cornflow/endpoints/login.py +26 -6
- cornflow/endpoints/reports.py +283 -0
- cornflow/migrations/versions/83164be03c23_.py +40 -0
- cornflow/migrations/versions/96f00d0961d1_reports_table.py +50 -0
- cornflow/models/__init__.py +2 -0
- cornflow/models/execution.py +8 -0
- cornflow/models/meta_models.py +23 -12
- cornflow/models/reports.py +119 -0
- cornflow/schemas/execution.py +3 -0
- cornflow/schemas/reports.py +48 -0
- cornflow/shared/const.py +21 -0
- cornflow/shared/exceptions.py +20 -9
- cornflow/static/v1.json +3854 -0
- cornflow/tests/const.py +7 -0
- cornflow/tests/{custom_liveServer.py → custom_live_server.py} +3 -1
- cornflow/tests/custom_test_case.py +2 -3
- cornflow/tests/integration/test_commands.py +1 -1
- cornflow/tests/integration/test_cornflowclient.py +116 -28
- cornflow/tests/unit/test_alarms.py +22 -9
- cornflow/tests/unit/test_cli.py +10 -5
- cornflow/tests/unit/test_commands.py +6 -2
- cornflow/tests/unit/test_executions.py +5 -0
- cornflow/tests/unit/test_main_alarms.py +8 -0
- cornflow/tests/unit/test_reports.py +308 -0
- cornflow/tests/unit/test_users.py +5 -2
- {cornflow-1.1.0a2.dist-info → cornflow-1.1.1a1.dist-info}/METADATA +31 -31
- {cornflow-1.1.0a2.dist-info → cornflow-1.1.1a1.dist-info}/RECORD +35 -28
- {cornflow-1.1.0a2.dist-info → cornflow-1.1.1a1.dist-info}/WHEEL +1 -1
- {cornflow-1.1.0a2.dist-info → cornflow-1.1.1a1.dist-info}/entry_points.txt +0 -0
- {cornflow-1.1.0a2.dist-info → cornflow-1.1.1a1.dist-info}/top_level.txt +0 -0
cornflow/tests/const.py
CHANGED
@@ -14,6 +14,7 @@ INSTANCE_URL = PREFIX + "/instance/"
|
|
14
14
|
INSTANCE_MPS = _get_file("./data/test_mps.mps")
|
15
15
|
INSTANCE_GC_20 = _get_file("./data/gc_20_7.json")
|
16
16
|
INSTANCE_FILE_FAIL = _get_file("./unit/test_instances.py")
|
17
|
+
INSTANCE_TSP = _get_file("./data/tsp_instance.json")
|
17
18
|
|
18
19
|
EXECUTION_PATH = _get_file("./data/new_execution.json")
|
19
20
|
BAD_EXECUTION_PATH = _get_file("./data/bad_execution.json")
|
@@ -34,6 +35,12 @@ CASE_INSTANCE_URL = PREFIX + "/case/instance/"
|
|
34
35
|
FULL_CASE_PATH = _get_file("./data/full_case_raw.json")
|
35
36
|
FULL_CASE_LIST = [FULL_CASE_PATH, _get_file("./data/full_case_raw_2.json")]
|
36
37
|
|
38
|
+
REPORT_PATH = _get_file("./data/new_report.json")
|
39
|
+
REPORT_HTML_FILE_PATH = _get_file("./data/new_report.html")
|
40
|
+
REPORT_PDF_FILE_PATH = _get_file("./data/new_report_2.pdf")
|
41
|
+
BAD_REPORT_PATH = _get_file("./data/bad_report.json")
|
42
|
+
REPORT_URL = PREFIX + "/report/"
|
43
|
+
|
37
44
|
JSON_PATCH_GOOD_PATH = _get_file("./data/json_patch_good.json")
|
38
45
|
JSON_PATCH_BAD_PATH = _get_file("./data/json_patch_bad.json")
|
39
46
|
FULL_CASE_JSON_PATCH_1 = _get_file("./data/full_case_patch.json")
|
@@ -39,7 +39,9 @@ class CustomTestCaseLive(LiveServerTestCase):
|
|
39
39
|
if create_all:
|
40
40
|
db.create_all()
|
41
41
|
access_init_command(False)
|
42
|
-
register_deployed_dags_command_test(
|
42
|
+
register_deployed_dags_command_test(
|
43
|
+
verbose=False, dags=["solve_model_dag", "gc", "timer", "tsp"]
|
44
|
+
)
|
43
45
|
user_data = dict(
|
44
46
|
username="testname",
|
45
47
|
email="test@test.com",
|
@@ -90,8 +90,8 @@ class CustomTestCase(TestCase):
|
|
90
90
|
self.roles_with_access = []
|
91
91
|
|
92
92
|
@staticmethod
|
93
|
-
def get_header_with_auth(token):
|
94
|
-
return {"Content-Type":
|
93
|
+
def get_header_with_auth(token, content_type="application/json"):
|
94
|
+
return {"Content-Type": content_type, "Authorization": "Bearer " + token}
|
95
95
|
|
96
96
|
def create_user(self, data):
|
97
97
|
return self.client.post(
|
@@ -169,7 +169,6 @@ class CustomTestCase(TestCase):
|
|
169
169
|
self.assertEqual(row.id, response.json["id"])
|
170
170
|
|
171
171
|
for key in self.get_keys_to_check(payload):
|
172
|
-
getattr(row, key)
|
173
172
|
if key in payload:
|
174
173
|
self.assertEqual(getattr(row, key), payload[key])
|
175
174
|
return row.id
|
@@ -3,7 +3,7 @@ from flask import current_app
|
|
3
3
|
from cornflow.commands.dag import register_deployed_dags_command
|
4
4
|
from cornflow.models import DeployedDAG
|
5
5
|
from cornflow.tests.const import PUBLIC_DAGS
|
6
|
-
from cornflow.tests.
|
6
|
+
from cornflow.tests.custom_live_server import CustomTestCaseLive
|
7
7
|
|
8
8
|
|
9
9
|
class TestCornflowCommands(CustomTestCaseLive):
|
@@ -1,17 +1,17 @@
|
|
1
1
|
"""
|
2
|
-
|
2
|
+
Main script to run the integration tests of cornflow-server
|
3
3
|
"""
|
4
|
-
|
4
|
+
|
5
5
|
import json
|
6
|
-
import pulp
|
7
6
|
import logging as log
|
7
|
+
import os
|
8
8
|
import time
|
9
|
+
from typing import Callable, Any
|
9
10
|
|
10
|
-
|
11
|
+
import pulp
|
11
12
|
from cornflow_client import CornFlowApiError
|
12
13
|
from cornflow_client.constants import INSTANCE_SCHEMA, SOLUTION_SCHEMA
|
13
14
|
|
14
|
-
# Import internal modules
|
15
15
|
from cornflow.app import create_app
|
16
16
|
from cornflow.shared.const import (
|
17
17
|
EXEC_STATE_CORRECT,
|
@@ -19,12 +19,13 @@ from cornflow.shared.const import (
|
|
19
19
|
EXEC_STATE_RUNNING,
|
20
20
|
EXEC_STATE_QUEUED,
|
21
21
|
STATUS_HEALTHY,
|
22
|
+
REPORT_STATE,
|
22
23
|
)
|
23
|
-
from cornflow.tests.const import INSTANCE_PATH, CASE_PATH
|
24
|
-
from cornflow.tests.
|
24
|
+
from cornflow.tests.const import INSTANCE_PATH, CASE_PATH, INSTANCE_MPS, INSTANCE_TSP
|
25
|
+
from cornflow.tests.custom_live_server import CustomTestCaseLive
|
25
26
|
|
26
27
|
|
27
|
-
def load_file(_file):
|
28
|
+
def load_file(_file: str):
|
28
29
|
with open(_file) as f:
|
29
30
|
temp = json.load(f)
|
30
31
|
return temp
|
@@ -34,6 +35,7 @@ class TestCornflowClientBasic(CustomTestCaseLive):
|
|
34
35
|
def setUp(self, create_all=False):
|
35
36
|
super().setUp()
|
36
37
|
self.items_to_check = ["name", "description"]
|
38
|
+
log.info(f"Start test case name: {self.id()}")
|
37
39
|
|
38
40
|
def check_status_evolution(self, execution, end_state=EXEC_STATE_CORRECT):
|
39
41
|
statuses = [execution["state"]]
|
@@ -127,7 +129,7 @@ class TestCornflowClientBasic(CustomTestCaseLive):
|
|
127
129
|
return execution
|
128
130
|
|
129
131
|
def create_instance_and_execution(self):
|
130
|
-
one_instance = self.create_new_instance(
|
132
|
+
one_instance = self.create_new_instance(INSTANCE_MPS)
|
131
133
|
name = "test_execution_name_123"
|
132
134
|
description = "test_execution_description_123"
|
133
135
|
schema = "solve_model_dag"
|
@@ -140,6 +142,31 @@ class TestCornflowClientBasic(CustomTestCaseLive):
|
|
140
142
|
)
|
141
143
|
return self.create_new_execution(payload)
|
142
144
|
|
145
|
+
def create_instance_and_execution_report(
|
146
|
+
self,
|
147
|
+
schema="tsp",
|
148
|
+
solver="cpsat",
|
149
|
+
data=None,
|
150
|
+
timeLimit=10,
|
151
|
+
report_name="report",
|
152
|
+
):
|
153
|
+
name = "test_instance_1"
|
154
|
+
description = "description123"
|
155
|
+
if data is None:
|
156
|
+
data = load_file(INSTANCE_TSP)
|
157
|
+
payload = dict(data=data, name=name, description=description, schema=schema)
|
158
|
+
one_instance = self.create_new_instance_payload(payload)
|
159
|
+
payload = dict(
|
160
|
+
instance_id=one_instance["id"],
|
161
|
+
config=dict(
|
162
|
+
solver=solver, timeLimit=timeLimit, report=dict(name=report_name)
|
163
|
+
),
|
164
|
+
description="test_execution_description_123",
|
165
|
+
name="test_execution_123",
|
166
|
+
schema=schema,
|
167
|
+
)
|
168
|
+
return self.create_new_execution(payload)
|
169
|
+
|
143
170
|
def create_timer_instance_and_execution(self, seconds=5):
|
144
171
|
payload = dict(
|
145
172
|
data=dict(seconds=seconds),
|
@@ -157,16 +184,47 @@ class TestCornflowClientBasic(CustomTestCaseLive):
|
|
157
184
|
)
|
158
185
|
return self.create_new_execution(payload)
|
159
186
|
|
187
|
+
@staticmethod
|
188
|
+
def try_until_condition(
|
189
|
+
func: Callable,
|
190
|
+
condition: Callable[[Any], bool],
|
191
|
+
number_of_times: int = 10,
|
192
|
+
sleep_time: float = 10,
|
193
|
+
):
|
194
|
+
for i in range(number_of_times):
|
195
|
+
time.sleep(sleep_time)
|
196
|
+
result = func()
|
197
|
+
if condition(result):
|
198
|
+
return result
|
199
|
+
raise TimeoutError(
|
200
|
+
"Timed out after {} seconds".format(number_of_times * sleep_time)
|
201
|
+
)
|
202
|
+
|
203
|
+
@staticmethod
|
204
|
+
def wait_until_report_finishes(
|
205
|
+
client, execution_id: str, report_status=REPORT_STATE.CORRECT
|
206
|
+
):
|
207
|
+
def func():
|
208
|
+
my_reports = client.raw.get_results(execution_id).json()["reports"]
|
209
|
+
if len(my_reports) == 0:
|
210
|
+
return None
|
211
|
+
first = my_reports[0]
|
212
|
+
if first["state"] != report_status:
|
213
|
+
return None
|
214
|
+
return first
|
215
|
+
|
216
|
+
return func
|
217
|
+
|
160
218
|
|
161
219
|
class TestCornflowClientOpen(TestCornflowClientBasic):
|
162
220
|
# TODO: user management
|
163
221
|
# TODO: infeasible execution
|
164
222
|
|
165
223
|
def test_new_instance_file(self):
|
166
|
-
self.create_new_instance_file(
|
224
|
+
self.create_new_instance_file(INSTANCE_MPS)
|
167
225
|
|
168
226
|
def test_new_instance(self):
|
169
|
-
return self.create_new_instance(
|
227
|
+
return self.create_new_instance(INSTANCE_MPS)
|
170
228
|
|
171
229
|
# TODO: reactivate test with new version of cornflow client which allows to pass
|
172
230
|
# optional arguments for the headers of the request
|
@@ -189,6 +247,49 @@ class TestCornflowClientOpen(TestCornflowClientBasic):
|
|
189
247
|
def test_new_execution(self):
|
190
248
|
return self.create_instance_and_execution()
|
191
249
|
|
250
|
+
def test_new_execution_with_tsp_report(self):
|
251
|
+
return self.create_instance_and_execution_report()
|
252
|
+
|
253
|
+
#
|
254
|
+
def test_new_execution_with_tsp_report_wait(self):
|
255
|
+
execution = self.create_instance_and_execution_report()
|
256
|
+
func = self.wait_until_report_finishes(self.client, execution["id"])
|
257
|
+
reports_info = self.try_until_condition(func, lambda v: v is not None, 20, 5)
|
258
|
+
id_report = reports_info["id"]
|
259
|
+
my_name = "./my_report.html"
|
260
|
+
try:
|
261
|
+
os.remove(my_name)
|
262
|
+
except:
|
263
|
+
pass
|
264
|
+
self.client.raw.get_one_report(id_report, "./", my_name)
|
265
|
+
self.assertTrue(os.path.exists(my_name))
|
266
|
+
try:
|
267
|
+
os.remove(my_name)
|
268
|
+
except OSError:
|
269
|
+
pass
|
270
|
+
|
271
|
+
# read header of file? we can parse it with beatifulsoup
|
272
|
+
|
273
|
+
def test_new_execution_with_timer_report_wait(self):
|
274
|
+
payload = dict(
|
275
|
+
solver="default", schema="timer", data={"seconds": 1}, timeLimit=1
|
276
|
+
)
|
277
|
+
execution = self.create_instance_and_execution_report(**payload)
|
278
|
+
func = self.wait_until_report_finishes(self.client, execution["id"])
|
279
|
+
reports_info = self.try_until_condition(func, lambda v: v is not None, 20, 5)
|
280
|
+
id_report = reports_info["id"]
|
281
|
+
my_name = "./my_report.html"
|
282
|
+
try:
|
283
|
+
os.remove(my_name)
|
284
|
+
except:
|
285
|
+
pass
|
286
|
+
self.client.raw.get_one_report(id_report, "./", my_name)
|
287
|
+
self.assertTrue(os.path.exists(my_name))
|
288
|
+
try:
|
289
|
+
os.remove(my_name)
|
290
|
+
except OSError:
|
291
|
+
pass
|
292
|
+
|
192
293
|
def test_delete_execution(self):
|
193
294
|
execution = self.test_new_execution()
|
194
295
|
response = self.client.raw.get_api_for_id("execution/", execution["id"])
|
@@ -213,7 +314,7 @@ class TestCornflowClientOpen(TestCornflowClientBasic):
|
|
213
314
|
self.assertTrue("error" in response.json())
|
214
315
|
|
215
316
|
def test_new_execution_bad_dag_name(self):
|
216
|
-
one_instance = self.create_new_instance(
|
317
|
+
one_instance = self.create_new_instance(INSTANCE_MPS)
|
217
318
|
name = "test_execution_name_123"
|
218
319
|
description = "test_execution_description_123"
|
219
320
|
payload = dict(
|
@@ -227,7 +328,7 @@ class TestCornflowClientOpen(TestCornflowClientBasic):
|
|
227
328
|
self.assertRaises(CornFlowApiError, _bad_func)
|
228
329
|
|
229
330
|
def test_new_execution_with_schema(self):
|
230
|
-
one_instance = self.create_new_instance(
|
331
|
+
one_instance = self.create_new_instance(INSTANCE_MPS)
|
231
332
|
name = "test_execution_name_123"
|
232
333
|
description = "test_execution_description_123"
|
233
334
|
payload = dict(
|
@@ -309,19 +410,6 @@ class TestCornflowClientAdmin(TestCornflowClientBasic):
|
|
309
410
|
def setUp(self, create_all=False):
|
310
411
|
super().setUp()
|
311
412
|
|
312
|
-
# we create a service user:
|
313
|
-
self.create_service_user(
|
314
|
-
dict(username="airflow", pwd="Airflow_test_password1", email="af@cf.com")
|
315
|
-
)
|
316
|
-
|
317
|
-
self.create_service_user(
|
318
|
-
dict(
|
319
|
-
username="service_user@cornflow.com",
|
320
|
-
pwd="Serviceuser_1234",
|
321
|
-
email="service_user@cornflow.com",
|
322
|
-
)
|
323
|
-
)
|
324
|
-
|
325
413
|
# we create an admin user
|
326
414
|
# we guarantee that the admin is there for airflow
|
327
415
|
self.client.token = self.create_admin(
|
@@ -404,7 +492,7 @@ class TestCornflowClientAdmin(TestCornflowClientBasic):
|
|
404
492
|
self.assertIsNone(execution_data["data"])
|
405
493
|
|
406
494
|
def test_edit_one_execution(self):
|
407
|
-
one_instance = self.create_new_instance(
|
495
|
+
one_instance = self.create_new_instance(INSTANCE_MPS)
|
408
496
|
payload = dict(
|
409
497
|
name="bla",
|
410
498
|
config=dict(solver="CBC"),
|
@@ -455,7 +543,7 @@ class TestCornflowClientAdmin(TestCornflowClientBasic):
|
|
455
543
|
self.assertRaises(CornFlowApiError, _launch_too_soon_func)
|
456
544
|
|
457
545
|
def test_check_instance(self):
|
458
|
-
instance = self.create_new_instance(
|
546
|
+
instance = self.create_new_instance(INSTANCE_MPS)
|
459
547
|
data_check_execution = self.client.create_instance_data_check(instance["id"])
|
460
548
|
self.assertEqual(data_check_execution["instance_id"], instance["id"])
|
461
549
|
status = self.client.get_status(data_check_execution["id"])
|
@@ -1,6 +1,10 @@
|
|
1
1
|
"""
|
2
2
|
|
3
3
|
"""
|
4
|
+
|
5
|
+
import unittest
|
6
|
+
import os
|
7
|
+
|
4
8
|
# Imports from internal modules
|
5
9
|
from cornflow.models import AlarmsModel
|
6
10
|
from cornflow.tests.const import ALARMS_URL
|
@@ -15,25 +19,34 @@ class TestAlarmsEndpoint(CustomTestCase):
|
|
15
19
|
self.response_items = {"id", "name", "description", "criticality", "schema"}
|
16
20
|
self.items_to_check = ["name", "description", "schema", "criticality"]
|
17
21
|
|
22
|
+
@unittest.skipUnless(
|
23
|
+
int(os.getenv("CF_ALARMS_ENDPOINT")) == 1, "No alarms implemented"
|
24
|
+
)
|
18
25
|
def test_post_alarm(self):
|
19
|
-
payload = {
|
26
|
+
payload = {
|
27
|
+
"name": "Alarm 1",
|
28
|
+
"description": "Description Alarm 1",
|
29
|
+
"criticality": 1,
|
30
|
+
}
|
20
31
|
self.create_new_row(self.url, self.model, payload)
|
21
32
|
|
33
|
+
@unittest.skipUnless(
|
34
|
+
int(os.getenv("CF_ALARMS_ENDPOINT")) == 1, "No alarms implemented"
|
35
|
+
)
|
22
36
|
def test_get_alarms(self):
|
23
37
|
data = [
|
24
38
|
{"name": "Alarm 1", "description": "Description Alarm 1", "criticality": 1},
|
25
|
-
{
|
39
|
+
{
|
40
|
+
"name": "Alarm 2",
|
41
|
+
"description": "Description Alarm 2",
|
42
|
+
"criticality": 2,
|
43
|
+
"schema": "solve_model_dag",
|
44
|
+
},
|
26
45
|
]
|
27
|
-
rows = self.get_rows(
|
28
|
-
self.url,
|
29
|
-
data,
|
30
|
-
check_data=False
|
31
|
-
)
|
46
|
+
rows = self.get_rows(self.url, data, check_data=False)
|
32
47
|
rows_data = list(rows.json)
|
33
48
|
for i in range(len(data)):
|
34
49
|
for key in self.get_keys_to_check(data[i]):
|
35
50
|
self.assertIn(key, rows_data[i])
|
36
51
|
if key in data[i]:
|
37
52
|
self.assertEqual(rows_data[i][key], data[i][key])
|
38
|
-
|
39
|
-
|
cornflow/tests/unit/test_cli.py
CHANGED
@@ -20,6 +20,11 @@ from cornflow.shared.exceptions import NoPermission, ObjectDoesNotExist
|
|
20
20
|
class CLITests(TestCase):
|
21
21
|
def setUp(self):
|
22
22
|
db.create_all()
|
23
|
+
self.number_of_views = 52
|
24
|
+
self.number_of_permissions = 574
|
25
|
+
if int(os.getenv("CF_ALARMS_ENDPOINT", 0)) != 1:
|
26
|
+
self.number_of_views = 50
|
27
|
+
self.number_of_permissions = 519
|
23
28
|
|
24
29
|
def tearDown(self):
|
25
30
|
db.session.remove()
|
@@ -131,7 +136,7 @@ class CLITests(TestCase):
|
|
131
136
|
result = runner.invoke(cli, ["views", "init", "-v"])
|
132
137
|
self.assertEqual(result.exit_code, 0)
|
133
138
|
views = ViewModel.get_all_objects().all()
|
134
|
-
self.assertEqual(len(views),
|
139
|
+
self.assertEqual(len(views), self.number_of_views)
|
135
140
|
|
136
141
|
def test_permissions_entrypoint(self):
|
137
142
|
runner = CliRunner()
|
@@ -155,8 +160,8 @@ class CLITests(TestCase):
|
|
155
160
|
permissions = PermissionViewRoleModel.get_all_objects().all()
|
156
161
|
self.assertEqual(len(actions), 5)
|
157
162
|
self.assertEqual(len(roles), 4)
|
158
|
-
self.assertEqual(len(views),
|
159
|
-
self.assertEqual(len(permissions),
|
163
|
+
self.assertEqual(len(views), self.number_of_views)
|
164
|
+
self.assertEqual(len(permissions), self.number_of_permissions)
|
160
165
|
|
161
166
|
def test_permissions_base_command(self):
|
162
167
|
runner = CliRunner()
|
@@ -171,8 +176,8 @@ class CLITests(TestCase):
|
|
171
176
|
permissions = PermissionViewRoleModel.get_all_objects().all()
|
172
177
|
self.assertEqual(len(actions), 5)
|
173
178
|
self.assertEqual(len(roles), 4)
|
174
|
-
self.assertEqual(len(views),
|
175
|
-
self.assertEqual(len(permissions),
|
179
|
+
self.assertEqual(len(views), self.number_of_views)
|
180
|
+
self.assertEqual(len(permissions), self.number_of_permissions)
|
176
181
|
|
177
182
|
def test_service_entrypoint(self):
|
178
183
|
runner = CliRunner()
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import json
|
2
|
-
|
2
|
+
import os
|
3
3
|
from flask_testing import TestCase
|
4
4
|
|
5
5
|
from cornflow.app import (
|
@@ -48,7 +48,11 @@ class TestCommands(TestCase):
|
|
48
48
|
"email": "testemail@test.org",
|
49
49
|
"password": "Testpassword1!",
|
50
50
|
}
|
51
|
-
|
51
|
+
|
52
|
+
if int(os.getenv("CF_ALARMS_ENDPOINT")) == 1:
|
53
|
+
self.resources = resources + alarms_resources
|
54
|
+
else:
|
55
|
+
self.resources = resources
|
52
56
|
self.runner = self.create_app().test_cli_runner()
|
53
57
|
self.runner.invoke(register_roles, ["-v"])
|
54
58
|
|
@@ -57,6 +57,7 @@ class TestExecutionsListEndpoint(BaseTestCases.ListFilters):
|
|
57
57
|
"instance_id",
|
58
58
|
"name",
|
59
59
|
"indicators",
|
60
|
+
"reports",
|
60
61
|
]
|
61
62
|
|
62
63
|
def test_new_execution(self):
|
@@ -260,6 +261,7 @@ class TestExecutionsDetailEndpointMock(CustomTestCase):
|
|
260
261
|
"schema",
|
261
262
|
"user_id",
|
262
263
|
"indicators",
|
264
|
+
"reports",
|
263
265
|
}
|
264
266
|
# we only check the following because this endpoint does not return data
|
265
267
|
self.items_to_check = ["name", "description"]
|
@@ -303,6 +305,7 @@ class TestExecutionsDetailEndpoint(
|
|
303
305
|
"name",
|
304
306
|
"created_at",
|
305
307
|
"state",
|
308
|
+
"reports",
|
306
309
|
]
|
307
310
|
execution = self.get_one_row(
|
308
311
|
self.url + idx,
|
@@ -408,6 +411,7 @@ class TestExecutionsDataEndpoint(TestExecutionsDetailEndpointMock):
|
|
408
411
|
"state",
|
409
412
|
"name",
|
410
413
|
"id",
|
414
|
+
"reports",
|
411
415
|
]
|
412
416
|
|
413
417
|
def test_get_one_execution(self):
|
@@ -450,6 +454,7 @@ class TestExecutionsLogEndpoint(TestExecutionsDetailEndpointMock):
|
|
450
454
|
"user_id",
|
451
455
|
"config",
|
452
456
|
"indicators",
|
457
|
+
"reports",
|
453
458
|
]
|
454
459
|
|
455
460
|
def test_get_one_execution(self):
|
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
"""
|
4
4
|
|
5
|
+
import unittest
|
6
|
+
import os
|
5
7
|
import json
|
6
8
|
|
7
9
|
# Imports from internal modules
|
@@ -29,6 +31,9 @@ class TestMainAlarmsEndpoint(CustomTestCase):
|
|
29
31
|
headers=self.get_header_with_auth(self.token),
|
30
32
|
).json["id"]
|
31
33
|
|
34
|
+
@unittest.skipUnless(
|
35
|
+
int(os.getenv("CF_ALARMS_ENDPOINT")) == 1, "No alarms implemented"
|
36
|
+
)
|
32
37
|
def test_post_main_alarm(self):
|
33
38
|
payload = {
|
34
39
|
"message": "Message Main Alarm 1",
|
@@ -37,6 +42,9 @@ class TestMainAlarmsEndpoint(CustomTestCase):
|
|
37
42
|
}
|
38
43
|
self.create_new_row(self.url, self.model, payload)
|
39
44
|
|
45
|
+
@unittest.skipUnless(
|
46
|
+
int(os.getenv("CF_ALARMS_ENDPOINT")) == 1, "No alarms implemented"
|
47
|
+
)
|
40
48
|
def test_get_main_alarms(self):
|
41
49
|
data = [
|
42
50
|
{
|