]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: Add unit test for file_create_locked()
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Wed, 28 Jun 2017 14:40:20 +0000 (17:40 +0300)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Mon, 3 Jul 2017 12:13:24 +0000 (15:13 +0300)
src/lib/Makefile.am
src/lib/test-file-create-locked.c [new file with mode: 0644]
src/lib/test-lib.c
src/lib/test-lib.h

index 4d48ce6080b4f9f672686e693ad48b5770e46b1d..ab28400c31f7755bedd9696242843c01210eb580 100644 (file)
@@ -320,6 +320,7 @@ test_lib_SOURCES = \
        test-crc32.c \
        test-data-stack.c \
        test-failures.c \
+       test-file-create-locked.c \
        test-guid.c \
        test-hash.c \
        test-hash-format.c \
diff --git a/src/lib/test-file-create-locked.c b/src/lib/test-file-create-locked.c
new file mode 100644 (file)
index 0000000..d604458
--- /dev/null
@@ -0,0 +1,91 @@
+/* Copyright (c) 2017 Dovecot authors, see the included COPYING file */
+
+#include "test-lib.h"
+#include "file-create-locked.h"
+
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/stat.h>
+
+static void create_file(const char *path)
+{
+       int fd;
+
+       fd = creat(path, 0600);
+       if (fd == -1)
+               i_fatal("creat(%s) failed: %m", path);
+       i_close_fd(&fd);
+}
+
+static bool wait_for_file(pid_t pid, const char *path)
+{
+       struct stat st;
+
+       for (unsigned int i = 0; i < 1000; i++) {
+               if (stat(path, &st) == 0)
+                       return TRUE;
+               if (errno != ENOENT)
+                       i_fatal("stat(%s) failed: %m", path);
+               if (kill(pid, 0) < 0) {
+                       if (errno == ESRCH)
+                               return FALSE;
+                       i_fatal("kill(SIGSRCH) failed: %m");
+               }
+               usleep(10000);
+       }
+       i_error("%s isn't being created", path);
+       return FALSE;
+}
+
+static void test_file_create_locked_basic(void)
+{
+       struct file_create_settings set = {
+               .lock_timeout_secs = 0,
+               .lock_method = FILE_LOCK_METHOD_FCNTL,
+       };
+       const char *path = ".test-file-create-locked";
+       struct file_lock *lock;
+       const char *error;
+       bool created;
+       pid_t pid;
+       int fd;
+
+       test_begin("file_create_locked()");
+
+       i_unlink_if_exists(path);
+       i_unlink_if_exists(".test-temp-file-create-locked-child");
+       pid = fork();
+       switch (pid) {
+       case (pid_t)-1:
+               i_error("fork() failed: %m");
+               break;
+       case 0:
+               /* child */
+               fd = file_create_locked(path, &set, &lock, &created, &error);
+               test_assert(fd > 0);
+               test_assert(created);
+               if (test_has_failed())
+                       exit(1);
+               create_file(".test-temp-file-create-locked-child");
+               sleep(60);
+               i_close_fd(&fd);
+               exit(0);
+       default:
+               /* parent */
+               test_assert(wait_for_file(pid, ".test-temp-file-create-locked-child"));
+               if (test_has_failed())
+                       break;
+               test_assert(file_create_locked(path, &set, &lock, &created, &error) == -1);
+               test_assert(errno == EAGAIN);
+               if (kill(pid, SIGKILL) < 0)
+                       i_error("kill(SIGKILL) failed: %m");
+               break;
+       }
+       i_unlink_if_exists(".test-temp-file-create-locked-child");
+       test_end();
+}
+
+void test_file_create_locked(void)
+{
+       test_file_create_locked_basic();
+}
index bbe14ee759b4a514f8ab33b3408c094eb092e514..aea8a47a7a9536b21c152b859947b696795f73a4 100644 (file)
@@ -15,6 +15,7 @@ int main(void)
                test_crc32,
                test_data_stack,
                test_failures,
+               test_file_create_locked,
                test_guid,
                test_hash,
                test_hash_format,
index d33ab86d8a666ea3c357508b47215b6b11522de2..3b96e4bd5851da924409c10cb64bed45743205de 100644 (file)
@@ -16,6 +16,7 @@ void test_crc32(void);
 void test_data_stack(void);
 enum fatal_test_state fatal_data_stack(unsigned int);
 void test_failures(void);
+void test_file_create_locked(void);
 void test_guid(void);
 void test_hash(void);
 void test_hash_format(void);