2525
2626@dataclass  
2727class  TestEnvironment :
28-  rust_dir : str 
28+  rust_build_dir : str 
2929 sdk_dir : str 
3030 target : str 
31-  package_server_pid : Optional [int ] =  None 
32-  emu_addr : Optional [str ] =  None 
33-  libstd_name : Optional [str ] =  None 
34-  libtest_name : Optional [str ] =  None 
3531 verbose : bool  =  False 
3632
3733 @staticmethod  
@@ -57,7 +53,7 @@ def env_file_path(cls):
5753 @classmethod  
5854 def  from_args (cls , args ):
5955 return  cls (
60-  os .path .abspath (args .rust ),
56+  os .path .abspath (args .rust_build ),
6157 os .path .abspath (args .sdk ),
6258 args .target ,
6359 verbose = args .verbose ,
@@ -68,32 +64,16 @@ def read_from_file(cls):
6864 with  open (cls .env_file_path (), encoding = "utf-8" ) as  f :
6965 test_env  =  json .loads (f .read ())
7066 return  cls (
71-  test_env ["rust_dir " ],
67+  test_env ["rust_build_dir " ],
7268 test_env ["sdk_dir" ],
7369 test_env ["target" ],
74-  libstd_name = test_env ["libstd_name" ],
75-  libtest_name = test_env ["libtest_name" ],
76-  emu_addr = test_env ["emu_addr" ],
77-  package_server_pid = test_env ["package_server_pid" ],
7870 verbose = test_env ["verbose" ],
7971 )
8072
8173 def  write_to_file (self ):
8274 with  open (self .env_file_path (), "w" , encoding = "utf-8" ) as  f :
8375 f .write (json .dumps (self .__dict__ ))
8476
85-  def  ssh_dir (self ):
86-  return  os .path .join (self .tmp_dir (), "ssh" )
87- 
88-  def  ssh_keyfile_path (self ):
89-  return  os .path .join (self .ssh_dir (), "fuchsia_ed25519" )
90- 
91-  def  ssh_authfile_path (self ):
92-  return  os .path .join (self .ssh_dir (), "fuchsia_authorized_keys" )
93- 
94-  def  vdl_output_path (self ):
95-  return  os .path .join (self .tmp_dir (), "vdl_output" )
96- 
9777 def  package_server_log_path (self ):
9878 return  os .path .join (self .tmp_dir (), "package_server_log" )
9979
@@ -113,7 +93,9 @@ def repo_dir(self):
11393
11494 def  libs_dir (self ):
11595 return  os .path .join (
116-  self .rust_dir ,
96+  self .rust_build_dir ,
97+  "host" ,
98+  "stage2" ,
11799 "lib" ,
118100 )
119101
@@ -212,21 +194,19 @@ def start_ffx_isolation(self):
212194 # Set configs 
213195 configs  =  {
214196 "log.enabled" : "true" ,
215-  "ssh.pub" : self .ssh_authfile_path (),
216-  "ssh.priv" : self .ssh_keyfile_path (),
217197 "test.is_isolated" : "true" ,
218198 "test.experimental_structured_output" : "true" ,
219199 }
220200 for  key , value  in  configs .items ():
221201 subprocess .check_call (
222202 [
223-  self . tool_path ( "ffx" ) ,
203+  ffx_path ,
224204 "config" ,
225205 "set" ,
226206 key ,
227207 value ,
228208 ],
229-  env = self . ffx_cmd_env () ,
209+  env = ffx_env ,
230210 stdout = self .subprocess_output (),
231211 stderr = self .subprocess_output (),
232212 )
@@ -248,6 +228,7 @@ def stop_ffx_isolation(self):
248228 self .tool_path ("ffx" ),
249229 "daemon" ,
250230 "stop" ,
231+  "-w" ,
251232 ],
252233 env = self .ffx_cmd_env (),
253234 stdout = self .subprocess_output (),
@@ -275,87 +256,62 @@ def start(self):
275256 elif  len (os .listdir (self .tmp_dir ())) !=  0 :
276257 raise  Exception (f"Temp directory is not clean (in { self .tmp_dir ()}  )
277258
278-  os .mkdir (self .ssh_dir ())
279259 os .mkdir (self .output_dir ())
280260
281-  # Find libstd and libtest 
282-  libstd_paths  =  glob .glob (os .path .join (self .rustlibs_dir (), "libstd-*.so" ))
283-  libtest_paths  =  glob .glob (os .path .join (self .rustlibs_dir (), "libtest-*.so" ))
284- 
285-  if  not  libstd_paths :
286-  raise  Exception (f"Failed to locate libstd (in { self .rustlibs_dir ()}  )
287- 
288-  if  not  libtest_paths :
289-  raise  Exception (f"Failed to locate libtest (in { self .rustlibs_dir ()}  )
261+  ffx_path  =  self .tool_path ("ffx" )
262+  ffx_env  =  self .ffx_cmd_env ()
290263
291-  self .libstd_name  =  os .path .basename (libstd_paths [0 ])
292-  self .libtest_name  =  os .path .basename (libtest_paths [0 ])
264+  # Start ffx isolation 
265+  self .log_info ("Starting ffx isolation..." )
266+  self .start_ffx_isolation ()
293267
294-  # Generate SSH keys for the emulator to use 
295-  self .log_info ("Generating SSH keys..." )
268+  # Stop any running emulators (there shouldn't be any) 
296269 subprocess .check_call (
297270 [
298-  "ssh-keygen" ,
299-  "-N" ,
300-  "" ,
301-  "-t" ,
302-  "ed25519" ,
303-  "-f" ,
304-  self .ssh_keyfile_path (),
305-  "-C" ,
306-  "Generated by fuchsia-test-runner.py" ,
271+  ffx_path ,
272+  "emu" ,
273+  "stop" ,
274+  "--all" ,
307275 ],
276+  env = ffx_env ,
308277 stdout = self .subprocess_output (),
309278 stderr = self .subprocess_output (),
310279 )
311-  authfile_contents  =  subprocess .check_output (
280+ 
281+  # Start emulator 
282+  self .log_info ("Starting emulator..." )
283+  product_bundle  =  "terminal.qemu-"  +  self .triple_to_arch (self .target )
284+  subprocess .check_call (
312285 [
313-  "ssh-keygen" ,
314-  "-y " ,
315-  "-f " ,
316-  self . ssh_keyfile_path () ,
286+  ffx_path ,
287+  "product-bundle " ,
288+  "get " ,
289+  product_bundle ,
317290 ],
291+  env = ffx_env ,
292+  stdout = self .subprocess_output (),
318293 stderr = self .subprocess_output (),
319294 )
320-  with  open (self .ssh_authfile_path (), "wb" ) as  authfile :
321-  authfile .write (authfile_contents )
322- 
323-  # Start ffx isolation 
324-  self .log_info ("Starting ffx isolation..." )
325-  self .start_ffx_isolation ()
326- 
327-  # Start emulator (this will generate the vdl output) 
328-  self .log_info ("Starting emulator..." )
295+  # FIXME: condition --accel hyper on target arch matching host arch 
329296 subprocess .check_call (
330297 [
331-  self . tool_path ( "fvdl" ) ,
332-  "--sdk " ,
298+  ffx_path ,
299+  "emu " ,
333300 "start" ,
334-  "--tuntap" ,
301+  product_bundle ,
335302 "--headless" ,
336-  "--nointeractive" ,
337-  "--ssh" ,
338-  self .ssh_dir (),
339-  "--vdl-output" ,
340-  self .vdl_output_path (),
341-  "--emulator-log" ,
303+  "--log" ,
342304 self .emulator_log_path (),
343-  "--image-name" ,
344-  "qemu-"  +  self .triple_to_arch (self .target ),
305+  "--net" ,
306+  "tap" ,
307+  "--accel" ,
308+  "hyper" ,
345309 ],
310+  env = ffx_env ,
346311 stdout = self .subprocess_output (),
347312 stderr = self .subprocess_output (),
348313 )
349314
350-  # Parse vdl output for relevant information 
351-  with  open (self .vdl_output_path (), encoding = "utf-8" ) as  f :
352-  vdl_content  =  f .read ()
353-  matches  =  re .search (
354-  r'network_address:\s+"\[([0-9a-f]{1,4}:(:[0-9a-f]{1,4}){4}%qemu)\]"' ,
355-  vdl_content ,
356-  )
357-  self .emu_addr  =  matches .group (1 )
358- 
359315 # Create new package repo 
360316 self .log_info ("Creating package repo..." )
361317 subprocess .check_call (
@@ -369,55 +325,40 @@ def start(self):
369325 stderr = self .subprocess_output (),
370326 )
371327
372-  # Start package server 
373-  self .log_info ("Starting package server..." )
374-  with  open (
375-  self .package_server_log_path (), "w" , encoding = "utf-8" 
376-  ) as  package_server_log :
377-  # We want this to be a long-running process that persists after the script finishes 
378-  # pylint: disable=consider-using-with 
379-  self .package_server_pid  =  subprocess .Popen (
380-  [
381-  self .tool_path ("pm" ),
382-  "serve" ,
383-  "-vt" ,
384-  "-repo" ,
385-  self .repo_dir (),
386-  "-l" ,
387-  ":8084" ,
388-  ],
389-  stdout = package_server_log ,
390-  stderr = package_server_log ,
391-  ).pid 
392- 
393-  # Register package server with emulator 
394-  self .log_info ("Registering package server..." )
395-  ssh_client  =  subprocess .check_output (
328+  # Add repo 
329+  subprocess .check_call (
396330 [
397-  "ssh" ,
398-  "-i" ,
399-  self .ssh_keyfile_path (),
400-  "-o" ,
401-  "StrictHostKeyChecking=accept-new" ,
402-  self .emu_addr ,
403-  "-f" ,
404-  "echo $SSH_CLIENT" ,
331+  ffx_path ,
332+  "repository" ,
333+  "add-from-pm" ,
334+  self .repo_dir (),
335+  "--repository" ,
336+  self .TEST_REPO_NAME ,
405337 ],
406-  text = True ,
338+  env = ffx_env ,
339+  stdout = self .subprocess_output (),
340+  stderr = self .subprocess_output (),
407341 )
408-  repo_addr  =  ssh_client .split ()[0 ].replace ("%" , "%25" )
409-  repo_url  =  f"http://[{ repo_addr }  
342+ 
343+  # Start repository server 
344+  subprocess .check_call (
345+  [ffx_path , "repository" , "server" , "start" , "--address" , "[::]:0" ],
346+  env = ffx_env ,
347+  stdout = self .subprocess_output (),
348+  stderr = self .subprocess_output (),
349+  )
350+ 
351+  # Register with newly-started emulator 
410352 subprocess .check_call (
411353 [
412-  "ssh" ,
413-  "-i" ,
414-  self .ssh_keyfile_path (),
415-  "-o" ,
416-  "StrictHostKeyChecking=accept-new" ,
417-  self .emu_addr ,
418-  "-f" ,
419-  f"pkgctl repo add url -f 1 -n { self .TEST_REPO_NAME } { repo_url }  ,
354+  ffx_path ,
355+  "target" ,
356+  "repository" ,
357+  "register" ,
358+  "--repository" ,
359+  self .TEST_REPO_NAME ,
420360 ],
361+  env = ffx_env ,
421362 stdout = self .subprocess_output (),
422363 stderr = self .subprocess_output (),
423364 )
@@ -471,8 +412,8 @@ def start(self):
471412 meta/package={package_dir}/meta/package 
472413 meta/{package_name}.cm={package_dir}/meta/{package_name}.cm 
473414 bin/{exe_name}={bin_path} 
474-  lib/{libstd_name}={rust_dir}/lib/rustlib/{rustlib_dir}/lib/{libstd_name } 
475-  lib/{libtest_name}={rust_dir}/lib/rustlib/{rustlib_dir}/lib/{libtest_name } 
415+  lib/{libstd_name}={libstd_path } 
416+  lib/{libtest_name}={libtest_path } 
476417 lib/ld.so.1={sdk_dir}/arch/{target_arch}/sysroot/dist/lib/ld.so.1 
477418 lib/libfdio.so={sdk_dir}/arch/{target_arch}/dist/libfdio.so 
478419 """ 
@@ -502,6 +443,16 @@ def run(self, args):
502443
503444 bin_path  =  os .path .abspath (args .bin_path )
504445
446+  # Find libstd and libtest 
447+  libstd_paths  =  glob .glob (os .path .join (self .rustlibs_dir (), "libstd-*.so" ))
448+  libtest_paths  =  glob .glob (os .path .join (self .rustlibs_dir (), "libtest-*.so" ))
449+ 
450+  if  not  libstd_paths :
451+  raise  Exception (f"Failed to locate libstd (in { self .rustlibs_dir ()}  )
452+ 
453+  if  not  libtest_paths :
454+  raise  Exception (f"Failed to locate libtest (in { self .rustlibs_dir ()}  )
455+ 
505456 # Build a unique, deterministic name for the test using the name of the 
506457 # binary and the last 6 hex digits of the hash of the full path 
507458 def  path_checksum (path ):
@@ -604,11 +555,12 @@ def log(msg):
604555 exe_name = exe_name ,
605556 package_dir = package_dir ,
606557 package_name = package_name ,
607-  rust_dir = self .rust_dir ,
608-  rustlib_dir = self .target ,
558+  target = self .target ,
609559 sdk_dir = self .sdk_dir ,
610-  libstd_name = self .libstd_name ,
611-  libtest_name = self .libtest_name ,
560+  libstd_name = os .path .basename (libstd_paths [0 ]),
561+  libtest_name = os .path .basename (libtest_paths [0 ]),
562+  libstd_path = libstd_paths [0 ],
563+  libtest_path = libtest_paths [0 ],
612564 target_arch = self .triple_to_arch (self .target ),
613565 )
614566 )
@@ -779,20 +731,15 @@ def stop(self):
779731 else :
780732 self .log_debug ("No ffx daemon log found" )
781733
782-  # Stop package server 
783-  self .log_info ("Stopping package server..." )
784-  os .kill (self .package_server_pid , signal .SIGTERM )
785- 
786734 # Shut down the emulator 
787735 self .log_info ("Stopping emulator..." )
788736 subprocess .check_call (
789737 [
790-  self .tool_path ("fvdl" ),
791-  "--sdk" ,
792-  "kill" ,
793-  "--launched-proto" ,
794-  self .vdl_output_path (),
738+  self .tool_path ("ffx" ),
739+  "emu" ,
740+  "stop" ,
795741 ],
742+  env = self .ffx_cmd_env (),
796743 stdout = self .subprocess_output (),
797744 stderr = self .subprocess_output (),
798745 )
@@ -969,8 +916,8 @@ def print_help(args):
969916 "start" , help = "initializes the testing environment" 
970917 )
971918 start_parser .add_argument (
972-  "--rust" ,
973-  help = "the directory of the installed Rust compiler for Fuchsia " ,
919+  "--rust-build " ,
920+  help = "the current compiler build directory (`$RUST_SRC/build` by default) " ,
974921 required = True ,
975922 )
976923 start_parser .add_argument (
0 commit comments