client.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. #***************************************************************************
  4. # _ _ ____ _
  5. # Project ___| | | | _ \| |
  6. # / __| | | | |_) | |
  7. # | (__| |_| | _ <| |___
  8. # \___|\___/|_| \_\_____|
  9. #
  10. # Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
  11. #
  12. # This software is licensed as described in the file COPYING, which
  13. # you should have received as part of this distribution. The terms
  14. # are also available at https://curl.se/docs/copyright.html.
  15. #
  16. # You may opt to use, copy, modify, merge, publish, distribute and/or sell
  17. # copies of the Software, and permit persons to whom the Software is
  18. # furnished to do so, under the terms of the COPYING file.
  19. #
  20. # This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
  21. # KIND, either express or implied.
  22. #
  23. # SPDX-License-Identifier: curl
  24. #
  25. ###########################################################################
  26. #
  27. import logging
  28. import os
  29. import shutil
  30. import subprocess
  31. from datetime import datetime
  32. from typing import Optional, Dict
  33. from . import ExecResult
  34. from .env import Env
  35. log = logging.getLogger(__name__)
  36. class LocalClient:
  37. def __init__(self, name: str, env: Env, run_dir: Optional[str] = None,
  38. timeout: Optional[float] = None,
  39. run_env: Optional[Dict[str,str]] = None):
  40. self.name = name
  41. self.path = os.path.join(env.build_dir, f'tests/http/clients/{name}')
  42. self.env = env
  43. self._run_env = run_env
  44. self._timeout = timeout if timeout else env.test_timeout
  45. self._curl = os.environ['CURL'] if 'CURL' in os.environ else env.curl
  46. self._run_dir = run_dir if run_dir else os.path.join(env.gen_dir, name)
  47. self._stdoutfile = f'{self._run_dir}/stdout'
  48. self._stderrfile = f'{self._run_dir}/stderr'
  49. self._rmrf(self._run_dir)
  50. self._mkpath(self._run_dir)
  51. @property
  52. def run_dir(self) -> str:
  53. return self._run_dir
  54. @property
  55. def stderr_file(self) -> str:
  56. return self._stderrfile
  57. def exists(self) -> bool:
  58. return os.path.exists(self.path)
  59. def download_file(self, i: int) -> str:
  60. return os.path.join(self._run_dir, f'download_{i}.data')
  61. def _rmf(self, path):
  62. if os.path.exists(path):
  63. return os.remove(path)
  64. def _rmrf(self, path):
  65. if os.path.exists(path):
  66. return shutil.rmtree(path)
  67. def _mkpath(self, path):
  68. if not os.path.exists(path):
  69. return os.makedirs(path)
  70. def run(self, args):
  71. self._rmf(self._stdoutfile)
  72. self._rmf(self._stderrfile)
  73. start = datetime.now()
  74. exception = None
  75. myargs = [self.path]
  76. myargs.extend(args)
  77. run_env = None
  78. if self._run_env:
  79. run_env = self._run_env.copy()
  80. for key in ['CURL_DEBUG']:
  81. if key in os.environ and key not in run_env:
  82. run_env[key] = os.environ[key]
  83. try:
  84. with open(self._stdoutfile, 'w') as cout, open(self._stderrfile, 'w') as cerr:
  85. p = subprocess.run(myargs, stderr=cerr, stdout=cout,
  86. cwd=self._run_dir, shell=False,
  87. input=None, env=run_env,
  88. timeout=self._timeout)
  89. exitcode = p.returncode
  90. except subprocess.TimeoutExpired:
  91. log.warning(f'Timeout after {self._timeout}s: {args}')
  92. exitcode = -1
  93. exception = 'TimeoutExpired'
  94. coutput = open(self._stdoutfile).readlines()
  95. cerrput = open(self._stderrfile).readlines()
  96. return ExecResult(args=myargs, exit_code=exitcode, exception=exception,
  97. stdout=coutput, stderr=cerrput,
  98. duration=datetime.now() - start)
  99. def dump_logs(self):
  100. lines = []
  101. lines.append('>>--stdout ----------------------------------------------\n')
  102. lines.extend(open(self._stdoutfile).readlines())
  103. lines.append('>>--stderr ----------------------------------------------\n')
  104. lines.extend(open(self._stderrfile).readlines())
  105. lines.append('<<-------------------------------------------------------\n')
  106. return ''.join(lines)