26
26
NEW_MFW_DELTA_VERSION = "mfw_nrf91x1_2.0.2-FOTA-TEST"
27
27
MFW_202_VERSION = "mfw_nrf91x1_2.0.2"
28
28
29
+ TEST_APP_BIN = {
30
+ "thingy91x" : "artifacts/stable_version_jan_2025-update-signed.bin" ,
31
+ "nrf9151dk" : "artifacts/nrf9151dk_mar_2025_update_signed.bin"
32
+ }
33
+
29
34
DEVICE_MSG_TIMEOUT = 60 * 5
30
35
APP_FOTA_TIMEOUT = 60 * 10
31
36
FULL_MFW_FOTA_TIMEOUT = 60 * 30
@@ -46,81 +51,80 @@ def await_nrfcloud(func, expected, field, timeout):
46
51
if expected in data :
47
52
break
48
53
49
- def get_appversion (t91x_fota ):
50
- shadow = t91x_fota .fota .get_device (t91x_fota .device_id )
54
+ def get_appversion (dut_fota ):
55
+ shadow = dut_fota .fota .get_device (dut_fota .device_id )
51
56
return shadow ["state" ]["reported" ]["device" ]["deviceInfo" ]["appVersion" ]
52
57
53
- def get_modemversion (t91x_fota ):
54
- shadow = t91x_fota .fota .get_device (t91x_fota .device_id )
58
+ def get_modemversion (dut_fota ):
59
+ shadow = dut_fota .fota .get_device (dut_fota .device_id )
55
60
return shadow ["state" ]["reported" ]["device" ]["deviceInfo" ]["modemFirmware" ]
56
61
57
- def run_fota_resumption (t91x_fota , fota_type ):
62
+ def run_fota_resumption (dut_fota , fota_type ):
58
63
timeout_50_percent = APP_FOTA_TIMEOUT / 2
59
- t91x_fota .uart .wait_for_str ("50%" , timeout = timeout_50_percent )
64
+ dut_fota .uart .wait_for_str ("50%" , timeout = timeout_50_percent )
60
65
logger .debug (f"Testing fota resumption on disconnect for { fota_type } fota" )
61
66
62
67
patterns_lte_offline = ["network: Network connectivity lost" ]
63
68
patterns_lte_normal = ["network: Network connectivity established" ]
64
69
65
70
# LTE disconnect
66
- t91x_fota .uart .flush ()
67
- t91x_fota .uart .write ("zbus disconnect\r \n " )
68
- t91x_fota .uart .wait_for_str (patterns_lte_offline , timeout = 20 )
71
+ dut_fota .uart .flush ()
72
+ dut_fota .uart .write ("zbus disconnect\r \n " )
73
+ dut_fota .uart .wait_for_str (patterns_lte_offline , timeout = 20 )
69
74
70
75
# LTE reconnect
71
- t91x_fota .uart .flush ()
72
- t91x_fota .uart .write ("zbus connect\r \n " )
73
- t91x_fota .uart .wait_for_str (patterns_lte_normal , timeout = 120 )
74
-
75
- t91x_fota .uart .wait_for_str ("fota_download: Refuse fragment, restart with offset" )
76
- t91x_fota .uart .wait_for_str ("fota_download: Downloading from offset:" )
77
-
78
- def run_fota_reschedule (t91x_fota , fota_type ):
79
- t91x_fota .uart .wait_for_str (f"5%" , timeout = APP_FOTA_TIMEOUT )
76
+ dut_fota .uart .flush ()
77
+ dut_fota .uart .write ("zbus connect\r \n " )
78
+ dut_fota .uart .wait_for_str (patterns_lte_normal , timeout = 120 )
79
+ dut_fota .uart .wait_for_str ("fota_download: Refuse fragment, restart with offset" )
80
+ dut_fota .uart .wait_for_str ("fota_download: Downloading from offset:" )
81
+
82
+ def run_fota_reschedule (dut_fota , fota_type ):
83
+ dut_fota .uart .wait_for_str ("5%" , timeout = APP_FOTA_TIMEOUT )
80
84
logger .debug (f"Cancelling FOTA, type: { fota_type } " )
81
85
82
- t91x_fota .fota .cancel_fota_job (t91x_fota .data ['job_id' ])
86
+ dut_fota .fota .cancel_fota_job (dut_fota .data ['job_id' ])
83
87
84
88
await_nrfcloud (
85
- functools .partial (t91x_fota .fota .get_fota_status , t91x_fota .data ['job_id' ]),
89
+ functools .partial (dut_fota .fota .get_fota_status , dut_fota .data ['job_id' ]),
86
90
"CANCELLED" ,
87
91
"FOTA status" ,
88
92
APP_FOTA_TIMEOUT
89
93
)
90
94
91
95
patterns_fota_cancel = ["Firmware download canceled" , "state_waiting_for_poll_request_entry" ]
92
96
93
- t91x_fota .uart .wait_for_str (patterns_fota_cancel , timeout = 180 )
97
+ dut_fota .uart .wait_for_str (patterns_fota_cancel , timeout = 180 )
94
98
95
- t91x_fota .data ['job_id' ] = t91x_fota .fota .create_fota_job (t91x_fota .device_id , t91x_fota .data ['bundle_id' ])
99
+ dut_fota .data ['job_id' ] = dut_fota .fota .create_fota_job (dut_fota .device_id , dut_fota .data ['bundle_id' ])
96
100
97
- logger .info (f"Rescheduled FOTA Job (ID: { t91x_fota .data ['job_id' ]} )" )
101
+ logger .info (f"Rescheduled FOTA Job (ID: { dut_fota .data ['job_id' ]} )" )
98
102
99
103
# Sleep a bit and trigger fota poll
100
104
for i in range (3 ):
101
105
try :
102
106
time .sleep (30 )
103
- t91x_fota .uart .write ("zbus button_press\r \n " )
104
- t91x_fota .uart .wait_for_str ("nrf_cloud_fota_poll: Starting FOTA download" )
107
+ dut_fota .uart .write ("zbus button_press\r \n " )
108
+ dut_fota .uart .wait_for_str ("nrf_cloud_fota_poll: Starting FOTA download" )
105
109
break
106
110
except AssertionError :
107
111
continue
108
112
else :
109
113
raise AssertionError (f"Fota update not available after { i } attempts" )
110
114
111
115
@pytest .fixture
112
- def run_fota_fixture (t91x_fota , hex_file , reschedule = False ):
116
+ def run_fota_fixture (dut_fota , hex_file , reschedule = False ):
113
117
def _run_fota (bundle_id = "" , fota_type = "app" , fotatimeout = APP_FOTA_TIMEOUT , new_version = TEST_APP_VERSION , reschedule = False ):
114
118
flash_device (os .path .abspath (hex_file ))
115
- t91x_fota .uart .xfactoryreset ()
116
- t91x_fota .uart .flush ()
119
+ dut_fota .uart .xfactoryreset ()
120
+ dut_fota .uart .flush ()
117
121
reset_device ()
118
- t91x_fota .uart .wait_for_str ("Connected to Cloud" )
122
+ dut_fota .uart .wait_for_str ("Connected to Cloud" )
119
123
120
124
time .sleep (60 )
121
125
122
126
if fota_type == "app" :
123
- bundle_id = t91x_fota .fota .upload_firmware (
127
+ bundle_id = dut_fota .fota .upload_firmware (
124
128
"nightly_test_app" ,
125
129
TEST_APP_BIN ,
126
130
TEST_APP_VERSION ,
@@ -130,39 +134,37 @@ def _run_fota(bundle_id="", fota_type="app", fotatimeout=APP_FOTA_TIMEOUT, new_v
130
134
logger .info (f"Uploaded file { TEST_APP_BIN } : bundleId: { bundle_id } " )
131
135
132
136
try :
133
- t91x_fota .data ['job_id' ] = t91x_fota .fota .create_fota_job (t91x_fota .device_id , bundle_id )
134
- t91x_fota .data ['bundle_id' ] = bundle_id
137
+ dut_fota .data ['job_id' ] = dut_fota .fota .create_fota_job (dut_fota .device_id , bundle_id )
138
+ dut_fota .data ['bundle_id' ] = bundle_id
135
139
except NRFCloudFOTAError as e :
136
140
pytest .skip (f"FOTA create_job REST API error: { e } " )
137
- logger .info (f"Created FOTA Job (ID: { t91x_fota .data ['job_id' ]} )" )
141
+ logger .info (f"Created FOTA Job (ID: { dut_fota .data ['job_id' ]} )" )
138
142
139
143
# Sleep a bit and trigger fota poll
140
144
for i in range (3 ):
141
145
try :
142
146
time .sleep (10 )
143
- t91x_fota .uart .write ("zbus button_press\r \n " )
144
- t91x_fota .uart .wait_for_str ("nrf_cloud_fota_poll: Starting FOTA download" )
147
+ dut_fota .uart .write ("zbus button_press\r \n " )
148
+ dut_fota .uart .wait_for_str ("nrf_cloud_fota_poll: Starting FOTA download" )
145
149
break
146
150
except AssertionError :
147
151
continue
148
152
else :
149
153
raise AssertionError (f"Fota update not available after { i } attempts" )
150
154
151
155
if reschedule :
152
- run_fota_reschedule (t91x_fota , fota_type )
156
+ run_fota_reschedule (dut_fota , fota_type )
153
157
154
158
if fota_type == "app" :
155
- run_fota_resumption (t91x_fota , "app" )
156
-
159
+ run_fota_resumption (dut_fota , "app" )
157
160
await_nrfcloud (
158
- functools .partial (t91x_fota .fota .get_fota_status , t91x_fota .data ['job_id' ]),
161
+ functools .partial (dut_fota .fota .get_fota_status , dut_fota .data ['job_id' ]),
159
162
"IN_PROGRESS" ,
160
163
"FOTA status" ,
161
164
fotatimeout
162
165
)
163
-
164
166
await_nrfcloud (
165
- functools .partial (t91x_fota .fota .get_fota_status , t91x_fota .data ['job_id' ]),
167
+ functools .partial (dut_fota .fota .get_fota_status , dut_fota .data ['job_id' ]),
166
168
"COMPLETED" ,
167
169
"FOTA status" ,
168
170
fotatimeout
@@ -171,14 +173,14 @@ def _run_fota(bundle_id="", fota_type="app", fotatimeout=APP_FOTA_TIMEOUT, new_v
171
173
try :
172
174
if fota_type == "app" :
173
175
await_nrfcloud (
174
- functools .partial (get_appversion , t91x_fota ),
176
+ functools .partial (get_appversion , dut_fota ),
175
177
new_version ,
176
178
"appVersion" ,
177
179
DEVICE_MSG_TIMEOUT
178
180
)
179
181
else :
180
182
await_nrfcloud (
181
- functools .partial (get_modemversion , t91x_fota ),
183
+ functools .partial (get_modemversion , dut_fota ),
182
184
new_version ,
183
185
"modemFirmware" ,
184
186
DEVICE_MSG_TIMEOUT
0 commit comments