aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Benjamin Barenblat <bbarenblat@galois.com>2014-01-27 15:15:43 -0800
committerGravatar Benjamin Barenblat <bbarenblat@galois.com>2014-01-27 15:17:06 -0800
commitbb3a3a61fe7b971ad8ef326ec7e4d5903e6860ee (patch)
tree1e7cb626e710d0cf1888ee89f45e65afb5b41a13
parentecdc86999a7eb30223209887801ec8bbeac1cc9e (diff)
Functional tests for C library
While gearing up to make an addition to the C library, I became concerned at the lack of test infrastructure for the project. The build system now integrates Check <http://check.sourceforge.net/>;, a lightweight testing framework for C, and there are a few tests to ensure no serious regressions occur. You can run the tests with “make check”.
-rw-r--r--Makefile.am2
-rw-r--r--configure.ac24
-rw-r--r--test/Makefile.am41
-rw-r--r--test/check_ppamltracer.c230
-rw-r--r--test/tmpdir.c92
-rw-r--r--test/tmpdir.h51
-rw-r--r--test/trace_invalid.c70
-rw-r--r--test/trace_invalid.h55
-rw-r--r--test/trace_valid.c76
-rw-r--r--test/trace_valid.h55
10 files changed, 694 insertions, 2 deletions
diff --git a/Makefile.am b/Makefile.am
index d46630e..d129516 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -20,7 +20,7 @@
ACLOCAL_AMFLAGS = -I m4
-SUBDIRS = include src
+SUBDIRS = include src test
EXTRA_DIST = Doxyfile bindings examples
dist-hook:
$(RM) `find $(distdir) -type f -name .gitignore`
diff --git a/configure.ac b/configure.ac
index 0b4b5fa..3e3a1d8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -60,11 +60,33 @@ DX_PDF_FEATURE(OFF)
DX_PS_FEATURE(OFF)
DX_INIT_DOXYGEN([ppamltracer], [Doxyfile], [doc])
+# Tests
+AC_CHECK_HEADERS([ftw.h unistd.h sys/stat.h time.h])
+AC_CHECK_TYPES(
+ [struct FTW],
+ [],
+ [],
+ [[#define _XOPEN_SOURCE 500
+#include <ftw.h>]])
+AC_CHECK_TYPES(
+ [struct timespec],
+ [],
+ [],
+ [[#define _POSIX_C_SOURCE 199309L
+#include <time.h>]])
+AC_CHECK_FUNCS([mkdtemp nanosleep nftw])
+PKG_CHECK_MODULES([check], [check >= 0.9.4],
+ [],
+ [AC_MSG_WARN([check not found; `make check' will fail])])
+AC_SUBST([check_CFLAGS])
+AC_SUBST([check_LIBS])
+
# Generate Makefiles and pkg-config file.
AC_CONFIG_FILES([
Makefile
src/Makefile
- include/Makefile])
+ include/Makefile
+ test/Makefile])
AC_CONFIG_FILES([ppamltracer.pc])
# All done.
diff --git a/test/Makefile.am b/test/Makefile.am
new file mode 100644
index 0000000..b5e30d5
--- /dev/null
+++ b/test/Makefile.am
@@ -0,0 +1,41 @@
+# Makefile.am -- automake script for ppamltracer tests
+# Copyright (C) 2013 Galois, Inc.
+#
+# This program is free software: you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free Software
+# Foundation, either version 3 of the License, or (at your option) any later
+# version.
+#
+# This program 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 General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# To contact Galois, complete the Web form at <http://corp.galois.com/contact/>
+# or write to Galois, Inc., 421 Southwest 6th Avenue, Suite 300, Portland,
+# Oregon, 97204-1622.
+
+TESTS = check_ppamltracer
+check_PROGRAMS = check_ppamltracer
+check_ppamltracer_SOURCES = \
+ check_ppamltracer.c \
+ tmpdir.c \
+ tmpdir.h \
+ trace_invalid.c \
+ trace_invalid.h \
+ trace_valid.c \
+ trace_valid.h
+check_ppamltracer_CFLAGS = \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/src \
+ -std=c99 \
+ -Wall \
+ -Wextra \
+ -pedantic \
+ @check_CFLAGS@
+check_ppamltracer_LDADD = \
+ $(top_builddir)/src/libppamltracer.la \
+ @check_LIBS@
diff --git a/test/check_ppamltracer.c b/test/check_ppamltracer.c
new file mode 100644
index 0000000..73a4631
--- /dev/null
+++ b/test/check_ppamltracer.c
@@ -0,0 +1,230 @@
+/* check_ppamltracer.c -- test program for ppamltracer
+ * Copyright (C) 2014 Galois, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option)
+ * any later version.
+ *
+ * This program 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 General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * To contact Galois, complete the Web form at
+ * <http://corp.galois.com/contact/> or write to Galois, Inc., 421 Southwest
+ * 6th Avenue, Suite 300, Portland, Oregon, 97204-1622. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define _POSIX_C_SOURCE 199309L
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if HAVE_TIME_H
+# include <time.h>
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#include <check.h>
+
+#include <otf.h>
+#include <ppaml/tracer.h>
+
+#include "tmpdir.h"
+#include "trace_invalid.h"
+#include "trace_valid.h"
+
+#define ignore(x) ((void)(x))
+
+#if (HAVE_FIXTURE_tmpdir && HAVE_FIXTURE_trace_invalid && HAVE_UNISTD_H)
+# define HAVE_TEST_init_creates_trace
+ START_TEST(test_init_creates_trace)
+ {
+ char index_file[128];
+ strcpy(index_file, trace_invalid_path());
+ strcat(index_file, ".otf");
+ ck_assert(access(index_file, F_OK) == 0);
+ }
+ END_TEST
+#endif
+
+#if (HAVE_FIXTURE_tmpdir && HAVE_FIXTURE_trace_valid)
+# define HAVE_TEST_simple_creates_valid_trace
+ START_TEST(test_simple_creates_valid_trace)
+ {
+ OTF_FileManager *const manager = OTF_FileManager_open(16);
+ ck_assert_msg(manager != NULL, otf_strerr);
+ OTF_Reader *const reader =
+ OTF_Reader_open(trace_valid_path(), manager);
+ ck_assert_msg(reader != NULL, otf_strerr);
+ ck_assert_msg(OTF_Reader_close(reader) == 1, otf_strerr);
+ OTF_FileManager_close(manager);
+ }
+ END_TEST
+
+# define HAVE_TEST_simple_defines_main
+ START_TEST(test_simple_defines_main)
+ {
+ OTF_FileManager *const manager = OTF_FileManager_open(16);
+ ck_assert_msg(manager != NULL, otf_strerr);
+ OTF_Reader *const reader =
+ OTF_Reader_open(trace_valid_path(), manager);
+ ck_assert_msg(reader != NULL, otf_strerr);
+ ck_assert_msg(OTF_Reader_close(reader) == 1, otf_strerr);
+ OTF_FileManager_close(manager);
+ }
+ END_TEST
+#endif
+
+#if (HAVE_FIXTURE_tmpdir && HAVE_TIME_H)
+# define HAVE_TEST_trace_accurate_timing
+ static uint64_t test_trace_accurate_timing_delta;
+
+ static int test_trace_accurate_timing_handle_enter(
+ void *const userData,
+ const uint64_t time,
+ const uint32_t function,
+ const uint32_t process,
+ const uint32_t source)
+ {
+ ignore(userData);
+ ignore(function);
+ ignore(process);
+ ignore(source);
+ test_trace_accurate_timing_delta = time;
+ return OTF_RETURN_OK;
+ }
+
+ static int test_trace_accurate_timing_handle_exit(
+ void *const userData,
+ const uint64_t time,
+ const uint32_t function,
+ const uint32_t process,
+ const uint32_t source)
+ {
+ ignore(userData);
+ ignore(function);
+ ignore(process);
+ ignore(source);
+ test_trace_accurate_timing_delta =
+ time - test_trace_accurate_timing_delta;
+ return OTF_RETURN_OK;
+ }
+
+ START_TEST(test_trace_accurate_timing)
+ {
+ // Create the trace.
+ char trace_base[128];
+ strcpy(trace_base, tmpdir_name());
+ strcat(trace_base, "/trace");
+ ppaml_tracer_t tracer;
+ ck_assert(
+ ppaml_tracer_init(&tracer, trace_base) == 0);
+ ppaml_phase_t phase;
+ ck_assert(
+ ppaml_phase_init(&tracer, &phase, "test phase") == 0);
+ // Time a single phase.
+ ck_assert(ppaml_phase_start(&phase) == 0);
+ const struct timespec hundred_ms =
+ { .tv_sec = 0, .tv_nsec = 100000000 };
+ nanosleep(&hundred_ms, NULL);
+ ck_assert(ppaml_phase_stop(&phase) == 0);
+ // Clean up and close the trace.
+ ck_assert(ppaml_phase_done(&phase) == 0);
+ ck_assert(ppaml_tracer_done(&tracer) == 0);
+ /* Verify that the delta is about 100 ms (100,000 ticks of the
+ * tracer timer). */
+ OTF_FileManager *const manager = OTF_FileManager_open(16);
+ ck_assert_msg(manager != NULL, otf_strerr);
+ OTF_Reader *const reader =
+ OTF_Reader_open(trace_base, manager);
+ ck_assert_msg(reader != NULL, otf_strerr);
+ OTF_HandlerArray *const handlers = OTF_HandlerArray_open();
+ ck_assert_msg(handlers != NULL, otf_strerr);
+ ck_assert_msg(
+ OTF_HandlerArray_setHandler(
+ handlers,
+ (OTF_FunctionPointer *)test_trace_accurate_timing_handle_enter,
+ OTF_ENTER_RECORD)
+ == 1,
+ otf_strerr);
+ ck_assert_msg(
+ OTF_HandlerArray_setHandler(
+ handlers,
+ (OTF_FunctionPointer *)test_trace_accurate_timing_handle_exit,
+ OTF_LEAVE_RECORD)
+ == 1,
+ otf_strerr);
+ ck_assert_msg(
+ OTF_Reader_readEvents(reader, handlers) != OTF_READ_ERROR,
+ otf_strerr);
+ /* Require less than +/- 10% to pass. Yes, this is an
+ * arbitrary metric, but it should trigger if there's a serious
+ * regression. */
+ ck_assert_msg(
+ 90000 <= test_trace_accurate_timing_delta,
+ "timed interval (%d us) is more than 10%% fast",
+ test_trace_accurate_timing_delta);
+ ck_assert_msg(test_trace_accurate_timing_delta < 110000,
+ "timed interval (%d us) is more than 10%% slow",
+ test_trace_accurate_timing_delta);
+ // All done.
+ ck_assert_msg(
+ OTF_HandlerArray_close(handlers) == 1, otf_strerr);
+ ck_assert_msg(OTF_Reader_close(reader) == 1, otf_strerr);
+ OTF_FileManager_close(manager);
+ }
+ END_TEST
+#endif
+
+Suite *ppamltracer_suite()
+{
+ Suite *const s = suite_create("ppamltracer");
+ // Test case: init
+ TCase *tc = tcase_create("init");
+ tmpdir_add_checked(tc);
+ trace_invalid_add_checked(tc);
+# ifdef HAVE_TEST_init_creates_trace
+ tcase_add_test(tc, test_init_creates_trace);
+# endif
+ suite_add_tcase(s, tc);
+ // Test case: valid
+ tc = tcase_create("valid");
+ tmpdir_add_checked(tc);
+ trace_valid_add_checked(tc);
+# ifdef HAVE_TEST_simple_creates_valid_trace
+ tcase_add_test(tc, test_simple_creates_valid_trace);
+# endif
+# ifdef HAVE_TEST_simple_defines_main
+ tcase_add_test(tc, test_simple_defines_main);
+# endif
+ suite_add_tcase(s, tc);
+ // Test case: timing-accurate
+ tc = tcase_create("accurate");
+ tmpdir_add_checked(tc);
+# ifdef HAVE_TEST_trace_accurate_timing
+ tcase_add_test(tc, test_trace_accurate_timing);
+# endif
+ suite_add_tcase(s, tc);
+ return s;
+}
+
+int main()
+{
+ Suite *const s = ppamltracer_suite();
+ SRunner *const runner = srunner_create(s);
+ srunner_run_all(runner, CK_NORMAL);
+ const int n_failed = srunner_ntests_failed(runner);
+ srunner_free(runner);
+ return (n_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
diff --git a/test/tmpdir.c b/test/tmpdir.c
new file mode 100644
index 0000000..5d0c4d0
--- /dev/null
+++ b/test/tmpdir.c
@@ -0,0 +1,92 @@
+/* tmpdir.c -- fixture to create a temporary directory
+ * Copyright (C) 2010 caf <https://stackoverflow.com/users/134633>
+ * Copyright (C) 2014 Galois, Inc.
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option)
+ * any later version.
+ *
+ * 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 General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * To contact Galois, complete the Web form at
+ * <http://corp.galois.com/contact/> or write to Galois, Inc., 421 Southwest
+ * 6th Avenue, Suite 300, Portland, Oregon, 97204-1622. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define _POSIX_C_SOURCE 200809L // mkdtemp(3)
+
+/* This is a bit out of order, but it needs to go here, before *any* includes
+ * are done, so that they can catch _XOPEN_SOURCE. */
+#if HAVE_FTW_H
+# define _XOPEN_SOURCE 500
+# include <ftw.h>
+#endif
+
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#include <check.h>
+
+#include "tmpdir.h"
+
+#define ignore(x) ((void)(x))
+
+#if (HAVE_STRUCT_FTW && HAVE_MKDTEMP && HAVE_NFTW)
+ static int unlink_cb(
+ const char *fpath,
+ const struct stat *sb,
+ int typeflag,
+ struct FTW *ftwbuf)
+ {
+ ignore(sb);
+ ignore(typeflag);
+ ignore(ftwbuf);
+ return remove(fpath);
+ }
+
+ static inline int rm_rf(char *path)
+ {
+ return nftw(path, unlink_cb, 64, FTW_DEPTH | FTW_PHYS);
+ }
+
+ static char tmpdir_buf[64];
+
+ void tmpdir_make() {
+ const char template[] = "scratch.XXXXXX";
+ strcpy(tmpdir_buf, template);
+ ck_assert(mkdtemp(tmpdir_buf) != NULL);
+ }
+
+ const char *tmpdir_name() {
+ if (strlen(tmpdir_buf) == 0) {
+ return NULL;
+ } else {
+ return tmpdir_buf;
+ }
+ }
+
+ void tmpdir_clean() {
+ rm_rf(tmpdir_buf);
+ tmpdir_buf[0] = '\0';
+ }
+#endif
diff --git a/test/tmpdir.h b/test/tmpdir.h
new file mode 100644
index 0000000..43db62f
--- /dev/null
+++ b/test/tmpdir.h
@@ -0,0 +1,51 @@
+/* tmpdir.h -- fixture to create a temporary directory
+ * Copyright (C) 2014 Galois, Inc.
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option)
+ * any later version.
+ *
+ * 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 General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * To contact Galois, complete the Web form at
+ * <http://corp.galois.com/contact/> or write to Galois, Inc., 421 Southwest
+ * 6th Avenue, Suite 300, Portland, Oregon, 97204-1622.
+ *
+ *
+ * This fixture creates and cleans a temporary subdirectory of the current
+ * directory. While the subdirectory is active, you can call 'tmpdir_name' to
+ * get its name. */
+
+#ifndef PPAML_TRACER_TEST_TMPDIR_H
+#define PPAML_TRACER_TEST_TMPDIR_H
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <check.h>
+
+#define HAVE_FIXTURE_tmpdir (HAVE_STRUCT_FTW && HAVE_MKDTEMP && HAVE_NFTW)
+
+#if HAVE_FIXTURE_tmpdir
+ void tmpdir_make();
+ void tmpdir_clean();
+
+ /* Returns the name of the currently-active temporary directory. If no
+ * directory is active, returns NULL. */
+ const char *tmpdir_name();
+
+ // Registers the fixture.
+ inline void tmpdir_add_checked(TCase *const tc) {
+ tcase_add_checked_fixture(tc, tmpdir_make, tmpdir_clean);
+ }
+#endif
+
+#endif
diff --git a/test/trace_invalid.c b/test/trace_invalid.c
new file mode 100644
index 0000000..cc93a03
--- /dev/null
+++ b/test/trace_invalid.c
@@ -0,0 +1,70 @@
+/* trace_invalid.c -- fixture to create an invalid OTF trace
+ * Copyright (C) 2014 Galois, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option)
+ * any later version.
+ *
+ * This program 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 General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * To contact Galois, complete the Web form at
+ * <http://corp.galois.com/contact/> or write to Galois, Inc., 421 Southwest
+ * 6th Avenue, Suite 300, Portland, Oregon, 97204-1622. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <check.h>
+
+#include <ppaml/tracer.h>
+
+#include "trace_invalid.h"
+#include "tmpdir.h"
+
+#if HAVE_FIXTURE_tmpdir
+
+ static const char name[] = "trace";
+ static bool active = false;
+
+ void trace_invalid_make()
+ {
+ active = true;
+ ppaml_tracer_t tracer;
+ ck_assert(
+ ppaml_tracer_init(&tracer, trace_invalid_path()) == 0);
+ ck_assert(ppaml_tracer_done(&tracer) == 0);
+ }
+
+ const char *trace_invalid_path()
+ {
+ static char path[128];
+ if (active) {
+ strcpy(path, tmpdir_name());
+ strcat(path, "/");
+ strcat(path, name);
+ return path;
+ } else {
+ return NULL;
+ }
+
+ }
+
+ void trace_invalid_clean()
+ {
+ active = false;
+ }
+
+#endif
diff --git a/test/trace_invalid.h b/test/trace_invalid.h
new file mode 100644
index 0000000..73881e1
--- /dev/null
+++ b/test/trace_invalid.h
@@ -0,0 +1,55 @@
+/* trace_invalid.h -- fixture to create an invalid trace
+ * Copyright (C) 2014 Galois, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option)
+ * any later version.
+ *
+ * This program 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 General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * To contact Galois, complete the Web form at
+ * <http://corp.galois.com/contact/> or write to Galois, Inc., 421 Southwest
+ * 6th Avenue, Suite 300, Portland, Oregon, 97204-1622.
+ *
+ *
+ * This fixture creates an invalid OTF trace in the currently-active temporary
+ * directory. It does not remove it, as it will be removed when the temporary
+ * directory is cleaned.
+ *
+ * Runtime dependency: tmpdir */
+
+#ifndef PPAML_TRACER_TEST_TRACE_INVALID_H
+#define PPAML_TRACER_TEST_TRACE_INVALID_H
+
+#include "tmpdir.h"
+
+#define HAVE_FIXTURE_trace_invalid HAVE_FIXTURE_tmpdir
+
+#if HAVE_FIXTURE_trace_invalid
+ void trace_invalid_make();
+
+ /* Despite its name, this function does not actually clean anything.
+ * It's provided to make it easier to interface with Check. */
+ void trace_invalid_clean();
+
+ /* Returns the path to the trace. If no trace is active, returns
+ * NULL. */
+ const char *trace_invalid_path();
+
+ // Registers the fixture.
+ inline void trace_invalid_add_checked(TCase *const tc) {
+ tcase_add_checked_fixture(
+ tc,
+ trace_invalid_make,
+ trace_invalid_clean);
+ }
+#endif
+
+#endif
diff --git a/test/trace_valid.c b/test/trace_valid.c
new file mode 100644
index 0000000..8c93980
--- /dev/null
+++ b/test/trace_valid.c
@@ -0,0 +1,76 @@
+/* trace_valid.c -- fixture to create an valid OTF trace
+ * Copyright (C) 2014 Galois, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option)
+ * any later version.
+ *
+ * This program 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 General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * To contact Galois, complete the Web form at
+ * <http://corp.galois.com/contact/> or write to Galois, Inc., 421 Southwest
+ * 6th Avenue, Suite 300, Portland, Oregon, 97204-1622. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <check.h>
+
+#include <ppaml/tracer.h>
+
+#include "trace_valid.h"
+#include "tmpdir.h"
+
+#if HAVE_FIXTURE_tmpdir
+
+ static const char name[] = "trace";
+ static bool active = false;
+
+ void trace_valid_make()
+ {
+ active = true;
+ ppaml_tracer_t tracer;
+ ck_assert(
+ ppaml_tracer_init(&tracer, trace_valid_path()) == 0);
+ ppaml_phase_t phase;
+ ck_assert(
+ ppaml_phase_init(&tracer, &phase, "test phase") == 0);
+ ck_assert(ppaml_phase_start(&phase) == 0);
+ ck_assert(ppaml_phase_stop(&phase) == 0);
+ ck_assert(ppaml_phase_done(&phase) == 0);
+ ck_assert(ppaml_tracer_done(&tracer) == 0);
+ }
+
+ const char *trace_valid_path()
+ {
+ static char path[128];
+ if (active) {
+ strcpy(path, tmpdir_name());
+ strcat(path, "/");
+ strcat(path, name);
+ return path;
+ } else {
+ return NULL;
+ }
+
+ }
+
+ void trace_valid_clean()
+ {
+ active = false;
+ }
+
+#endif
diff --git a/test/trace_valid.h b/test/trace_valid.h
new file mode 100644
index 0000000..32e49ae
--- /dev/null
+++ b/test/trace_valid.h
@@ -0,0 +1,55 @@
+/* trace_valid.h -- fixture to create an valid trace
+ * Copyright (C) 2014 Galois, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option)
+ * any later version.
+ *
+ * This program 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 General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * To contact Galois, complete the Web form at
+ * <http://corp.galois.com/contact/> or write to Galois, Inc., 421 Southwest
+ * 6th Avenue, Suite 300, Portland, Oregon, 97204-1622.
+ *
+ *
+ * This fixture creates an valid OTF trace in the currently-active temporary
+ * directory. It does not remove it, as it will be removed when the temporary
+ * directory is cleaned.
+ *
+ * Runtime dependency: tmpdir */
+
+#ifndef PPAML_TRACER_TEST_TRACE_VALID_H
+#define PPAML_TRACER_TEST_TRACE_VALID_H
+
+#include "tmpdir.h"
+
+#define HAVE_FIXTURE_trace_valid HAVE_FIXTURE_tmpdir
+
+#if HAVE_FIXTURE_trace_valid
+ void trace_valid_make();
+
+ /* Despite its name, this function does not actually clean anything.
+ * It's provided to make it easier to interface with Check. */
+ void trace_valid_clean();
+
+ /* Returns the path to the trace. If no trace is active, returns
+ * NULL. */
+ const char *trace_valid_path();
+
+ // Registers the fixture.
+ inline void trace_valid_add_checked(TCase *const tc) {
+ tcase_add_checked_fixture(
+ tc,
+ trace_valid_make,
+ trace_valid_clean);
+ }
+#endif
+
+#endif