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
@@ -606,8 +606,8 @@ def run_event_test_phase(test, phase, datapath_module, values, scan_time, event_
606
606
  scan_time_multiplier = (1 / 3)
607
607
  fields += [BRG_RSSI_MOVEMENT_THRESHOLD]
608
608
 
609
- test = (cert_config.brg_configure_ble5(test, fields=fields, values=values, module=datapath_module)[0] if ble5_test
610
- else cert_config.brg_configure(test, fields=fields, values=values, module=datapath_module)[0])
609
+ ble5 = ble5_test and test.dut_is_bridge() # ble5 only for bridge dut (with combo we don't need to wait)
610
+ test = cert_config.brg_configure(test, fields=fields, values=values, module=datapath_module, ble5=ble5)[0]
611
611
  test.set_phase_rc(phase, test.rc)
612
612
  test.add_phase_reason(phase, test.reason)
613
613
  if test.rc == TEST_FAILED and test.exit_on_param_failure:
@@ -1273,7 +1273,6 @@ def output_power_supported(board_type, output_power):
1273
1273
  else:
1274
1274
  return output_power in ag.OUTPUT_POWER_2_4_SUPPORTED_VALUES
1275
1275
 
1276
-
1277
1276
  def wiliot_pkts_validation(test, all_messages_in_test, all_data_pkts):
1278
1277
  PHASE_NAME = "Wiliot packets validation"
1279
1278
  phase_run_print(PHASE_NAME)
@@ -1290,7 +1289,7 @@ def wiliot_pkts_validation(test, all_messages_in_test, all_data_pkts):
1290
1289
  wiliot_pkts_validation_phase = seq_id_validation(wiliot_pkts_validation_phase, all_data_pkts)
1291
1290
 
1292
1291
  field_functionality_pass_fail_print(wiliot_pkts_validation_phase, PHASE_NAME)
1293
- test.phases[-1:-1] = [wiliot_pkts_validation_phase]
1292
+ test.add_phase(wiliot_pkts_validation_phase)
1294
1293
  return test
1295
1294
 
1296
1295
 
@@ -1373,19 +1372,19 @@ def generate_graph_stress_test(test, results, test_pkts_received):
1373
1372
  graph_data = []
1374
1373
  for i in range(0, len(results), 2):
1375
1374
  if i + 1 < len(results):
1376
- graph_data.append({'pkts_per_sec': results[i], 'percent_received': results[i + 1]})
1375
+ graph_data.append({'pkts_per_sec': results[i], 'received_pps': results[i + 1]})
1377
1376
 
1378
1377
  graph_df = pd.DataFrame(graph_data)
1379
1378
  html_file_path = os.path.join(ARTIFACTS_DIR, test.dir, 'stress_graph.html')
1380
1379
 
1381
1380
  # First graph: percentage received vs packets per second
1382
- fig1 = px.line(graph_df, x='pkts_per_sec', y='percent_received',
1383
- title='Percentage of packets uploaded by packets per second advertised',
1384
- labels={'pkts_per_sec': 'Packets Sent Per Second', 'percent_received': 'Percentage of packets received'},
1385
- markers=True, text='percent_received')
1381
+ fig1 = px.line(graph_df, x='pkts_per_sec', y='received_pps',
1382
+ title='Packets Per Second Uploaded vs Packets Per Second Advertised',
1383
+ labels={'pkts_per_sec': 'Advertised PPS', 'received_pps': 'Uploaded PPS'},
1384
+ markers=True, text='received_pps')
1386
1385
 
1387
- # Set y-axis to 1-100 scale
1388
- fig1.update_yaxes(range=[1, 100])
1386
+ # Set y-axis to [0 - highest_pps] scale
1387
+ fig1.update_yaxes(range=[0, results[-2]])
1389
1388
 
1390
1389
  # Position text labels next to the markers
1391
1390
  fig1.update_traces(textposition="top right")
@@ -1435,16 +1434,16 @@ def stress_analysis(test, pps, sent_pkts, received_pkts):
1435
1434
  print(f'Number of packets sent: {pkts_sent_count}')
1436
1435
  print(f'Number of packets received: {pkts_received_count}')
1437
1436
  percentage_received = round(pkts_received_count * 100 / pkts_sent_count)
1437
+ received_pps = pps * percentage_received / 100
1438
1438
 
1439
1439
  # PASS/FAIL logic
1440
- stage_pass = pkts_received_count / pkts_sent_count * 100
1441
- if stage_pass < 1: # If less than 1% of the packets were received, fail the test
1440
+ if percentage_received < 1: # If less than 1% of the packets were received, fail the test
1442
1441
  test.rc = TEST_FAILED
1443
1442
  test.reason = "Insufficient amount of packets were scanned & uploaded by the gateway"
1444
1443
  else:
1445
- test.reason = f'{percentage_received}% of packets received, average pps: {pps * percentage_received / 100}'
1444
+ test.reason = f'received pps: {received_pps} ({percentage_received}% of packets)'
1446
1445
 
1447
- return test, percentage_received
1446
+ return test, received_pps
1448
1447
 
1449
1448
 
1450
1449
  def generate_adv_payload(test_indicator, unique_pkt=False):
@@ -313,14 +313,14 @@ def brg_configure_ble5(test, cfg_pkt=None, module=None, fields=None, values=None
313
313
  if wait is False:
314
314
  return test, DONE
315
315
  while not pkts_found:
316
- if ((datetime.datetime.now() - start_time).seconds > ((ag.BLE5_PARAM_PRIMARY_CHANNEL_SCAN_CYCLE/1000)+1)):
316
+ if ((datetime.datetime.now() - start_time).seconds > BLE5_MAX_DURATION_SEC):
317
317
  if num_of_tries < 3:
318
318
  num_of_tries += 1
319
319
  start_time = datetime.datetime.now()
320
320
  gw_downlink(test=test, raw_tx_data=cfg_pkt.dump(), max_duration=BLE5_MAX_DURATION_MS, max_retries=BLE5_MAX_RETRIES, target=target)
321
- print(f"Brg configure - BLE5 mode : No pkts found after {(ag.BLE5_PARAM_PRIMARY_CHANNEL_SCAN_CYCLE/1000)+1} seconds, in try number {num_of_tries}")
321
+ print(f"Brg configure - BLE5 mode : No pkts found after {BLE5_MAX_DURATION_SEC} seconds, in try number {num_of_tries}")
322
322
  else:
323
- test.add_reason(f"Brg configure - BLE5 mode : No pkts found after {BLE5_MAX_DURATION_MS} seconds, in 3 tries")
323
+ test.add_reason(f"Brg configure - BLE5 mode : No pkts found after {BLE5_MAX_DURATION_SEC} seconds, in 3 tries")
324
324
  test.rc = TEST_FAILED
325
325
  time.sleep(1)
326
326
  mqttc.flush_pkts()
@@ -14,6 +14,7 @@ except importlib.metadata.PackageNotFoundError:
14
14
  CERT_VERSION = LOCAL_DEV
15
15
  CERT_MQTT_LOG_FILE = "cert_mqtt_log.json"
16
16
  DATA_SIM_LOG_FILE = "data_sim_log.txt"
17
+ RESULT_NOTES_FILE = "results_notes.txt"
17
18
  UT_RESULT_FILE_HTML = "results.html"
18
19
  UT_RESULT_FILE_PDF = "results.pdf"
19
20
  UTILS_BASE_REL_PATH = "../../../utils"
@@ -255,6 +255,9 @@ def interference_analysis(ble_serial):
255
255
  for key in CNTRS_KEYS:
256
256
  diff_dict[key] = handle_wrap_around(end_cntrs[key] - start_cntrs[key])
257
257
  bad_crc_percentage = round((diff_dict[BAD_CRC] / (diff_dict[WLT_RX] + diff_dict[NON_WLT_RX])) * 100)
258
+ notes_file_path = os.path.join(ARTIFACTS_DIR, RESULT_NOTES_FILE)
259
+ with open(notes_file_path, "a") as f:
260
+ f.write(f'Channel {channel[0]} ({channel[1]} MHz) Ambient Interference (bad CRC percentage): {bad_crc_percentage}%\n')
258
261
  print(color('WARNING', f'Channel {channel[0]} ({channel[1]} MHz) Ambient Interference (bad CRC percentage) is: {bad_crc_percentage}%'))
259
262
  print(f'Good CRC packets = {diff_dict[NON_WLT_RX] + diff_dict[WLT_RX] - diff_dict[BAD_CRC]}, bad CRC packets: {diff_dict[BAD_CRC]}')
260
263
 
@@ -36,6 +36,7 @@ BLE_MAC_ADDRESS = "BLE MAC Address"
36
36
  BOARD_TYPE = "Board Type"
37
37
  BLE_VER = "BLE Version"
38
38
  SUP_API_VER = "Supported API Version"
39
+ ADD_INFO = "Additional information"
39
40
  # TODO: This is a temporary list of all schema module names - remove this when auto generated
40
41
  MODULE_SCHEMA_NAMES_LIST = ["Cloud Connectivity", "Edge Management", "Calibration", "Datapath", "Energizer 2.4GHz",
41
42
  "Energizer Sub-1GHz", "Power Management", "BLE Sensor", "Custom"]
@@ -256,6 +257,13 @@ def generate_results_files(dut=None, tester=None, html=True, pdf=True, failures=
256
257
  hdr_page.append(Paragraph(f"{SIM} {BOARD_TYPE}: {ag.BOARD_TYPES_LIST[internal_brg.board_type]}", bold_text_style))
257
258
  hdr_page.append(Paragraph(f"{SIM} {BLE_VER}: {internal_brg.version}", bold_text_style))
258
259
  hdr_page.append(Paragraph(f"{SIM} {SUP_API_VER}: {internal_brg.api_version}", bold_text_style))
260
+ notes_file_path = os.path.join(ARTIFACTS_DIR, RESULT_NOTES_FILE)
261
+ if os.path.exists(notes_file_path):
262
+ hdr_page.append(Paragraph(f"<u>{ADD_INFO}:</u>", bold_text_style))
263
+ with open(notes_file_path, 'r') as f:
264
+ for line in f.readlines():
265
+ hdr_page.append(Paragraph(f"{line}", bold_text_style))
266
+
259
267
  hdr_page.append(Spacer(1, 20))
260
268
 
261
269
  # Analyze results per module and generate results per module for PDF
certificate/cert_utils.py CHANGED
@@ -220,6 +220,9 @@ class WltTest:
220
220
  return phase
221
221
  return None
222
222
 
223
+ def add_phase(self, phase):
224
+ self.phases[-1:-1] = [phase]
225
+
223
226
  def update_overall_rc(self):
224
227
  if any([phase.rc == TEST_FAILED for phase in self.phases]):
225
228
  self.rc = TEST_FAILED
@@ -22,6 +22,7 @@ energy2400/output_power_test OUTPUT_POWER_2_4_MAX_MINUS_26 OUTPUT_POWER_2_4_MAX_
22
22
  energy2400/duty_cycle_test 1 25 50 75
23
23
  energy2400/signal_indicator_test rssi_threshold rx tx_eu_pattern disable_rx disable_tx rx_tx
24
24
  energy2400/signal_indicator_ble5_test rssi_threshold rx tx disable_rx disable_tx rx_tx
25
+ energy2400/signal_indicator_ext_adv_test ext_adv_rx37 ext_adv_rx10
25
26
 
26
27
  # ------------- energy_sub1g -------------
27
28
  energy_sub1g/pattern_test SUB1G_ENERGY_PATTERN_NO_ENERGIZING SUB1G_ENERGY_PATTERN_SINGLE_TONE_915000 SUB1G_ENERGY_PATTERN_FCC_HOPPING SUB1G_ENERGY_PATTERN_SINGLE_TONE_917500 SUB1G_ENERGY_PATTERN_NZ_HOPPING
@@ -67,8 +68,9 @@ cloud_connectivity/uplink_test mgmt_pkt pixels_pkt sensor_pkt
67
68
  cloud_connectivity/downlink_test
68
69
  cloud_connectivity/uplink_ext_adv_test
69
70
  cloud_connectivity/reboot_test
70
- cloud_connectivity/stress_test 20 40 60 80 100 120 140 160 180 200 222 250 285 333
71
- cloud_connectivity/ext_adv_stress_test 20 40 60 80 100 120 140 160 180 200
71
+ cloud_connectivity/stress_test
72
+ cloud_connectivity/ext_adv_stress_test
72
73
  cloud_connectivity/channel_scan_behaviour_test
73
74
  cloud_connectivity/acl_test deny allow
74
- cloud_connectivity/acl_ext_adv_test deny allow
75
+ cloud_connectivity/acl_ext_adv_test deny allow
76
+ cloud_connectivity/deduplication_test
@@ -22,6 +22,7 @@ energy2400/output_power_test OUTPUT_POWER_2_4_MAX_MINUS_14 OUTPUT_POWER_2_4_MAX_
22
22
  energy2400/duty_cycle_test 1 50 75
23
23
  energy2400/signal_indicator_test rx_tx
24
24
  energy2400/signal_indicator_ble5_test rx_tx
25
+ energy2400/signal_indicator_ext_adv_test ext_adv_rx37
25
26
 
26
27
  # ------------- energy_sub1g -------------
27
28
  energy_sub1g/pattern_test SUB1G_ENERGY_PATTERN_NO_ENERGIZING SUB1G_ENERGY_PATTERN_FCC_HOPPING SUB1G_ENERGY_PATTERN_SINGLE_TONE_917500 SUB1G_ENERGY_PATTERN_NZ_HOPPING
@@ -59,7 +60,7 @@ cloud_connectivity/uplink_test mgmt_pkt pixels_pkt
59
60
  cloud_connectivity/downlink_test
60
61
  cloud_connectivity/uplink_ext_adv_test
61
62
  cloud_connectivity/reboot_test
62
- cloud_connectivity/stress_test 100 222
63
- cloud_connectivity/ext_adv_stress_test 20 100
63
+ cloud_connectivity/stress_test
64
+ cloud_connectivity/ext_adv_stress_test
64
65
  cloud_connectivity/acl_test deny
65
66
  cloud_connectivity/acl_ext_adv_test allow
@@ -22,7 +22,7 @@ energy2400/output_power_test OUTPUT_POWER_2_4_MAX_MINUS_26 OUTPUT_POWER_2_4_MAX_
22
22
  energy2400/duty_cycle_test 1 25 50 75
23
23
  energy2400/signal_indicator_test rssi_threshold rx tx_eu_pattern disable_rx disable_tx rx_tx
24
24
  energy2400/signal_indicator_ble5_test rssi_threshold rx tx disable_rx disable_tx rx_tx
25
- #energy2400/signal_indicator_ext_adv_test rssi_threshold brg0_tx_brg1_rx brg0_rxtx_brg1_rxtx
25
+ energy2400/signal_indicator_ext_adv_test ext_adv_rx37 ext_adv_rx10
26
26
 
27
27
  # ------------- energy_sub1g -------------
28
28
  energy_sub1g/pattern_test SUB1G_ENERGY_PATTERN_NO_ENERGIZING SUB1G_ENERGY_PATTERN_SINGLE_TONE_915000 SUB1G_ENERGY_PATTERN_FCC_HOPPING SUB1G_ENERGY_PATTERN_SINGLE_TONE_917500 SUB1G_ENERGY_PATTERN_NZ_HOPPING
@@ -67,9 +67,10 @@ cloud_connectivity/uplink_test mgmt_pkt pixels_pkt sensor_pkt geolocation
67
67
  cloud_connectivity/downlink_test
68
68
  cloud_connectivity/uplink_ext_adv_test
69
69
  cloud_connectivity/reboot_test
70
- cloud_connectivity/stress_test 20 40 60 80 100 120 140 160 180 200 222 250 285 333
71
- cloud_connectivity/ext_adv_stress_test 20 40 60 80 100 120 140 160 180 200
70
+ cloud_connectivity/stress_test
71
+ cloud_connectivity/ext_adv_stress_test
72
72
  cloud_connectivity/channel_scan_behaviour_test
73
73
  cloud_connectivity/acl_test deny allow
74
74
  cloud_connectivity/acl_ext_adv_test deny allow
75
75
  cloud_connectivity/brg_ota_test
76
+ cloud_connectivity/deduplication_test
@@ -2,7 +2,7 @@
2
2
  "name": "Access Control List using Extended Advertising",
3
3
  "module": "Cloud Connectivity",
4
4
  "purpose": "Test the access control list (ACL) functionality, configure allow list and deny list and test the behavior, while the Bridge is transmitting in extended advertising",
5
- "documentation": "<TEST_DOCUMENTATION_LINK>",
5
+ "documentation": "https://community.wiliot.com/customers/s/article/Wiliot-Network---Gateway-Extended-Advertising-Implementation",
6
6
  "initialCondition": "Gateway configured to defaults",
7
7
  "procedure": ["Test prolog", "configure the brg to be on the deny list", "configure the brg to be on the allow list", "Test epilog"],
8
8
  "expectedOutcome": "For the deny list - no unified packets are found, for the allow list - unified packets are found",
@@ -2,7 +2,7 @@
2
2
  "name": "Access Control List",
3
3
  "module": "Cloud Connectivity",
4
4
  "purpose": "Test the access control list (ACL) functionality, configure allow list and deny list and test the behavior",
5
- "documentation": "<TEST_DOCUMENTATION_LINK>",
5
+ "documentation": "https://community.wiliot.com/customers/s/article/Access-Control-List",
6
6
  "initialCondition": "Gateway configured to defaults",
7
7
  "procedure": ["Test prolog", "configure the brg to be on the deny list", "configure the brg to be on the allow list", "Test epilog"],
8
8
  "expectedOutcome": "For the deny list - no unified packets are found, for the allow list - unified packets are found",
@@ -2,7 +2,7 @@
2
2
  "name": "Gateway Channel behavior",
3
3
  "module": "Cloud Connectivity",
4
4
  "purpose": "Test gateway's channel scanning time cycles on all main channels",
5
- "documentation": "<TEST_DOCUMENTATION_LINK>",
5
+ "documentation": "",
6
6
  "initialCondition": "Gateway configured with default settings",
7
7
  "procedure": ["Test prolog",
8
8
  "Send packets as close as possible to continuously on all 3 channels, with a unique channel identifier",
@@ -0,0 +1,14 @@
1
+ {
2
+ "name": "Gateway Deduplication",
3
+ "module": "Cloud Connectivity",
4
+ "purpose": "Test gateway's packet deduplication capability when receiving identical BLE packets",
5
+ "documentation": "",
6
+ "initialCondition": "Gateway configured to defaults",
7
+ "procedure": ["Test prolog", "Send mixed packet types (pixels, mgmt, sensor, side_info_sensor) via data simulator", "Collect received packets from MQTT", "Analyze duplicate packets and calculate duplicate percentage", "Test epilog"],
8
+ "expectedOutcome": "Duplicate percentage should be <= 5% of total received packets",
9
+ "mandatory": 0,
10
+ "multiBridgeTest": 0,
11
+ "gwOnlyTest": 1,
12
+ "dataSimOnlyTest": 1,
13
+ "allSupportedValues": []
14
+ }
@@ -0,0 +1,85 @@
1
+ # This test meant to show the GW performance when is put in a pkt stress generated from the BLE via the UART
2
+ from certificate.cert_prints import *
3
+ from certificate.cert_defines import *
4
+ from certificate.wlt_types import *
5
+ import certificate.cert_common as cert_common
6
+ import certificate.cert_utils as cert_utils
7
+ import certificate.cert_mqtt as cert_mqtt
8
+ import certificate.cert_data_sim as cert_data_sim
9
+ import pandas as pd
10
+
11
+
12
+ # DEFINES
13
+ UPLINK_TEST_INDICATOR = cert_utils.get_random_hex_str(len=6)
14
+ NUM_OF_BRGS = 3
15
+
16
+
17
+ # HELPER FUNCTIONS
18
+ def duplication_analysis(test, pkts, received_pkts):
19
+ if len(received_pkts) == 0:
20
+ test.rc = TEST_FAILED
21
+ test.reason = "No packets were received!"
22
+ return test
23
+
24
+ _sent_pkts = []
25
+ for pkt in pkts:
26
+ pkt_str = pkt.get_pkt()
27
+ adva_endianness_change = cert_common.change_endianness(pkt_str[:12]) + pkt_str[12:] # Switch to big endian adva
28
+ _sent_pkts.append(adva_endianness_change)
29
+
30
+ sent_df = pd.DataFrame(_sent_pkts, columns=[PACKETS])
31
+ received_df = pd.DataFrame(received_pkts, columns=[PACKETS])
32
+
33
+ merged_df = pd.merge(sent_df, received_df, on=PACKETS, how='inner')
34
+ # Count total received packets (including duplicates) and unique packets
35
+ pkts_received_total = len(merged_df)
36
+ merged_df_unique = merged_df.drop_duplicates(subset=[PACKETS])
37
+ pkts_duplicates = pkts_received_total - len(merged_df_unique)
38
+
39
+ # Prints
40
+ print(f'Number of packets sent: {len(sent_df)}')
41
+ print(f'Number of packets received in total: {pkts_received_total}, out of them {pkts_duplicates} are duplicates')
42
+
43
+ duplicate_percentage = (pkts_duplicates / pkts_received_total) * 100
44
+ print(f'{duplicate_percentage:.2f}% of the received packets are duplicates')
45
+
46
+ if duplicate_percentage > 5.0:
47
+ test.rc = TEST_FAILED
48
+ test.reason = f"{duplicate_percentage:.2f}% of the received packets are duplicates"
49
+ return test
50
+
51
+ return test
52
+
53
+
54
+ def run(test):
55
+ test = cert_common.test_prolog(test)
56
+ if test.rc == TEST_FAILED:
57
+ return cert_common.test_epilog(test)
58
+
59
+ dut_mqttc = test.get_mqttc_by_target(DUT)
60
+ dut_mqttc.flush_pkts()
61
+ pkts = []
62
+
63
+ # generate pkts and send them using data simulator
64
+ data_pkts, _ = cert_data_sim.brg_pkt_gen(num_of_pkts_per_brg=10, num_of_brgs=NUM_OF_BRGS,
65
+ pkt_type=PIXELS_PKT, indicator=UPLINK_TEST_INDICATOR)
66
+
67
+ mgmt_pkts, _ = cert_data_sim.brg_pkt_gen(num_of_pkts_per_brg=10, num_of_brgs=NUM_OF_BRGS,
68
+ pkt_type=MGMT_PKT, indicator=UPLINK_TEST_INDICATOR)
69
+ sensor_pkts, _ = cert_data_sim.brg_pkt_gen(num_of_pkts_per_brg=10, num_of_brgs=NUM_OF_BRGS,
70
+ pkt_type=SENSOR_PKT, indicator=UPLINK_TEST_INDICATOR)
71
+ si_pkts, _ = cert_data_sim.brg_pkt_gen(num_of_pkts_per_brg=10, num_of_brgs=NUM_OF_BRGS,
72
+ pkt_type=SIDE_INFO_SENSOR_PKT, indicator=UPLINK_TEST_INDICATOR)
73
+ pkts = data_pkts + mgmt_pkts + sensor_pkts + si_pkts
74
+
75
+ pixel_sim_thread = cert_data_sim.GenericSimThread(test=test, pkts=pkts, send_single_cycle=True)
76
+ pixel_sim_thread.start()
77
+
78
+ mqtt_scan_wait(test, 10 + test.dut.upload_wait_time)
79
+ cert_mqtt.dump_pkts(test, log="deduplication_test")
80
+ recieved_pkts = cert_mqtt.get_all_data_pkts(dut_mqttc, indicator=UPLINK_TEST_INDICATOR)
81
+ pixel_sim_thread.stop()
82
+
83
+ test = duplication_analysis(test, pkts, [p[ALIAS_BRIDGE_ID] + p[PAYLOAD] for p in recieved_pkts])
84
+
85
+ return cert_common.test_epilog(test)
@@ -121,10 +121,7 @@ def report_and_results(test, sniffed_pkts):
121
121
  test.reason = 'No packets collected.'
122
122
  return
123
123
 
124
- if test.active_brg.board_type == ag.BOARD_TYPE_FANSTEL_WIFI_V0:
125
- x_value = ('tx_max_retries', 'TX Max Retries')
126
- else:
127
- x_value = ('tx_max_duration', 'TX Max Duration')
124
+ x_value = ('tx_max_duration', 'TX Max Duration')
128
125
 
129
126
  # Create scatter with OLS trendline per channel
130
127
  fig = px.scatter(
@@ -12,5 +12,5 @@
12
12
  "multiBridgeTest": 0,
13
13
  "gwOnlyTest": 1,
14
14
  "dataSimOnlyTest": 1,
15
- "allSupportedValues": [20, 40, 60, 80, 100, 120, 140, 160, 180, 200]
15
+ "allSupportedValues": []
16
16
  }
@@ -51,13 +51,13 @@ def run(test):
51
51
 
52
52
  cert_config.gw_action(test, f'{cert_gw_sim.BLE_SIM_INIT} 1', TESTER)
53
53
 
54
+ ppses = [20, 40, 60, 80, 100, 120, 140, 160, 180, 200]
54
55
  test_pkts_received = []
55
56
  data_pkts_received = []
56
57
  results = []
57
- for param in test.params:
58
- phase_run_print(f"PPS = {param}")
58
+ for pps in ppses:
59
+ phase_run_print(f"PPS = {pps}")
59
60
  test.flush_all_mqtt_packets()
60
- pps = param.value
61
61
  # adv_duration is increased only for lowest pps to increase packets sample for reliable results
62
62
  adv_duration = ADV_DURATION_LOWEST_PPS if pps == LOWEST_PPS else ADV_DURATION_DEFAULT
63
63
  delay = math.floor(1000 / pps) # This should be bigger than 2ms
@@ -74,17 +74,18 @@ def run(test):
74
74
  cert_config.gw_action(test, gw_action_cmd, TESTER)
75
75
  mqtt_scan_wait(test, adv_duration + upload_wait_time)
76
76
 
77
- cert_mqtt.dump_pkts(test, log=param.name)
77
+ cert_mqtt.dump_pkts(test, log=str(pps))
78
78
  phase_pkts_received = cert_mqtt.get_all_aggregated_data_pkts(test.get_mqttc_by_target(DUT), indicator=STRESS_TEST_INDICATOR)
79
79
 
80
- test, percentage_received = cert_common.stress_analysis(
80
+ test, received_pps = cert_common.stress_analysis(
81
81
  test, pps, generated_payloads,
82
82
  [(p[ALIAS_BRIDGE_ID] + p[AGGREGATED_PAYLOAD]) for p in phase_pkts_received])
83
- results.extend([pps, percentage_received])
84
- cert_mqtt.generate_log_file(test, param.name)
83
+ results.extend([pps, received_pps])
84
+ cert_mqtt.generate_log_file(test, str(pps))
85
85
 
86
- test.set_phase_rc(param.name, test.rc)
87
- test.add_phase_reason(param.name, test.reason)
86
+ test.add_phase(cert_utils.Phase(pps))
87
+ test.set_phase_rc(str(pps), test.rc)
88
+ test.add_phase_reason(str(pps), test.reason)
88
89
  if test.rc == TEST_FAILED and test.exit_on_param_failure:
89
90
  break # break the whole for loop and keep the test as failed
90
91
  test.reset_result() # reset result and continue to next param
@@ -12,5 +12,5 @@
12
12
  "multiBridgeTest": 0,
13
13
  "gwOnlyTest": 1,
14
14
  "dataSimOnlyTest": 1,
15
- "allSupportedValues": [20, 40, 60, 80, 100, 120, 140, 160, 180, 200, 222, 250, 285, 333]
15
+ "allSupportedValues": []
16
16
  }
@@ -50,14 +50,13 @@ def run(test):
50
50
  return cert_common.test_epilog(test)
51
51
 
52
52
  cert_config.gw_action(test, f'{cert_gw_sim.BLE_SIM_INIT} 1', TESTER)
53
-
53
+ ppses = [20, 40, 60, 80, 100, 120, 140, 160, 180, 200, 222, 250, 285, 333]
54
54
  test_pkts_received = []
55
55
  data_pkts_received = []
56
56
  results = []
57
- for param in test.params:
58
- phase_run_print(f"PPS = {param}")
57
+ for pps in ppses:
58
+ phase_run_print(f"PPS = {pps}")
59
59
  test.flush_all_mqtt_packets()
60
- pps = param.value
61
60
  # adv_duration is increased only for lowest pps to increase packets sample for reliable results
62
61
  adv_duration = ADV_DURATION_LOWEST_PPS if pps == LOWEST_PPS else ADV_DURATION_DEFAULT
63
62
  delay = math.floor(1000 / pps)
@@ -73,17 +72,18 @@ def run(test):
73
72
  f'{BLE_SIM_ADV_37_38_39} {delay} {BLE_SIM_RADIO_1MBPS} {adv_duration * pps}', TESTER)
74
73
  mqtt_scan_wait(test, adv_duration + upload_wait_time)
75
74
 
76
- cert_mqtt.dump_pkts(test, log=param.name)
75
+ cert_mqtt.dump_pkts(test, log=str(pps))
77
76
  phase_pkts_received = cert_mqtt.get_all_data_pkts(test.get_mqttc_by_target(DUT), indicator=STRESS_TEST_INDICATOR)
78
77
 
79
- test, percentage_received = cert_common.stress_analysis(
78
+ test, received_pps = cert_common.stress_analysis(
80
79
  test, pps, generated_payloads,
81
80
  [(p[ALIAS_BRIDGE_ID] + p[PAYLOAD]) for p in phase_pkts_received])
82
- results.extend([pps, percentage_received])
83
- cert_mqtt.generate_log_file(test, param.name)
81
+ results.extend([pps, received_pps])
82
+ cert_mqtt.generate_log_file(test, str(pps))
84
83
 
85
- test.set_phase_rc(param.name, test.rc)
86
- test.add_phase_reason(param.name, test.reason)
84
+ test.add_phase(cert_utils.Phase(pps))
85
+ test.set_phase_rc(str(pps), test.rc)
86
+ test.add_phase_reason(str(pps), test.reason)
87
87
  if test.rc == TEST_FAILED and test.exit_on_param_failure:
88
88
  break # break the whole for loop and keep the test as failed
89
89
  test.reset_result() # reset result and continue to next param
@@ -130,6 +130,7 @@ def run(test):
130
130
 
131
131
  mqtt_scan_wait(test, 10 + test.dut.upload_wait_time)
132
132
  cert_mqtt.dump_pkts(test, log=param.name)
133
+ pixel_sim_thread.stop()
133
134
  all_data_messages_in_test.extend(dut_mqttc._userdata[PKTS].data)
134
135
  all_data_pkts.extend(cert_mqtt.get_all_data_pkts(dut_mqttc))
135
136
  recieved_pkts = cert_mqtt.get_all_data_pkts(dut_mqttc, indicator=UPLINK_TEST_INDICATOR)
@@ -63,10 +63,11 @@ def run(test):
63
63
  test = cert_common.test_prolog(test)
64
64
  if test.rc == TEST_FAILED:
65
65
  return cert_common.test_epilog(test)
66
+ dut = cert_config.get_brg_by_target(test, DUT)
66
67
 
67
68
  for param in test.params:
68
69
  phase_run_print(param.name)
69
- test = EVENT_TEST_MAP[param.value](test, param.name, test.active_brg.datapath)
70
+ test = EVENT_TEST_MAP[param.value](test, param.name, dut.datapath)
70
71
  cert_mqtt.generate_log_file(test, param.name)
71
72
  field_functionality_pass_fail_print(test, param.name)
72
73
  test.set_phase_rc(param.name, test.rc)
@@ -79,10 +80,11 @@ def run(test):
79
80
  continue
80
81
 
81
82
  # Reset to defaults after every phase (don't fail the phase on that)
82
- test = cert_config.config_brg_defaults(test, modules=[test.active_brg.datapath], ble5=True)[0]
83
- print_update_wait(2 * BLE5_MAX_DURATION_SEC)
83
+ test = cert_config.config_brg_defaults(test, modules=[dut.datapath], ble5=test.dut_is_bridge())[0]
84
84
  if test.rc == TEST_FAILED:
85
85
  test.add_reason("Failed to restore brg to defaults")
86
+ if test.dut_is_bridge():
87
+ wait_time_n_print(BLE5_MAX_DURATION_SEC)
86
88
 
87
89
  if test.rc == TEST_FAILED:
88
90
  test.set_phase_rc(param.name, test.rc)
@@ -92,4 +94,4 @@ def run(test):
92
94
  else:
93
95
  test.reset_result()
94
96
 
95
- return cert_common.test_epilog(test, revert_brgs=True, modules=[test.active_brg.datapath], ble5=True)
97
+ return cert_common.test_epilog(test, revert_brgs=True, modules=[dut.datapath], ble5=test.dut_is_bridge())
@@ -54,10 +54,11 @@ def run(test):
54
54
  test = cert_common.test_prolog(test)
55
55
  if test.rc == TEST_FAILED:
56
56
  return cert_common.test_epilog(test)
57
+ dut = cert_config.get_brg_by_target(test, DUT)
57
58
 
58
59
  for param in test.params:
59
60
  phase_run_print(param.name)
60
- test = EVENT_TEST_MAP[param.value](test, param.name, test.active_brg.datapath)
61
+ test = EVENT_TEST_MAP[param.value](test, param.name, dut.datapath)
61
62
  cert_mqtt.generate_log_file(test, param.name)
62
63
  field_functionality_pass_fail_print(test, param.name)
63
64
  test.set_phase_rc(param.name, test.rc)
@@ -70,7 +71,7 @@ def run(test):
70
71
  continue
71
72
 
72
73
  # Reset to defaults after every phase (don't fail the phase on that)
73
- test = cert_config.config_brg_defaults(test, modules=[test.active_brg.datapath])[0]
74
+ test = cert_config.config_brg_defaults(test, modules=[dut.datapath])[0]
74
75
  if test.rc == TEST_FAILED:
75
76
  test.add_reason("Failed to restore brg to defaults")
76
77
 
@@ -82,4 +83,4 @@ def run(test):
82
83
  else:
83
84
  test.reset_result()
84
85
 
85
- return cert_common.test_epilog(test, revert_brgs=True, modules=[test.active_brg.datapath])
86
+ return cert_common.test_epilog(test, revert_brgs=True, modules=[dut.datapath])
@@ -2,7 +2,7 @@
2
2
  "name": "Supported Pixels",
3
3
  "module": "Datapath",
4
4
  "purpose": "Test pixels handling in the bridge for different amount of pixels",
5
- "documentation": "<TEST_DOCUMENTATION_LINK>",
5
+ "documentation": "",
6
6
  "initialCondition": "Bridge & data simulator configured to defaults",
7
7
  "procedure": ["Test prolog",
8
8
  "Generate packets from the given amount of pixels & scan for packets in the bridge",
@@ -10,15 +10,15 @@ import certificate.cert_data_sim as cert_data_sim
10
10
  def run(test):
11
11
 
12
12
  fields = [BRG_PACER_INTERVAL, BRG_RX_CHANNEL, BRG_PKT_FILTER]
13
- datapath_module = test.active_brg.datapath
13
+ dut = cert_config.get_brg_by_target(test, DUT)
14
14
 
15
15
  test = cert_common.test_prolog(test)
16
16
  if test.rc == TEST_FAILED:
17
17
  return cert_common.test_epilog(test)
18
18
 
19
19
  for param in test.params:
20
- test = cert_config.brg_configure_ble5(test, fields=fields, values=[param.value, ag.RX_CHANNEL_10_500K, ag.PKT_FILTER_TEMP_PKT],
21
- module=datapath_module)[0]
20
+ test = cert_config.brg_configure(test, fields=fields, values=[param.value, ag.RX_CHANNEL_10_500K, ag.PKT_FILTER_TEMP_PKT],
21
+ module=dut.datapath, ble5=test.dut_is_bridge())[0]
22
22
  if test.rc == TEST_FAILED:
23
23
  if test.exit_on_param_failure:
24
24
  break # break the whole for loop and keep the test as failed
@@ -49,4 +49,4 @@ def run(test):
49
49
  break # break the whole for loop and keep the test as failed
50
50
  test.reset_result() # reset result and continue to next param
51
51
 
52
- return cert_common.test_epilog(test, revert_brgs=True, revert_gws=test.internal_brg, modules=[datapath_module], ble5=True)
52
+ return cert_common.test_epilog(test, revert_brgs=True, revert_gws=test.internal_brg, modules=[dut.datapath], ble5=test.dut_is_bridge())
@@ -12,16 +12,16 @@ PKT_FILTER_TEST_PACER_INTERVAL = 10
12
12
  def run(test):
13
13
 
14
14
  fields = [BRG_PKT_FILTER, BRG_RX_CHANNEL, BRG_PACER_INTERVAL]
15
- datapath_module = eval(f'ModuleDatapathV{test.active_brg.api_version}')
15
+ dut = cert_config.get_brg_by_target(test, DUT)
16
16
 
17
17
  test = cert_common.test_prolog(test)
18
18
  if test.rc == TEST_FAILED:
19
19
  return cert_common.test_epilog(test)
20
20
 
21
21
  for param in test.params:
22
- test = cert_config.brg_configure_ble5(test, fields=fields,
23
- values=[param.value, RX_CHANNEL_21, PKT_FILTER_TEST_PACER_INTERVAL],
24
- module=datapath_module)[0]
22
+ test = cert_config.brg_configure(test, fields=fields,
23
+ values=[param.value, RX_CHANNEL_21, PKT_FILTER_TEST_PACER_INTERVAL],
24
+ module=dut.datapath, ble5=test.dut_is_bridge())[0]
25
25
  test.set_phase_rc(param.name, test.rc)
26
26
  test.add_phase_reason(param.name, test.reason)
27
27
  if test.rc == TEST_FAILED:
@@ -58,4 +58,4 @@ def run(test):
58
58
  break # break the whole for loop and keep the test as failed
59
59
  test.reset_result() # reset result and continue to next param
60
60
 
61
- return cert_common.test_epilog(test, revert_brgs=True, revert_gws=test.internal_brg, modules=[datapath_module], ble5=True)
61
+ return cert_common.test_epilog(test, revert_brgs=True, revert_gws=test.internal_brg, modules=[dut.datapath], ble5=test.dut_is_bridge())
@@ -12,16 +12,16 @@ PKT_FILTER_TEST_PACER_INTERVAL = 10
12
12
  def run(test):
13
13
 
14
14
  fields = [BRG_PKT_FILTER, BRG_RX_CHANNEL, BRG_PACER_INTERVAL]
15
- datapath_module = eval(f'ModuleDatapathV{test.active_brg.api_version}')
15
+ dut = cert_config.get_brg_by_target(test, DUT)
16
16
 
17
17
  test = cert_common.test_prolog(test)
18
18
  if test.rc == TEST_FAILED:
19
19
  return cert_common.test_epilog(test)
20
20
 
21
21
  for param in test.params:
22
- test = cert_config.brg_configure_ble5(test, fields=fields,
23
- values=[param.value, RX_CHANNEL_10_500K, PKT_FILTER_TEST_PACER_INTERVAL],
24
- module=datapath_module)[0]
22
+ test = cert_config.brg_configure(test, fields=fields,
23
+ values=[param.value, RX_CHANNEL_10_500K, PKT_FILTER_TEST_PACER_INTERVAL],
24
+ module=dut.datapath, ble5=test.dut_is_bridge())[0]
25
25
  test.set_phase_rc(param.name, test.rc)
26
26
  test.add_phase_reason(param.name, test.reason)
27
27
  if test.rc == TEST_FAILED:
@@ -57,4 +57,4 @@ def run(test):
57
57
  break # break the whole for loop and keep the test as failed
58
58
  test.reset_result() # reset result and continue to next param
59
59
 
60
- return cert_common.test_epilog(test, revert_brgs=True, revert_gws=test.internal_brg, modules=[datapath_module], ble5=True)
60
+ return cert_common.test_epilog(test, revert_brgs=True, revert_gws=test.internal_brg, modules=[dut.datapath], ble5=test.dut_is_bridge())