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