wiliot-certificate 4.4.3__py3-none-any.whl → 4.5.0a1__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 (295) hide show
  1. {brg_certificate → certificate}/ag/wlt_cmd_if.html +10 -4
  2. {brg_certificate → certificate}/ag/wlt_types_ag.py +1878 -519
  3. {brg_certificate → certificate}/ag/wlt_types_ag_jsons/brg2brg_ota.json +69 -0
  4. {brg_certificate → certificate}/ag/wlt_types_ag_jsons/brg2gw_hb.json +109 -0
  5. {brg_certificate → certificate}/ag/wlt_types_ag_jsons/brg2gw_hb_sleep.json +45 -0
  6. {brg_certificate → certificate}/ag/wlt_types_ag_jsons/calibration.json +96 -0
  7. {brg_certificate → certificate}/ag/wlt_types_ag_jsons/custom.json +99 -0
  8. {brg_certificate → certificate}/ag/wlt_types_ag_jsons/datapath.json +241 -13
  9. {brg_certificate → certificate}/ag/wlt_types_ag_jsons/energy2400.json +120 -0
  10. {brg_certificate → certificate}/ag/wlt_types_ag_jsons/energySub1g.json +96 -0
  11. {brg_certificate → certificate}/ag/wlt_types_ag_jsons/externalSensor.json +135 -6
  12. {brg_certificate → certificate}/ag/wlt_types_ag_jsons/interface.json +157 -0
  13. {brg_certificate → certificate}/ag/wlt_types_ag_jsons/powerManagement.json +205 -0
  14. brg_certificate/ag/wlt_types_ag_jsons/unified_echo_pkt.json → certificate/ag/wlt_types_ag_jsons/unified_echo_ext_pkt.json +27 -11
  15. certificate/ag/wlt_types_ag_jsons/unified_echo_pkt.json +175 -0
  16. certificate/ag/wlt_types_ag_jsons/unified_sensor_pkt.json +65 -0
  17. certificate/cert_common.py +1459 -0
  18. certificate/cert_config.py +455 -0
  19. {brg_certificate → certificate}/cert_data_sim.py +131 -46
  20. {brg_certificate → certificate}/cert_defines.py +120 -128
  21. {brg_certificate → certificate}/cert_gw_sim.py +151 -49
  22. {brg_certificate → certificate}/cert_mqtt.py +164 -59
  23. {brg_certificate → certificate}/cert_prints.py +34 -33
  24. {brg_certificate → certificate}/cert_protobuf.py +15 -6
  25. {brg_certificate → certificate}/cert_results.py +205 -48
  26. certificate/cert_utils.py +622 -0
  27. certificate/certificate.py +198 -0
  28. certificate/certificate_cli.py +79 -0
  29. certificate/certificate_eth_test_list.txt +74 -0
  30. certificate/certificate_sanity_test_list.txt +65 -0
  31. certificate/certificate_test_list.txt +75 -0
  32. {brg_certificate → certificate}/tests/calibration/interval_test/interval_test.json +2 -2
  33. {brg_certificate → certificate}/tests/calibration/interval_test/interval_test.py +7 -6
  34. certificate/tests/calibration/output_power_test/output_power_test.json +22 -0
  35. certificate/tests/calibration/output_power_test/output_power_test.py +39 -0
  36. {brg_certificate → certificate}/tests/calibration/pattern_test/pattern_test.json +1 -1
  37. {brg_certificate → certificate}/tests/calibration/pattern_test/pattern_test.py +20 -15
  38. certificate/tests/cloud_connectivity/acl_ext_adv_test/acl_ext_adv_test.json +14 -0
  39. certificate/tests/cloud_connectivity/acl_ext_adv_test/acl_ext_adv_test.py +140 -0
  40. certificate/tests/cloud_connectivity/acl_test/acl_test.json +14 -0
  41. certificate/tests/cloud_connectivity/acl_test/acl_test.py +98 -0
  42. certificate/tests/cloud_connectivity/brg_ota_test/brg_ota_test.json +18 -0
  43. certificate/tests/cloud_connectivity/brg_ota_test/brg_ota_test.py +39 -0
  44. certificate/tests/cloud_connectivity/channel_scan_behaviour_test/channel_scan_behaviour_test.json +18 -0
  45. certificate/tests/cloud_connectivity/channel_scan_behaviour_test/channel_scan_behaviour_test.py +215 -0
  46. certificate/tests/cloud_connectivity/connection_test/connection_test.json +17 -0
  47. certificate/tests/cloud_connectivity/connection_test/connection_test.py +74 -0
  48. certificate/tests/cloud_connectivity/downlink_test/downlink_test.json +20 -0
  49. certificate/tests/cloud_connectivity/downlink_test/downlink_test.py +204 -0
  50. certificate/tests/cloud_connectivity/ext_adv_stress_test/ext_adv_stress_test.json +16 -0
  51. certificate/tests/cloud_connectivity/ext_adv_stress_test/ext_adv_stress_test.py +98 -0
  52. certificate/tests/cloud_connectivity/reboot_test/reboot_test.json +17 -0
  53. certificate/tests/cloud_connectivity/reboot_test/reboot_test.py +57 -0
  54. certificate/tests/cloud_connectivity/registration_test/registration_test.json +19 -0
  55. certificate/tests/cloud_connectivity/registration_test/registration_test.py +384 -0
  56. certificate/tests/cloud_connectivity/registration_test/registration_test_cli.py +90 -0
  57. certificate/tests/cloud_connectivity/stress_test/stress_test.json +16 -0
  58. certificate/tests/cloud_connectivity/stress_test/stress_test.py +97 -0
  59. certificate/tests/cloud_connectivity/uplink_ext_adv_test/uplink_ext_adv_test.json +24 -0
  60. certificate/tests/cloud_connectivity/uplink_ext_adv_test/uplink_ext_adv_test.py +93 -0
  61. certificate/tests/cloud_connectivity/uplink_test/uplink_test.json +19 -0
  62. certificate/tests/cloud_connectivity/uplink_test/uplink_test.py +161 -0
  63. {brg_certificate → certificate}/tests/datapath/aging_test/aging_test.json +1 -1
  64. certificate/tests/datapath/aging_test/aging_test.py +138 -0
  65. certificate/tests/datapath/event_ble5_test/event_ble5_test.json +16 -0
  66. certificate/tests/datapath/event_ble5_test/event_ble5_test.py +95 -0
  67. certificate/tests/datapath/event_test/event_test.json +16 -0
  68. certificate/tests/datapath/event_test/event_test.py +85 -0
  69. {brg_certificate → certificate}/tests/datapath/num_of_tags_test/num_of_tags_test.json +1 -1
  70. {brg_certificate → certificate}/tests/datapath/num_of_tags_test/num_of_tags_test.py +10 -8
  71. certificate/tests/datapath/output_power_test/output_power_test.json +22 -0
  72. {brg_certificate → certificate}/tests/datapath/output_power_test/output_power_test.py +17 -6
  73. {brg_certificate → certificate}/tests/datapath/pacer_interval_ble5_test/pacer_interval_ble5_test.json +1 -1
  74. {brg_certificate → certificate}/tests/datapath/pacer_interval_ble5_test/pacer_interval_ble5_test.py +10 -8
  75. {brg_certificate → certificate}/tests/datapath/pacer_interval_test/pacer_interval_test.json +1 -1
  76. {brg_certificate → certificate}/tests/datapath/pacer_interval_test/pacer_interval_test.py +9 -7
  77. {brg_certificate → certificate}/tests/datapath/pattern_test/pattern_test.json +2 -2
  78. {brg_certificate → certificate}/tests/datapath/pattern_test/pattern_test.py +18 -6
  79. certificate/tests/datapath/pkt_filter_ble5_chl21_test/pkt_filter_ble5_chl21_test.json +19 -0
  80. certificate/tests/datapath/pkt_filter_ble5_chl21_test/pkt_filter_ble5_chl21_test.py +61 -0
  81. {brg_certificate → certificate}/tests/datapath/pkt_filter_ble5_test/pkt_filter_ble5_test.json +1 -1
  82. {brg_certificate → certificate}/tests/datapath/pkt_filter_ble5_test/pkt_filter_ble5_test.py +11 -10
  83. certificate/tests/datapath/pkt_filter_brg2gw_ext_adv_test/pkt_filter_brg2gw_ext_adv_test.json +18 -0
  84. certificate/tests/datapath/pkt_filter_brg2gw_ext_adv_test/pkt_filter_brg2gw_ext_adv_test.py +83 -0
  85. {brg_certificate → certificate}/tests/datapath/pkt_filter_gen3_test/pkt_filter_gen3_test.json +1 -1
  86. {brg_certificate → certificate}/tests/datapath/pkt_filter_gen3_test/pkt_filter_gen3_test.py +10 -9
  87. {brg_certificate → certificate}/tests/datapath/pkt_filter_test/pkt_filter_test.json +1 -1
  88. {brg_certificate → certificate}/tests/datapath/pkt_filter_test/pkt_filter_test.py +10 -9
  89. {brg_certificate → certificate}/tests/datapath/rssi_threshold_test/rssi_threshold_test.json +1 -1
  90. {brg_certificate → certificate}/tests/datapath/rssi_threshold_test/rssi_threshold_test.py +9 -8
  91. brg_certificate/tests/datapath/output_power_test/output_power_test.json → certificate/tests/datapath/rx_channel_hopping_test/rx_channel_hopping_test.json +5 -4
  92. certificate/tests/datapath/rx_channel_hopping_test/rx_channel_hopping_test.py +77 -0
  93. {brg_certificate → certificate}/tests/datapath/rx_channel_test/rx_channel_test.json +2 -2
  94. {brg_certificate → certificate}/tests/datapath/rx_channel_test/rx_channel_test.py +7 -6
  95. {brg_certificate → certificate}/tests/datapath/rx_rate_gen2_test/rx_rate_gen2_test.json +7 -7
  96. {brg_certificate → certificate}/tests/datapath/rx_rate_gen2_test/rx_rate_gen2_test.py +112 -72
  97. {brg_certificate → certificate}/tests/datapath/rx_rate_gen3_test/rx_rate_gen3_test.json +7 -7
  98. {brg_certificate → certificate}/tests/datapath/rx_rate_gen3_test/rx_rate_gen3_test.py +112 -72
  99. {brg_certificate → certificate}/tests/datapath/stress_gen3_test/stress_gen3_test.json +3 -3
  100. {brg_certificate → certificate}/tests/datapath/stress_gen3_test/stress_gen3_test.py +12 -11
  101. {brg_certificate → certificate}/tests/datapath/stress_test/stress_test.json +3 -3
  102. {brg_certificate → certificate}/tests/datapath/stress_test/stress_test.py +12 -11
  103. {brg_certificate → certificate}/tests/datapath/tx_repetition_test/tx_repetition_test.json +2 -1
  104. {brg_certificate → certificate}/tests/datapath/tx_repetition_test/tx_repetition_test.py +14 -13
  105. certificate/tests/edge_mgmt/action_blink_test/action_blink_test.json +14 -0
  106. certificate/tests/edge_mgmt/action_blink_test/action_blink_test.py +24 -0
  107. certificate/tests/edge_mgmt/action_get_battery_sensor_test/action_get_battery_sensor_test.json +14 -0
  108. certificate/tests/edge_mgmt/action_get_battery_sensor_test/action_get_battery_sensor_test.py +43 -0
  109. certificate/tests/edge_mgmt/action_get_module_test/action_get_module_test.json +14 -0
  110. certificate/tests/edge_mgmt/action_get_module_test/action_get_module_test.py +42 -0
  111. certificate/tests/edge_mgmt/action_get_pof_data_test/action_get_pof_data_test.json +14 -0
  112. certificate/tests/edge_mgmt/action_get_pof_data_test/action_get_pof_data_test.py +44 -0
  113. certificate/tests/edge_mgmt/action_gw_hb_test/action_gw_hb_test.json +15 -0
  114. certificate/tests/edge_mgmt/action_gw_hb_test/action_gw_hb_test.py +42 -0
  115. certificate/tests/edge_mgmt/action_reboot_test/action_reboot_test.json +14 -0
  116. certificate/tests/edge_mgmt/action_reboot_test/action_reboot_test.py +49 -0
  117. certificate/tests/edge_mgmt/action_restore_defaults_test/action_restore_defaults_test.json +14 -0
  118. certificate/tests/edge_mgmt/action_restore_defaults_test/action_restore_defaults_test.py +102 -0
  119. certificate/tests/edge_mgmt/action_send_hb_test/action_send_hb_test.json +14 -0
  120. certificate/tests/edge_mgmt/action_send_hb_test/action_send_hb_test.py +41 -0
  121. {brg_certificate → certificate}/tests/edge_mgmt/periodic_msgs_test/periodic_msgs_test.json +2 -2
  122. {brg_certificate → certificate}/tests/edge_mgmt/periodic_msgs_test/periodic_msgs_test.py +22 -11
  123. {brg_certificate → certificate}/tests/energy2400/duty_cycle_test/duty_cycle_test.json +1 -1
  124. {brg_certificate → certificate}/tests/energy2400/duty_cycle_test/duty_cycle_test.py +7 -6
  125. certificate/tests/energy2400/output_power_test/output_power_test.json +22 -0
  126. {brg_certificate → certificate}/tests/energy2400/output_power_test/output_power_test.py +17 -6
  127. {brg_certificate → certificate}/tests/energy2400/pattern_test/pattern_test.json +1 -1
  128. {brg_certificate → certificate}/tests/energy2400/pattern_test/pattern_test.py +7 -6
  129. certificate/tests/energy2400/signal_indicator_ble5_test/signal_indicator_ble5_test.json +25 -0
  130. certificate/tests/energy2400/signal_indicator_ble5_test/signal_indicator_ble5_test.py +378 -0
  131. brg_certificate/tests/energy2400/signal_indicator_ble5_10_500k_test/signal_indicator_ble5_10_500k_test.json → certificate/tests/energy2400/signal_indicator_ext_adv_test/signal_indicator_ext_adv_test.json +3 -3
  132. brg_certificate/tests/energy2400/signal_indicator_ble5_10_500k_test/signal_indicator_ble5_10_500k_test.py → certificate/tests/energy2400/signal_indicator_ext_adv_test/signal_indicator_ext_adv_test.py +97 -87
  133. certificate/tests/energy2400/signal_indicator_test/signal_indicator_test.json +23 -0
  134. certificate/tests/energy2400/signal_indicator_test/signal_indicator_test.py +350 -0
  135. {brg_certificate → certificate}/tests/energy_sub1g/duty_cycle_test/duty_cycle_test.json +1 -1
  136. {brg_certificate → certificate}/tests/energy_sub1g/duty_cycle_test/duty_cycle_test.py +7 -6
  137. {brg_certificate → certificate}/tests/energy_sub1g/pattern_test/pattern_test.json +1 -1
  138. {brg_certificate → certificate}/tests/energy_sub1g/pattern_test/pattern_test.py +7 -6
  139. {brg_certificate → certificate}/tests/pwr_mgmt/pwr_mgmt_test/pwr_mgmt_test.json +1 -1
  140. {brg_certificate → certificate}/tests/pwr_mgmt/pwr_mgmt_test/pwr_mgmt_test.py +10 -10
  141. {brg_certificate → certificate}/tests/sensors/ext_sensor_test/ext_sensor_test.json +4 -4
  142. certificate/tests/sensors/ext_sensor_test/ext_sensor_test.py +455 -0
  143. certificate/wlt_types.py +122 -0
  144. {gw_certificate → common}/api_if/202/status.json +6 -0
  145. {gw_certificate → common}/api_if/203/status.json +6 -0
  146. {gw_certificate → common}/api_if/204/status.json +6 -0
  147. common/api_if/206/data.json +85 -0
  148. common/api_if/206/status.json +69 -0
  149. common/api_if/api_validation.py +85 -0
  150. common/web/templates/generator.html +148 -0
  151. common/web/templates/index.html +20 -0
  152. common/web/templates/menu.html +54 -0
  153. common/web/templates/parser.html +53 -0
  154. {brg_certificate/ag → common/web/templates}/wlt_types.html +1216 -191
  155. common/web/web_utils.py +377 -0
  156. {brg_certificate → common}/wltPb_pb2.py +14 -12
  157. {gw_certificate/common → common}/wltPb_pb2.pyi +16 -2
  158. gui_certificate/gui_certificate_cli.py +14 -0
  159. gui_certificate/server.py +1062 -0
  160. gui_certificate/templates/cert_run.html +1207 -0
  161. wiliot_certificate-4.5.0a1.dist-info/METADATA +110 -0
  162. wiliot_certificate-4.5.0a1.dist-info/RECORD +182 -0
  163. {wiliot_certificate-4.4.3.dist-info → wiliot_certificate-4.5.0a1.dist-info}/WHEEL +1 -1
  164. wiliot_certificate-4.5.0a1.dist-info/entry_points.txt +5 -0
  165. wiliot_certificate-4.5.0a1.dist-info/top_level.txt +3 -0
  166. brg_certificate/ag/energous_v0_defines.py +0 -925
  167. brg_certificate/ag/energous_v1_defines.py +0 -931
  168. brg_certificate/ag/energous_v2_defines.py +0 -925
  169. brg_certificate/ag/energous_v3_defines.py +0 -925
  170. brg_certificate/ag/energous_v4_defines.py +0 -925
  171. brg_certificate/ag/fanstel_lan_v0_defines.py +0 -925
  172. brg_certificate/ag/fanstel_lte_v0_defines.py +0 -925
  173. brg_certificate/ag/fanstel_wifi_v0_defines.py +0 -925
  174. brg_certificate/ag/minew_lte_v0_defines.py +0 -925
  175. brg_certificate/ag/wlt_types_ag_jsons/unified_echo_ext_pkt.json +0 -61
  176. brg_certificate/brg_certificate.py +0 -225
  177. brg_certificate/brg_certificate_cli.py +0 -63
  178. brg_certificate/cert_common.py +0 -923
  179. brg_certificate/cert_config.py +0 -402
  180. brg_certificate/cert_utils.py +0 -362
  181. brg_certificate/certificate_bcc_sanity_test_list.txt +0 -40
  182. brg_certificate/certificate_bcc_test_list.txt +0 -48
  183. brg_certificate/certificate_sanity_test_list.txt +0 -43
  184. brg_certificate/certificate_test_list.txt +0 -53
  185. brg_certificate/config/eclipse.json +0 -10
  186. brg_certificate/config/hivemq.json +0 -10
  187. brg_certificate/config/mosquitto.json +0 -10
  188. brg_certificate/config/mosquitto.md +0 -95
  189. brg_certificate/config/wiliot-dev.json +0 -10
  190. brg_certificate/restore_brg.py +0 -61
  191. brg_certificate/tests/calibration/output_power_test/output_power_test.json +0 -16
  192. brg_certificate/tests/calibration/output_power_test/output_power_test.py +0 -28
  193. brg_certificate/tests/datapath/aging_test/aging_test.py +0 -143
  194. brg_certificate/tests/datapath/pacer_interval_tags_count_test/pacer_interval_tags_count_test.json +0 -16
  195. brg_certificate/tests/datapath/pacer_interval_tags_count_test/pacer_interval_tags_count_test.py +0 -73
  196. brg_certificate/tests/datapath/tx_repetition_algo_test/tx_repetition_algo_test.json +0 -17
  197. brg_certificate/tests/datapath/tx_repetition_algo_test/tx_repetition_algo_test.py +0 -118
  198. brg_certificate/tests/edge_mgmt/actions_test/actions_test.json +0 -14
  199. brg_certificate/tests/edge_mgmt/actions_test/actions_test.py +0 -396
  200. brg_certificate/tests/edge_mgmt/brg2brg_ota_ble5_test/brg2brg_ota_ble5_test.json +0 -20
  201. brg_certificate/tests/edge_mgmt/brg2brg_ota_ble5_test/brg2brg_ota_ble5_test.py +0 -94
  202. brg_certificate/tests/edge_mgmt/brg2brg_ota_test/brg2brg_ota_test.json +0 -19
  203. brg_certificate/tests/edge_mgmt/brg2brg_ota_test/brg2brg_ota_test.py +0 -87
  204. brg_certificate/tests/edge_mgmt/leds_test/leds_test.json +0 -17
  205. brg_certificate/tests/edge_mgmt/leds_test/leds_test.py +0 -223
  206. brg_certificate/tests/edge_mgmt/ota_test/ota_test.json +0 -17
  207. brg_certificate/tests/edge_mgmt/ota_test/ota_test.py +0 -128
  208. brg_certificate/tests/energy2400/output_power_test/output_power_test.json +0 -16
  209. brg_certificate/tests/energy2400/signal_indicator_ble5_10_250k_test/signal_indicator_ble5_10_250k_test.json +0 -20
  210. brg_certificate/tests/energy2400/signal_indicator_ble5_10_250k_test/signal_indicator_ble5_10_250k_test.py +0 -321
  211. brg_certificate/tests/energy2400/signal_indicator_sub1g_2_4_test/signal_indicator_sub1g_2_4_test.json +0 -20
  212. brg_certificate/tests/energy2400/signal_indicator_sub1g_2_4_test/signal_indicator_sub1g_2_4_test.py +0 -141
  213. brg_certificate/tests/energy2400/signal_indicator_test/signal_indicator_test.json +0 -20
  214. brg_certificate/tests/energy2400/signal_indicator_test/signal_indicator_test.py +0 -276
  215. brg_certificate/tests/energy_sub1g/signal_indicator_functionality_test/signal_indicator_functionality_test.json +0 -20
  216. brg_certificate/tests/energy_sub1g/signal_indicator_functionality_test/signal_indicator_functionality_test.py +0 -390
  217. brg_certificate/tests/energy_sub1g/signal_indicator_test/signal_indicator_test.json +0 -16
  218. brg_certificate/tests/energy_sub1g/signal_indicator_test/signal_indicator_test.py +0 -28
  219. brg_certificate/tests/sensors/ext_sensor_test/ext_sensor_test.py +0 -305
  220. brg_certificate/wltPb_pb2.pyi +0 -234
  221. brg_certificate/wlt_types.py +0 -113
  222. gw_certificate/ag/ut_defines.py +0 -364
  223. gw_certificate/ag/wlt_types.py +0 -85
  224. gw_certificate/ag/wlt_types_ag.py +0 -5310
  225. gw_certificate/ag/wlt_types_data.py +0 -64
  226. gw_certificate/api/extended_api.py +0 -23
  227. gw_certificate/api_if/200/data.json +0 -106
  228. gw_certificate/api_if/200/status.json +0 -47
  229. gw_certificate/api_if/201/data.json +0 -98
  230. gw_certificate/api_if/201/status.json +0 -53
  231. gw_certificate/api_if/205/logs.json +0 -12
  232. gw_certificate/api_if/api_validation.py +0 -38
  233. gw_certificate/api_if/gw_capabilities.py +0 -54
  234. gw_certificate/cert_results.py +0 -145
  235. gw_certificate/common/analysis_data_bricks.py +0 -60
  236. gw_certificate/common/debug.py +0 -42
  237. gw_certificate/common/serialization_formatter.py +0 -93
  238. gw_certificate/common/utils.py +0 -8
  239. gw_certificate/common/utils_defines.py +0 -15
  240. gw_certificate/common/wltPb_pb2.py +0 -84
  241. gw_certificate/gw_certificate.py +0 -154
  242. gw_certificate/gw_certificate_cli.py +0 -87
  243. gw_certificate/interface/4.4.93_app.zip +0 -0
  244. gw_certificate/interface/4.4.93_sd_bl_app.zip +0 -0
  245. gw_certificate/interface/ble_simulator.py +0 -61
  246. gw_certificate/interface/ble_sniffer.py +0 -189
  247. gw_certificate/interface/flash_fw.py +0 -90
  248. gw_certificate/interface/if_defines.py +0 -36
  249. gw_certificate/interface/mqtt.py +0 -563
  250. gw_certificate/interface/nrfutil-linux +0 -0
  251. gw_certificate/interface/nrfutil-mac +0 -0
  252. gw_certificate/interface/nrfutil.exe +0 -0
  253. gw_certificate/interface/pkt_generator.py +0 -594
  254. gw_certificate/interface/uart_if.py +0 -236
  255. gw_certificate/interface/uart_ports.py +0 -20
  256. gw_certificate/templates/results.html +0 -241
  257. gw_certificate/templates/stage.html +0 -22
  258. gw_certificate/templates/table.html +0 -6
  259. gw_certificate/templates/test.html +0 -38
  260. gw_certificate/tests/__init__.py +0 -10
  261. gw_certificate/tests/actions.py +0 -289
  262. gw_certificate/tests/bad_crc_to_PER_quantization.csv +0 -51
  263. gw_certificate/tests/connection.py +0 -188
  264. gw_certificate/tests/downlink.py +0 -172
  265. gw_certificate/tests/generic.py +0 -238
  266. gw_certificate/tests/registration.py +0 -340
  267. gw_certificate/tests/static/__init__.py +0 -0
  268. gw_certificate/tests/static/connection_defines.py +0 -9
  269. gw_certificate/tests/static/downlink_defines.py +0 -9
  270. gw_certificate/tests/static/generated_packet_table.py +0 -195
  271. gw_certificate/tests/static/packet_table.csv +0 -10067
  272. gw_certificate/tests/static/references.py +0 -5
  273. gw_certificate/tests/static/uplink_defines.py +0 -14
  274. gw_certificate/tests/throughput.py +0 -240
  275. gw_certificate/tests/uplink.py +0 -853
  276. wiliot_certificate-4.4.3.dist-info/METADATA +0 -211
  277. wiliot_certificate-4.4.3.dist-info/RECORD +0 -210
  278. wiliot_certificate-4.4.3.dist-info/entry_points.txt +0 -3
  279. wiliot_certificate-4.4.3.dist-info/top_level.txt +0 -3
  280. {brg_certificate → certificate}/__init__.py +0 -0
  281. {brg_certificate → certificate}/ag/wlt_types_ag_jsons/side_info_sensor.json +0 -0
  282. {brg_certificate → certificate}/ag/wlt_types_ag_jsons/signal_indicator_data.json +0 -0
  283. {gw_certificate → common}/api_if/202/data.json +0 -0
  284. {gw_certificate/api_if/200 → common/api_if/202}/logs.json +0 -0
  285. {gw_certificate → common}/api_if/203/data.json +0 -0
  286. {gw_certificate/api_if/201 → common/api_if/203}/logs.json +0 -0
  287. {gw_certificate → common}/api_if/204/data.json +0 -0
  288. {gw_certificate/api_if/202 → common/api_if/204}/logs.json +0 -0
  289. {gw_certificate → common}/api_if/205/data.json +0 -0
  290. {gw_certificate/api_if/203 → common/api_if/205}/logs.json +0 -0
  291. {gw_certificate → common}/api_if/205/status.json +0 -0
  292. {gw_certificate/api_if/204 → common/api_if/206}/logs.json +0 -0
  293. {gw_certificate → common/api_if}/__init__.py +0 -0
  294. {gw_certificate/api_if → gui_certificate}/__init__.py +0 -0
  295. {wiliot_certificate-4.4.3.dist-info → wiliot_certificate-4.5.0a1.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,384 @@
1
+
2
+ import datetime
3
+ import time
4
+ import os
5
+ import requests
6
+ import json
7
+
8
+ from enum import Enum
9
+ from typing import Literal
10
+
11
+ from certificate.cert_defines import TEST_FAILED, TEST_PASSED, TEST_SKIPPED
12
+ from certificate.cert_prints import phase_run_print
13
+
14
+ import certificate.cert_utils as cert_utils
15
+ import certificate.cert_common as cert_common
16
+
17
+
18
+ # HELPER DEFINES
19
+ GW_REGISTER_DOC = "https://community.wiliot.com/customers/s/article/Registering-Third-Party-Gateways"
20
+ GW_MQTT_DOC = "https://community.wiliot.com/customers/s/article/Sending-Wiliot-Packets-to-the-Wiliot-Cloud"
21
+
22
+ REGISTRATION_API_KEY_ENV_VAR = "REGISTRATION_TEST_API_KEY"
23
+
24
+ REG_CERT_OWNER_ID = 'gw-certification-account'
25
+
26
+ STAGES_TIMEOUT_MINUTES = 2
27
+ TOKEN_EXPIRY_MINUTES = 3
28
+ CLOUD_DELAY_SEC = 7
29
+ BUSY_WAIT_DELAY_SEC = 5
30
+ STAGE_START_DELAY_MS = (BUSY_WAIT_DELAY_SEC + CLOUD_DELAY_SEC + 1) * 1000
31
+
32
+ ERROR_NO_REGISTER = 'Gateway did not register itself in time.'
33
+ ERROR_NO_ONLINE = 'Gateway did not connect to MQTT in time.'
34
+ ERROR_NO_ACTIVE = 'Gateway did not upload a status message with its configurations in time.'
35
+ ERROR_NO_REFRESH = 'Gateway did not reconnect to MQTT in time.'
36
+
37
+ HEADERS = {
38
+ "accept": "application/json",
39
+ "Content-Type": "application/json",
40
+ "Authorization": None
41
+ }
42
+ BASE_URL = "https://api.us-east-2.prod.wiliot.cloud"
43
+ OWNER_URL = BASE_URL + f"/v1/owner/{REG_CERT_OWNER_ID}"
44
+ API_TOKEN_URL = BASE_URL + '/v1/auth/token/api'
45
+
46
+ # GLOBALS
47
+ api_key = None
48
+ gw_online_ts = None
49
+
50
+
51
+ # HTTP RELATED
52
+ class HttpMethod(str, Enum):
53
+ GET = "GET"
54
+ POST = "POST"
55
+ PUT = "PUT"
56
+ DELETE = "DELETE"
57
+
58
+
59
+ def http_request(path, payload, request_method: HttpMethod):
60
+ headers = HEADERS
61
+
62
+ def get_token():
63
+ headers = {
64
+ 'Authorization': api_key
65
+ }
66
+ response = requests.post(API_TOKEN_URL, headers=headers)
67
+ if response.status_code == 200:
68
+ token = response.json()
69
+ return token["access_token"]
70
+ else:
71
+ raise Exception(f"Failed to get token. statuscode: {response.status_code}, {response.text}")
72
+
73
+ headers['Authorization'] = get_token()
74
+ response = requests.request(request_method, (OWNER_URL + path), headers=headers, data=payload)
75
+ try:
76
+ message = response.json()
77
+ except json.JSONDecodeError:
78
+ message = response.text
79
+ if isinstance(message, str):
80
+ message = {"data": message}
81
+ message.update({'status_code': response.status_code})
82
+ return message
83
+
84
+
85
+ def get_gateway(gateway_id):
86
+ path = f"/gateway/{gateway_id}"
87
+ result = http_request(path, payload=None, request_method=HttpMethod.GET)
88
+ if result['status_code'] != 200:
89
+ raise Exception(f"get_gateway request failed with status_code {result['status_code']}")
90
+ return result["data"]
91
+
92
+
93
+ def register_gateway(gateways: list):
94
+ payload = {
95
+ "gateways": gateways
96
+ }
97
+ path = "/gateway"
98
+ response = http_request(path, payload=json.dumps(payload), request_method=HttpMethod.PUT)
99
+ return (response.get("data", "").lower() == "ok", response)
100
+
101
+
102
+ def delete_gateway(gateway_id):
103
+ path = f"/gateway/{gateway_id}"
104
+ response = http_request(path, payload=None, request_method=HttpMethod.DELETE)
105
+ return response.get('message', "").lower().find("success") != -1
106
+
107
+
108
+ def kick_gw_from_mqtt(gw_id):
109
+ path = f"/gateway/{gw_id}/kick-mqtt-connection"
110
+ response = http_request(path, payload=None, request_method=HttpMethod.POST)
111
+ return response
112
+
113
+
114
+ def get_kong_logs(gw_id):
115
+ """
116
+ Only available under the certificate registration account
117
+ """
118
+ path = f"/gateway/{gw_id}/auth-logs"
119
+
120
+ return http_request(path, payload=None, request_method=HttpMethod.GET)
121
+
122
+
123
+ # TEST RELATED
124
+ class GetGwField(Enum):
125
+ STATUS = 'status'
126
+ ONLINE = 'online'
127
+ ONLINE_UPDATED_AT = 'onlineUpdatedAt'
128
+ ACTIVATED_AT = 'activatedAt'
129
+
130
+
131
+ class Status(Enum):
132
+ PRE_REGISTERED = 'pre-registered'
133
+ REGISTERED = 'registered'
134
+ APPROVED = 'approved'
135
+ ACTIVE = 'active'
136
+
137
+
138
+ class GenericRegistrationStage():
139
+ def __init__(self, dut, **kwargs):
140
+ self.__dict__.update(kwargs)
141
+ self.dut = dut
142
+ self.start_time = None
143
+ self.duration = datetime.timedelta(0)
144
+ self.report = ''
145
+ self.error_summary = ''
146
+
147
+ def calc_run_duration(self):
148
+ self.duration = datetime.datetime.now() - self.start_time
149
+
150
+ def add_report_header(self):
151
+ self.report += f'This phase {(self.stage_tooltip.lower())}.\n'
152
+ self.report += '-' * 50 + '\n'
153
+
154
+ def get_gateway_field(self, field: GetGwField):
155
+ temp = get_gateway(self.dut)
156
+ return temp[field.value]
157
+
158
+ def kick_gw_from_mqtt(self):
159
+ response = kick_gw_from_mqtt(self.dut)
160
+ print(f"Kick response:{response}")
161
+
162
+ def validate_kong_logs(self, endpoint: Literal['device-authorize', 'registry', 'token', 'refresh']):
163
+ message = get_kong_logs(self.dut)
164
+ status_code = message.get('status_code')
165
+ if status_code == 404:
166
+ response_data = message.get('message')
167
+ if 'not found' in response_data:
168
+ print("Could not find gw when requesting for logs.")
169
+ print("Either it is not registered, didn't issue any requests, or is missing the X-Gateway-ID header.")
170
+ return False
171
+ else:
172
+ raise Exception(f'Failed getting kong logs: {response_data}')
173
+ if isinstance(message, dict) and message.get('status_code') != 200:
174
+ print(f"Failed fetching logs, status_code:{message.get('status_code')}")
175
+ return False
176
+
177
+ # Convert datetime.datetime.now() format to epoch in MS
178
+ stage_start_ts = self.start_time.timestamp() * 1000 - STAGE_START_DELAY_MS
179
+
180
+ for log in message['data']:
181
+ if log['timestamp'] > stage_start_ts and endpoint in log['endpoint']:
182
+ response_code = log['responseCode']
183
+ if response_code != 200:
184
+ print(f"An HTTP request to /{endpoint} resulted in an invalid response code:{response_code}")
185
+ else:
186
+ print(f"A valid HTTP request to /{endpoint} was received")
187
+ return True
188
+
189
+ print(f"No valid HTTP request to /{endpoint} was found")
190
+ return False
191
+
192
+ def prepare_stage(self):
193
+ pass
194
+
195
+
196
+ class Registry(GenericRegistrationStage):
197
+ def __init__(self, **kwargs):
198
+ self.__dict__.update(kwargs)
199
+ self.stage_tooltip = "Validate the gateway's registry step"
200
+ super().__init__(name=type(self).__name__, **self.__dict__)
201
+
202
+ def prepare_stage(self):
203
+ print('Pre-registering the gateway, please make sure it is not registered to any other account '
204
+ 'and that your device is ready to run the registration flow')
205
+
206
+ def pre_register_gw_anew(gw_id):
207
+ pre_registered, message = register_gateway([gw_id])
208
+ status_code = message.get('status_code')
209
+ if status_code == 400:
210
+ response_data = message.get('message')
211
+ if 'already exists' in response_data:
212
+ print(f'{gw_id} already exists in Wiliot platform! Deleting and pre-registering from scratch')
213
+ self.kick_gw_from_mqtt()
214
+ delete_gateway(gw_id)
215
+ time.sleep(CLOUD_DELAY_SEC)
216
+ pre_registered, message = register_gateway([gw_id])
217
+ if status_code == 403:
218
+ raise Exception(f"The API key within {REGISTRATION_API_KEY_ENV_VAR} seems invalid."
219
+ " It is not authorized to pre-register the gateway")
220
+ return pre_registered, message
221
+
222
+ pre_registered, message = pre_register_gw_anew(self.dut)
223
+ if not pre_registered:
224
+ print(f'Failed pre-registering the gateway. HTTP response:\n{message}')
225
+ raise Exception("Failed pre-registering the gateway. Make sure: Your API key is valid,"
226
+ " and you have a stable internet connection. Otherwise, try again later.")
227
+ print(f"{self.dut} was pre-registered successfully")
228
+
229
+ def run(self):
230
+ self.start_time = datetime.datetime.now()
231
+ print("Waiting for the gateway to finish the Registry step..")
232
+ timeout = datetime.datetime.now() + datetime.timedelta(minutes=STAGES_TIMEOUT_MINUTES)
233
+ self.status = self.get_gateway_field(GetGwField.STATUS)
234
+ while datetime.datetime.now() < timeout and not any(self.status == s.value for s in {Status.APPROVED, Status.ACTIVE}):
235
+ time.sleep(BUSY_WAIT_DELAY_SEC)
236
+ self.status = self.get_gateway_field(GetGwField.STATUS)
237
+
238
+ time.sleep(CLOUD_DELAY_SEC)
239
+ self.validate_kong_logs('device-authorize')
240
+ self.validate_kong_logs('registry')
241
+ self.calc_run_duration()
242
+
243
+ def generate_stage_report(self):
244
+ self.add_report_header()
245
+ if not any(self.status == s.value for s in {Status.APPROVED, Status.ACTIVE}):
246
+ self.error_summary = ERROR_NO_REGISTER
247
+ self.report += f'{ERROR_NO_REGISTER}\n'
248
+ print(f"The gateway failed to register. Its status is '{self.status}' while it is expected to be '{Status.APPROVED.value}'.")
249
+ self.report += "There was an error in the Device-authorize or Registry steps.\n"
250
+ self.report += f"Please go over the Device-authorize and Registry sections in this document:\n{GW_REGISTER_DOC}\n"
251
+ if self.status == Status.REGISTERED:
252
+ self.report += "Highly likely that the gateway is missing the 'X-Gateway-ID' header in it's HTTP requests.\n"
253
+ return False
254
+ else:
255
+ self.report += "Device-authorize and Registry requests were issued well.\n"
256
+ self.report += "Gateway registered successfully.\n"
257
+ print("Gateway registered successfully")
258
+ return True
259
+
260
+
261
+ class Online(GenericRegistrationStage):
262
+ def __init__(self, **kwargs):
263
+ self.__dict__.update(kwargs)
264
+ self.stage_tooltip = "Validate the gateway become online on the platform"
265
+ super().__init__(name=type(self).__name__, **self.__dict__)
266
+
267
+ def run(self):
268
+ self.start_time = datetime.datetime.now()
269
+ print("Waiting for the gateway to connect to MQTT..")
270
+ timeout = datetime.datetime.now() + datetime.timedelta(minutes=STAGES_TIMEOUT_MINUTES)
271
+ self.online = self.get_gateway_field(GetGwField.ONLINE)
272
+ while datetime.datetime.now() < timeout and self.online is not True:
273
+ time.sleep(BUSY_WAIT_DELAY_SEC)
274
+ self.online = self.get_gateway_field(GetGwField.ONLINE)
275
+
276
+ time.sleep(CLOUD_DELAY_SEC)
277
+ self.validate_kong_logs('token')
278
+ if self.online:
279
+ global gw_online_ts
280
+ gw_online_ts = datetime.datetime.now()
281
+ self.calc_run_duration()
282
+
283
+ def generate_stage_report(self):
284
+ self.add_report_header()
285
+ if self.online is not True:
286
+ self.error_summary = ERROR_NO_ONLINE
287
+ self.report += f'{ERROR_NO_ONLINE}\n'
288
+ self.report += "Either it didn't acquire a token or it didn't connect to MQTT in time.\n"
289
+ self.report += f"Please go over the Poll For Token section in:\n{GW_REGISTER_DOC}\n"
290
+ self.report += f"and the MQTT details in:\n{GW_MQTT_DOC}\n"
291
+ print("Gateway did not connect to MQTT within time limit")
292
+ return False
293
+ else:
294
+ self.report += "Token acquisition and MQTT connection were done succesfully.\n"
295
+ self.report += "Gateway is online.\n"
296
+ print("Gateway connected to MQTT successfully, it is online")
297
+ return True
298
+
299
+
300
+ class Refresh(GenericRegistrationStage):
301
+ def __init__(self, **kwargs):
302
+ self.__dict__.update(kwargs)
303
+ self.stage_tooltip = "Validate the gateway refresh-token step"
304
+ super().__init__(name=type(self).__name__, **self.__dict__)
305
+
306
+ def run(self):
307
+ self.start_time = datetime.datetime.now()
308
+ print("Waiting for the token to expire..")
309
+ timeout = gw_online_ts + datetime.timedelta(minutes=TOKEN_EXPIRY_MINUTES)
310
+ while datetime.datetime.now() < timeout:
311
+ time.sleep(BUSY_WAIT_DELAY_SEC)
312
+
313
+ print("Token expired, kicking gateway")
314
+ self.kick_gw_from_mqtt()
315
+
316
+ # Sleep here since it sometimes take time for the cloud to kick and change the gateway's online status
317
+ time.sleep(CLOUD_DELAY_SEC)
318
+ print("Waiting for the gateway to refresh its token and connect to MQTT..")
319
+ timeout = datetime.datetime.now() + datetime.timedelta(minutes=STAGES_TIMEOUT_MINUTES)
320
+ self.online = self.get_gateway_field(GetGwField.ONLINE)
321
+ while datetime.datetime.now() < timeout and self.online is not True:
322
+ time.sleep(BUSY_WAIT_DELAY_SEC)
323
+ self.online = self.get_gateway_field(GetGwField.ONLINE)
324
+
325
+ time.sleep(CLOUD_DELAY_SEC)
326
+ self.validate_kong_logs('refresh')
327
+ self.calc_run_duration()
328
+
329
+ def generate_stage_report(self):
330
+ self.add_report_header()
331
+ if self.online is not True:
332
+ self.error_summary = ERROR_NO_REFRESH
333
+ self.report += f'{ERROR_NO_REFRESH}\n'
334
+ self.report += "Either it didn't refresh its token or it didn't connect to MQTT in time.\n"
335
+ self.report += f"Please go over the Refresh Token section in:\n{GW_REGISTER_DOC}\n"
336
+ self.report += f"and the MQTT details in:\n{GW_MQTT_DOC}\n"
337
+ print("Gateway did not reconnect MQTT (was the token refreshed?)")
338
+ return False
339
+ else:
340
+ self.report += "Token refresh and MQTT reconnection were done succesfully.\n"
341
+ self.report += "Gateway is online.\n"
342
+ return True
343
+
344
+
345
+ def end_test(dut):
346
+ print(f'Deleting {dut} from {REG_CERT_OWNER_ID} before exiting')
347
+ time.sleep(CLOUD_DELAY_SEC)
348
+ delete_gateway(dut)
349
+
350
+
351
+ def prepare_results(stage, phase_pass, skip_stage):
352
+ stage.rc = TEST_SKIPPED if skip_stage else TEST_PASSED if phase_pass else TEST_FAILED
353
+
354
+
355
+ def run(test: cert_utils.WltTest):
356
+ test = cert_common.test_prolog(test, flush_mqtt=False)
357
+ if test.rc == TEST_FAILED:
358
+ return cert_common.test_epilog(test, flush_mqtt=False)
359
+
360
+ global api_key
361
+ api_key = os.getenv(REGISTRATION_API_KEY_ENV_VAR)
362
+ if api_key is None:
363
+ raise Exception('Must include an apikey')
364
+
365
+ STAGES = [Registry, Online, Refresh]
366
+ phases = {p.name: stage(dut=test.dut.id_str) for p, stage in zip(test.params, STAGES)}
367
+
368
+ for param in test.params:
369
+ phase_run_print(f" - {param.name}")
370
+ phase = phases[param.name]
371
+ phase.prepare_stage()
372
+ phase.run()
373
+ test.rc = TEST_PASSED if phase.generate_stage_report() else TEST_FAILED
374
+ test.set_phase_rc(param.name, test.rc)
375
+ test.add_phase_reason(param.name, phase.error_summary)
376
+
377
+ if test.rc == TEST_FAILED and test.exit_on_param_failure:
378
+ print(f'\nPhase {param.name} failed: {phase.report}')
379
+ break
380
+ test.reset_result() # reset result and continue to next param
381
+
382
+ end_test(test.dut.id_str)
383
+
384
+ return cert_common.test_epilog(test, flush_mqtt=False)
@@ -0,0 +1,90 @@
1
+
2
+ import datetime
3
+ from argparse import ArgumentParser
4
+ import os
5
+ import traceback
6
+ import webbrowser
7
+ import tabulate
8
+
9
+ from certificate.cert_defines import CERT_VERSION, TEST_FAILED, TEST_PASSED, TEST_SKIPPED
10
+ from certificate.cert_prints import *
11
+ import certificate.cert_common as cert_common
12
+ import certificate.cert_utils as cert_utils
13
+ import certificate.cert_results as cert_results
14
+
15
+ import certificate.tests.cloud_connectivity.registration_test.registration_test as registration_test
16
+
17
+
18
+ # HELPER DEFINES
19
+ TEST_LINE = "cloud_connectivity/registration_test registry online refresh"
20
+
21
+
22
+ class RegTestCli:
23
+ """Registration Test CLI."""
24
+ def __init__(self):
25
+ usage = ("wlt-reg-test [-h] -dut <GWID> -ak <API_KEY>\n")
26
+
27
+ self.parser = ArgumentParser(prog='wlt-reg-test',
28
+ description=f'Registration Test v{CERT_VERSION}', usage=usage)
29
+
30
+ self.required = self.parser.add_argument_group('required arguments')
31
+ self.required.add_argument('--dut', type=str, help="Gateway ID", required=True)
32
+ self.required.add_argument('--apikey', '-ak', type=str, help="API key provided by Wiliot", required=True)
33
+
34
+ def parse_args(self, args=None):
35
+ """Parse arguments and return them."""
36
+ return self.parser.parse_args(args)
37
+
38
+
39
+ def prepare_results(stage, phase_pass, skip_stage):
40
+ stage.rc = TEST_SKIPPED if skip_stage else TEST_PASSED if phase_pass else TEST_FAILED
41
+
42
+
43
+ def main():
44
+ cli = RegTestCli()
45
+ args = cli.parse_args()
46
+
47
+ os.environ[registration_test.REGISTRATION_API_KEY_ENV_VAR] = f"{args.apikey}"
48
+
49
+ start_time = datetime.datetime.now()
50
+ dut = cert_utils.Gateway(id_str=args.dut)
51
+
52
+ test = cert_utils.WltTest(TEST_LINE, '', dut, exit_on_param_failure=True)
53
+ tests = [test]
54
+
55
+ # Running the tests
56
+ utPrint(SEP)
57
+ utPrint("\n - ".join([f"\nRunning {len(tests)} tests:"] +
58
+ [t.name if not t.internal_brg else f"{t.name} (internal brg)" for t in tests]))
59
+
60
+ failures, skipped = 0, 0
61
+ i = 0
62
+
63
+ try:
64
+ test_module_name = cert_utils.load_module(f'{test.module_name}.py', f'{test.dir}/{test.module_name}.py')
65
+ test = test_module_name.run(test)
66
+ except Exception as e:
67
+ traceback.print_exc()
68
+ test.add_phase_reason(RESTORE_CONFIG, f"Exception occurred: {e!r}")
69
+ test.rc = TEST_FAILED
70
+ finally:
71
+ test.update_overall_rc()
72
+ if test.rc == TEST_FAILED:
73
+ failures += 1
74
+ print(f"Test Duration: {test.duration}")
75
+ print(tabulate.tabulate([[i + 1, i + 1 - (failures + skipped), skipped, failures, len(tests)]],
76
+ headers=["FINISHED", "PASSED", "SKIPPED", "FAILED", "TOTAL"], tablefmt="pretty"))
77
+ cert_common.wait_time_n_print(2)
78
+
79
+ # Print results
80
+ cert_results.generate_results_files(test.dut, test.tester, html=True, pdf=True, failures=failures,
81
+ skipped=skipped, start_time=start_time, tests=tests)
82
+ if not pipeline_running():
83
+ webbrowser.open('file://' + os.path.realpath(os.path.join(ARTIFACTS_DIR, UT_RESULT_FILE_PDF)))
84
+
85
+ if failures:
86
+ sys.exit(-1)
87
+
88
+
89
+ if __name__ == '__main__':
90
+ main()
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "Gateway Uplink Stress",
3
+ "module": "Cloud Connectivity",
4
+ "purpose": "Test gateway's stress handling capabilities for different rates and durations",
5
+ "documentation": "https://community.wiliot.com/customers/s/article/Sending-Wiliot-Packets-to-the-Wiliot-Cloud",
6
+ "initialCondition": "Gateway configured to defaults, in a BLE-clean environment",
7
+ "procedure": ["Test prolog",
8
+ "For each pps value, advertise packets at that rate, once on each of the three BLE advertising channels, and compare the advertised vs uploaded rate",
9
+ "Test epilog"],
10
+ "expectedOutcome": "Find the maximum PPS supported by the gateway",
11
+ "mandatory": 1,
12
+ "multiBridgeTest": 0,
13
+ "gwOnlyTest": 1,
14
+ "dataSimOnlyTest": 1,
15
+ "allSupportedValues": [20, 40, 60, 80, 100, 120, 140, 160, 180, 200, 222, 250, 285, 333]
16
+ }
@@ -0,0 +1,97 @@
1
+
2
+ from certificate.cert_prints import *
3
+ from certificate.cert_defines import *
4
+ from certificate.wlt_types import *
5
+ from certificate.ag.wlt_types_ag import OUTPUT_POWER_2_4_MAX
6
+ import certificate.cert_common as cert_common
7
+ import certificate.cert_utils as cert_utils
8
+ import certificate.cert_mqtt as cert_mqtt
9
+ import certificate.cert_config as cert_config
10
+ import certificate.cert_gw_sim as cert_gw_sim
11
+ import math
12
+
13
+
14
+ # DEFINES
15
+ STRESS_TEST_INDICATOR = cert_utils.get_random_hex_str(len=6)
16
+
17
+ DUPLICATES = 1
18
+ ADVA_ASCII_LEN = 12
19
+
20
+ LOWEST_PPS = 20
21
+ ADV_DURATION_LOWEST_PPS = 50
22
+ ADV_DURATION_DEFAULT = 30
23
+
24
+
25
+ # HELPER FUNCTIONS
26
+
27
+
28
+ def generate_adv_payloads_list(payload, duplicates):
29
+ """
30
+ Should always stay synced to how cmd_ble_sim generate additional packets with unique_pkts_count
31
+ """
32
+ payload_start = payload[:-8]
33
+ last_hex = payload[-8:]
34
+ last_int = int.from_bytes(bytes.fromhex(last_hex), byteorder='little', signed=False)
35
+
36
+ pkts_list = []
37
+ for i in range(duplicates):
38
+ value = last_int + i
39
+ # Convert back to 4 bytes in little-endian and then to hex
40
+ new_hex = value.to_bytes(4, byteorder='little', signed=False).hex().upper()
41
+
42
+ pkts_list.append(payload_start + new_hex)
43
+
44
+ return pkts_list
45
+
46
+
47
+ def run(test):
48
+ test = cert_common.test_prolog(test)
49
+ if test.rc == TEST_FAILED:
50
+ return cert_common.test_epilog(test)
51
+
52
+ cert_config.gw_action(test, f'{cert_gw_sim.BLE_SIM_INIT} 1', TESTER)
53
+
54
+ test_pkts_received = []
55
+ data_pkts_received = []
56
+ results = []
57
+ for param in test.params:
58
+ phase_run_print(f"PPS = {param}")
59
+ test.flush_all_mqtt_packets()
60
+ pps = param.value
61
+ # adv_duration is increased only for lowest pps to increase packets sample for reliable results
62
+ adv_duration = ADV_DURATION_LOWEST_PPS if pps == LOWEST_PPS else ADV_DURATION_DEFAULT
63
+ delay = math.floor(1000 / pps)
64
+ upload_wait_time = test.dut.upload_wait_time + 15
65
+
66
+ # Generate pkts and get ready to advertise
67
+ payload = cert_common.generate_adv_payload(STRESS_TEST_INDICATOR)
68
+ generated_payloads = generate_adv_payloads_list(payload, adv_duration * pps)
69
+
70
+ # We provide the tester with the first pkt only. It then advertises in a loop pkts identical
71
+ # to the ones we generated (by incrementing the last bytes).
72
+ cert_config.gw_action(test, f'{cert_gw_sim.BLE_SIM} {generated_payloads[0]} {DUPLICATES} {OUTPUT_POWER_2_4_MAX} '
73
+ f'{BLE_SIM_ADV_37_38_39} {delay} {BLE_SIM_RADIO_1MBPS} {adv_duration * pps}', TESTER)
74
+ mqtt_scan_wait(test, adv_duration + upload_wait_time)
75
+
76
+ cert_mqtt.dump_pkts(test, log=param.name)
77
+ phase_pkts_received = cert_mqtt.get_all_data_pkts(test.get_mqttc_by_target(DUT), indicator=STRESS_TEST_INDICATOR)
78
+
79
+ test, percentage_received = cert_common.stress_analysis(
80
+ test, pps, generated_payloads,
81
+ [(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)
84
+
85
+ test.set_phase_rc(param.name, test.rc)
86
+ test.add_phase_reason(param.name, test.reason)
87
+ if test.rc == TEST_FAILED and test.exit_on_param_failure:
88
+ break # break the whole for loop and keep the test as failed
89
+ test.reset_result() # reset result and continue to next param
90
+ data_pkts_received.extend(cert_mqtt.get_all_data_pkts(test.get_mqttc_by_target(DUT)))
91
+ test_pkts_received.extend(test.get_mqttc_by_target(DUT)._userdata[PKTS].data)
92
+ cert_config.gw_action(test, f'{cert_gw_sim.BLE_SIM_INIT} 0', TESTER)
93
+
94
+ # Generate stress test graphs
95
+ cert_common.generate_graph_stress_test(test, results, data_pkts_received)
96
+
97
+ return cert_common.test_epilog(test)
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "Gateway Uplink Extended Advertising",
3
+ "module": "Cloud Connectivity",
4
+ "purpose": "Verify gateway BLE scans and MQTT uplinks in Extended Advertising mode",
5
+ "documentation": "https://community.wiliot.com/customers/s/article/Wiliot-Network---Gateway-Extended-Advertising-Implementation",
6
+ "initialCondition": "Gateway configured to defaults",
7
+ "procedure": [
8
+ "Test prolog",
9
+ "Enable GW CERT TESTER to allow TESTER transmit extended advertising packets",
10
+ "Configure TESTER datapath pattern to Extended Advertising (DATAPATH_PATTERN_EXTENDED_ADV)",
11
+ "Flush MQTT packets; generate pixel packets with 31-byte payload and send via GenericSimThread (single cycle)",
12
+ "Wait for MQTT scan (≈20s)",
13
+ "Analyze: each 31-byte payload must be expanded to aggregated 217 bytes (31×7) and repeated 7 times; validate ≥80% of expected payloads received",
14
+ "Restore TESTER datapath defaults and disable GW CERT TESTER",
15
+ "Generate log and pass/fail summary",
16
+ "Test epilog"
17
+ ],
18
+ "expectedOutcome": "Received amount of aggregated packets matches the expected amount and all additional validations pass as expected",
19
+ "mandatory": 0,
20
+ "multiBridgeTest": 0,
21
+ "gwOnlyTest": 1,
22
+ "dataSimOnlyTest": 1,
23
+ "allSupportedValues": []
24
+ }