Ack, Mathi.
> -----Original Message----- > From: Hans Nordeback [mailto:[email protected]] > Sent: Wednesday, November 25, 2015 11:03 PM > To: Mathivanan Naickan Palanivelu; Ramesh Babu Betham; > [email protected] > Cc: [email protected] > Subject: [PATCH 1 of 1] core: Add unit test for sysf_ipc.c V3 [#1520] > > configure.ac | 1 + > osaf/libs/core/leap/Makefile.am | 2 +- > osaf/libs/core/leap/tests/Makefile.am | 51 +++++ > osaf/libs/core/leap/tests/test_sysf_ipc.cc | 273 > +++++++++++++++++++++++++++++ > 4 files changed, 326 insertions(+), 1 deletions(-) > > > Updated to use c++11 thread support. > Additional unit test program for sysf_ipc as an example on how to write unit > tests on self contained components in openSAF. This is an exampled that can > be extended. > Updated with review comments. > > diff --git a/configure.ac b/configure.ac > --- a/configure.ac > +++ b/configure.ac > @@ -704,6 +704,7 @@ AC_CONFIG_FILES([ > osaf/libs/core/include/Makefile > osaf/libs/core/common/Makefile > osaf/libs/core/common/include/Makefile > + osaf/libs/core/leap/tests/Makefile > osaf/libs/core/leap/Makefile > osaf/libs/core/leap/include/Makefile > osaf/libs/core/mbcsv/Makefile > diff --git a/osaf/libs/core/leap/Makefile.am > b/osaf/libs/core/leap/Makefile.am > --- a/osaf/libs/core/leap/Makefile.am > +++ b/osaf/libs/core/leap/Makefile.am > @@ -18,7 +18,7 @@ include $(top_srcdir)/Makefile.common > > MAINTAINERCLEANFILES = Makefile.in > > -SUBDIRS = include > +SUBDIRS = include tests > > noinst_LTLIBRARIES = libleap.la > > diff --git a/osaf/libs/core/leap/tests/Makefile.am > b/osaf/libs/core/leap/tests/Makefile.am > new file mode 100644 > --- /dev/null > +++ b/osaf/libs/core/leap/tests/Makefile.am > @@ -0,0 +1,51 @@ > +# -*- OpenSAF -*- > +# > +# (C) Copyright 2015 The OpenSAF Foundation # # 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. This file and program are licensed # > +under the GNU Lesser General Public License Version 2.1, February 1999. > +# The complete license can be accessed from the following location: > +# http://opensource.org/licenses/lgpl-license.php > +# See the Copying file included with the OpenSAF distribution for full > +# licensing terms. > +# > +# Author(s): Ericsson AB > +# > + > +include $(top_srcdir)/Makefile.common > + > +TESTS = testleap > + > +check_PROGRAMS = testleap > + > +testleap_CXXFLAGS =$(AM_CXXFLAGS) > + > +testleap_CPPFLAGS = \ > + -DSA_CLM_B01=1 \ > + $(AM_CPPFLAGS) \ > + -I$(top_srcdir)/osaf/libs/common/amf/include \ > + -I$(top_srcdir)/osaf/libs/common/immsv/include \ > + -I$(top_srcdir)/osaf/tools/saflog/include \ > + -I$(GTEST_DIR)/include > + > +testleap_LDFLAGS = \ > + -lpthread > + > +testleap_SOURCES = \ > + test_sysf_ipc.cc > + > +testleap_LDADD = \ > + $(GTEST_DIR)/lib/libgtest.la \ > + $(GTEST_DIR)/lib/libgtest_main.la \ > + $(top_builddir)/osaf/tools/saflog/src/libsaflog.la \ > + $(top_builddir)/osaf/tools/safimm/src/libimmutil.la \ > + $(top_builddir)/osaf/libs/core/libopensaf_core.la \ > + $(top_builddir)/osaf/libs/common/amf/libamf_common.la \ > + $(top_builddir)/osaf/libs/saf/libSaNtf/libSaNtf.la \ > + $(top_builddir)/osaf/libs/saf/libSaImm/libSaImmOi.la \ > + $(top_builddir)/osaf/libs/saf/libSaImm/libSaImmOm.la \ > + $(top_builddir)/osaf/libs/saf/libSaClm/libSaClm.la \ > + $(top_builddir)/osaf/libs/saf/libSaLog/libSaLog.la \ > + $(top_builddir)/osaf/libs/agents/infrastructure/rda/librda.la > diff --git a/osaf/libs/core/leap/tests/test_sysf_ipc.cc > b/osaf/libs/core/leap/tests/test_sysf_ipc.cc > new file mode 100755 > --- /dev/null > +++ b/osaf/libs/core/leap/tests/test_sysf_ipc.cc > @@ -0,0 +1,273 @@ > +/* -*- OpenSAF -*- > + * > + * (C) Copyright 2015 The OpenSAF Foundation > + * > + * 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. This file and program are > +licensed > + * under the GNU Lesser General Public License Version 2.1, February 1999. > + * The complete license can be accessed from the following location: > + * http://opensource.org/licenses/lgpl-license.php > + * See the Copying file included with the OpenSAF distribution for full > + * licensing terms. > + * > + * Author(s): Ericsson AB > + * > + */ > + > +#include <iostream> > +#include <string> > +#include <thread> > +#include <mutex> > +#include <sched.h> > +#include <poll.h> > +#include <cstdlib> > +#include <ctime> > +#include <unistd.h> > +#include <signal.h> > + > +#include "sysf_ipc.h" > + > +#include "ncs_main_papi.h" > +#include "gtest/gtest.h" > + > +std::mutex send_ctr_mutex; > + > +typedef struct message_ { > + struct message_ *next; > + NCS_IPC_PRIORITY prio; > + int seq_no; > +} Message; > + > +bool mbox_clean(NCSCONTEXT arg, NCSCONTEXT msg) { > + Message *curr; > + Message *temp; > + > + /* clean the entire mailbox */ > + for (curr = (Message *)msg; curr;) { > + temp = curr; > + curr = curr->next; > + > + delete temp; > + } > + return true; > +} > + > +// The fixture for testing c-function sysf_ipc class SysfIpcTest : > +public ::testing::Test { > + public: > + > + protected: > + > + SysfIpcTest() { > + // Setup work can be done here for each test. > + no_of_msgs_sent = 0; > + no_of_msgs_received = 0; > + } > + > + virtual ~SysfIpcTest() { > + // Cleanup work that doesn't throw exceptions here. > + } > + > + // If the constructor and destructor are not enough for setting up > + // and cleaning up each test, you can define the following methods: > + > + virtual void SetUp() { > + // Code here will be called immediately after the constructor (right > + // before each test). > + int rc = ncs_leap_startup(); > + ASSERT_EQ(rc, NCSCC_RC_SUCCESS); > + > + rc = m_NCS_IPC_CREATE(&mbox); > + ASSERT_EQ(rc, NCSCC_RC_SUCCESS); > + > + rc = m_NCS_IPC_ATTACH(&mbox); > + ASSERT_EQ(rc, NCSCC_RC_SUCCESS); > + } > + > + virtual void TearDown() { > + // Code here will be called immediately after each test (right > + // before the destructor). > + int rc = m_NCS_IPC_DETACH(&mbox, mbox_clean, 0); > + EXPECT_EQ(rc, NCSCC_RC_SUCCESS); > + > + rc = m_NCS_IPC_RELEASE(&mbox, 0); > + EXPECT_EQ(rc, NCSCC_RC_SUCCESS); > + > + ncs_leap_shutdown(); > + } > + > + void send_msg(NCS_IPC_PRIORITY prio, int seq_no) { > + Message *msg; > + > + msg = new Message; > + msg->prio = prio; > + msg->seq_no = seq_no; > + int rc = m_NCS_IPC_SEND(&mbox, msg, prio); > + ASSERT_EQ(rc, NCSCC_RC_SUCCESS); > + } > + > + void recv_msg(NCS_IPC_PRIORITY prio, int seq_no) { > + Message *msg; > + > + msg = reinterpret_cast<Message*>(ncs_ipc_non_blk_recv(&mbox)); > + ASSERT_TRUE(msg != NULL); > + ASSERT_EQ(msg->prio, prio); > + ASSERT_EQ(msg->seq_no, seq_no); > + delete msg; > + } > + > + // > + static void sighandler(int signo); > + > + // > + static void MessageReceiver(); > + > + // > + static void MessageSender() { > + Message *msg; > + int prio; > + srand(time(NULL)); > + int rc = NCSCC_RC_SUCCESS; > + > + for (int i = 0; i < 60; ++i) { > + msg = new Message; > + > + prio = (random() % 3) + 1; > + msg->prio = (NCS_IPC_PRIORITY) prio; > + msg->seq_no = i; > + > + rc = m_NCS_IPC_SEND(&mbox, msg, msg->prio); > + EXPECT_EQ(rc, NCSCC_RC_SUCCESS); > + > + { > + std::lock_guard<std::mutex> lck(send_ctr_mutex); > + no_of_msgs_sent++; > + } > + > + sched_yield(); > + } > + } > + > + // Objects declared here can be used by all tests in the test case. > + > + static SYSF_MBX mbox; > + static uint32_t no_of_msgs_sent; > + static uint32_t no_of_msgs_received; > +}; > + > +SYSF_MBX SysfIpcTest::mbox = 0; > +uint32_t SysfIpcTest::no_of_msgs_sent = 0; uint32_t > +SysfIpcTest::no_of_msgs_received = 0; > + > +void SysfIpcTest::sighandler(int signo) { > + int rc = m_NCS_IPC_DETACH(&mbox, 0, 0); > + EXPECT_EQ(rc, NCSCC_RC_SUCCESS); > +} > + > +void SysfIpcTest::MessageReceiver() { > + NCS_SEL_OBJ mbox_fd; > + pollfd fds; > + bool done = false; > + Message *msg; > + > + mbox_fd = ncs_ipc_get_sel_obj(&mbox); > + > + fds.fd = mbox_fd.rmv_obj; > + fds.events = POLLIN; > + > + while (!done) { > + int rc = poll(&fds, 1, -1); > + > + if (rc == -1) { > + if (errno == EINTR) { > + continue; > + } > + ASSERT_EQ(rc, 0); > + } > + > + if (fds.revents & POLLIN) { > + while ((msg = > reinterpret_cast<Message*>(ncs_ipc_non_blk_recv(&mbox))) != NULL) { > + no_of_msgs_received++; > + > + if (msg->seq_no == 4711) { > + done = true; > + } > + > + delete msg; > + } > + } > + } > + > + { > + std::lock_guard<std::mutex> lck(send_ctr_mutex); > + ASSERT_EQ(no_of_msgs_received, no_of_msgs_sent); > + } > +} > + > +// Tests send and receive > +TEST_F(SysfIpcTest, TestSendReceiveMessage) { > + Message *msg; > + > + // send messages > + send_msg(NCS_IPC_PRIORITY_LOW, 1); > + send_msg(NCS_IPC_PRIORITY_LOW, 2); > + send_msg(NCS_IPC_PRIORITY_NORMAL, 1); > + send_msg(NCS_IPC_PRIORITY_NORMAL, 2); > send_msg(NCS_IPC_PRIORITY_HIGH, > + 1); send_msg(NCS_IPC_PRIORITY_HIGH, 2); > + send_msg(NCS_IPC_PRIORITY_VERY_HIGH, 1); > + send_msg(NCS_IPC_PRIORITY_VERY_HIGH, 2); > + > + // receive messages > + recv_msg(NCS_IPC_PRIORITY_VERY_HIGH, 1); > + recv_msg(NCS_IPC_PRIORITY_VERY_HIGH, 2); > + recv_msg(NCS_IPC_PRIORITY_HIGH, 1); > recv_msg(NCS_IPC_PRIORITY_HIGH, > + 2); recv_msg(NCS_IPC_PRIORITY_NORMAL, 1); > + recv_msg(NCS_IPC_PRIORITY_NORMAL, 2); > recv_msg(NCS_IPC_PRIORITY_LOW, > + 1); recv_msg(NCS_IPC_PRIORITY_LOW, 2); > + > + msg = reinterpret_cast<Message*>(ncs_ipc_non_blk_recv(&mbox)); > + EXPECT_TRUE(msg == NULL); > +} > + > +// Tests threads sending and receiving messages TEST_F(SysfIpcTest, > +TestThreadsSendReceiveMessage) { > + std::thread sndr_thread[5]; > + srand(time(NULL)); > + > + // > + struct sigaction actions; > + memset(&actions, 0, sizeof(actions)); sigemptyset(&actions.sa_mask); > + actions.sa_flags = 0; actions.sa_handler = sighandler; > + > + int rc = sigaction(SIGTERM, &actions, NULL); ASSERT_EQ(rc, 0); > + > + std::thread msg_receiver(MessageReceiver); > + > + ASSERT_EQ(msg_receiver.joinable(), true); > + > + for (int i = 0; i < 5; ++i) { > + sndr_thread[i] = std::thread(MessageSender); } > + > + for (int i = 0; i < 5; ++i) { > + sndr_thread[i].join(); > + } > + > + sched_yield(); > + > + { > + std::lock_guard<std::mutex> lck(send_ctr_mutex); > + no_of_msgs_sent++; > + } > + > + send_msg(NCS_IPC_PRIORITY_LOW, 4711); > + > + msg_receiver.join(); > +} ------------------------------------------------------------------------------ _______________________________________________ Opensaf-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/opensaf-devel
