@@ -161,6 +161,40 @@ def is_uploaded():
161
161
return True
162
162
163
163
164
+ @contextmanager
165
+ def _upload_time_limit (seconds ):
166
+ def signal_handler (signum , frame ):
167
+ raise TimeoutError ("Apk upload took more than %s seconds" % seconds )
168
+
169
+ signal .signal (signal .SIGALRM , signal_handler )
170
+ signal .alarm (seconds )
171
+ try :
172
+ yield
173
+ finally :
174
+ signal .alarm (0 )
175
+
176
+ class UploadApkException (Exception ):
177
+ pass
178
+
179
+ def _upload_and_check_response (apk_file_path ):
180
+ with _upload_time_limit (600 ):
181
+ with open (apk_file_path , 'rb' ) as f :
182
+ resp = sauce .storage ._session .request ('post' , '/v1/storage/upload' , files = {'payload' : f })
183
+
184
+ try :
185
+ if resp ['item' ]['name' ] != test_suite_data .apk_name :
186
+ raise UploadApkException ("Incorrect apk was uploaded to Sauce storage, response:\n %s" % resp )
187
+ except KeyError :
188
+ raise UploadApkException ("Error when uploading apk to Sauce storage, response:\n %s" % resp )
189
+
190
+ def _upload_and_check_response_with_retries (apk_file_path , retries = 3 ):
191
+ for _ in range (retries ):
192
+ try :
193
+ _upload_and_check_response (apk_file_path )
194
+ break
195
+ except (ConnectionError , RemoteDisconnected ):
196
+ sleep (10 )
197
+
164
198
def pytest_configure (config ):
165
199
global option
166
200
option = config .option
@@ -180,75 +214,51 @@ def pytest_configure(config):
180
214
apibase = 'eu-central-1.saucelabs.com'
181
215
else :
182
216
raise NotImplementedError ("Unknown SauceLabs datacenter" )
217
+
183
218
global sauce
184
219
sauce = SauceLab ('https://api.' + apibase + '/' , sauce_username , sauce_access_key )
185
220
if config .getoption ('log_steps' ):
186
221
import logging
187
222
logging .basicConfig (level = logging .INFO )
188
- if config .getoption ('env' ) != 'api' :
189
- test_suite_data .apk_name = ([i for i in [i for i in config .getoption ('apk' ).split ('/' )
190
- if '.apk' in i ]])[0 ]
191
- if is_master (config ):
192
- pr_number = config .getoption ('pr_number' )
193
- if config .getoption ('testrail_report' ):
194
- if pr_number :
195
- run_number = len (testrail_report .get_runs (pr_number )) + 1
196
- run_name = 'PR-%s run #%s' % (pr_number , run_number )
197
- else :
198
- run_name = test_suite_data .apk_name
199
- testrail_report .add_run (run_name )
200
- if pr_number :
201
- from github import Github
202
- repo = Github (github_token ).get_user ('status-im' ).get_repo ('status-mobile' )
203
- pull = repo .get_pull (int (pr_number ))
204
- pull .get_commits ()[0 ].create_status (state = 'pending' , context = 'Mobile e2e tests' ,
205
- description = 'e2e tests are running' )
206
- if config .getoption ('env' ) == 'sauce' :
207
- if not is_uploaded ():
208
- def _upload_and_check_response (apk_file_path ):
209
- @contextmanager
210
- def _upload_time_limit (seconds ):
211
- def signal_handler (signum , frame ):
212
- raise TimeoutError ("Apk upload took more than %s seconds" % seconds )
213
-
214
- signal .signal (signal .SIGALRM , signal_handler )
215
- signal .alarm (seconds )
216
- try :
217
- yield
218
- finally :
219
- signal .alarm (0 )
220
-
221
- with _upload_time_limit (600 ):
222
- class UploadApkException (Exception ):
223
- pass
224
-
225
- with open (apk_file_path , 'rb' ) as f :
226
- resp = sauce .storage ._session .request ('post' , '/v1/storage/upload' ,
227
- files = {'payload' : f })
228
- try :
229
- if resp ['item' ]['name' ] != test_suite_data .apk_name :
230
- raise UploadApkException (
231
- "Incorrect apk was uploaded to Sauce storage, response:\n %s" % resp )
232
- except KeyError :
233
- raise UploadApkException (
234
- "Error when uploading apk to Sauce storage, response:\n %s" % resp )
235
-
236
- if 'http' in config .getoption ('apk' ):
237
- # it works with just a file_name, but I've added full path because not sure how it'll behave on the remote run (Jenkins)
238
- file_path , to_remove = os .path .join (os .path .dirname (__file__ ), test_suite_data .apk_name ), True
239
- urllib .request .urlretrieve (config .getoption ('apk' ),
240
- filename = file_path ) # if url is not valid it raises an error
241
- else :
242
- file_path , to_remove = config .getoption ('apk' ), False
243
-
244
- for _ in range (3 ):
245
- try :
246
- _upload_and_check_response (apk_file_path = file_path )
247
- break
248
- except (ConnectionError , RemoteDisconnected ):
249
- sleep (10 )
250
- if to_remove :
251
- os .remove (file_path )
223
+ if config .getoption ('env' ) == 'api' :
224
+ return
225
+
226
+ test_suite_data .apk_name = ([i for i in [i for i in config .getoption ('apk' ).split ('/' )
227
+ if '.apk' in i ]])[0 ]
228
+ if not is_master (config ):
229
+ return
230
+
231
+ pr_number = config .getoption ('pr_number' )
232
+ if config .getoption ('testrail_report' ):
233
+ if pr_number :
234
+ run_number = len (testrail_report .get_runs (pr_number )) + 1
235
+ run_name = 'PR-%s run #%s' % (pr_number , run_number )
236
+ else :
237
+ run_name = test_suite_data .apk_name
238
+ testrail_report .add_run (run_name )
239
+
240
+ if pr_number :
241
+ from github import Github
242
+ repo = Github (github_token ).get_user ('status-im' ).get_repo ('status-mobile' )
243
+ pull = repo .get_pull (int (pr_number ))
244
+ pull .get_commits ()[0 ].create_status (
245
+ state = 'pending' ,
246
+ context = 'Mobile e2e tests' ,
247
+ description = 'e2e tests are running'
248
+ )
249
+
250
+ if config .getoption ('env' ) == 'sauce' and not is_uploaded ():
251
+ apk_src = config .getoption ('apk' )
252
+ if apk_src .startsWith ('http' ):
253
+ # Absolute path adde to handle CI runs.
254
+ apk_path = os .path .join (os .path .dirname (__file__ ), test_suite_data .apk_name )
255
+ urllib .request .urlretrieve (apk_src , filename = apk_path )
256
+ else :
257
+ apk_path = apk_src
258
+
259
+ _upload_and_check_response_with_retries (apk_path )
260
+ if apk_src .startsWith ('http' ):
261
+ os .remove (apk_path )
252
262
253
263
254
264
def pytest_unconfigure (config ):
0 commit comments