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()