wiliot-certificate 4.5.0__py3-none-any.whl → 4.5.0a2__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.
- certificate/ag/wlt_types_ag_jsons/brg2brg_ota.json +211 -0
- certificate/ag/wlt_types_ag_jsons/brg2gw_hb.json +894 -0
- certificate/ag/wlt_types_ag_jsons/brg2gw_hb_sleep.json +184 -0
- certificate/ag/wlt_types_ag_jsons/calibration.json +490 -0
- certificate/ag/wlt_types_ag_jsons/custom.json +614 -0
- certificate/ag/wlt_types_ag_jsons/datapath.json +900 -0
- certificate/ag/wlt_types_ag_jsons/energy2400.json +670 -0
- certificate/ag/wlt_types_ag_jsons/energySub1g.json +691 -0
- certificate/ag/wlt_types_ag_jsons/externalSensor.json +727 -0
- certificate/ag/wlt_types_ag_jsons/interface.json +1095 -0
- certificate/ag/wlt_types_ag_jsons/powerManagement.json +1439 -0
- certificate/ag/wlt_types_ag_jsons/side_info_sensor.json +105 -0
- certificate/ag/wlt_types_ag_jsons/signal_indicator_data.json +77 -0
- certificate/ag/wlt_types_ag_jsons/unified_echo_ext_pkt.json +126 -0
- certificate/ag/wlt_types_ag_jsons/unified_echo_pkt.json +175 -0
- certificate/ag/wlt_types_ag_jsons/unified_sensor_pkt.json +65 -0
- certificate/cert_common.py +35 -65
- certificate/cert_config.py +18 -43
- certificate/cert_data_sim.py +9 -12
- certificate/cert_defines.py +0 -8
- certificate/cert_gw_sim.py +7 -32
- certificate/cert_mqtt.py +5 -15
- certificate/cert_prints.py +0 -1
- certificate/cert_results.py +37 -48
- certificate/cert_utils.py +15 -24
- certificate/certificate.py +5 -12
- certificate/certificate_cli.py +13 -10
- certificate/certificate_eth_test_list.txt +3 -4
- certificate/certificate_sanity_test_list.txt +2 -3
- certificate/certificate_test_list.txt +4 -4
- certificate/tests/calibration/interval_test/interval_test.json +0 -1
- certificate/tests/calibration/output_power_test/output_power_test.json +0 -1
- certificate/tests/calibration/pattern_test/pattern_test.json +0 -1
- certificate/tests/cloud_connectivity/acl_ext_adv_test/acl_ext_adv_test.json +0 -1
- certificate/tests/cloud_connectivity/acl_test/acl_test.json +0 -1
- certificate/tests/cloud_connectivity/acl_test/acl_test.py +15 -13
- certificate/tests/cloud_connectivity/brg_ota_test/brg_ota_test.json +1 -2
- certificate/tests/cloud_connectivity/brg_ota_test/brg_ota_test.py +6 -8
- certificate/tests/cloud_connectivity/channel_scan_behaviour_test/channel_scan_behaviour_test.json +0 -1
- certificate/tests/cloud_connectivity/channel_scan_behaviour_test/channel_scan_behaviour_test.py +3 -3
- certificate/tests/cloud_connectivity/connection_test/connection_test.json +0 -1
- certificate/tests/cloud_connectivity/connection_test/connection_test.py +13 -6
- certificate/tests/cloud_connectivity/deduplication_test/deduplication_test.json +0 -1
- certificate/tests/cloud_connectivity/deduplication_test/deduplication_test.py +11 -6
- certificate/tests/cloud_connectivity/downlink_test/downlink_test.json +0 -1
- certificate/tests/cloud_connectivity/downlink_test/downlink_test.py +4 -1
- certificate/tests/cloud_connectivity/ext_adv_stress_test/ext_adv_stress_test.json +0 -1
- certificate/tests/cloud_connectivity/ext_adv_stress_test/ext_adv_stress_test.py +9 -14
- certificate/tests/cloud_connectivity/reboot_test/reboot_test.json +0 -1
- certificate/tests/cloud_connectivity/reboot_test/reboot_test.py +0 -2
- certificate/tests/cloud_connectivity/registration_test/registration_test.json +0 -1
- certificate/tests/cloud_connectivity/registration_test/registration_test_cli.py +1 -1
- certificate/tests/cloud_connectivity/stress_test/stress_test.json +0 -1
- certificate/tests/cloud_connectivity/stress_test/stress_test.py +11 -15
- certificate/tests/cloud_connectivity/uplink_ext_adv_test/uplink_ext_adv_test.json +0 -1
- certificate/tests/cloud_connectivity/uplink_ext_adv_test/uplink_ext_adv_test.py +2 -1
- certificate/tests/cloud_connectivity/uplink_test/uplink_test.json +0 -1
- certificate/tests/cloud_connectivity/uplink_test/uplink_test.py +20 -27
- certificate/tests/datapath/aging_test/aging_test.json +0 -1
- certificate/tests/datapath/aging_test/aging_test.py +3 -7
- certificate/tests/datapath/event_ble5_test/event_ble5_test.json +2 -3
- certificate/tests/datapath/event_ble5_test/event_ble5_test.py +13 -7
- certificate/tests/datapath/event_test/event_test.json +2 -3
- certificate/tests/datapath/event_test/event_test.py +10 -5
- certificate/tests/datapath/num_of_tags_test/num_of_tags_test.json +1 -2
- certificate/tests/datapath/num_of_tags_test/num_of_tags_test.py +5 -9
- certificate/tests/datapath/output_power_test/output_power_test.json +0 -1
- certificate/tests/datapath/pacer_interval_ble5_test/pacer_interval_ble5_test.json +0 -1
- certificate/tests/datapath/pacer_interval_ble5_test/pacer_interval_ble5_test.py +4 -4
- certificate/tests/datapath/pacer_interval_test/pacer_interval_test.json +0 -1
- certificate/tests/datapath/pattern_test/pattern_test.json +0 -1
- certificate/tests/datapath/pkt_filter_ble5_chl21_test/pkt_filter_ble5_chl21_test.json +0 -1
- certificate/tests/datapath/pkt_filter_ble5_chl21_test/pkt_filter_ble5_chl21_test.py +5 -5
- certificate/tests/datapath/pkt_filter_ble5_test/pkt_filter_ble5_test.json +0 -1
- certificate/tests/datapath/pkt_filter_ble5_test/pkt_filter_ble5_test.py +5 -5
- certificate/tests/datapath/pkt_filter_brg2gw_ext_adv_test/pkt_filter_brg2gw_ext_adv_test.json +0 -1
- certificate/tests/datapath/pkt_filter_brg2gw_ext_adv_test/pkt_filter_brg2gw_ext_adv_test.py +8 -10
- certificate/tests/datapath/pkt_filter_gen3_test/pkt_filter_gen3_test.json +0 -1
- certificate/tests/datapath/pkt_filter_test/pkt_filter_test.json +0 -1
- certificate/tests/datapath/rssi_threshold_test/rssi_threshold_test.json +0 -1
- certificate/tests/datapath/rx_channel_hopping_test/rx_channel_hopping_test.json +0 -1
- certificate/tests/datapath/rx_channel_test/rx_channel_test.json +0 -1
- certificate/tests/datapath/rx_rate_gen2_test/rx_rate_gen2_test.json +0 -1
- certificate/tests/datapath/rx_rate_gen2_test/rx_rate_gen2_test.py +1 -1
- certificate/tests/datapath/rx_rate_gen3_test/rx_rate_gen3_test.json +0 -1
- certificate/tests/datapath/stress_gen3_test/stress_gen3_test.json +0 -1
- certificate/tests/datapath/stress_gen3_test/stress_gen3_test.py +0 -3
- certificate/tests/datapath/stress_test/stress_test.json +0 -1
- certificate/tests/datapath/stress_test/stress_test.py +0 -3
- certificate/tests/datapath/tx_repetition_test/tx_repetition_test.json +0 -1
- certificate/tests/edge_mgmt/action_blink_test/action_blink_test.json +0 -1
- certificate/tests/edge_mgmt/action_get_battery_sensor_test/action_get_battery_sensor_test.json +0 -1
- certificate/tests/edge_mgmt/action_get_module_test/action_get_module_test.json +0 -1
- certificate/tests/edge_mgmt/action_get_pof_data_test/action_get_pof_data_test.json +0 -1
- certificate/tests/edge_mgmt/action_gw_hb_test/action_gw_hb_test.json +0 -1
- certificate/tests/edge_mgmt/action_reboot_test/action_reboot_test.json +0 -1
- certificate/tests/edge_mgmt/action_restore_defaults_test/action_restore_defaults_test.json +0 -1
- certificate/tests/edge_mgmt/action_send_hb_test/action_send_hb_test.json +0 -1
- certificate/tests/edge_mgmt/action_send_hb_test/action_send_hb_test.py +14 -18
- certificate/tests/edge_mgmt/periodic_msgs_test/periodic_msgs_test.json +0 -1
- certificate/tests/energy2400/duty_cycle_test/duty_cycle_test.json +0 -1
- certificate/tests/energy2400/output_power_test/output_power_test.json +0 -1
- certificate/tests/energy2400/pattern_test/pattern_test.json +0 -1
- certificate/tests/energy2400/signal_indicator_ble5_test/signal_indicator_ble5_test.json +0 -1
- certificate/tests/energy2400/signal_indicator_ble5_test/signal_indicator_ble5_test.py +3 -4
- certificate/tests/energy2400/signal_indicator_ext_adv_test/signal_indicator_ext_adv_test.json +9 -9
- certificate/tests/energy2400/signal_indicator_ext_adv_test/signal_indicator_ext_adv_test.py +271 -113
- certificate/tests/energy2400/signal_indicator_test/signal_indicator_test.json +0 -1
- certificate/tests/energy2400/signal_indicator_test/signal_indicator_test.py +1 -1
- certificate/tests/energy_sub1g/duty_cycle_test/duty_cycle_test.json +0 -1
- certificate/tests/energy_sub1g/pattern_test/pattern_test.json +0 -1
- certificate/tests/pwr_mgmt/pwr_mgmt_test/pwr_mgmt_test.json +0 -1
- certificate/tests/sensors/ext_sensor_test/ext_sensor_test.json +0 -1
- certificate/tests/sensors/ext_sensor_test/ext_sensor_test.py +9 -4
- common/api_if/api_validation.py +0 -6
- common/web/templates/generator.html +79 -141
- common/web/web_utils.py +56 -78
- gui_certificate/server.py +78 -283
- gui_certificate/templates/cert_run.html +113 -179
- {wiliot_certificate-4.5.0.dist-info → wiliot_certificate-4.5.0a2.dist-info}/METADATA +22 -7
- {wiliot_certificate-4.5.0.dist-info → wiliot_certificate-4.5.0a2.dist-info}/RECORD +125 -109
- {wiliot_certificate-4.5.0.dist-info → wiliot_certificate-4.5.0a2.dist-info}/WHEEL +0 -0
- {wiliot_certificate-4.5.0.dist-info → wiliot_certificate-4.5.0a2.dist-info}/entry_points.txt +0 -0
- {wiliot_certificate-4.5.0.dist-info → wiliot_certificate-4.5.0a2.dist-info}/licenses/LICENSE +0 -0
- {wiliot_certificate-4.5.0.dist-info → wiliot_certificate-4.5.0a2.dist-info}/top_level.txt +0 -0
gui_certificate/server.py
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import json
|
|
3
3
|
import tempfile
|
|
4
|
-
import
|
|
5
|
-
from flask import Flask, render_template, request, session, redirect, url_for, flash, send_file
|
|
4
|
+
from flask import Flask, render_template, request, session, redirect, url_for, flash, send_file, jsonify
|
|
6
5
|
from jinja2 import ChoiceLoader, PackageLoader
|
|
7
6
|
from werkzeug.utils import secure_filename
|
|
8
7
|
from certificate.certificate_cli import CertificateCLI
|
|
@@ -32,23 +31,9 @@ TEMP_BASE = tempfile.gettempdir()
|
|
|
32
31
|
UPLOAD_FOLDER = os.path.join(TEMP_BASE, "wiliot_certificate_uploaded_schemas")
|
|
33
32
|
CONFIG_FOLDER = os.path.join(TEMP_BASE, "wiliot_certificate_saved_configs")
|
|
34
33
|
TEST_LIST_FOLDER = os.path.join(TEMP_BASE, "wiliot_certificate_test_lists")
|
|
35
|
-
CUSTOM_BROKER_FOLDER = os.path.join(TEMP_BASE, "wiliot_certificate_custom_brokers")
|
|
36
34
|
ALLOWED_EXTENSIONS = {'json'}
|
|
37
35
|
MAX_UPLOAD_SIZE = 16 * 1024 * 1024 # 16MB
|
|
38
36
|
|
|
39
|
-
# Default custom broker configuration (from hivemq.json)
|
|
40
|
-
DEFAULT_CUSTOM_BROKER = {
|
|
41
|
-
"port": 8883,
|
|
42
|
-
"brokerUrl": "mqtts://broker.hivemq.com",
|
|
43
|
-
"username": "",
|
|
44
|
-
"password": "",
|
|
45
|
-
"ownerId": "wiliot"
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
CUSTOM_BROKER_HELP = {
|
|
49
|
-
"ownerId": "Used to construct topics, e.g.: data-v2/<ownerId>/<gatewayId>"
|
|
50
|
-
}
|
|
51
|
-
|
|
52
37
|
app = Flask(__name__)
|
|
53
38
|
app.secret_key = os.urandom(24) # Required for sessions
|
|
54
39
|
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
|
|
@@ -58,7 +43,6 @@ app.config['MAX_CONTENT_LENGTH'] = MAX_UPLOAD_SIZE
|
|
|
58
43
|
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
|
|
59
44
|
os.makedirs(CONFIG_FOLDER, exist_ok=True)
|
|
60
45
|
os.makedirs(TEST_LIST_FOLDER, exist_ok=True)
|
|
61
|
-
os.makedirs(CUSTOM_BROKER_FOLDER, exist_ok=True)
|
|
62
46
|
|
|
63
47
|
# extend Jinja search path to include shared dir
|
|
64
48
|
app.jinja_loader = ChoiceLoader([
|
|
@@ -86,32 +70,9 @@ def get_mandatory_modules_for_flavor(flavor):
|
|
|
86
70
|
return [MODULE_CLOUD_CONNECTIVITY, MODULE_EDGE_MGMT]
|
|
87
71
|
return []
|
|
88
72
|
|
|
89
|
-
def get_mandatory_modules_by_schema(schema_data, flavor):
|
|
90
|
-
"""Get modules that are mandatory by schema (modules declared in schema)."""
|
|
91
|
-
if not schema_data or "modules" not in schema_data:
|
|
92
|
-
return []
|
|
93
|
-
|
|
94
|
-
# Only apply to bridge flavors (bridge_only and combo)
|
|
95
|
-
if flavor not in (FLAVOR_BRIDGE_ONLY, FLAVOR_COMBO):
|
|
96
|
-
return []
|
|
97
|
-
|
|
98
|
-
schema_modules = schema_data.get("modules", {})
|
|
99
|
-
if not isinstance(schema_modules, dict):
|
|
100
|
-
return []
|
|
101
|
-
|
|
102
|
-
# Map schema module names to test module names
|
|
103
|
-
mandatory_by_schema = []
|
|
104
|
-
for schema_mod_name in schema_modules.keys():
|
|
105
|
-
# Map schema module name to test module name
|
|
106
|
-
test_mod_name = test_module_and_schema_module_to_other(schema_mod_name)
|
|
107
|
-
if test_mod_name not in mandatory_by_schema and test_mod_name != 'custom':
|
|
108
|
-
mandatory_by_schema.append(test_mod_name)
|
|
109
|
-
|
|
110
|
-
return mandatory_by_schema
|
|
111
|
-
|
|
112
73
|
# TODO: This is a temporary mapping to map test module names to schema module names - remove this
|
|
113
|
-
def
|
|
114
|
-
"""Map test module names
|
|
74
|
+
def test_module_to_schema_module(test_module_name):
|
|
75
|
+
"""Map test module names to validation schema module names."""
|
|
115
76
|
mapping = {
|
|
116
77
|
"calibration": "calibration",
|
|
117
78
|
"datapath": "datapath",
|
|
@@ -121,12 +82,7 @@ def test_module_and_schema_module_to_other(module_name):
|
|
|
121
82
|
"sensors": "externalSensor", # different name
|
|
122
83
|
"custom": "custom"
|
|
123
84
|
}
|
|
124
|
-
|
|
125
|
-
if module_name == k:
|
|
126
|
-
return v
|
|
127
|
-
if module_name == v:
|
|
128
|
-
return k
|
|
129
|
-
return module_name # Return as-is if not in mapping
|
|
85
|
+
return mapping.get(test_module_name, test_module_name) # Return as-is if not in mapping
|
|
130
86
|
|
|
131
87
|
def filter_modules_by_flavor(tests_schema, flavor, schema_data=None):
|
|
132
88
|
"""Filter modules and tests based on selected flavor."""
|
|
@@ -159,17 +115,12 @@ def filter_modules_by_flavor(tests_schema, flavor, schema_data=None):
|
|
|
159
115
|
# Include all tests for combo
|
|
160
116
|
filtered_tests.append(test)
|
|
161
117
|
|
|
162
|
-
#
|
|
163
|
-
mandatory_by_schema = get_mandatory_modules_by_schema(schema_data, flavor) if schema_data else []
|
|
164
|
-
is_mandatory_by_schema = mod_name in mandatory_by_schema
|
|
165
|
-
|
|
166
|
-
# Only include module if it has tests or is mandatory (by flavor or schema)
|
|
118
|
+
# Only include module if it has tests or is mandatory
|
|
167
119
|
# For mandatory modules, include even if no tests match (they'll be shown but empty)
|
|
168
|
-
if filtered_tests or mod_name in mandatory_modules
|
|
120
|
+
if filtered_tests or mod_name in mandatory_modules:
|
|
169
121
|
mod_copy = mod.copy()
|
|
170
122
|
mod_copy["tests"] = filtered_tests
|
|
171
123
|
mod_copy["is_mandatory"] = mod_name in mandatory_modules
|
|
172
|
-
mod_copy["is_mandatory_by_schema"] = is_mandatory_by_schema
|
|
173
124
|
filtered_modules.append(mod_copy)
|
|
174
125
|
|
|
175
126
|
# Sort modules: cloud_connectivity first, then edge_mgmt, then by schema order
|
|
@@ -185,7 +136,7 @@ def filter_modules_by_flavor(tests_schema, flavor, schema_data=None):
|
|
|
185
136
|
if schema_module_order:
|
|
186
137
|
try:
|
|
187
138
|
# Map test module name to schema module name
|
|
188
|
-
schema_mod_name =
|
|
139
|
+
schema_mod_name = test_module_to_schema_module(mod_name)
|
|
189
140
|
idx = schema_module_order.index(schema_mod_name)
|
|
190
141
|
return (2, idx)
|
|
191
142
|
except ValueError:
|
|
@@ -334,37 +285,30 @@ def verify_schema_matches_selection(schema_data, flavor, selected_modules, selec
|
|
|
334
285
|
bridge_modules_to_check = [m for m in selected_modules if m not in (MODULE_CLOUD_CONNECTIVITY, MODULE_EDGE_MGMT)]
|
|
335
286
|
for test_mod_name in bridge_modules_to_check:
|
|
336
287
|
# Map test module name to schema module name
|
|
337
|
-
schema_mod_name =
|
|
288
|
+
schema_mod_name = test_module_to_schema_module(test_mod_name)
|
|
338
289
|
if schema_mod_name not in schema_module_names:
|
|
339
290
|
warnings.append(f"Module '{test_mod_name}' may not be supported according to the uploaded schema")
|
|
340
291
|
|
|
341
292
|
return len(errors) == 0, errors, warnings
|
|
342
293
|
|
|
343
|
-
def check_certification_status(flavor, selected_modules, selected_tests, tests_schema
|
|
294
|
+
def check_certification_status(flavor, selected_modules, selected_tests, tests_schema):
|
|
344
295
|
"""Check if the selection qualifies for certification or is test-only."""
|
|
345
296
|
mandatory_modules = get_mandatory_modules_for_flavor(flavor)
|
|
346
|
-
mandatory_by_schema = get_mandatory_modules_by_schema(schema_data, flavor) if schema_data else []
|
|
347
297
|
all_mandatory_tests = []
|
|
348
298
|
|
|
349
|
-
# Get
|
|
350
|
-
selected_module_names = [m.get("name") if isinstance(m, dict) else m for m in selected_modules]
|
|
351
|
-
|
|
352
|
-
# Get all mandatory tests from ALL selected modules (not just mandatory modules)
|
|
353
|
-
# When a module is selected, its mandatory tests become mandatory
|
|
299
|
+
# Get all mandatory tests from mandatory modules
|
|
354
300
|
for mod in tests_schema.get("modules", []):
|
|
355
301
|
mod_name = mod.get("name", "")
|
|
356
|
-
if mod_name in
|
|
302
|
+
if mod_name in mandatory_modules:
|
|
357
303
|
for test in mod.get("tests", []):
|
|
358
304
|
if test.get("meta", {}).get("mandatory", 0) == 1:
|
|
359
305
|
all_mandatory_tests.append(test.get("id"))
|
|
360
306
|
|
|
361
307
|
# Check if all mandatory modules are selected
|
|
308
|
+
selected_module_names = [m.get("name") if isinstance(m, dict) else m for m in selected_modules]
|
|
362
309
|
missing_modules = [m for m in mandatory_modules if m not in selected_module_names]
|
|
363
310
|
|
|
364
|
-
# Check if all
|
|
365
|
-
missing_modules_by_schema = [m for m in mandatory_by_schema if m not in selected_module_names]
|
|
366
|
-
|
|
367
|
-
# Check if all mandatory tests (from selected modules) are selected
|
|
311
|
+
# Check if all mandatory tests are selected
|
|
368
312
|
missing_tests = [t for t in all_mandatory_tests if t not in selected_tests]
|
|
369
313
|
|
|
370
314
|
# Check for "at least one additional module" requirement for Bridge Only and Combo
|
|
@@ -375,11 +319,9 @@ def check_certification_status(flavor, selected_modules, selected_tests, tests_s
|
|
|
375
319
|
if len(additional_modules) == 0:
|
|
376
320
|
missing_additional_module = True
|
|
377
321
|
|
|
378
|
-
|
|
379
|
-
is_certified = (len(missing_modules) == 0 and len(missing_modules_by_schema) == 0 and
|
|
380
|
-
len(missing_tests) == 0 and not missing_additional_module and not unsterile_run)
|
|
322
|
+
is_certified = len(missing_modules) == 0 and len(missing_tests) == 0 and not missing_additional_module
|
|
381
323
|
|
|
382
|
-
return is_certified, missing_modules, missing_tests, missing_additional_module
|
|
324
|
+
return is_certified, missing_modules, missing_tests, missing_additional_module
|
|
383
325
|
|
|
384
326
|
def _prepare_form_data_for_template(session, cert_schema):
|
|
385
327
|
"""Prepare form_data for template, ensuring custom_broker_path is included if available."""
|
|
@@ -446,18 +388,15 @@ def _sort_tests_by_module_priority(test_ids: list[str]) -> list[str]:
|
|
|
446
388
|
Test ID format: 'module/test_name'
|
|
447
389
|
"""
|
|
448
390
|
def test_sort_key(test_id: str):
|
|
449
|
-
module
|
|
450
|
-
#
|
|
451
|
-
if module == MODULE_CLOUD_CONNECTIVITY and "connection" in test_name.lower():
|
|
452
|
-
return (0, test_id)
|
|
453
|
-
# other cloud_connectivity tests
|
|
391
|
+
module = test_id.split('/')[0] if '/' in test_id else test_id
|
|
392
|
+
# cloud_connectivity first
|
|
454
393
|
if module == MODULE_CLOUD_CONNECTIVITY:
|
|
455
|
-
return (
|
|
394
|
+
return (0, test_id)
|
|
456
395
|
# edge_mgmt second
|
|
457
396
|
if module == MODULE_EDGE_MGMT:
|
|
458
|
-
return (
|
|
397
|
+
return (1, test_id)
|
|
459
398
|
# Others last
|
|
460
|
-
return (
|
|
399
|
+
return (2, test_id)
|
|
461
400
|
|
|
462
401
|
return sorted(test_ids, key=test_sort_key)
|
|
463
402
|
|
|
@@ -477,65 +416,14 @@ def _write_testlist(selected_ids: list[str], form_data=None, is_certified=False)
|
|
|
477
416
|
f.write("# NON-CERTIFYING RUN (mandatory tests/modules missing)\n")
|
|
478
417
|
for test_id in sorted_test_ids:
|
|
479
418
|
tid_safe = test_id.replace('/', '_')
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
dynamic_param = form_data.get(dynamic_param_key) if form_data else None
|
|
483
|
-
|
|
484
|
-
if dynamic_param is not None and dynamic_param != "":
|
|
485
|
-
# Use dynamic parameter value
|
|
486
|
-
params = [str(dynamic_param)]
|
|
487
|
-
else:
|
|
488
|
-
# Use regular parameter array
|
|
489
|
-
param_key = f"params_{tid_safe}[]"
|
|
490
|
-
params = form_data.getlist(param_key) if form_data else [] # list[str]
|
|
419
|
+
param_key = f"params_{tid_safe}[]"
|
|
420
|
+
params = form_data.getlist(param_key) if form_data else [] # list[str]
|
|
491
421
|
# Example line format: "<module/test> <param1> <param2> ..."
|
|
492
422
|
line = " ".join([test_id] + params)
|
|
493
423
|
f.write(line + "\n")
|
|
494
424
|
print(f"Custom test list saved in {path}")
|
|
495
425
|
return path
|
|
496
426
|
|
|
497
|
-
def _write_custom_broker_config(form_data, cert_schema_title="cert_run") -> str:
|
|
498
|
-
"""
|
|
499
|
-
Generate a custom broker JSON configuration file from form data.
|
|
500
|
-
Extracts broker field values and creates a JSON file matching hivemq.json format.
|
|
501
|
-
"""
|
|
502
|
-
# Extract broker configuration from form_data
|
|
503
|
-
broker_config = {}
|
|
504
|
-
|
|
505
|
-
# Field names follow pattern: {schema_title}_custom_broker_{field_name}
|
|
506
|
-
field_prefix = f"{cert_schema_title}_custom_broker_"
|
|
507
|
-
|
|
508
|
-
# Extract values from form_data, using defaults if not provided
|
|
509
|
-
for field in DEFAULT_CUSTOM_BROKER.keys():
|
|
510
|
-
field_name = f"{field_prefix}{field}"
|
|
511
|
-
value = form_data.get(field_name, "")
|
|
512
|
-
|
|
513
|
-
if field == "port":
|
|
514
|
-
# Convert port to int if it's a number
|
|
515
|
-
try:
|
|
516
|
-
broker_config[field] = int(value) if value else DEFAULT_CUSTOM_BROKER[field]
|
|
517
|
-
except (ValueError, TypeError):
|
|
518
|
-
broker_config[field] = DEFAULT_CUSTOM_BROKER[field]
|
|
519
|
-
elif field == "ownerId":
|
|
520
|
-
# Convert ownerId to topics
|
|
521
|
-
broker_config[CUSTOM_BROKER_UPDATE_TOPIC] = f'update/{value}/<{GW_ID}>'
|
|
522
|
-
broker_config[CUSTOM_BROKER_DATA_TOPIC] = f'data/{value}/<{GW_ID}>'
|
|
523
|
-
broker_config[CUSTOM_BROKER_STATUS_TOPIC] = f'status/{value}/<{GW_ID}>'
|
|
524
|
-
else:
|
|
525
|
-
broker_config[field] = value
|
|
526
|
-
|
|
527
|
-
# Generate filename with timestamp
|
|
528
|
-
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
|
|
529
|
-
filename = f"custom_broker_{timestamp}.json"
|
|
530
|
-
filepath = os.path.join(CUSTOM_BROKER_FOLDER, filename)
|
|
531
|
-
|
|
532
|
-
# Write JSON file
|
|
533
|
-
with open(filepath, 'w', encoding='utf-8') as f:
|
|
534
|
-
json.dump(broker_config, f, indent=4)
|
|
535
|
-
|
|
536
|
-
print(f"Custom broker config saved in {filepath}")
|
|
537
|
-
return filepath
|
|
538
|
-
|
|
539
427
|
@app.route("/")
|
|
540
428
|
def index():
|
|
541
429
|
"""Redirect to step 1 or show current step."""
|
|
@@ -563,7 +451,6 @@ def step(step_num):
|
|
|
563
451
|
session['selected_modules'] = []
|
|
564
452
|
session['selected_tests'] = []
|
|
565
453
|
session['form_data'] = {}
|
|
566
|
-
session['schema_mandatory_initialized'] = False
|
|
567
454
|
|
|
568
455
|
title = "Run Certificate"
|
|
569
456
|
tests_schema = web_utils.scan_tests_dir(CERT_TESTS_ROOT)
|
|
@@ -618,22 +505,7 @@ def step(step_num):
|
|
|
618
505
|
flavor = session.get('flavor')
|
|
619
506
|
if 'selected_modules' not in session or not session.get('selected_modules'):
|
|
620
507
|
mandatory_modules = get_mandatory_modules_for_flavor(flavor)
|
|
621
|
-
|
|
622
|
-
schema_data = result # result is the validated schema data
|
|
623
|
-
mandatory_by_schema = get_mandatory_modules_by_schema(schema_data, flavor)
|
|
624
|
-
all_mandatory = list(set(mandatory_modules + mandatory_by_schema))
|
|
625
|
-
session['selected_modules'] = all_mandatory
|
|
626
|
-
# Mark schema-mandatory modules as initialized
|
|
627
|
-
session['schema_mandatory_initialized'] = True
|
|
628
|
-
else:
|
|
629
|
-
# If modules already exist, add schema-mandatory modules and mark as initialized
|
|
630
|
-
schema_data = result
|
|
631
|
-
mandatory_by_schema = get_mandatory_modules_by_schema(schema_data, flavor)
|
|
632
|
-
current_modules = session.get('selected_modules', [])
|
|
633
|
-
updated_modules = list(set(current_modules + mandatory_by_schema))
|
|
634
|
-
if len(updated_modules) > len(current_modules):
|
|
635
|
-
session['selected_modules'] = updated_modules
|
|
636
|
-
session['schema_mandatory_initialized'] = True
|
|
508
|
+
session['selected_modules'] = mandatory_modules
|
|
637
509
|
# For GW only, skip step 3 (modules)
|
|
638
510
|
if session.get('flavor') == FLAVOR_GW_ONLY:
|
|
639
511
|
session['current_step'] = 4
|
|
@@ -703,19 +575,43 @@ def step(step_num):
|
|
|
703
575
|
else:
|
|
704
576
|
form_data_dict[key] = request.form.get(key)
|
|
705
577
|
|
|
706
|
-
# Handle custom_broker
|
|
578
|
+
# Handle custom_broker file upload
|
|
707
579
|
cert_cli = CertificateCLI()
|
|
708
580
|
cert_schema = web_utils.parser_to_schema(cert_cli.parser)
|
|
709
581
|
custom_broker_field_name = f"{cert_schema['title']}_custom_broker"
|
|
582
|
+
custom_broker_file_key = f"{custom_broker_field_name}_file"
|
|
710
583
|
|
|
711
|
-
#
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
584
|
+
# Preserve existing custom_broker_path if no new file is uploaded
|
|
585
|
+
existing_custom_broker_path = session.get('custom_broker_path')
|
|
586
|
+
if existing_custom_broker_path:
|
|
587
|
+
form_data_dict[custom_broker_field_name] = existing_custom_broker_path
|
|
588
|
+
|
|
589
|
+
if custom_broker_file_key in request.files:
|
|
590
|
+
file = request.files[custom_broker_file_key]
|
|
591
|
+
if file and file.filename and allowed_file(file.filename):
|
|
592
|
+
filename = secure_filename(file.filename)
|
|
593
|
+
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
|
|
594
|
+
filename = f"{timestamp}_{filename}"
|
|
595
|
+
filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename)
|
|
596
|
+
file.save(filepath)
|
|
597
|
+
|
|
598
|
+
# Validate file is valid JSON
|
|
599
|
+
try:
|
|
600
|
+
with open(filepath, "r", encoding="utf-8") as f:
|
|
601
|
+
json.load(f)
|
|
602
|
+
# Store normalized path
|
|
603
|
+
normalized_path = os.path.normpath(filepath)
|
|
604
|
+
session['custom_broker_path'] = normalized_path
|
|
605
|
+
form_data_dict[custom_broker_field_name] = normalized_path
|
|
606
|
+
except json.JSONDecodeError as e:
|
|
607
|
+
error = f"Invalid JSON in custom broker file: {e}"
|
|
608
|
+
os.remove(filepath)
|
|
609
|
+
except Exception as e:
|
|
610
|
+
error = f"Error reading custom broker file: {e}"
|
|
611
|
+
if os.path.exists(filepath):
|
|
612
|
+
os.remove(filepath)
|
|
613
|
+
elif file and file.filename:
|
|
614
|
+
error = "Custom broker file must be a JSON file"
|
|
719
615
|
|
|
720
616
|
# Validate all required fields (required for moving forward, but allow going back)
|
|
721
617
|
if action == 'next':
|
|
@@ -735,22 +631,13 @@ def step(step_num):
|
|
|
735
631
|
field_name = f"{cert_schema['title']}_{field['name']}"
|
|
736
632
|
field_value = form_data_dict.get(field_name, '')
|
|
737
633
|
|
|
738
|
-
# Special handling for custom_broker
|
|
634
|
+
# Special handling for custom_broker file upload
|
|
739
635
|
if field['name'] == 'custom_broker':
|
|
740
|
-
# Check
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
if
|
|
745
|
-
broker_field_name = f"{broker_field_prefix}{broker_field_key}"
|
|
746
|
-
broker_field_value = form_data_dict.get(broker_field_name, '')
|
|
747
|
-
if not broker_field_value or (isinstance(broker_field_value, str) and not broker_field_value.strip()):
|
|
748
|
-
missing_required.append(f"custom_broker.{broker_field_key}")
|
|
749
|
-
break
|
|
750
|
-
# Also check if path was generated (should be generated above if fields are valid)
|
|
751
|
-
if not field_value and not session.get('custom_broker_path'):
|
|
752
|
-
# Only add if we haven't already added a broker field error
|
|
753
|
-
if not any('custom_broker.' in req for req in missing_required):
|
|
636
|
+
# Check if file was uploaded or path exists in session
|
|
637
|
+
custom_broker_file_key = f"{field_name}_file"
|
|
638
|
+
if custom_broker_file_key not in request.files or not request.files[custom_broker_file_key].filename:
|
|
639
|
+
# Check if path exists in form_data or session
|
|
640
|
+
if not field_value and not session.get('custom_broker_path'):
|
|
754
641
|
missing_required.append(field.get('name', field['label']))
|
|
755
642
|
else:
|
|
756
643
|
# For other fields, check if value is provided
|
|
@@ -794,30 +681,9 @@ def step(step_num):
|
|
|
794
681
|
# This ensures mandatory items are only pre-checked at the beginning
|
|
795
682
|
if flavor and not selected_modules:
|
|
796
683
|
mandatory_modules = get_mandatory_modules_for_flavor(flavor)
|
|
797
|
-
|
|
798
|
-
schema_data = load_schema_data(schema_path) if schema_path else None
|
|
799
|
-
mandatory_by_schema = get_mandatory_modules_by_schema(schema_data, flavor) if schema_data else []
|
|
800
|
-
all_mandatory = list(set(mandatory_modules + mandatory_by_schema))
|
|
801
|
-
selected_modules = all_mandatory
|
|
684
|
+
selected_modules = mandatory_modules
|
|
802
685
|
session['selected_modules'] = selected_modules
|
|
803
686
|
|
|
804
|
-
# Ensure schema-mandatory modules are added when first reaching step 3 (only if not already initialized)
|
|
805
|
-
# Use a session flag to track if schema-mandatory modules have been initialized
|
|
806
|
-
if step_num == 3 and flavor and schema_path:
|
|
807
|
-
schema_mandatory_initialized = session.get('schema_mandatory_initialized', False)
|
|
808
|
-
if not schema_mandatory_initialized:
|
|
809
|
-
schema_data = load_schema_data(schema_path) if schema_path else None
|
|
810
|
-
if schema_data:
|
|
811
|
-
mandatory_by_schema = get_mandatory_modules_by_schema(schema_data, flavor)
|
|
812
|
-
# Add schema-mandatory modules that aren't already selected
|
|
813
|
-
current_modules = session.get('selected_modules', [])
|
|
814
|
-
updated_modules = list(set(current_modules + mandatory_by_schema))
|
|
815
|
-
if len(updated_modules) > len(current_modules):
|
|
816
|
-
selected_modules = updated_modules
|
|
817
|
-
session['selected_modules'] = selected_modules
|
|
818
|
-
# Mark as initialized so we don't re-add them when going back
|
|
819
|
-
session['schema_mandatory_initialized'] = True
|
|
820
|
-
|
|
821
687
|
# Initialize mandatory tests only if not already in session and we have selected modules
|
|
822
688
|
# Only initialize when first reaching step 4 (not on every GET request)
|
|
823
689
|
if flavor and selected_modules and not selected_tests and step_num == 4:
|
|
@@ -848,28 +714,17 @@ def step(step_num):
|
|
|
848
714
|
schema_data = load_schema_data(schema_path) if schema_path else None
|
|
849
715
|
filtered_modules = filter_modules_by_flavor(tests_schema, flavor, schema_data)
|
|
850
716
|
|
|
851
|
-
# Get CLI schemas for form fields - use certificate_cli for all flavors (needed early for unsterile_run check)
|
|
852
|
-
cert_cli = CertificateCLI()
|
|
853
|
-
cert_schema = web_utils.parser_to_schema(cert_cli.parser)
|
|
854
|
-
|
|
855
|
-
# Check if unsterile_run is set in form_data
|
|
856
|
-
form_data = _prepare_form_data_for_template(session, cert_schema)
|
|
857
|
-
unsterile_run_field = f"{cert_schema['title']}_unsterile_run"
|
|
858
|
-
unsterile_run = bool(form_data.get(unsterile_run_field))
|
|
859
|
-
|
|
860
717
|
# Get certification status
|
|
861
718
|
is_certified = True
|
|
862
719
|
missing_modules = []
|
|
863
720
|
missing_tests = []
|
|
864
721
|
missing_tests_details = [] # List of dicts with test id and label
|
|
865
722
|
missing_additional_module = False
|
|
866
|
-
missing_modules_by_schema = []
|
|
867
723
|
if step_num >= 4 and flavor and selected_modules and selected_tests:
|
|
868
724
|
# Convert selected_modules to module dicts for check_certification_status
|
|
869
725
|
module_dicts = [m for m in filtered_modules if m.get('name') in selected_modules]
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
flavor, module_dicts, selected_tests, tests_schema, schema_data, unsterile_run
|
|
726
|
+
is_certified, missing_modules, missing_tests, missing_additional_module = check_certification_status(
|
|
727
|
+
flavor, module_dicts, selected_tests, tests_schema
|
|
873
728
|
)
|
|
874
729
|
|
|
875
730
|
# Get test details (labels) for missing tests
|
|
@@ -896,12 +751,10 @@ def step(step_num):
|
|
|
896
751
|
)
|
|
897
752
|
schema_errors = errors
|
|
898
753
|
schema_warnings = warnings
|
|
899
|
-
# Get missing schema-mandatory modules for display (recalculate if not already set)
|
|
900
|
-
if not missing_modules_by_schema and step_num >= 4 and flavor and selected_modules:
|
|
901
|
-
_, _, _, _, missing_modules_by_schema = check_certification_status(
|
|
902
|
-
flavor, module_dicts, selected_tests, tests_schema, schema_data, unsterile_run
|
|
903
|
-
)
|
|
904
754
|
|
|
755
|
+
# Get CLI schemas for form fields - use certificate_cli for all flavors
|
|
756
|
+
cert_cli = CertificateCLI()
|
|
757
|
+
cert_schema = web_utils.parser_to_schema(cert_cli.parser)
|
|
905
758
|
|
|
906
759
|
# Calculate total test count including mandatory tests from selected modules
|
|
907
760
|
total_test_count = len(selected_tests)
|
|
@@ -917,8 +770,6 @@ def step(step_num):
|
|
|
917
770
|
# Prepare data for JavaScript validation
|
|
918
771
|
# Always initialize these to avoid Undefined errors in template
|
|
919
772
|
mandatory_modules_for_js = get_mandatory_modules_for_flavor(flavor) if flavor else []
|
|
920
|
-
schema_data_for_js = load_schema_data(schema_path) if schema_path else None
|
|
921
|
-
mandatory_modules_by_schema_for_js = get_mandatory_modules_by_schema(schema_data_for_js, flavor) if (schema_data_for_js and flavor) else []
|
|
922
773
|
mandatory_tests_for_js = []
|
|
923
774
|
|
|
924
775
|
if step_num in [3, 4] and flavor:
|
|
@@ -988,22 +839,16 @@ def step(step_num):
|
|
|
988
839
|
missing_additional_module=missing_additional_module,
|
|
989
840
|
schema_errors=schema_errors,
|
|
990
841
|
schema_warnings=schema_warnings,
|
|
991
|
-
missing_modules_by_schema=missing_modules_by_schema,
|
|
992
842
|
mandatory_modules_for_js=mandatory_modules_for_js,
|
|
993
|
-
mandatory_modules_by_schema_for_js=mandatory_modules_by_schema_for_js,
|
|
994
843
|
mandatory_tests_for_js=mandatory_tests_for_js,
|
|
995
844
|
error=error,
|
|
996
845
|
warning=warning,
|
|
997
846
|
form_data=_prepare_form_data_for_template(session, cert_schema),
|
|
998
|
-
custom_broker_defaults=DEFAULT_CUSTOM_BROKER,
|
|
999
|
-
custom_broker_help=CUSTOM_BROKER_HELP,
|
|
1000
|
-
custom_broker_field_keys=list(DEFAULT_CUSTOM_BROKER.keys()),
|
|
1001
847
|
run_completed=run_completed,
|
|
1002
848
|
run_terminal=run_terminal,
|
|
1003
849
|
run_pid=run_pid,
|
|
1004
850
|
run_is_certified=run_is_certified,
|
|
1005
|
-
available_ports=available_ports
|
|
1006
|
-
unsterile_run=unsterile_run)
|
|
851
|
+
available_ports=available_ports)
|
|
1007
852
|
|
|
1008
853
|
def execute_certificate():
|
|
1009
854
|
"""Execute the certificate run based on session data."""
|
|
@@ -1029,13 +874,7 @@ def execute_certificate():
|
|
|
1029
874
|
tests_schema = web_utils.scan_tests_dir(CERT_TESTS_ROOT)
|
|
1030
875
|
filtered_modules = filter_modules_by_flavor(tests_schema, flavor)
|
|
1031
876
|
module_dicts = [m for m in filtered_modules if m.get('name') in session.get('selected_modules', [])]
|
|
1032
|
-
|
|
1033
|
-
# Check if unsterile_run is set in form_data
|
|
1034
|
-
cert_cli = CertificateCLI()
|
|
1035
|
-
cert_schema = web_utils.parser_to_schema(cert_cli.parser)
|
|
1036
|
-
unsterile_run_field = f"{cert_schema['title']}_unsterile_run"
|
|
1037
|
-
unsterile_run = bool(form_data.get(unsterile_run_field))
|
|
1038
|
-
is_certified, _, _, _, _ = check_certification_status(flavor, module_dicts, selected_tests, tests_schema, schema_data, unsterile_run)
|
|
877
|
+
is_certified, _, _, _ = check_certification_status(flavor, module_dicts, selected_tests, tests_schema)
|
|
1039
878
|
|
|
1040
879
|
full_cmd = []
|
|
1041
880
|
|
|
@@ -1098,17 +937,6 @@ def export_config():
|
|
|
1098
937
|
flash("No configuration to export. Please complete at least step 1 and 2.", "error")
|
|
1099
938
|
return redirect(url_for('step', step_num=session.get('current_step', 1)))
|
|
1100
939
|
|
|
1101
|
-
# Extract custom broker form field values from form_data
|
|
1102
|
-
form_data = session.get('form_data', {})
|
|
1103
|
-
cert_cli = CertificateCLI()
|
|
1104
|
-
cert_schema = web_utils.parser_to_schema(cert_cli.parser)
|
|
1105
|
-
custom_broker_fields = {}
|
|
1106
|
-
field_prefix = f"{cert_schema['title']}_custom_broker_"
|
|
1107
|
-
for field_name in DEFAULT_CUSTOM_BROKER.keys():
|
|
1108
|
-
full_field_name = f"{field_prefix}{field_name}"
|
|
1109
|
-
if full_field_name in form_data:
|
|
1110
|
-
custom_broker_fields[field_name] = form_data[full_field_name]
|
|
1111
|
-
|
|
1112
940
|
# Prepare configuration data
|
|
1113
941
|
config = {
|
|
1114
942
|
'version': '1.0',
|
|
@@ -1117,10 +945,9 @@ def export_config():
|
|
|
1117
945
|
'schema_path': session.get('schema_path'),
|
|
1118
946
|
'selected_modules': session.get('selected_modules', []),
|
|
1119
947
|
'selected_tests': session.get('selected_tests', []),
|
|
1120
|
-
'form_data': form_data,
|
|
948
|
+
'form_data': session.get('form_data', {}),
|
|
1121
949
|
'schema_data': load_schema_data(session.get('schema_path')), # Load schema data from file for export
|
|
1122
|
-
'custom_broker_path': session.get('custom_broker_path')
|
|
1123
|
-
'custom_broker_fields': custom_broker_fields # Include custom broker form field values
|
|
950
|
+
'custom_broker_path': session.get('custom_broker_path') # Include custom broker file path
|
|
1124
951
|
}
|
|
1125
952
|
|
|
1126
953
|
# Create filename with timestamp
|
|
@@ -1181,47 +1008,17 @@ def import_config():
|
|
|
1181
1008
|
json.dump(schema_data, f, indent=2)
|
|
1182
1009
|
except Exception:
|
|
1183
1010
|
pass # If we can't save, user will need to re-upload
|
|
1184
|
-
|
|
1185
|
-
custom_broker_fields = config_data.get('custom_broker_fields', {})
|
|
1186
|
-
if custom_broker_fields:
|
|
1187
|
-
# Restore broker form field values to form_data
|
|
1188
|
-
cert_cli = CertificateCLI()
|
|
1189
|
-
cert_schema = web_utils.parser_to_schema(cert_cli.parser)
|
|
1190
|
-
field_prefix = f"{cert_schema['title']}_custom_broker_"
|
|
1191
|
-
for field_name, field_value in custom_broker_fields.items():
|
|
1192
|
-
full_field_name = f"{field_prefix}{field_name}"
|
|
1193
|
-
session['form_data'][full_field_name] = field_value
|
|
1194
|
-
# Regenerate broker config file from form fields
|
|
1195
|
-
try:
|
|
1196
|
-
broker_config_path = _write_custom_broker_config(session['form_data'], cert_schema['title'])
|
|
1197
|
-
session['custom_broker_path'] = os.path.normpath(broker_config_path)
|
|
1198
|
-
except Exception:
|
|
1199
|
-
pass # If generation fails, user can reconfigure in step 4
|
|
1200
|
-
else:
|
|
1201
|
-
# Backward compatibility: try to use existing path
|
|
1202
|
-
session['custom_broker_path'] = config_data.get('custom_broker_path')
|
|
1011
|
+
session['custom_broker_path'] = config_data.get('custom_broker_path')
|
|
1203
1012
|
|
|
1204
1013
|
# Validate schema file still exists
|
|
1205
1014
|
if session['schema_path'] and not os.path.exists(session['schema_path']):
|
|
1206
1015
|
flash(f"Warning: Schema file not found at {session['schema_path']}. Please re-upload it in step 2.", "warning")
|
|
1207
1016
|
session['current_step'] = 2
|
|
1208
|
-
# Validate custom_broker file still exists if present
|
|
1017
|
+
# Validate custom_broker file still exists if present
|
|
1209
1018
|
elif session.get('custom_broker_path') and not os.path.exists(session['custom_broker_path']):
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
cert_cli = CertificateCLI()
|
|
1214
|
-
cert_schema = web_utils.parser_to_schema(cert_cli.parser)
|
|
1215
|
-
broker_config_path = _write_custom_broker_config(session['form_data'], cert_schema['title'])
|
|
1216
|
-
session['custom_broker_path'] = os.path.normpath(broker_config_path)
|
|
1217
|
-
except Exception:
|
|
1218
|
-
flash(f"Warning: Custom broker configuration will be regenerated in step 4.", "warning")
|
|
1219
|
-
if session.get('current_step', 0) < 4:
|
|
1220
|
-
session['current_step'] = 4
|
|
1221
|
-
else:
|
|
1222
|
-
flash(f"Warning: Custom broker file not found at {session['custom_broker_path']}. Please reconfigure it in step 4.", "warning")
|
|
1223
|
-
if session.get('current_step', 0) < 4:
|
|
1224
|
-
session['current_step'] = 4
|
|
1019
|
+
flash(f"Warning: Custom broker file not found at {session['custom_broker_path']}. Please re-upload it in step 4.", "warning")
|
|
1020
|
+
if session.get('current_step', 0) < 4:
|
|
1021
|
+
session['current_step'] = 4
|
|
1225
1022
|
else:
|
|
1226
1023
|
# Determine appropriate step based on what's configured
|
|
1227
1024
|
if session.get('selected_tests'):
|
|
@@ -1250,8 +1047,6 @@ def import_config():
|
|
|
1250
1047
|
def clear_session():
|
|
1251
1048
|
"""Clear session and start fresh."""
|
|
1252
1049
|
session.clear()
|
|
1253
|
-
# Initialize session flags
|
|
1254
|
-
session['schema_mandatory_initialized'] = False
|
|
1255
1050
|
return redirect(url_for('step', step_num=1))
|
|
1256
1051
|
|
|
1257
1052
|
@app.route("/parser")
|
|
@@ -1264,4 +1059,4 @@ def generator():
|
|
|
1264
1059
|
|
|
1265
1060
|
@app.route("/data_structs", methods=['GET', 'POST'])
|
|
1266
1061
|
def data_structs():
|
|
1267
|
-
return web_utils.utils_data_structs(web_utils.CERT_WEB)
|
|
1062
|
+
return web_utils.utils_data_structs(web_utils.CERT_WEB)
|