Lines Matching refs:self
62 def __init__(self, pid: int, started_at: datetime, run_dir):
63 self._pid = pid
64 self._started_at = started_at
65 self._duration = timedelta(seconds=0)
66 self._run_dir = run_dir
67 self._samples = []
68 self._psu = None
69 self._stats = None
72 def duration(self) -> timedelta:
73 return self._duration
76 def stats(self) -> Optional[Dict[str,Any]]:
77 return self._stats
79 def sample(self):
80 elapsed = datetime.now() - self._started_at
82 if self._psu is None:
83 self._psu = psutil.Process(pid=self._pid)
84 mem = self._psu.memory_info()
85 self._samples.append({
87 'cpu': self._psu.cpu_percent(),
94 def finish(self):
95 self._duration = datetime.now() - self._started_at
96 if len(self._samples) > 0:
97 weights = [s['time'].total_seconds() for s in self._samples]
98 self._stats = {}
99 for key in self.STAT_KEYS:
100 self._stats[key] = fmean([s[key] for s in self._samples], weights)
102 self._stats = None
103 self._psu = None
105 def __repr__(self):
106 return f'RunProfile[pid={self._pid}, '\
107 f'duration={self.duration.total_seconds():.3f}s, '\
108 f'stats={self.stats}]'
113 def __init__(self, env, run_dir):
114 self._env = env
115 self._run_dir = run_dir
116 self._proc = None
117 self._stdoutfile = os.path.join(self._run_dir, 'tcpdump.out')
118 self._stderrfile = os.path.join(self._run_dir, 'tcpdump.err')
121 def stats(self) -> Optional[List[str]]:
122 if self._proc:
125 for line in open(self._stdoutfile)
128 def stats_excluding(self, src_port) -> Optional[List[str]]:
129 if self._proc:
132 for line in self.stats
136 def stderr(self) -> List[str]:
137 if self._proc:
139 return open(self._stderrfile).readlines()
141 def sample(self):
145 tcpdump = self._env.tcpdump()
157 with open(self._stdoutfile, 'w') as cout, open(self._stderrfile, 'w') as cerr:
158 self._proc = subprocess.Popen(args, stdout=cout, stderr=cerr,
159 text=True, cwd=self._run_dir,
161 assert self._proc
162 assert self._proc.returncode is None
163 while self._proc:
165 self._proc.wait(timeout=1)
171 def start(self):
173 self.sample()
177 def finish(self):
178 if self._proc:
180 self._proc.terminate()
181 self._proc = None
186 def __init__(self, args: List[str], exit_code: int,
193 self._args = args
194 self._exit_code = exit_code
195 self._exception = exception
196 self._stdout = stdout
197 self._stderr = stderr
198 self._profile = profile
199 self._tcpdump = tcpdump
200 self._duration = duration if duration is not None else timedelta()
201 self._response = None
202 self._responses = []
203 self._results = {}
204 self._assets = []
205 self._stats = []
206 self._json_out = None
207 self._with_stats = with_stats
209 self._parse_stats()
213 out = ''.join(self._stdout)
214 self._json_out = json.loads(out)
218 def __repr__(self):
219 return f"ExecResult[code={self.exit_code}, exception={self._exception}, "\
220 f"args={self._args}, stdout={self._stdout}, stderr={self._stderr}]"
222 def _parse_stats(self):
223 self._stats = []
224 for line in self._stdout:
226 self._stats.append(json.loads(line))
233 def exit_code(self) -> int:
234 return self._exit_code
237 def args(self) -> List[str]:
238 return self._args
241 def outraw(self) -> bytes:
242 return ''.join(self._stdout).encode()
245 def stdout(self) -> str:
246 return ''.join(self._stdout)
249 def json(self) -> Optional[Dict]:
251 return self._json_out
254 def stderr(self) -> str:
255 return ''.join(self._stderr)
258 def trace_lines(self) -> List[str]:
259 return self._stderr
262 def duration(self) -> timedelta:
263 return self._duration
266 def profile(self) -> Optional[RunProfile]:
267 return self._profile
270 def tcpdump(self) -> Optional[RunTcpDump]:
271 return self._tcpdump
274 def response(self) -> Optional[Dict]:
275 return self._response
278 def responses(self) -> List[Dict]:
279 return self._responses
282 def results(self) -> Dict:
283 return self._results
286 def assets(self) -> List:
287 return self._assets
290 def with_stats(self) -> bool:
291 return self._with_stats
294 def stats(self) -> List:
295 return self._stats
298 def total_connects(self) -> Optional[int]:
299 if len(self.stats):
301 for stat in self.stats:
306 def add_response(self, resp: Dict):
307 self._response = resp
308 self._responses.append(resp)
310 def add_results(self, results: Dict):
311 self._results.update(results)
313 self.add_response(results['response'])
315 def add_assets(self, assets: List):
316 self._assets.extend(assets)
318 def check_exit_code(self, code: Union[int, bool]):
320 assert self.exit_code == 0, f'expected exit code {code}, '\
321 f'got {self.exit_code}\n{self.dump_logs()}'
323 assert self.exit_code != 0, f'expected exit code {code}, '\
324 f'got {self.exit_code}\n{self.dump_logs()}'
326 assert self.exit_code == code, f'expected exit code {code}, '\
327 f'got {self.exit_code}\n{self.dump_logs()}'
329 def check_response(self, http_status: Optional[int] = 200,
335 self.check_exit_code(exitcode)
336 if self.with_stats and isinstance(exitcode, int):
337 for idx, x in enumerate(self.stats):
341 f'got {x["exitcode"]}\n{self.dump_logs()}'
343 if self.with_stats:
344 assert len(self.stats) == count, \
346 f'got {len(self.stats)}\n{self.dump_logs()}'
348 assert len(self.responses) == count, \
350 f'got {len(self.responses)}\n{self.dump_logs()}'
352 if self.with_stats:
353 for idx, x in enumerate(self.stats):
355 f'response #{idx} reports no http_code\n{self.dump_stat(x)}'
358 f'got {x["http_code"]}\n{self.dump_stat(x)}'
360 for idx, x in enumerate(self.responses):
363 f'got {x["status"]}\n{self.dump_stat(x)}'
365 if self.with_stats:
374 for idx, x in enumerate(self.stats):
377 f'got version {x["http_version"]}\n{self.dump_stat(x)}'
379 for idx, x in enumerate(self.responses):
382 f'got {x["protocol"]}\n{self.dump_logs()}'
384 assert self.total_connects == connect_count, \
385 f'expected {connect_count}, but {self.total_connects} '\
386 f'were made\n{self.dump_logs()}'
388 def check_stats(self, count: int, http_status: Optional[int] = None,
393 self.check_exit_code(0)
394 assert len(self.stats) == count, \
395 f'stats count: expected {count}, got {len(self.stats)}\n{self.dump_logs()}'
397 for idx, x in enumerate(self.stats):
399 f'status #{idx} reports no http_code\n{self.dump_stat(x)}'
402 f'got {x["http_code"]}\n{self.dump_stat(x)}'
404 for idx, x in enumerate(self.stats):
408 f'got {x["exitcode"]}\n{self.dump_stat(x)}'
410 for idx, x in enumerate(self.stats):
411 assert 'remote_port' in x, f'remote_port missing\n{self.dump_stat(x)}'
414 f'got {x["remote_port"]}\n{self.dump_stat(x)}'
416 for idx, x in enumerate(self.stats):
417 assert 'remote_ip' in x, f'remote_ip missing\n{self.dump_stat(x)}'
420 f'got {x["remote_ip"]}\n{self.dump_stat(x)}'
422 def dump_logs(self):
424 lines.extend(self._stdout)
426 lines.extend(self._stderr)
430 def dump_stat(self, x):
438 lines.extend(self.xfer_trace_for(xfer_id))
441 lines.extend(self._stderr)
445 def xfer_trace_for(self, xfer_id) -> List[str]:
447 return [line for line in self._stderr if pat.match(line)]
461 def __init__(self, env: Env,
467 self.env = env
468 self._timeout = timeout if timeout else env.test_timeout
469 self._curl = os.environ['CURL'] if 'CURL' in os.environ else env.curl
470 self._run_dir = run_dir if run_dir else os.path.join(env.gen_dir, 'curl')
471 self._stdoutfile = f'{self._run_dir}/curl.stdout'
472 self._stderrfile = f'{self._run_dir}/curl.stderr'
473 self._headerfile = f'{self._run_dir}/curl.headers'
474 self._log_path = f'{self._run_dir}/curl.log'
475 self._silent = silent
476 self._run_env = run_env
477 self._server_addr = server_addr if server_addr else '127.0.0.1'
478 self._rmrf(self._run_dir)
479 self._mkpath(self._run_dir)
482 def run_dir(self) -> str:
483 return self._run_dir
485 def download_file(self, i: int) -> str:
486 return os.path.join(self.run_dir, f'download_{i}.data')
488 def _rmf(self, path):
492 def _rmrf(self, path):
496 def _mkpath(self, path):
500 def get_proxy_args(self, proto: str = 'http/1.1',
503 proxy_name = self._server_addr if use_ip else self.env.proxy_domain
505 pport = self.env.pts_port(proto) if tunnel else self.env.proxys_port
508 '--resolve', f'{proxy_name}:{pport}:{self._server_addr}',
509 '--proxy-cacert', self.env.ca.cert_file,
515 '--proxy', f'http://{proxy_name}:{self.env.proxy_port}/',
516 '--resolve', f'{proxy_name}:{self.env.proxy_port}:{self._server_addr}',
522 def http_get(self, url: str, extra_args: Optional[List[str]] = None,
528 return self._raw(url, options=extra_args,
535 def http_download(self, urls: List[str],
555 self._rmf(self.download_file(i))
560 return self._raw(urls, alpn_proto=alpn_proto, options=extra_args,
566 def http_upload(self, urls: List[str], data: str,
582 return self._raw(urls, alpn_proto=alpn_proto, options=extra_args,
588 def http_delete(self, urls: List[str],
602 return self._raw(urls, alpn_proto=alpn_proto, options=extra_args,
607 def http_put(self, urls: List[str], data=None, fdata=None,
626 return self._raw(urls, intext=data,
632 def http_form(self, urls: List[str], form: Dict[str, str],
648 return self._raw(urls, alpn_proto=alpn_proto, options=extra_args,
652 def ftp_get(self, urls: List[str],
670 self._rmf(self.download_file(i))
675 return self._raw(urls, options=extra_args,
681 def ftp_ssl_get(self, urls: List[str],
692 return self.ftp_get(urls=urls, with_stats=with_stats,
697 def ftp_upload(self, urls: List[str],
720 return self._raw(urls, options=extra_args,
727 def ftp_ssl_upload(self, urls: List[str],
739 return self.ftp_upload(urls=urls, fupload=fupload, updata=updata,
744 def response_file(self, idx: int):
745 return os.path.join(self._run_dir, f'download_{idx}.data')
747 def run_direct(self, args, with_stats: bool = False, with_profile: bool = False):
748 my_args = [self._curl]
757 return self._run(args=my_args, with_stats=with_stats, with_profile=with_profile)
759 def _run(self, args, intext='', with_stats: bool = False,
761 self._rmf(self._stdoutfile)
762 self._rmf(self._stderrfile)
763 self._rmf(self._headerfile)
769 tcpdump = RunTcpDump(self.env, self._run_dir)
772 with open(self._stdoutfile, 'w') as cout, open(self._stderrfile, 'w') as cerr:
774 end_at = started_at + timedelta(seconds=self._timeout) \
775 if self._timeout else None
778 cwd=self._run_dir, shell=False,
779 env=self._run_env)
780 profile = RunProfile(p.pid, started_at, self._run_dir)
791 raise subprocess.TimeoutExpired(cmd=args, timeout=self._timeout)
799 cwd=self._run_dir, shell=False,
801 timeout=self._timeout,
802 env=self._run_env)
808 f'(configured {self._timeout}s): {args}')
813 coutput = open(self._stdoutfile).readlines()
814 cerrput = open(self._stderrfile).readlines()
821 def _raw(self, urls, intext='', timeout=None, options=None, insecure=False,
829 args = self._complete_args(
833 r = self._run(args, intext=intext, with_stats=with_stats,
836 self._parse_headerfile(self._headerfile, r=r)
839 def _complete_args(self, urls, timeout=None, options=None,
847 args = [self._curl, "-s", "--path-as-is"]
852 args.extend(["-D", self._headerfile])
853 if def_tracing is not False and not self._silent:
855 if self.env.verbose > 1:
867 if alpn_proto not in self.ALPN_ARG:
869 args.append(self.ALPN_ARG[alpn_proto])
878 args.extend(["--cacert", self.env.ca.cert_file])
884 '--resolve', f'{u.hostname}:{port}:{self._server_addr}',
891 def _parse_headerfile(self, headerfile: str, r: Optional[ExecResult] = None) -> ExecResult: