wiliot-certificate 1.4.0a2__py3-none-any.whl → 1.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 (76) hide show
  1. brg_certificate/ag/energous_v0_defines.py +12 -12
  2. brg_certificate/ag/energous_v1_defines.py +12 -12
  3. brg_certificate/ag/energous_v2_defines.py +12 -12
  4. brg_certificate/ag/energous_v3_defines.py +12 -12
  5. brg_certificate/ag/energous_v4_defines.py +12 -12
  6. brg_certificate/ag/fanstel_lan_v0_defines.py +12 -12
  7. brg_certificate/ag/fanstel_lte_v0_defines.py +12 -12
  8. brg_certificate/ag/fanstel_wifi_v0_defines.py +12 -12
  9. brg_certificate/ag/minew_lte_v0_defines.py +12 -12
  10. brg_certificate/ag/wlt_cmd_if.html +1 -1
  11. brg_certificate/ag/wlt_types.html +3 -3
  12. brg_certificate/ag/wlt_types_ag.py +12 -12
  13. brg_certificate/brg_certificate.py +9 -6
  14. brg_certificate/cert_common.py +21 -13
  15. brg_certificate/cert_config.py +1 -1
  16. brg_certificate/cert_defines.py +21 -3
  17. brg_certificate/cert_gw_sim.py +6 -4
  18. brg_certificate/cert_mqtt.py +8 -2
  19. brg_certificate/cert_prints.py +7 -5
  20. brg_certificate/cert_protobuf.py +5 -1
  21. brg_certificate/cert_results.py +99 -69
  22. brg_certificate/cert_utils.py +10 -14
  23. brg_certificate/restore_brg.py +2 -0
  24. brg_certificate/tests/calibration/interval_test/interval_test.py +1 -1
  25. brg_certificate/tests/calibration/output_power_test/output_power_test.py +1 -1
  26. brg_certificate/tests/calibration/pattern_test/pattern_test.py +1 -1
  27. brg_certificate/tests/datapath/adaptive_pacer_algo_test/adaptive_pacer_algo_test.py +4 -4
  28. brg_certificate/tests/datapath/num_of_tags_test/num_of_tags_test.py +2 -2
  29. brg_certificate/tests/datapath/output_power_test/output_power_test.py +1 -1
  30. brg_certificate/tests/datapath/pacer_interval_ble5_test/pacer_interval_ble5_test.py +1 -1
  31. brg_certificate/tests/datapath/pacer_interval_tags_count_test/pacer_interval_tags_count_test.py +2 -2
  32. brg_certificate/tests/datapath/pacer_interval_test/pacer_interval_test.py +1 -1
  33. brg_certificate/tests/datapath/pattern_test/pattern_test.py +1 -1
  34. brg_certificate/tests/datapath/pkt_filter_ble5_test/pkt_filter_ble5_test.py +1 -1
  35. brg_certificate/tests/datapath/pkt_filter_gen3_test/pkt_filter_gen3_test.py +1 -1
  36. brg_certificate/tests/datapath/pkt_filter_test/pkt_filter_test.py +1 -1
  37. brg_certificate/tests/datapath/rssi_threshold_test/rssi_threshold_test.py +1 -1
  38. brg_certificate/tests/datapath/rx_channel_test/rx_channel_test.py +1 -1
  39. brg_certificate/tests/datapath/rx_rate_gen2_test/rx_rate_gen2_test.py +1 -1
  40. brg_certificate/tests/datapath/rx_rate_gen3_test/rx_rate_gen3_test.py +1 -1
  41. brg_certificate/tests/datapath/stress_gen3_test/stress_gen3_test.py +2 -2
  42. brg_certificate/tests/datapath/stress_test/stress_test.py +2 -2
  43. brg_certificate/tests/datapath/tx_repetition_algo_test/tx_repetition_algo_test.py +1 -1
  44. brg_certificate/tests/datapath/tx_repetition_test/tx_repetition_test.py +1 -1
  45. brg_certificate/tests/edge_mgmt/actions_test/actions_test.py +4 -4
  46. brg_certificate/tests/edge_mgmt/brg2brg_ota_ble5_test/brg2brg_ota_ble5_test.py +1 -1
  47. brg_certificate/tests/edge_mgmt/brg2brg_ota_test/brg2brg_ota_test.py +1 -1
  48. brg_certificate/tests/edge_mgmt/leds_test/leds_test.py +1 -1
  49. brg_certificate/tests/edge_mgmt/ota_test/ota_test.py +1 -1
  50. brg_certificate/tests/edge_mgmt/stat_test/stat_test.py +1 -1
  51. brg_certificate/tests/energy2400/duty_cycle_test/duty_cycle_test.py +1 -1
  52. brg_certificate/tests/energy2400/output_power_test/output_power_test.py +1 -1
  53. brg_certificate/tests/energy2400/pattern_test/pattern_test.py +1 -1
  54. brg_certificate/tests/energy2400/signal_indicator_ble5_test/signal_indicator_ble5_test.py +1 -1
  55. brg_certificate/tests/energy2400/signal_indicator_sub1g_2_4_test/signal_indicator_sub1g_2_4_test.py +1 -1
  56. brg_certificate/tests/energy_sub1g/duty_cycle_test/duty_cycle_test.py +1 -1
  57. brg_certificate/tests/energy_sub1g/pattern_test/pattern_test.py +1 -1
  58. brg_certificate/tests/energy_sub1g/signal_indicator_functionality_test/signal_indicator_functionality_test.py +1 -1
  59. brg_certificate/tests/energy_sub1g/signal_indicator_test/signal_indicator_test.py +1 -1
  60. brg_certificate/wltPb_pb2.py +50 -38
  61. brg_certificate/wltPb_pb2.pyi +32 -32
  62. brg_certificate/wlt_types.py +4 -6
  63. common/wlt_logo.png +0 -0
  64. gw_certificate/ag/ut_defines.py +4 -1
  65. gw_certificate/cert_results.py +138 -0
  66. gw_certificate/gw_certificate.py +20 -6
  67. gw_certificate/interface/mqtt.py +1 -0
  68. gw_certificate/tests/actions.py +0 -1
  69. gw_certificate/tests/connection.py +1 -1
  70. gw_certificate/tests/generic.py +43 -17
  71. {wiliot_certificate-1.4.0a2.dist-info → wiliot_certificate-1.5.0a1.dist-info}/METADATA +6 -4
  72. {wiliot_certificate-1.4.0a2.dist-info → wiliot_certificate-1.5.0a1.dist-info}/RECORD +76 -74
  73. {wiliot_certificate-1.4.0a2.dist-info → wiliot_certificate-1.5.0a1.dist-info}/top_level.txt +1 -0
  74. {wiliot_certificate-1.4.0a2.dist-info → wiliot_certificate-1.5.0a1.dist-info}/LICENSE +0 -0
  75. {wiliot_certificate-1.4.0a2.dist-info → wiliot_certificate-1.5.0a1.dist-info}/WHEEL +0 -0
  76. {wiliot_certificate-1.4.0a2.dist-info → wiliot_certificate-1.5.0a1.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,138 @@
1
+ import os
2
+ import tabulate
3
+ from reportlab.lib import colors
4
+ from reportlab.lib.pagesizes import letter
5
+ from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph, Spacer, PageBreak, KeepTogether, Image
6
+ from reportlab.lib.styles import ParagraphStyle
7
+ from reportlab.lib.enums import TA_CENTER, TA_LEFT
8
+
9
+ # Local imports
10
+ from gw_certificate.ag.ut_defines import TEST_FAILED, TEST_INCONCLUSIVE, TEST_PASSED, TEST_INFO, TEST_WARNING, TEST_OPTIONAL
11
+ BASE_DIR = os.path.dirname(os.path.abspath(__file__))
12
+ format_timedelta = lambda delta: f"{int(delta.total_seconds()//3600):02}:{int((delta.total_seconds()%3600)//60):02}:{int(delta.total_seconds()%60):02}"
13
+
14
+ ##################################
15
+ # GENERIC
16
+ ##################################
17
+ def generate_pdf_results_file(gw_cert):
18
+ # Extract GW certificate tests results
19
+ failures, inconclusive = 0, 0
20
+ for test in gw_cert.tests:
21
+ if test.rc == TEST_INCONCLUSIVE:
22
+ inconclusive += 1
23
+ elif test.rc == TEST_FAILED:
24
+ failures += 1
25
+
26
+ # Generate PDF file
27
+ doc = SimpleDocTemplate(gw_cert.result_pdf_path, pagesize=letter)
28
+ doc.title = f"Wiliot Gateway Certificate Results"
29
+ elements, hdr_page = [], []
30
+
31
+ # Add Wiliot Logo
32
+ img = Image(os.path.join(BASE_DIR, "../common", "wlt_logo.png"), width=100, height=40) # Adjust size as needed
33
+ hdr_page.append(img)
34
+ hdr_page.append(Spacer(1, 20))
35
+
36
+ # Title and Summary
37
+ red_header = STYLES_PDF.get("RED_HEADER", ParagraphStyle("Default"))
38
+ green_header = STYLES_PDF.get("GREEN_HEADER", ParagraphStyle("Default"))
39
+ module_header = STYLES_PDF.get("MODULE_HEADER", ParagraphStyle("Default"))
40
+ test_header = STYLES_PDF.get("TEST_HEADER", ParagraphStyle("Default"))
41
+ text_style_bold = STYLES_PDF.get("BLACK_BOLD", ParagraphStyle("Default"))
42
+ if gw_cert.error:
43
+ title = Paragraph(f"<b>Wiliot Gateway Certificate Error!</b>", red_header)
44
+ hdr_page.append(title)
45
+ hdr_page.append(Spacer(1, 20))
46
+ hdr_page.append(Paragraph(f"{gw_cert.error}", text_style_bold))
47
+ else:
48
+ title = Paragraph(f"<b>Wiliot Gateway Certificate Passed!</b>", green_header) if not failures else Paragraph(f"<b>Wiliot Gateway Certificate Failed!</b>", red_header)
49
+ hdr_page.append(title)
50
+ hdr_page.append(Spacer(1, 20))
51
+ hdr_page.append(Paragraph(f"<b>Summary</b>", module_header))
52
+ hdr_page.append(Spacer(1, 20))
53
+ hdr_page.append(Paragraph(f"Run date: {gw_cert.current_datetime.strftime('%d/%m/%Y, %H:%M:%S')}", text_style_bold))
54
+ hdr_page.append(Paragraph(f"Tests duration: {format_timedelta(gw_cert.runtime())}", text_style_bold))
55
+ hdr_page.append(Paragraph(f"Certificate version: {gw_cert.gw_cert_version}", text_style_bold))
56
+ hdr_page.append(Paragraph(f"BLE simulator mac: {gw_cert.uart.mac}", text_style_bold))
57
+ hdr_page.append(Paragraph(f"BLE simulator version: {gw_cert.uart.fw_version}", text_style_bold))
58
+ hdr_page.append(Paragraph(f"Tested gateway ID: {gw_cert.gw_id}", text_style_bold))
59
+ hdr_page.append(Spacer(1, 20))
60
+
61
+ # Count Table
62
+ count_data = [
63
+ ["PASSED", "INCONCLUSIVE", "FAILED", "TOTAL"],
64
+ [len(gw_cert.tests)-(failures+inconclusive), inconclusive, failures, len(gw_cert.tests)]
65
+ ]
66
+ count_table = Table(count_data)
67
+ count_table.setStyle(INNER_TABLE_STYLE)
68
+ hdr_page.append(count_table)
69
+ hdr_page.append(Spacer(1, 20))
70
+
71
+ # Test Results
72
+ summary_data = []
73
+ text_style_center = STYLES_PDF.get("BLACK", ParagraphStyle("Default"))
74
+ text_style_left = STYLES_PDF.get("BLACK_LEFT", ParagraphStyle("Default"))
75
+ for test in gw_cert.tests:
76
+ summary_data += [[test, pass_or_fail_pdf(test), format_timedelta(test.duration)]]
77
+ elements.append(Paragraph(f"<b>{test.test_name}</b>", module_header))
78
+ elements.append(Spacer(1, 20))
79
+ elements.append(pass_or_fail_pdf(test))
80
+ elements.append(Spacer(1, 10))
81
+ elements.append(Paragraph(f"Test duration: {format_timedelta(test.duration)}", text_style_bold))
82
+ elements.append(Spacer(1, 10))
83
+ inner_table, stages_breakdown = [["Phase", "Result", "Duration"]], []
84
+ for stage in test.stages:
85
+ stages_breakdown += [KeepTogether([Paragraph(stage.stage_name, test_header), Spacer(1, 10), pass_or_fail_pdf(stage), Spacer(1, 10)]
86
+ + [Paragraph(l, text_style_left) for l in stage.report.split('\n')]
87
+ + [Spacer(1, 10)])]
88
+ inner_table += [[Paragraph(stage.stage_name, text_style_center), pass_or_fail_pdf(stage), Paragraph(format_timedelta(stage.duration), text_style_center)]]
89
+ test_table = Table(inner_table)
90
+ test_table.setStyle(INNER_TABLE_STYLE)
91
+ elements.append(test_table)
92
+ elements.append(Spacer(1, 20))
93
+ elements += stages_breakdown
94
+ elements.append(PageBreak())
95
+ summary_table = Table([["Name", "Result", "Duration"]] + summary_data)
96
+ summary_table.setStyle(INNER_TABLE_STYLE)
97
+ elements = hdr_page + [summary_table, PageBreak()] + elements
98
+
99
+ doc.build(elements)
100
+
101
+
102
+ ##################################
103
+ # PDF
104
+ ##################################
105
+ STYLES_PDF = {
106
+ "GREEN_HEADER": ParagraphStyle("Green Header", fontName="Helvetica-Bold", fontSize=20, textColor=colors.green, alignment=TA_CENTER),
107
+ "RED_HEADER": ParagraphStyle("Red Header", fontName="Helvetica-Bold", fontSize=20, textColor=colors.red, alignment=TA_CENTER),
108
+ "MODULE_HEADER": ParagraphStyle("Module Header", fontName="Helvetica-Bold", fontSize=16, textColor=colors.navy, alignment=TA_CENTER),
109
+ "TEST_HEADER": ParagraphStyle("Test Header", fontName="Helvetica-Bold", fontSize=12, textColor=colors.black, alignment=TA_CENTER),
110
+ "BLACK": ParagraphStyle("Black", fontName="Helvetica", fontSize=9, textColor=colors.black, splitLongWords=False, alignment=TA_CENTER, wordWrap = 'CJK'),
111
+ "BLACK_LEFT": ParagraphStyle("Black Left", fontName="Helvetica", fontSize=9, textColor=colors.black, splitLongWords=False, alignment=TA_LEFT, wordWrap = 'CJK'),
112
+ "BLACK_BOLD": ParagraphStyle("Black Bold", fontName="Helvetica-Bold", fontSize=9, textColor=colors.black, splitLongWords=False, alignment=TA_LEFT, wordWrap = 'CJK'),
113
+ "BLUE": ParagraphStyle("Blue", fontName="Helvetica-Bold", fontSize=9, textColor=colors.navy, splitLongWords=False, alignment=TA_CENTER),
114
+ "CYAN": ParagraphStyle("Cyan", fontName="Helvetica-Bold", fontSize=9, textColor=colors.cyan, splitLongWords=False, alignment=TA_CENTER),
115
+ "GREEN": ParagraphStyle("Green", fontName="Helvetica-Bold", fontSize=9, textColor=colors.green, splitLongWords=False, alignment=TA_CENTER),
116
+ "WARNING": ParagraphStyle("Warning", fontName="Helvetica-Bold", fontSize=9, textColor=colors.gold, splitLongWords=False, alignment=TA_CENTER),
117
+ "RED": ParagraphStyle("Red", fontName="Helvetica-Bold", fontSize=9, textColor=colors.red, splitLongWords=False, alignment=TA_CENTER),
118
+ "GRAY": ParagraphStyle("Gray", fontName="Helvetica-Bold", fontSize=9, textColor=colors.gray, splitLongWords=False, alignment=TA_CENTER),
119
+ }
120
+ def color_pdf(c, t):
121
+ style = STYLES_PDF.get(c, ParagraphStyle("Default"))
122
+ return Paragraph(t, style)
123
+ pdf_result_map = {TEST_FAILED: color_pdf("RED", "FAILED"), TEST_INCONCLUSIVE: color_pdf("WARNING", "INCONCLUSIVE"),
124
+ TEST_PASSED: color_pdf("GREEN", "PASSED"), TEST_INFO: color_pdf("CYAN", "INFO"),
125
+ TEST_WARNING: color_pdf("WARNING", "WARNING"), TEST_OPTIONAL: color_pdf("GRAY", "OPTIONAL")}
126
+ pass_or_fail_pdf = lambda obj : pdf_result_map[obj.rc]
127
+
128
+ INNER_TABLE_STYLE = TableStyle([
129
+ ('BACKGROUND', (0, 0), (-1, 0), colors.grey),
130
+ ('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
131
+ ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
132
+ ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
133
+ ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
134
+ ('FONTSIZE', (0, 0), (-1, 0), 9),
135
+ ('BOTTOMPADDING', (0, 0), (-1, 0), 12),
136
+ ('BACKGROUND', (0, 1), (-1, -1), colors.whitesmoke),
137
+ ('WORDWRAP', (0, 0), (-1, -1), False),
138
+ ])
@@ -20,6 +20,7 @@ from gw_certificate.tests import *
20
20
  from gw_certificate.interface.uart_ports import get_uart_ports
21
21
  from gw_certificate.api_if.gw_capabilities import GWCapabilities
22
22
  from gw_certificate.tests import TESTS_NO_UART
23
+ import gw_certificate.cert_results as cert_results
23
24
 
24
25
  GW_CERT_VERSION = importlib.metadata.version("wiliot-certificate")
25
26
 
@@ -45,14 +46,16 @@ class GWCertificate:
45
46
  aggregation_time=0, env='prod'):
46
47
  # Runtime
47
48
  self.env_dirs = WiliotDir()
48
- self.current_datetime = datetime.datetime.now().strftime('%Y%m%d_%H%M%S')
49
- self.certificate_dir = os.path.join(self.env_dirs.get_wiliot_root_app_dir(), 'gw-certificate', self.current_datetime)
49
+ self.current_datetime = datetime.datetime.now()
50
+ self.duration = None
51
+ self.certificate_dir = os.path.join(self.env_dirs.get_wiliot_root_app_dir(), 'gw-certificate', self.current_datetime.strftime('%Y%m%d_%H%M%S'))
50
52
  self.env_dirs.create_dir(self.certificate_dir)
51
53
  self.logger_filename = initialize_logger(self.certificate_dir)
52
54
  self.logger_filepath = os.path.join(self.certificate_dir, f'{self.logger_filename}.log')
53
55
  self.mqtt_logger_filepath = os.path.join(self.certificate_dir, f'{self.logger_filename}_mqtt.log')
54
56
  self.sniffer_logger_filepath = os.path.join(self.certificate_dir, f'{self.logger_filename}_sniffer.log')
55
- self.result_html_path = os.path.join(self.certificate_dir, f'results_{self.current_datetime}.html')
57
+ self.result_html_path = os.path.join(self.certificate_dir, f'results_{self.current_datetime.strftime('%Y%m%d_%H%M%S')}.html')
58
+ self.result_pdf_path = os.path.join(self.certificate_dir, f'results_{self.current_datetime.strftime('%Y%m%d_%H%M%S')}.pdf')
56
59
  self.template_engine = TemplateEngine()
57
60
  self.env = env
58
61
 
@@ -68,6 +71,7 @@ class GWCertificate:
68
71
  self.stress_pps = stress_pps
69
72
  self.aggregation_time = aggregation_time
70
73
  self.actions = actions
74
+ self.error = ""
71
75
 
72
76
  # UART-related. Require only when running tests that need it
73
77
  self.use_uart = not all(test in TESTS_NO_UART for test in tests)
@@ -76,7 +80,9 @@ class GWCertificate:
76
80
  self.uart_comports = get_uart_ports()
77
81
  debug_print(f'UART Ports:{self.uart_comports}')
78
82
  if len(self.uart_comports) < 1:
79
- raise GWCertificateError('A Wiliot certification kit must be connected to USB!')
83
+ self.error = "A Wiliot certification kit must be connected to USB!"
84
+ cert_results.generate_pdf_results_file(self)
85
+ raise GWCertificateError(self.error)
80
86
 
81
87
  for port in self.uart_comports:
82
88
  try:
@@ -85,13 +91,19 @@ class GWCertificate:
85
91
  except UARTError as e:
86
92
  debug_print(f'Port: {port} - {e}')
87
93
  if type(self.uart) is not UARTInterface:
88
- raise GWCertificateError("Cannot initialize any port!")
94
+ self.error = "Cannot initialize any port!"
95
+ cert_results.generate_pdf_results_file(self)
96
+ raise GWCertificateError(self.error)
89
97
  self.ble_sim = BLESimulator(self.uart)
90
98
  self.sniffer = BLESniffer(self.uart, logger_filepath=self.sniffer_logger_filepath)
91
99
 
92
100
  # Tests
93
101
  self.tests = [t(**self.__dict__) for t in tests]
94
102
  debug_print(f'Running Tests: {self.tests}')
103
+
104
+ def runtime(self):
105
+ datetime.timedelta
106
+ return datetime.datetime.now() - self.current_datetime
95
107
 
96
108
  def run_tests(self):
97
109
  debug_print("Sleeping 20 seconds after mqtt connect")
@@ -125,11 +137,13 @@ class GWCertificate:
125
137
  sniffer_log = sniffer_log,
126
138
  gw_id = self.gw_id,
127
139
  version = self.gw_cert_version,
128
- datetime = self.current_datetime)
140
+ datetime = self.current_datetime.strftime('%Y%m%d_%H%M%S'))
129
141
  with open(self.result_html_path, 'w', encoding="utf-8") as f:
130
142
  f.write(html)
143
+ cert_results.generate_pdf_results_file(self)
131
144
  debug_print("Test Finished. Results HTML Saved: " + self.result_html_path)
132
145
  webbrowser.open('file://' + os.path.realpath(self.result_html_path))
146
+ webbrowser.open('file://' + os.path.realpath(self.result_pdf_path))
133
147
 
134
148
  if __name__ == "__main__":
135
149
  from api_secrets import *
@@ -216,6 +216,7 @@ class MqttClient:
216
216
  "gatewayId": gw_id,
217
217
  "imageDirUrl": image_dir_url,
218
218
  "versionUUID": version_uuid,
219
+ "upgradeBlSd": upgrade_bl_sd,
219
220
  "txPacket": reboot_packet,
220
221
  "txMaxRetries": tx_max_duration // 100,
221
222
  "txMaxDurationMs": tx_max_duration,
@@ -248,7 +248,6 @@ class ActionsTest(GenericTest):
248
248
 
249
249
  def run(self):
250
250
  super().run()
251
- self.test_pass = PERFECT_SCORE
252
251
  for stage in self.stages:
253
252
  stage.prepare_stage()
254
253
  stage.run()
@@ -182,5 +182,5 @@ class ConnectionTest(GenericTest):
182
182
  for stage in self.stages:
183
183
  stage.prepare_stage()
184
184
  stage.run()
185
- self.test_pass = PassCriteria.calc_for_test(self, stage)
186
185
  self.add_to_test_report(stage.generate_stage_report())
186
+ self.test_pass = PassCriteria.calc_for_test(self, stage)
@@ -7,6 +7,7 @@ from gw_certificate.common.debug import debug_print
7
7
  from gw_certificate.api_if.gw_capabilities import GWCapabilities
8
8
  from gw_certificate.interface.ble_simulator import BLESimulator
9
9
  from gw_certificate.interface.mqtt import MqttClient
10
+ from gw_certificate.ag.ut_defines import TEST_PASSED, TEST_FAILED, TEST_INCONCLUSIVE, TEST_OPTIONAL, TEST_WARNING, TEST_INFO
10
11
 
11
12
  PASS_STATUS = {True: 'PASS', False: 'FAIL'}
12
13
 
@@ -37,19 +38,6 @@ class PassCriteria():
37
38
  return 'Inconclusive'
38
39
  else:
39
40
  return 'Fail'
40
-
41
- @staticmethod
42
- def missing_score(pass_value:int) -> int:
43
- return PERFECT_SCORE - pass_value
44
-
45
- @staticmethod
46
- def calc_for_stage_uplink(pass_value:int, stage_name:str) -> int:
47
- error_msg = "Insufficient amount of packets were scanned & uploaded by the gateway"
48
- return pass_value, error_msg
49
-
50
- @staticmethod
51
- def calc_for_stage_stress(pass_value: int, stage_name:str) -> int:
52
- return pass_value
53
41
 
54
42
  @staticmethod
55
43
  def calc_for_stage_downlink(rsquared, slope, stage_name:str):
@@ -99,12 +87,14 @@ class GenericTest:
99
87
  self.pass_min = PASS_MINIMUM
100
88
  self.inconclusive_min = INCONCLUSIVE_MINIMUM
101
89
  self.start_time = None
90
+ self.duration = None
102
91
  self.test_name = test_name
103
92
  self.test_dir = os.path.join(self.certificate_dir, self.test_name)
104
93
  self.env_dirs.create_dir(self.test_dir)
105
94
  self.stages = []
106
95
  self.test_tooltip = kwargs.get('test_tooltip', 'Missing tooltip')
107
96
  self.result_indication = kwargs.get('result_indication', SCORE_BASED)
97
+ self.rc = TEST_PASSED
108
98
 
109
99
  def __repr__(self):
110
100
  return self.test_name
@@ -125,8 +115,12 @@ class GenericTest:
125
115
  def create_test_html(self):
126
116
  self.report_html = self.template_engine.render_template('test.html', test=self,
127
117
  running_time = self.runtime())
128
-
118
+
129
119
  def end_test(self):
120
+ self.determine_rc()
121
+ for stage in self.stages:
122
+ stage.determine_rc()
123
+ self.duration = self.runtime()
130
124
  self.create_test_html()
131
125
 
132
126
  def score_pass(self):
@@ -143,6 +137,21 @@ class GenericTest:
143
137
  if self.test_pass < self.inconclusive_min:
144
138
  return True
145
139
  return False
140
+
141
+ def determine_rc(self):
142
+ # Set test rc - defaults to TEST_PASSED (rc=0)
143
+ if self.result_indication == 'info':
144
+ if self.score_pass():
145
+ self.rc = TEST_INFO
146
+ else:
147
+ self.rc = TEST_WARNING
148
+ elif self.result_indication == 'optional':
149
+ self.rc = TEST_OPTIONAL
150
+ else:
151
+ if self.score_inconclusive():
152
+ self.rc = TEST_INCONCLUSIVE
153
+ elif self.score_fail():
154
+ self.rc = TEST_FAILED
146
155
 
147
156
 
148
157
  class GenericStage():
@@ -156,9 +165,11 @@ class GenericStage():
156
165
  self.report = ''
157
166
  self.report_html = ''
158
167
  self.start_time = None
168
+ self.duration = None
159
169
  self.csv_path = os.path.join(self.test_dir, f'{self.stage_name}.csv')
160
170
  self.stage_tooltip = kwargs.get('stage_tooltip', 'Missing tooltip')
161
171
  self.error_summary = kwargs.get('error_summary', ERR_SUMMARY_DEFAULT)
172
+ self.rc = TEST_PASSED
162
173
 
163
174
  def __repr__(self):
164
175
  return self.stage_name
@@ -180,11 +191,14 @@ class GenericStage():
180
191
 
181
192
  def add_report_header(self):
182
193
  uncapitalize = lambda s: s[:1].lower() + s[1:] if s else ''
183
- self.add_to_stage_report(f'Stage run time: {datetime.datetime.now() - self.start_time}')
194
+ self.duration = datetime.datetime.now() - self.start_time
195
+ self.add_to_stage_report(f'Stage run time: {self.duration}')
184
196
  self.add_to_stage_report(f'This stage {uncapitalize(self.stage_tooltip)}.')
185
197
  self.add_report_line_separator()
186
198
 
187
199
  def add_report_topic_validation(self, topic:Literal['status', 'data']):
200
+ pass
201
+ # Pass until validated
188
202
  if self.topic_suffix != '':
189
203
  return
190
204
  valid_topic, invalid_msg, invalid_topic = self.mqttc.validate_serialization_topic(topic)
@@ -192,7 +206,7 @@ class GenericStage():
192
206
  # For now not failing stage since the customBroker command include topics explicitly
193
207
  # self.stage_pass = MINIMUM_SCORE
194
208
  # self.error_summary += "Invalid serialization-topic combination. "
195
- self.add_to_stage_report(f'Warning: Received message on {invalid_topic} although serialization is {self.mqttc.get_serialization()}')
209
+ self.add_to_stage_report(f'Note: Received message on {invalid_topic} although serialization is {self.mqttc.get_serialization()}')
196
210
 
197
211
  def score_pass(self):
198
212
  if self.stage_pass >= self.pass_min:
@@ -208,4 +222,16 @@ class GenericStage():
208
222
  if self.stage_pass < self.inconclusive_min:
209
223
  return True
210
224
  return False
211
-
225
+
226
+ def determine_rc(self):
227
+ # Set stage rc - defaults to TEST_PASSED (rc=0)
228
+ if self.result_indication == 'info':
229
+ if self.score_pass():
230
+ self.rc = TEST_INFO
231
+ else:
232
+ self.rc = TEST_WARNING
233
+ else:
234
+ if self.score_inconclusive():
235
+ self.rc = TEST_INCONCLUSIVE
236
+ elif self.score_fail():
237
+ self.rc = TEST_FAILED
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: wiliot_certificate
3
- Version: 1.4.0a2
3
+ Version: 1.5.0a1
4
4
  Summary: A library for certifying Wiliot-compliant boards
5
5
  Author-email: Wiliot <support@wiliot.com>
6
6
  License: MIT License
@@ -93,11 +93,13 @@ Increments time delays between packets to evaluate GW's capability in handling i
93
93
  #### GW Certificate Release Notes:
94
94
  1.4.0:
95
95
  - Released in a standalone wiliot-certificate package
96
- - Python 3.12 support
96
+ - Python 3.13 support
97
97
  - Gw API version 205 support
98
- - Registration Test
98
+ - Registration test added
99
+ - Bridge OTA stage added under actions
99
100
  - Aggregation flag supported by StressTest
100
-
101
+ - -update flag compatibility fix. Upgrades bootloader as well
102
+ - -actions flag to select specific actions to test
101
103
 
102
104
  ```
103
105
  usage: wlt-gw-certificate [-h] -owner OWNER -gw GW [-suffix SUFFIX] [-tests {connection,uplink,downlink,stress}]