client.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  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 pytest
  28. import json
  29. import logging
  30. import os
  31. import re
  32. import shutil
  33. import subprocess
  34. from datetime import timedelta, datetime
  35. from typing import List, Optional, Dict, Union
  36. from urllib.parse import urlparse
  37. from . import ExecResult
  38. from .env import Env
  39. log = logging.getLogger(__name__)
  40. class LocalClient:
  41. def __init__(self, name: str, env: Env, run_dir: Optional[str] = None,
  42. timeout: Optional[float] = None,
  43. run_env: Optional[Dict[str,str]] = None):
  44. self.name = name
  45. self.path = os.path.join(env.project_dir, f'tests/http/clients/{name}')
  46. self.env = env
  47. self._run_env= run_env
  48. self._timeout = timeout if timeout else env.test_timeout
  49. self._curl = os.environ['CURL'] if 'CURL' in os.environ else env.curl
  50. self._run_dir = run_dir if run_dir else os.path.join(env.gen_dir, name)
  51. self._stdoutfile = f'{self._run_dir}/stdout'
  52. self._stderrfile = f'{self._run_dir}/stderr'
  53. self._rmrf(self._run_dir)
  54. self._mkpath(self._run_dir)
  55. @property
  56. def run_dir(self) -> str:
  57. return self._run_dir
  58. @property
  59. def stderr_file(self) -> str:
  60. return self._stderrfile
  61. def exists(self) -> bool:
  62. return os.path.exists(self.path)
  63. def download_file(self, i: int) -> str:
  64. return os.path.join(self._run_dir, f'download_{i}.data')
  65. def _rmf(self, path):
  66. if os.path.exists(path):
  67. return os.remove(path)
  68. def _rmrf(self, path):
  69. if os.path.exists(path):
  70. return shutil.rmtree(path)
  71. def _mkpath(self, path):
  72. if not os.path.exists(path):
  73. return os.makedirs(path)
  74. def run(self, args):
  75. self._rmf(self._stdoutfile)
  76. self._rmf(self._stderrfile)
  77. start = datetime.now()
  78. exception = None
  79. myargs = [self.path]
  80. myargs.extend(args)
  81. try:
  82. with open(self._stdoutfile, 'w') as cout:
  83. with open(self._stderrfile, 'w') as cerr:
  84. p = subprocess.run(myargs, stderr=cerr, stdout=cout,
  85. cwd=self._run_dir, shell=False,
  86. input=None, env=self._run_env,
  87. timeout=self._timeout)
  88. exitcode = p.returncode
  89. except subprocess.TimeoutExpired:
  90. log.warning(f'Timeout after {self._timeout}s: {args}')
  91. exitcode = -1
  92. exception = 'TimeoutExpired'
  93. coutput = open(self._stdoutfile).readlines()
  94. cerrput = open(self._stderrfile).readlines()
  95. return ExecResult(args=myargs, exit_code=exitcode, exception=exception,
  96. stdout=coutput, stderr=cerrput,
  97. duration=datetime.now() - start)
  98. def dump_logs(self):
  99. lines = []
  100. lines.append('>>--stdout ----------------------------------------------\n')
  101. lines.extend(open(self._stdoutfile).readlines())
  102. lines.append('>>--stderr ----------------------------------------------\n')
  103. lines.extend(open(self._stderrfile).readlines())
  104. lines.append('<<-------------------------------------------------------\n')
  105. return ''.join(lines)