aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/test
diff options
context:
space:
mode:
authorEgor Tensin <Egor.Tensin@gmail.com>2023-07-18 18:39:00 +0200
committerEgor Tensin <Egor.Tensin@gmail.com>2023-07-18 19:57:17 +0200
commit6a200443106bb83c6261c64c323ceb9f0563fdad (patch)
tree45d1f41f2da35631079bc4b559b1cb44b4c34e32 /test
parentnet: don't copy data in struct buf (diff)
downloadcimple-6a200443106bb83c6261c64c323ceb9f0563fdad.tar.gz
cimple-6a200443106bb83c6261c64c323ceb9f0563fdad.zip
implement flame graph generation
Diffstat (limited to 'test')
-rw-r--r--test/CMakeLists.txt9
-rw-r--r--test/py/conftest.py41
-rw-r--r--test/py/lib/tests.py4
-rw-r--r--test/py/test_repo.py8
-rw-r--r--test/pytest.ini1
5 files changed, 56 insertions, 7 deletions
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 7f4ff11..d370c53 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -29,3 +29,12 @@ add_python_tests(python_tests_stress
add_python_tests(python_tests_valgrind
Python3::Interpreter -m pytest ${python_test_args} -m "not stress"
--valgrind-binary "${CMAKE_CURRENT_SOURCE_DIR}/../src/valgrind.sh")
+
+if(NOT DEFINED FLAME_GRAPHS_DIR)
+ set(FLAME_GRAPHS_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
+endif()
+
+add_python_tests(python_tests_perf
+ Python3::Interpreter -m pytest ${python_test_args} -m "flame_graph"
+ --flame-graph-binary "${CMAKE_CURRENT_SOURCE_DIR}/../scripts/flame_graph.sh"
+ --flame-graphs-dir "${FLAME_GRAPHS_DIR}")
diff --git a/test/py/conftest.py b/test/py/conftest.py
index ab2cbfb..db3f0b8 100644
--- a/test/py/conftest.py
+++ b/test/py/conftest.py
@@ -51,6 +51,9 @@ BINARY_PARAMS = [
PARAM_VALGRIND = ParamBinary('valgrind', required=False)
+PARAM_FLAME_GRAPH = ParamBinary('flame_graph', required=False)
+PARAM_FLAME_GRAPHS_DIR = Param('flame_graphs_dir', 'directory to store flame graphs', required=False)
+
class ParamVersion(Param):
def __init__(self):
@@ -62,6 +65,8 @@ PARAM_VERSION = ParamVersion()
PARAMS = list(BINARY_PARAMS)
PARAMS += [
PARAM_VALGRIND,
+ PARAM_FLAME_GRAPH,
+ PARAM_FLAME_GRAPHS_DIR,
PARAM_VERSION,
]
@@ -94,14 +99,19 @@ def paths(pytestconfig):
return Paths(pytestconfig)
+class CmdLineValgrind(CmdLine):
+ def __init__(self, binary):
+ # Signal to Valgrind that ci scripts should obviously be exempt from
+ # memory leak checking:
+ super().__init__(binary, '--trace-children-skip=*/ci', '--')
+
+
@fixture(scope='session')
def base_cmd_line(pytestconfig):
cmd_line = CmdLine.unbuffered()
valgrind = pytestconfig.getoption(PARAM_VALGRIND.codename)
if valgrind is not None:
- # Signal to Valgrind that ci scripts should obviously be exempt from
- # memory leak checking:
- cmd_line = CmdLine.wrap(CmdLine(valgrind, '--trace-children-skip=*/ci', '--'), cmd_line)
+ cmd_line = CmdLine.wrap(CmdLineValgrind(valgrind), cmd_line)
return cmd_line
@@ -194,6 +204,29 @@ def repo_path(tmp_path):
return os.path.join(tmp_path, 'repo')
+@fixture
+def flame_graph_path(pytestconfig, tmp_path):
+ dir = pytestconfig.getoption(PARAM_FLAME_GRAPHS_DIR.codename)
+ if dir is None:
+ return os.path.join(tmp_path, 'flame_graph.svg')
+ os.makedirs(dir, exist_ok=True)
+ return os.path.join(dir, 'flame_graph.svg')
+
+
+@fixture
+def profiler(pytestconfig, server, workers, flame_graph_path):
+ script = pytestconfig.getoption(PARAM_FLAME_GRAPH.codename)
+ if script is None:
+ yield
+ return
+ pids = [server.pid] + [worker.pid for worker in workers]
+ pids = map(str, pids)
+ cmd_line = CmdLine(script, flame_graph_path, *pids)
+ with cmd_line.run_async() as proc:
+ yield
+ assert proc.returncode == 0
+
+
ALL_REPOS = [
repo.TestRepoOutputSimple,
repo.TestRepoOutputEmpty,
@@ -225,5 +258,5 @@ Env = namedtuple('Env', ['server', 'workers', 'client', 'db'])
@fixture
-def env(server, workers, client, sqlite_db):
+def env(server, workers, profiler, client, sqlite_db):
return Env(server, workers, client, sqlite_db)
diff --git a/test/py/lib/tests.py b/test/py/lib/tests.py
index a676021..fe90f96 100644
--- a/test/py/lib/tests.py
+++ b/test/py/lib/tests.py
@@ -14,8 +14,10 @@ def my_parametrize(names, values, ids=None, **kwargs):
if len(_names) == 1:
ids = [f'{names}={v}' for v in values]
else:
+ _values = [combination.values if hasattr(combination, 'values') else combination
+ for combination in values]
ids = [
'-'.join(f'{k}={v}' for k, v in zip(_names, combination))
- for combination in values
+ for combination in _values
]
return pytest.mark.parametrize(names, values, ids=ids, **kwargs)
diff --git a/test/py/test_repo.py b/test/py/test_repo.py
index 49d5a32..c973e37 100644
--- a/test/py/test_repo.py
+++ b/test/py/test_repo.py
@@ -79,7 +79,11 @@ def test_repo(env, test_repo, numof_clients, runs_per_client):
@pytest.mark.stress
-@my_parametrize(('numof_clients', 'runs_per_client'),
- [(10, 50), (1, 2000), (4, 500)])
+@my_parametrize('numof_clients,runs_per_client',
+ [
+ (10, 50),
+ (1, 2000),
+ pytest.param(4, 500, marks=pytest.mark.flame_graph),
+ ])
def test_repo_stress(env, stress_test_repo, numof_clients, runs_per_client):
_test_repo_internal(env, stress_test_repo, numof_clients, runs_per_client)
diff --git a/test/pytest.ini b/test/pytest.ini
index 766e409..49e206d 100644
--- a/test/pytest.ini
+++ b/test/pytest.ini
@@ -6,3 +6,4 @@ log_cli_level = INFO
markers =
stress: Big tests; don't run them w/ Valgrind or in QEMU
+ flame_graph: Generate the flame graph for these tests