From 7a32d7f5883ae0429790e11b75282785b789bd12 Mon Sep 17 00:00:00 2001 From: Salvatore Benedetto Date: Thu, 11 Sep 2008 15:08:18 +0000 Subject: [PATCH] * Adding unit test for xsi message queue git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27419 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/tests/system/libroot/posix/Jamfile | 4 + .../libroot/posix/xsi_msg_queue_test1.cpp | 241 ++++++++++++++++++ 2 files changed, 245 insertions(+) create mode 100644 src/tests/system/libroot/posix/xsi_msg_queue_test1.cpp diff --git a/src/tests/system/libroot/posix/Jamfile b/src/tests/system/libroot/posix/Jamfile index 5b4d22bfc5..2b92ae2ef5 100644 --- a/src/tests/system/libroot/posix/Jamfile +++ b/src/tests/system/libroot/posix/Jamfile @@ -60,6 +60,10 @@ SimpleTest init_rld_after_fork_test : init_rld_after_fork_test.cpp ; +SimpleTest xsi_msg_queue_test1 + : xsi_msg_queue_test1.cpp +; + SimpleTest xsi_sem_test1 : xsi_sem_test1.cpp ; diff --git a/src/tests/system/libroot/posix/xsi_msg_queue_test1.cpp b/src/tests/system/libroot/posix/xsi_msg_queue_test1.cpp new file mode 100644 index 0000000000..f308a25619 --- /dev/null +++ b/src/tests/system/libroot/posix/xsi_msg_queue_test1.cpp @@ -0,0 +1,241 @@ +/* + * Copyright 2008, Salvatore Benedetto, salvatore.benedetto@gmail.com. + * Distributed under the terms of the MIT License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "TestUnitUtils.h" + +#define KEY ((key_t)12345) + +static status_t +remove_msg_queue(int msgID) +{ + return msgctl(msgID, IPC_RMID, 0); +} + +struct message { + long type; + char text[20]; +}; + + +static void +test_msgget() +{ + TEST_SET("msgget({IPC_PRIVATE, key})"); + + const char* currentTest = NULL; + + // Open private set with IPC_PRIVATE + TEST("msgget(IPC_PRIVATE) - private"); + int msgID = msgget(IPC_PRIVATE, S_IRUSR | S_IWUSR); + assert_posix_bool_success(msgID != -1); + + // Destroy private msg_queue + TEST("msgctl(IPC_RMID) - private"); + status_t status = remove_msg_queue(msgID); + assert_posix_bool_success(status != -1); + + // Open non-private non-existing set with IPC_CREAT + TEST("msgget(KEY, IPC_CREAT) non-existing"); + msgID = msgget(KEY, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR + | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); + assert_posix_bool_success(status != -1); + + // Re-open non-private existing without IPC_CREAT + TEST("msgget(KEY) re-open existing without IPC_CREAT"); + int returnID = msgget(KEY, 0); + assert_equals(msgID, returnID); + + // Re-open non-private existing with IPC_CREAT + TEST("msgget(IPC_CREATE) re-open existing with IPC_CREAT"); + returnID = msgget(KEY, IPC_CREAT | IPC_EXCL); + assert_posix_bool_success(errno == EEXIST); + + // Destroy non-private msg_queue + TEST("msgctl(IPC_RMID)"); + status = remove_msg_queue(msgID); + assert_posix_bool_success(status != -1); + + // Open non-private non-existing without IPC_CREAT + TEST("msgget(IPC_CREATE) non-existing without IPC_CREAT"); + msgID = msgget(KEY, IPC_EXCL | S_IRUSR | S_IWUSR + | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); + assert_posix_bool_success(errno == ENOENT); + + // Destroy non-existing msg_queue + TEST("msgctl()"); + status = remove_msg_queue(msgID); + assert_posix_bool_success(errno == EINVAL); + + TEST("done"); +} + + +static void +test_msgctl() +{ + TEST_SET("msgctl({IPC_STAT, IPC_SET, IPC_RMID})"); + + const char* currentTest = NULL; + + // Open non-private non-existing set with IPC_CREAT + TEST("msgget(IPC_CREATE) non-existing"); + int msgID = msgget(KEY, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR + | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); + assert_posix_bool_success(msgID != -1); + + // IPC_SET + TEST("msgctl(IPC_SET)"); + struct msqid_ds msg_queue; + memset(&msg_queue, 0, sizeof(struct msqid_ds)); + msg_queue.msg_perm.uid = getuid() + 3; + msg_queue.msg_perm.gid = getgid() + 3; + msg_queue.msg_perm.mode = 0666; + msg_queue.msg_qbytes = 512; + status_t status = msgctl(msgID, IPC_SET, &msg_queue); + assert_posix_bool_success(status != 1); + + // IPC_STAT set + TEST("msgctl(IPC_STAT)"); + memset(&msg_queue, 0, sizeof(struct msqid_ds)); + status = msgctl(msgID, IPC_STAT, &msg_queue); + assert_posix_bool_success(status != 1); + TEST("msgctl(IPC_STAT): number of bytes"); + assert_equals((msglen_t)msg_queue.msg_qbytes, (msglen_t)512); + TEST("msgctl(IPC_STAT): uid"); + assert_equals(msg_queue.msg_perm.uid, getuid() + 3); + TEST("msgctl(IPC_STAT): gid"); + assert_equals(msg_queue.msg_perm.gid, getgid() + 3); + + // Destroy non-private msg_queue + TEST("msgctl(IPC_RMID)"); + status = remove_msg_queue(msgID); + assert_posix_bool_success(status != 1); + + TEST("done"); +} + + +static void +test_msgsnd() +{ + TEST_SET("msgsnd({EAGAIN, send})"); + + const char* currentTest = NULL; + + // Open non-private non-existing set with IPC_CREAT + TEST("msgget(IPC_CREATE) non-existing"); + int msgID = msgget(KEY, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR + | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); + assert_posix_bool_success(msgID != -1); + + // Send simple message + TEST("msgsnd(simple message)"); + struct message msg; + msg.type = 0; + strcpy(msg.text, "Message to send\n"); + status_t status = msgsnd((key_t)msgID, (void *)&msg, 20, 0); + assert_posix_bool_success(status != 1); + + // IPC_SET + TEST("msgctl(IPC_SET) - set limit to 512"); + struct msqid_ds msg_queue; + memset(&msg_queue, 0, sizeof(struct msqid_ds)); + msg_queue.msg_perm.uid = getuid() + 3; + msg_queue.msg_perm.gid = getgid() + 3; + msg_queue.msg_perm.mode = 0666; + msg_queue.msg_qbytes = 512; + status = msgctl(msgID, IPC_SET, &msg_queue); + assert_posix_bool_success(status != 1); + + // Send big message IPC_NOWAIT + TEST("msgsnd(IPC_NOWAIT)"); + msgsnd((key_t)msgID, (void *)&msg, 500, IPC_NOWAIT); + assert_posix_bool_success(errno == EAGAIN); + + // Destroy non-private msg_queue + TEST("msgctl(IPC_RMID)"); + status = remove_msg_queue(msgID); + assert_posix_bool_success(status != 1); + + TEST("done"); +} + + +static void +test_msgrcv() +{ + TEST_SET("msgrcv({IPC_STAT, IPC_SET, IPC_RMID})"); + + const char* currentTest = NULL; + + // Open non-private non-existing set with IPC_CREAT + TEST("msgget(IPC_CREATE) non-existing"); + int msgID = msgget(KEY, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR + | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); + assert_posix_bool_success(msgID != -1); + + // Receive simple message + TEST("msgrcv(IPC_NOWAIT)"); + struct message msg; + memset(&msg, 0, sizeof(struct message)); + msgrcv((key_t)msgID, (void *)&msg, 20, 0, IPC_NOWAIT); + assert_posix_bool_success(errno == ENOMSG); + + pid_t child = fork(); + if (child == 0) { + // Send a simple message + TEST("msgsnd(simple message)"); + struct message smsg; + msg.type = 0; + strcpy(msg.text, "Message to send\n"); + status_t status = msgsnd((key_t)msgID, (void *)&smsg, 20, 0); + assert_posix_bool_success(status != 1); + exit(0); + } + + wait_for_child(child); + TEST("msgrcv(E2BIG)"); + msgrcv((key_t)msgID, (void *)&msg, 10, 0, IPC_NOWAIT); + assert_posix_bool_success(errno == E2BIG); + + TEST("msgrcv(MSG_NOERROR)"); + status_t status + = msgrcv((key_t)msgID, (void *)&msg, 10, 0, IPC_NOWAIT | MSG_NOERROR); + assert_posix_bool_success(status != -1); + + // Destroy non-private msg_queue + TEST("msgctl(IPC_RMID)"); + status = remove_msg_queue(msgID); + assert_posix_bool_success(status != 1); + + TEST("done"); +} + + +int +main() +{ + test_msgget(); + test_msgctl(); + test_msgsnd(); + test_msgrcv(); + + printf("\nAll tests OK\n"); +}