From c2bcca04bac7e6ba99ba4cc1d17e99c5ed2b12cf Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 12 Sep 2017 15:27:36 -0400 Subject: tests: Add macro for auto-error checking Having our tests forced into a `goto out` style is seriously annoying since we can't write tests like we write production code. Add a macro that checks for the error being NULL. This doesn't fully solve the problem since the test functions are still forced into `void` returns; at some point I may extend GLib to have `g_test_add_err_func()`. --- tests/libglnx-testlib.h | 34 ++++++++++++ tests/test-libglnx-fdio.c | 135 ++++++++++++++-------------------------------- 2 files changed, 74 insertions(+), 95 deletions(-) create mode 100644 tests/libglnx-testlib.h diff --git a/tests/libglnx-testlib.h b/tests/libglnx-testlib.h new file mode 100644 index 0000000..ee750e4 --- /dev/null +++ b/tests/libglnx-testlib.h @@ -0,0 +1,34 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2017 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. + */ + +#pragma once + +typedef GError _GLnxTestAutoError; +static inline void +_glnx_test_auto_error_cleanup (_GLnxTestAutoError *autoerror) +{ + g_assert_no_error (autoerror); + /* We could add a clear call here, but no point...we'll have aborted */ +} +G_DEFINE_AUTOPTR_CLEANUP_FUNC(_GLnxTestAutoError, _glnx_test_auto_error_cleanup); + +#define _GLNX_TEST_DECLARE_ERROR(local_error, error) \ + g_autoptr(_GLnxTestAutoError) local_error = NULL; \ + GError **error = &local_error diff --git a/tests/test-libglnx-fdio.c b/tests/test-libglnx-fdio.c index 4047df6..9ec9be7 100644 --- a/tests/test-libglnx-fdio.c +++ b/tests/test-libglnx-fdio.c @@ -26,6 +26,8 @@ #include #include +#include "libglnx-testlib.h" + static gboolean renameat_test_setup (int *out_srcfd, int *out_destfd, GError **error) @@ -59,14 +61,13 @@ renameat_test_setup (int *out_srcfd, int *out_destfd, static void test_renameat2_noreplace (void) { - g_autoptr(GError) local_error = NULL; - GError **error = &local_error; + _GLNX_TEST_DECLARE_ERROR(local_error, error); glnx_fd_close int srcfd = -1; glnx_fd_close int destfd = -1; struct stat stbuf; if (!renameat_test_setup (&srcfd, &destfd, error)) - goto out; + return; if (glnx_renameat2_noreplace (srcfd, "foo", destfd, "bar") == 0) g_assert_not_reached (); @@ -76,156 +77,106 @@ test_renameat2_noreplace (void) } if (glnx_renameat2_noreplace (srcfd, "foo", destfd, "baz") < 0) - { - glnx_set_error_from_errno (error); - goto out; - } + return (void)glnx_throw_errno_prefix (error, "renameat"); if (!glnx_fstatat (destfd, "bar", &stbuf, AT_SYMLINK_NOFOLLOW, error)) - goto out; + return; if (fstatat (srcfd, "foo", &stbuf, AT_SYMLINK_NOFOLLOW) == 0) g_assert_not_reached (); else g_assert_cmpint (errno, ==, ENOENT); - - out: - g_assert_no_error (local_error); } static void test_renameat2_exchange (void) { - g_autoptr(GError) local_error = NULL; - GError **error = &local_error; + _GLNX_TEST_DECLARE_ERROR(local_error, error); + glnx_fd_close int srcfd = -1; glnx_fd_close int destfd = -1; - struct stat stbuf; - if (!renameat_test_setup (&srcfd, &destfd, error)) - goto out; + return; if (glnx_renameat2_exchange (AT_FDCWD, "srcdir", AT_FDCWD, "destdir") < 0) - { - glnx_set_error_from_errno (error); - goto out; - } + return (void)glnx_throw_errno_prefix (error, "renameat"); /* Ensure the dir fds are the same */ - if (fstatat (srcfd, "foo", &stbuf, AT_SYMLINK_NOFOLLOW) < 0) - { - glnx_set_error_from_errno (error); - goto out; - } - if (fstatat (destfd, "bar", &stbuf, AT_SYMLINK_NOFOLLOW) < 0) - { - glnx_set_error_from_errno (error); - goto out; - } + struct stat stbuf; + if (!glnx_fstatat (srcfd, "foo", &stbuf, AT_SYMLINK_NOFOLLOW, error)) + return; + if (!glnx_fstatat (destfd, "bar", &stbuf, AT_SYMLINK_NOFOLLOW, error)) + return; /* But the dirs should be swapped */ - if (fstatat (AT_FDCWD, "destdir/foo", &stbuf, AT_SYMLINK_NOFOLLOW) < 0) - { - glnx_set_error_from_errno (error); - goto out; - } - if (fstatat (AT_FDCWD, "srcdir/bar", &stbuf, AT_SYMLINK_NOFOLLOW) < 0) - { - glnx_set_error_from_errno (error); - goto out; - } - - out: - g_assert_no_error (local_error); + if (!glnx_fstatat (AT_FDCWD, "destdir/foo", &stbuf, AT_SYMLINK_NOFOLLOW, error)) + return; + if (!glnx_fstatat (AT_FDCWD, "srcdir/bar", &stbuf, AT_SYMLINK_NOFOLLOW, error)) + return; } static void test_tmpfile (void) { - g_autoptr(GError) local_error = NULL; - GError **error = &local_error; - g_auto(GLnxTmpfile) tmpf = { 0, }; + _GLNX_TEST_DECLARE_ERROR(local_error, error); + g_auto(GLnxTmpfile) tmpf = { 0, }; if (!glnx_open_tmpfile_linkable_at (AT_FDCWD, ".", O_WRONLY|O_CLOEXEC, &tmpf, error)) - goto out; - + return; if (glnx_loop_write (tmpf.fd, "foo", strlen ("foo")) < 0) - { - (void)glnx_throw_errno_prefix (error, "write"); - goto out; - } - + return (void)glnx_throw_errno_prefix (error, "write"); if (glnx_link_tmpfile_at (&tmpf, GLNX_LINK_TMPFILE_NOREPLACE, AT_FDCWD, "foo", error)) - goto out; - - out: - g_assert_no_error (local_error); + return; } static void test_stdio_file (void) { - g_autoptr(GError) local_error = NULL; - GError **error = &local_error; + _GLNX_TEST_DECLARE_ERROR(local_error, error); g_auto(GLnxTmpfile) tmpf = { 0, }; g_autoptr(FILE) f = NULL; if (!glnx_open_anonymous_tmpfile (O_RDWR|O_CLOEXEC, &tmpf, error)) - goto out; + return; f = fdopen (tmpf.fd, "w"); tmpf.fd = -1; /* Ownership was transferred via fdopen() */ if (!f) - { - (void)glnx_throw_errno_prefix (error, "fdopen"); - goto out; - } - + return (void)glnx_throw_errno_prefix (error, "fdopen"); if (fwrite ("hello", 1, strlen ("hello"), f) != strlen ("hello")) - { - (void)glnx_throw_errno_prefix (error, "fwrite"); - goto out; - } + return (void)glnx_throw_errno_prefix (error, "fwrite"); if (!glnx_stdio_file_flush (f, error)) - goto out; - - out: - g_assert_no_error (local_error); + return; } static void test_fstatat (void) { - g_autoptr(GError) local_error = NULL; - GError **error = &local_error; + _GLNX_TEST_DECLARE_ERROR(local_error, error); struct stat stbuf = { 0, }; if (!glnx_fstatat_allow_noent (AT_FDCWD, ".", &stbuf, 0, error)) - goto out; + return; g_assert_cmpint (errno, ==, 0); g_assert_no_error (local_error); g_assert (S_ISDIR (stbuf.st_mode)); if (!glnx_fstatat_allow_noent (AT_FDCWD, "nosuchfile", &stbuf, 0, error)) - goto out; + return; g_assert_cmpint (errno, ==, ENOENT); g_assert_no_error (local_error); - - out: - g_assert_no_error (local_error); } static void test_filecopy (void) { - g_autoptr(GError) local_error = NULL; - GError **error = &local_error; + _GLNX_TEST_DECLARE_ERROR(local_error, error); g_auto(GLnxTmpfile) tmpf = { 0, }; const char foo[] = "foo"; if (!glnx_file_replace_contents_at (AT_FDCWD, foo, (guint8*)foo, sizeof (foo), GLNX_FILE_REPLACE_NODATASYNC, NULL, error)) - goto out; + return; if (!glnx_file_copy_at (AT_FDCWD, foo, NULL, AT_FDCWD, "bar", GLNX_FILE_COPY_NOXATTRS, NULL, error)) - goto out; + return; if (glnx_file_copy_at (AT_FDCWD, foo, NULL, AT_FDCWD, "bar", GLNX_FILE_COPY_NOXATTRS, NULL, error)) @@ -236,13 +187,10 @@ test_filecopy (void) if (!glnx_file_copy_at (AT_FDCWD, foo, NULL, AT_FDCWD, "bar", GLNX_FILE_COPY_NOXATTRS | GLNX_FILE_COPY_OVERWRITE, NULL, error)) - goto out; + return; if (symlinkat ("nosuchtarget", AT_FDCWD, "link") < 0) - { - glnx_throw_errno_prefix (error, "symlinkat"); - goto out; - } + return (void) glnx_throw_errno_prefix (error, "symlinkat"); /* Shouldn't be able to overwrite a symlink without GLNX_FILE_COPY_OVERWRITE */ if (glnx_file_copy_at (AT_FDCWD, foo, NULL, AT_FDCWD, "link", @@ -256,20 +204,17 @@ test_filecopy (void) if (!glnx_file_copy_at (AT_FDCWD, foo, NULL, AT_FDCWD, "link", GLNX_FILE_COPY_NOXATTRS | GLNX_FILE_COPY_OVERWRITE, NULL, error)) - goto out; + return; struct stat stbuf; if (!glnx_fstatat_allow_noent (AT_FDCWD, "nosuchtarget", &stbuf, AT_SYMLINK_NOFOLLOW, error)) - goto out; + return; g_assert_cmpint (errno, ==, ENOENT); g_assert_no_error (local_error); if (!glnx_fstatat (AT_FDCWD, "link", &stbuf, AT_SYMLINK_NOFOLLOW, error)) - goto out; + return; g_assert (S_ISREG (stbuf.st_mode)); - - out: - g_assert_no_error (local_error); } int main (int argc, char **argv) -- cgit v1.2.1