Tests: add duplicated providers tests
authorFrancis Deslauriers <francis.deslauriers@efficios.com>
Fri, 9 Feb 2018 21:56:52 +0000 (16:56 -0500)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Wed, 30 May 2018 09:39:04 +0000 (05:39 -0400)
Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
12 files changed:
configure.ac
tests/fast_regression
tests/regression/Makefile.am
tests/regression/ust/Makefile.am
tests/regression/ust/multi-lib/Makefile.am [new file with mode: 0644]
tests/regression/ust/multi-lib/README [new file with mode: 0644]
tests/regression/ust/multi-lib/callsites.c [new file with mode: 0644]
tests/regression/ust/multi-lib/callsites.h [new file with mode: 0644]
tests/regression/ust/multi-lib/multi-lib-test.c [new file with mode: 0644]
tests/regression/ust/multi-lib/probes.c [new file with mode: 0644]
tests/regression/ust/multi-lib/probes.h [new file with mode: 0644]
tests/regression/ust/multi-lib/test_multi_lib [new file with mode: 0755]

index f5b105e4babdd41b945cc4d17c788e0069c804ab..60e76b03bcc77c30c2a8a796a8fa05eb623cd778 100644 (file)
@@ -1088,6 +1088,7 @@ AC_CONFIG_FILES([
        tests/regression/ust/buffers-pid/Makefile
        tests/regression/ust/periodical-metadata-flush/Makefile
        tests/regression/ust/multi-session/Makefile
+       tests/regression/ust/multi-lib/Makefile
        tests/regression/ust/overlap/Makefile
        tests/regression/ust/overlap/demo/Makefile
        tests/regression/ust/linking/Makefile
index bbce068f72d5cd1688e039fef3a4682e60b1fa40..f76b53dc2a5e1b22600c0841e7a331ebc9cc56ad 100644 (file)
@@ -21,6 +21,7 @@ regression/tools/regen-statedump/test_ust
 regression/ust/before-after/test_before_after
 regression/ust/buffers-pid/test_buffers_pid
 regression/ust/multi-session/test_multi_session
+regression/ust/multi-lib/test_multi_lib
 regression/ust/nprocesses/test_nprocesses
 regression/ust/overlap/test_overlap
 regression/ust/java-jul/test_java_jul
index b1642812af9f1116cf51c88dcf10db7ea2846a56..50e89e4c52ad7f5a9426003c356082ffe62e70cc 100644 (file)
@@ -46,7 +46,8 @@ TESTS += ust/before-after/test_before_after \
        ust/test_event_basic \
        ust/test_event_tracef \
        ust/test_event_perf \
-       ust/blocking/test_blocking
+       ust/blocking/test_blocking \
+       ust/multi-lib/test_multi_lib
 endif # HAVE_LIBLTTNG_UST_CTL
 
 if PYTHON_BINDING
index 06cf97a4720c25bc4a957b8a9c0f00230a97724a..6237b1610653c12b90f957817fd7e2d1bfc5979e 100644 (file)
@@ -3,7 +3,7 @@ SUBDIRS = nprocesses high-throughput low-throughput before-after multi-session \
                overlap buffers-pid linking daemon exit-fast fork libc-wrapper \
                periodical-metadata-flush java-jul java-log4j python-logging \
                getcpu-override clock-override type-declarations \
-               rotation-destroy-flush blocking
+               rotation-destroy-flush blocking multi-lib
 
 if HAVE_OBJCOPY
 SUBDIRS += baddr-statedump ust-dl
diff --git a/tests/regression/ust/multi-lib/Makefile.am b/tests/regression/ust/multi-lib/Makefile.am
new file mode 100644 (file)
index 0000000..3fb4ae7
--- /dev/null
@@ -0,0 +1,129 @@
+noinst_SCRIPTS = test_multi_lib
+EXTRA_DIST = test_multi_lib
+noinst_PROGRAMS = exec-with-callsites exec-without-callsites
+
+exec_with_callsites_SOURCES = multi-lib-test.c callsites.c
+exec_with_callsites_LDFLAGS = -ldl -lpopt
+exec_with_callsites_CFLAGS = $(AM_CFLAGS) -DHAS_CALLSITES=1
+
+exec_without_callsites_SOURCES = multi-lib-test.c
+exec_without_callsites_LDFLAGS = -ldl -lpopt -llttng-ust
+exec_without_callsites_LDADD = probes.o
+exec_without_callsites_CFLAGS = $(AM_CFLAGS) -DHAS_CALLSITES=0
+
+PROBES_SRC=probes.c probes.h
+PROBES_LDF=-shared -module -llttng-ust -avoid-version -rpath $(abs_builddir)/.libs/
+PROBES_CF=$(AM_CFLAGS) $(AM_CPPFLAGS) $(CFLAGS) $(CPPFLAGS) -c -I$(srcdir)/
+
+probes.o: probes.c probes.h
+       $(CC) $(PROBES_CF) -o $@ $<
+
+noinst_LTLIBRARIES = libprobes_a.la libprobes_a_prime.la \
+                       libprobes_b.la libprobes_c.la libprobes_c_prime.la \
+                       libprobes_d.la libprobes_e.la libprobes_f.la \
+                       libprobes_g.la libprobes_h.la libprobes_i.la \
+                       libprobes_j.la libprobes_k.la libprobes_l.la \
+                       libprobes_m.la libprobes_n.la libprobes_o.la \
+                       libprobes_p.la
+
+noinst_LTLIBRARIES += libcallsites_1.la libcallsites_2.la
+
+CALLSITES_SRC=callsites.c callsites.h
+CALLSITES_LDF=-shared -module -llttng-ust -avoid-version -rpath $(abs_builddir)/.libs/
+CALLSITES_CF=-c -I.
+
+libprobes_a_la_SOURCES = $(PROBES_SRC)
+libprobes_a_la_LDFLAGS = $(PROBES_LDF)
+libprobes_a_la_CFLAGS = $(AM_CFLAGS) $(PROBES_CF) -DACTIVATE_PROBES_A
+
+libprobes_a_prime_la_SOURCES = $(PROBES_SRC)
+libprobes_a_prime_la_LDFLAGS = $(PROBES_LDF)
+libprobes_a_prime_la_CFLAGS = $(AM_CFLAGS) $(PROBES_CF) -DACTIVATE_PROBES_A
+
+libprobes_b_la_SOURCES = $(PROBES_SRC)
+libprobes_b_la_LDFLAGS = $(PROBES_LDF)
+libprobes_b_la_CFLAGS = $(AM_CFLAGS) $(PROBES_CF) -DACTIVATE_PROBES_B
+
+libprobes_c_la_SOURCES = $(PROBES_SRC)
+libprobes_c_la_LDFLAGS = $(PROBES_LDF)
+libprobes_c_la_CFLAGS = $(AM_CFLAGS) $(PROBES_CF) -DACTIVATE_PROBES_C
+
+libprobes_c_prime_la_SOURCES = $(PROBES_SRC)
+libprobes_c_prime_la_LDFLAGS = $(PROBES_LDF)
+libprobes_c_prime_la_CFLAGS = $(AM_CFLAGS) $(PROBES_CF) -DACTIVATE_PROBES_C
+
+libprobes_d_la_SOURCES = $(PROBES_SRC)
+libprobes_d_la_LDFLAGS = $(PROBES_LDF)
+libprobes_d_la_CFLAGS = $(AM_CFLAGS) $(PROBES_CF) -DACTIVATE_PROBES_D
+
+libprobes_e_la_SOURCES = $(PROBES_SRC)
+libprobes_e_la_LDFLAGS = $(PROBES_LDF)
+libprobes_e_la_CFLAGS = $(AM_CFLAGS) $(PROBES_CF) -DACTIVATE_PROBES_E
+
+libprobes_f_la_SOURCES = $(PROBES_SRC)
+libprobes_f_la_LDFLAGS = $(PROBES_LDF)
+libprobes_f_la_CFLAGS = $(AM_CFLAGS) $(PROBES_CF) -DACTIVATE_PROBES_F
+
+libprobes_g_la_SOURCES = $(PROBES_SRC)
+libprobes_g_la_LDFLAGS = $(PROBES_LDF)
+libprobes_g_la_CFLAGS = $(AM_CFLAGS) $(PROBES_CF) -DACTIVATE_PROBES_G
+
+libprobes_h_la_SOURCES = $(PROBES_SRC)
+libprobes_h_la_LDFLAGS = $(PROBES_LDF)
+libprobes_h_la_CFLAGS = $(AM_CFLAGS) $(PROBES_CF) -DACTIVATE_PROBES_H
+
+libprobes_i_la_SOURCES = $(PROBES_SRC)
+libprobes_i_la_LDFLAGS = $(PROBES_LDF)
+libprobes_i_la_CFLAGS = $(AM_CFLAGS) $(PROBES_CF) -DACTIVATE_PROBES_I
+
+libprobes_j_la_SOURCES = $(PROBES_SRC)
+libprobes_j_la_LDFLAGS = $(PROBES_LDF)
+libprobes_j_la_CFLAGS = $(AM_CFLAGS) $(PROBES_CF) -DACTIVATE_PROBES_J
+
+libprobes_k_la_SOURCES = $(PROBES_SRC)
+libprobes_k_la_LDFLAGS = $(PROBES_LDF)
+libprobes_k_la_CFLAGS = $(AM_CFLAGS) $(PROBES_CF) -DACTIVATE_PROBES_K
+
+libprobes_l_la_SOURCES = $(PROBES_SRC)
+libprobes_l_la_LDFLAGS = $(PROBES_LDF)
+libprobes_l_la_CFLAGS = $(AM_CFLAGS) $(PROBES_CF) -DACTIVATE_PROBES_L
+
+libprobes_m_la_SOURCES = $(PROBES_SRC)
+libprobes_m_la_LDFLAGS = $(PROBES_LDF)
+libprobes_m_la_CFLAGS = $(AM_CFLAGS) $(PROBES_CF) -DACTIVATE_PROBES_M
+
+libprobes_n_la_SOURCES = $(PROBES_SRC)
+libprobes_n_la_LDFLAGS = $(PROBES_LDF)
+libprobes_n_la_CFLAGS = $(AM_CFLAGS) $(PROBES_CF) -DACTIVATE_PROBES_N
+
+libprobes_o_la_SOURCES = $(PROBES_SRC)
+libprobes_o_la_LDFLAGS = $(PROBES_LDF)
+libprobes_o_la_CFLAGS = $(AM_CFLAGS) $(PROBES_CF) -DACTIVATE_PROBES_O
+
+libprobes_p_la_SOURCES = $(PROBES_SRC)
+libprobes_p_la_LDFLAGS = $(PROBES_LDF)
+libprobes_p_la_CFLAGS = $(AM_CFLAGS) $(PROBES_CF) -DACTIVATE_PROBES_P
+
+libcallsites_1_la_SOURCES = $(CALLSITES_SRC)
+libcallsites_1_la_LDFLAGS = $(CALLSITES_LDF)
+libcallsites_1_la_CFLAGS = $(AM_CFLAGS) $(CALLSITES_CF) -DVALUE=11111
+
+libcallsites_2_la_SOURCES = $(CALLSITES_SRC)
+libcallsites_2_la_LDFLAGS = $(CALLSITES_LDF)
+libcallsites_2_la_CFLAGS = $(AM_CFLAGS) $(CALLSITES_CF) -DVALUE=22222
+
+CLEANFILES=probes.o
+
+all-local:
+       @if [ x"$(srcdir)" != x"$(builddir)" ]; then \
+               for script in $(EXTRA_DIST); do \
+                       cp -f $(srcdir)/$$script $(builddir); \
+               done; \
+       fi
+
+clean-local:
+       @if [ x"$(srcdir)" != x"$(builddir)" ]; then \
+               for script in $(EXTRA_DIST); do \
+                       rm -f $(builddir)/$$script; \
+               done; \
+       fi
diff --git a/tests/regression/ust/multi-lib/README b/tests/regression/ust/multi-lib/README
new file mode 100644 (file)
index 0000000..15b969f
--- /dev/null
@@ -0,0 +1,21 @@
+Those test cases are designed to test the support for loading and unloading
+probe providers and callsites at run time during tracing. One test case also
+tests the event payload comparaison functions.
+
+Testing build artefacts:
+------------------------
+
+./exec-with-callsites
+       Test binary built with tracepoint callsites
+
+./exec-without-callsites
+       Test binary built without tracepoint callsites
+
+/.libs/libprobe_*.so:
+       Libraries containing slight variations of probe providers for the same
+       tracepoint name. Note that the file /.libs/libprobes_a_prime.so has the same
+       content as .libs/libprobes_a.so likewise for libprobes_c_prime.so
+
+/.libs/libcallsites_*.so
+  Libraries containing tracepoint callsites. The user must dlopen the library
+  and use dlsym to get an handle on the function that calls the tracepoint.
diff --git a/tests/regression/ust/multi-lib/callsites.c b/tests/regression/ust/multi-lib/callsites.c
new file mode 100644 (file)
index 0000000..4b61ac2
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) - 2018 Francis Deslauriers <francis.deslauriers@efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#define TRACEPOINT_DEFINE
+#define TRACEPOINT_PROBE_DYNAMIC_LINKAGE
+#include "probes.h"
+
+#include <stdint.h>
+#include <stdio.h>
+#include <time.h>
+#include <pthread.h>
+
+#ifndef VALUE
+#define VALUE (-1)
+#endif
+
+void call_tracepoint(void) {
+       tracepoint(multi, tp, VALUE);
+}
+
diff --git a/tests/regression/ust/multi-lib/callsites.h b/tests/regression/ust/multi-lib/callsites.h
new file mode 100644 (file)
index 0000000..547a6a6
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) - 2018 Francis Deslauriers <francis.deslauriers@efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#ifndef CALLSITES_H
+#define CALLSITES_H
+void call_tracepoint();
+#endif /* CALLSITES_H */
diff --git a/tests/regression/ust/multi-lib/multi-lib-test.c b/tests/regression/ust/multi-lib/multi-lib-test.c
new file mode 100644 (file)
index 0000000..e145aa2
--- /dev/null
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) - 2018 Francis Deslauriers <francis.deslauriers@efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <dlfcn.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <popt.h>
+
+#if HAS_CALLSITES
+#include "callsites.h"
+#endif
+
+void exec_callsite()
+{
+#if HAS_CALLSITES
+       call_tracepoint();
+#endif
+}
+
+void print_list(void)
+{
+       fprintf(stderr, "Test list (-t X):\n");
+       fprintf(stderr, "\t0: dlopen() all libraries pass in arguments and execute "
+                       "the callsite.\n");
+       fprintf(stderr, "\t1: simulate the upgrade of a probe provider using dlopen() and dlclose(). \n");
+       fprintf(stderr, "\t2: simulate the upgrade of a library containing the callsites using dlopen() and dlclose(). \n");
+}
+
+int dl_open_all(int nb_libraries, char **libraries)
+{
+       int i, ret = 0;
+       void **handles;
+
+       handles = malloc(nb_libraries * sizeof(void *));
+       if (!handles) {
+               ret = -1;
+               goto error;
+       }
+
+       /* Iterate over the libs to dlopen and save the handles. */
+       for (i = 0; i < nb_libraries; i++) {
+               handles[i] = dlopen(libraries[i], RTLD_NOW);
+               if (!handles[i]) {
+                       ret = -1;
+                       goto error;
+               }
+       }
+
+       exec_callsite();
+error:
+       free(handles);
+       return ret;
+}
+
+/*
+ * Takes 2 paths to libraries, dlopen() the first, trace, dlopen() the second,
+ * and dlclose the first to simulate the upgrade of a library.
+ */
+int upgrade_lib(int nb_libraries, char **libraries)
+{
+       int i, ret = 0;
+       void *handles[2];
+
+       if (nb_libraries != 2) {
+               ret = -1;
+               goto error;
+       }
+
+       /* Iterate over the libs to dlopen and save the handles. */
+       for (i = 0; i < nb_libraries; i++) {
+               handles[i] = dlopen(libraries[i], RTLD_NOW);
+               if (!handles[i]) {
+                       ret = -1;
+                       goto error;
+               }
+
+               exec_callsite();
+       }
+
+       ret = dlclose(handles[0]);
+       if (ret) {
+               goto error;
+       }
+
+       exec_callsite();
+
+error:
+       return ret;
+}
+
+/*
+ * Simulate the upgrade of a library containing a callsite.
+ * Receives two libraries containing callsites for the same tracepoint.
+ */
+int upgrade_callsite(int nb_libraries, char **libraries)
+{
+       int ret = 0;
+       void *handles[2];
+       void (*fct_ptr[2])(void);
+
+       if (nb_libraries != 2) {
+               ret = -1;
+               goto error;
+       }
+
+       /* Load the probes in the first library. */
+       handles[0] = dlopen(libraries[0], RTLD_NOW);
+       if (!handles[0]) {
+               ret = -1;
+               goto error;
+       }
+
+       /*
+        * Get the pointer to the old function containing the callsite and call it.
+        */
+       fct_ptr[0] = dlsym(handles[0], "call_tracepoint");
+       if (!fct_ptr[0]) {
+               ret = -1;
+               goto error;
+       }
+       fct_ptr[0]();
+
+       /* Load the new callsite library. */
+       handles[1] = dlopen(libraries[1], RTLD_NOW);
+       if (!handles[1]) {
+               ret = -1;
+               goto error;
+       }
+
+       /*
+        * Get the pointer to the new function containing the callsite and call it.
+        */
+       fct_ptr[1] = dlsym(handles[1], "call_tracepoint");
+       if (!fct_ptr[1]) {
+               ret = -1;
+               goto error;
+       }
+       fct_ptr[1]();
+
+       /* Unload the old callsite library. */
+       ret = dlclose(handles[0]);
+       if (ret) {
+               goto error;
+       }
+
+       /* Call the function containing the callsite in the new library. */
+       fct_ptr[1]();
+
+       ret = dlclose(handles[1]);
+       if (ret) {
+               goto error;
+       }
+
+error:
+       return ret;
+}
+
+int main(int argc, const char **argv)
+{
+       int c, ret = 0, test = -1, nb_libraries = 0;
+       char **libraries = NULL;
+       poptContext optCon;
+       struct poptOption optionsTable[] = {
+                       { "test", 't', POPT_ARG_INT, &test, 0, "Test to run", NULL },
+                       { "list", 'l', 0, 0, 'l', "List of tests (-t X)", NULL },
+                       POPT_AUTOHELP
+                       { NULL, 0, 0, NULL, 0 }
+       };
+
+       optCon = poptGetContext(NULL, argc, argv, optionsTable, 0);
+       if (argc < 2) {
+               poptPrintUsage(optCon, stderr, 0);
+               ret = -1;
+               goto error;
+       }
+
+       while ((c = poptGetNextOpt(optCon)) >= 0) {
+               switch(c) {
+               case 'l':
+                       print_list();
+                       goto error;
+               }
+       }
+
+       /*
+        * Populate the libraries array with the arguments passed to the process.
+        */
+       while (poptPeekArg(optCon) != NULL) {
+               nb_libraries++;
+               libraries = realloc(libraries, nb_libraries * sizeof(char *));
+               if (!libraries) {
+                       ret = -1;
+                       goto error;
+               }
+               libraries[nb_libraries - 1] = (char *) poptGetArg(optCon);
+       }
+
+       switch(test) {
+       case 0:
+#if HAS_CALLSITES
+               ret = dl_open_all(nb_libraries, libraries);
+#else
+               fprintf(stderr, "Test not implemented for configuration "
+                               "(HAS_CALLSITES=%d)\n", HAS_CALLSITES == 1);
+#endif
+               break;
+       case 1:
+#if HAS_CALLSITES
+               ret = upgrade_lib(nb_libraries, libraries);
+#else
+               fprintf(stderr, "Test not implemented for configuration "
+                               "(HAS_CALLSITES=%d)\n", HAS_CALLSITES == 1);
+#endif
+               break;
+       case 2:
+#if !HAS_CALLSITES
+               ret = upgrade_callsite(nb_libraries, libraries);
+#else
+               fprintf(stderr, "Test not implemented for configuration "
+                               "(HAS_CALLSITES=%d)\n", HAS_CALLSITES == 1);
+#endif
+               break;
+       default:
+               fprintf(stderr, "Test %d not implemented\n", test);
+               ret = -1;
+               break;
+       }
+error:
+       free(libraries);
+       poptFreeContext(optCon);
+       return ret;
+}
diff --git a/tests/regression/ust/multi-lib/probes.c b/tests/regression/ust/multi-lib/probes.c
new file mode 100644 (file)
index 0000000..3ee9164
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) - 2018 Francis Deslauriers <francis.deslauriers@efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+#define TRACEPOINT_CREATE_PROBES
+#include "probes.h"
diff --git a/tests/regression/ust/multi-lib/probes.h b/tests/regression/ust/multi-lib/probes.h
new file mode 100644 (file)
index 0000000..31e6ec3
--- /dev/null
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) - 2018 Francis Deslauriers <francis.deslauriers@efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#undef TRACEPOINT_PROVIDER
+#define TRACEPOINT_PROVIDER multi
+
+#undef TRACEPOINT_INCLUDE
+#define TRACEPOINT_INCLUDE "./probes.h"
+
+#if !defined(PROBES_H) || defined(TRACEPOINT_HEADER_MULTI_READ)
+#define PROBES_H
+
+#include <lttng/tracepoint.h>
+#include <stdint.h>
+
+#if defined(ACTIVATE_PROBES_A)
+TRACEPOINT_EVENT(multi, tp,
+       TP_ARGS(uint64_t, arg),
+       TP_FIELDS(
+               ctf_integer(uint64_t, arg_long_A, arg)
+       )
+)
+#elif defined(ACTIVATE_PROBES_B)
+TRACEPOINT_EVENT(multi, tp,
+       TP_ARGS(uint64_t, arg),
+       TP_FIELDS(
+               ctf_integer(uint64_t, arg_long_B, arg)
+               ctf_float(float, arg_float_B, (float) arg)
+       )
+)
+#elif defined(ACTIVATE_PROBES_C)
+TRACEPOINT_ENUM(multi, enum_a,
+       TP_ENUM_VALUES(
+               ctf_enum_value("FIELD_A", 0)
+               ctf_enum_value("FIELD_B", 1)
+               ctf_enum_range("RANGE_C", 2, 10)
+       )
+)
+TRACEPOINT_EVENT(multi, tp,
+       TP_ARGS(uint64_t, arg),
+       TP_FIELDS(
+               ctf_enum(multi, enum_a, int16_t, enum_short_C,  0)
+               ctf_enum(multi, enum_a, int32_t, enum_int_C,  1)
+               ctf_enum(multi, enum_a, uint64_t, enum_long_C,  2)
+       )
+)
+#elif defined(ACTIVATE_PROBES_D)
+TRACEPOINT_ENUM(multi, enum_a,
+       TP_ENUM_VALUES(
+               ctf_enum_value("FIELD_A", 0)
+               ctf_enum_value("FIELD_B", 1)
+               ctf_enum_range("RANGE_C_PRIME", 2, 10)
+       )
+)
+TRACEPOINT_EVENT(multi, tp,
+       TP_ARGS(uint64_t, arg),
+       TP_FIELDS(
+       ctf_enum(multi, enum_a, int32_t, enum_int_D,  1)
+               ctf_enum(multi, enum_a, int16_t, enum_short_D,  0)
+               ctf_enum(multi, enum_a, uint64_t, enum_long_D,  2)
+       )
+)
+#elif defined(ACTIVATE_PROBES_E)
+/*
+ * Here we declare tracepoints really similar to one another but are different.
+ * This is meant to test tracepoint comparaison code.
+ */
+TRACEPOINT_EVENT(multi, tp,
+       TP_ARGS(uint64_t, arg),
+       TP_FIELDS(
+               ctf_integer(uint64_t, arg_long, arg)
+       )
+)
+#elif defined(ACTIVATE_PROBES_F)
+TRACEPOINT_EVENT(multi, tp,
+       TP_ARGS(uint64_t, arg),
+       TP_FIELDS(
+               ctf_integer(int64_t, arg_long, arg)
+       )
+)
+#elif defined(ACTIVATE_PROBES_G)
+TRACEPOINT_EVENT(multi, tp,
+       TP_ARGS(uint64_t, arg),
+       TP_FIELDS(
+               ctf_integer_hex(int64_t, arg_long, arg)
+       )
+)
+#elif defined(ACTIVATE_PROBES_H)
+TRACEPOINT_EVENT(multi, tp,
+       TP_ARGS(uint64_t, arg),
+       TP_FIELDS(
+               ctf_integer_hex(int16_t, arg_long, arg)
+       )
+)
+#elif defined(ACTIVATE_PROBES_I)
+TRACEPOINT_EVENT(multi, tp,
+       TP_ARGS(uint64_t, arg),
+       TP_FIELDS(
+               ctf_integer_hex(int32_t, arg_long, arg)
+       )
+)
+#elif defined(ACTIVATE_PROBES_J)
+TRACEPOINT_EVENT(multi, tp,
+       TP_ARGS(uint64_t, arg),
+       TP_FIELDS(
+               ctf_float(float, arg_float, (float) arg)
+       )
+)
+#elif defined(ACTIVATE_PROBES_K)
+TRACEPOINT_EVENT(multi, tp,
+       TP_ARGS(uint64_t, arg),
+       TP_FIELDS(
+               ctf_float(double, arg_float, (double) arg)
+       )
+)
+#elif defined(ACTIVATE_PROBES_L)
+TRACEPOINT_ENUM(multi, enum_a,
+       TP_ENUM_VALUES(
+               ctf_enum_value("FIELD_A", 0)
+               ctf_enum_value("FIELD_B", 1)
+               ctf_enum_range("RANGE_C", 2, 10)
+       )
+)
+TRACEPOINT_EVENT(multi, tp,
+       TP_ARGS(uint64_t, arg),
+       TP_FIELDS(
+               ctf_enum(multi, enum_a, int32_t, enum_int,  1)
+       )
+)
+#elif defined(ACTIVATE_PROBES_M)
+TRACEPOINT_ENUM(multi, enum_a,
+       TP_ENUM_VALUES(
+               ctf_enum_value("FIELD_A", 0)
+               ctf_enum_value("FIELD_B", 1)
+               ctf_enum_range("RANGE_C", 2, 10)
+       )
+)
+TRACEPOINT_EVENT(multi, tp,
+       TP_ARGS(uint64_t, arg),
+       TP_FIELDS(
+       ctf_enum(multi, enum_a, int64_t, enum_int,  1)
+       )
+)
+#elif defined(ACTIVATE_PROBES_N)
+TRACEPOINT_ENUM(multi, enum_a,
+       TP_ENUM_VALUES(
+               ctf_enum_value("FIELD_A", 0)
+               ctf_enum_value("FIELD_B", 1)
+               ctf_enum_range("RANGE_C", 2, 10)
+       )
+)
+TRACEPOINT_EVENT(multi, tp,
+       TP_ARGS(uint64_t, arg),
+       TP_FIELDS(
+               ctf_enum(multi, enum_a, int16_t, enum_int,  1)
+       )
+)
+#elif defined(ACTIVATE_PROBES_O)
+TRACEPOINT_EVENT(multi, tp,
+       TP_ARGS(uint64_t, arg),
+       TP_FIELDS(
+               ctf_string(arg_string, "string")
+       )
+)
+#elif defined(ACTIVATE_PROBES_P)
+TRACEPOINT_EVENT(multi, tp,
+       TP_ARGS(uint64_t, arg),
+       TP_FIELDS(
+               ctf_string(my_arg_string, "string")
+       )
+)
+#else
+TRACEPOINT_EVENT(multi, tp,
+       TP_ARGS(uint64_t, arg),
+       TP_FIELDS(
+       )
+)
+#endif
+
+#endif /* PROBES_H */
+
+#include <lttng/tracepoint-event.h>
diff --git a/tests/regression/ust/multi-lib/test_multi_lib b/tests/regression/ust/multi-lib/test_multi_lib
new file mode 100755 (executable)
index 0000000..d66230a
--- /dev/null
@@ -0,0 +1,262 @@
+#!/bin/bash
+#
+# Copyright (C) - 2018 Francis Deslauriers <francis.deslauriers@efficios.com>
+#
+# This library is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this library; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+
+TEST_DESC="UST - Dynamic loading and unloading of libraries"
+
+CURDIR=$(dirname $0)/
+TESTDIR=$CURDIR/../../..
+SESSION_NAME="multi_lib"
+
+EXEC_NAME_WITH_CALLSITES=./$CURDIR/exec-with-callsites
+EXEC_NAME_WITHOUT_CALLSITES=./$CURDIR/exec-without-callsites
+SO_DIR=$CURDIR/.libs/
+SO_PROBES_A=$SO_DIR/libprobes_a.so
+SO_PROBES_A_PRIME=$SO_DIR/libprobes_a_prime.so
+SO_PROBES_B=$SO_DIR/libprobes_b.so
+SO_PROBES_C=$SO_DIR/libprobes_c.so
+SO_PROBES_C_PRIME=$SO_DIR/libprobes_c_prime.so
+SO_PROBES_D=$SO_DIR/libprobes_d.so
+SO_CALLSITE_1=$SO_DIR/libcallsites_1.so
+SO_CALLSITE_2=$SO_DIR/libcallsites_2.so
+
+NUM_TESTS=55
+
+source $TESTDIR/utils/utils.sh
+
+test_dlopen_same_provider_name_same_event()
+{
+       local event_name="multi:tp"
+       diag "dlopen 2 providers, same event name, same payload"
+
+       enable_ust_lttng_event_ok $SESSION_NAME "$event_name"
+
+       start_lttng_tracing_ok $SESSION_NAME
+
+       $EXEC_NAME_WITH_CALLSITES -t 0 $SO_PROBES_A $SO_PROBES_A_PRIME
+
+       stop_lttng_tracing_ok $SESSION_NAME
+
+       # Expect 2 identical events in the trace
+       trace_match_only $event_name 2 $TRACE_PATH
+
+       # Expect a single event ID in the metadata
+       validate_metadata_event $event_name 1 $TRACE_PATH
+
+       return $?
+}
+
+test_dlopen_same_provider_name_different_event()
+{
+       local event_name="multi:tp"
+       # Regular expression for event tp with one argument: arg_long
+       local event_a_payload_exp="^.*$event_name.*arg_long_A.*"
+       # Regular expression for event tp with two arguments: arg_long and
+       # arg_float
+       local event_b_payload_exp="^.*$event_name.*arg_long_B.*arg_float_B.*"
+       diag "dlopen 2 providers, same event name, different payload"
+
+       enable_ust_lttng_event_ok $SESSION_NAME "$event_name"
+
+       start_lttng_tracing_ok $SESSION_NAME
+
+       $EXEC_NAME_WITH_CALLSITES -t 0 $SO_PROBES_A $SO_PROBES_B
+
+       stop_lttng_tracing_ok $SESSION_NAME
+
+       # Expect 2 identical events in the trace
+       trace_match_only $event_name 2 $TRACE_PATH
+
+       # Expect 2 events ID in the metadata
+       validate_metadata_event $event_name 2 $TRACE_PATH
+
+       # Expect 2 events with different payloads
+       validate_trace_exp $event_a_payload_exp $TRACE_PATH
+       validate_trace_exp $event_b_payload_exp $TRACE_PATH
+
+       return $?
+}
+
+test_dlopen_same_provider_name_same_enum()
+{
+       local event_name="multi:tp"
+       # Regular expression for event tp with one argument: arg_long
+       local event_c_payload_exp="^.*$event_name.*enum_int_C.*"
+       # Regular expression for event tp with two arguments: arg_long and
+       # arg_float
+       local event_d_payload_exp="^.*$event_name.*enum_int_D.*"
+       diag "dlopen 2 providers, same event name, same enum definition"
+
+       enable_ust_lttng_event_ok $SESSION_NAME "$event_name"
+
+       start_lttng_tracing_ok $SESSION_NAME
+
+       $EXEC_NAME_WITH_CALLSITES -t 0 $SO_PROBES_C $SO_PROBES_C_PRIME
+
+       stop_lttng_tracing_ok $SESSION_NAME
+
+       # Expect 2 identical events in the trace
+       trace_match_only $event_name 2 $TRACE_PATH
+
+       # Expect 2 events ID in the metadata
+       validate_metadata_event $event_name 1 $TRACE_PATH
+
+       return $?
+}
+
+test_dlopen_same_provider_name_different_enum()
+{
+       local event_name="multi:tp"
+       # Regular expression for event tp with one argument: arg_long
+       local event_c_payload_exp="^.*$event_name.*enum_int_C.*"
+       # Regular expression for event tp with two arguments: arg_long and
+       # arg_float
+       local event_d_payload_exp="^.*$event_name.*enum_int_D.*"
+       diag "dlopen 2 providers, same event name, different enum definition"
+
+       enable_ust_lttng_event_ok $SESSION_NAME "$event_name"
+
+       start_lttng_tracing_ok $SESSION_NAME
+
+       $EXEC_NAME_WITH_CALLSITES -t 0 $SO_PROBES_C $SO_PROBES_D
+
+       stop_lttng_tracing_ok $SESSION_NAME
+
+       # Expect 2 identical events in the trace
+       trace_match_only $event_name 2 $TRACE_PATH
+
+       # Expect 2 events ID in the metadata
+       validate_metadata_event $event_name 2 $TRACE_PATH
+
+       # Expect 2 events with different payloads
+       validate_trace_exp $event_c_payload_exp $TRACE_PATH
+       validate_trace_exp $event_d_payload_exp $TRACE_PATH
+
+       return $?
+}
+
+test_upgrade_probes_dlopen_dclose()
+{
+       local event_name="multi:tp"
+       diag "Upgrade probe provider using dlopen/dlclose during tracing"
+
+       enable_ust_lttng_event_ok $SESSION_NAME "$event_name"
+
+       start_lttng_tracing_ok $SESSION_NAME
+
+       $EXEC_NAME_WITH_CALLSITES -t 1 $SO_PROBES_A $SO_PROBES_B
+
+       stop_lttng_tracing_ok $SESSION_NAME
+
+       # Expect 2 identical events in the trace
+       trace_match_only $event_name 4 $TRACE_PATH
+
+       # Expect 2 events ID in the metadata
+       validate_metadata_event $event_name 2 $TRACE_PATH
+
+       return $?
+}
+
+test_upgrade_callsites_dlopen_dclose()
+{
+       local event_name="multi:tp"
+       diag "Upgrade callsite using dlopen/dlclose during tracing"
+
+       enable_ust_lttng_event_ok $SESSION_NAME "$event_name"
+
+       start_lttng_tracing_ok $SESSION_NAME
+
+       $EXEC_NAME_WITHOUT_CALLSITES -t 2 $SO_CALLSITE_1 $SO_CALLSITE_2
+
+       stop_lttng_tracing_ok $SESSION_NAME
+
+       # Expect 2 identical events in the trace
+       trace_match_only $event_name 3 $TRACE_PATH
+
+       # Expect 2 events ID in the metadata
+       validate_metadata_event $event_name 1 $TRACE_PATH
+
+       return $?
+}
+
+test_event_field_comparison()
+{
+       local event_name="multi:tp"
+       diag "Load mutliple events with slight variations in the field descriptions."
+
+       local library_prefix="libprobes_"
+       local nb_libs=0
+       local library_list=" "
+       # Concatenate all the probe libraries in a string.
+       for postfix in {a..p}; do
+               library_list="$library_list $SO_DIR/$library_prefix$postfix.so"
+               let nb_libs+=1
+       done
+
+       enable_ust_lttng_event_ok $SESSION_NAME "$event_name"
+
+       start_lttng_tracing_ok $SESSION_NAME
+
+       $EXEC_NAME_WITH_CALLSITES -t 0 $library_list
+
+       stop_lttng_tracing_ok $SESSION_NAME
+
+       # Expect $nb_libs identical events in the trace
+       trace_match_only $event_name $nb_libs $TRACE_PATH
+
+       # Expect $nb_libs events ID in the metadata
+       validate_metadata_event $event_name $nb_libs $TRACE_PATH
+
+       return $?
+}
+
+
+plan_tests $NUM_TESTS
+
+print_test_banner "$TEST_DESC"
+
+TESTS=(
+       "test_dlopen_same_provider_name_same_event"
+       "test_dlopen_same_provider_name_different_event"
+       "test_dlopen_same_provider_name_different_enum"
+       "test_dlopen_same_provider_name_same_enum"
+       "test_event_field_comparison"
+       "test_upgrade_probes_dlopen_dclose"
+       "test_upgrade_callsites_dlopen_dclose"
+)
+
+TEST_COUNT=${#TESTS[@]}
+i=0
+
+start_lttng_sessiond
+
+while [ "$i" -lt "$TEST_COUNT" ]; do
+
+       TRACE_PATH=$(mktemp -d)
+
+       create_lttng_session_ok $SESSION_NAME $TRACE_PATH
+
+       # Execute test
+       ${TESTS[$i]}
+
+       destroy_lttng_session_ok $SESSION_NAME
+
+       rm -rf $TRACE_PATH
+
+       let "i++"
+done
+
+stop_lttng_sessiond
This page took 0.039466 seconds and 5 git commands to generate.