From: "Tzvetomir Stoyanov (VMware)" <tz.stoyanov@gmail.com>
To: rostedt@goodmis.org
Cc: linux-trace-devel@vger.kernel.org
Subject: [PATCH 4/9] trace-cmd: Unit test for libtracefs
Date: Wed, 29 Jan 2020 11:54:16 +0200 [thread overview]
Message-ID: <20200129095421.881786-5-tz.stoyanov@gmail.com> (raw)
In-Reply-To: <20200129095421.881786-1-tz.stoyanov@gmail.com>
The CUnit test infrastructure is integrated in trace-cmd.
http://cunit.sourceforge.net/
The library and its headers must be installed on the machine, in order
to build the trace-cmd unit tests. For Fedora, these packages must be installed:
CUnit, CUnit-devel
A new directory is added:
utest
containing unit tests implementation.
Added new target to trace-cmd top Makefile:
make test
which builds the unit test binary:
utest/trace-utest
The goal of this patch is not to provide full unit test coverage of
libtracefs, but to be a POC for adding test infrastructure to trace-cmd.
The first API, covered be the test is:
tracefs_iterate_raw_events()
Signed-off-by: Tzvetomir Stoyanov (VMware) <tz.stoyanov@gmail.com>
---
Makefile | 13 ++++-
utest/Makefile | 41 ++++++++++++++
utest/README | 15 +++++
utest/trace-utest.c | 83 ++++++++++++++++++++++++++++
utest/trace-utest.h | 11 ++++
utest/tracefs-utest.c | 125 ++++++++++++++++++++++++++++++++++++++++++
6 files changed, 286 insertions(+), 2 deletions(-)
create mode 100644 utest/Makefile
create mode 100644 utest/README
create mode 100644 utest/trace-utest.c
create mode 100644 utest/trace-utest.h
create mode 100644 utest/tracefs-utest.c
diff --git a/Makefile b/Makefile
index 477625f..ddf52ea 100644
--- a/Makefile
+++ b/Makefile
@@ -200,7 +200,7 @@ TRACE_LIBS = -L$(LIBTRACECMD_DIR) -ltracecmd \
-L$(LIBTRACEFS_DIR) -ltracefs
export LIBS TRACE_LIBS
-export LIBTRACEEVENT_DIR LIBTRACECMD_DIR
+export LIBTRACEEVENT_DIR LIBTRACECMD_DIR LIBTRACEFS_DIR
export LIBTRACECMD_STATIC LIBTRACECMD_SHARED
export LIBTRACEEVENT_STATIC LIBTRACEEVENT_SHARED
export LIBTRACEFS_STATIC LIBTRACEFS_SHARED
@@ -234,6 +234,9 @@ ifeq ($(VSOCK_DEFINED), 1)
CFLAGS += -DVSOCK
endif
+CUNIT_INSTALLED := $(shell if (echo -e "\#include <CUnit/Basic.h>\n void main(){CU_initialize_registry();}" | $(CC) -x c -lcunit - >/dev/null 2>&1) ; then echo 1; else echo 0 ; fi)
+export CUNIT_INSTALLED
+
export CFLAGS
export INCLUDES
@@ -319,7 +322,6 @@ $(LIBTRACEFS_STATIC): force
$(LIBTRACEFS_SHARED): force
$(Q)$(MAKE) -C $(src)/lib/tracefs $@
-
libtraceevent.so: $(LIBTRACEEVENT_SHARED)
libtraceevent.a: $(LIBTRACEEVENT_STATIC)
libtracecmd.a: $(LIBTRACECMD_STATIC)
@@ -329,6 +331,12 @@ libtracefs.so: $(LIBTRACEFS_SHARED)
libs: $(LIBTRACECMD_SHARED) $(LIBTRACEEVENT_SHARED) $(LIBTRACEFS_SHARED)
+test: force $(LIBTRACEEVENT_STATIC) $(LIBTRACEFS_STATIC) $(LIBTRACECMD_STATIC)
+ifneq ($(CUNIT_INSTALLED),1)
+ $(error CUnit framework not installed, cannot build unit tests))
+endif
+ $(Q)$(MAKE) -C $(src)/utest $@
+
plugins_traceevent: force $(obj)/lib/traceevent/plugins/traceevent_plugin_dir \
$(obj)/lib/traceevent/plugins/trace_python_dir
$(Q)$(MAKE) -C $(src)/lib/traceevent/plugins
@@ -430,6 +438,7 @@ clean:
$(MAKE) -C $(src)/lib/tracefs clean
$(MAKE) -C $(src)/lib/traceevent/plugins clean
$(MAKE) -C $(src)/lib/trace-cmd/plugins clean
+ $(MAKE) -C $(src)/utest clean
$(MAKE) -C $(src)/python clean
$(MAKE) -C $(src)/tracecmd clean
if [ -f $(kshark-dir)/build/Makefile ]; then $(MAKE) -C $(kshark-dir)/build clean; fi
diff --git a/utest/Makefile b/utest/Makefile
new file mode 100644
index 0000000..55aa46a
--- /dev/null
+++ b/utest/Makefile
@@ -0,0 +1,41 @@
+
+include $(src)/scripts/utils.mk
+
+bdir:=$(obj)/utest
+
+TARGETS = $(bdir)/trace-utest
+
+OBJS =
+OBJS += trace-utest.o
+OBJS += tracefs-utest.o
+
+LIBS += -lcunit \
+ -L$(LIBTRACEFS_DIR) -ltracefs \
+ -L$(LIBTRACEEVENT_DIR) -ltraceevent
+
+OBJS := $(OBJS:%.o=$(bdir)/%.o)
+DEPS := $(OBJS:$(bdir)/%.o=$(bdir)/.%.d)
+
+$(bdir):
+ @mkdir -p $(bdir)
+
+$(OBJS): | $(bdir)
+$(DEPS): | $(bdir)
+
+$(bdir)/trace-utest: $(OBJS)
+ $(Q)$(do_app_build)
+
+$(bdir)/%.o: %.c
+ $(Q)$(call do_fpic_compile)
+
+$(DEPS): $(bdir)/.%.d: %.c
+ $(Q)$(CC) -M $(CPPFLAGS) $(CFLAGS) $< > $@
+
+$(OBJS): $(bdir)/%.o : $(bdir)/.%.d
+
+dep_includes := $(wildcard $(DEPS))
+
+test: $(TARGETS)
+
+clean:
+ $(RM) $(TARGETS) $(bdir)/*.o $(bdir)/.*.d
diff --git a/utest/README b/utest/README
new file mode 100644
index 0000000..f93630d
--- /dev/null
+++ b/utest/README
@@ -0,0 +1,15 @@
+
+Unit tests for trace-cmd libraries. The tests use CUnit framework:
+ http://cunit.sourceforge.net/
+which must be pre installed on the system, before building the unit tests.
+The framework can be downloaded, compiled and installed manually, or
+using a precompiled distro package:
+
+ Fedora:
+ CUnit
+ CUnit-devel
+
+ Ubuntu and Debian:
+ libcunit1
+ libcunit1-doc
+ libcunit1-dev
diff --git a/utest/trace-utest.c b/utest/trace-utest.c
new file mode 100644
index 0000000..58d4d4e
--- /dev/null
+++ b/utest/trace-utest.c
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: LGPL-2.1
+/*
+ * Copyright (C) 2020, VMware, Tzvetomir Stoyanov <tz.stoyanov@gmail.com>
+ *
+ */
+#include <stdio.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <stdlib.h>
+
+#include <CUnit/CUnit.h>
+#include <CUnit/Basic.h>
+
+#include "trace-utest.h"
+
+enum unit_tests {
+ RUN_NONE = 0,
+ RUN_TRACEFS = (1 << 0),
+ RUN_ALL = 0xFFFF
+};
+
+static void print_help(char **argv)
+{
+ printf("Usage: %s [OPTIONS]\n", basename(argv[0]));
+ printf("\t-s, --silent\tPrint test summary\n");
+ printf("\t-r, --run test\tRun specific test:\n");
+ printf("\t\t tracefs run libtracefs tests\n");
+ printf("\t-h, --help\tPrint usage information\n");
+ exit(0);
+}
+
+int main(int argc, char **argv)
+{
+ CU_BasicRunMode verbose = CU_BRM_VERBOSE;
+ enum unit_tests tests = RUN_NONE;
+
+ for (;;) {
+ int c;
+ int index = 0;
+ const char *opts = "+hsr:";
+ static struct option long_options[] = {
+ {"silent", no_argument, NULL, 's'},
+ {"run", required_argument, NULL, 'r'},
+ {"help", no_argument, NULL, 'h'},
+ {NULL, 0, NULL, 0}
+ };
+
+ c = getopt_long (argc, argv, opts, long_options, &index);
+ if (c == -1)
+ break;
+ switch (c) {
+ case 'r':
+ if (strcmp(optarg, "tracefs") == 0)
+ tests |= RUN_TRACEFS;
+ else
+ print_help(argv);
+ break;
+ case 's':
+ verbose = CU_BRM_SILENT;
+ break;
+ case 'h':
+ default:
+ print_help(argv);
+ break;
+ }
+ }
+
+ if (tests == RUN_NONE)
+ tests = RUN_ALL;
+
+ if (CU_initialize_registry() != CUE_SUCCESS) {
+ printf("Test registry cannot be initialized\n");
+ return -1;
+ }
+
+ if (tests & RUN_TRACEFS)
+ test_tracefs_lib();
+
+ CU_basic_set_mode(verbose);
+ CU_basic_run_tests();
+ CU_cleanup_registry();
+ return 0;
+}
diff --git a/utest/trace-utest.h b/utest/trace-utest.h
new file mode 100644
index 0000000..917c0e7
--- /dev/null
+++ b/utest/trace-utest.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: LGPL-2.1 */
+/*
+ * Copyright (C) 2020, VMware, Tzvetomir Stoyanov <tz.stoyanov@gmail.com>
+ *
+ */
+#ifndef _TRACE_UTEST_H_
+#define _TRACE_UTEST_H_
+
+void test_tracefs_lib(void);
+
+#endif /* _TRACE_UTEST_H_ */
diff --git a/utest/tracefs-utest.c b/utest/tracefs-utest.c
new file mode 100644
index 0000000..d3ba213
--- /dev/null
+++ b/utest/tracefs-utest.c
@@ -0,0 +1,125 @@
+// SPDX-License-Identifier: LGPL-2.1
+/*
+ * Copyright (C) 2020, VMware, Tzvetomir Stoyanov <tz.stoyanov@gmail.com>
+ *
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <CUnit/CUnit.h>
+#include <CUnit/Basic.h>
+
+#include "tracefs.h"
+
+#define TRACEFS_SUITE "trasefs library"
+#define TEST_INSTANCE_NAME "cunit_test_iter"
+#define TEST_ARRAY_SIZE 50
+
+static struct tracefs_instance *test_instance;
+static struct tep_handle *test_tep;
+static int test_array[TEST_ARRAY_SIZE];
+static int test_found;
+
+static int test_callback(struct tep_event *event, struct tep_record *record,
+ int cpu, void *context)
+{
+ struct tep_format_field *field;
+ int val, i;
+
+ field = tep_find_field(event, "buf");
+ if (field) {
+ val = *((int *)(record->data + field->offset));
+ for (i = 0; i < TEST_ARRAY_SIZE; i++) {
+ if (test_array[i] == val) {
+ test_array[i] = 0;
+ test_found++;
+ break;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static void test_iter_write(void)
+{
+ char *path;
+ int i, fd;
+ int ret;
+
+ path = tracefs_instance_get_file(test_instance, "trace_marker");
+ CU_TEST(path != NULL);
+ fd = open(path, O_WRONLY);
+ CU_TEST(fd >= 0);
+
+ for (i = 0; i < TEST_ARRAY_SIZE; i++) {
+ test_array[i] = random();
+ ret = write(fd, test_array + i, sizeof(int));
+ CU_TEST(ret == sizeof(int));
+ }
+
+ tracefs_put_tracing_file(path);
+ close(fd);
+}
+
+
+static void test_iter_raw_events(void)
+{
+ int ret;
+
+ ret = tracefs_iterate_raw_events(NULL, test_instance, test_callback, NULL);
+ CU_TEST(ret < 0);
+ ret = tracefs_iterate_raw_events(test_tep, NULL, test_callback, NULL);
+ CU_TEST(ret == 0);
+ ret = tracefs_iterate_raw_events(test_tep, test_instance, NULL, NULL);
+ CU_TEST(ret < 0);
+
+ test_found = 0;
+ test_iter_write();
+ ret = tracefs_iterate_raw_events(test_tep, test_instance,
+ test_callback, NULL);
+ CU_TEST(ret == 0);
+ CU_TEST(test_found == TEST_ARRAY_SIZE);
+}
+
+static int test_suite_destroy(void)
+{
+ tracefs_instance_destroy(test_instance);
+ tracefs_instance_free(test_instance);
+ tep_free(test_tep);
+ return 0;
+}
+
+static int test_suite_init(void)
+{
+ const char *systems[] = {"ftrace", NULL};
+
+ test_tep = tracefs_local_events_system(NULL, systems);
+ if (test_tep == NULL)
+ return 1;
+
+ test_instance = tracefs_instance_alloc(TEST_INSTANCE_NAME);
+ if (test_instance == NULL)
+ return 1;
+
+ if (tracefs_instance_create(test_instance) < 0)
+ return 1;
+
+ return 0;
+}
+
+void test_tracefs_lib(void)
+{
+ CU_pSuite suite = NULL;
+
+ suite = CU_add_suite(TRACEFS_SUITE, test_suite_init, test_suite_destroy);
+ if (suite == NULL) {
+ fprintf(stderr, "Suite \"%s\" cannot be ceated\n", TRACEFS_SUITE);
+ return;
+ }
+ CU_add_test(suite, "tracefs_iterate_raw_events API",
+ test_iter_raw_events);
+}
--
2.24.1
next prev parent reply other threads:[~2020-01-29 9:54 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-01-29 9:54 [PATCH 0/9] libtracefs: few fixes and a lot of unit tests Tzvetomir Stoyanov (VMware)
2020-01-29 9:54 ` [PATCH 1/9] trace-cmd: fix description of tracefs_get_tracing_dir() API Tzvetomir Stoyanov (VMware)
2020-01-29 9:54 ` [PATCH 2/9] trace-cmd: Remove tracefs_read_page_record() API Tzvetomir Stoyanov (VMware)
2020-01-29 9:54 ` [PATCH 3/9] trace-cmd: Add sanity check of tracefs_get_tracing_file() input parameter Tzvetomir Stoyanov (VMware)
2020-01-29 9:54 ` Tzvetomir Stoyanov (VMware) [this message]
2020-01-29 9:54 ` [PATCH 5/9] trace-cmd: Unit tests for libtracefs APIs related to tracing file / directory Tzvetomir Stoyanov (VMware)
2020-01-29 9:54 ` [PATCH 6/9] trace-cmd: Unit tests for libtracefs APIs related to ftrace instances Tzvetomir Stoyanov (VMware)
2020-01-29 9:54 ` [PATCH 7/9] trace-cmd: Unit tests for libtracefs APIs related to ftrace events and systems Tzvetomir Stoyanov (VMware)
2020-01-29 9:54 ` [PATCH 8/9] trace-cmd: Unit test for tracefs_tracers() API Tzvetomir Stoyanov (VMware)
2020-01-29 9:54 ` [PATCH 9/9] trace-cmd: Unit tests for libtracefs APIs related to allocating a tep handler based on local events Tzvetomir Stoyanov (VMware)
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200129095421.881786-5-tz.stoyanov@gmail.com \
--to=tz.stoyanov@gmail.com \
--cc=linux-trace-devel@vger.kernel.org \
--cc=rostedt@goodmis.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).