Skip to content

Commit

Permalink
Port performance tests
Browse files Browse the repository at this point in the history
Compared to existing performance tests, fixtures are generated in
/usr/local/lib/pulp/lib/python3.7/site-packages/rest_framework/static/fixtures/.
And then available at http://localhost:80/static/fixtures/.

closes #5458
https://pulp.plan.io/issues/5458
  • Loading branch information
lubosmj committed Oct 29, 2019
1 parent 441e754 commit 9ece27d
Show file tree
Hide file tree
Showing 8 changed files with 510 additions and 9 deletions.
1 change: 1 addition & 0 deletions CHANGES/5458.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Port performance tests to pulp_file
1 change: 1 addition & 0 deletions pulp_file/manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ def __init__(self, relative_path, size, digest):
relative_path (str): A relative path.
digest (str): The file sha256 hex digest.
size (int): The file size in bytes.
"""
self.relative_path = relative_path
self.digest = digest
Expand Down
Empty file.
78 changes: 78 additions & 0 deletions pulp_file/tests/performance/pulpperf/interact.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import logging
import requests
import tempfile
import time

from .utils import measureit, urljoin

BASE_ADDR = "http://localhost:24817"
CONTENT_ADDR = "http://localhost:24816"


def get(url, params={}):
"""Wrapper around requests.get with some simplification in our case."""
url = BASE_ADDR + url

r = requests.get(url=url, params=params)
r.raise_for_status()
data = r.json()
return data


def get_results(url, params={}):
"""Wrapper around requests.get with some simplification in our case."""
out = []
page = 0
while True:
data = get(url, params)
out += data["results"]
page += 1
params["page"] = page
if data["next"] is None:
break
return out


def post(url, data):
"""Wrapper around requests.post with some simplification in our case."""
url = BASE_ADDR + url

r = requests.post(url=url, json=data)
r.raise_for_status()
return r.json()


def download(base_url, file_name, file_size):
"""Downlad file with expected size and drop it."""
with tempfile.TemporaryFile() as downloaded_file:
full_url = urljoin(CONTENT_ADDR, base_url, file_name)
duration, response = measureit(requests.get, full_url)
response.raise_for_status()
downloaded_file.write(response.content)
assert downloaded_file.tell() == file_size
return duration


def wait_for_tasks(tasks, timeout=None):
"""
Wait for tasks to finish.
Returns task info. If we time out, list of None is returned.
"""
start = time.time()
out = []
step = 3
for t in tasks:
while True:
if timeout is not None:
now = time.time()
if now >= start + timeout:
raise Exception("Task %s timeouted" % t)
response = get(t)
logging.debug("Task status is '%s', full response %s" % (response["state"], response))
if response["state"] in ("failed", "cancelled", "completed"):
out.append(response)
break
else:
time.sleep(step)
return out
105 changes: 105 additions & 0 deletions pulp_file/tests/performance/pulpperf/reporting.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import datetime
import statistics

DATETIME_FMT = "%Y-%m-%dT%H:%M:%S.%fZ"


def parse_date_from_string(s, parse_format="%Y-%m-%dT%H:%M:%S.%fZ"):
"""Parse string to datetime object.
:param s: str like '2018-11-18T21:03:32.493697Z'
:param parse_format: str defaults to %Y-%m-%dT%H:%M:%S.%fZ
:return: datetime.datetime
"""
return datetime.datetime.strptime(s, parse_format)


def tasks_table(tasks, performance_task_name):
"""Return overview of tasks."""
out = []
for t in tasks:
created_at = parse_date_from_string(t["pulp_created"])
started_at = parse_date_from_string(t["started_at"])
finished_at = parse_date_from_string(t["finished_at"])
task_duration = finished_at - started_at
waiting_time = started_at - created_at
out.append(
"\n-> {task_name} => Waiting time (s): {wait} | Service time (s): {service}".format(
task_name=performance_task_name,
wait=waiting_time.total_seconds(),
service=task_duration.total_seconds(),
)
)
return "\n".join(out)


def tasks_min_max_table(tasks):
"""Return overview of tasks dates min and max in a table."""
"""
out = "\n%11s\t%27s\t%27s\n" % ("field", "min", "max")
for f in ("pulp_created", "started_at", "finished_at"):
sample = [datetime.datetime.strptime(t[f], DATETIME_FMT) for t in tasks]
out += "%11s\t%s\t%s\n" % (
f,
min(sample).strftime(DATETIME_FMT),
max(sample).strftime(DATETIME_FMT),
)
return out
"""


def data_stats(data):
"""Return basic stats fetch from provided data."""
return {
"samples": len(data),
"min": min(data),
"max": max(data),
"mean": statistics.mean(data),
"stdev": statistics.stdev(data) if len(data) > 1 else 0.0,
}


def fmt_data_stats(data):
"""
Format data.
https://stackoverflow.com/questions/455612/limiting-floats-to-two-decimal-points
"""
return {
"samples": data["samples"],
"min": float("%.02f" % round(data["min"], 2)),
"max": float("%.02f" % round(data["max"], 2)),
"mean": float("%.02f" % round(data["mean"], 2)),
"stdev": float("%.02f" % round(data["stdev"], 2)),
}


def tasks_waiting_time(tasks):
"""Analyse tasks waiting time (i.e. started_at - _created)."""
durations = []
for t in tasks:
diff = datetime.datetime.strptime(
t["started_at"], DATETIME_FMT
) - datetime.datetime.strptime(t["pulp_created"], DATETIME_FMT)
durations.append(diff.total_seconds())
return fmt_data_stats(data_stats(durations))


def tasks_service_time(tasks):
"""Analyse tasks service time (i.e. finished_at - started_at)."""
durations = []
for t in tasks:
diff = datetime.datetime.strptime(
t["finished_at"], DATETIME_FMT
) - datetime.datetime.strptime(t["started_at"], DATETIME_FMT)
durations.append(diff.total_seconds())
return fmt_data_stats(data_stats(durations))


def print_fmt_experiment_time(label, start, end):
"""Print formatted label and experiment time."""
print("\n-> {} => Experiment time (s): {}".format(label, (end - start).total_seconds()))


def report_tasks_stats(performance_task_name, tasks):
"""Print out basic stats about received tasks."""
print(tasks_table(tasks, performance_task_name))
32 changes: 32 additions & 0 deletions pulp_file/tests/performance/pulpperf/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import logging
import random
import time
import string
import requests


def get_random_string():
"""Return random string."""
return "".join(random.choice(string.ascii_lowercase) for i in range(5))


def urljoin(*args):
"""This sucks, but works. Better ways welcome."""
return "/".join([i.lstrip("/").rstrip("/") for i in args])


def measureit(func, *args, **kwargs):
"""Measure execution time of passed function."""
logging.debug("Measuring duration of %s %s %s" % (func.__name__, args, kwargs))
before = time.clock()
out = func(*args, **kwargs)
after = time.clock()
return after - before, out


def parse_pulp_manifest(url):
"""Parse pulp manifest."""
response = requests.get(url)
response.text.split("\n")
data = [i.strip().split(",") for i in response.text.split("\n")]
return [(i[0], i[1], int(i[2])) for i in data if i != [""]]
9 changes: 0 additions & 9 deletions pulp_file/tests/performance/test_nothing.py

This file was deleted.

Loading

0 comments on commit 9ece27d

Please sign in to comment.