@@ -308,7 +308,9 @@ def send_get(what):
308308
309309    else :
310310        # run via pyboard interface 
311-         had_crash , output_mupy  =  run_script_on_remote_target (pyb , args , test_file , is_special )
311+         had_crash , output_mupy  =  pyb .run_script_on_remote_target (
312+             args , test_file_abspath , is_special 
313+         )
312314
313315    # canonical form for all ports/platforms is to use \n for end-of-line 
314316    output_mupy  =  output_mupy .replace (b"\r \n " , b"\n " )
@@ -393,6 +395,51 @@ def value(self):
393395        return  self ._value 
394396
395397
398+ class  PyboardNodeRunner :
399+     def  __init__ (self ):
400+         mjs  =  os .getenv ("MICROPY_MICROPYTHON_MJS" )
401+         if  mjs  is  None :
402+             mjs  =  base_path ("../ports/webassembly/build-standard/micropython.mjs" )
403+         else :
404+             mjs  =  os .path .abspath (mjs )
405+         self .micropython_mjs  =  mjs 
406+ 
407+     def  close (self ):
408+         pass 
409+ 
410+     def  run_script_on_remote_target (self , args , test_file , is_special ):
411+         cwd  =  os .path .dirname (test_file )
412+ 
413+         # Create system command list. 
414+         cmdlist  =  ["node" ]
415+         if  test_file .endswith (".py" ):
416+             # Run a Python script indirectly via "node micropython.mjs <script.py>". 
417+             cmdlist .append (self .micropython_mjs )
418+             if  args .heapsize  is  not None :
419+                 cmdlist .extend (["-X" , "heapsize="  +  args .heapsize ])
420+             cmdlist .append (test_file )
421+         else :
422+             # Run a js/mjs script directly with Node, passing in the path to micropython.mjs. 
423+             cmdlist .append (test_file )
424+             cmdlist .append (self .micropython_mjs )
425+ 
426+         # Run the script. 
427+         try :
428+             had_crash  =  False 
429+             output_mupy  =  subprocess .check_output (
430+                 cmdlist , stderr = subprocess .STDOUT , timeout = TEST_TIMEOUT , cwd = cwd 
431+             )
432+         except  subprocess .CalledProcessError  as  er :
433+             had_crash  =  True 
434+             output_mupy  =  er .output  +  b"CRASH" 
435+         except  subprocess .TimeoutExpired  as  er :
436+             had_crash  =  True 
437+             output_mupy  =  (er .output  or  b"" ) +  b"TIMEOUT" 
438+ 
439+         # Return the results. 
440+         return  had_crash , output_mupy 
441+ 
442+ 
396443def  run_tests (pyb , tests , args , result_dir , num_threads = 1 ):
397444    test_count  =  ThreadSafeCounter ()
398445    testcase_count  =  ThreadSafeCounter ()
@@ -631,6 +678,20 @@ def run_tests(pyb, tests, args, result_dir, num_threads=1):
631678            )  # RA fsp rtc function doesn't support nano sec info 
632679        elif  args .target  ==  "qemu-arm" :
633680            skip_tests .add ("misc/print_exception.py" )  # requires sys stdfiles 
681+         elif  args .target  ==  "webassembly" :
682+             skip_tests .add ("basics/string_format_modulo.py" )  # can't print nulls to stdout 
683+             skip_tests .add ("basics/string_strip.py" )  # can't print nulls to stdout 
684+             skip_tests .add ("extmod/binascii_a2b_base64.py" )
685+             skip_tests .add ("extmod/re_stack_overflow.py" )
686+             skip_tests .add ("extmod/time_res.py" )
687+             skip_tests .add ("extmod/vfs_posix.py" )
688+             skip_tests .add ("extmod/vfs_posix_enoent.py" )
689+             skip_tests .add ("extmod/vfs_posix_paths.py" )
690+             skip_tests .add ("extmod/vfs_userfs.py" )
691+             skip_tests .add ("micropython/emg_exc.py" )
692+             skip_tests .add ("micropython/extreme_exc.py" )
693+             skip_tests .add ("micropython/heapalloc_exc_compressed_emg_exc.py" )
694+             skip_tests .add ("micropython/import_mpy_invalid.py" )
634695
635696    # Some tests are known to fail on 64-bit machines 
636697    if  pyb  is  None  and  platform .architecture ()[0 ] ==  "64bit" :
@@ -977,6 +1038,7 @@ def main():
9771038    LOCAL_TARGETS  =  (
9781039        "unix" ,
9791040        "qemu-arm" ,
1041+         "webassembly" ,
9801042    )
9811043    EXTERNAL_TARGETS  =  (
9821044        "pyboard" ,
@@ -997,6 +1059,8 @@ def main():
9971059                args .mpy_cross_flags  =  "-march=host" 
9981060            elif  args .target  ==  "qemu-arm" :
9991061                args .mpy_cross_flags  =  "-march=armv7m" 
1062+         if  args .target  ==  "webassembly" :
1063+             pyb  =  PyboardNodeRunner ()
10001064    elif  args .target  in  EXTERNAL_TARGETS :
10011065        global  pyboard 
10021066        sys .path .append (base_path ("../tools" ))
@@ -1015,6 +1079,7 @@ def main():
10151079                args .mpy_cross_flags  =  "-march=armv7m" 
10161080
10171081        pyb  =  pyboard .Pyboard (args .device , args .baudrate , args .user , args .password )
1082+         pyboard .Pyboard .run_script_on_remote_target  =  run_script_on_remote_target 
10181083        pyb .enter_raw_repl ()
10191084    else :
10201085        raise  ValueError ("target must be one of %s"  %  ", " .join (LOCAL_TARGETS  +  EXTERNAL_TARGETS ))
@@ -1032,6 +1097,10 @@ def main():
10321097        else :
10331098            tests  =  []
10341099    elif  len (args .files ) ==  0 :
1100+         test_extensions  =  ("*.py" ,)
1101+         if  args .target  ==  "webassembly" :
1102+             test_extensions  +=  ("*.js" , "*.mjs" )
1103+ 
10351104        if  args .test_dirs  is  None :
10361105            test_dirs  =  (
10371106                "basics" ,
@@ -1072,12 +1141,16 @@ def main():
10721141                    "inlineasm" ,
10731142                    "ports/qemu-arm" ,
10741143                )
1144+             elif  args .target  ==  "webassembly" :
1145+                 test_dirs  +=  ("float" ,)
10751146        else :
10761147            # run tests from these directories 
10771148            test_dirs  =  args .test_dirs 
10781149        tests  =  sorted (
10791150            test_file 
1080-             for  test_files  in  (glob ("{}/*.py" .format (dir )) for  dir  in  test_dirs )
1151+             for  test_files  in  (
1152+                 glob (os .path .join (dir , ext )) for  dir  in  test_dirs  for  ext  in  test_extensions 
1153+             )
10811154            for  test_file  in  test_files 
10821155        )
10831156    else :
0 commit comments