@@ -143,6 +143,14 @@ def subprocess_output(self):
143143 return sys .stdout
144144 return subprocess .DEVNULL
145145
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+
146154 def ffx_daemon_log_path (self ):
147155 return os .path .join (self .tmp_dir (), "ffx_daemon_log" )
148156
@@ -178,7 +186,7 @@ def start_ffx_isolation(self):
178186 )
179187
180188 # Disable analytics
181- subprocess .check_call (
189+ self .check_call (
182190 [
183191 ffx_path ,
184192 "config" ,
@@ -197,7 +205,7 @@ def start_ffx_isolation(self):
197205 "test.experimental_structured_output" : "true" ,
198206 }
199207 for key , value in configs .items ():
200- subprocess .check_call (
208+ self .check_call (
201209 [
202210 ffx_path ,
203211 "config" ,
@@ -222,7 +230,7 @@ def ffx_cmd_env(self):
222230 }
223231
224232 def stop_ffx_isolation (self ):
225- subprocess .check_call (
233+ self .check_call (
226234 [
227235 self .tool_path ("ffx" ),
228236 "daemon" ,
@@ -265,7 +273,7 @@ def start(self):
265273 self .start_ffx_isolation ()
266274
267275 # Stop any running emulators (there shouldn't be any)
268- subprocess .check_call (
276+ self .check_call (
269277 [
270278 ffx_path ,
271279 "emu" ,
@@ -282,11 +290,11 @@ def start(self):
282290 product_name = "minimal." + self .triple_to_arch (self .target )
283291 fuchsia_version = "20.20240412.3.1"
284292
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 (
288294 [
289295 ffx_path ,
296+ "--machine" ,
297+ "json" ,
290298 "product" ,
291299 "lookup" ,
292300 product_name ,
@@ -300,16 +308,15 @@ def start(self):
300308
301309 self .log_debug (out )
302310
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 )
308315 raise Exception ("Unable to parse transfer manifest" )
309316
310317 # Download the product bundle.
311318 product_bundle_dir = os .path .join (self .tmp_dir (), 'product-bundle' )
312- subprocess .check_call (
319+ self .check_call (
313320 [
314321 ffx_path ,
315322 "product" ,
@@ -325,7 +332,7 @@ def start(self):
325332
326333 # Start emulator
327334 # FIXME: condition --accel hyper on target arch matching host arch
328- subprocess .check_call (
335+ self .check_call (
329336 [
330337 ffx_path ,
331338 "emu" ,
@@ -346,42 +353,52 @@ def start(self):
346353
347354 # Create new package repo
348355 self .log_info ("Creating package repo..." )
349- subprocess .check_call (
356+ self .check_call (
350357 [
351- self . tool_path ( "pm" ) ,
352- "newrepo " ,
353- "-repo " ,
358+ ffx_path ,
359+ "repository " ,
360+ "create " ,
354361 self .repo_dir (),
355362 ],
363+ env = ffx_env ,
356364 stdout = self .subprocess_output (),
357365 stderr = self .subprocess_output (),
358366 )
359367
360- # Add repo
361- subprocess .check_call (
368+ self .check_call (
362369 [
363370 ffx_path ,
364371 "repository" ,
365372 "add-from-pm" ,
366- self .repo_dir (),
367373 "--repository" ,
368374 self .TEST_REPO_NAME ,
375+ self .repo_dir (),
369376 ],
370377 env = ffx_env ,
371378 stdout = self .subprocess_output (),
372379 stderr = self .subprocess_output (),
373380 )
374381
382+ # Write to file
383+ self .write_to_file ()
384+
375385 # 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+ ],
378395 env = ffx_env ,
379396 stdout = self .subprocess_output (),
380397 stderr = self .subprocess_output (),
381398 )
382399
383400 # Register with newly-started emulator
384- subprocess .check_call (
401+ self .check_call (
385402 [
386403 ffx_path ,
387404 "target" ,
@@ -395,12 +412,6 @@ def start(self):
395412 stderr = self .subprocess_output (),
396413 )
397414
398- # Create lockfiles
399- open (self .pm_lockfile_path (), "a" ).close ()
400-
401- # Write to file
402- self .write_to_file ()
403-
404415 self .log_info ("Success! Your environment is ready to run tests." )
405416
406417 # FIXME: shardify this
@@ -445,7 +456,6 @@ def start(self):
445456 meta/{package_name}.cm={package_dir}/meta/{package_name}.cm
446457 bin/{exe_name}={bin_path}
447458 lib/{libstd_name}={libstd_path}
448- lib/{libtest_name}={libtest_path}
449459 lib/ld.so.1={sdk_dir}/arch/{target_arch}/sysroot/dist/lib/ld.so.1
450460 lib/libfdio.so={sdk_dir}/arch/{target_arch}/dist/libfdio.so
451461 """
@@ -482,9 +492,6 @@ def run(self, args):
482492 if not libstd_paths :
483493 raise Exception (f"Failed to locate libstd (in { self .rustlibs_dir ()} )" )
484494
485- if not libtest_paths :
486- raise Exception (f"Failed to locate libtest (in { self .rustlibs_dir ()} )" )
487-
488495 # Build a unique, deterministic name for the test using the name of the
489496 # binary and the last 6 hex digits of the hash of the full path
490497 def path_checksum (path ):
@@ -500,6 +507,7 @@ def path_checksum(path):
500507 cml_path = os .path .join (package_dir , "meta" , f"{ package_name } .cml" )
501508 cm_path = os .path .join (package_dir , "meta" , f"{ package_name } .cm" )
502509 manifest_path = os .path .join (package_dir , f"{ package_name } .manifest" )
510+ manifest_json_path = os .path .join (package_dir , f"package_manifest.json" )
503511 far_path = os .path .join (package_dir , f"{ package_name } -0.far" )
504512
505513 shared_libs = args .shared_libs [: args .n ]
@@ -523,22 +531,6 @@ def log(msg):
523531
524532 log (f"Bin path: { bin_path } " )
525533
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-
542534 log ("Writing CML..." )
543535
544536 # Write and compile CML
@@ -563,7 +555,7 @@ def log(msg):
563555
564556 log ("Compiling CML..." )
565557
566- subprocess .check_call (
558+ self .check_call (
567559 [
568560 self .tool_path ("cmc" ),
569561 "compile" ,
@@ -580,8 +572,8 @@ def log(msg):
580572 log ("Writing manifest..." )
581573
582574 # 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 (
585577 self .MANIFEST_TEMPLATE .format (
586578 bin_path = bin_path ,
587579 exe_name = exe_name ,
@@ -590,71 +582,87 @@ def log(msg):
590582 target = self .target ,
591583 sdk_dir = self .sdk_dir ,
592584 libstd_name = os .path .basename (libstd_paths [0 ]),
593- libtest_name = os .path .basename (libtest_paths [0 ]),
594585 libstd_path = libstd_paths [0 ],
595- libtest_path = libtest_paths [0 ],
596586 target_arch = self .triple_to_arch (self .target ),
597587 )
598588 )
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+ )
599595 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" ]
601610
602611 log ("Compiling and archiving manifest..." )
603612
604- subprocess .check_call (
613+ self .check_call (
605614 [
606- self .tool_path ("pm" ),
615+ self .tool_path ("ffx" ),
616+ "package" ,
617+ "build" ,
618+ manifest_path ,
607619 "-o" ,
608620 package_dir ,
609- "-m" ,
610- manifest_path ,
611- "build" ,
621+ "--api-level" ,
622+ str (api_level ),
612623 ],
624+ env = self .ffx_cmd_env (),
613625 stdout = log_file ,
614626 stderr = log_file ,
615627 )
616- subprocess .check_call (
628+
629+ self .check_call (
617630 [
618- self .tool_path ("pm" ),
619- "-o" ,
620- package_dir ,
621- "-m" ,
622- manifest_path ,
631+ self .tool_path ("ffx" ),
632+ "package" ,
623633 "archive" ,
634+ "create" ,
635+ "-o" ,
636+ far_path ,
637+ manifest_json_path ,
624638 ],
639+ env = self .ffx_cmd_env (),
625640 stdout = log_file ,
626641 stderr = log_file ,
627642 )
628643
629644 log ("Publishing package to repo..." )
630645
631646 # 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+ )
651659
652660 log ("Running ffx test..." )
653661
654662 # Run test on emulator
655663 subprocess .run (
656664 [
657- self . tool_path ( "ffx" ) ,
665+ ffx_path ,
658666 "test" ,
659667 "run" ,
660668 f"fuchsia-pkg://{ self .TEST_REPO_NAME } /{ package_name } #meta/{ package_name } .cm" ,
@@ -765,7 +773,7 @@ def stop(self):
765773
766774 # Shut down the emulator
767775 self .log_info ("Stopping emulator..." )
768- subprocess .check_call (
776+ self .check_call (
769777 [
770778 self .tool_path ("ffx" ),
771779 "emu" ,
0 commit comments