wiliot-certificate 4.5.0a1__py3-none-any.whl → 4.5.0a3__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.
Files changed (43) hide show
  1. certificate/cert_common.py +14 -15
  2. certificate/cert_config.py +3 -3
  3. certificate/cert_defines.py +1 -0
  4. certificate/cert_gw_sim.py +3 -0
  5. certificate/cert_results.py +8 -0
  6. certificate/cert_utils.py +3 -0
  7. certificate/certificate_eth_test_list.txt +5 -3
  8. certificate/certificate_sanity_test_list.txt +3 -2
  9. certificate/certificate_test_list.txt +4 -3
  10. certificate/tests/cloud_connectivity/acl_ext_adv_test/acl_ext_adv_test.json +1 -1
  11. certificate/tests/cloud_connectivity/acl_test/acl_test.json +1 -1
  12. certificate/tests/cloud_connectivity/channel_scan_behaviour_test/channel_scan_behaviour_test.json +1 -1
  13. certificate/tests/cloud_connectivity/deduplication_test/deduplication_test.json +14 -0
  14. certificate/tests/cloud_connectivity/deduplication_test/deduplication_test.py +85 -0
  15. certificate/tests/cloud_connectivity/downlink_test/downlink_test.py +1 -4
  16. certificate/tests/cloud_connectivity/ext_adv_stress_test/ext_adv_stress_test.json +1 -1
  17. certificate/tests/cloud_connectivity/ext_adv_stress_test/ext_adv_stress_test.py +10 -9
  18. certificate/tests/cloud_connectivity/stress_test/stress_test.json +1 -1
  19. certificate/tests/cloud_connectivity/stress_test/stress_test.py +10 -10
  20. certificate/tests/cloud_connectivity/uplink_test/uplink_test.py +1 -0
  21. certificate/tests/datapath/event_ble5_test/event_ble5_test.py +6 -4
  22. certificate/tests/datapath/event_test/event_test.py +4 -3
  23. certificate/tests/datapath/num_of_tags_test/num_of_tags_test.json +1 -1
  24. certificate/tests/datapath/pacer_interval_ble5_test/pacer_interval_ble5_test.py +4 -4
  25. certificate/tests/datapath/pkt_filter_ble5_chl21_test/pkt_filter_ble5_chl21_test.py +5 -5
  26. certificate/tests/datapath/pkt_filter_ble5_test/pkt_filter_ble5_test.py +5 -5
  27. certificate/tests/datapath/pkt_filter_brg2gw_ext_adv_test/pkt_filter_brg2gw_ext_adv_test.py +10 -8
  28. certificate/tests/datapath/rssi_threshold_test/rssi_threshold_test.json +1 -1
  29. certificate/tests/energy2400/signal_indicator_ble5_test/signal_indicator_ble5_test.py +1 -2
  30. certificate/tests/energy2400/signal_indicator_ext_adv_test/signal_indicator_ext_adv_test.json +8 -9
  31. certificate/tests/energy2400/signal_indicator_ext_adv_test/signal_indicator_ext_adv_test.py +110 -270
  32. certificate/tests/sensors/ext_sensor_test/ext_sensor_test.py +4 -9
  33. common/api_if/api_validation.py +2 -2
  34. common/web/templates/generator.html +141 -79
  35. common/web/web_utils.py +78 -56
  36. gui_certificate/server.py +111 -19
  37. gui_certificate/templates/cert_run.html +43 -6
  38. {wiliot_certificate-4.5.0a1.dist-info → wiliot_certificate-4.5.0a3.dist-info}/METADATA +35 -36
  39. {wiliot_certificate-4.5.0a1.dist-info → wiliot_certificate-4.5.0a3.dist-info}/RECORD +43 -41
  40. {wiliot_certificate-4.5.0a1.dist-info → wiliot_certificate-4.5.0a3.dist-info}/WHEEL +0 -0
  41. {wiliot_certificate-4.5.0a1.dist-info → wiliot_certificate-4.5.0a3.dist-info}/entry_points.txt +0 -0
  42. {wiliot_certificate-4.5.0a1.dist-info → wiliot_certificate-4.5.0a3.dist-info}/licenses/LICENSE +0 -0
  43. {wiliot_certificate-4.5.0a1.dist-info → wiliot_certificate-4.5.0a3.dist-info}/top_level.txt +0 -0
gui_certificate/server.py CHANGED
@@ -70,9 +70,32 @@ def get_mandatory_modules_for_flavor(flavor):
70
70
  return [MODULE_CLOUD_CONNECTIVITY, MODULE_EDGE_MGMT]
71
71
  return []
72
72
 
73
+ def get_mandatory_modules_by_schema(schema_data, flavor):
74
+ """Get modules that are mandatory by schema (modules declared in schema)."""
75
+ if not schema_data or "modules" not in schema_data:
76
+ return []
77
+
78
+ # Only apply to bridge flavors (bridge_only and combo)
79
+ if flavor not in (FLAVOR_BRIDGE_ONLY, FLAVOR_COMBO):
80
+ return []
81
+
82
+ schema_modules = schema_data.get("modules", {})
83
+ if not isinstance(schema_modules, dict):
84
+ return []
85
+
86
+ # Map schema module names to test module names
87
+ mandatory_by_schema = []
88
+ for schema_mod_name in schema_modules.keys():
89
+ # Map schema module name to test module name
90
+ test_mod_name = test_module_and_schema_module_to_other(schema_mod_name)
91
+ if test_mod_name not in mandatory_by_schema:
92
+ mandatory_by_schema.append(test_mod_name)
93
+
94
+ return mandatory_by_schema
95
+
73
96
  # TODO: This is a temporary mapping to map test module names to schema module names - remove this
74
- def test_module_to_schema_module(test_module_name):
75
- """Map test module names to validation schema module names."""
97
+ def test_module_and_schema_module_to_other(module_name):
98
+ """Map test module names and schema module names to one another."""
76
99
  mapping = {
77
100
  "calibration": "calibration",
78
101
  "datapath": "datapath",
@@ -82,7 +105,12 @@ def test_module_to_schema_module(test_module_name):
82
105
  "sensors": "externalSensor", # different name
83
106
  "custom": "custom"
84
107
  }
85
- return mapping.get(test_module_name, test_module_name) # Return as-is if not in mapping
108
+ for k, v in mapping.items():
109
+ if module_name == k:
110
+ return v
111
+ if module_name == v:
112
+ return k
113
+ return module_name # Return as-is if not in mapping
86
114
 
87
115
  def filter_modules_by_flavor(tests_schema, flavor, schema_data=None):
88
116
  """Filter modules and tests based on selected flavor."""
@@ -115,12 +143,17 @@ def filter_modules_by_flavor(tests_schema, flavor, schema_data=None):
115
143
  # Include all tests for combo
116
144
  filtered_tests.append(test)
117
145
 
118
- # Only include module if it has tests or is mandatory
146
+ # Get modules mandatory by schema
147
+ mandatory_by_schema = get_mandatory_modules_by_schema(schema_data, flavor) if schema_data else []
148
+ is_mandatory_by_schema = mod_name in mandatory_by_schema
149
+
150
+ # Only include module if it has tests or is mandatory (by flavor or schema)
119
151
  # For mandatory modules, include even if no tests match (they'll be shown but empty)
120
- if filtered_tests or mod_name in mandatory_modules:
152
+ if filtered_tests or mod_name in mandatory_modules or is_mandatory_by_schema:
121
153
  mod_copy = mod.copy()
122
154
  mod_copy["tests"] = filtered_tests
123
155
  mod_copy["is_mandatory"] = mod_name in mandatory_modules
156
+ mod_copy["is_mandatory_by_schema"] = is_mandatory_by_schema
124
157
  filtered_modules.append(mod_copy)
125
158
 
126
159
  # Sort modules: cloud_connectivity first, then edge_mgmt, then by schema order
@@ -136,7 +169,7 @@ def filter_modules_by_flavor(tests_schema, flavor, schema_data=None):
136
169
  if schema_module_order:
137
170
  try:
138
171
  # Map test module name to schema module name
139
- schema_mod_name = test_module_to_schema_module(mod_name)
172
+ schema_mod_name = test_module_and_schema_module_to_other(mod_name)
140
173
  idx = schema_module_order.index(schema_mod_name)
141
174
  return (2, idx)
142
175
  except ValueError:
@@ -285,30 +318,37 @@ def verify_schema_matches_selection(schema_data, flavor, selected_modules, selec
285
318
  bridge_modules_to_check = [m for m in selected_modules if m not in (MODULE_CLOUD_CONNECTIVITY, MODULE_EDGE_MGMT)]
286
319
  for test_mod_name in bridge_modules_to_check:
287
320
  # Map test module name to schema module name
288
- schema_mod_name = test_module_to_schema_module(test_mod_name)
321
+ schema_mod_name = test_module_and_schema_module_to_other(test_mod_name)
289
322
  if schema_mod_name not in schema_module_names:
290
323
  warnings.append(f"Module '{test_mod_name}' may not be supported according to the uploaded schema")
291
324
 
292
325
  return len(errors) == 0, errors, warnings
293
326
 
294
- def check_certification_status(flavor, selected_modules, selected_tests, tests_schema):
327
+ def check_certification_status(flavor, selected_modules, selected_tests, tests_schema, schema_data=None):
295
328
  """Check if the selection qualifies for certification or is test-only."""
296
329
  mandatory_modules = get_mandatory_modules_for_flavor(flavor)
330
+ mandatory_by_schema = get_mandatory_modules_by_schema(schema_data, flavor) if schema_data else []
297
331
  all_mandatory_tests = []
298
332
 
299
- # Get all mandatory tests from mandatory modules
333
+ # Get selected module names (handle both dict and string formats)
334
+ selected_module_names = [m.get("name") if isinstance(m, dict) else m for m in selected_modules]
335
+
336
+ # Get all mandatory tests from ALL selected modules (not just mandatory modules)
337
+ # When a module is selected, its mandatory tests become mandatory
300
338
  for mod in tests_schema.get("modules", []):
301
339
  mod_name = mod.get("name", "")
302
- if mod_name in mandatory_modules:
340
+ if mod_name in selected_module_names:
303
341
  for test in mod.get("tests", []):
304
342
  if test.get("meta", {}).get("mandatory", 0) == 1:
305
343
  all_mandatory_tests.append(test.get("id"))
306
344
 
307
345
  # 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]
309
346
  missing_modules = [m for m in mandatory_modules if m not in selected_module_names]
310
347
 
311
- # Check if all mandatory tests are selected
348
+ # Check if all schema-mandatory modules are selected
349
+ missing_modules_by_schema = [m for m in mandatory_by_schema if m not in selected_module_names]
350
+
351
+ # Check if all mandatory tests (from selected modules) are selected
312
352
  missing_tests = [t for t in all_mandatory_tests if t not in selected_tests]
313
353
 
314
354
  # Check for "at least one additional module" requirement for Bridge Only and Combo
@@ -319,9 +359,10 @@ def check_certification_status(flavor, selected_modules, selected_tests, tests_s
319
359
  if len(additional_modules) == 0:
320
360
  missing_additional_module = True
321
361
 
322
- is_certified = len(missing_modules) == 0 and len(missing_tests) == 0 and not missing_additional_module
362
+ is_certified = (len(missing_modules) == 0 and len(missing_modules_by_schema) == 0 and
363
+ len(missing_tests) == 0 and not missing_additional_module)
323
364
 
324
- return is_certified, missing_modules, missing_tests, missing_additional_module
365
+ return is_certified, missing_modules, missing_tests, missing_additional_module, missing_modules_by_schema
325
366
 
326
367
  def _prepare_form_data_for_template(session, cert_schema):
327
368
  """Prepare form_data for template, ensuring custom_broker_path is included if available."""
@@ -451,6 +492,7 @@ def step(step_num):
451
492
  session['selected_modules'] = []
452
493
  session['selected_tests'] = []
453
494
  session['form_data'] = {}
495
+ session['schema_mandatory_initialized'] = False
454
496
 
455
497
  title = "Run Certificate"
456
498
  tests_schema = web_utils.scan_tests_dir(CERT_TESTS_ROOT)
@@ -505,7 +547,22 @@ def step(step_num):
505
547
  flavor = session.get('flavor')
506
548
  if 'selected_modules' not in session or not session.get('selected_modules'):
507
549
  mandatory_modules = get_mandatory_modules_for_flavor(flavor)
508
- session['selected_modules'] = mandatory_modules
550
+ # Add schema-mandatory modules
551
+ schema_data = result # result is the validated schema data
552
+ mandatory_by_schema = get_mandatory_modules_by_schema(schema_data, flavor)
553
+ all_mandatory = list(set(mandatory_modules + mandatory_by_schema))
554
+ session['selected_modules'] = all_mandatory
555
+ # Mark schema-mandatory modules as initialized
556
+ session['schema_mandatory_initialized'] = True
557
+ else:
558
+ # If modules already exist, add schema-mandatory modules and mark as initialized
559
+ schema_data = result
560
+ mandatory_by_schema = get_mandatory_modules_by_schema(schema_data, flavor)
561
+ current_modules = session.get('selected_modules', [])
562
+ updated_modules = list(set(current_modules + mandatory_by_schema))
563
+ if len(updated_modules) > len(current_modules):
564
+ session['selected_modules'] = updated_modules
565
+ session['schema_mandatory_initialized'] = True
509
566
  # For GW only, skip step 3 (modules)
510
567
  if session.get('flavor') == FLAVOR_GW_ONLY:
511
568
  session['current_step'] = 4
@@ -681,9 +738,30 @@ def step(step_num):
681
738
  # This ensures mandatory items are only pre-checked at the beginning
682
739
  if flavor and not selected_modules:
683
740
  mandatory_modules = get_mandatory_modules_for_flavor(flavor)
684
- selected_modules = mandatory_modules
741
+ # Add schema-mandatory modules if schema is available
742
+ schema_data = load_schema_data(schema_path) if schema_path else None
743
+ mandatory_by_schema = get_mandatory_modules_by_schema(schema_data, flavor) if schema_data else []
744
+ all_mandatory = list(set(mandatory_modules + mandatory_by_schema))
745
+ selected_modules = all_mandatory
685
746
  session['selected_modules'] = selected_modules
686
747
 
748
+ # Ensure schema-mandatory modules are added when first reaching step 3 (only if not already initialized)
749
+ # Use a session flag to track if schema-mandatory modules have been initialized
750
+ if step_num == 3 and flavor and schema_path:
751
+ schema_mandatory_initialized = session.get('schema_mandatory_initialized', False)
752
+ if not schema_mandatory_initialized:
753
+ schema_data = load_schema_data(schema_path) if schema_path else None
754
+ if schema_data:
755
+ mandatory_by_schema = get_mandatory_modules_by_schema(schema_data, flavor)
756
+ # Add schema-mandatory modules that aren't already selected
757
+ current_modules = session.get('selected_modules', [])
758
+ updated_modules = list(set(current_modules + mandatory_by_schema))
759
+ if len(updated_modules) > len(current_modules):
760
+ selected_modules = updated_modules
761
+ session['selected_modules'] = selected_modules
762
+ # Mark as initialized so we don't re-add them when going back
763
+ session['schema_mandatory_initialized'] = True
764
+
687
765
  # Initialize mandatory tests only if not already in session and we have selected modules
688
766
  # Only initialize when first reaching step 4 (not on every GET request)
689
767
  if flavor and selected_modules and not selected_tests and step_num == 4:
@@ -720,11 +798,13 @@ def step(step_num):
720
798
  missing_tests = []
721
799
  missing_tests_details = [] # List of dicts with test id and label
722
800
  missing_additional_module = False
801
+ missing_modules_by_schema = []
723
802
  if step_num >= 4 and flavor and selected_modules and selected_tests:
724
803
  # Convert selected_modules to module dicts for check_certification_status
725
804
  module_dicts = [m for m in filtered_modules if m.get('name') in selected_modules]
726
- is_certified, missing_modules, missing_tests, missing_additional_module = check_certification_status(
727
- flavor, module_dicts, selected_tests, tests_schema
805
+ schema_data = load_schema_data(schema_path) if schema_path else None
806
+ is_certified, missing_modules, missing_tests, missing_additional_module, missing_modules_by_schema = check_certification_status(
807
+ flavor, module_dicts, selected_tests, tests_schema, schema_data
728
808
  )
729
809
 
730
810
  # Get test details (labels) for missing tests
@@ -751,6 +831,11 @@ def step(step_num):
751
831
  )
752
832
  schema_errors = errors
753
833
  schema_warnings = warnings
834
+ # Get missing schema-mandatory modules for display (recalculate if not already set)
835
+ if not missing_modules_by_schema and step_num >= 4 and flavor and selected_modules:
836
+ _, _, _, _, missing_modules_by_schema = check_certification_status(
837
+ flavor, module_dicts, selected_tests, tests_schema, schema_data
838
+ )
754
839
 
755
840
  # Get CLI schemas for form fields - use certificate_cli for all flavors
756
841
  cert_cli = CertificateCLI()
@@ -770,6 +855,8 @@ def step(step_num):
770
855
  # Prepare data for JavaScript validation
771
856
  # Always initialize these to avoid Undefined errors in template
772
857
  mandatory_modules_for_js = get_mandatory_modules_for_flavor(flavor) if flavor else []
858
+ schema_data_for_js = load_schema_data(schema_path) if schema_path else None
859
+ mandatory_modules_by_schema_for_js = get_mandatory_modules_by_schema(schema_data_for_js, flavor) if (schema_data_for_js and flavor) else []
773
860
  mandatory_tests_for_js = []
774
861
 
775
862
  if step_num in [3, 4] and flavor:
@@ -839,7 +926,9 @@ def step(step_num):
839
926
  missing_additional_module=missing_additional_module,
840
927
  schema_errors=schema_errors,
841
928
  schema_warnings=schema_warnings,
929
+ missing_modules_by_schema=missing_modules_by_schema,
842
930
  mandatory_modules_for_js=mandatory_modules_for_js,
931
+ mandatory_modules_by_schema_for_js=mandatory_modules_by_schema_for_js,
843
932
  mandatory_tests_for_js=mandatory_tests_for_js,
844
933
  error=error,
845
934
  warning=warning,
@@ -874,7 +963,8 @@ def execute_certificate():
874
963
  tests_schema = web_utils.scan_tests_dir(CERT_TESTS_ROOT)
875
964
  filtered_modules = filter_modules_by_flavor(tests_schema, flavor)
876
965
  module_dicts = [m for m in filtered_modules if m.get('name') in session.get('selected_modules', [])]
877
- is_certified, _, _, _ = check_certification_status(flavor, module_dicts, selected_tests, tests_schema)
966
+ schema_data = load_schema_data(schema_path) if schema_path else None
967
+ is_certified, _, _, _, _ = check_certification_status(flavor, module_dicts, selected_tests, tests_schema, schema_data)
878
968
 
879
969
  full_cmd = []
880
970
 
@@ -1047,6 +1137,8 @@ def import_config():
1047
1137
  def clear_session():
1048
1138
  """Clear session and start fresh."""
1049
1139
  session.clear()
1140
+ # Initialize session flags
1141
+ session['schema_mandatory_initialized'] = False
1050
1142
  return redirect(url_for('step', step_num=1))
1051
1143
 
1052
1144
  @app.route("/parser")
@@ -326,12 +326,15 @@
326
326
  name="modules[]"
327
327
  id="module_{{ mod.name }}"
328
328
  value="{{ mod.name }}"
329
- {% if is_selected %}checked{% elif is_mandatory and not has_selections %}checked{% endif %}>
329
+ {% if is_selected or (is_mandatory and not has_selections) or (mod.is_mandatory_by_schema and not has_selections) %}checked{% endif %}>
330
330
  <label class="form-check-label" for="module_{{ mod.name }}" style="font-weight: bold; font-size: 1.1rem;">
331
331
  {{ mod.name }}
332
332
  {% if is_mandatory %}
333
333
  <span class="mandatory-badge">Mandatory</span>
334
334
  {% endif %}
335
+ {% if mod.is_mandatory_by_schema %}
336
+ <span class="mandatory-badge" style="background: #0066cc;">Mandatory by Schema</span>
337
+ {% endif %}
335
338
  {{ kb_link(mod_doc) }}
336
339
  </label>
337
340
  <p class="text-muted mt-1 mb-0">
@@ -644,12 +647,13 @@
644
647
  {% endif %}
645
648
  {% if missing_tests_details %}
646
649
  <div class="alert alert-warning">
647
- <strong>Missing Mandatory Tests:</strong>
650
+ <strong>Missing Mandatory Tests from Selected Modules:</strong>
648
651
  <ul class="mb-0">
649
652
  {% for test in missing_tests_details %}
650
653
  <li>{{ test.label }} <small class="text-muted">({{ test.module }})</small></li>
651
654
  {% endfor %}
652
655
  </ul>
656
+ <small class="d-block mt-2">When a module is selected, its mandatory tests must also be selected.</small>
653
657
  </div>
654
658
  {% endif %}
655
659
  {% endif %}
@@ -662,7 +666,10 @@
662
666
  <h5 class="mb-0">Schema Verification</h5>
663
667
  </div>
664
668
  <div class="card-body">
665
- {% if schema_errors or schema_warnings %}
669
+ {% if schema_errors or schema_warnings or missing_modules_by_schema %}
670
+ <p><strong>Schema Status:</strong>
671
+ <span class="badge bg-warning text-dark">SCHEMA DOES NOT MATCH RUN SETTINGS</span>
672
+ </p>
666
673
  {% if schema_errors %}
667
674
  <div class="alert alert-danger">
668
675
  <strong>Errors:</strong>
@@ -683,12 +690,24 @@
683
690
  </ul>
684
691
  </div>
685
692
  {% endif %}
693
+ {% if missing_modules_by_schema %}
694
+ <div class="alert alert-warning mt-3">
695
+ <strong>Missing Modules Mandatory by Schema:</strong>
696
+ <ul class="mb-0">
697
+ {% for mod in missing_modules_by_schema %}
698
+ <li>{{ mod }}</li>
699
+ {% endfor %}
700
+ </ul>
701
+ <small class="d-block mt-2">These modules are declared in your validation schema but are not selected. They should be included for proper certification.</small>
702
+ </div>
703
+ {% endif %}
686
704
  {% else %}
687
705
  <p><strong>Schema Status:</strong>
688
- <span class="badge bg-success">SCHEMA MATCHES TEST CONFIGURATION</span>
706
+ <span class="badge bg-success">SCHEMA MATCHES RUN SETTINGS</span>
689
707
  <small class="text-muted d-block mt-1">The uploaded schema matches the selected flavor, modules, and tests</small>
690
708
  </p>
691
709
  {% endif %}
710
+
692
711
  </div>
693
712
  </div>
694
713
 
@@ -843,6 +862,7 @@
843
862
  const brgCertSchema = {{ cert_schema|tojson|safe }};
844
863
 
845
864
  // Step 3: Module selection validation
865
+ const mandatoryModulesBySchema = {{ mandatory_modules_by_schema_for_js|tojson|safe }};
846
866
  function checkStep3Validation() {
847
867
  if (stepNum !== 3) return;
848
868
 
@@ -861,6 +881,14 @@
861
881
  warnings.push('Missing mandatory modules: ' + missingMandatory.join(', '));
862
882
  }
863
883
 
884
+ // Check if schema-mandatory modules are deselected
885
+ if (mandatoryModulesBySchema && mandatoryModulesBySchema.length > 0) {
886
+ const missingBySchema = mandatoryModulesBySchema.filter(m => !selectedModules.includes(m));
887
+ if (missingBySchema.length > 0) {
888
+ warnings.push('Missing modules mandatory by schema: ' + missingBySchema.join(', '));
889
+ }
890
+ }
891
+
864
892
  // Check Bridge/Combo requirement for at least one additional module
865
893
  if (selectedFlavor === 'bridge_only' || selectedFlavor === 'combo') {
866
894
  const nonMandatorySelected = selectedModules.filter(m => !mandatoryModules.includes(m));
@@ -903,12 +931,21 @@
903
931
  warnings.push('Missing mandatory modules: ' + missingMandatoryModules.join(', '));
904
932
  }
905
933
 
906
- // Check if mandatory tests are deselected
934
+ // Check if schema-mandatory modules are deselected
935
+ if (mandatoryModulesBySchema && mandatoryModulesBySchema.length > 0) {
936
+ const missingBySchema = mandatoryModulesBySchema.filter(m => !selectedModules.includes(m));
937
+ if (missingBySchema.length > 0) {
938
+ warnings.push('Missing modules mandatory by schema: ' + missingBySchema.join(', '));
939
+ }
940
+ }
941
+
942
+ // Check if mandatory tests from selected modules are deselected
943
+ // When a module is selected, its mandatory tests become mandatory
907
944
  const missingMandatoryTests = mandatoryTests
908
945
  .filter(t => selectedModules.includes(t.module) && !selectedTests.includes(t.id))
909
946
  .map(t => t.label + ' (' + t.module + ')');
910
947
  if (missingMandatoryTests.length > 0) {
911
- warnings.push('Missing mandatory tests: ' + missingMandatoryTests.length + ' test(s)');
948
+ warnings.push('Missing mandatory tests from selected modules: ' + missingMandatoryTests.length + ' test(s)');
912
949
  }
913
950
 
914
951
  if (warnings.length > 0) {
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wiliot_certificate
3
- Version: 4.5.0a1
3
+ Version: 4.5.0a3
4
4
  Summary: A library for certifying Wiliot-compliant boards
5
5
  Author-email: Wiliot <support@wiliot.com>
6
6
  License-Expression: MIT
@@ -30,35 +30,60 @@ Requires-Dist: reportlab>=4.3.1
30
30
  Requires-Dist: google-api-python-client>=2.162.0
31
31
  Dynamic: license-file
32
32
 
33
- # wiliot-certificate Version 4.5.0
33
+ # wiliot-certificate
34
34
 
35
35
  <!-- Description -->
36
36
  wiliot-certificate is a Python library that provides tools for testing and certifying boards for compatibility with Wiliot’s ecosystem.
37
- This python package includes the following CLI utilities:
37
+ This python package includes the following tools:
38
38
  - Certification Wizard (`wlt-cert`)
39
39
  - Certificate CLI (`wlt-cert-cli`)
40
40
  - Tester Upgrade (`wlt-cert-tester-upgrade`)
41
41
  - Registration Certificate (`wlt-cert-reg`)
42
42
 
43
- # Version:
44
- wiliot-certificate versions 4.5.0 are compatible with firmware version >=4.5.0 (API VERSION: 13)
43
+ # Versioning:
44
+ wiliot-certificate versions 4.5.x are compatible with firmware version >=4.5.0 (API VERSION: 13)
45
45
 
46
46
  ## Installing wiliot-certificate
47
- Install wiliot-certificate:
48
47
  ````commandline
49
48
  pip install wiliot-certificate
50
49
  ````
51
50
 
52
51
  ## Using wiliot-certificate
53
52
  ### Certification
54
- In terminal, run:
55
53
  ````commandline
56
54
  wlt-cert
57
55
  ````
58
- <!-- This tool walks you through... TODO -->
59
- <!-- You need to have a json validation schema <LINK>, certification tester & custom broker file <LINK> -->
56
+ This tool is the default to test and certify your device.
57
+ It runs a setup wizard that walks you through the initialization steps before running the tests.
58
+ You'll need a [validation schema](https://community.wiliot.com/customers/s/article/Validation-Schema), tester device and custom broker json file ([more info here](https://community.wiliot.com/customers/s/article/Wiliot-Gateway-Certification)).
59
+ Once set up it opens a terminal and tests your device.
60
60
 
61
- #### The following capabilities are not tested in this version
61
+
62
+
63
+ ### Certificate CLI
64
+ ````commandline
65
+ wlt-cert-cli -h
66
+ ````
67
+ CLI version of the certificate. Use -h for details on the different arguments.
68
+
69
+
70
+ ### Tester Upgrade
71
+ ````commandline
72
+ wlt-cert-tester-upgrade
73
+ ````
74
+ Upgrades the firmware of the tester device to the version required for certification.
75
+
76
+
77
+ ### Registration Certificate
78
+ ````commandline
79
+ wlt-cert-reg
80
+ ````
81
+ Certify the gateway registration process to Wiliot platform.
82
+ The gateway must use Wiliot production MQTT broker, and mustn't be registered to any account on Wiliot platform.
83
+ Use -h for details on the arguments. [More info here](https://community.wiliot.com/customers/s/article/Wiliot-Gateway-Certification)
84
+
85
+
86
+ ## The following capabilities are not tested in this version
62
87
  ##### Cloud Connectivity & Misc
63
88
  - Board type registered within the Board Type Management system
64
89
  - Bridge OTA progress reporting
@@ -82,29 +107,3 @@ wlt-cert
82
107
  ##### Calibration
83
108
  - Functionality of output power and interval calibration
84
109
  - Functionality of calibration transmission patterns for the configuration STANDARD & EU & DISABLE
85
-
86
-
87
- ### Certificate CLI
88
- In terminal, run:
89
- ````commandline
90
- wlt-cert-cli -h
91
- ````
92
- CLI version of the certificate. Use -h for details on the different arguments.
93
-
94
-
95
- ### Tester Upgrade
96
- In terminal, run:
97
- ````commandline
98
- wlt-cert-tester-upgrade
99
- ````
100
- Upgrades the firmware of the tester device to the version required for certification.
101
-
102
-
103
- ### Registration Certificate
104
- In terminal, run:
105
- ````commandline
106
- wlt-cert-reg
107
- ````
108
- Certify the gateway registration process to Wiliot platform.
109
- The gateway must use Wiliot production MQTT broker, and mustn't be registered to any account on Wiliot platform.
110
- Use -h for details on the arguments. <!-- More info can be found in TODO link-->