From ee0fecde29edbfeba8ea405a2ae554cd8755cc2b Mon Sep 17 00:00:00 2001 From: Jonathan Rajotte Date: Tue, 14 Nov 2017 17:06:16 -0500 Subject: [PATCH] Introduce basic babeltrace testing Signed-off-by: Jonathan Rajotte --- lttng_ivc/config.yaml | 6 + lttng_ivc/settings.py | 3 + lttng_ivc/tests/babeltrace/__init__.py | 0 lttng_ivc/tests/babeltrace/base/__init__.py | 0 .../babeltrace/base/test_babeltrace_base.py | 319 ++++++++++++++++++ .../traces/packet_lost_2_stream/metadata | 58 ++++ .../traces/packet_lost_2_stream/test_stream_0 | Bin 0 -> 640 bytes .../traces/packet_lost_2_stream/test_stream_1 | Bin 0 -> 384 bytes lttng_ivc/utils/runtime.py | 3 + 9 files changed, 389 insertions(+) create mode 100644 lttng_ivc/tests/babeltrace/__init__.py create mode 100644 lttng_ivc/tests/babeltrace/base/__init__.py create mode 100644 lttng_ivc/tests/babeltrace/base/test_babeltrace_base.py create mode 100644 lttng_ivc/traces/packet_lost_2_stream/metadata create mode 100644 lttng_ivc/traces/packet_lost_2_stream/test_stream_0 create mode 100644 lttng_ivc/traces/packet_lost_2_stream/test_stream_1 diff --git a/lttng_ivc/config.yaml b/lttng_ivc/config.yaml index a70a156..add9dc2 100644 --- a/lttng_ivc/config.yaml +++ b/lttng_ivc/config.yaml @@ -44,6 +44,12 @@ lttng-modules: ref: stable-2.10 babeltrace: + - marker: babeltrace-1.3 + url: https://github.com/efficios/babeltrace + ref: stable-1.3 + - marker: babeltrace-1.4 + url: https://github.com/efficios/babeltrace + ref: stable-1.4 - marker: babeltrace-1.5 url: https://github.com/efficios/babeltrace ref: stable-1.5 diff --git a/lttng_ivc/settings.py b/lttng_ivc/settings.py index 5889b19..e21c47b 100644 --- a/lttng_ivc/settings.py +++ b/lttng_ivc/settings.py @@ -18,6 +18,9 @@ apps_jul_1 = os.path.join(apps_folder, "jul-1.0") apps_jul_2 = os.path.join(apps_folder, "jul-2.0") apps_python = os.path.join(apps_folder, "python") +traces_folder = os.path.join(base_dir, "traces") +trace_lost_packet = os.path.join(traces_folder, "packet_lost_2_stream") + # Used for checksum validation project_py_file_location = os.path.join(base_dir, "utils/project.py") diff --git a/lttng_ivc/tests/babeltrace/__init__.py b/lttng_ivc/tests/babeltrace/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/lttng_ivc/tests/babeltrace/base/__init__.py b/lttng_ivc/tests/babeltrace/base/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/lttng_ivc/tests/babeltrace/base/test_babeltrace_base.py b/lttng_ivc/tests/babeltrace/base/test_babeltrace_base.py new file mode 100644 index 0000000..8cc0031 --- /dev/null +++ b/lttng_ivc/tests/babeltrace/base/test_babeltrace_base.py @@ -0,0 +1,319 @@ +import pytest +import os +import shutil +import filecmp + +import lttng_ivc.utils.ProjectFactory as ProjectFactory +import lttng_ivc.utils.utils as utils +import lttng_ivc.utils.runtime as Run +import lttng_ivc.settings as Settings + + +from lttng_ivc.utils.skip import must_be_root +from itertools import combinations +""" + +FC: Fully Compatible +BC: Feature of the smallest version number will works. + ++------------------------------------------------------------------------------+ +| Babeltrace vs UST/Tools/Metadata | ++--------------------------+------------+------------+------------+------------+ +| Babeltrace / LTTng | 2.7 | 2.8 | 2.9 | 2.10 | ++--------------------------+------------+------------+------------+------------+ +| 1.3 | FC | BC | BC | BC | +| 1.4 | FC | FC | FC | FC | +| 1.5 | FC | FC | FC | FC | ++--------------------------+------------+------------+------------+------------+ + +""" +test_matrix_base_ust = [ + ("babeltrace-1.3", "lttng-tools-2.7"), + ("babeltrace-1.3", "lttng-tools-2.8"), + ("babeltrace-1.3", "lttng-tools-2.9"), + ("babeltrace-1.3", "lttng-tools-2.10"), + ("babeltrace-1.4", "lttng-tools-2.7"), + ("babeltrace-1.4", "lttng-tools-2.8"), + ("babeltrace-1.4", "lttng-tools-2.9"), + ("babeltrace-1.4", "lttng-tools-2.10"), + ("babeltrace-1.5", "lttng-tools-2.7"), + ("babeltrace-1.5", "lttng-tools-2.8"), + ("babeltrace-1.5", "lttng-tools-2.9"), + ("babeltrace-1.5", "lttng-tools-2.10"), +] + +test_matrix_base_modules = [ + ("babeltrace-1.3", "lttng-modules-2.7", "lttng-tools-2.7"), + ("babeltrace-1.3", "lttng-modules-2.8", "lttng-tools-2.8"), + ("babeltrace-1.3", "lttng-modules-2.9", "lttng-tools-2.9"), + ("babeltrace-1.3", "lttng-modules-2.10", "lttng-tools-2.10"), + ("babeltrace-1.4", "lttng-modules-2.7", "lttng-tools-2.7"), + ("babeltrace-1.4", "lttng-modules-2.8", "lttng-tools-2.8"), + ("babeltrace-1.4", "lttng-modules-2.9", "lttng-tools-2.9"), + ("babeltrace-1.4", "lttng-modules-2.10", "lttng-tools-2.10"), + ("babeltrace-1.5", "lttng-modules-2.7", "lttng-tools-2.7"), + ("babeltrace-1.5", "lttng-modules-2.8", "lttng-tools-2.8"), + ("babeltrace-1.5", "lttng-modules-2.9", "lttng-tools-2.9"), + ("babeltrace-1.5", "lttng-modules-2.10", "lttng-tools-2.10"), +] + +test_matrix_lost_packet = [ + ("babeltrace-1.3", False), + ("babeltrace-1.4", True), + ("babeltrace-1.5", True), +] + +test_matrix_same_trace_modules = [ + (["babeltrace-1.3", "babeltrace-1.4", "babeltrace-1.5"], "lttng-modules-2.7", "lttng-tools-2.7"), + (["babeltrace-1.3", "babeltrace-1.4", "babeltrace-1.5"], "lttng-modules-2.8", "lttng-tools-2.8"), + (["babeltrace-1.3", "babeltrace-1.4", "babeltrace-1.5"], "lttng-modules-2.9", "lttng-tools-2.9"), + (["babeltrace-1.3", "babeltrace-1.4", "babeltrace-1.5"], "lttng-modules-2.10", "lttng-tools-2.10"), +] + +test_matrix_same_trace_ust = [ + (["babeltrace-1.3", "babeltrace-1.4", "babeltrace-1.5"], "lttng-tools-2.7"), + (["babeltrace-1.3", "babeltrace-1.4", "babeltrace-1.5"], "lttng-tools-2.8"), + (["babeltrace-1.3", "babeltrace-1.4", "babeltrace-1.5"], "lttng-tools-2.9"), + (["babeltrace-1.3", "babeltrace-1.4", "babeltrace-1.5"], "lttng-tools-2.10"), +] + + +runtime_matrix_base_ust = [] +runtime_matrix_lost_packet = [] +runtime_matrix_base_modules = [] +runtime_matrix_same_trace_modules = [] +runtime_matrix_same_trace_ust = [] + + +if not Settings.test_only: + runtime_matrix_base_ust = test_matrix_base_ust + runtime_matrix_base_modules = test_matrix_base_modules + runtime_matrix_lost_packet = test_matrix_lost_packet + runtime_matrix_same_trace_modules = test_matrix_same_trace_modules + runtime_matrix_same_trace_ust = test_matrix_same_trace_ust +else: + for tup in test_matrix_base_ust: + if (tup[0] in Settings.test_only or tup[1] in + Settings.test_only): + runtime_matrix_base_ust.append(tup) + for tup in test_matrix_base_modules: + if (tup[0] in Settings.test_only or tup[1] in + Settings.test_only): + runtime_matrix_base_modules.append(tup) + for tup in test_matrix_lost_packet: + if (tup[0] in Settings.test_only or tup[1] in + Settings.test_only): + test_matrix_lost_packet.append(tup) + for tup in test_matrix_same_trace_modules: + if (tup[0] in Settings.test_only or tup[1] in + Settings.test_only): + runtime_matrix_same_trace_modules.append(tup) + for tup in test_matrix_same_trace_ust: + if (tup[0] in Settings.test_only or tup[1] in + Settings.test_only): + runtime_matrix_same_trace_ust.append(tup) + + +@pytest.mark.parametrize("babeltrace_l, tools_l", runtime_matrix_base_ust) +def test_babeltrace_base_ust(tmpdir, babeltrace_l, tools_l): + + nb_events = 100 + + # Prepare environment + babeltrace = ProjectFactory.get_precook(babeltrace_l) + tools = ProjectFactory.get_precook(tools_l) + + runtime_path = os.path.join(str(tmpdir), "runtime") + app_path = os.path.join(str(tmpdir), "app") + + with Run.get_runtime(runtime_path) as runtime: + runtime.add_project(tools) + runtime.add_project(babeltrace) + + # Make application using the runtime + shutil.copytree(Settings.apps_gen_events_folder, app_path) + runtime.run("make V=1", cwd=app_path) + + # Start lttng-sessiond + sessiond = utils.sessiond_spawn(runtime) + + # Create session using mi to get path and session name + runtime.run('lttng create trace') + runtime.run('lttng enable-event -u tp:tptest') + runtime.run('lttng start') + + # Run application + cmd = './app {}'.format(nb_events) + runtime.run(cmd, cwd=app_path) + + # Stop tracing + runtime.run('lttng destroy -a') + cp = runtime.subprocess_terminate(sessiond) + if cp.returncode != 0: + pytest.fail("Sessiond return code") + + # Do not validate the metadata only the return code of babeltrace + cmd = 'babeltrace -o ctf-metadata {}'.format(runtime.lttng_home) + runtime.run(cmd) + + cmd = 'babeltrace {}'.format(runtime.lttng_home) + cp_process, cp_out, cp_err = runtime.run(cmd) + assert(utils.line_count(cp_out) == nb_events) + + +@must_be_root +@pytest.mark.parametrize("babeltrace_l,modules_l,tools_l", runtime_matrix_base_modules) +def test_babeltrace_base_modules(tmpdir, babeltrace_l, modules_l, tools_l): + modules = ProjectFactory.get_precook(modules_l) + if modules.skip: + pytest.skip("{} cannot be built on this kernel".format(modules.label)) + tools = ProjectFactory.get_precook(tools_l) + babeltrace = ProjectFactory.get_precook(babeltrace_l) + + nb_events = 100 + + with Run.get_runtime(str(tmpdir)) as runtime: + runtime.add_project(modules) + runtime.add_project(tools) + runtime.add_project(babeltrace) + + sessiond = utils.sessiond_spawn(runtime) + runtime.load_test_module() + + runtime.run("lttng create trace") + runtime.run("lttng enable-event -k lttng_test_filter_event") + runtime.run("lttng start") + with open(Settings.lttng_test_procfile, 'w') as procfile: + procfile.write("{}".format(nb_events)) + + runtime.run("lttng stop") + runtime.run("lttng destroy -a") + + sessiond = runtime.subprocess_terminate(sessiond) + if sessiond.returncode != 0: + pytest.fail("Return value of sessiond is not zero") + return + + babeltrace_cmd = 'babeltrace {}'.format(runtime.lttng_home) + cp_process, cp_out, cp_err = runtime.run(babeltrace_cmd) + assert(utils.line_count(cp_out) == nb_events) + + +@must_be_root +@pytest.mark.parametrize("babeltrace_list,modules_l,tools_l", runtime_matrix_same_trace_modules) +def test_babeltrace_same_trace_modules(tmpdir, babeltrace_list, modules_l, tools_l): + modules = ProjectFactory.get_precook(modules_l) + if modules.skip: + pytest.skip("{} cannot be built on this kernel".format(modules.label)) + tools = ProjectFactory.get_precook(tools_l) + + nb_events = 100 + + with Run.get_runtime(str(tmpdir)) as runtime: + runtime.add_project(modules) + runtime.add_project(tools) + + sessiond = utils.sessiond_spawn(runtime) + runtime.load_test_module() + + runtime.run("lttng create trace") + runtime.run("lttng enable-event -k lttng_test_filter_event") + runtime.run("lttng start") + with open(Settings.lttng_test_procfile, 'w') as procfile: + procfile.write("{}".format(nb_events)) + + runtime.run("lttng stop") + runtime.run("lttng destroy -a") + + sessiond = runtime.subprocess_terminate(sessiond) + if sessiond.returncode != 0: + pytest.fail("Return value of sessiond is not zero") + return + + # Actual testing + processed_trace_files = {} + # Gather text traces + for label in babeltrace_list: + babeltrace = ProjectFactory.get_precook(label) + runtime.add_project(babeltrace) + babeltrace_cmd = 'babeltrace {}'.format(runtime.lttng_home) + cp_process, cp_out, cp_err = runtime.run(babeltrace_cmd) + assert (utils.line_count(cp_out) == nb_events) + processed_trace_files[label] = cp_out + runtime.remove_project(babeltrace) + + # Perform combinations and validate that traces match + for a, b in combinations(processed_trace_files, 2): + version_a = processed_trace_files[a] + version_b = processed_trace_files[b] + assert (filecmp.cmp(version_a, version_b)), "Processed trace from {} and {} differ.".format(a,b) + +@pytest.mark.parametrize("babeltrace_list,tools_l", runtime_matrix_same_trace_ust) +def test_babeltrace_same_trace_ust(tmpdir, babeltrace_list, tools_l): + tools = ProjectFactory.get_precook(tools_l) + + nb_events = 100 + + app_path = os.path.join(str(tmpdir), "app") + + with Run.get_runtime(str(tmpdir)) as runtime: + runtime.add_project(tools) + + shutil.copytree(Settings.apps_gen_events_folder, app_path) + runtime.run("make V=1", cwd=app_path) + + sessiond = utils.sessiond_spawn(runtime) + + # Create session using mi to get path and session name + runtime.run('lttng create trace') + runtime.run('lttng enable-event -u tp:tptest') + runtime.run('lttng start') + + # Run application + cmd = './app {}'.format(nb_events) + runtime.run(cmd, cwd=app_path) + + # Stop tracing + runtime.run('lttng destroy -a') + cp = runtime.subprocess_terminate(sessiond) + if cp.returncode != 0: + pytest.fail("Sessiond return code") + + # Actual testing + processed_trace_files = {} + # Gather text traces + for label in babeltrace_list: + babeltrace = ProjectFactory.get_precook(label) + runtime.add_project(babeltrace) + babeltrace_cmd = 'babeltrace {}'.format(runtime.lttng_home) + cp_process, cp_out, cp_err = runtime.run(babeltrace_cmd) + assert (utils.line_count(cp_out) == nb_events) + processed_trace_files[label] = cp_out + runtime.remove_project(babeltrace) + + # Perform combinations and validate that traces match + for a, b in combinations(processed_trace_files, 2): + version_a = processed_trace_files[a] + version_b = processed_trace_files[b] + assert (filecmp.cmp(version_a, version_b)), "Processed trace from {} and {} differ.".format(a, b) + + + +@pytest.mark.parametrize("babeltrace_l,supported", runtime_matrix_lost_packet) +def test_babeltrace_lost_patcket(tmpdir, babeltrace_l, supported): + babeltrace = ProjectFactory.get_precook(babeltrace_l) + + trace_path = Settings.trace_lost_packet + + with Run.get_runtime(str(tmpdir)) as runtime: + runtime.add_project(babeltrace) + cmd = "babeltrace {}".format(trace_path) + cp, cp_out, cp_err = runtime.run(cmd) + if supported: + assert(utils.file_contains(cp_err, "Tracer lost 3 trace packets")) + assert(utils.file_contains(cp_err, "Tracer lost 2 trace packets")) + assert(utils.file_contains(cp_err, "Tracer lost 1 trace packets")) + else: + os.path.getsize(cp_err) > 0 + + assert(utils.line_count(cp_out) == 8) diff --git a/lttng_ivc/traces/packet_lost_2_stream/metadata b/lttng_ivc/traces/packet_lost_2_stream/metadata new file mode 100644 index 0000000..c0ea8f5 --- /dev/null +++ b/lttng_ivc/traces/packet_lost_2_stream/metadata @@ -0,0 +1,58 @@ +/* CTF 1.8 */ + +trace { + major = 1; + minor = 8; + uuid = "eb5045f7-b471-488e-b963-0221ddf423a7"; + byte_order = be; + packet.header := struct { + integer { size = 32; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } magic; + integer { size = 8; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } uuid[16]; + integer { size = 32; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } stream_id; + } align(8); +}; + +env { + host = "sinkpad"; +}; + +clock { + name = test_clock; + uuid = "2447a359-1e57-448f-96ef-3c324327047c"; + description = "This is a test clock"; + freq = 1000000000; + precision = 10; + offset_s = 1351530929945824323; + offset = 0; + absolute = TRUE; +}; + +stream { + id = 0; + event.header := struct { + integer { size = 32; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } id; + integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; map = clock.test_clock.value; } timestamp; + } align(8); + + packet.context := struct { + integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } timestamp_begin; + integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } timestamp_end; + integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } content_size; + integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } packet_size; + integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } events_discarded; + integer { size = 64; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } packet_seq_num; + } align(8); +}; + +event { + id = 0; + name = "dummy_event"; + stream_id = 0; + fields := struct { + integer { size = 32; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } dummy_value; + integer { size = 32; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } tracefile_id; + integer { size = 32; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } packet_begin; + integer { size = 32; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } packet_end; + } align(1); +}; + diff --git a/lttng_ivc/traces/packet_lost_2_stream/test_stream_0 b/lttng_ivc/traces/packet_lost_2_stream/test_stream_0 new file mode 100644 index 0000000000000000000000000000000000000000..b0beb6b4e77cde2169ae96acc087214363676c05 GIT binary patch literal 640 zcmX^3NB-dJ0N3wZ3O)LECNnAC{i3{_0TYNogqRf|Gz+E*ga{Xc31&g{qKQJe2l3l4 z3RR{7p>f*Jh-5lQ4~!3DL-iu5Kw=WGUlXd-214Vsp9#rGEg&1l2kD3EMN)ypBw)WS zRA~T&#%Vt@l93)jHY|cb`k{J}R3I@4*dGX0ngXG5+Ruh$WDt