configure.ac | 1 +
osaf/libs/core/leap/Makefile.am | 2 +-
osaf/libs/core/leap/tests/Makefile.am | 49 ++++
osaf/libs/core/leap/tests/test_sysf_ipc.cc | 315 +++++++++++++++++++++++++++++
4 files changed, 366 insertions(+), 1 deletions(-)
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.
diff --git a/configure.ac b/configure.ac
--- a/configure.ac
+++ b/configure.ac
@@ -701,6 +701,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,49 @@
+# -*- 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)
+
+testleap_LDFLAGS = \
+ -lgtest -lpthread
+
+testleap_SOURCES = \
+ test_sysf_ipc.cc
+
+testleap_LDADD = \
+ $(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,315 @@
+#include <iostream>
+#include <string>
+#include <pthread.h>
+#include <sched.h>
+#include <poll.h>
+#include <cstdlib>
+#include <ctime>
+#include <unistd.h>
+#include <signal.h>
+
+#include "sysf_ipc.h"
+#include "gtest.h"
+
+extern "C" unsigned int ncs_leap_startup(void);
+extern "C" void ncs_leap_shutdown(void);
+
+SYSF_MBX mbox;
+
+pthread_mutex_t 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;
+
+ pthread_mutex_lock(&mutex);
+ std::cout << "mbox_clean: [" << (void*) msg << "]" << std::endl;
+ pthread_mutex_unlock(&mutex);
+
+ /* clean the entire mailbox */
+ for (curr = (Message *)msg; curr;) {
+ temp = curr;
+ curr = curr->next;
+ pthread_mutex_lock(&mutex);
+ std::cout << "Deleteing temp->seq_no: " << temp->seq_no << std::endl;
+ pthread_mutex_unlock(&mutex);
+ delete temp;
+ }
+ return true;
+}
+
+void sighandler(int signo) {
+ //pthread_t self = pthread_self();
+
+ pthread_mutex_lock(&mutex);
+ std::cout << "Thread: " << signo << " : " << (void*) pthread_self() <<
std::endl;
+ pthread_mutex_unlock(&mutex);
+
+ m_NCS_IPC_DETACH(&mbox, 0, 0);
+
+ pthread_exit(0);
+}
+
+namespace {
+
+// The fixture for testing c-function sysf_ipc
+class SysfIpcTest : public ::testing::Test {
+
+ protected:
+
+ // You can remove any or all of the following functions if its body
+ // is empty.
+
+ SysfIpcTest() {
+ // You can do set-up work for each test here.
+ pthread_mutex_init(&mutex, NULL);
+ }
+
+ virtual ~SysfIpcTest() {
+ // You can do clean-up 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).
+ 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).
+ 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;
+ 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* MessageReceiver(void* args) {
+ SYSF_MBX mbox = *(SYSF_MBX*)(args);
+ NCS_SEL_OBJ mbox_fd;
+ pollfd fds;
+ // int rc;
+ Message *msg;
+
+ EXPECT_TRUE(args != NULL);
+
+ mbox_fd = ncs_ipc_get_sel_obj(&mbox);
+ //ASSERT_NE(mbox_fd, 0);
+
+ fds.fd = mbox_fd.rmv_obj;
+ fds.events = POLLIN;
+
+ while (true) {
+ int rc = poll(&fds, 1, -1);
+
+ if (rc == -1) {
+ if (errno == EINTR) {
+ continue;
+ }
+
+ std::cerr << "poll failed" << std::endl;
+ break;
+ }
+
+ if (fds.revents & POLLIN) {
+ while ((msg = reinterpret_cast<Message*>(ncs_ipc_non_blk_recv(&mbox)))
!= NULL) {
+ pthread_mutex_lock(&mutex);
+ std::cout << "MessageReceiver: " << "[" << (void*) msg <<"] " <<
msg->prio << ":" << msg->seq_no << std::endl;
+ pthread_mutex_unlock(&mutex);
+
+ if (msg->seq_no == 4711) {
+ return (void*) -1;
+ }
+ delete msg;
+
+ //ASSERT_TRUE(msg != NULL);
+ //ASSERT_EQ(msg->type, NCS_IPC_PRIORITY_VERY_HIGH);
+ //ASSERT_EQ(msg->seq_no, 1);
+ }
+ //delete msg;
+ }
+ }
+ return (void*)0;
+ }
+
+ static void* MessageSender(void* args) {
+ SYSF_MBX mbox = *(SYSF_MBX*)(args);
+ Message *msg;
+ int rc;
+ int prio;
+ srand(time(NULL));
+
+ pthread_mutex_lock(&mutex);
+ std::cout << "MessageSender: thread_id=" << pthread_self() << std::endl;
+ pthread_mutex_unlock(&mutex);
+
+ rc = m_NCS_IPC_ATTACH(&mbox);
+ if (rc != NCSCC_RC_SUCCESS) {
+ pthread_mutex_lock(&mutex);
+ std::cout << "MessageSender: failed to attach, rc=" << rc << std::endl;
+ pthread_mutex_unlock(&mutex);
+ }
+
+ for (int i = 0; i < 60; ++i) {
+ msg = new Message;
+
+ pthread_mutex_lock(&mutex);
+ std::cout << "MessageSender: sending [" << (void*) msg << "]" <<
std::endl;
+ pthread_mutex_unlock(&mutex);
+
+ prio = (random() % 3) + 1;
+ msg->prio = (NCS_IPC_PRIORITY) prio;
+ msg->seq_no = i;
+ rc = m_NCS_IPC_SEND(&mbox, msg, msg->prio);
+
+ sched_yield();
+ }
+
+ //ASSERT_EQ(rc, NCSCC_RC_SUCCESS);
+
+ rc = m_NCS_IPC_DETACH(&mbox, mbox_clean, 0);
+ if (rc != NCSCC_RC_SUCCESS) {
+ pthread_mutex_lock(&mutex);
+ std::cout << "MessageSender: failed to detach, rc = : " << rc <<
std::endl;
+ pthread_mutex_unlock(&mutex);
+ }
+
+ pthread_exit(0);
+ }
+
+ // Objects declared here can be used by all tests in the test case for Foo.
+
+ //SYSF_MBX mbox;
+
+ unsigned int rc;
+};
+
+
+// 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) {
+ // create receiver thread
+ pthread_t rcvr_thread;
+ pthread_t sndr_thread[500];
+ SYSF_MBX args = mbox;
+ srand(time(NULL));
+ //int thr_id;
+ struct sigaction actions;
+ //int prio;
+
+ memset(&actions, 0, sizeof(actions));
+ sigemptyset(&actions.sa_mask);
+ actions.sa_flags = 0;
+ actions.sa_handler = sighandler;
+
+ rc = sigaction(SIGTERM, &actions, NULL);
+
+ //pthread_attr_t rcvr_attr;
+ struct sched_param param;
+
+ memset(¶m, 0, sizeof(param));
+
+ //if (prio + 1 <= 32) {
+ // param.sched_priority = prio + 1;
+ //}
+
+ //rc = pthread_attr_init(&rcvr_attr);
+ //rc = pthread_attr_setschedparam(&rcvr_attr, ¶m);
+
+ rc = pthread_create(&rcvr_thread, NULL, MessageReceiver, (void*) &args);
+ ASSERT_EQ(rc, 0);
+
+ pthread_attr_t detached_attr;
+ pthread_attr_init(&detached_attr);
+
+ pthread_attr_setdetachstate(&detached_attr, PTHREAD_CREATE_DETACHED);
+
+ for (int i = 0; i < 5; ++i) {
+ rc = pthread_create(&sndr_thread[i], &detached_attr, MessageSender,
(void*) &args);
+ ASSERT_EQ(rc, 0);
+ }
+
+ ASSERT_EQ(rc, NULL);
+
+ sleep(1);
+
+ send_msg(NCS_IPC_PRIORITY_HIGH, 4711);
+
+ pthread_join(rcvr_thread, NULL);
+
+}
+
+} // namespace
+
+int main(int argc, char **argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
------------------------------------------------------------------------------
One dashboard for servers and applications across Physical-Virtual-Cloud
Widest out-of-the-box monitoring support with 50+ applications
Performance metrics, stats and reports that give you Actionable Insights
Deep dive visibility with transaction tracing using APM Insight.
http://ad.doubleclick.net/ddm/clk/290420510;117567292;y
_______________________________________________
Opensaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel