go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/cipd/client/testing/update_running_exe_test.py (about) 1 #!/usr/bin/env python 2 # Copyright 2016 The LUCI Authors. All rights reserved. 3 # Use of this source code is governed under the Apache License, Version 2.0 4 # that can be found in the LICENSE file. 5 6 """Adhoc test to verify cipd can replace running executables on Windows. 7 8 Assumes active Go environment. Will rebuild cipd client before executing 9 the test. 10 11 Meant to be run manually. 12 """ 13 14 import contextlib 15 import os 16 import shutil 17 import subprocess 18 import tempfile 19 20 21 TESTING_DIR = os.path.dirname(os.path.abspath(__file__)) 22 TEMP_DIR = os.path.join(TESTING_DIR, '.tmp_dir') 23 24 25 SLEEPER_GO=r""" 26 package main 27 28 import "time" 29 30 func main() { 31 time.Sleep(30 * time.Second) 32 } 33 """ 34 35 36 @contextlib.contextmanager 37 def temp_dir(work_dir): 38 tmp = tempfile.mkdtemp(dir=work_dir) 39 try: 40 yield tmp 41 finally: 42 shutil.rmtree(tmp) 43 44 45 def build_sleeper(work_dir, out): 46 with temp_dir(work_dir) as tmp: 47 with open(os.path.join(tmp, 'main.go'), 'wt') as f: 48 f.write(SLEEPER_GO) 49 subprocess.check_call(['go', 'build', '-o', out, '.'], cwd=tmp) 50 51 52 def build_cipd(out): 53 subprocess.check_call([ 54 'go', 'build', 55 '-o', out, 56 'go.chromium.org/luci/cipd/client/cmd/cipd', 57 ]) 58 59 60 def list_dir(path): 61 print 'File tree:' 62 for root, subdirs, files in os.walk(path): 63 for p in subdirs: 64 print 'D ' + os.path.join(root, p)[len(path)+1:] 65 for p in files: 66 print 'F ' + os.path.join(root, p)[len(path)+1:] 67 68 69 def main(): 70 if not os.path.exists(TEMP_DIR): 71 os.mkdir(TEMP_DIR) 72 73 print 'Building CIPD client' 74 cipd_exe = os.path.join(TEMP_DIR, 'cipd.exe') 75 build_cipd(cipd_exe) 76 77 print 'Building test executable' 78 sleeper_exe = os.path.join(TEMP_DIR, 'sleeper.exe') 79 build_sleeper(TEMP_DIR, sleeper_exe) 80 81 sleeper_cipd = os.path.join(TEMP_DIR, 'sleeper.cipd') 82 with temp_dir(TEMP_DIR) as tmp: 83 tmp_sleeper_exe = os.path.join(tmp, 'sleeper.exe') 84 85 print 'Packaging the test executable into a cipd package' 86 shutil.copy(sleeper_exe, tmp_sleeper_exe) 87 subprocess.check_call([ 88 cipd_exe, 'pkg-build', 89 '-in', tmp, 90 '-name', 'adhoc-testing', 91 '-out', sleeper_cipd, 92 ]) 93 94 print 'Starting the test executable and attempt to update it by cipd' 95 print 'Exe: %s' % tmp_sleeper_exe 96 sleeper_proc = subprocess.Popen([tmp_sleeper_exe]) 97 try: 98 subprocess.check_call([ 99 cipd_exe, 'pkg-deploy', 100 '-root', tmp, 101 sleeper_cipd, 102 ]) 103 # This shows that exe is updated, and the old exe (still running) is now 104 # in trash (<root>/.cipd/trash/). 105 list_dir(tmp) 106 finally: 107 sleeper_proc.terminate() 108 sleeper_proc.wait() 109 110 # Do it again. This time it should remove all the trash. 111 subprocess.check_call([ 112 cipd_exe, 'pkg-deploy', 113 '-root', tmp, 114 sleeper_cipd, 115 ]) 116 # This shows that the trash directory is empty now. 117 list_dir(tmp) 118 119 120 if __name__ == '__main__': 121 main()