Compare commits

..

2 Commits

Author SHA1 Message Date
selvam krishnamoorthy
4a8bb83f03 Merge pull request #115 from sadhyama/parodus_yocto
Cherry-picked all the required checkins to bring this to yocto stable
2017-06-23 15:25:16 +05:30
Gayathri
91739f63a9 Added negative test cases for mutex.c
Added partner_id to metadata

Added partner_id check for wrp msg_type EVENT

Added test for partners_check.c

To fix build issues on ubuntu 14.04 32 bit

Fixed broken Fedora build.

Integrate valgrind

Fix valgrind errors

To fix travis build failure due to log flooding

To fix nanomsg linking issue on fedura and ubuntu 32 bit

Added log for Last Reboot reason

Logs are modified as per webpa telemetry data

Added signal handler for parodus

Fixed parodus client reconnect issue due to delay in sending keep alive

Remove simple.c integration test cases
2017-06-23 12:58:23 +05:30
41 changed files with 3550 additions and 1962 deletions

View File

@@ -8,12 +8,12 @@ compiler:
addons:
coverity_scan:
project:
name: "selvamKrish-parodus"
name: "Comcast/parodus"
description: "C implementation of the WebPA client coordinator"
notification_email: kselvam019@gmail.com
notification_email: weston_schmidt@alumni.purdue.edu
build_command_prepend: "mkdir coverity_build && cd coverity_build && cmake .."
build_command: "make"
branch_pattern: parodus_lws
branch_pattern: master
before_install:
- sudo pip install codecov
@@ -21,7 +21,7 @@ before_install:
install:
- sudo apt-get update -qq
- sudo apt-get install -y -qq libcunit1 libcunit1-dev uuid-dev valgrind
- sudo apt-get install -y -qq libcunit1 libcunit1-dev valgrind
script:
- mkdir build

View File

@@ -36,7 +36,6 @@ include_directories(${INCLUDE_DIR}
${INCLUDE_DIR}/wrp-c
${INCLUDE_DIR}/libparodus
${INCLUDE_DIR}/cimplog
${INCLUDE_DIR}/libseshat
)
# Compile options/flags
@@ -65,19 +64,31 @@ ExternalProject_Add(trower-base64
add_library(libtrower-base64 STATIC SHARED IMPORTED)
add_dependencies(libtrower-base64 trower-base64)
# libwebsocket external dependency
# nopoll external dependency
#-------------------------------------------------------------------------------
set(PATCHES_DIR ${CMAKE_CURRENT_SOURCE_DIR}/patches)
ExternalProject_Add(lws
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/_prefix/lws
GIT_REPOSITORY https://github.com/warmcat/libwebsockets.git
GIT_TAG "ed92b6dfe75ad65a78dadfa4dc96da4568d95d69"
PATCH_COMMAND patch -p1 < ${PATCHES_DIR}/lws.patch
CMAKE_ARGS += -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR}
-DCMAKE_BUILD_TYPE=DEBUG
set(NOPOLL_LOG_SRC ${PREFIX_DIR}/nopoll/src/nopoll/src/nopoll_log.c)
ExternalProject_Add(nopoll
PREFIX ${PREFIX_DIR}/nopoll
GIT_REPOSITORY https://github.com/ASPLes/nopoll.git
GIT_TAG "b18aacc06b4dc9700e0a261efc201a8e125e4328"
PATCH_COMMAND patch -p1 < ${PATCHES_DIR}/nopoll.patch
COMMAND touch NEWS README AUTHORS ChangeLog
COMMAND libtoolize --force
COMMAND aclocal
COMMAND autoheader --warnings=error
COMMAND automake --add-missing -Werror
COMMAND autoconf --force --warnings=error
CONFIGURE_COMMAND COMMAND <SOURCE_DIR>/configure --prefix=${PREFIX}
--includedir=${INCLUDE_DIR}
--libdir=${LIBRARY_DIR}
${CUSTOM_HOST}
BUILD_IN_SOURCE 1
)
add_library(libwebsockets STATIC SHARED IMPORTED)
add_dependencies(libwebsockets lws)
add_library(libnopoll STATIC SHARED IMPORTED)
add_dependencies(libnopoll nopoll)
# nanoMsg external dependency
#-------------------------------------------------------------------------------
@@ -165,22 +176,6 @@ ExternalProject_Add(libparodus
add_library(liblibparodus STATIC SHARED IMPORTED)
add_dependencies(liblibparodus libparodus)
# libseshat external dependency
#-------------------------------------------------------------------------------
ExternalProject_Add(libseshat
DEPENDS cJSON trower-base64 msgpack wrp-c
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/_prefix/libseshat
GIT_REPOSITORY https://github.com/comcast/seshat.git
CMAKE_ARGS += -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR}
-DMAIN_PROJ_BUILD=ON
-DMAIN_PROJ_LIB_PATH=${LIBRARY_DIR}
-DMAIN_PROJ_LIB64_PATH=${LIBRARY_DIR64}
-DMAIN_PROJ_COMMON_PATH=${COMMON_LIBRARY_DIR}
-DMAIN_PROJ_INCLUDE_PATH=${INCLUDE_DIR}
)
add_library(liblibseshat STATIC SHARED IMPORTED)
add_dependencies(liblibseshat libseshat)
if (BUILD_TESTING)
# cmocka external dependency
#-------------------------------------------------------------------------------

View File

@@ -1,57 +0,0 @@
diff --git a/lib/client-parser.c b/lib/client-parser.c
index b979c62..79b25be 100644
--- a/lib/client-parser.c
+++ b/lib/client-parser.c
@@ -439,6 +439,7 @@ spill:
/* get it sent as soon as possible */
lws_callback_on_writable(wsi);
+ callback_action = LWS_CALLBACK_CLIENT_RECEIVE_PING;
ping_drop:
wsi->u.ws.rx_ubuf_head = 0;
handled = 1;
@@ -494,7 +495,7 @@ ping_drop:
* It's nicely buffered with the pre-padding taken care of
* so it can be sent straight out again using lws_write
*/
- if (handled)
+ if (handled && callback_action != LWS_CALLBACK_CLIENT_RECEIVE_PING)
goto already_done;
eff_buf.token = &wsi->u.ws.rx_ubuf[LWS_PRE];
@@ -533,7 +534,7 @@ utf8_fail: lwsl_info("utf8 error\n");
}
if (eff_buf.token_len < 0 &&
- callback_action != LWS_CALLBACK_CLIENT_RECEIVE_PONG)
+ callback_action != LWS_CALLBACK_CLIENT_RECEIVE_PONG && callback_action != LWS_CALLBACK_CLIENT_RECEIVE_PING)
goto already_done;
if (!eff_buf.token)
diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h
index 23d6588..2081b0a 100644
--- a/lib/libwebsockets.h
+++ b/lib/libwebsockets.h
@@ -1235,6 +1235,8 @@ enum lws_callback_reasons {
/**< RAW mode file is writeable */
LWS_CALLBACK_RAW_CLOSE_FILE = 66,
/**< RAW mode wsi that adopted a file is closing */
+ LWS_CALLBACK_CLIENT_RECEIVE_PING = 67,
+ /**< clients receive PING packets with this callback reason */
/****** add new things just above ---^ ******/
diff --git a/lib/ssl.c b/lib/ssl.c
index 651757f..d928afc 100644
--- a/lib/ssl.c
+++ b/lib/ssl.c
@@ -378,6 +378,9 @@ lws_ssl_capable_read(struct lws *wsi, unsigned char *buf, int len)
lwsl_debug("%p: SSL_read says %d\n", wsi, n);
/* manpage: returning 0 means connection shut down */
if (!n) {
+ /* Setting close reason for SSL socket close from server */
+ wsi->vhost->protocols->callback(wsi, LWS_CALLBACK_WS_PEER_INITIATED_CLOSE,
+ wsi->user_space, "SSL_Socket_Close", 16 );
n = lws_ssl_get_error(wsi, n);
lwsl_debug("%p: ssl err %d errno %d\n", wsi, n, errno);
if (n == SSL_ERROR_ZERO_RETURN)

1495
patches/nopoll.patch Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -11,7 +11,7 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set(SOURCES main.c lws_handlers.c ParodusInternal.c
set(SOURCES main.c mutex.c networking.c nopoll_helpers.c nopoll_handlers.c ParodusInternal.c
string_helpers.c time.c config.c conn_interface.c connection.c spin_thread.c client_list.c service_alive.c upstream.c downstream.c thread_tasks.c partners_check.c)
add_executable(parodus ${SOURCES})
@@ -21,8 +21,7 @@ target_link_libraries (parodus
-lwrp-c
-lmsgpackc
-ltrower-base64
-llibseshat
-luuid
-lnopoll
-lm
-lcimplog
-lssl
@@ -31,6 +30,5 @@ target_link_libraries (parodus
-lcjson
-lpthread
-lrt
-lwebsockets
)
install (TARGETS parodus DESTINATION bin)

View File

@@ -74,7 +74,8 @@ char* getWebpaConveyHeader()
buffer = cJSON_PrintUnformatted(response);
ParodusInfo("X-WebPA-Convey Header: [%zd]%s\n", strlen(buffer), buffer);
if(lws_b64_encode_string (buffer, strlen(buffer), encodedData, encodedDataSize) < 0)
if(nopoll_base64_encode (buffer, strlen(buffer), encodedData, &encodedDataSize) != nopoll_true)
{
ParodusError("Base64 Encoding failed for Connection Header\n");
}

View File

@@ -25,10 +25,10 @@
#include <sys/wait.h>
#include <cJSON.h>
#include <nopoll.h>
#include <nanomsg/nn.h>
#include <nanomsg/pipeline.h>
#include <wrp-c.h>
#include <libwebsockets.h>
#include "parodus_log.h"
/*----------------------------------------------------------------------------*/
@@ -50,6 +50,7 @@ extern int numLoops;
typedef struct ParodusMsg__
{
noPollMsg * msg;
void * payload;
size_t len;
struct ParodusMsg__ *next;
@@ -69,6 +70,8 @@ int numLoops;
extern "C" {
#endif
int checkHostIp(char * serverIP);
void parStrncpy(char *destStr, const char *srcStr, size_t destSize);
char* getWebpaConveyHeader();

View File

@@ -32,7 +32,6 @@ void set_parodus_cfg(ParodusCfg *cfg)
void parseCommandLine(int argc,char **argv,ParodusCfg * cfg)
{
int c;
while (1)
{
static struct option long_options[] = {
@@ -49,12 +48,11 @@ void parseCommandLine(int argc,char **argv,ParodusCfg * cfg)
{"webpa-inteface-used", required_argument, 0, 'i'},
{"parodus-local-url", required_argument, 0, 'l'},
{"partner-id", required_argument, 0, 'p'},
{"seshat-url", required_argument, 0, 'e'},
{0, 0, 0, 0}
};
/* getopt_long stores the option index here. */
int option_index = 0;
c = getopt_long (argc, argv, "m:s:f:d:r:n:b:u:t:o:i:l:p:e:",long_options, &option_index);
c = getopt_long (argc, argv, "m:s:f:d:r:n:b:u:t:o:i:l:p:",long_options, &option_index);
/* Detect the end of the options. */
if (c == -1)
@@ -81,12 +79,7 @@ void parseCommandLine(int argc,char **argv,ParodusCfg * cfg)
parStrncpy(cfg->hw_mac, optarg,sizeof(cfg->hw_mac));
ParodusInfo("hw_mac is %s\n",cfg->hw_mac);
break;
case 'e':
parStrncpy(cfg->seshat_url, optarg,sizeof(cfg->seshat_url));
ParodusInfo("seshat_url is %s\n",cfg->seshat_url);
break;
case 'r':
parStrncpy(cfg->hw_last_reboot_reason, optarg,sizeof(cfg->hw_last_reboot_reason));
ParodusInfo("hw_last_reboot_reason is %s\n",cfg->hw_last_reboot_reason);
@@ -249,16 +242,6 @@ void loadParodusCfg(ParodusCfg * config,ParodusCfg *cfg)
ParodusPrint("partner_id is NULL. read from tmp file\n");
}
if( strlen(pConfig->seshat_url) !=0)
{
strncpy(cfg->seshat_url, pConfig->seshat_url,strlen(pConfig->seshat_url)+1);
}
else
{
ParodusInfo("seshat_url is NULL. Read from tmp file\n");
}
cfg->boot_time = pConfig->boot_time;
cfg->secureFlag = 1;
cfg->webpa_ping_timeout = pConfig->webpa_ping_timeout;

View File

@@ -61,7 +61,6 @@ typedef struct
unsigned int secureFlag;
char local_url[124];
char partner_id[64];
char seshat_url[128];
} ParodusCfg;
/*----------------------------------------------------------------------------*/

View File

@@ -13,40 +13,50 @@
#include "upstream.h"
#include "downstream.h"
#include "thread_tasks.h"
#include "nopoll_helpers.h"
#include "mutex.h"
#include "spin_thread.h"
#include "service_alive.h"
#include <libseshat.h>
#include <libwebsockets.h>
/*----------------------------------------------------------------------------*/
/* Macros */
/*----------------------------------------------------------------------------*/
#define HEARTBEAT_RETRY_SEC 30 /* Heartbeat (ping/pong) timeout in seconds */
#define SESHAT_SERVICE_NAME "Parodus"
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
bool close_retry = false;
bool LastReasonStatus = false;
volatile unsigned int heartBeatTimer = 0;
/*----------------------------------------------------------------------------*/
/* Function Prototypes */
/*----------------------------------------------------------------------------*/
pthread_mutex_t close_mut=PTHREAD_MUTEX_INITIALIZER;
static bool __registerWithSeshat(void);
static void *heartBeatHandlerTask();
/*----------------------------------------------------------------------------*/
/* External Functions */
/*----------------------------------------------------------------------------*/
void createLWSsocket(void *config_in, void (* initKeypress)())
void createSocketConnection(void *config_in, void (* initKeypress)())
{
bool seshat_registered = false;
int intTimer=0;
ParodusCfg *tmpCfg = (ParodusCfg*)config_in;
noPollCtx *ctx;
loadParodusCfg(tmpCfg,get_parodus_cfg());
createLWSconnection();
ParodusPrint("Configure nopoll thread handlers in Parodus\n");
nopoll_thread_handlers(&createMutex, &destroyMutex, &lockMutex, &unlockMutex);
ctx = nopoll_ctx_new();
if (!ctx)
{
ParodusError("\nError creating nopoll context\n");
}
#ifdef NOPOLL_LOGGER
nopoll_log_set_handler (ctx, __report_log, NULL);
#endif
createNopollConnection(ctx);
packMetaData();
UpStreamMsgQ = NULL;
@@ -54,7 +64,6 @@ void createLWSsocket(void *config_in, void (* initKeypress)())
StartThread(processUpstreamMessage);
ParodusMsgQ = NULL;
StartThread(messageHandlerTask);
StartThread(heartBeatHandlerTask);
StartThread(serviceAliveTask);
if (NULL != initKeypress)
@@ -62,98 +71,47 @@ void createLWSsocket(void *config_in, void (* initKeypress)())
(* initKeypress) ();
}
seshat_registered = __registerWithSeshat();
UNUSED(seshat_registered);
do
{
lws_service(get_global_context(), 50);
if(conn_retry)
nopoll_loop_wait(ctx, 5000000);
intTimer = intTimer + 5;
if(heartBeatTimer >= get_parodus_cfg()->webpa_ping_timeout)
{
wsi_dumb = NULL;
lws_context_destroy(get_global_context());
ParodusInfo("conn_retry is %d, hence closing the connection and retrying\n", conn_retry);
createLWSconnection();
}
}while(!conn_retry);
lws_context_destroy(get_global_context());
}
/*----------------------------------------------------------------------------*/
/* Internal functions */
/*----------------------------------------------------------------------------*/
/**
* @brief Helper function to register with seshat.
*
* @note return whether successfully registered.
*
* @return true when registered, false otherwise.
*/
static bool __registerWithSeshat()
{
char *seshat_url = get_parodus_cfg()->seshat_url;
char *parodus_url = get_parodus_cfg()->local_url;
char *discover_url = NULL;
bool rv = false;
if( 0 == init_lib_seshat(seshat_url) ) {
ParodusInfo("seshatlib initialized! (url %s)\n", seshat_url);
if( 0 == seshat_register(SESHAT_SERVICE_NAME, parodus_url) ) {
ParodusInfo("seshatlib registered! (url %s)\n", parodus_url);
discover_url = seshat_discover(SESHAT_SERVICE_NAME);
if( (NULL != discover_url) && (0 == strcmp(parodus_url, discover_url)) ) {
ParodusInfo("seshatlib discovered url = %s\n", discover_url);
rv = true;
} else {
ParodusError("seshatlib registration error (url %s)!", discover_url);
}
free(discover_url);
} else {
ParodusError("seshatlib not registered! (url %s)\n", parodus_url);
}
} else {
ParodusPrint("seshatlib not initialized! (url %s)\n", seshat_url);
}
shutdown_seshat_lib();
return rv;
}
/*
* @brief To handle heartbeat mechanism
*/
static void *heartBeatHandlerTask()
{
while (FOREVER())
{
sleep(HEARTBEAT_RETRY_SEC);
if(heartBeatTimer >= get_parodus_cfg()->webpa_ping_timeout)
{
if(!conn_retry)
if(!close_retry)
{
ParodusError("ping wait time > %d. Terminating the connection with WebPA server and retrying\n", get_parodus_cfg()->webpa_ping_timeout);
ParodusInfo("Reconnect detected, setting Ping_Miss reason for Reconnect\n");
set_global_reconnect_reason("Ping_Miss");
LastReasonStatus = true;
conn_retry = true;
pthread_mutex_lock (&close_mut);
close_retry = true;
pthread_mutex_unlock (&close_mut);
}
else
{
ParodusPrint("heartBeatHandler - conn_retry set to %d, hence resetting the heartBeatTimer\n",conn_retry);
{
ParodusPrint("heartBeatHandler - close_retry set to %d, hence resetting the heartBeatTimer\n",close_retry);
}
heartBeatTimer = 0;
}
else
else if(intTimer >= 30)
{
ParodusPrint("heartBeatTimer %d\n",heartBeatTimer);
heartBeatTimer += HEARTBEAT_RETRY_SEC;
heartBeatTimer += HEARTBEAT_RETRY_SEC;
intTimer = 0;
}
}
heartBeatTimer = 0;
return NULL;
if(close_retry)
{
ParodusInfo("close_retry is %d, hence closing the connection and retrying\n", close_retry);
close_and_unref_connection(get_global_conn());
set_global_conn(NULL);
createNopollConnection(ctx);
}
} while(!close_retry);
close_and_unref_connection(get_global_conn());
nopoll_ctx_unref(ctx);
nopoll_cleanup_library();
}

View File

@@ -30,7 +30,7 @@ extern UpStreamMsg *UpStreamMsgQ;
* Loads the WebPA config file, if not provided by the caller,
* and creates the intial connection and manages the connection wait, close mechanisms.
*/
void createLWSsocket(void *config_in, void (* initKeypress)());
void createSocketConnection(void *config_in, void (* initKeypress)());
#ifdef __cplusplus
}

View File

@@ -9,15 +9,15 @@
#include "connection.h"
#include "time.h"
#include "config.h"
#include "upstream.h"
#include "nopoll_helpers.h"
#include "mutex.h"
#include "spin_thread.h"
#include "lws_handlers.h"
/*----------------------------------------------------------------------------*/
/* Macros */
/*----------------------------------------------------------------------------*/
#define MAX_PAYLOAD 102400
#define HTTP_CUSTOM_HEADER_COUNT 4
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
@@ -25,27 +25,20 @@
char deviceMAC[32]={'\0'};
static char *reconnect_reason = "webpa_process_starts";
static struct lws_context *g_context;
struct lws *wsi_dumb;
pthread_mutex_t res_mutex ;
bool conn_retry = true;
char * fragmentMsg = NULL;
int fragmentSize = 0;
int payloadSize = 0;
static noPollConn *g_conn = NULL;
/*----------------------------------------------------------------------------*/
/* External Functions */
/*----------------------------------------------------------------------------*/
struct lws_context *get_global_context(void)
noPollConn *get_global_conn(void)
{
return g_context;
return g_conn;
}
void set_global_context(struct lws_context *contextRef)
void set_global_conn(noPollConn *conn)
{
g_context = contextRef;
g_conn = conn;
}
char *get_global_reconnect_reason()
@@ -58,255 +51,245 @@ void set_global_reconnect_reason(char *reason)
reconnect_reason = reason;
}
char * join_fragment_msg (char *firstMsg,int firstSize,char *secondMsg,int secondSize,int * result)
/**
* @brief createNopollConnection interface to create WebSocket client connections.
*Loads the WebPA config file and creates the intial connection and manages the connection wait, close mechanisms.
*/
int createNopollConnection(noPollCtx *ctx)
{
*result = firstSize + secondSize;
fragmentSize = *result;
char *tmpMsg = (char *)malloc(sizeof(char)* (*result));
memcpy(tmpMsg,firstMsg,firstSize);
memcpy (tmpMsg + (firstSize), secondMsg, secondSize);
free(firstMsg);
free(secondMsg);
return tmpMsg;
}
int parodus_callback(struct lws *wsi, enum lws_callback_reasons reason,void *user, void *in, size_t len)
{
int n;
char * payload = NULL;
unsigned char * out = NULL;
switch (reason) {
case LWS_CALLBACK_CLIENT_ESTABLISHED:
ParodusInfo("Connected to server successfully\n");
conn_retry = false;
break;
case LWS_CALLBACK_CLOSED:
ParodusInfo("Callback closed, websocket session ends \n");
if(!LastReasonStatus)
{
ParodusInfo("Setting reconnect reason as Unknown\n");
set_global_reconnect_reason("Unknown");
}
wsi_dumb = NULL;
conn_retry = true;
break;
bool initial_retry = false;
int backoffRetryTime = 0;
int max_retry_sleep;
char device_id[32]={'\0'};
char user_agent[512]={'\0'};
const char * headerNames[HTTP_CUSTOM_HEADER_COUNT] = {"X-WebPA-Device-Name","X-WebPA-Device-Protocols","User-Agent", "X-WebPA-Convey"};
const char *headerValues[HTTP_CUSTOM_HEADER_COUNT];
int headerCount = HTTP_CUSTOM_HEADER_COUNT; /* Invalid X-Webpa-Convey header Bug # WEBPA-787 */
char port[8];
noPollConnOpts * opts;
char server_Address[256];
char redirectURL[128]={'\0'};
char *temp_ptr, *conveyHeader;
int connErr=0;
struct timespec connErr_start,connErr_end,*connErr_startPtr,*connErr_endPtr;
connErr_startPtr = &connErr_start;
connErr_endPtr = &connErr_end;
//Retry Backoff count shall start at c=2 & calculate 2^c - 1.
int c=2;
case LWS_CALLBACK_CLIENT_RECEIVE:
((char *)in)[len] = '\0';
//ParodusInfo("length %d payload : %s\n", (int)len, (char *)in);
if(ctx == NULL) {
return nopoll_false;
}
ParodusInfo("**** Recieved %d bytes from server\n",(int)len);
char * tmpMsg = NULL;
payload = (char *)malloc(sizeof(char)*len);
strcpy(payload,(char *)in);
FILE *fp;
fp = fopen("/tmp/parodus_ready", "r");
if (lws_is_final_fragment(wsi))
{
if (fp!=NULL)
{
unlink("/tmp/parodus_ready");
ParodusPrint("Closing Parodus_Ready FIle \n");
fclose(fp);
}
if(fragmentMsg == NULL)
{
listenerOnrequest_queue(payload,len);
}
else
{
tmpMsg = join_fragment_msg(fragmentMsg,fragmentSize,payload,len,&payloadSize);
len = payloadSize;
listenerOnrequest_queue(tmpMsg,len);
fragmentMsg = NULL;
fragmentSize = 0;
payloadSize = 0;
}
}
else
{
if(fragmentMsg == NULL)
{
fragmentMsg = payload;
fragmentSize = len;
}
else
{
fragmentMsg = join_fragment_msg(fragmentMsg,fragmentSize,payload,len,&payloadSize);
}
}
lws_callback_on_writable(wsi);
break;
parStrncpy(deviceMAC, get_parodus_cfg()->hw_mac,sizeof(deviceMAC));
snprintf(device_id, sizeof(device_id), "mac:%s", deviceMAC);
ParodusInfo("Device_id %s\n",device_id);
case LWS_CALLBACK_CLIENT_CONNECTION_ERROR:
ParodusError("***** Failed to Connected to server *******\n");
wsi_dumb = NULL;
conn_retry = true;
break;
case LWS_CALLBACK_WS_PEER_INITIATED_CLOSE:
ParodusInfo("Received server socket close\n");
if( (NULL != (char *)in) && (0 == strcmp((char *)in, "SSL_Socket_Close")) )
{
ParodusInfo("Last close reason received is %s\n", (char *)in);
set_global_reconnect_reason("Server_closed_connection");
LastReasonStatus = true;
}
break;
case LWS_CALLBACK_CLIENT_WRITEABLE:
// Call back to send response to server
if(ResponseMsgQ != NULL)
{
//Read response data from queue
while(ResponseMsgQ)
{
pthread_mutex_lock (&res_mutex);
UpStreamMsg *message = ResponseMsgQ;
ResponseMsgQ = ResponseMsgQ->next;
pthread_mutex_unlock (&res_mutex);
out = (unsigned char *)malloc(sizeof(unsigned char) * (LWS_PRE + message->len));
memcpy (LWS_PRE + out, message->msg, message->len);
n = lws_write(wsi, LWS_PRE + out, message->len, LWS_WRITE_BINARY);
if (n < 0)
{
ParodusError("Failed to send to server\n");
free(message->msg);
message->msg = NULL;
return 1;
}
if (n < (int)message->len) {
ParodusError("Partial write\n");
return -1;
}
ParodusInfo("Sent %d bytes of data to server successfully \n",n);
free(out);
free(message->msg);
message->msg = NULL;
}
}
lws_callback_on_writable(wsi);
break;
case LWS_CALLBACK_CLIENT_RECEIVE_PING:
ParodusInfo("Resetting HeartBeat Timer\n");
heartBeatTimer = 0;
break;
case LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER:
//Call back to send custom header to server
ParodusPrint("Send custom header to server\n");
char device_id[32]={'\0'};
char user_agent[512]={'\0'};
char *conveyHeader;
unsigned char **p = (unsigned char **)in, *end = (*p) + len;
strncpy(deviceMAC, get_parodus_cfg()->hw_mac,sizeof(deviceMAC));
snprintf(device_id, sizeof(device_id), "mac:%s", deviceMAC);
snprintf(user_agent, sizeof(user_agent),"%s (%s; %s/%s;)",
headerValues[0] = device_id;
headerValues[1] = "wrp-0.11,getset-0.1";
ParodusPrint("BootTime In sec: %d\n", get_parodus_cfg()->boot_time);
ParodusInfo("Received reboot_reason as:%s\n", get_parodus_cfg()->hw_last_reboot_reason);
ParodusInfo("Received reconnect_reason as:%s\n", reconnect_reason);
snprintf(user_agent, sizeof(user_agent),
"%s (%s; %s/%s;)",
((0 != strlen(get_parodus_cfg()->webpa_protocol)) ? get_parodus_cfg()->webpa_protocol : "unknown"),
((0 != strlen(get_parodus_cfg()->fw_name)) ? get_parodus_cfg()->fw_name : "unknown"),
((0 != strlen(get_parodus_cfg()->hw_model)) ? get_parodus_cfg()->hw_model : "unknown"),
((0 != strlen(get_parodus_cfg()->hw_manufacturer)) ? get_parodus_cfg()->hw_manufacturer : "unknown"));
ParodusInfo("User-Agent: %s\n",user_agent);
conveyHeader = getWebpaConveyHeader();
if (lws_add_http_header_by_name(wsi,
(unsigned char *)"X-WebPA-Device-Name:",
(unsigned char *)device_id,strlen(device_id),p,end))
return -1;
if (lws_add_http_header_by_name(wsi,
(unsigned char *)"X-WebPA-Device-Protocols:",
(unsigned char *)"wrp-0.11,getset-0.1",strlen("wrp-0.11,getset-0.1"),p,end))
return -1;
if (lws_add_http_header_by_name(wsi,
(unsigned char *)"User-Agent:",
(unsigned char *)user_agent,strlen(user_agent),p,end))
return -1;
if(strlen(conveyHeader) > 0)
{
if (lws_add_http_header_by_name(wsi,
(unsigned char *)"X-WebPA-Convey:",
(unsigned char *)conveyHeader,strlen(conveyHeader),p,end))
return -1;
}
break;
case LWS_CALLBACK_OPENSSL_PERFORM_SERVER_CERT_VERIFICATION:
/* Disable self signed verification */
X509_STORE_CTX_set_error((X509_STORE_CTX*)user, X509_V_OK);
return 0;
break;
default:
break;
}
return 0;
}
static const struct lws_protocols protocols[] = {
ParodusInfo("User-Agent: %s\n",user_agent);
headerValues[2] = user_agent;
conveyHeader = getWebpaConveyHeader();
if(strlen(conveyHeader) > 0)
{
NULL,
parodus_callback,
0,
MAX_PAYLOAD,
},
{ NULL, NULL, 0, 0 } /* end */
};
LWS_VISIBLE void lwsl_emit_syslog(int level, const char *line)
{
UNUSED(level);
ParodusInfo(" %s",line);
}
void createLWSconnection()
{
struct lws_context_creation_info info;
struct lws_client_connect_info i;
struct lws_context *context;
int port = 8080,use_ssl =0;
memset(&info, 0, sizeof info);
memset(&i, 0, sizeof(i));
use_ssl = LCCSCF_USE_SSL;
info.port = CONTEXT_PORT_NO_LISTEN;
info.protocols = protocols;
info.gid = -1;
info.uid = -1;
info.iface = get_parodus_cfg()->webpa_interface_used;
lws_set_log_level(LLL_INFO | LLL_NOTICE | LLL_WARN | LLL_LATENCY | LLL_CLIENT | LLL_COUNT,lwsl_emit_syslog);
info.options |= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
context = lws_create_context(&info);
if (context == NULL) {
ParodusError("Creating libwebsocket context failed\n");
exit(1);
headerValues[3] = conveyHeader;
}
set_global_context(context);
i.port = port;
i.address = get_parodus_cfg()->webpa_url;
i.context = context;
i.ssl_connection = use_ssl;
i.host = i.address;
i.path = "/api/v2/device";
while(1)
else
{
if (!wsi_dumb)
{
ParodusInfo("Connecting to server..\n");
i.pwsi = &wsi_dumb;
lws_client_connect_via_info(&i);
}
/*We need lws service here till client connects to server, without lws_service callback will not work*/
lws_service(context, 500);
if(!conn_retry)
/*Connected to server, break the loop and try lws service from main thread*/
break;
headerValues[3] = "";
headerCount -= 1;
}
snprintf(port,sizeof(port),"%d",8080);
parStrncpy(server_Address, get_parodus_cfg()->webpa_url, sizeof(server_Address));
ParodusInfo("server_Address %s\n",server_Address);
max_retry_sleep = (int) pow(2, get_parodus_cfg()->webpa_backoff_max) -1;
ParodusPrint("max_retry_sleep is %d\n", max_retry_sleep );
do
{
//calculate backoffRetryTime and to perform exponential increment during retry
if(backoffRetryTime < max_retry_sleep)
{
backoffRetryTime = (int) pow(2, c) -1;
}
ParodusPrint("New backoffRetryTime value calculated as %d seconds\n", backoffRetryTime);
noPollConn *connection;
if(get_parodus_cfg()->secureFlag)
{
ParodusPrint("secure true\n");
/* disable verification */
opts = nopoll_conn_opts_new ();
nopoll_conn_opts_ssl_peer_verify (opts, nopoll_false);
nopoll_conn_opts_set_ssl_protocol (opts, NOPOLL_METHOD_TLSV1_2);
connection = nopoll_conn_tls_new(ctx, opts, server_Address, port, NULL,
get_parodus_cfg()->webpa_path_url, NULL, NULL, get_parodus_cfg()->webpa_interface_used,
headerNames, headerValues, headerCount);// WEBPA-787
}
else
{
ParodusPrint("secure false\n");
connection = nopoll_conn_new(ctx, server_Address, port, NULL,
get_parodus_cfg()->webpa_path_url, NULL, NULL, get_parodus_cfg()->webpa_interface_used,
headerNames, headerValues, headerCount);// WEBPA-787
}
set_global_conn(connection);
if(get_global_conn() != NULL)
{
if(!nopoll_conn_is_ok(get_global_conn()))
{
ParodusError("Error connecting to server\n");
ParodusError("RDK-10037 - WebPA Connection Lost\n");
// Copy the server address from config to avoid retrying to the same failing talaria redirected node
parStrncpy(server_Address, get_parodus_cfg()->webpa_url, sizeof(server_Address));
close_and_unref_connection(get_global_conn());
set_global_conn(NULL);
initial_retry = true;
ParodusInfo("Waiting with backoffRetryTime %d seconds\n", backoffRetryTime);
sleep(backoffRetryTime);
continue;
}
else
{
ParodusPrint("Connected to Server but not yet ready\n");
initial_retry = false;
//reset backoffRetryTime back to the starting value, as next reason can be different
c = 2;
backoffRetryTime = (int) pow(2, c) -1;
}
if(!nopoll_conn_wait_until_connection_ready(get_global_conn(), 10, redirectURL))
{
if (strncmp(redirectURL, "Redirect:", 9) == 0) // only when there is a http redirect
{
ParodusError("Received temporary redirection response message %s\n", redirectURL);
// Extract server Address and port from the redirectURL
temp_ptr = strtok(redirectURL , ":"); //skip Redirect
temp_ptr = strtok(NULL , ":"); // skip https
temp_ptr = strtok(NULL , ":");
parStrncpy(server_Address, temp_ptr+2, sizeof(server_Address));
parStrncpy(port, strtok(NULL , "/"), sizeof(port));
ParodusInfo("Trying to Connect to new Redirected server : %s with port : %s\n", server_Address, port);
//reset c=2 to start backoffRetryTime as retrying using new redirect server
c = 2;
}
else
{
ParodusError("Client connection timeout\n");
ParodusError("RDK-10037 - WebPA Connection Lost\n");
// Copy the server address from config to avoid retrying to the same failing talaria redirected node
parStrncpy(server_Address, get_parodus_cfg()->webpa_url, sizeof(server_Address));
ParodusInfo("Waiting with backoffRetryTime %d seconds\n", backoffRetryTime);
sleep(backoffRetryTime);
c++;
}
close_and_unref_connection(get_global_conn());
set_global_conn(NULL);
initial_retry = true;
}
else
{
initial_retry = false;
ParodusInfo("Connection is ready\n");
}
}
else
{
/* If the connect error is due to DNS resolving to 10.0.0.1 then start timer.
* Timeout after 15 minutes if the error repeats continuously and kill itself.
*/
if((checkHostIp(server_Address) == -2))
{
if(connErr == 0)
{
getCurrentTime(connErr_startPtr);
connErr = 1;
ParodusInfo("First connect error occurred, initialized the connect error timer\n");
}
else
{
getCurrentTime(connErr_endPtr);
ParodusPrint("checking timeout difference:%ld\n", timeValDiff(connErr_startPtr, connErr_endPtr));
if(timeValDiff(connErr_startPtr, connErr_endPtr) >= (15*60*1000))
{
ParodusError("WebPA unable to connect due to DNS resolving to 10.0.0.1 for over 15 minutes; crashing service.\n");
reconnect_reason = "Dns_Res_webpa_reconnect";
LastReasonStatus = true;
kill(getpid(),SIGTERM);
}
}
}
initial_retry = true;
ParodusInfo("Waiting with backoffRetryTime %d seconds\n", backoffRetryTime);
sleep(backoffRetryTime);
c++;
// Copy the server address from config to avoid retrying to the same failing talaria redirected node
parStrncpy(server_Address, get_parodus_cfg()->webpa_url, sizeof(server_Address));
}
}while(initial_retry);
if(get_parodus_cfg()->secureFlag)
{
ParodusInfo("Connected to server over SSL\n");
}
else
{
ParodusInfo("Connected to server\n");
}
// Reset close_retry flag and heartbeatTimer once the connection retry is successful
ParodusPrint("createNopollConnection(): close_mut lock\n");
pthread_mutex_lock (&close_mut);
close_retry = false;
pthread_mutex_unlock (&close_mut);
ParodusPrint("createNopollConnection(): close_mut unlock\n");
heartBeatTimer = 0;
// Reset connErr flag on successful connection
connErr = 0;
reconnect_reason = "webpa_process_starts";
LastReasonStatus =false;
ParodusPrint("LastReasonStatus reset after successful connection\n");
setMessageHandlers();
return nopoll_true;
}
void close_and_unref_connection(noPollConn *conn)
{
if (conn) {
nopoll_conn_close(conn);
if (0 < nopoll_conn_ref_count (conn)) {
nopoll_conn_unref(conn);
}
}
}

View File

@@ -19,23 +19,26 @@ extern "C" {
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
extern bool conn_retry;
extern bool close_retry;
extern volatile unsigned int heartBeatTimer;
extern struct lws *wsi_dumb;
extern pthread_mutex_t close_mut;
/*----------------------------------------------------------------------------*/
/* Function Prototypes */
/*----------------------------------------------------------------------------*/
int createNopollConnection(noPollCtx *);
/**
* @brief Interface to terminate WebSocket client connections and clean up resources.
*/
int parodus_callback(struct lws *wsi, enum lws_callback_reasons reason,void *user, void *in, size_t len);
void close_and_unref_connection(noPollConn *);
noPollConn *get_global_conn(void);
void set_global_conn(noPollConn *);
char *get_global_reconnect_reason();
void set_global_reconnect_reason(char *reason);
void createLWSconnection();
struct lws_context *get_global_context(void);
void set_global_context(struct lws_context *contextRef);
#ifdef __cplusplus
}

View File

@@ -145,7 +145,6 @@ void listenerOnMessage(void * msg, size_t msgSize)
ParodusError( "Failure in msgpack decoding for receivdMsg: rv is %d\n", rv );
}
ParodusPrint("free for downstream decoded msg\n");
free(msg);
wrp_free_struct(message);
}
}

View File

@@ -1,75 +0,0 @@
/**
* @file lws_handlers.c
*
* @description This describes lws handler functions.
*
* Copyright (c) 2015 Comcast
*/
#include "ParodusInternal.h"
#include "lws_handlers.h"
#include "connection.h"
/*----------------------------------------------------------------------------*/
/* Macros */
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
pthread_mutex_t g_mutex=PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t g_cond=PTHREAD_COND_INITIALIZER;
ParodusMsg *ParodusMsgQ = NULL;
/*----------------------------------------------------------------------------*/
/* External Functions */
/*----------------------------------------------------------------------------*/
/**
* @brief listenerOnrequest_queue function to add messages to the queue
*
* @param[in] reqSize size of the incoming message
* @param[in] requestMsg The message received from server for various process requests
*/
void listenerOnrequest_queue(void *requestMsg,int reqSize)
{
ParodusMsg *message;
message = (ParodusMsg *)malloc(sizeof(ParodusMsg));
if(message)
{
message->payload = requestMsg;
message->len = reqSize;
message->next = NULL;
pthread_mutex_lock (&g_mutex);
ParodusPrint("mutex lock in producer thread\n");
if(ParodusMsgQ == NULL)
{
ParodusMsgQ = message;
ParodusPrint("Producer added message\n");
pthread_cond_signal(&g_cond);
pthread_mutex_unlock (&g_mutex);
ParodusPrint("mutex unlock in producer thread\n");
}
else
{
ParodusMsg *temp = ParodusMsgQ;
while(temp->next)
{
temp = temp->next;
}
temp->next = message;
pthread_mutex_unlock (&g_mutex);
}
}
else
{
//Memory allocation failed
ParodusError("Memory allocation is failed\n");
}
ParodusPrint("*****listenerOnrequest_queue*****\n");
}

View File

@@ -1,40 +0,0 @@
/**
* @file lws_handlers.h
*
* @description This header defines lws handler functions.
*
* Copyright (c) 2015 Comcast
*/
#ifndef _LWS_HANDLERS_H_
#define _LWS_HANDLERS_H_
#ifdef __cplusplus
extern "C" {
#endif
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
extern pthread_mutex_t g_mutex;
extern pthread_cond_t g_cond;
/*----------------------------------------------------------------------------*/
/* Function Prototypes */
/*----------------------------------------------------------------------------*/
/**
* @brief listenerOnrequest_queue function to add messages to the queue
*
* @param[in] reqSize size of the incoming message
* @param[in] requestMsg The message received from server for various process requests
*/
void listenerOnrequest_queue(void *requestMsg,int reqSize);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -66,7 +66,7 @@ int main( int argc, char **argv)
ParodusInfo("********** Starting component: Parodus **********\n ");
parseCommandLine(argc,argv,&parodusCfg);
createLWSsocket(&parodusCfg,NULL);
createSocketConnection(&parodusCfg,NULL);
return 0;
}

159
src/mutex.c Normal file
View File

@@ -0,0 +1,159 @@
/**
* Copyright 2016 Comcast Cable Communications Management, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include "mutex.h"
#include "parodus_log.h"
/*----------------------------------------------------------------------------*/
/* Macros */
/*----------------------------------------------------------------------------*/
/* none */
/*----------------------------------------------------------------------------*/
/* Data Structures */
/*----------------------------------------------------------------------------*/
/* none */
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
/* none */
/*----------------------------------------------------------------------------*/
/* Function Prototypes */
/*----------------------------------------------------------------------------*/
/* none */
/*----------------------------------------------------------------------------*/
/* External Functions */
/*----------------------------------------------------------------------------*/
/**
* @brief createMutex Nopoll create mutex handler
*/
noPollPtr createMutex()
{
pthread_mutexattr_t attr;
pthread_mutex_t * mutex;
int rtn;
mutex = (pthread_mutex_t*) malloc(sizeof(pthread_mutex_t));
if (mutex == NULL) {
ParodusError("Failed to create mutex\n");
return NULL;
}
pthread_mutexattr_init( &attr);
/*pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_ERRORCHECK);*/
pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_RECURSIVE);
/* init the mutex using default values */
rtn = pthread_mutex_init (mutex, &attr);
pthread_mutexattr_destroy (&attr);
if (rtn != 0) {
ParodusError("Error in init Mutex\n");
free(mutex);
return NULL;
} else {
ParodusPrint("mutex init successfully\n");
}
return mutex;
}
/**
* @brief lockMutex Nopoll lock mutex handler
*/
void lockMutex(noPollPtr _mutex)
{
int rtn;
char errbuf[100];
if (_mutex == NULL) {
ParodusError("Received null mutex\n");
return;
}
pthread_mutex_t * mutex = _mutex;
/* lock the mutex */
rtn = pthread_mutex_lock (mutex);
if (rtn != 0) {
strerror_r (rtn, errbuf, 100);
ParodusError("Error in Lock mutex: %s\n", errbuf);
/* do some reporting */
return;
}
return;
}
/**
* @brief unlockMutex Nopoll unlock mutex handler
*/
void unlockMutex(noPollPtr _mutex)
{
int rtn;
char errbuf[100];
if (_mutex == NULL) {
ParodusError("Received null mutex\n");
return;
}
pthread_mutex_t * mutex = _mutex;
/* unlock mutex */
rtn = pthread_mutex_unlock (mutex);
if (rtn != 0) {
/* do some reporting */
strerror_r (rtn, errbuf, 100);
ParodusError("Error in unlock mutex: %s\n", errbuf);
return;
}
return;
}
/**
* @brief destroyMutex Nopoll destroy mutex handler
*/
void destroyMutex(noPollPtr _mutex)
{
if (_mutex == NULL) {
ParodusError("Received null mutex\n");
return;
}
pthread_mutex_t * mutex = _mutex;
if (pthread_mutex_destroy (mutex) != 0) {
/* do some reporting */
ParodusError("problem in destroy\n");
return;
} else {
ParodusPrint("Mutex destroyed \n");
}
free(mutex);
return;
}
/*----------------------------------------------------------------------------*/
/* Internal functions */
/*----------------------------------------------------------------------------*/
/* none */

58
src/mutex.h Normal file
View File

@@ -0,0 +1,58 @@
/**
* Copyright 2016 Comcast Cable Communications Management, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <nopoll.h>
#include <pthread.h>
#ifndef _MUTEX_H_
#define _MUTEX_H_
#ifdef __cplusplus
extern "C" {
#endif
/*----------------------------------------------------------------------------*/
/* Function Prototypes */
/*----------------------------------------------------------------------------*/
/**
* @brief createMutex Nopoll create mutex handler
*/
noPollPtr createMutex();
/**
* @brief lockMutex Nopoll lock mutex handler
*/
void lockMutex(noPollPtr _mutex);
/**
* @brief unlockMutex Nopoll unlock mutex handler
*/
void unlockMutex(noPollPtr _mutex);
/**
* @brief destroyMutex Nopoll destroy mutex handler
*/
void destroyMutex(noPollPtr _mutex);
#ifdef __cplusplus
}
#endif
#endif

104
src/networking.c Normal file
View File

@@ -0,0 +1,104 @@
/**
* Copyright 2016 Comcast Cable Communications Management, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include "ParodusInternal.h"
/*----------------------------------------------------------------------------*/
/* Macros */
/*----------------------------------------------------------------------------*/
/* none */
/*----------------------------------------------------------------------------*/
/* Data Structures */
/*----------------------------------------------------------------------------*/
/* none */
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
/* none */
/*----------------------------------------------------------------------------*/
/* Function Prototypes */
/*----------------------------------------------------------------------------*/
/* none */
/*----------------------------------------------------------------------------*/
/* External Functions */
/*----------------------------------------------------------------------------*/
/**
* Interface to check if the Host server DNS is resolved to an IP address that
* is not 10.0.0.1.
*
* @param[in] serverIP server address DNS
*
* @returns 0 on success, error otherwise
*/
int checkHostIp(char * serverIP)
{
int status = -1;
struct addrinfo *res, *result;
int retVal;
char addrstr[100];
void *ptr;
char *localIp = "10.0.0.1";
struct addrinfo hints;
ParodusPrint("...............Inside checkHostIp..............%s \n", serverIP);
memset(&hints,0,sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = 0;
retVal = getaddrinfo(serverIP, "http", &hints, &result);
if (retVal != 0)
{
ParodusError("getaddrinfo: %s\n", gai_strerror(retVal));
}
else
{
res = result;
while(res)
{
ptr = &((struct sockaddr_in *) res->ai_addr)->sin_addr;
inet_ntop (res->ai_family, ptr, addrstr, 100);
ParodusPrint("IPv4 address of %s is %s \n", serverIP, addrstr);
if (strcmp(localIp,addrstr) == 0)
{
ParodusPrint("Host Ip resolved to 10.0.0.1\n");
status = -2;
}
else
{
ParodusPrint("Host Ip resolved correctly, proceeding with the connection\n");
status = 0;
break;
}
res = res->ai_next;
}
freeaddrinfo(result);
}
return status;
}
/*----------------------------------------------------------------------------*/
/* Internal functions */
/*----------------------------------------------------------------------------*/
/* none */

137
src/nopoll_handlers.c Normal file
View File

@@ -0,0 +1,137 @@
/**
* @file nopoll_handlers.c
*
* @description This describes nopoll handler functions.
*
* Copyright (c) 2015 Comcast
*/
#include "ParodusInternal.h"
#include "nopoll_handlers.h"
#include "connection.h"
/*----------------------------------------------------------------------------*/
/* Macros */
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
pthread_mutex_t g_mutex=PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t g_cond=PTHREAD_COND_INITIALIZER;
ParodusMsg *ParodusMsgQ = NULL;
/*----------------------------------------------------------------------------*/
/* External Functions */
/*----------------------------------------------------------------------------*/
/**
* @brief listenerOnMessage_queue function to add messages to the queue
*
* @param[in] ctx The context where the connection happens.
* @param[in] conn The Websocket connection object
* @param[in] msg The message received from server for various process requests
* @param[out] user_data data which is to be sent
*/
void listenerOnMessage_queue(noPollCtx * ctx, noPollConn * conn, noPollMsg * msg,noPollPtr user_data)
{
UNUSED(ctx);
UNUSED(conn);
UNUSED(user_data);
ParodusMsg *message;
message = (ParodusMsg *)malloc(sizeof(ParodusMsg));
if(message)
{
message->msg = msg;
message->payload = (void *)nopoll_msg_get_payload (msg);
message->len = nopoll_msg_get_payload_size (msg);
message->next = NULL;
nopoll_msg_ref(msg);
pthread_mutex_lock (&g_mutex);
ParodusPrint("mutex lock in producer thread\n");
if(ParodusMsgQ == NULL)
{
ParodusMsgQ = message;
ParodusPrint("Producer added message\n");
pthread_cond_signal(&g_cond);
pthread_mutex_unlock (&g_mutex);
ParodusPrint("mutex unlock in producer thread\n");
}
else
{
ParodusMsg *temp = ParodusMsgQ;
while(temp->next)
{
temp = temp->next;
}
temp->next = message;
pthread_mutex_unlock (&g_mutex);
}
}
else
{
//Memory allocation failed
ParodusError("Memory allocation is failed\n");
}
ParodusPrint("*****Returned from listenerOnMessage_queue*****\n");
}
/**
* @brief listenerOnPingMessage function to create WebSocket listener to receive heartbeat ping messages
*
* @param[in] ctx The context where the connection happens.
* @param[in] conn Websocket connection object
* @param[in] msg The ping message received from the server
* @param[out] user_data data which is to be sent
*/
void listenerOnPingMessage (noPollCtx * ctx, noPollConn * conn, noPollMsg * msg, noPollPtr user_data)
{
UNUSED(ctx);
UNUSED(user_data);
noPollPtr payload = NULL;
payload = (noPollPtr ) nopoll_msg_get_payload(msg);
if ((payload!=NULL))
{
ParodusInfo("Ping received with payload %s, opcode %d\n",(char *)payload, nopoll_msg_opcode(msg));
if (nopoll_msg_opcode(msg) == NOPOLL_PING_FRAME)
{
nopoll_conn_send_frame (conn, nopoll_true, nopoll_true, NOPOLL_PONG_FRAME, strlen(payload), payload, 0);
heartBeatTimer = 0;
ParodusPrint("Sent Pong frame and reset HeartBeat Timer\n");
}
}
}
void listenerOnCloseMessage (noPollCtx * ctx, noPollConn * conn, noPollPtr user_data)
{
UNUSED(ctx);
UNUSED(conn);
ParodusPrint("listenerOnCloseMessage(): mutex lock in producer thread\n");
if((user_data != NULL) && (strstr(user_data, "SSL_Socket_Close") != NULL) && !LastReasonStatus)
{
ParodusInfo("Reconnect detected, setting Reconnect reason as Server close\n");
set_global_reconnect_reason("Server_closed_connection");
LastReasonStatus = true;
}
else if ((user_data == NULL) && !LastReasonStatus)
{
ParodusInfo("Reconnect detected, setting Reconnect reason as Unknown\n");
set_global_reconnect_reason("Unknown");
}
pthread_mutex_lock (&close_mut);
close_retry = true;
pthread_mutex_unlock (&close_mut);
ParodusPrint("listenerOnCloseMessage(): mutex unlock in producer thread\n");
}

59
src/nopoll_handlers.h Normal file
View File

@@ -0,0 +1,59 @@
/**
* @file nopoll_handlers.h
*
* @description This header defines nopoll handler functions.
*
* Copyright (c) 2015 Comcast
*/
#ifndef _NOPOLL_HANDLERS_H_
#define _NOPOLL_HANDLERS_H_
#include "nopoll.h"
#ifdef __cplusplus
extern "C" {
#endif
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
extern pthread_mutex_t g_mutex;
extern pthread_cond_t g_cond;
extern pthread_mutex_t close_mut;
extern volatile unsigned int heartBeatTimer;
extern bool close_retry;
/*----------------------------------------------------------------------------*/
/* Function Prototypes */
/*----------------------------------------------------------------------------*/
/**
* @brief listenerOnMessage_queue function to add messages to the queue
*
* @param[in] ctx The context where the connection happens.
* @param[in] conn The Websocket connection object
* @param[in] msg The message received from server for various process requests
* @param[out] user_data data which is to be sent
*/
void listenerOnMessage_queue(noPollCtx * ctx, noPollConn * conn, noPollMsg * msg,noPollPtr user_data);
/**
* @brief listenerOnPingMessage function to create WebSocket listener to receive heartbeat ping messages
*
* @param[in] ctx The context where the connection happens.
* @param[in] conn Websocket connection object
* @param[in] msg The ping message received from the server
* @param[out] user_data data which is to be sent
*/
void listenerOnPingMessage (noPollCtx * ctx, noPollConn * conn, noPollMsg * msg, noPollPtr user_data);
void listenerOnCloseMessage (noPollCtx * ctx, noPollConn * conn, noPollPtr user_data);
#ifdef __cplusplus
}
#endif
#endif

112
src/nopoll_helpers.c Normal file
View File

@@ -0,0 +1,112 @@
/**
* @file nopoll_helpers.c
*
* @description This file is used to manage incomming and outgoing messages.
*
* Copyright (c) 2015 Comcast
*/
#include "ParodusInternal.h"
#include "connection.h"
#include "nopoll_helpers.h"
#include "nopoll_handlers.h"
/*----------------------------------------------------------------------------*/
/* Macros */
/*----------------------------------------------------------------------------*/
#define MAX_SEND_SIZE (60 * 1024)
#define FLUSH_WAIT_TIME (2000000LL)
/*----------------------------------------------------------------------------*/
/* External functions */
/*----------------------------------------------------------------------------*/
void setMessageHandlers()
{
nopoll_conn_set_on_msg(get_global_conn(), (noPollOnMessageHandler) listenerOnMessage_queue, NULL);
nopoll_conn_set_on_ping_msg(get_global_conn(), (noPollOnMessageHandler)listenerOnPingMessage, NULL);
nopoll_conn_set_on_close(get_global_conn(), (noPollOnCloseHandler)listenerOnCloseMessage, NULL);
}
/** To send upstream msgs to server ***/
void sendMessage(noPollConn *conn, void *msg, size_t len)
{
int bytesWritten = 0;
ParodusInfo("sendMessage length %zu\n", len);
if(nopoll_conn_is_ok(conn) && nopoll_conn_is_ready(conn))
{
//bytesWritten = nopoll_conn_send_binary(conn, msg, len);
bytesWritten = sendResponse(conn, msg, len);
ParodusPrint("Number of bytes written: %d\n", bytesWritten);
if (bytesWritten != (int) len)
{
ParodusError("Failed to send bytes %zu, bytes written were=%d (errno=%d, %s)..\n", len, bytesWritten, errno, strerror(errno));
}
}
else
{
ParodusError("Failed to send msg upstream as connection is not OK\n");
}
}
int sendResponse(noPollConn * conn, void * buffer, size_t length)
{
char *cp = buffer;
int final_len_sent = 0;
noPollOpCode frame_type = NOPOLL_BINARY_FRAME;
while (length > 0)
{
int bytes_sent, len_to_send;
len_to_send = length > MAX_SEND_SIZE ? MAX_SEND_SIZE : length;
length -= len_to_send;
bytes_sent = __nopoll_conn_send_common(conn, cp, len_to_send, length > 0 ? nopoll_false : nopoll_true, 0, frame_type);
if (bytes_sent != len_to_send)
{
if (-1 == bytes_sent || (bytes_sent = nopoll_conn_flush_writes(conn, FLUSH_WAIT_TIME, bytes_sent)) != len_to_send)
{
ParodusError("sendResponse() Failed to send all the data\n");
cp = NULL;
break;
}
}
cp += len_to_send;
final_len_sent += len_to_send;
frame_type = NOPOLL_CONTINUATION_FRAME;
}
return final_len_sent;
}
/**
* @brief __report_log Nopoll log handler
* Nopoll log handler for integrating nopoll logs
*/
void __report_log (noPollCtx * ctx, noPollDebugLevel level, const char * log_msg, noPollPtr user_data)
{
UNUSED(ctx);
UNUSED(user_data);
if (level == NOPOLL_LEVEL_DEBUG)
{
//ParodusPrint("%s\n", log_msg);
}
if (level == NOPOLL_LEVEL_INFO)
{
ParodusInfo ("%s\n", log_msg);
}
if (level == NOPOLL_LEVEL_WARNING)
{
ParodusPrint("%s\n", log_msg);
}
if (level == NOPOLL_LEVEL_CRITICAL)
{
ParodusError("%s\n", log_msg );
}
return;
}

41
src/nopoll_helpers.h Normal file
View File

@@ -0,0 +1,41 @@
/**
* @file nopoll_handlers.h
*
* @description This header defines functions to manage incomming and outgoing messages.
*
* Copyright (c) 2015 Comcast
*/
#ifndef _NOPOLL_HELPERS_H_
#define _NOPOLL_HELPERS_H_
#include "nopoll.h"
#ifdef __cplusplus
extern "C" {
#endif
/*----------------------------------------------------------------------------*/
/* Function Prototypes */
/*----------------------------------------------------------------------------*/
/**
* @brief Interface to create WebSocket client connections.
* Loads the WebPA config file, if not provided by the caller,
* and creates the intial connection and manages the connection wait, close mechanisms.
*/
int sendResponse(noPollConn * conn,void *str, size_t bufferSize);
void setMessageHandlers();
void sendMessage(noPollConn *conn, void *msg, size_t len);
/**
* @brief __report_log Nopoll log handler
* Nopoll log handler for integrating nopoll logs
*/
void __report_log (noPollCtx * ctx, noPollDebugLevel level, const char * log_msg, noPollPtr user_data);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -82,7 +82,7 @@ void *serviceAliveTask()
else
{
ParodusInfo("No clients are registered, waiting ..\n");
sleep(70);
sleep(50);
}
}
}

View File

@@ -37,6 +37,7 @@ void *messageHandlerTask()
listenerOnMessage(message->payload, message->len);
nopoll_msg_unref(message->msg);
free(message);
message = NULL;
}

View File

@@ -12,6 +12,7 @@
#include "partners_check.h"
#include "connection.h"
#include "client_list.h"
#include "nopoll_helpers.h"
/*----------------------------------------------------------------------------*/
/* Macros */
@@ -27,9 +28,7 @@ size_t metaPackSize=-1;
UpStreamMsg *UpStreamMsgQ = NULL;
UpStreamMsg *ResponseMsgQ = NULL;
pthread_mutex_t res_mutex ;
pthread_mutex_t nano_mut=PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t nano_con=PTHREAD_COND_INITIALIZER;
@@ -296,10 +295,10 @@ void *processUpstreamMessage()
ParodusPrint("encodedSize after appending :%zu\n", encodedSize);
ParodusPrint("metadata appended upstream msg %s\n", (char *)appendData);
ParodusInfo("Sending metadata appended upstream msg to server\n");
response_queue(appendData,encodedSize);
sendMessage(get_global_conn(),appendData, encodedSize);
//free( appendData);
//appendData =NULL;
free( appendData);
appendData =NULL;
}
else
{
@@ -346,10 +345,10 @@ void sendUpstreamMsgToServer(void **resp_bytes, size_t resp_size)
ParodusPrint("encodedSize after appending :%zu\n", encodedSize);
ParodusInfo("Sending response to server\n");
response_queue(appendData,encodedSize);
sendMessage(get_global_conn(),appendData, encodedSize);
//free(appendData);
//appendData =NULL;
free(appendData);
appendData =NULL;
}
else
{
@@ -357,35 +356,3 @@ void sendUpstreamMsgToServer(void **resp_bytes, size_t resp_size)
}
}
void response_queue(void *responseMsg,int reqSize)
{
UpStreamMsg *message = (UpStreamMsg *)malloc(sizeof(UpStreamMsg));
if(message)
{
message->msg =responseMsg;
message->len =reqSize;
message->next=NULL;
pthread_mutex_lock (&res_mutex);
if(ResponseMsgQ == NULL)
{
ResponseMsgQ = message;
pthread_mutex_unlock (&res_mutex);
}
else
{
UpStreamMsg *temp = ResponseMsgQ;
while(temp->next)
{
temp = temp->next;
}
temp->next = message;
pthread_mutex_unlock (&res_mutex);
}
}
else
{
ParodusError("failure in allocation for message\n");
}
}

View File

@@ -23,10 +23,6 @@ typedef struct UpStreamMsg__
struct UpStreamMsg__ *next;
} UpStreamMsg;
extern pthread_mutex_t res_mutex;
extern UpStreamMsg *ResponseMsgQ;
/*----------------------------------------------------------------------------*/
/* Function Prototypes */
/*----------------------------------------------------------------------------*/
@@ -36,7 +32,6 @@ void *handle_upstream();
void *processUpstreamMessage();
void sendUpstreamMsgToServer(void **resp_bytes, size_t resp_size);
void response_queue(void *responseMsg,int reqSize);
#ifdef __cplusplus
}

View File

@@ -12,12 +12,12 @@
# See the License for the specific language governing permissions and
# limitations under the License.
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -g -fprofile-arcs -ftest-coverage -O0")
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -W -g -fprofile-arcs -ftest-coverage -O0")
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DTEST ")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -g -fprofile-arcs -ftest-coverage -O0")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -W -g -fprofile-arcs -ftest-coverage -O0")
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage -O0")
set (PARODUS_COMMON_SRC ../src/string_helpers.c ../src/time.c ../src/config.c ../src/spin_thread.c)
set (PARODUS_COMMON_LIBS gcov -lcunit -lcimplog -llibseshat -lwebsockets -lcrypto -lwrp-c -luuid -lpthread -lm -lmsgpackc -lcjson -ltrower-base64 -lnanomsg -Wl,--no-as-needed -lrt )
set (PARODUS_COMMON_SRC ../src/string_helpers.c ../src/mutex.c ../src/time.c ../src/config.c ../src/spin_thread.c)
set (PARODUS_COMMON_LIBS gcov -lcunit -lcimplog -lwrp-c -lpthread -lm -lmsgpackc -lcjson -ltrower-base64 -lnopoll -lnanomsg -Wl,--no-as-needed -lrt)
if(NOT DISABLE_VALGRIND)
set (MEMORY_CHECK valgrind --leak-check=full --show-reachable=yes -v)
@@ -25,20 +25,26 @@ endif ()
link_directories ( ${LIBRARY_DIR} )
#-------------------------------------------------------------------------------
# test_mutex
#-------------------------------------------------------------------------------
add_test(NAME test_mutex COMMAND ${MEMORY_CHECK} ./test_mutex)
add_executable(test_mutex test_mutex.c ../src/mutex.c)
target_link_libraries (test_mutex ${PARODUS_COMMON_LIBS} -lcmocka)
#-------------------------------------------------------------------------------
# test_networking
#-------------------------------------------------------------------------------
#add_test(NAME test_networking COMMAND ${MEMORY_CHECK} ./test_networking)
#add_executable(test_networking test_networking.c ../src/networking.c)
#target_link_libraries (test_networking ${PARODUS_COMMON_LIBS})
add_test(NAME test_networking COMMAND ${MEMORY_CHECK} ./test_networking)
add_executable(test_networking test_networking.c ../src/networking.c)
target_link_libraries (test_networking ${PARODUS_COMMON_LIBS})
#-------------------------------------------------------------------------------
# test_nopoll_helpers
#-------------------------------------------------------------------------------
#add_test(NAME test_nopoll_helpers COMMAND ${MEMORY_CHECK} ./test_nopoll_helpers)
#add_executable(test_nopoll_helpers test_nopoll_helpers.c ../src/nopoll_helpers.c)
#target_link_libraries (test_nopoll_helpers -Wl,--no-as-needed -lrt -lcmocka -lcimplog -lnopoll)
add_test(NAME test_nopoll_helpers COMMAND ${MEMORY_CHECK} ./test_nopoll_helpers)
add_executable(test_nopoll_helpers test_nopoll_helpers.c ../src/nopoll_helpers.c)
target_link_libraries (test_nopoll_helpers -Wl,--no-as-needed -lrt -lcmocka -lcimplog -lnopoll)
#-------------------------------------------------------------------------------
# libpd_test
@@ -49,8 +55,6 @@ target_link_libraries (libpd_test
cunit
-llibparodus
-lwrp-c
-llibseshat
-luuid
-lmsgpackc
-ltrower-base64
-lnanomsg
@@ -88,47 +92,38 @@ add_executable(test_string_helpers test_string_helpers.c ../src/string_helpers.c
target_link_libraries (test_string_helpers ${PARODUS_COMMON_LIBS} )
#-------------------------------------------------------------------------------
# test_lws_handlers
# test_nopoll_handlers
#-------------------------------------------------------------------------------
add_test(NAME test_lws_handlers COMMAND ${MEMORY_CHECK} ./test_lws_handlers)
add_executable(test_lws_handlers test_lws_handlers.c ../src/lws_handlers.c)
target_link_libraries (test_lws_handlers -lwebsockets -lcrypto -lcunit -lcimplog -Wl,--no-as-needed -lrt -lpthread -lm)
add_test(NAME test_nopoll_handlers COMMAND ${MEMORY_CHECK} ./test_nopoll_handlers)
add_executable(test_nopoll_handlers test_nopoll_handlers.c ../src/nopoll_handlers.c)
target_link_libraries (test_nopoll_handlers -lnopoll -lcunit -lcimplog -Wl,--no-as-needed -lrt -lpthread -lm)
#-------------------------------------------------------------------------------
# test_connection
#-------------------------------------------------------------------------------
add_test(NAME test_connection COMMAND ${MEMORY_CHECK} ./test_connection)
add_executable(test_connection test_connection.c ../src/connection.c ../src/lws_handlers.c ../src/upstream.c ../src/client_list.c ../src/service_alive.c ../src/partners_check.c ${PARODUS_COMMON_SRC})
add_executable(test_connection test_connection.c ../src/connection.c ${PARODUS_COMMON_SRC})
target_link_libraries (test_connection ${PARODUS_COMMON_LIBS} -lcmocka)
#-------------------------------------------------------------------------------
# test_connection - function createLWSconnection
# test_connection - function createNopollConnection
#-------------------------------------------------------------------------------
add_test(NAME test_createConnection COMMAND ${MEMORY_CHECK} ./test_createConnection)
add_executable(test_createConnection test_createConnection.c ../src/connection.c ../src/string_helpers.c ../src/config.c ../src/lws_handlers.c ../src/upstream.c ../src/client_list.c ../src/partners_check.c ../src/ParodusInternal.c)
add_executable(test_createConnection test_createConnection.c ../src/connection.c ../src/string_helpers.c ../src/config.c)
target_link_libraries (test_createConnection ${PARODUS_COMMON_LIBS} -lcmocka)
#-------------------------------------------------------------------------------
# test_paroduCallback - function parodus_callback
#-------------------------------------------------------------------------------
add_test(NAME test_parodusCallback COMMAND ${MEMORY_CHECK} ./test_parodusCallback)
add_executable(test_parodusCallback test_parodusCallback.c ../src/connection.c ../src/string_helpers.c ../src/config.c ../src/upstream.c ../src/client_list.c ../src/partners_check.c)
target_link_libraries (test_parodusCallback ${PARODUS_COMMON_LIBS} -lcmocka)
#-------------------------------------------------------------------------------
# test_client_list
#-------------------------------------------------------------------------------
add_test(NAME test_client_list COMMAND ${MEMORY_CHECK} ./test_client_list)
add_executable(test_client_list test_client_list.c ../src/client_list.c ../src/service_alive.c ../src/upstream.c ../src/downstream.c ../src/connection.c ../src/lws_handlers.c ../src/ParodusInternal.c ../src/thread_tasks.c ../src/conn_interface.c ../src/partners_check.c ${PARODUS_COMMON_SRC})
add_executable(test_client_list test_client_list.c ../src/client_list.c ../src/service_alive.c ../src/upstream.c ../src/networking.c ../src/nopoll_helpers.c ../src/downstream.c ../src/connection.c ../src/nopoll_handlers.c ../src/ParodusInternal.c ../src/thread_tasks.c ../src/conn_interface.c ../src/partners_check.c ${PARODUS_COMMON_SRC})
target_link_libraries (test_client_list ${PARODUS_COMMON_LIBS})
#-------------------------------------------------------------------------------
# test_service_alive
#-------------------------------------------------------------------------------
add_test(NAME test_service_alive COMMAND ${MEMORY_CHECK} ./test_service_alive)
add_executable(test_service_alive test_service_alive.c ../src/client_list.c ../src/service_alive.c ../src/upstream.c ../src/lws_handlers.c ../src/config.c ../src/connection.c ../src/ParodusInternal.c ../src/downstream.c ../src/thread_tasks.c ../src/conn_interface.c ../src/partners_check.c ${PARODUS_COMMON_SRC})
add_executable(test_service_alive test_service_alive.c ../src/client_list.c ../src/service_alive.c ../src/upstream.c ../src/networking.c ../src/nopoll_helpers.c ../src/nopoll_handlers.c ../src/config.c ../src/connection.c ../src/ParodusInternal.c ../src/downstream.c ../src/thread_tasks.c ../src/conn_interface.c ../src/partners_check.c ${PARODUS_COMMON_SRC})
target_link_libraries (test_service_alive ${PARODUS_COMMON_LIBS})
#-------------------------------------------------------------------------------
@@ -163,7 +158,7 @@ target_link_libraries (test_thread_tasks -lcmocka ${PARODUS_COMMON_LIBS} )
# test_conn_interface
#-------------------------------------------------------------------------------
add_test(NAME test_conn_interface COMMAND ${MEMORY_CHECK} ./test_conn_interface)
add_executable(test_conn_interface test_conn_interface.c ../src/conn_interface.c ../src/config.c ../src/string_helpers.c )
add_executable(test_conn_interface test_conn_interface.c ../src/conn_interface.c ../src/config.c ../src/string_helpers.c ../src/mutex.c)
target_link_libraries (test_conn_interface -lcmocka ${PARODUS_COMMON_LIBS} )
#-------------------------------------------------------------------------------
@@ -178,7 +173,7 @@ target_link_libraries (test_ParodusInternal -lcmocka ${PARODUS_COMMON_LIBS} )
#-------------------------------------------------------------------------------
add_test(NAME test_partners_check COMMAND ${MEMORY_CHECK} ./test_partners_check)
add_executable(test_partners_check test_partners_check.c ../src/partners_check.c)
target_link_libraries (test_partners_check -lcmocka ${PARODUS_COMMON_LIBS})
target_link_libraries (test_partners_check -lcmocka -lwrp-c ${PARODUS_COMMON_LIBS})
if (INTEGRATION_TESTING)
#-------------------------------------------------------------------------------
@@ -190,7 +185,9 @@ add_executable(simple_connection simple_connection.c ${PARODUS_COMMON_SRC}
../src/conn_interface.c
../src/thread_tasks.c
../src/downstream.c
../src/lws_handlers.c
../src/networking.c
../src/nopoll_helpers.c
../src/nopoll_handlers.c
../src/connection.c
../src/ParodusInternal.c
../src/client_list.c
@@ -198,25 +195,4 @@ add_executable(simple_connection simple_connection.c ${PARODUS_COMMON_SRC}
../src/service_alive.c)
target_link_libraries (simple_connection ${PARODUS_COMMON_LIBS})
#-------------------------------------------------------------------------------
# simple test
#-------------------------------------------------------------------------------
add_test(NAME simple COMMAND ${MEMORY_CHECK} ./simple)
add_executable(simple simple.c
../src/upstream.c
../src/conn_interface.c
../src/downstream.c
../src/thread_tasks.c
../src/lws_handlers.c
../src/string_helpers.c
../src/time.c
../src/config.c
../src/connection.c
../src/ParodusInternal.c
../src/spin_thread.c
../src/client_list.c
../src/partners_check.c
../src/service_alive.c)
target_link_libraries (simple ${PARODUS_COMMON_LIBS} gcov -lnanomsg )
endif (INTEGRATION_TESTING)

View File

@@ -1,712 +0,0 @@
/**
* Copyright 2010-2016 Comcast Cable Communications Management, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdarg.h>
#include <CUnit/Basic.h>
#include <stdbool.h>
#include <assert.h>
#include <nopoll.h>
//#include <nanomsg/bus.h>
#include "../src/ParodusInternal.h"
#include "../src/config.h"
#include "../src/nopoll_helpers.h"
#include "../src/downstream.h"
#include "../src/upstream.h"
#include<errno.h>
/* Nanomsg related Macros */
#define ENDPOINT "tcp://127.0.0.1:6666"
#define CLIENT1_URL "tcp://127.0.0.1:6667"
#define CLIENT2_URL "tcp://127.0.0.1:6668"
#define CLIENT3_URL "tcp://127.0.0.1:6669"
#define HTTP_CUSTOM_HEADER_COUNT 4
static void send_nanomsg_upstream(void **buf, int size);
void *handle_testsuites();
headers_t headers = { 2, {"Header 1", "Header 2"}};
void test_nanomsg_client_registration1()
{
/*****Test svc registation for nanomsg client1 ***/
ParodusInfo("test_nanomsg_client_registration1\n");
const wrp_msg_t reg = { .msg_type = WRP_MSG_TYPE__SVC_REGISTRATION,
.u.reg.service_name = "iot",
.u.reg.url = CLIENT1_URL};
void *bytes;
int size =0;
int rv1, rc;
wrp_msg_t *msg1;
int sock, bind;
int byte =0;
int t=25000;
// msgpack encode
ParodusPrint("msgpack encode\n");
size = wrp_struct_to( &reg, WRP_BYTES, &bytes );
/*** Enable this to decode and verify upstream registration msg **/
/***
rv = wrp_to_struct(bytes, size, WRP_BYTES, &message);
ParodusPrint("decoded msgType:%d\n", message->msg_type);
ParodusPrint("decoded service_name:%s\n", message->u.reg.service_name);
ParodusPrint("decoded dest:%s\n", message->u.reg.url);
wrp_free_struct(message);
***/
//nanomsg socket
sock = nn_socket (AF_SP, NN_PUSH);
int connect = nn_connect (sock, ENDPOINT);
CU_ASSERT(connect >= 0);
rc = nn_setsockopt(sock, NN_SOL_SOCKET, NN_SNDTIMEO, &t, sizeof(t));
CU_ASSERT(rc >= 0);
byte = nn_send (sock, bytes, size, 0);
ParodusInfo("----->Expected byte to be sent:%d\n", size);
ParodusInfo("----->actual byte sent:%d\n", byte);
ParodusInfo("Nanomsg client1 - Testing Upstream Registration msg send\n");
CU_ASSERT_EQUAL( byte, size );
//************************************************************
int sock1 = nn_socket (AF_SP, NN_PULL);
byte = 0;
bind = nn_bind(sock1, reg.u.reg.url);
CU_ASSERT(bind >= 0);
void *buf = NULL;
rc = nn_setsockopt(sock1, NN_SOL_SOCKET, NN_RCVTIMEO, &t, sizeof(t));
CU_ASSERT(rc >= 0);
ParodusPrint("Client 1 waiting for acknowledgement \n");
byte = nn_recv(sock1, &buf, NN_MSG, 0);
ParodusInfo("Data Received for client 1 : %s \n", (char * )buf);
rv1 = wrp_to_struct((void *)buf, byte, WRP_BYTES, &msg1);
CU_ASSERT_EQUAL( rv1, byte );
ParodusPrint("msg1->msg_type for client 1 = %d \n", msg1->msg_type);
ParodusPrint("msg1->status for client 1 = %d \n", msg1->u.auth.status);
CU_ASSERT_EQUAL(msg1->msg_type, 2);
CU_ASSERT_EQUAL(msg1->u.auth.status, 200);
rc = nn_freemsg(buf);
CU_ASSERT(rc == 0);
free(bytes);
wrp_free_struct(msg1);
rc = nn_shutdown(sock1, bind);
CU_ASSERT(rc == 0);
}
void test_nanomsg_client_registration2()
{
/*****Test svc registation for upstream - nanomsg client2 ***/
ParodusInfo("test_nanomsg_client_registration2\n");
const wrp_msg_t reg = { .msg_type = WRP_MSG_TYPE__SVC_REGISTRATION,
.u.reg.service_name = "iot2",
.u.reg.url = CLIENT2_URL};
void *bytes;
int size;
int rv1, rc;
wrp_msg_t *msg1;
int sock, bind;
int byte =0;
int t=28000;
// msgpack encode
ParodusPrint("msgpack encode\n");
size = wrp_struct_to( &reg, WRP_BYTES, &bytes );
/*** Enable this to decode and verify packed upstream registration msg **/
/**
rv = wrp_to_struct(bytes, size, WRP_BYTES, &message);
ParodusPrint("decoded msgType:%d\n", message->msg_type);
ParodusPrint("decoded service_name:%s\n", message->u.reg.service_name);
ParodusPrint("decoded dest:%s\n", message->u.reg.url);
wrp_free_struct(message);
***/
//nanomsg socket
sock = nn_socket (AF_SP, NN_PUSH);
int connect = nn_connect (sock, ENDPOINT);
CU_ASSERT( connect >= 0);
rc = nn_setsockopt(sock, NN_SOL_SOCKET, NN_SNDTIMEO, &t, sizeof(t));
CU_ASSERT(rc >= 0);
byte = nn_send (sock, bytes, size,0);
ParodusInfo("----->Expected byte to be sent:%d\n", size);
ParodusInfo("----->actual byte sent:%d\n", byte);
ParodusInfo("Nanomsg client2 - Testing Upstream Registration msg send\n");
CU_ASSERT_EQUAL( byte, size );
int sock1 = nn_socket (AF_SP, NN_PULL);
byte = 0;
bind = nn_bind(sock1, reg.u.reg.url);
CU_ASSERT(bind >= 0);
void *buf1 = NULL;
rc = nn_setsockopt(sock1, NN_SOL_SOCKET, NN_RCVTIMEO, &t, sizeof(t));
CU_ASSERT(rc >= 0);
ParodusPrint("Client 2 waiting for acknowledgement \n");
byte = nn_recv(sock1, &buf1, NN_MSG, 0);
ParodusInfo("Data Received : %s \n", (char * )buf1);
rv1 = wrp_to_struct((void *)buf1, byte, WRP_BYTES, &msg1);
CU_ASSERT_EQUAL( rv1, byte );
ParodusPrint("msg1->msg_type for client 2 = %d \n", msg1->msg_type);
ParodusPrint("msg1->status for client 2 = %d \n", msg1->u.auth.status);
CU_ASSERT_EQUAL(msg1->msg_type, 2);
CU_ASSERT_EQUAL(msg1->u.auth.status, 200);
rc = nn_freemsg(buf1);
CU_ASSERT(rc == 0);
free(bytes);
wrp_free_struct(msg1);
rc = nn_shutdown(sock1, bind);
CU_ASSERT(rc == 0);
}
void test_nanomsg_client_registration3()
{
/*****Test svc registation for upstream - nanomsg client2 ***/
ParodusInfo("test_nanomsg_client_registration3\n");
const wrp_msg_t reg = { .msg_type = WRP_MSG_TYPE__SVC_REGISTRATION,
.u.reg.service_name = "iot",
.u.reg.url = CLIENT3_URL};
void *bytes;
int size;
int rv1, rc;
wrp_msg_t *msg1;
int sock;
int byte =0;
int t=35000;
// msgpack encode
ParodusPrint("msgpack encode\n");
size = wrp_struct_to( &reg, WRP_BYTES, &bytes );
/*** Enable this to decode and verify packed upstream registration msg **/
/**
rv = wrp_to_struct(bytes, size, WRP_BYTES, &message);
ParodusPrint("decoded msgType:%d\n", message->msg_type);
ParodusPrint("decoded service_name:%s\n", message->u.reg.service_name);
ParodusPrint("decoded dest:%s\n", message->u.reg.url);
wrp_free_struct(message);
***/
//nanomsg socket
sock = nn_socket (AF_SP, NN_PUSH);
int connect = nn_connect (sock, ENDPOINT);
CU_ASSERT(connect >= 0);
rc = nn_setsockopt(sock, NN_SOL_SOCKET, NN_SNDTIMEO, &t, sizeof(t));
CU_ASSERT(rc >= 0);
byte = nn_send (sock, bytes, size,0);
ParodusInfo("----->Expected byte to be sent:%d\n", size);
ParodusInfo("----->actual byte sent:%d\n", byte);
ParodusInfo("Nanomsg client3 - Testing Upstream Registration msg send\n");
CU_ASSERT_EQUAL( byte, size );
int sock1 = nn_socket (AF_SP, NN_PULL);
byte = 0;
int bind = nn_bind(sock1, reg.u.reg.url);
CU_ASSERT(bind >= 0);
ParodusPrint("Need to close this bind %d \n", bind);
void *buf2 = NULL;
rc = nn_setsockopt(sock1, NN_SOL_SOCKET, NN_RCVTIMEO, &t, sizeof(t));
CU_ASSERT(rc >= 0);
ParodusPrint("Client 3 is waiting for acknowledgement \n");
byte = nn_recv(sock1, &buf2, NN_MSG, 0);
ParodusInfo("Data Received : %s \n", (char * )buf2);
rv1 = wrp_to_struct((void *)buf2, byte, WRP_BYTES, &msg1);
CU_ASSERT_EQUAL( rv1, byte );
ParodusPrint("msg1->msg_type for client 3 = %d \n", msg1->msg_type);
ParodusPrint("msg1->status for client 3 = %d \n", msg1->u.auth.status);
CU_ASSERT_EQUAL(msg1->msg_type, 2);
CU_ASSERT_EQUAL(msg1->u.auth.status, 200);
rc = nn_freemsg(buf2);
CU_ASSERT(rc == 0);
free(bytes);
wrp_free_struct(msg1);
rc = nn_shutdown(sock1, bind);
CU_ASSERT(rc == 0);
}
void test_nanomsg_downstream_success()
{
ParodusInfo("test_nanomsg_downstream_success\n");
int sock;
int bit=0, rc;
wrp_msg_t *message;
void *buf =NULL;
char* destVal = NULL;
// char dest[32] = {'\0'};
char *dest = NULL;
//char *temp_ptr;
int bind = -1;
const wrp_msg_t msg = { .msg_type = WRP_MSG_TYPE__SVC_REGISTRATION,
.u.reg.service_name = "iot",
.u.reg.url = CLIENT3_URL};
sock = nn_socket (AF_SP, NN_PULL);
while(bind == -1)
{
bind = nn_bind(sock, msg.u.reg.url);
sleep(3);
}
ParodusPrint("Bind returns = %d \n", bind);
ParodusPrint("***** Nanomsg client3 in Receiving mode in %s *****\n", msg.u.reg.url);
bit = nn_recv (sock, &buf, NN_MSG, 0);
ParodusInfo ("----->Received downstream request from server to client3 : \"%s\"\n", (char *)buf);
ParodusPrint("Received %d bytes\n", bit);
CU_ASSERT(bit >= 0);
//Decode and verify downstream request has received by correct registered client
wrp_to_struct(buf, bit, WRP_BYTES, &message);
destVal = message->u.req.dest;
dest = strtok(destVal , "/");
//temp_ptr = strtok(destVal , "/");
// ParodusPrint("temp_ptr = %s \n", temp_ptr);
strcpy(dest,strtok(NULL , "/"));
ParodusInfo("------>decoded dest:%s\n", dest);
CU_ASSERT_STRING_EQUAL( msg.u.reg.service_name, dest );
wrp_free_struct(message);
//To send nanomsg client response upstream
send_nanomsg_upstream(&buf, bit);
rc = nn_freemsg(buf);
CU_ASSERT(rc == 0);
rc = nn_shutdown(sock, bind);
CU_ASSERT(rc == 0);
//Need to wait for parodus to finish it's task.
sleep(10);
}
void test_nanomsg_downstream_failure()
{
int sock, bind, rc;
int bit =0;
char *buf =NULL;
ParodusError("test_nanomsg_downstream_failure\n");
sleep(60);
sock = nn_socket (AF_SP, NN_PULL);
bind = nn_bind (sock, CLIENT3_URL);
CU_ASSERT(bind >= 0);
ParodusPrint("***** Nanomsg client3 in Receiving mode *****\n");
bit = nn_recv (sock, &buf, NN_MSG, 0);
ParodusInfo ("Received downstream request from server for client3 : \"%s\"\n", buf);
CU_ASSERT(bit >= 0);
rc = nn_freemsg(buf);
CU_ASSERT(rc == 0);
rc = nn_shutdown(sock, bind);
CU_ASSERT(rc == 0);
}
void test_checkHostIp()
{
int ret;
ParodusPrint("**********************************Calling check_host_ip \n");
ret = checkHostIp("fabric.webpa.comcast.net");
ParodusPrint("------------------> Ret = %d \n", ret);
CU_ASSERT_EQUAL(ret, 0);
}
void test_sendMessage()
{
noPollConnOpts * opts;
noPollCtx *ctx = NULL;
noPollConn *conn = NULL;
ParodusPrint("**********************************Calling sendMessage \n");
const char * headerNames[HTTP_CUSTOM_HEADER_COUNT] = {"X-WebPA-Device-Name","X-WebPA-Device-Protocols","User-Agent", "X-WebPA-Convey"};
const char * headerValues[HTTP_CUSTOM_HEADER_COUNT];
headerValues[0] = "123567892366";
headerValues[1] = "wrp-0.11,getset-0.1";
headerValues[2] = "WebPA-1.6 (TG1682_DEV_master_2016000000sdy;TG1682/ARRISGroup,Inc.;)";
headerValues[3] = "zacbvfxcvglodfjdigjkdshuihgkvn";
int headerCount = HTTP_CUSTOM_HEADER_COUNT;
//ctx = nopoll_ctx_new();
opts = nopoll_conn_opts_new ();
nopoll_conn_opts_ssl_peer_verify (opts, nopoll_false);
nopoll_conn_opts_set_ssl_protocol (opts, NOPOLL_METHOD_TLSV1_2);
conn = nopoll_conn_tls_new(ctx, opts, "fabric.webpa.comcast.net", "8080", NULL, "/api/v2/device", NULL, NULL, "eth0",
headerNames, headerValues, headerCount);
/*while(conn == NULL)
{
opts = nopoll_conn_opts_new ();
nopoll_conn_opts_ssl_peer_verify (opts, nopoll_false);
nopoll_conn_opts_set_ssl_protocol (opts, NOPOLL_METHOD_TLSV1_2);
conn = nopoll_conn_tls_new(ctx, opts, "fabric.webpa.comcast.net", 8080, NULL, "/api/v2/device", NULL, NULL, "eth0",
headerNames, headerValues, headerCount);
}*/
ParodusPrint("Sending conn as %p \n", conn);
sendMessage(conn, "hello", 6);
}
void test_parseCommandLine()
{
int argc =11;
char * command[15]={'\0'};
command[0] = "parodus";
command[1] = "--hw-model=TG1682";
command[2] = "--hw-serial-number=Fer23u948590";
command[3] = "--hw-manufacturer=ARRISGroup,Inc.";
command[4] = "--hw-mac=123567892366";
command[5] = "--hw-last-reboot-reason=unknown";
command[6] = "--fw-name=TG1682_DEV_master_2016000000sdy";
command[7] = "--webpa-ping-time=180";
command[8] = "--webpa-inteface-used=eth0";
command[9] = "--webpa-url=fabric.webpa.comcast.net";
command[10] = "--webpa-backoff-max=0";
ParodusCfg parodusCfg;
memset(&parodusCfg,0,sizeof(parodusCfg));
ParodusPrint("call parseCommand\n");
parseCommandLine(argc,command,&parodusCfg);
ParodusPrint("parodusCfg.webpa_ping_timeout is %d\n", parodusCfg.webpa_ping_timeout);
ParodusPrint("parodusCfg.webpa_backoff_max is %d\n", parodusCfg.webpa_backoff_max);
CU_ASSERT_STRING_EQUAL( parodusCfg.hw_model, "TG1682");
CU_ASSERT_STRING_EQUAL( parodusCfg.hw_serial_number, "Fer23u948590");
CU_ASSERT_STRING_EQUAL( parodusCfg.hw_manufacturer, "ARRISGroup,Inc.");
CU_ASSERT_STRING_EQUAL( parodusCfg.hw_mac, "123567892366");
CU_ASSERT_STRING_EQUAL( parodusCfg.hw_last_reboot_reason, "unknown");
CU_ASSERT_STRING_EQUAL( parodusCfg.fw_name, "TG1682_DEV_master_2016000000sdy");
CU_ASSERT( parodusCfg.webpa_ping_timeout==180);
CU_ASSERT_STRING_EQUAL( parodusCfg.webpa_interface_used, "eth0");
CU_ASSERT_STRING_EQUAL( parodusCfg.webpa_url, "fabric.webpa.comcast.net");
CU_ASSERT( parodusCfg.webpa_backoff_max==0);
}
void test_loadParodusCfg()
{
ParodusPrint("Calling test_loadParodusCfg \n");
//ParodusCfg parodusCfg, tmpcfg;
ParodusCfg tmpcfg;
ParodusCfg *Cfg;
Cfg = (ParodusCfg*)malloc(sizeof(ParodusCfg));
strcpy(Cfg->hw_model, "TG1682");
strcpy(Cfg->hw_serial_number, "Fer23u948590");
strcpy(Cfg->hw_manufacturer , "ARRISGroup,Inc.");
strcpy(Cfg->hw_mac , "123567892366");
memset(&tmpcfg,0,sizeof(tmpcfg));
loadParodusCfg(Cfg,&tmpcfg);
ParodusInfo("tmpcfg.hw_model = %s, tmpcfg.hw_serial_number = %s, tmpcfg.hw_manufacturer = %s, tmpcfg.hw_mac = %s, \n", tmpcfg.hw_model,tmpcfg.hw_serial_number, tmpcfg.hw_manufacturer, tmpcfg.hw_mac);
CU_ASSERT_STRING_EQUAL( tmpcfg.hw_model, "TG1682");
CU_ASSERT_STRING_EQUAL( tmpcfg.hw_serial_number, "Fer23u948590");
CU_ASSERT_STRING_EQUAL( tmpcfg.hw_manufacturer, "ARRISGroup,Inc.");
CU_ASSERT_STRING_EQUAL( tmpcfg.hw_mac, "123567892366");
}
void add_suites( CU_pSuite *suite )
{
ParodusInfo("--------Start of Test Cases Execution ---------\n");
*suite = CU_add_suite( "tests", NULL, NULL );
CU_add_test( *suite, "Test 1", test_nanomsg_client_registration1 );
CU_add_test( *suite, "Test 2", test_nanomsg_client_registration2 );
CU_add_test( *suite, "Test 3", test_nanomsg_client_registration3 );
CU_add_test( *suite, "Test 4", test_nanomsg_downstream_success );
//CU_add_test( *suite, "Test 5", test_nanomsg_downstream_failure );
ParodusInfo("-------------Integration testing is completed-----------\n");
ParodusInfo("******************************************************************\n");
//sleep(10);
ParodusInfo("-------------Start of Unit Test Cases Execution---------\n");
CU_add_test( *suite, "UnitTest 1", test_parseCommandLine );
CU_add_test( *suite, "UnitTest 2", test_checkHostIp );
CU_add_test( *suite, "UnitTest 3", test_sendMessage );
CU_add_test( *suite, "UnitTest 4", test_loadParodusCfg );
}
/*----------------------------------------------------------------------------*/
/* External Functions */
/*----------------------------------------------------------------------------*/
int main( void )
{
pid_t pid, pid1;
char value[512] = {'\0'};
char* data =NULL;
int status;
char commandUrl[255];
pid_t curl_pid;
char * command[] = {"parodus","--hw-model=TG1682", "--hw-serial-number=Fer23u948590","--hw-manufacturer=ARRISGroup,Inc.","--hw-mac=123567892366","--hw-last-reboot-reason=unknown","--fw-name=TG1682_DEV_master_2016000000sdy","--boot-time=10","--webpa-ping-time=180","--webpa-inteface-used=eth0","--webpa-url=fabric-cd.webpa.comcast.net","--webpa-backoff-max=9", NULL};
//int size = sizeof(command)/sizeof(command[0]);
//int i;
//ParodusInfo("commad: ");
//for(i=0;i<size-1;i++)
//ParodusInfo("command:%s",command);
ParodusInfo("Starting parodus process \n");
const char *s = getenv("WEBPA_AUTH_HEADER");
sprintf(commandUrl, "curl -i -H \"Authorization:Basic %s\" -H \"Accept: application/json\" -w %%{time_total} -k \"https://api-cd.webpa.comcast.net:8090/api/v2/device/mac:123567892366/iot?names=Device.DeviceInfo.Webpa.X_COMCAST-COM_SyncProtocolVersion\"", s);
ParodusPrint("---------------------->>>>Executing system(commandUrl)\n");
curl_pid = getpid();
ParodusPrint("child process execution with curl_pid:%d\n", curl_pid);
pid = fork();
if (pid == -1)
{
ParodusError("fork was unsuccessful for pid (errno=%d, %s)\n",errno, strerror(errno));
return -1;
}
else if (pid == 0)
{
int err;
ParodusPrint("child process created for parodus\n");
pid = getpid();
ParodusPrint("child process execution with pid:%d\n", pid);
err = execv("../src/parodus", command);
if(errno == 2)
{
err = execv("./src/parodus", command);
}
ParodusError("err is %d, errno is %d\n",err, errno);
}
else if (pid > 0)
{
int link[2];
sleep(5);
//Starting test suites execution in new thread
ParodusPrint("Creating new thread for test suite execution\n");
pthread_t testId;
int err1 = 0;
err1 = pthread_create(&testId,NULL,handle_testsuites,(void *)&pid);
if(err1 != 0)
ParodusError("Error creating test suite thread %s\n",strerror(err1));
else
ParodusPrint("test suite thread created successfully\n");
if (pipe(link)==-1)
{
ParodusError("Failed to create pipe\n");
}
else
ParodusPrint("Created pipe to read curl output\n");
pid1 = fork();
if (pid1 == -1)
{
ParodusError("fork was unsuccessful for pid1 (errno=%d, %s)\n",errno, strerror(errno));
return -1;
}
else if(pid1 == 0)
{
while(NULL == fopen("/tmp/parodus_ready", "r"))
{
sleep(5);
}
dup2 (link[1], STDOUT_FILENO);
close(link[0]);
close(link[1]);
sleep(40);
system(commandUrl);
ParodusInfo("\n----Executed first Curl request for downstream ------- \n");
}
else if(pid1 > 0)
{
//wait fro child process to finish and read from pipe
waitpid(pid1, &status, 0);
//reading from pipe
ParodusPrint("parent process...:%d\n", pid1);
close(link[1]);
int nbytes = read(link[0], value, sizeof(value));
ParodusPrint("Read %d \n", nbytes);
if ((data = strstr(value, "message:Success")) !=NULL)
{
ParodusInfo("curl success\n");
}
else
{
ParodusError("curl failure..\n");
}
while(1);
}
}
return 0;
}
void *handle_testsuites(void* pid)
{
unsigned rv = 1;
CU_pSuite suite = NULL;
pid_t pid_parodus = *((int *)pid);
ParodusPrint("Starting handle_testsuites thread\n");
sleep(25);
if( CUE_SUCCESS == CU_initialize_registry() )
{
add_suites( &suite );
if( NULL != suite )
{
CU_basic_set_mode( CU_BRM_VERBOSE );
CU_basic_run_tests();
ParodusPrint( "\n" );
CU_basic_show_failures( CU_get_failure_list() );
ParodusPrint( "\n\n" );
rv = CU_get_number_of_tests_failed();
}
CU_cleanup_registry();
}
kill(pid_parodus, SIGKILL);
ParodusInfo("parodus process with pid %d is stopped\n", pid_parodus);
if( 0 != rv )
{
_exit(-1);
}
_exit(0);
}
static void send_nanomsg_upstream(void **buf, int size)
{
/**** To send nanomsg response to server ****/
int rv;
void *bytes;
int resp_size;
int sock;
int byte;
wrp_msg_t *message;
ParodusInfo("Decoding downstream request received from server\n");
rv = wrp_to_struct(*buf, size, WRP_BYTES, &message);
ParodusPrint("after downstream req decode:%d\n", rv);
/**** Preparing Nanomsg client response ****/
wrp_msg_t resp_m;
resp_m.msg_type = WRP_MSG_TYPE__REQ;
ParodusPrint("resp_m.msg_type:%d\n", resp_m.msg_type);
resp_m.u.req.source = message->u.req.dest;
ParodusPrint("------resp_m.u.req.source is:%s\n", resp_m.u.req.source);
resp_m.u.req.dest = message->u.req.source;
ParodusPrint("------resp_m.u.req.dest is:%s\n", resp_m.u.req.dest);
resp_m.u.req.transaction_uuid = message->u.req.transaction_uuid;
ParodusPrint("------resp_m.u.req.transaction_uuid is:%s\n", resp_m.u.req.transaction_uuid);
resp_m.u.req.headers = NULL;
resp_m.u.req.payload = "{statusCode:200,message:Success}";
ParodusPrint("------resp_m.u.req.payload is:%s\n", (char *)resp_m.u.req.payload);
resp_m.u.req.payload_size = strlen(resp_m.u.req.payload);
resp_m.u.req.metadata = NULL;
resp_m.u.req.include_spans = false;
resp_m.u.req.spans.spans = NULL;
resp_m.u.req.spans.count = 0;
ParodusPrint("Encoding downstream response\n");
resp_size = wrp_struct_to( &resp_m, WRP_BYTES, &bytes );
/*** Enable this to verify downstream response by decoding ***/
/***
wrp_msg_t *message1;
rv = wrp_to_struct(bytes, resp_size, WRP_BYTES, &message1);
ParodusPrint("after downstream response decode:%d\n", rv);
ParodusPrint("downstream response decoded msgType:%d\n", message1->msg_type);
ParodusPrint("downstream response decoded source:%s\n", message1->u.req.source);
ParodusPrint("downstream response decoded dest:%s\n", message1->u.req.dest);
ParodusPrint("downstream response decoded transaction_uuid:%s\n", message1->u.req.transaction_uuid);
ParodusPrint("downstream response decoded payload:%s\n", (char*)message1->u.req.payload);
wrp_free_struct(message1);
***/
/**** Nanomsg client sending msgs ****/
sock = nn_socket (AF_SP, NN_PUSH);
int connect = nn_connect (sock, ENDPOINT);
CU_ASSERT(connect >= 0);
sleep(1);
ParodusInfo("nanomsg client sending response upstream\n");
byte = nn_send (sock, bytes, resp_size,0);
ParodusInfo("----->Expected byte to be sent:%d\n", resp_size);
ParodusInfo("----->actual byte sent:%d\n", byte);
CU_ASSERT(byte==resp_size );
wrp_free_struct(message);
free(bytes);
ParodusPrint("---- End of send_nanomsg_upstream ----\n");
}

View File

@@ -22,6 +22,7 @@
#include <setjmp.h>
#include <cmocka.h>
#include <assert.h>
#include <nopoll.h>
#include "../src/ParodusInternal.h"
#include "../src/config.h"
@@ -35,12 +36,12 @@ bool LastReasonStatus;
/* Mocks */
/*----------------------------------------------------------------------------*/
int lws_b64_encode_string(const char *content,int length,char *output, int output_size)
nopoll_bool nopoll_base64_encode(const char *content,int length,char *output, int *output_size)
{
UNUSED(content); UNUSED(length); UNUSED(output_size);
strcpy(output, "AWYFUJHUDUDKJDDRDKUIIKORE\nSFJLIRRSHLOUTDESTDJJITTESLOIUHJGDRS\nGIUY&%WSJ");
function_called();
return (int)(intptr_t)mock();
return (nopoll_bool)(intptr_t)mock();
}
char *get_global_reconnect_reason()
@@ -76,8 +77,8 @@ void test_getWebpaConveyHeader()
will_return(get_global_reconnect_reason, (intptr_t)"Ping-Miss");
expect_function_call(get_global_reconnect_reason);
will_return(lws_b64_encode_string, 352);
expect_function_call(lws_b64_encode_string);
will_return(nopoll_base64_encode, nopoll_true);
expect_function_call(nopoll_base64_encode);
getWebpaConveyHeader();
}
@@ -89,8 +90,8 @@ void err_getWebpaConveyHeader()
will_return(get_global_reconnect_reason, (intptr_t)NULL);
expect_function_call(get_global_reconnect_reason);
will_return(lws_b64_encode_string, -1);
expect_function_call(lws_b64_encode_string);
will_return(nopoll_base64_encode, nopoll_false);
expect_function_call(nopoll_base64_encode);
getWebpaConveyHeader();
}

View File

@@ -26,8 +26,6 @@
#include "../src/config.h"
#define K_argc 15
/*----------------------------------------------------------------------------*/
/* Mocks */
/*----------------------------------------------------------------------------*/
@@ -52,12 +50,11 @@ void test_setParodusConfig()
strcpy(cfg.webpa_protocol , "WebPA-1.6");
strcpy(cfg.webpa_uuid , "1234567-345456546");
strcpy(cfg.partner_id , "comcast");
strcpy(cfg.seshat_url, "ipc://tmp/seshat_service.url");
cfg.secureFlag = 1;
cfg.boot_time = 423457;
cfg.webpa_ping_timeout = 30;
cfg.webpa_backoff_max = 255;
set_parodus_cfg(&cfg);
ParodusCfg *temp = get_parodus_cfg();
@@ -73,8 +70,6 @@ void test_setParodusConfig()
assert_string_equal(cfg.webpa_protocol, temp->webpa_protocol);
assert_string_equal(cfg.webpa_uuid, temp->webpa_uuid);
assert_string_equal(cfg.partner_id, temp->partner_id);
assert_string_equal(cfg.seshat_url, temp->seshat_url);
assert_int_equal((int) cfg.secureFlag, (int) temp->secureFlag);
assert_int_equal((int) cfg.boot_time, (int) temp->boot_time);
@@ -97,26 +92,23 @@ void test_getParodusConfig()
void test_parseCommandLine()
{
int argc =K_argc;
char * command[argc+1];
int i = 0;
int argc =14;
char * command[15]={'\0'};
command[i++] = "parodus";
command[i++] = "--hw-model=TG1682";
command[i++] = "--hw-serial-number=Fer23u948590";
command[i++] = "--hw-manufacturer=ARRISGroup,Inc.";
command[i++] = "--hw-mac=123567892366";
command[i++] = "--hw-last-reboot-reason=unknown";
command[i++] = "--fw-name=TG1682_DEV_master_2016000000sdy";
command[i++] = "--webpa-ping-time=180";
command[i++] = "--webpa-inteface-used=br0";
command[i++] = "--webpa-url=localhost";
command[i++] = "--webpa-backoff-max=0";
command[i++] = "--boot-time=1234";
command[i++] = "--parodus-local-url=tcp://127.0.0.1:6666";
command[i++] = "--partner-id=cox";
command[i++] = "--seshat-url=ipc://127.0.0.1:7777";
command[i] = '\0';
command[0] = "parodus";
command[1] = "--hw-model=TG1682";
command[2] = "--hw-serial-number=Fer23u948590";
command[3] = "--hw-manufacturer=ARRISGroup,Inc.";
command[4] = "--hw-mac=123567892366";
command[5] = "--hw-last-reboot-reason=unknown";
command[6] = "--fw-name=TG1682_DEV_master_2016000000sdy";
command[7] = "--webpa-ping-time=180";
command[8] = "--webpa-inteface-used=br0";
command[9] = "--webpa-url=localhost";
command[10] = "--webpa-backoff-max=0";
command[11] = "--boot-time=1234";
command[12] = "--parodus-local-url=tcp://127.0.0.1:6666";
command[13] = "--partner-id=cox";
ParodusCfg parodusCfg;
memset(&parodusCfg,0,sizeof(parodusCfg));
@@ -136,8 +128,6 @@ void test_parseCommandLine()
assert_int_equal( (int) parodusCfg.boot_time,1234);
assert_string_equal( parodusCfg.local_url,"tcp://127.0.0.1:6666");
assert_string_equal( parodusCfg.partner_id,"cox");
assert_string_equal( parodusCfg.seshat_url, "ipc://127.0.0.1:7777");
}
void test_parseCommandLineNull()
@@ -147,7 +137,7 @@ void test_parseCommandLineNull()
void err_parseCommandLine()
{
int argc =K_argc;
int argc =14;
char * command[20]={'\0'};
command[0] = "parodus";

View File

@@ -21,6 +21,7 @@
#include <setjmp.h>
#include <cmocka.h>
#include <assert.h>
#include <nopoll.h>
#include "../src/ParodusInternal.h"
#include "../src/conn_interface.h"
@@ -32,22 +33,46 @@
/*----------------------------------------------------------------------------*/
UpStreamMsg *UpStreamMsgQ;
ParodusMsg *ParodusMsgQ;
bool conn_retry;
struct lws *wsi_dumb;
extern bool close_retry;
extern volatile unsigned int heartBeatTimer;
/*----------------------------------------------------------------------------*/
/* Mocks */
/*----------------------------------------------------------------------------*/
void createLWSconnection()
int createNopollConnection(noPollCtx *ctx)
{
function_called();
UNUSED(ctx);
function_called();
return (int) mock();
}
void nopoll_log_set_handler (noPollCtx *ctx, noPollLogHandler handler, noPollPtr user_data)
{
UNUSED(ctx); UNUSED(handler); UNUSED(user_data);
function_called();
}
void __report_log (noPollCtx * ctx, noPollDebugLevel level, const char * log_msg, noPollPtr user_data)
{
UNUSED(ctx); UNUSED(level); UNUSED(log_msg); UNUSED(user_data);
function_called();
}
void nopoll_thread_handlers ( noPollMutexCreate mutex_create,
noPollMutexDestroy mutex_destroy,
noPollMutexLock mutex_lock,
noPollMutexUnlock mutex_unlock
)
{
UNUSED(mutex_create); UNUSED(mutex_destroy); UNUSED(mutex_lock); UNUSED(mutex_unlock);
function_called();
}
void packMetaData()
{
function_called();
}
void *handle_upstream()
{
return NULL;
@@ -68,9 +93,9 @@ void *serviceAliveTask()
return NULL;
}
int lws_service(struct lws_context * context,int timeout)
int nopoll_loop_wait(noPollCtx * ctx,long timeout)
{
UNUSED(context); UNUSED(timeout);
UNUSED(ctx); UNUSED(timeout);
function_called();
return (int) mock();
}
@@ -81,21 +106,32 @@ void set_global_reconnect_reason(char *reason)
function_called();
}
void lws_context_destroy(struct lws_context * context)
void close_and_unref_connection(noPollConn *conn)
{
UNUSED(context);
UNUSED(conn);
function_called();
}
struct lws_context *get_global_context(void)
void nopoll_cleanup_library ()
{
function_called();
return (struct lws_context *) (intptr_t)mock();
}
void set_global_context(struct lws_context *contextRef)
void nopoll_ctx_unref(noPollCtx * ctx)
{
UNUSED(contextRef);
UNUSED(ctx);
function_called();
}
noPollConn *get_global_conn(void)
{
function_called();
return (noPollConn *) (intptr_t)mock();
}
void set_global_conn(noPollConn *conn)
{
UNUSED(conn);
function_called();
}
@@ -105,6 +141,11 @@ void StartThread(void *(*start_routine) (void *))
function_called();
}
noPollCtx* nopoll_ctx_new(void)
{
function_called();
return (noPollCtx*) (intptr_t)mock();
}
void initKeypress()
{
function_called();
@@ -113,59 +154,79 @@ void initKeypress()
/* Tests */
/*----------------------------------------------------------------------------*/
void test_createLWSsocket()
void test_createSocketConnection()
{
noPollCtx *ctx;
ParodusCfg cfg;
memset(&cfg,0,sizeof(ParodusCfg));
conn_retry = true;
expect_function_call(createLWSconnection);
close_retry = false;
expect_function_call(nopoll_thread_handlers);
will_return(nopoll_ctx_new, (intptr_t)&ctx);
expect_function_call(nopoll_ctx_new);
expect_function_call(nopoll_log_set_handler);
will_return(createNopollConnection, nopoll_true);
expect_function_call(createNopollConnection);
expect_function_call(packMetaData);
expect_function_calls(StartThread, 5);
expect_function_calls(StartThread, 4);
expect_function_call(initKeypress);
will_return(get_global_context, NULL);
expect_function_call(get_global_context);
will_return(lws_service, 1);
expect_function_call(lws_service);
will_return(get_global_context, NULL);
expect_function_call(get_global_context);
expect_function_call(lws_context_destroy);
expect_function_call(createLWSconnection);
will_return(get_global_context, NULL);
expect_function_call(get_global_context);
expect_function_call(lws_context_destroy);
createLWSsocket(&cfg,initKeypress);
will_return(nopoll_loop_wait, 1);
expect_function_call(nopoll_loop_wait);
expect_function_call(set_global_reconnect_reason);
will_return(get_global_conn, (intptr_t)NULL);
expect_function_call(get_global_conn);
expect_function_call(close_and_unref_connection);
expect_function_call(set_global_conn);
will_return(createNopollConnection, nopoll_true);
expect_function_call(createNopollConnection);
will_return(get_global_conn, (intptr_t)NULL);
expect_function_call(get_global_conn);
expect_function_call(close_and_unref_connection);
expect_function_call(nopoll_ctx_unref);
expect_function_call(nopoll_cleanup_library);
createSocketConnection(&cfg,initKeypress);
}
void test_createLWSsocket1()
void test_createSocketConnection1()
{
noPollCtx *ctx;
ParodusCfg cfg;
memset(&cfg,0,sizeof(ParodusCfg));
conn_retry = true;
expect_function_call(createLWSconnection);
memset(&cfg,0, sizeof(ParodusCfg));
close_retry = true;
expect_function_call(nopoll_thread_handlers);
will_return(nopoll_ctx_new, (intptr_t)&ctx);
expect_function_call(nopoll_ctx_new);
expect_function_call(nopoll_log_set_handler);
will_return(createNopollConnection, nopoll_true);
expect_function_call(createNopollConnection);
expect_function_call(packMetaData);
expect_function_calls(StartThread, 5);
will_return(get_global_context, NULL);
expect_function_call(get_global_context);
will_return(lws_service, 1);
expect_function_call(lws_service);
will_return(get_global_context, NULL);
expect_function_call(get_global_context);
expect_function_call(lws_context_destroy);
expect_function_call(createLWSconnection);
will_return(get_global_context, NULL);
expect_function_call(get_global_context);
expect_function_call(lws_context_destroy);
createLWSsocket(&cfg,NULL);
expect_function_calls(StartThread, 4);
will_return(nopoll_loop_wait, 1);
expect_function_call(nopoll_loop_wait);
will_return(get_global_conn, (intptr_t)NULL);
expect_function_call(get_global_conn);
expect_function_call(close_and_unref_connection);
expect_function_call(set_global_conn);
will_return(createNopollConnection, nopoll_true);
expect_function_call(createNopollConnection);
will_return(get_global_conn, (intptr_t)NULL);
expect_function_call(get_global_conn);
expect_function_call(close_and_unref_connection);
expect_function_call(nopoll_ctx_unref);
expect_function_call(nopoll_cleanup_library);
createSocketConnection(&cfg,NULL);
}
void test_createLWSsocket2()
void test_createSocketConnection2()
{
noPollCtx *ctx;
ParodusCfg cfg;
memset(&cfg,0,sizeof(ParodusCfg));
strcpy(cfg.hw_model, "TG1682");
@@ -181,47 +242,72 @@ void test_createLWSsocket2()
strcpy(cfg.webpa_uuid , "1234567-345456546");
cfg.webpa_ping_timeout = 1;
conn_retry = true;
expect_function_call(createLWSconnection);
close_retry = false;
expect_function_call(nopoll_thread_handlers);
will_return(nopoll_ctx_new, (intptr_t)&ctx);
expect_function_call(nopoll_ctx_new);
expect_function_call(nopoll_log_set_handler);
will_return(createNopollConnection, nopoll_true);
expect_function_call(createNopollConnection);
expect_function_call(packMetaData);
expect_function_calls(StartThread, 5);
will_return(get_global_context, NULL);
expect_function_call(get_global_context);
will_return(lws_service, 1);
expect_function_call(lws_service);
will_return(get_global_context, NULL);
expect_function_call(get_global_context);
expect_function_call(lws_context_destroy);
expect_function_call(createLWSconnection);
will_return(get_global_context, NULL);
expect_function_call(get_global_context);
expect_function_call(lws_context_destroy);
createLWSsocket(&cfg,NULL);
expect_function_calls(StartThread, 4);
will_return(nopoll_loop_wait, 1);
will_return(nopoll_loop_wait, 1);
will_return(nopoll_loop_wait, 1);
will_return(nopoll_loop_wait, 1);
will_return(nopoll_loop_wait, 1);
will_return(nopoll_loop_wait, 1);
will_return(nopoll_loop_wait, 1);
expect_function_calls(nopoll_loop_wait, 7);
expect_function_call(set_global_reconnect_reason);
will_return(get_global_conn, (intptr_t)NULL);
expect_function_call(get_global_conn);
expect_function_call(close_and_unref_connection);
expect_function_call(set_global_conn);
will_return(createNopollConnection, nopoll_true);
expect_function_call(createNopollConnection);
will_return(get_global_conn, (intptr_t)NULL);
expect_function_call(get_global_conn);
expect_function_call(close_and_unref_connection);
expect_function_call(nopoll_ctx_unref);
expect_function_call(nopoll_cleanup_library);
createSocketConnection(&cfg,NULL);
}
void err_createLWSsocket()
void err_createSocketConnection()
{
conn_retry = true;
expect_function_call(createLWSconnection);
close_retry = true;
heartBeatTimer = 0;
expect_function_call(nopoll_thread_handlers);
will_return(nopoll_ctx_new, (intptr_t)NULL);
expect_function_call(nopoll_ctx_new);
expect_function_call(nopoll_log_set_handler);
will_return(createNopollConnection, nopoll_true);
expect_function_call(createNopollConnection);
expect_function_call(packMetaData);
expect_function_calls(StartThread, 5);
will_return(get_global_context, NULL);
expect_function_call(get_global_context);
will_return(lws_service, 1);
expect_function_call(lws_service);
will_return(get_global_context, NULL);
expect_function_call(get_global_context);
expect_function_call(lws_context_destroy);
expect_function_call(createLWSconnection);
will_return(get_global_context, NULL);
expect_function_call(get_global_context);
expect_function_call(lws_context_destroy);
createLWSsocket(NULL,NULL);
expect_function_calls(StartThread, 4);
will_return(nopoll_loop_wait, 1);
expect_function_call(nopoll_loop_wait);
will_return(get_global_conn, (intptr_t)NULL);
expect_function_call(get_global_conn);
expect_function_call(close_and_unref_connection);
expect_function_call(set_global_conn);
will_return(createNopollConnection, nopoll_true);
expect_function_call(createNopollConnection);
will_return(get_global_conn, (intptr_t)NULL);
expect_function_call(get_global_conn);
expect_function_call(close_and_unref_connection);
expect_function_call(nopoll_ctx_unref);
expect_function_call(nopoll_cleanup_library);
createSocketConnection(NULL,NULL);
}
/*----------------------------------------------------------------------------*/
/* External Functions */
/*----------------------------------------------------------------------------*/
@@ -229,10 +315,10 @@ void err_createLWSsocket()
int main(void)
{
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_createLWSsocket),
cmocka_unit_test(test_createLWSsocket1),
cmocka_unit_test(test_createLWSsocket2),
cmocka_unit_test(err_createLWSsocket),
cmocka_unit_test(test_createSocketConnection),
cmocka_unit_test(test_createSocketConnection1),
cmocka_unit_test(test_createSocketConnection2),
cmocka_unit_test(err_createSocketConnection),
};
return cmocka_run_group_tests(tests, NULL, NULL);

View File

@@ -22,6 +22,7 @@
#include <setjmp.h>
#include <cmocka.h>
#include <assert.h>
#include <nopoll.h>
#include "../src/ParodusInternal.h"
#include "../src/connection.h"
@@ -44,21 +45,29 @@ char* getWebpaConveyHeader()
return NULL;
}
int checkHostIp(char * serverIP)
{
UNUSED(serverIP);
return 0;
}
void setMessageHandlers()
{
}
/*----------------------------------------------------------------------------*/
/* Tests */
/*----------------------------------------------------------------------------*/
void test_get_global_context()
void test_get_global_conn()
{
assert_null(get_global_context());
assert_null(get_global_conn());
}
void test_set_global_context()
void test_set_global_conn()
{
static struct lws_context *context;
set_global_context(context);
assert_ptr_equal(context, get_global_context());
static noPollConn *gNPConn;
set_global_conn(gNPConn);
assert_ptr_equal(gNPConn, get_global_conn());
}
void test_get_global_reconnect_reason()
@@ -73,6 +82,10 @@ void test_set_global_reconnect_reason()
assert_string_equal(reason, get_global_reconnect_reason());
}
void test_closeConnection()
{
close_and_unref_connection(get_global_conn());
}
/*----------------------------------------------------------------------------*/
/* External Functions */
@@ -80,10 +93,11 @@ void test_set_global_reconnect_reason()
int main(void)
{
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_get_global_context),
cmocka_unit_test(test_set_global_context),
cmocka_unit_test(test_get_global_conn),
cmocka_unit_test(test_set_global_conn),
cmocka_unit_test(test_get_global_reconnect_reason),
cmocka_unit_test(test_set_global_reconnect_reason),
cmocka_unit_test(test_closeConnection),
};
return cmocka_run_group_tests(tests, NULL, NULL);

View File

@@ -22,65 +22,324 @@
#include <setjmp.h>
#include <cmocka.h>
#include <assert.h>
#include <nopoll.h>
#include "../src/ParodusInternal.h"
#include "../src/connection.h"
#include "../src/config.h"
#include "../src/upstream.h"
#include "../src/lws_handlers.h"
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
bool conn_retry;
volatile unsigned int heartBeatTimer;
bool close_retry;
bool LastReasonStatus;
volatile unsigned int heartBeatTimer;
pthread_mutex_t close_mut;
/*----------------------------------------------------------------------------*/
/* Mocks */
/*----------------------------------------------------------------------------*/
struct lws_context* lws_create_context ( struct lws_context_creation_info * info)
noPollConn * nopoll_conn_tls_new (noPollCtx * ctx, noPollConnOpts * options, const char * host_ip, const char * host_port, const char * host_name, const char * get_url, const char * protocols, const char * origin, const char * outbound_interface, const char * headerNames[], const char * headerValues[], const int headerCount)
{
function_called();
return (struct lws_context *) (intptr_t)mock();
}
struct lws* lws_client_connect_via_info (struct lws_client_connect_info * ccinfo)
{
function_called();
return (struct lws *) (intptr_t)mock();
UNUSED(options); UNUSED(host_port); UNUSED(host_name); UNUSED(get_url); UNUSED(protocols);
UNUSED(origin); UNUSED(outbound_interface); UNUSED(headerNames); UNUSED(headerValues); UNUSED(headerCount);
function_called();
check_expected((intptr_t)ctx);
check_expected((intptr_t)host_ip);
return (noPollConn *) (intptr_t)mock();
}
int lws_service(struct lws_context * context,int timeout)
noPollConn * nopoll_conn_new (noPollCtx * ctx, const char * host_ip, const char * host_port, const char * host_name, const char * get_url, const char * protocols, const char * origin, const char * outbound_interface, const char * headerNames[], const char * headerValues[], const int headerCount)
{
UNUSED(context); UNUSED(timeout);
UNUSED(host_port); UNUSED(host_name); UNUSED(get_url); UNUSED(protocols); UNUSED(origin);
UNUSED(outbound_interface); UNUSED(headerNames); UNUSED(headerValues); UNUSED(headerCount);
function_called();
check_expected((intptr_t)ctx);
check_expected((intptr_t)host_ip);
return (noPollConn *)(intptr_t)mock();
}
nopoll_bool nopoll_conn_is_ok (noPollConn * conn)
{
UNUSED(conn);
function_called();
return (nopoll_bool) mock();
}
nopoll_bool nopoll_conn_wait_until_connection_ready (noPollConn * conn, int timeout, char * message)
{
UNUSED(timeout); UNUSED(message);
UNUSED(conn);
function_called();
return (nopoll_bool) mock();
}
char* getWebpaConveyHeader()
{
function_called();
return (char*) (intptr_t)mock();
}
int checkHostIp(char * serverIP)
{
(void) serverIP;
function_called();
return (int) mock();
}
void getCurrentTime(struct timespec *timer)
{
(void) timer;
function_called();
}
long timeValDiff(struct timespec *starttime, struct timespec *finishtime)
{
(void) starttime; (void) finishtime;
function_called();
return (long) mock();
}
int kill(pid_t pid, int sig)
{
UNUSED(pid); UNUSED(sig);
function_called();
return (int) mock();
}
void nopoll_conn_close(noPollConn *conn)
{
UNUSED(conn);
function_called();
}
int nopoll_conn_ref_count(noPollConn * conn)
{
UNUSED(conn);
function_called();
return (int) mock();
}
void nopoll_conn_unref( noPollConn * conn)
{
UNUSED(conn);
function_called();
}
int strncmp(const char *s1, const char *s2, size_t n)
{
UNUSED(s1); UNUSED(s2); UNUSED(n);
function_called();
return (int) mock();
}
char *strtok(char *str, const char *delim)
{
UNUSED(str); UNUSED(delim);
function_called();
return (char*) (intptr_t)mock();
}
void setMessageHandlers()
{
function_called();
}
/*----------------------------------------------------------------------------*/
/* Tests */
/*----------------------------------------------------------------------------*/
void test_createSecureConnection()
{
noPollConn *gNPConn;
noPollCtx *ctx = nopoll_ctx_new();
ParodusCfg *cfg = (ParodusCfg*)malloc(sizeof(ParodusCfg));
memset(cfg, 0, sizeof(ParodusCfg));
struct lws_context *lwscontext;
struct lws * info;
conn_retry = false;
cfg->secureFlag = 1;
strcpy(cfg->webpa_url , "fabric.webpa.comcast.net");
strcpy(cfg->webpa_url , "localhost");
set_parodus_cfg(cfg);
will_return(lws_create_context, (intptr_t)&lwscontext);
expect_function_call(lws_create_context);
will_return(lws_client_connect_via_info, (intptr_t)&info);
expect_function_call(lws_client_connect_via_info);
will_return(lws_service, 1);
expect_function_call(lws_service);
createLWSconnection();
assert_non_null(ctx);
will_return(getWebpaConveyHeader, (intptr_t)"WebPA-1.6 (TG1682)");
expect_function_call(getWebpaConveyHeader);
expect_value(nopoll_conn_tls_new, (intptr_t)ctx, (intptr_t)ctx);
expect_string(nopoll_conn_tls_new, (intptr_t)host_ip, "localhost");
will_return(nopoll_conn_tls_new, (intptr_t)&gNPConn);
expect_function_call(nopoll_conn_tls_new);
will_return(nopoll_conn_is_ok, nopoll_true);
expect_function_call(nopoll_conn_is_ok);
will_return(nopoll_conn_wait_until_connection_ready, nopoll_true);
expect_function_call(nopoll_conn_wait_until_connection_ready);
expect_function_call(setMessageHandlers);
int ret = createNopollConnection(ctx);
assert_int_equal(ret, nopoll_true);
free(cfg);
nopoll_ctx_unref (ctx);
}
void test_createConnection()
{
noPollConn *gNPConn;
noPollCtx *ctx = nopoll_ctx_new();
ParodusCfg *cfg = (ParodusCfg*)malloc(sizeof(ParodusCfg));
memset(cfg, 0, sizeof(ParodusCfg));
assert_non_null(cfg);
cfg->secureFlag = 0;
strcpy(cfg->webpa_url , "localhost");
set_parodus_cfg(cfg);
assert_non_null(ctx);
will_return(getWebpaConveyHeader, (intptr_t)"WebPA-1.6 (TG1682)");
expect_function_call(getWebpaConveyHeader);
expect_value(nopoll_conn_new, (intptr_t)ctx, (intptr_t)ctx);
expect_string(nopoll_conn_new, (intptr_t)host_ip, "localhost");
will_return(nopoll_conn_new, (intptr_t)&gNPConn);
expect_function_call(nopoll_conn_new);
will_return(nopoll_conn_is_ok, nopoll_true);
expect_function_call(nopoll_conn_is_ok);
will_return(nopoll_conn_wait_until_connection_ready, nopoll_true);
expect_function_call(nopoll_conn_wait_until_connection_ready);
expect_function_call(setMessageHandlers);
int ret = createNopollConnection(ctx);
assert_int_equal(ret, nopoll_true);
free(cfg);
nopoll_ctx_unref (ctx);
}
void test_createConnectionConnNull()
{
noPollConn *gNPConn;
noPollCtx *ctx = nopoll_ctx_new();
ParodusCfg *cfg = (ParodusCfg*)malloc(sizeof(ParodusCfg));
memset(cfg, 0, sizeof(ParodusCfg));
cfg->secureFlag = 1;
cfg->webpa_backoff_max = 2;
strcpy(cfg->webpa_url , "localhost");
set_parodus_cfg(cfg);
assert_non_null(ctx);
will_return(getWebpaConveyHeader, (intptr_t)"");
expect_function_call(getWebpaConveyHeader);
expect_value(nopoll_conn_tls_new, (intptr_t)ctx, (intptr_t)ctx);
expect_string(nopoll_conn_tls_new, (intptr_t)host_ip, "localhost");
will_return(nopoll_conn_tls_new, (intptr_t)NULL);
expect_function_call(nopoll_conn_tls_new);
will_return(checkHostIp, -2);
expect_function_call(checkHostIp);
expect_function_call(getCurrentTime);
expect_value(nopoll_conn_tls_new, (intptr_t)ctx, (intptr_t)ctx);
expect_string(nopoll_conn_tls_new,(intptr_t)host_ip, "localhost");
will_return(nopoll_conn_tls_new, (intptr_t)NULL);
expect_function_call(nopoll_conn_tls_new);
will_return(checkHostIp, -2);
expect_function_call(checkHostIp);
expect_function_call(getCurrentTime);
will_return(timeValDiff, 15*60*1000);
expect_function_call(timeValDiff);
will_return(timeValDiff, 15*60*1000);
expect_function_call(timeValDiff);
will_return(kill, 1);
expect_function_call(kill);
expect_value(nopoll_conn_tls_new, (intptr_t)ctx, (intptr_t)ctx);
expect_string(nopoll_conn_tls_new, (intptr_t)host_ip, "localhost");
will_return(nopoll_conn_tls_new, (intptr_t)&gNPConn);
expect_function_call(nopoll_conn_tls_new);
will_return(nopoll_conn_is_ok, nopoll_true);
expect_function_call(nopoll_conn_is_ok);
will_return(nopoll_conn_wait_until_connection_ready, nopoll_true);
expect_function_call(nopoll_conn_wait_until_connection_ready);
expect_function_call(setMessageHandlers);
createNopollConnection(ctx);
free(cfg);
nopoll_ctx_unref (ctx);
}
void test_createConnectionConnNotOk()
{
noPollConn *gNPConn;
noPollCtx *ctx = nopoll_ctx_new();
ParodusCfg *cfg = (ParodusCfg*)malloc(sizeof(ParodusCfg));
memset(cfg, 0, sizeof(ParodusCfg));
assert_non_null(cfg);
cfg->secureFlag = 0;
strcpy(cfg->webpa_url , "localhost");
set_parodus_cfg(cfg);
assert_non_null(ctx);
will_return(getWebpaConveyHeader, (intptr_t)"WebPA-1.6 (TG1682)");
expect_function_call(getWebpaConveyHeader);
expect_value(nopoll_conn_new, (intptr_t)ctx, (intptr_t)ctx);
expect_string(nopoll_conn_new, (intptr_t)host_ip, "localhost");
will_return(nopoll_conn_new, (intptr_t)&gNPConn);
expect_function_call(nopoll_conn_new);
will_return(nopoll_conn_is_ok, nopoll_false);
expect_function_call(nopoll_conn_is_ok);
expect_function_call(nopoll_conn_close);
will_return(nopoll_conn_ref_count, 1);
expect_function_call(nopoll_conn_ref_count);
expect_function_call(nopoll_conn_unref);
expect_value(nopoll_conn_new, (intptr_t)ctx, (intptr_t)ctx);
expect_string(nopoll_conn_new, (intptr_t)host_ip, "localhost");
will_return(nopoll_conn_new, (intptr_t)&gNPConn);
expect_function_call(nopoll_conn_new);
will_return(nopoll_conn_is_ok, nopoll_true);
expect_function_call(nopoll_conn_is_ok);
will_return(nopoll_conn_wait_until_connection_ready, nopoll_false);
expect_function_call(nopoll_conn_wait_until_connection_ready);
will_return(strncmp, 12);
expect_function_call(strncmp);
expect_function_call(nopoll_conn_close);
will_return(nopoll_conn_ref_count, 0);
expect_function_call(nopoll_conn_ref_count);
expect_value(nopoll_conn_new, (intptr_t)ctx, (intptr_t)ctx);
expect_string(nopoll_conn_new, (intptr_t)host_ip, "localhost");
will_return(nopoll_conn_new, (intptr_t)&gNPConn);
expect_function_call(nopoll_conn_new);
will_return(nopoll_conn_is_ok, nopoll_true);
expect_function_call(nopoll_conn_is_ok);
will_return(nopoll_conn_wait_until_connection_ready, nopoll_false);
expect_function_call(nopoll_conn_wait_until_connection_ready);
will_return(strncmp, 0);
expect_function_call(strncmp);
will_return(strtok, (intptr_t)"");
will_return(strtok, (intptr_t)"");
will_return(strtok, (intptr_t)"p.10.0.0.12");
will_return(strtok, (intptr_t)"8080");
expect_function_calls(strtok, 4);
expect_function_call(nopoll_conn_close);
will_return(nopoll_conn_ref_count, 1);
expect_function_call(nopoll_conn_ref_count);
expect_function_call(nopoll_conn_unref);
expect_value(nopoll_conn_new, (intptr_t)ctx, (intptr_t)ctx);
expect_string(nopoll_conn_new, (intptr_t)host_ip, "10.0.0.12");
will_return(nopoll_conn_new, (intptr_t)&gNPConn);
expect_function_call(nopoll_conn_new);
will_return(nopoll_conn_is_ok, nopoll_true);
expect_function_call(nopoll_conn_is_ok);
will_return(nopoll_conn_wait_until_connection_ready, nopoll_true);
expect_function_call(nopoll_conn_wait_until_connection_ready);
expect_function_call(setMessageHandlers);
int ret = createNopollConnection(ctx);
assert_int_equal(ret, nopoll_true);
free(cfg);
nopoll_ctx_unref (ctx);
}
void err_createConnectionCtxNull()
{
noPollCtx *ctx = NULL;
assert_null(ctx);
int ret = createNopollConnection(ctx);
assert_int_equal(ret, nopoll_false);
}
/*----------------------------------------------------------------------------*/
@@ -91,6 +350,10 @@ int main(void)
{
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_createSecureConnection),
cmocka_unit_test(test_createConnection),
cmocka_unit_test(test_createConnectionConnNull),
cmocka_unit_test(test_createConnectionConnNotOk),
cmocka_unit_test(err_createConnectionCtxNull),
};
return cmocka_run_group_tests(tests, NULL, NULL);

View File

@@ -89,9 +89,6 @@ int validate_partner_id(wrp_msg_t *msg, partners_t **partnerIds)
void test_listenerOnMessage()
{
char * msg = "Hello";
char * message = (char*)malloc(sizeof(char)*strlen(msg));
strcpy(message,msg);
will_return(wrp_to_struct, 1);
expect_function_calls(wrp_to_struct, 1);
reg_list_item_t *head = (reg_list_item_t *) malloc(sizeof(reg_list_item_t));
@@ -107,15 +104,13 @@ void test_listenerOnMessage()
expect_function_call(get_global_node);
will_return(nn_send, 20);
expect_function_calls(nn_send, 1);
listenerOnMessage(message, strlen(message));
listenerOnMessage("Hello", 6);
free(head);
}
void test_listenerOnMessageMultipleClients()
{
char * msg = "Hello";
char * message = (char*)malloc(sizeof(char)*strlen(msg));
strcpy(message,msg);
will_return(wrp_to_struct, 1);
expect_function_calls(wrp_to_struct, 1);
@@ -145,7 +140,7 @@ void test_listenerOnMessageMultipleClients()
will_return(nn_send, 20);
expect_function_calls(nn_send, 1);
listenerOnMessage(message, strlen(message));
listenerOnMessage("Hello", 6);
free(head1);
free(head2);
free(head);
@@ -153,20 +148,14 @@ void test_listenerOnMessageMultipleClients()
void err_listenerOnMessage()
{
char * msg = "Hello";
char * message = (char*)malloc(sizeof(char)*strlen(msg));
strcpy(message,msg);
will_return(wrp_to_struct, 0);
expect_function_calls(wrp_to_struct, 1);
listenerOnMessage(message, strlen(message));
listenerOnMessage("Hello", 6);
}
void err_listenerOnMessageServiceUnavailable()
{
char * msg = "Hello";
char * message = (char*)malloc(sizeof(char)*strlen(msg));
strcpy(message,msg);
will_return(wrp_to_struct, 2);
expect_function_calls(wrp_to_struct, 1);
@@ -178,14 +167,11 @@ void err_listenerOnMessageServiceUnavailable()
expect_function_call(get_global_node);
expect_function_call(sendUpstreamMsgToServer);
listenerOnMessage(message, strlen(message));
listenerOnMessage("Hello", 6);
}
void err_listenerOnMessageInvalidPartnerId()
{
char * msg = "Hello";
char * message = (char*)malloc(sizeof(char)*strlen(msg));
strcpy(message,msg);
will_return(wrp_to_struct, 2);
expect_function_calls(wrp_to_struct, 1);
@@ -195,7 +181,7 @@ void err_listenerOnMessageInvalidPartnerId()
expect_function_call(validate_partner_id);
expect_function_call(sendUpstreamMsgToServer);
listenerOnMessage(message, strlen(message));
listenerOnMessage("Hello", 6);
}
void err_listenerOnMessageAllNull()

132
tests/test_mutex.c Normal file
View File

@@ -0,0 +1,132 @@
/**
* Copyright 2010-2016 Comcast Cable Communications Management, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <assert.h>
#include <errno.h>
#include <pthread.h>
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <CUnit/Basic.h>
#include "../src/ParodusInternal.h"
#include "../src/mutex.h"
struct shared_data {
noPollPtr mutex;
int number;
};
/*----------------------------------------------------------------------------*/
/* Mocks */
/*----------------------------------------------------------------------------*/
int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr)
{
UNUSED(attr); UNUSED(mutex);
return (int)mock();
}
int pthread_mutex_destroy(pthread_mutex_t *mutex)
{
UNUSED(mutex);
return (int)mock();
}
/*----------------------------------------------------------------------------*/
/* Tests */
/*----------------------------------------------------------------------------*/
void* a(void *in)
{
struct shared_data *data = (struct shared_data*) in;
lockMutex(data->mutex);
data->number++;
sleep(1);
data->number++;
sleep(1);
data->number++;
unlockMutex(data->mutex);
return NULL;
}
void* b(void *in)
{
struct shared_data *data = (struct shared_data*) in;
lockMutex(data->mutex);
data->number+=10;
sleep(1);
data->number+=10;
sleep(1);
data->number+=10;
unlockMutex(data->mutex);
return NULL;
}
void test_Mutex()
{
volatile struct shared_data data;
pthread_t thread[2];
data.number = 0;
will_return(pthread_mutex_init, 0);
data.mutex = createMutex();
pthread_create(&thread[0], NULL, a, (void*)(&data));
pthread_create(&thread[1], NULL, b, (void*)(&data));
pthread_join(thread[0], NULL);
pthread_join(thread[1], NULL);
will_return(pthread_mutex_destroy, 0);
destroyMutex(data.mutex);
assert_int_equal(33, data.number);
}
void err_mutex()
{
static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
noPollPtr mutex = &mtx;
will_return(pthread_mutex_destroy, -1);
destroyMutex(mutex);
will_return(pthread_mutex_init, -1);
mutex = createMutex();
}
void err_mutexNull()
{
lockMutex(NULL);
unlockMutex(NULL);
destroyMutex(NULL);
}
/*----------------------------------------------------------------------------*/
/* External Functions */
/*----------------------------------------------------------------------------*/
int main( void )
{
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_Mutex),
cmocka_unit_test(err_mutex),
cmocka_unit_test(err_mutexNull),
};
return cmocka_run_group_tests(tests, NULL, NULL);
}

View File

@@ -17,30 +17,72 @@
#include <stdarg.h>
#include <stdbool.h>
#include <CUnit/Basic.h>
#include <nopoll.h>
#include <nopoll_private.h>
#include <pthread.h>
#include "../src/lws_handlers.h"
#include "../src/nopoll_handlers.h"
#include "../src/parodus_log.h"
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
volatile unsigned int heartBeatTimer;
bool LastReasonStatus;
pthread_mutex_t close_mut;
bool close_retry;
/*----------------------------------------------------------------------------*/
/* Mocks */
/*----------------------------------------------------------------------------*/
void set_global_reconnect_reason(char *reason)
{
(void) reason;
}
const unsigned char *nopoll_msg_get_payload(noPollMsg *msg)
{
if( NULL != msg ) {
return (unsigned char *) "Dummy payload";
}
return NULL;
}
noPollOpCode nopoll_msg_opcode (noPollMsg * msg)
{
if(NULL != msg)
{
return NOPOLL_PING_FRAME;
}
return NOPOLL_UNKNOWN_OP_CODE;
}
int nopoll_msg_get_payload_size(noPollMsg *msg)
{
(void) msg;
return 1;
}
int nopoll_conn_send_frame (noPollConn * conn, nopoll_bool fin, nopoll_bool masked,
noPollOpCode op_code, long length, noPollPtr content, long sleep_in_header)
{
(void) conn; (void) fin; (void) masked; (void) op_code;
(void) length; (void) content; (void) sleep_in_header;
return 0;
}
/*----------------------------------------------------------------------------*/
/* Tests */
/*----------------------------------------------------------------------------*/
void *a(void *in)
{
void *msg = "Dummy Payload";
noPollMsg msg;
(void) in;
listenerOnrequest_queue(msg,13 );
listenerOnMessage_queue(NULL, NULL, &msg, NULL);
pthread_exit(0);
return NULL;
@@ -48,10 +90,10 @@ void *a(void *in)
void *b(void *in)
{
void *msg = "Dummy Payload1";
noPollMsg msg;
(void) in;
listenerOnrequest_queue(msg, 14);
listenerOnMessage_queue(NULL, NULL, &msg, NULL);
pthread_exit(0);
return NULL;
@@ -69,11 +111,55 @@ void test_listenerOnMessage_queue()
}
void *a1(void *in)
{
char str[] = "SSL_Socket_Close";
(void) in;
LastReasonStatus = false;
listenerOnCloseMessage(NULL, NULL, NULL);
LastReasonStatus = false;
listenerOnCloseMessage(NULL, NULL, (noPollPtr) str);
LastReasonStatus = true;
listenerOnCloseMessage(NULL, NULL, NULL);
LastReasonStatus = true;
listenerOnCloseMessage(NULL, NULL, (noPollPtr) str);
pthread_exit(0);
return NULL;
}
void test_listenerOnCloseMessage()
{
pthread_t thread_a;
pthread_create(&thread_a, NULL, a1, NULL);
pthread_join(thread_a, NULL);
}
void test_listenerOnPingMessage()
{
noPollConn c;
noPollMsg m;
listenerOnPingMessage(NULL, &c, NULL, NULL);
listenerOnPingMessage(NULL, &c, &m, NULL);
listenerOnPingMessage(NULL, NULL, NULL, NULL);
}
void add_suites( CU_pSuite *suite )
{
ParodusInfo("--------Start of Test Cases Execution ---------\n");
*suite = CU_add_suite( "tests", NULL, NULL );
CU_add_test( *suite, "Test 1", test_listenerOnMessage_queue );
CU_add_test( *suite, "Test 2", test_listenerOnCloseMessage );
CU_add_test( *suite, "Test 3", test_listenerOnPingMessage );
}
/*----------------------------------------------------------------------------*/

267
tests/test_nopoll_helpers.c Normal file
View File

@@ -0,0 +1,267 @@
/**
* Copyright 2010-2016 Comcast Cable Communications Management, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <nopoll.h>
#include "../src/parodus_log.h"
#include "../src/nopoll_helpers.h"
/*----------------------------------------------------------------------------*/
/* Macros */
/*----------------------------------------------------------------------------*/
#define UNUSED(x) (void )(x)
#define MAX_SEND_SIZE (60 * 1024)
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
static noPollConn *conn;
/*----------------------------------------------------------------------------*/
/* Mocks */
/*----------------------------------------------------------------------------*/
nopoll_bool nopoll_conn_is_ok( noPollConn *conn )
{
ParodusInfo("function_called : %s\n",__FUNCTION__);
function_called();
check_expected((intptr_t)conn);
return (nopoll_bool)mock();
}
nopoll_bool nopoll_conn_is_ready( noPollConn *conn )
{
ParodusInfo("function_called : %s\n",__FUNCTION__);
function_called();
check_expected((intptr_t)conn);
return (nopoll_bool)mock();
}
int __nopoll_conn_send_common (noPollConn * conn, const char * content, long length, nopoll_bool has_fin, long sleep_in_header, noPollOpCode frame_type)
{
UNUSED(has_fin); UNUSED(sleep_in_header); UNUSED(frame_type); UNUSED(content);
ParodusInfo("function_called : %s\n",__FUNCTION__);
function_called();
check_expected((intptr_t)conn);
check_expected(length);
return (int)mock();
}
int nopoll_conn_flush_writes(noPollConn * conn, long timeout, int previous_result)
{
UNUSED(timeout);
ParodusInfo("function_called : %s\n",__FUNCTION__);
function_called();
check_expected((intptr_t)conn);
check_expected(previous_result);
return (int)mock();
}
noPollConn *get_global_conn()
{
return conn;
}
void listenerOnMessage_queue(noPollCtx * ctx, noPollConn * conn, noPollMsg * msg,noPollPtr user_data)
{
UNUSED(ctx); UNUSED(conn); UNUSED(msg); UNUSED(user_data);
}
void listenerOnPingMessage (noPollCtx * ctx, noPollConn * conn, noPollMsg * msg, noPollPtr user_data)
{
UNUSED(ctx); UNUSED(conn); UNUSED(msg); UNUSED(user_data);
}
void listenerOnCloseMessage (noPollCtx * ctx, noPollConn * conn, noPollPtr user_data)
{
UNUSED(ctx); UNUSED(conn); UNUSED(user_data);
}
/*----------------------------------------------------------------------------*/
/* Tests */
/*----------------------------------------------------------------------------*/
void test_setMessageHandlers()
{
setMessageHandlers();
}
void test_sendResponse()
{
int len = strlen("Hello Parodus!");
expect_value(__nopoll_conn_send_common, (intptr_t)conn, (intptr_t)conn);
expect_value(__nopoll_conn_send_common, length,(intptr_t) len);
will_return(__nopoll_conn_send_common, (intptr_t)len);
expect_function_calls(__nopoll_conn_send_common, 1);
int bytesWritten = sendResponse(conn, "Hello Parodus!", len);
ParodusPrint("Number of bytes written: %d\n", bytesWritten);
assert_int_equal(bytesWritten, len);
}
void test_sendResponseWithFragments()
{
int len = (MAX_SEND_SIZE*2)+64;
expect_value(__nopoll_conn_send_common, (intptr_t)conn, (intptr_t)conn);
expect_value(__nopoll_conn_send_common, length, MAX_SEND_SIZE);
will_return(__nopoll_conn_send_common, MAX_SEND_SIZE);
expect_value(__nopoll_conn_send_common, (intptr_t)conn, (intptr_t)conn);
expect_value(__nopoll_conn_send_common, length, MAX_SEND_SIZE);
will_return(__nopoll_conn_send_common, MAX_SEND_SIZE);
expect_value(__nopoll_conn_send_common, (intptr_t)conn, (intptr_t)conn);
expect_value(__nopoll_conn_send_common, length, 64);
will_return(__nopoll_conn_send_common, 64);
expect_function_calls(__nopoll_conn_send_common, 3);
int bytesWritten = sendResponse(conn, "Hello Parodus!", len);
ParodusPrint("Number of bytes written: %d\n", bytesWritten);
assert_int_equal(bytesWritten, len);
}
void err_sendResponse()
{
int len = strlen("Hello Parodus!");
expect_value(__nopoll_conn_send_common, (intptr_t)conn, (intptr_t)conn);
expect_value(__nopoll_conn_send_common, length, (intptr_t)len);
will_return(__nopoll_conn_send_common, -1);
expect_function_calls(__nopoll_conn_send_common, 1);
int bytesWritten = sendResponse(conn, "Hello Parodus!", len);
ParodusPrint("Number of bytes written: %d\n", bytesWritten);
assert_int_equal(bytesWritten, 0);
}
void err_sendResponseFlushWrites()
{
int len = strlen("Hello Parodus!");
expect_value(__nopoll_conn_send_common, (intptr_t)conn, (intptr_t)conn);
expect_value(__nopoll_conn_send_common, length, len);
will_return(__nopoll_conn_send_common, len-3);
expect_function_calls(__nopoll_conn_send_common, 1);
expect_value(nopoll_conn_flush_writes, (intptr_t)conn, (intptr_t)conn);
expect_value(nopoll_conn_flush_writes, previous_result, len-3);
will_return(nopoll_conn_flush_writes, len-3);
expect_function_calls(nopoll_conn_flush_writes, 1);
int bytesWritten = sendResponse(conn, "Hello Parodus!", len);
ParodusPrint("Number of bytes written: %d\n", bytesWritten);
assert_int_equal(bytesWritten, 0);
}
void err_sendResponseConnNull()
{
int len = strlen("Hello Parodus!");
expect_value(__nopoll_conn_send_common, (intptr_t)conn, (intptr_t)NULL);
expect_value(__nopoll_conn_send_common, length, len);
will_return(__nopoll_conn_send_common, -1);
expect_function_calls(__nopoll_conn_send_common, 1);
int bytesWritten = sendResponse(NULL, "Hello Parodus!", len);
ParodusPrint("Number of bytes written: %d\n", bytesWritten);
assert_int_equal(bytesWritten, 0);
}
void test_sendMessage()
{
int len = strlen("Hello Parodus!");
expect_value(nopoll_conn_is_ok, (intptr_t)conn, (intptr_t)conn);
will_return(nopoll_conn_is_ok, nopoll_true);
expect_function_call(nopoll_conn_is_ok);
expect_value(nopoll_conn_is_ready, (intptr_t)conn, (intptr_t)conn);
will_return(nopoll_conn_is_ready, nopoll_true);
expect_function_call(nopoll_conn_is_ready);
expect_value(__nopoll_conn_send_common, (intptr_t)conn, (intptr_t)conn);
expect_value(__nopoll_conn_send_common, length, len);
will_return(__nopoll_conn_send_common, len);
expect_function_calls(__nopoll_conn_send_common, 1);
sendMessage(conn, "Hello Parodus!", len);
}
void err_sendMessage()
{
int len = strlen("Hello Parodus!");
expect_value(nopoll_conn_is_ok, (intptr_t)conn, (intptr_t)conn);
will_return(nopoll_conn_is_ok, nopoll_true);
expect_function_call(nopoll_conn_is_ok);
expect_value(nopoll_conn_is_ready, (intptr_t)conn, (intptr_t)conn);
will_return(nopoll_conn_is_ready, nopoll_true);
expect_function_call(nopoll_conn_is_ready);
expect_value(__nopoll_conn_send_common, (intptr_t)conn,(intptr_t) conn);
expect_value(__nopoll_conn_send_common, length, len);
will_return(__nopoll_conn_send_common, len-2);
expect_function_calls(__nopoll_conn_send_common, 1);
expect_value(nopoll_conn_flush_writes, (intptr_t)conn, (intptr_t)conn);
expect_value(nopoll_conn_flush_writes, previous_result, len-2);
will_return(nopoll_conn_flush_writes, len-3);
expect_function_calls(nopoll_conn_flush_writes, 1);
sendMessage(conn, "Hello Parodus!", len);
}
void err_sendMessageConnNull()
{
int len = strlen("Hello Parodus!");
expect_value(nopoll_conn_is_ok, (intptr_t)conn, (intptr_t)NULL);
will_return(nopoll_conn_is_ok, nopoll_false);
expect_function_call(nopoll_conn_is_ok);
sendMessage(NULL, "Hello Parodus!", len);
}
void test_reportLog()
{
__report_log(NULL, NOPOLL_LEVEL_DEBUG, "Debug", NULL);
__report_log(NULL, NOPOLL_LEVEL_INFO, "Info", NULL);
__report_log(NULL, NOPOLL_LEVEL_WARNING, "Warning", NULL);
__report_log(NULL, NOPOLL_LEVEL_CRITICAL, "Critical", NULL);
}
/*----------------------------------------------------------------------------*/
/* External Functions */
/*----------------------------------------------------------------------------*/
int main(void)
{
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_setMessageHandlers),
cmocka_unit_test(test_sendResponse),
cmocka_unit_test(test_sendResponseWithFragments),
cmocka_unit_test(err_sendResponse),
cmocka_unit_test(err_sendResponseFlushWrites),
cmocka_unit_test(err_sendResponseConnNull),
cmocka_unit_test(test_sendMessage),
cmocka_unit_test(err_sendMessage),
cmocka_unit_test(err_sendMessageConnNull),
cmocka_unit_test(test_reportLog),
};
return cmocka_run_group_tests(tests, NULL, NULL);
}

View File

@@ -1,389 +0,0 @@
/**
* Copyright 2010-2016 Comcast Cable Communications Management, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdarg.h>
#include <CUnit/Basic.h>
#include <stdbool.h>
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <assert.h>
#include "../src/ParodusInternal.h"
#include "../src/connection.h"
#include "../src/config.h"
#include "../src/upstream.h"
#include "../src/lws_handlers.h"
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
bool conn_retry;
volatile unsigned int heartBeatTimer;
bool LastReasonStatus;
/*----------------------------------------------------------------------------*/
/* Mocks */
/*----------------------------------------------------------------------------*/
int lws_is_final_fragment (struct lws * wsi)
{
function_called();
return (int) mock();
}
int lws_callback_on_writable (struct lws * wsi)
{
return 1;
}
void listenerOnrequest_queue(void *requestMsg,int reqSize)
{
UNUSED(requestMsg);
UNUSED(reqSize);
}
int lws_write (struct lws * wsi,unsigned char * buf,size_t len,enum lws_write_protocol protocol)
{
function_called();
return (int) mock();
}
char* getWebpaConveyHeader()
{
function_called();
return (char*) (intptr_t)mock();
}
int LWS_WARN_UNUSED_RESULT lws_add_http_header_by_name (struct lws * wsi,const unsigned char *name,const unsigned char *value,int length,unsigned char **p,unsigned char *end)
{
function_called();
return (int) mock();
}
/*----------------------------------------------------------------------------*/
/* Tests */
/*----------------------------------------------------------------------------*/
void test_callBack1()
{
struct lws *info = malloc(10);
void *user = "connection";
void *in = "payload";
size_t size = 0;
parodus_callback(info,LWS_CALLBACK_CLIENT_ESTABLISHED,user,in,size);
if(!conn_retry)
{
ParodusInfo("Success: conn_retry status changed %d\n",conn_retry);
}
free(info);
}
void test_callBack2()
{
struct lws *info = malloc(10);
void *user = "connection";
void *in = "payload";
size_t size = 0;
parodus_callback(info,LWS_CALLBACK_CLOSED,user,in,size);
if(conn_retry)
{
ParodusInfo("Success: conn_retry status changed %d\n",conn_retry);
}
free(info);
}
void test_callBack3()
{
struct lws *info = malloc(10);
void *user = "connection";
size_t size = 0;
void *bytes;
const wrp_msg_t msg = { .msg_type = WRP_MSG_TYPE__REQ,
.u.req.transaction_uuid = "c07ee5e1-70be-444c-a156-097c767ad8aa",
.u.req.content_type = "application/json",
.u.req.source = "source-address",
.u.req.dest = "dest-address",
.u.req.partner_ids = NULL,
.u.req.headers = NULL,
.u.req.include_spans = false,
.u.req.spans.spans = NULL,
.u.req.spans.count = 0,
.u.req.payload = "Test libwebsocket reciever callback",
.u.req.payload_size = 35
};
size = wrp_struct_to( &msg, WRP_BYTES, &bytes );
will_return(lws_is_final_fragment,1);
expect_function_call(lws_is_final_fragment);
parodus_callback(info,LWS_CALLBACK_CLIENT_RECEIVE,user,bytes,size);
free(bytes);
free(info);
}
void test_callBack4()
{
struct lws *info = malloc(10);
void *user = "connection";
size_t size = 0;
void *bytes;
ParodusInfo( "\n Inside test_encode_decode()....\n" );
const wrp_msg_t msg = { .msg_type = WRP_MSG_TYPE__REQ,
.u.req.transaction_uuid = "c07ee5e1-70be-444c-a156-097c767ad8aa",
.u.req.content_type = "application/json",
.u.req.source = "source-address",
.u.req.dest = "dest-address",
.u.req.partner_ids = NULL,
.u.req.headers = NULL,
.u.req.include_spans = false,
.u.req.spans.spans = NULL,
.u.req.spans.count = 0,
.u.req.payload = "Test libwebsocket reciever callback",
.u.req.payload_size = 35
};
size = wrp_struct_to( &msg, WRP_BYTES, &bytes );
will_return(lws_is_final_fragment,0);
expect_function_call(lws_is_final_fragment);
parodus_callback(info,LWS_CALLBACK_CLIENT_RECEIVE,user,bytes,size);
will_return(lws_is_final_fragment,0);
expect_function_call(lws_is_final_fragment);
parodus_callback(info,LWS_CALLBACK_CLIENT_RECEIVE,user,bytes,size);
will_return(lws_is_final_fragment,1);
expect_function_call(lws_is_final_fragment);
parodus_callback(info,LWS_CALLBACK_CLIENT_RECEIVE,user,bytes,size);
free(bytes);
free(info);
}
void test_callBack5()
{
struct lws *info = malloc(10);
void *user = "connection";
void *in = "payload";
size_t size = 0;
parodus_callback(info,LWS_CALLBACK_CLIENT_CONNECTION_ERROR,user,in,size);
if(conn_retry)
{
ParodusInfo("Success: conn_retry status changed %d\n",conn_retry);
}
free(info);
}
void test_callBack6()
{
struct lws *info = malloc(10);
void *user = "connection";
void *in = "payload";
size_t size = 0;
UpStreamMsg *message = (UpStreamMsg *)malloc(sizeof(UpStreamMsg));
message->msg = (char*)malloc(sizeof(char)*10);
strcpy(message->msg,"payload");
message->len = 7;
message->next = NULL;
ResponseMsgQ = message;
will_return(lws_write,7);
expect_function_call(lws_write);
parodus_callback(info,LWS_CALLBACK_CLIENT_WRITEABLE,user,in,size);
free(message->msg);
free(message);
free(info);
}
void test_callBack7()
{
struct lws *info = malloc(10);
void *user = "connection";
void *in = "payload";
size_t size = 0;
UpStreamMsg *message = (UpStreamMsg *)malloc(sizeof(UpStreamMsg));
message->msg = (char*)malloc(sizeof(char)*10);
strcpy(message->msg,"payload");
message->len = 7;
message->next = NULL;
ResponseMsgQ = message;
will_return(lws_write,-1);
expect_function_call(lws_write);
parodus_callback(info,LWS_CALLBACK_CLIENT_WRITEABLE,user,in,size);
free(message->msg);
free(message);
free(info);
}
void test_callBack8()
{
struct lws *info = malloc(10);
void *user = "connection";
void *in = "payload";
size_t size = 0;
UpStreamMsg *message = (UpStreamMsg *)malloc(sizeof(UpStreamMsg));
message->msg = (char*)malloc(sizeof(char)*10);
strcpy(message->msg,"payload");
message->len = 7;
message->next = NULL;
ResponseMsgQ = message;
will_return(lws_write,5);
expect_function_call(lws_write);
parodus_callback(info,LWS_CALLBACK_CLIENT_WRITEABLE,user,in,size);
free(message->msg);
free(message);
free(info);
}
void test_callBack9()
{
struct lws *info = malloc(10);
void *user = "connection";
void *in = "payload";
size_t size = 0;
will_return(getWebpaConveyHeader, (intptr_t)"WebPA-1.6 (TG1682)");
expect_function_call(getWebpaConveyHeader);
will_return(lws_add_http_header_by_name,0);
expect_function_call(lws_add_http_header_by_name);
will_return(lws_add_http_header_by_name,0);
expect_function_call(lws_add_http_header_by_name);
will_return(lws_add_http_header_by_name,0);
expect_function_call(lws_add_http_header_by_name);
will_return(lws_add_http_header_by_name,0);
expect_function_call(lws_add_http_header_by_name);
parodus_callback(info,LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER,user,in,size);
free(info);
}
void test_callBack10()
{
struct lws *info = malloc(10);
void *user = "connection";
void *in = "payload";
size_t size = 0;
will_return(getWebpaConveyHeader, (intptr_t)"");
expect_function_call(getWebpaConveyHeader);
will_return(lws_add_http_header_by_name,1);
expect_function_call(lws_add_http_header_by_name);
parodus_callback(info,LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER,user,in,size);
free(info);
}
void test_callBack11()
{
struct lws *info = malloc(10);
void *user = "connection";
void *in = "payload";
size_t size = 0;
will_return(getWebpaConveyHeader, (intptr_t)"");
expect_function_call(getWebpaConveyHeader);
will_return(lws_add_http_header_by_name,0);
expect_function_call(lws_add_http_header_by_name);
will_return(lws_add_http_header_by_name,1);
expect_function_call(lws_add_http_header_by_name);
parodus_callback(info,LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER,user,in,size);
free(info);
}
void test_callBack12()
{
struct lws *info = malloc(10);
void *user = "connection";
void *in = "payload";
size_t size = 0;
will_return(getWebpaConveyHeader, (intptr_t)"");
expect_function_call(getWebpaConveyHeader);
will_return(lws_add_http_header_by_name,0);
expect_function_call(lws_add_http_header_by_name);
will_return(lws_add_http_header_by_name,0);
expect_function_call(lws_add_http_header_by_name);
will_return(lws_add_http_header_by_name,1);
expect_function_call(lws_add_http_header_by_name);
parodus_callback(info,LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER,user,in,size);
free(info);
}
void test_callBack13()
{
struct lws *info = malloc(10);
void *user = "connection";
void *in = "payload";
size_t size = 0;
will_return(getWebpaConveyHeader, (intptr_t)"");
expect_function_call(getWebpaConveyHeader);
will_return(lws_add_http_header_by_name,0);
expect_function_call(lws_add_http_header_by_name);
will_return(lws_add_http_header_by_name,0);
expect_function_call(lws_add_http_header_by_name);
will_return(lws_add_http_header_by_name,0);
expect_function_call(lws_add_http_header_by_name);
parodus_callback(info,LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER,user,in,size);
free(info);
}
void test_callBack14()
{
struct lws *info = malloc(10);
void *user = "connection";
void *in = "payload";
size_t size = 0;
will_return(getWebpaConveyHeader, (intptr_t)"WebPA-1.6 (TG1682)");
expect_function_call(getWebpaConveyHeader);
will_return(lws_add_http_header_by_name,0);
expect_function_call(lws_add_http_header_by_name);
will_return(lws_add_http_header_by_name,0);
expect_function_call(lws_add_http_header_by_name);
will_return(lws_add_http_header_by_name,0);
expect_function_call(lws_add_http_header_by_name);
will_return(lws_add_http_header_by_name,1);
expect_function_call(lws_add_http_header_by_name);
parodus_callback(info,LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER,user,in,size);
free(info);
}
void test_callBack15()
{
struct lws *info = malloc(10);
void *in = "payload";
size_t size = 0;
X509_STORE_CTX *ctx;
ctx = X509_STORE_CTX_new();
parodus_callback(info,LWS_CALLBACK_OPENSSL_PERFORM_SERVER_CERT_VERIFICATION,ctx,in,size);
free(info);
}
/*----------------------------------------------------------------------------*/
/* External Functions */
/*----------------------------------------------------------------------------*/
int main(void)
{
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_callBack1),
cmocka_unit_test(test_callBack2),
cmocka_unit_test(test_callBack3),
cmocka_unit_test(test_callBack4),
cmocka_unit_test(test_callBack5),
cmocka_unit_test(test_callBack6),
cmocka_unit_test(test_callBack7),
cmocka_unit_test(test_callBack8),
cmocka_unit_test(test_callBack9),
cmocka_unit_test(test_callBack10),
cmocka_unit_test(test_callBack11),
cmocka_unit_test(test_callBack12),
cmocka_unit_test(test_callBack13),
cmocka_unit_test(test_callBack14),
cmocka_unit_test(test_callBack15),
};
return cmocka_run_group_tests(tests, NULL, NULL);
}

View File

@@ -22,6 +22,7 @@
#include <setjmp.h>
#include <cmocka.h>
#include <nopoll.h>
#include <wrp-c.h>
#include <nanomsg/nn.h>
@@ -34,6 +35,7 @@
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
static noPollConn *conn;
static char *reconnect_reason = "webpa_process_starts";
static ParodusCfg parodusCfg;
extern size_t metaPackSize;
@@ -44,6 +46,10 @@ wrp_msg_t *temp = NULL;
/* Mocks */
/*----------------------------------------------------------------------------*/
noPollConn *get_global_conn()
{
return conn;
}
char *get_global_reconnect_reason()
{
@@ -61,7 +67,11 @@ int get_numOfClients()
function_called();
return (int)mock();
}
void sendMessage(noPollConn *conn, void *msg, size_t len)
{
(void) conn; (void) msg; (void) len;
function_called();
}
ParodusCfg *get_parodus_cfg(void)
{
@@ -269,7 +279,7 @@ void test_processUpstreamMessage()
will_return(appendEncodedData, 100);
expect_function_call(appendEncodedData);
//expect_function_call(sendMessage);
expect_function_call(sendMessage);
expect_function_call(wrp_free_struct);
will_return(nn_freemsg,1);
@@ -306,7 +316,7 @@ void test_processUpstreamMessageInvalidPartner()
will_return(appendEncodedData, 100);
expect_function_call(appendEncodedData);
//expect_function_call(sendMessage);
expect_function_call(sendMessage);
expect_function_call(wrp_free_struct);
will_return(nn_freemsg,1);
@@ -553,7 +563,7 @@ void test_sendUpstreamMsgToServer()
will_return(appendEncodedData, 100);
expect_function_call(appendEncodedData);
//expect_function_call(sendMessage);
expect_function_call(sendMessage);
sendUpstreamMsgToServer(&bytes, 110);
free(bytes);
}