From ebd03709764da853483f12a31a7e0c8c4c8f8d9f Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 2 Mar 2016 10:05:08 -0500 Subject: [PATCH] tests: Unify some tmpdir code, add ability for C to use libtest.sh I want to be able to easily test the C API on actual data in an OSTree repo. The shell `libtest.sh` has code to generate it. Bridge the two worlds by introducing a little `libostreetest` library which has a C API which spawns a shell that runs things in `libtest.sh`. Yes, this is about as beautiful as it sounds, which is to say, it's not. But it works! Note while we were here, I realized we were actually now creating *two* tmpdirs per test in `make check` because the tap driver was already doing that. Unify it so we know the C code can rely on it. --- Makefile-tests.am | 18 ++++++++-- buildutil/tap-test | 18 +++++++--- tests/libostreetest.c | 82 +++++++++++++++++++++++++++++++++++++++++++ tests/libostreetest.h | 39 ++++++++++++++++++++ tests/libtest.sh | 34 +++++++----------- tests/test-basic-c.c | 54 ++++++++++++++++++++++++++++ 6 files changed, 216 insertions(+), 29 deletions(-) create mode 100644 tests/libostreetest.c create mode 100644 tests/libostreetest.h create mode 100644 tests/test-basic-c.c diff --git a/Makefile-tests.am b/Makefile-tests.am index 4045e0c3..61b9b66a 100644 --- a/Makefile-tests.am +++ b/Makefile-tests.am @@ -121,7 +121,8 @@ libreaddir_rand_la_LDFLAGS = -avoid-version test_programs = tests/test-varint tests/test-ot-unix-utils tests/test-bsdiff tests/test-mutable-tree \ tests/test-keyfile-utils tests/test-ot-opt-utils tests/test-ot-tool-util \ - tests/test-gpg-verify-result tests/test-checksum tests/test-lzma tests/test-rollsum + tests/test-gpg-verify-result tests/test-checksum tests/test-lzma tests/test-rollsum \ + tests/test-basic-c # An interactive tool noinst_PROGRAMS += tests/test-rollsum-cli @@ -130,8 +131,16 @@ if USE_LIBARCHIVE test_programs += tests/test-libarchive-import endif -TESTS_CFLAGS = $(ostree_bin_shared_cflags) $(OT_INTERNAL_GIO_UNIX_CFLAGS) -I$(srcdir)/libglnx -TESTS_LDADD = $(ostree_bin_shared_ldadd) $(OT_INTERNAL_GIO_UNIX_LIBS) +common_tests_cflags = $(ostree_bin_shared_cflags) $(OT_INTERNAL_GIO_UNIX_CFLAGS) -I$(srcdir)/libglnx +common_tests_ldadd = $(ostree_bin_shared_ldadd) $(OT_INTERNAL_GIO_UNIX_LIBS) + +noinst_LTLIBRARIES += libostreetest.la +libostreetest_la_SOURCES = tests/libostreetest.c +libostreetest_la_CFLAGS = $(common_tests_cflags) -I $(srcdir)/tests +libostreetest_la_LIBADD = $(common_tests_ldadd) + +TESTS_CFLAGS = $(common_tests_cflags) +TESTS_LDADD = $(common_tests_ldadd) libostreetest.la tests_test_rollsum_cli_SOURCES = src/libostree/ostree-rollsum.c tests/test-rollsum-cli.c tests_test_rollsum_cli_CFLAGS = $(TESTS_CFLAGS) $(OT_DEP_ZLIB_CFLAGS) @@ -144,6 +153,9 @@ tests_test_rollsum_LDADD = libbupsplit.la $(TESTS_LDADD) $(OT_DEP_ZLIB_LIBS) tests_test_mutable_tree_CFLAGS = $(TESTS_CFLAGS) tests_test_mutable_tree_LDADD = $(TESTS_LDADD) +tests_test_basic_c_CFLAGS = $(TESTS_CFLAGS) +tests_test_basic_c_LDADD = $(TESTS_LDADD) + tests_test_ot_unix_utils_CFLAGS = $(TESTS_CFLAGS) tests_test_ot_unix_utils_LDADD = $(TESTS_LDADD) diff --git a/buildutil/tap-test b/buildutil/tap-test index 970b1c33..38080bb3 100755 --- a/buildutil/tap-test +++ b/buildutil/tap-test @@ -1,12 +1,22 @@ #! /bin/bash - -# run a GTest in tap mode. The test binary is passed as $1 +# +# Run a test in tap mode, ensuring we have a temporary directory. We +# always use /var/tmp becuase we might want to use user xattrs, which +# aren't available on tmpfs. +# +# The test binary is passed as $1 srcd=$(cd $(dirname $1) && pwd) bn=$(basename $1) -tempdir=$(mktemp -d) +tempdir=$(mktemp -d /var/tmp/tap-test.XXXXXX) +touch ${tempdir}/.testtmp function cleanup () { - rm "${tempdir}" -rf + if test -n "${TEST_SKIP_CLEANUP:-}"; then + echo "Skipping cleanup of ${test_tmpdir}" + else if test -f ${tempdir}/.test; then + rm "${tempdir}" -rf + fi + fi } trap cleanup EXIT cd ${tempdir} diff --git a/tests/libostreetest.c b/tests/libostreetest.c new file mode 100644 index 00000000..9ebebde0 --- /dev/null +++ b/tests/libostreetest.c @@ -0,0 +1,82 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2015 Red Hat, Inc. + * + * 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; either + * version 2 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 + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" +#include +#include + +#include "libglnx.h" +#include "libostreetest.h" + +/* This function hovers in a quantum superposition of horrifying and + * beautiful. Future generations may interpret it as modern art. + */ +static gboolean +run_libtest (const char *cmd, GError **error) +{ + gboolean ret = FALSE; + const char *builddir = g_getenv ("G_TEST_BUILDDIR"); + int estatus; + g_autoptr(GPtrArray) argv = g_ptr_array_new (); + g_autoptr(GString) cmdstr = g_string_new (""); + + g_ptr_array_add (argv, "bash"); + g_ptr_array_add (argv, "-c"); + + g_string_append (cmdstr, ". "); + g_string_append (cmdstr, builddir); + g_string_append (cmdstr, "/tests/libtest.sh; "); + g_string_append (cmdstr, cmd); + + g_ptr_array_add (argv, cmdstr->str); + g_ptr_array_add (argv, NULL); + + if (!g_spawn_sync (NULL, (char**)argv->pdata, NULL, G_SPAWN_SEARCH_PATH, + NULL, NULL, NULL, NULL, &estatus, error)) + goto out; + + if (!g_spawn_check_exit_status (estatus, error)) + goto out; + + ret = TRUE; + out: + return ret; +} + +gboolean +ot_test_setup_repo (OtTest *self, + GCancellable *cancellable, + GError **error) +{ + gboolean ret = FALSE; + g_autoptr(GFile) repo_path = g_file_new_for_path ("repo"); + + if (!run_libtest ("setup_test_repository", error)) + goto out; + + self->repo = ostree_repo_new (repo_path); + + if (!ostree_repo_open (self->repo, cancellable, error)) + goto out; + + ret = TRUE; + out: + return ret; +} diff --git a/tests/libostreetest.h b/tests/libostreetest.h new file mode 100644 index 00000000..2ab93481 --- /dev/null +++ b/tests/libostreetest.h @@ -0,0 +1,39 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2016 Colin Walters + * + * 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; either + * version 2 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 + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Colin Walters + */ + +#pragma once + +#include +#include + +G_BEGIN_DECLS + +typedef struct { + OstreeRepo *repo; + GSubprocess *shell; +} OtTest; + +gboolean ot_test_setup_repo (OtTest *self, + GCancellable *cancellable, + GError **error); + +G_END_DECLS diff --git a/tests/libtest.sh b/tests/libtest.sh index 4efbabbe..0db3382d 100755 --- a/tests/libtest.sh +++ b/tests/libtest.sh @@ -18,28 +18,22 @@ # Boston, MA 02111-1307, USA. SRCDIR=$(dirname $0) -_cleanup_tmpdir () { - if test -n "${LIBTEST_SKIP_CLEANUP:-}"; then - echo "Skipping cleanup of ${test_tmpdir}" - else if test -f ${test_tmpdir}/.test; then - rm ${test_tmpdir} -rf - fi - fi + +assert_not_reached () { + echo $@ 1>&2; exit 1 } -# If we're running as a local test (i.e. through `make check`), then -# UNINSTALLEDTESTS=1. Otherwise (i.e. as an installed test), it's undefined, in -# which case we're already in a tmpdir. -if test -n "${UNINSTALLEDTESTS:-}"; then - test_tmpdir=$(mktemp -d /var/tmp/test.XXXXXX) - touch ${test_tmpdir}/.test - trap _cleanup_tmpdir EXIT - cd ${test_tmpdir} - export PATH=${G_TEST_BUILDDIR}:${PATH} -fi - test_tmpdir=$(pwd) +# Extra sanity checks +if test -d .git; then + assert_not_reached "Found .git, not in a tempdir?" +fi +echo "in ${test_tmpdir}" +if ! echo ${test_tmpdir} | grep -E -q '^/(var/)?tmp'; then + assert_not_reached "Not in /tmp or /var/tmp" +fi + export G_DEBUG=fatal-warnings # Also, unbreak `tar` inside `make check`...Automake will inject @@ -73,10 +67,6 @@ else CMD_PREFIX="env LD_PRELOAD=${SRCDIR}/libreaddir-rand.so" fi -assert_not_reached () { - echo $@ 1>&2; exit 1 -} - assert_streq () { test "$1" = "$2" || (echo 1>&2 "$1 != $2"; exit 1) } diff --git a/tests/test-basic-c.c b/tests/test-basic-c.c new file mode 100644 index 00000000..e0bcf9f8 --- /dev/null +++ b/tests/test-basic-c.c @@ -0,0 +1,54 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2016 Red Hat, Inc. + * + * 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; either + * version 2 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 + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include +#include +#include + +#include "libglnx.h" +#include "libostreetest.h" + +static void +test_repo_is_not_system (gconstpointer data) +{ + OtTest *self = (void*)data; + g_assert (!ostree_repo_is_system (self->repo)); +} + +int main (int argc, char **argv) +{ + g_autoptr(GError) error = NULL; + OtTest selfd = {NULL,}; + + g_test_init (&argc, &argv, NULL); + + if (!ot_test_setup_repo (&selfd, NULL, &error)) + goto out; + + g_test_add_data_func ("/repo-not-system", &selfd, test_repo_is_not_system); + + return g_test_run(); + out: + if (error) + g_error ("%s", error->message); + return 1; +}