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(&param, 0, sizeof(param));
+
+  //if (prio + 1 <= 32) {
+  //  param.sched_priority = prio + 1;
+  //}
+
+  //rc = pthread_attr_init(&rcvr_attr);
+  //rc = pthread_attr_setschedparam(&rcvr_attr, &param);
+
+  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

Reply via email to