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();
+}

------------------------------------------------------------------------------
Go from Idea to Many App Stores Faster with Intel(R) XDK
Give your users amazing mobile app experiences with Intel(R) XDK.
Use one codebase in this all-in-one HTML5 development environment.
Design, debug & build mobile apps & 2D/3D high-impact games for multiple OSs.
http://pubads.g.doubleclick.net/gampad/clk?id=254741551&iu=/4140
_______________________________________________
Opensaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to