9
9
10
10
import argparse
11
11
from dataclasses import dataclass
12
- import fcntl
13
12
import glob
14
13
import hashlib
15
- import io
16
14
import json
17
15
import os
18
16
import platform
@@ -143,6 +141,14 @@ def subprocess_output(self):
143
141
return sys .stdout
144
142
return subprocess .DEVNULL
145
143
144
+ def check_call (self , args , ** kwargs ):
145
+ self .log_info (f"Running: { ' ' .join (args )} " )
146
+ return subprocess .check_call (args , ** kwargs )
147
+
148
+ def check_output (self , args , ** kwargs ):
149
+ self .log_info (f"Running: { ' ' .join (args )} " )
150
+ return subprocess .check_output (args , ** kwargs )
151
+
146
152
def ffx_daemon_log_path (self ):
147
153
return os .path .join (self .tmp_dir (), "ffx_daemon_log" )
148
154
@@ -178,7 +184,7 @@ def start_ffx_isolation(self):
178
184
)
179
185
180
186
# Disable analytics
181
- subprocess .check_call (
187
+ self .check_call (
182
188
[
183
189
ffx_path ,
184
190
"config" ,
@@ -197,7 +203,7 @@ def start_ffx_isolation(self):
197
203
"test.experimental_structured_output" : "true" ,
198
204
}
199
205
for key , value in configs .items ():
200
- subprocess .check_call (
206
+ self .check_call (
201
207
[
202
208
ffx_path ,
203
209
"config" ,
@@ -222,7 +228,7 @@ def ffx_cmd_env(self):
222
228
}
223
229
224
230
def stop_ffx_isolation (self ):
225
- subprocess .check_call (
231
+ self .check_call (
226
232
[
227
233
self .tool_path ("ffx" ),
228
234
"daemon" ,
@@ -265,7 +271,7 @@ def start(self):
265
271
self .start_ffx_isolation ()
266
272
267
273
# Stop any running emulators (there shouldn't be any)
268
- subprocess .check_call (
274
+ self .check_call (
269
275
[
270
276
ffx_path ,
271
277
"emu" ,
@@ -282,11 +288,11 @@ def start(self):
282
288
product_name = "minimal." + self .triple_to_arch (self .target )
283
289
fuchsia_version = "20.20240412.3.1"
284
290
285
- # FIXME: We should be able to replace this with the machine parsable
286
- # `ffx --machine json product lookup ...` once F15 is released.
287
- out = subprocess .check_output (
291
+ out = self .check_output (
288
292
[
289
293
ffx_path ,
294
+ "--machine" ,
295
+ "json" ,
290
296
"product" ,
291
297
"lookup" ,
292
298
product_name ,
@@ -300,16 +306,15 @@ def start(self):
300
306
301
307
self .log_debug (out )
302
308
303
- for line in io .BytesIO (out ):
304
- if line .startswith (b"gs://" ):
305
- transfer_manifest_url = line .rstrip ()
306
- break
307
- else :
308
- raise Exception ("Unable to parse transfer manifest" )
309
+ try :
310
+ transfer_manifest_url = json .loads (out )["transfer_manifest_url" ]
311
+ except Exception as e :
312
+ print (e )
313
+ raise Exception ("Unable to parse transfer manifest" ) from e
309
314
310
315
# Download the product bundle.
311
316
product_bundle_dir = os .path .join (self .tmp_dir (), 'product-bundle' )
312
- subprocess .check_call (
317
+ self .check_call (
313
318
[
314
319
ffx_path ,
315
320
"product" ,
@@ -325,7 +330,7 @@ def start(self):
325
330
326
331
# Start emulator
327
332
# FIXME: condition --accel hyper on target arch matching host arch
328
- subprocess .check_call (
333
+ self .check_call (
329
334
[
330
335
ffx_path ,
331
336
"emu" ,
@@ -346,42 +351,52 @@ def start(self):
346
351
347
352
# Create new package repo
348
353
self .log_info ("Creating package repo..." )
349
- subprocess .check_call (
354
+ self .check_call (
350
355
[
351
- self . tool_path ( "pm" ) ,
352
- "newrepo " ,
353
- "-repo " ,
356
+ ffx_path ,
357
+ "repository " ,
358
+ "create " ,
354
359
self .repo_dir (),
355
360
],
361
+ env = ffx_env ,
356
362
stdout = self .subprocess_output (),
357
363
stderr = self .subprocess_output (),
358
364
)
359
365
360
- # Add repo
361
- subprocess .check_call (
366
+ self .check_call (
362
367
[
363
368
ffx_path ,
364
369
"repository" ,
365
370
"add-from-pm" ,
366
- self .repo_dir (),
367
371
"--repository" ,
368
372
self .TEST_REPO_NAME ,
373
+ self .repo_dir (),
369
374
],
370
375
env = ffx_env ,
371
376
stdout = self .subprocess_output (),
372
377
stderr = self .subprocess_output (),
373
378
)
374
379
380
+ # Write to file
381
+ self .write_to_file ()
382
+
375
383
# Start repository server
376
- subprocess .check_call (
377
- [ffx_path , "repository" , "server" , "start" , "--address" , "[::]:0" ],
384
+ self .check_call (
385
+ [
386
+ ffx_path ,
387
+ "repository" ,
388
+ "server" ,
389
+ "start" ,
390
+ "--address" ,
391
+ "[::]:0" ,
392
+ ],
378
393
env = ffx_env ,
379
394
stdout = self .subprocess_output (),
380
395
stderr = self .subprocess_output (),
381
396
)
382
397
383
398
# Register with newly-started emulator
384
- subprocess .check_call (
399
+ self .check_call (
385
400
[
386
401
ffx_path ,
387
402
"target" ,
@@ -395,12 +410,6 @@ def start(self):
395
410
stderr = self .subprocess_output (),
396
411
)
397
412
398
- # Create lockfiles
399
- open (self .pm_lockfile_path (), "a" ).close ()
400
-
401
- # Write to file
402
- self .write_to_file ()
403
-
404
413
self .log_info ("Success! Your environment is ready to run tests." )
405
414
406
415
# FIXME: shardify this
@@ -445,7 +454,6 @@ def start(self):
445
454
meta/{package_name}.cm={package_dir}/meta/{package_name}.cm
446
455
bin/{exe_name}={bin_path}
447
456
lib/{libstd_name}={libstd_path}
448
- lib/{libtest_name}={libtest_path}
449
457
lib/ld.so.1={sdk_dir}/arch/{target_arch}/sysroot/dist/lib/ld.so.1
450
458
lib/libfdio.so={sdk_dir}/arch/{target_arch}/dist/libfdio.so
451
459
"""
@@ -482,9 +490,6 @@ def run(self, args):
482
490
if not libstd_paths :
483
491
raise Exception (f"Failed to locate libstd (in { self .rustlibs_dir ()} )" )
484
492
485
- if not libtest_paths :
486
- raise Exception (f"Failed to locate libtest (in { self .rustlibs_dir ()} )" )
487
-
488
493
# Build a unique, deterministic name for the test using the name of the
489
494
# binary and the last 6 hex digits of the hash of the full path
490
495
def path_checksum (path ):
@@ -500,6 +505,7 @@ def path_checksum(path):
500
505
cml_path = os .path .join (package_dir , "meta" , f"{ package_name } .cml" )
501
506
cm_path = os .path .join (package_dir , "meta" , f"{ package_name } .cm" )
502
507
manifest_path = os .path .join (package_dir , f"{ package_name } .manifest" )
508
+ manifest_json_path = os .path .join (package_dir , "package_manifest.json" )
503
509
far_path = os .path .join (package_dir , f"{ package_name } -0.far" )
504
510
505
511
shared_libs = args .shared_libs [: args .n ]
@@ -523,22 +529,6 @@ def log(msg):
523
529
524
530
log (f"Bin path: { bin_path } " )
525
531
526
- log ("Setting up package..." )
527
-
528
- # Set up package
529
- subprocess .check_call (
530
- [
531
- self .tool_path ("pm" ),
532
- "-o" ,
533
- package_dir ,
534
- "-n" ,
535
- package_name ,
536
- "init" ,
537
- ],
538
- stdout = log_file ,
539
- stderr = log_file ,
540
- )
541
-
542
532
log ("Writing CML..." )
543
533
544
534
# Write and compile CML
@@ -563,7 +553,7 @@ def log(msg):
563
553
564
554
log ("Compiling CML..." )
565
555
566
- subprocess .check_call (
556
+ self .check_call (
567
557
[
568
558
self .tool_path ("cmc" ),
569
559
"compile" ,
@@ -590,64 +580,80 @@ def log(msg):
590
580
target = self .target ,
591
581
sdk_dir = self .sdk_dir ,
592
582
libstd_name = os .path .basename (libstd_paths [0 ]),
593
- libtest_name = os .path .basename (libtest_paths [0 ]),
594
583
libstd_path = libstd_paths [0 ],
595
- libtest_path = libtest_paths [0 ],
596
584
target_arch = self .triple_to_arch (self .target ),
597
585
)
598
586
)
587
+ # `libtest`` was historically a shared library, but now seems to be (sometimes?)
588
+ # statically linked. If we find it as a shared library, include it in the manifest.
589
+ if libtest_paths :
590
+ manifest .write (
591
+ f"lib/{ os .path .basename (libtest_paths [0 ])} ={ libtest_paths [0 ]} \n "
592
+ )
599
593
for shared_lib in shared_libs :
600
594
manifest .write (f"lib/{ os .path .basename (shared_lib )} ={ shared_lib } \n " )
601
595
596
+ log ("Determining API level..." )
597
+ out = self .check_output (
598
+ [
599
+ self .tool_path ("ffx" ),
600
+ "--machine" ,
601
+ "json" ,
602
+ "version" ,
603
+ ],
604
+ env = self .ffx_cmd_env (),
605
+ stderr = log_file ,
606
+ )
607
+ api_level = json .loads (out )["tool_version" ]["api_level" ]
608
+
602
609
log ("Compiling and archiving manifest..." )
603
610
604
- subprocess .check_call (
611
+ self .check_call (
605
612
[
606
- self .tool_path ("pm" ),
613
+ self .tool_path ("ffx" ),
614
+ "package" ,
615
+ "build" ,
616
+ manifest_path ,
607
617
"-o" ,
608
618
package_dir ,
609
- "-m" ,
610
- manifest_path ,
611
- "build" ,
619
+ "--api-level" ,
620
+ str (api_level ),
612
621
],
622
+ env = self .ffx_cmd_env (),
613
623
stdout = log_file ,
614
624
stderr = log_file ,
615
625
)
616
- subprocess .check_call (
626
+
627
+ self .check_call (
617
628
[
618
- self .tool_path ("pm" ),
619
- "-o" ,
620
- package_dir ,
621
- "-m" ,
622
- manifest_path ,
629
+ self .tool_path ("ffx" ),
630
+ "package" ,
623
631
"archive" ,
632
+ "create" ,
633
+ "-o" ,
634
+ far_path ,
635
+ manifest_json_path ,
624
636
],
637
+ env = self .ffx_cmd_env (),
625
638
stdout = log_file ,
626
639
stderr = log_file ,
627
640
)
628
641
629
642
log ("Publishing package to repo..." )
630
643
631
644
# Publish package to repo
632
- with open (self .pm_lockfile_path (), "w" ) as pm_lockfile :
633
- fcntl .lockf (pm_lockfile .fileno (), fcntl .LOCK_EX )
634
- subprocess .check_call (
635
- [
636
- self .tool_path ("pm" ),
637
- "publish" ,
638
- "-a" ,
639
- "-repo" ,
640
- self .repo_dir (),
641
- "-f" ,
642
- far_path ,
643
- ],
644
- stdout = log_file ,
645
- stderr = log_file ,
646
- )
647
- # This lock should be released automatically when the pm
648
- # lockfile is closed, but we'll be polite and unlock it now
649
- # since the spec leaves some wiggle room.
650
- fcntl .lockf (pm_lockfile .fileno (), fcntl .LOCK_UN )
645
+ self .check_call (
646
+ [
647
+ self .tool_path ("ffx" ),
648
+ "repository" ,
649
+ "publish" ,
650
+ "--package" ,
651
+ os .path .join (package_dir , "package_manifest.json" ),
652
+ self .repo_dir (),
653
+ ],
654
+ stdout = log_file ,
655
+ stderr = log_file ,
656
+ )
651
657
652
658
log ("Running ffx test..." )
653
659
@@ -765,7 +771,7 @@ def stop(self):
765
771
766
772
# Shut down the emulator
767
773
self .log_info ("Stopping emulator..." )
768
- subprocess .check_call (
774
+ self .check_call (
769
775
[
770
776
self .tool_path ("ffx" ),
771
777
"emu" ,
0 commit comments