@@ -1984,7 +1984,8 @@ def tearDown(self):
19841984 test .support .reap_children ()
19851985
19861986 def _run_remote_exec_test (self , script_code , python_args = None , env = None ,
1987- prologue = '' , after_ready = None ,
1987+ python_executable = None , prologue = '' ,
1988+ after_ready = None ,
19881989 script_path = os_helper .TESTFN + '_remote.py' ):
19891990 # Create the script that will be remotely executed
19901991 self .addCleanup (os_helper .unlink , script_path )
@@ -2032,7 +2033,10 @@ def _run_remote_exec_test(self, script_code, python_args=None, env=None,
20322033''' )
20332034
20342035 # Start the target process and capture its output
2035- cmd = [sys .executable ]
2036+ if python_executable is None :
2037+ python_executable = sys .executable
2038+
2039+ cmd = [python_executable ]
20362040 if python_args :
20372041 cmd .extend (python_args )
20382042 cmd .append (target )
@@ -2248,6 +2252,55 @@ def delete_loaded_libpython(proc):
22482252 self .assertIn (b"Remote script executed successfully!" , stdout )
22492253 self .assertEqual (stderr , b"" )
22502254
2255+ @unittest .skipUnless (sys .platform == 'linux' , 'Linux-only regression test' )
2256+ @unittest .skipUnless (
2257+ sysconfig .get_config_var ('Py_ENABLE_SHARED' ) == 0 ,
2258+ 'requires a static Python build' )
2259+ def test_remote_exec_deleted_static_executable (self ):
2260+ """Test remote exec when the target static executable was deleted."""
2261+ build_dir = sysconfig .get_config_var ('abs_builddir' )
2262+ srcdir = sysconfig .get_config_var ('srcdir' )
2263+ if not build_dir or not srcdir :
2264+ self .skipTest ('cannot determine build-tree locations' )
2265+
2266+ pybuilddir_txt = os .path .join (build_dir , 'pybuilddir.txt' )
2267+ if not os .path .exists (pybuilddir_txt ):
2268+ self .skipTest (f'{ pybuilddir_txt !r} does not exist' )
2269+
2270+ with open (pybuilddir_txt , encoding = 'utf-8' ) as pybuilddir_file :
2271+ pybuilddir = pybuilddir_file .read ().strip ()
2272+ source_ext_dir = os .path .join (build_dir , pybuilddir )
2273+ if not os .path .isdir (source_ext_dir ):
2274+ self .skipTest (f'{ source_ext_dir !r} does not exist' )
2275+
2276+ with os_helper .temp_dir () as copied_root :
2277+ copied_build_dir = os .path .join (copied_root , 'build' )
2278+ copied_pybuilddir = os .path .join (copied_build_dir , pybuilddir )
2279+ os .makedirs (os .path .dirname (copied_pybuilddir ))
2280+ os .symlink (os .path .join (srcdir , 'Lib' ),
2281+ os .path .join (copied_root , 'Lib' ))
2282+ os .symlink (source_ext_dir , copied_pybuilddir )
2283+ shutil .copy2 (pybuilddir_txt ,
2284+ os .path .join (copied_build_dir , 'pybuilddir.txt' ))
2285+
2286+ copied_python = os .path .join (copied_build_dir ,
2287+ os .path .basename (sys .executable ))
2288+ shutil .copy2 (sys .executable , copied_python )
2289+
2290+ def delete_loaded_executable (proc ):
2291+ os_helper .unlink (copied_python )
2292+ with open (f'/proc/{ proc .pid } /maps' , encoding = 'utf-8' ) as maps :
2293+ self .assertIn (f'{ copied_python } (deleted)' ,
2294+ maps .read ())
2295+
2296+ script = 'print("Remote script executed successfully!")'
2297+ returncode , stdout , stderr = self ._run_remote_exec_test (
2298+ script , python_args = ['-S' ], python_executable = copied_python ,
2299+ after_ready = delete_loaded_executable )
2300+ self .assertEqual (returncode , 0 )
2301+ self .assertIn (b"Remote script executed successfully!" , stdout )
2302+ self .assertEqual (stderr , b"" )
2303+
22512304 def test_remote_exec_in_process_without_debug_fails_envvar (self ):
22522305 """Test remote exec in a process without remote debugging enabled"""
22532306 script = os_helper .TESTFN + '_remote.py'
0 commit comments