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

Reply via email to