Compare commits

...

66 Commits

Author SHA1 Message Date
shilpa24balaji
f032d2ca30 Merge pull request #347 from xmidt-org/4.1_pb
4.1 pb
2020-03-18 14:28:54 -07:00
shilpa24balaji
9cfc734c51 Merge pull request #331 from rajnishdey/errMsgUpdate
Change Info log level from error log level for "received temporary re…
2019-11-18 10:51:06 -08:00
Rajnish
153add9bec Change Info log level from error log level for "received temporary redirection response". 2019-11-18 11:28:43 -05:00
shilpa24balaji
7679fdaf4a Merge pull request #327 from bill1600/ifcdown
update backoff delay and interface down logic
2019-11-15 12:27:41 -08:00
Bill Williams
1c09a80493 fix condition test in wait_while_interface_down 2019-11-14 15:31:28 -08:00
Bill Williams
bfad8ed44b fix deadlock in wait_while_interface_down 2019-11-14 10:56:47 -08:00
Shilpa Seshadri
8c576f8f48 Merge tag '1.1.2' of https://github.com/Comcast/parodus into parodus_debug
Nov 2019 release
2019-11-13 12:58:37 -08:00
Shilpa Seshadri
dacac5fe8d To print nopoll debug logs changing level to info 2019-11-13 12:02:01 -08:00
Bill Williams
17c7faff50 update backoff delay error logging 2019-11-12 15:12:53 -08:00
Bill Williams
01120da9ac backoff delay updates 2019-11-12 14:37:10 -08:00
shilpa24balaji
c7c6fb4926 Merge pull request #328 from bill1600/nosig9
Nosig9
2019-11-12 10:30:59 -08:00
Bill Williams
f4b2c252ae update changelog for nosig9 2019-11-12 10:18:40 -08:00
Bill Williams
8794ce2092 dont try to install handler for signal 9 2019-11-12 10:17:01 -08:00
Bill Williams
a61e97633b update backoff delay for interface down 2019-11-11 13:24:07 -08:00
shilpa24balaji
4d3d6ec99d Merge pull request #326 from bill1600/bkpshut
update parodus shutdown
2019-11-06 10:42:54 -08:00
shilpa24balaji
e6ac264e47 Update CHANGELOG.md 2019-11-06 10:31:53 -08:00
Bill Williams
70c9975ae9 remove leftover local test 2019-11-05 14:21:37 -08:00
Bill Williams
11a2b6f123 restore test_interface_down_retry 2019-11-04 15:29:43 -08:00
Bill Williams
81d8f59bbd fix so that parodus can be killed if it connection fail loop 2019-11-01 14:14:18 -07:00
Bill Williams
846b0588c2 pu cloud status back 2019-11-01 11:40:35 -07:00
Bill Williams
ad44ff0221 remove 403 upgrade from this build 2019-11-01 10:00:39 -07:00
Bill Williams
513647ceef remove unnecessary nopoll_con_ref_count 2019-10-31 15:26:51 -07:00
Bill Williams
2ec3443b1d update parodus shutdown 2019-10-29 11:34:29 -07:00
shilpa24balaji
55e10aa051 Merge pull request #325 from shilpa24balaji/3.12_p3b
Update retry time in connection-health-file
2019-10-25 11:56:33 -07:00
Shilpa Seshadri
879a585b66 Update retry time in connection-health-file 2019-10-24 18:20:20 -07:00
shilpa24balaji
ea3534678b Merge pull request #321 from xmidt-org/unref_crash
nopoll_conn_unref crash fix
2019-09-18 16:49:19 -07:00
Shilpa Seshadri
6ebb62ead4 Removing the additional conn_unref as conn_close handles this 2019-09-18 11:18:26 -07:00
Shilpa Seshadri
5ec16a7370 Re-order the cloud status update to prevent the nopoll_conn_unref crash 2019-09-16 16:26:56 -07:00
shilpa24balaji
7b81cb4efd Update README.md 2019-09-12 17:12:48 -07:00
shilpa24balaji
4c6a6a99e6 Merge pull request #320 from xmidt-org/event_handler
Ping Status change event handler
2019-09-12 16:42:01 -07:00
shilpa24balaji
106e1bfeb3 Merge pull request #318 from bill1600/waitconrdy
initialize wait_status in wait_connection_ready
2019-09-10 10:28:27 -07:00
Shilpa Seshadri
4f01170670 Handler definition for Ping Status change event 2019-09-09 16:51:39 -07:00
shilpa24balaji
f37d1911d6 Merge pull request #319 from xmidt-org/master
Sync from master branch
2019-09-09 13:13:29 -07:00
Bill Williams
3a436999fc initialize wait_status in wait_connection_ready 2019-09-06 11:56:56 -07:00
shilpa24balaji
016c80960c Merge pull request #316 from guruchandru/parodus_event
Parodus cloud Status update and Unit tests
2019-08-22 16:34:48 -07:00
Guru Chandru
b286857a22 Parodus cloud Status update and Unit tests 2019-08-22 11:50:56 +05:30
Shilpa Seshadri
f998106aed Log reconnect reason and update change log 2019-08-19 21:46:45 -07:00
shilpa24balaji
2d209b2a0d Merge pull request #315 from xmidt-org/event_handler
Pause connection retry when interface is down
2019-08-19 16:41:41 -07:00
Shilpa Seshadri
3f471100db Pause retry when interface is down and until its up 2019-08-17 03:43:50 -07:00
shilpa24balaji
ddc04f9da0 Merge pull request #313 from guruchandru/parodus_checkin
Parodus cloud-status shows "online" when connection is closed during …
2019-08-15 15:34:09 -07:00
Guru Chandru
a23615f3a5 Parodus cloud-status shows "online" when connection is closed during interface-down 2019-08-14 18:39:01 +05:30
shilpa24balaji
b1caff4a1a Merge pull request #312 from guruchandru/parodus_handler
parodus event handler to listen to interface_down and interface_up event
2019-08-09 12:41:59 -07:00
Sadhyama Vengilat
11c9052d77 parodus event handler to listen to interface_down and interface_up event 2019-08-07 12:19:38 +05:30
guruchandru
5ceb57a8c3 Merge pull request #1 from bill1600/sysevent
add pause/resume heartBeatTimer
2019-08-06 10:48:59 +05:30
guruchandru
c4ebe239ac Merge branch 'parodus_handler' into sysevent 2019-08-06 10:39:45 +05:30
shilpa24balaji
1622c44c89 Merge pull request #307 from gbuddappagari/parodus_onboard
RDKB-20643:Add OnBoarding logs
2019-07-24 20:15:06 -07:00
shilpa24balaji
fb542586e7 Update CMakeLists.txt 2019-07-24 20:13:40 -07:00
Gayathri Buddappagari
0afb87c29b RDKB-20643:Add OnBoarding logs 2019-07-15 17:02:01 +05:30
shilpa24balaji
f168e4d148 Merge pull request #308 from bill1600/nopoll_102
Use nopoll version 1.0.2
2019-07-02 14:52:36 -07:00
Bill Williams
97570a24d5 Use nopoll version 1.0.2 2019-07-02 13:24:20 -07:00
shilpa24balaji
95b6f75284 Merge pull request #306 from bill1600/newauthtoken
request new auth token on every retry, not just after 403
2019-06-12 11:38:10 -07:00
Bill Williams
f87e69c07b no need for backoff after 403 2019-06-11 14:20:45 -07:00
Bill Williams
647905639c refine connect/auth-token logic 2019-06-05 08:56:28 -07:00
Bill Williams
ceadc4b51f refine fetch auth token 2019-06-03 16:55:29 -07:00
Bill Williams
38dee179e7 request new auth token on every retry, not just after 403 2019-05-30 13:44:49 -07:00
shilpa24balaji
9feafedff8 Merge pull request #302 from bill1600/clrtoken
requestNewAuthToken will clear token if it fails
2019-05-21 17:49:33 -07:00
Bill Williams
2807f8e43a add test_auth_token_more.c 2019-05-16 13:48:02 -07:00
Bill Williams
5132675700 add unit tests for auth_token 2019-05-16 13:41:19 -07:00
Bill Williams
e166b9fdf5 use memset to clear auth token in requestNewAuthToken 2019-05-14 13:34:35 -07:00
Bill Williams
60789f0ec8 requestNewAuthToken will clear token if it fails 2019-05-14 11:51:40 -07:00
Bill Williams
3fb0708b15 add pause/resume heartBeatTimer 2019-05-07 16:19:37 -07:00
shilpa24balaji
65098e36cb Merge pull request #298 from bill1600/nano_115
Update to use nanomsg v 1.1.4
2019-04-24 10:30:41 -07:00
shilpa24balaji
c585300f76 Merge pull request #297 from bill1600/test_upstream
Add unit test for re-registrations
2019-04-24 10:27:48 -07:00
Bill Williams
e4e78118cf Use nanomsg version 1.1.4 2019-04-23 17:12:48 -07:00
Bill Williams
8b4541b570 Update to use nanomsg v 1.1.5 2019-04-23 13:29:35 -07:00
Bill Williams
acc542647b Add unit test for re-registrations 2019-04-12 09:09:23 -07:00
32 changed files with 1163 additions and 192 deletions

View File

@@ -10,6 +10,20 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Fix mutex error in service alive
- Security: Mutual Authentication (mTLS or two way TLS)
- Rename command line options for MTLS cert and Key
- Update to use nanomsg v. 1.1.4
- requestNewAuthToken will clear the token if it fails.
- request auth token on every retry, not just after 403
- update to use nopoll v 1.0.2
- Add pause/resume heartBeatTimer
- parodus event handler to listen to interface_down and interface_up event
- Pause connection retry during interface_down event
- Add callback handler for ping status change event
- Fixed nopoll_conn_unref crash
- Update retry timestamp in connection-health-file
- fix so that parodus can be killed, even if in a connection fail loop
- provide signal handlers so we shut down properly when INCLUDE_BREAKPAD active
- send status code and reason in websocket close message
- dont try to install handler for signal 9
## [1.0.2] - 2019-02-08
- Refactored connection.c and updated corresponding unit tests

View File

@@ -85,7 +85,7 @@ add_dependencies(libtrower-base64 trower-base64)
ExternalProject_Add(nopoll
PREFIX ${PREFIX_DIR}/nopoll
GIT_REPOSITORY https://github.com/Comcast/nopoll.git
GIT_TAG "1.0.1"
GIT_TAG "1.0.2"
CONFIGURE_COMMAND COMMAND <SOURCE_DIR>/autogen.sh --prefix=${PREFIX}
--includedir=${INCLUDE_DIR}
--libdir=${LIBRARY_DIR}
@@ -101,7 +101,7 @@ add_dependencies(libnopoll nopoll)
ExternalProject_Add(nanomsg
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/_prefix/nanomsg
GIT_REPOSITORY https://github.com/nanomsg/nanomsg.git
GIT_TAG "1.1.2"
GIT_TAG "1.1.4"
CMAKE_ARGS += -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR}
)
add_library(libnanomsg STATIC SHARED IMPORTED)
@@ -152,7 +152,7 @@ add_dependencies(libcurl curl)
ExternalProject_Add(cimplog
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/_prefix/cimplog
GIT_REPOSITORY https://github.com/Comcast/cimplog.git
GIT_TAG "1.0.1"
GIT_TAG "1.0.2"
CMAKE_ARGS += -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} -DBUILD_TESTING=OFF
)
add_library(libcimplog STATIC SHARED IMPORTED)

View File

@@ -1,6 +1,6 @@
# parodus
[![Build Status](https://travis-ci.org/Comcast/parodus.svg?branch=master)](https://travis-ci.org/Comcast/parodus)
[![Build Status](https://travis-ci.org/xmidt-org/parodus.svg?branch=master)](https://travis-ci.org/xmidt-org/parodus)
[![codecov.io](http://codecov.io/github/Comcast/parodus/coverage.svg?branch=master)](http://codecov.io/github/Comcast/parodus?branch=master)
[![Coverity](https://img.shields.io/coverity/scan/11192.svg)](https://scan.coverity.com/projects/comcast-parodus)
[![Apache V2 License](http://img.shields.io/badge/license-Apache%20V2-blue.svg)](https://github.com/Comcast/parodus/blob/master/LICENSE)

View File

@@ -25,6 +25,11 @@
#include "config.h"
#include "connection.h"
bool interface_down_event = false;
pthread_mutex_t interface_down_mut=PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t interface_down_con=PTHREAD_COND_INITIALIZER;
/*----------------------------------------------------------------------------*/
/* External Functions */
/*----------------------------------------------------------------------------*/
@@ -139,3 +144,47 @@ void timespec_diff(struct timespec *start, struct timespec *stop,
return;
}
/*------------------------------------------------------------------------------*/
/* For interface_down_event Flag */
/*------------------------------------------------------------------------------*/
// Get value of interface_down_event
bool get_interface_down_event()
{
bool tmp = false;
pthread_mutex_lock (&interface_down_mut);
tmp = interface_down_event;
pthread_mutex_unlock (&interface_down_mut);
return tmp;
}
// Reset value of interface_down_event to false
void reset_interface_down_event()
{
pthread_mutex_lock (&interface_down_mut);
interface_down_event = false;
pthread_cond_signal(&interface_down_con);
pthread_mutex_unlock (&interface_down_mut);
}
// set value of interface_down_event to true
void set_interface_down_event()
{
pthread_mutex_lock (&interface_down_mut);
interface_down_event = true;
pthread_mutex_unlock (&interface_down_mut);
}
pthread_cond_t *get_interface_down_con(void)
{
return &interface_down_con;
}
pthread_mutex_t *get_interface_down_mut(void)
{
return &interface_down_mut;
}

View File

@@ -49,6 +49,7 @@
/*----------------------------------------------------------------------------*/
/* Macros */
/*----------------------------------------------------------------------------*/
#define UNUSED(x) (void )(x)
#define NANO_SOCKET_SEND_TIMEOUT_MS 2000
#define NANO_SOCKET_RCV_TIMEOUT_MS 500
@@ -107,6 +108,7 @@ typedef struct {
//--- Used in connection.c for backoff delay timer
typedef struct {
struct timespec ts;
int count;
int max_count;
int delay;
@@ -157,6 +159,25 @@ void addCRUDmsgToQueue(wrp_msg_t *crudMsg);
void timespec_diff(struct timespec *start, struct timespec *stop,
struct timespec *result);
/*------------------------------------------------------------------------------*/
/* For interface_down_event Flag */
/*------------------------------------------------------------------------------*/
// Get value of interface_down_event
bool get_interface_down_event();
// Reset value of interface_down_event to false
void reset_interface_down_event();
// Set value of interface_down_event to true
void set_interface_down_event();
pthread_cond_t *get_interface_down_con();
pthread_mutex_t *get_interface_down_mut();
#ifdef __cplusplus
}
#endif

View File

@@ -66,17 +66,11 @@ int requestNewAuthToken(char *newToken, size_t len, int r_count)
struct token_data data;
data.size = 0;
data.data = newToken;
curl = curl_easy_init();
if(curl)
{
//this memory will be dynamically grown by write call back fn as required
data.data = (char *) malloc(sizeof(char) * 1);
if(NULL == data.data)
{
ParodusError("Failed to allocate memory.\n");
return -1;
}
data.data[0] = '\0';
createCurlheader(mac_header, serial_header, uuid_header, transaction_uuid, list, &headers_list);
@@ -137,11 +131,8 @@ int requestNewAuthToken(char *newToken, size_t len, int r_count)
{
ParodusError("curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
curl_easy_cleanup(curl);
if(data.data)
{
free(data.data);
data.data = NULL;
}
data.size = 0;
memset (data.data, 0, len);
return -1;
}
else
@@ -149,19 +140,15 @@ int requestNewAuthToken(char *newToken, size_t len, int r_count)
if(response_code == 200)
{
ParodusInfo("cURL success\n");
strncpy(newToken, data.data, len);
}
}
if(data.data)
{
free(data.data);
data.data = NULL;
}
curl_easy_cleanup(curl);
}
else
{
ParodusError("curl init failure\n");
data.size = 0;
memset (data.data, 0, len);
return -1;
}
@@ -179,6 +166,7 @@ void getAuthToken(ParodusCfg *cfg)
int status = -1;
int retry_count = 0;
memset (cfg->webpa_auth_token, 0, sizeof(cfg->webpa_auth_token));
if( cfg->hw_mac != NULL && strlen(cfg->hw_mac) !=0 )
{
if( cfg->client_cert_path !=NULL && strlen(cfg->client_cert_path) !=0 )
@@ -225,28 +213,23 @@ void getAuthToken(ParodusCfg *cfg)
*/
size_t write_callback_fn(void *buffer, size_t size, size_t nmemb, struct token_data *data)
{
ParodusCfg *cfg;
size_t max_data_size = sizeof (cfg->webpa_auth_token);
size_t index = data->size;
size_t n = (size * nmemb);
char* tmp;
data->size += (size * nmemb);
data->size += n;
tmp = realloc(data->data, data->size + 1); /* +1 for '\0' */
if(tmp) {
data->data = tmp;
} else {
if(data->data) {
free(data->data);
}
ParodusError("Failed to allocate memory for data\n");
if (data->size >= max_data_size) {
ParodusError("Auth token data overruns buffer\n");
data->size = 0;
return 0;
}
memcpy((data->data + index), buffer, n);
data->data[data->size] = '\0';
return size * nmemb;
return n;
}
/* @brief function to generate random uuid.

View File

@@ -435,6 +435,7 @@ int parseCommandLine(int argc,char **argv,ParodusCfg * cfg)
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);
OnboardLog("Last reboot reason is %s\n",cfg->hw_last_reboot_reason);
break;
case 'n':

View File

@@ -101,6 +101,7 @@ void createSocketConnection(void (* initKeypress)())
if(!create_conn_rtn)
{
ParodusError("Unrecovered error, terminating the process\n");
OnboardLog("Unrecovered error, terminating the process\n");
abort();
}
packMetaData();
@@ -144,8 +145,14 @@ void createSocketConnection(void (* initKeypress)())
{
ParodusError("ping wait time > %d . Terminating the connection with WebPA server and retrying\n", webpa_ping_timeout_ms / 1000);
ParodusInfo("Reconnect detected, setting Ping_Miss reason for Reconnect\n");
OnboardLog("Reconnect detected, setting Ping_Miss reason for Reconnect\n");
set_global_reconnect_reason("Ping_Miss");
set_global_reconnect_status(true);
// Invoke the ping status change event callback as "missed" ping
if(NULL != on_ping_status_change)
{
on_ping_status_change("missed");
}
set_close_retry();
}
else
@@ -161,6 +168,10 @@ void createSocketConnection(void (* initKeypress)())
if( false == seshat_registered ) {
seshat_registered = __registerWithSeshat();
}
if (get_interface_down_event ())
if (0 != wait_while_interface_down ())
break;
if(get_close_retry())
{
@@ -168,8 +179,6 @@ void createSocketConnection(void (* initKeypress)())
close_and_unref_connection(get_global_conn());
set_global_conn(NULL);
get_parodus_cfg()->cloud_status = CLOUD_STATUS_OFFLINE;
ParodusInfo("cloud_status set as %s after connection close\n", get_parodus_cfg()->cloud_status);
if(get_parodus_cfg()->cloud_disconnect !=NULL)
{
ParodusPrint("get_parodus_cfg()->cloud_disconnect is %s\n", get_parodus_cfg()->cloud_disconnect);
@@ -209,13 +218,18 @@ void createSocketConnection(void (* initKeypress)())
deleteAllClients ();
ParodusInfo ("reconnect reason at close %s\n", get_global_reconnect_reason());
ParodusInfo ("shutdown reason at close %s\n", get_global_shutdown_reason());
close_and_unref_connection(get_global_conn());
nopoll_ctx_unref(ctx);
nopoll_cleanup_library();
curl_global_cleanup();
}
void shutdownSocketConnection(void) {
void shutdownSocketConnection(char *reason) {
set_global_shutdown_reason (reason);
g_shutdown = true;
reset_interface_down_event ();
terminate_backoff_delay ();
}

View File

@@ -45,7 +45,7 @@ extern UpStreamMsg *UpStreamMsgQ;
* and creates the intial connection and manages the connection wait, close mechanisms.
*/
void createSocketConnection(void (* initKeypress)());
void shutdownSocketConnection(void);
void shutdownSocketConnection(char *reason);
#ifdef __cplusplus
}

View File

@@ -38,11 +38,34 @@
#define HTTP_CUSTOM_HEADER_COUNT 5
#define INITIAL_CJWT_RETRY -2
#define UPDATE_HEALTH_FILE_INTERVAL_SECS 450
/* Close codes defined in RFC 6455, section 11.7. */
enum {
CloseNormalClosure = 1000,
CloseGoingAway = 1001,
CloseProtocolError = 1002,
CloseUnsupportedData = 1003,
CloseNoStatus = 1005,
CloseAbnormalClosure = 1006,
CloseInvalidFramePayloadData = 1007,
ClosePolicyViolation = 1008,
CloseMessageTooBig = 1009,
CloseMandatoryExtension = 1010,
CloseInternalServerErr = 1011,
CloseServiceRestart = 1012,
CloseTryAgainLater = 1013,
CloseTLSHandshake = 1015
};
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
pthread_mutex_t backoff_delay_mut=PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t backoff_delay_con=PTHREAD_COND_INITIALIZER;
static char *shutdown_reason = SHUTDOWN_REASON_PARODUS_STOP; /* goes in the close message */
static char *reconnect_reason = "webpa_process_starts";
static int cloud_disconnect_max_time = 5;
static noPollConn *g_conn = NULL;
@@ -65,6 +88,16 @@ void set_global_conn(noPollConn *conn)
g_conn = conn;
}
char *get_global_shutdown_reason()
{
return shutdown_reason;
}
void set_global_shutdown_reason(char *reason)
{
shutdown_reason = reason;
}
char *get_global_reconnect_reason()
{
return reconnect_reason;
@@ -199,6 +232,14 @@ void init_backoff_timer (backoff_timer_t *timer, int max_count)
timer->count = 1;
timer->max_count = max_count;
timer->delay = 1;
clock_gettime (CLOCK_REALTIME, &timer->ts);
}
void terminate_backoff_delay (void)
{
pthread_mutex_lock (&backoff_delay_mut);
pthread_cond_signal(&backoff_delay_con);
pthread_mutex_unlock (&backoff_delay_mut);
}
int update_backoff_delay (backoff_timer_t *timer)
@@ -211,11 +252,50 @@ int update_backoff_delay (backoff_timer_t *timer)
return timer->delay;
}
static void backoff_delay (backoff_timer_t *timer)
#define BACKOFF_ERR -1
#define BACKOFF_SHUTDOWN 1
#define BACKOFF_DELAY_TAKEN 0
void start_conn_in_progress (void);
/* backoff_delay
*
* delays for the number of seconds specified in parameter timer
* g_shutdown can break out of the delay.
*
* returns -1 pthread_cond_timedwait error
* 1 shutdown
* 0 delay taken
*/
static int backoff_delay (backoff_timer_t *timer)
{
struct timespec ts;
int rtn;
// periodically update the health file.
clock_gettime (CLOCK_REALTIME, &ts);
if ((ts.tv_sec - timer->ts.tv_sec) >= UPDATE_HEALTH_FILE_INTERVAL_SECS) {
start_conn_in_progress ();
timer->ts.tv_sec += UPDATE_HEALTH_FILE_INTERVAL_SECS;
}
update_backoff_delay (timer);
ParodusInfo("Waiting with backoffRetryTime %d seconds\n", timer->delay);
sleep (timer->delay);
ts.tv_sec += timer->delay;
pthread_mutex_lock (&backoff_delay_mut);
// The condition variable will only be set if we shut down.
rtn = pthread_cond_timedwait (&backoff_delay_con, &backoff_delay_mut, &ts);
pthread_mutex_unlock (&backoff_delay_mut);
if (g_shutdown)
return BACKOFF_SHUTDOWN;
if ((rtn != 0) && (rtn != ETIMEDOUT)) {
ParodusError ("pthread_cond_timedwait error (%d) in backoff_delay.\n", rtn);
return BACKOFF_ERR;
}
return BACKOFF_DELAY_TAKEN;
}
//--------------------------------------------------------------------
@@ -296,21 +376,25 @@ void set_current_server (create_connection_ctx_t *ctx)
ctx->current_server = get_current_server (&ctx->server_list);
}
void set_extra_headers (create_connection_ctx_t *ctx, int reauthorize)
{
if (reauthorize && (get_parodus_cfg()->client_cert_path !=NULL && strlen(get_parodus_cfg()->client_cert_path) >0))
{
getAuthToken(get_parodus_cfg());
}
ctx->extra_headers = build_extra_hdrs (&ctx->header_info);
}
void free_extra_headers (create_connection_ctx_t *ctx)
{
FREE_PTR_VAR (ctx->extra_headers)
}
void set_extra_headers (create_connection_ctx_t *ctx)
{
ParodusCfg * cfg = get_parodus_cfg();
free_extra_headers (ctx);
if ((strlen(cfg->webpa_auth_token) == 0) &&
(cfg->client_cert_path != NULL) && (strlen(cfg->client_cert_path) > 0))
{
getAuthToken(cfg);
}
ctx->extra_headers = build_extra_hdrs (&ctx->header_info);
}
void free_connection_ctx (create_connection_ctx_t *ctx)
{
free_extra_headers (ctx);
@@ -387,8 +471,10 @@ int nopoll_connect (create_connection_ctx_t *ctx, int is_ipv6)
}
if ((NULL == connection) && (!is_ipv6)) {
if((checkHostIp(server->server_addr) == -2)) {
if (check_timer_expired (&ctx->connect_timer, 15*60*1000)) {
if (check_timer_expired (&ctx->connect_timer, 15*60*1000) && !get_interface_down_event()) {
ParodusError("WebPA unable to connect due to DNS resolving to 10.0.0.1 for over 15 minutes; crashing service.\n");
OnboardLog("WebPA unable to connect due to DNS resolving to 10.0.0.1 for over 15 minutes; crashing service.\n");
OnboardLog("Reconnect detected, setting Dns_Res_webpa_reconnect reason for Reconnect\n");
set_global_reconnect_reason("Dns_Res_webpa_reconnect");
set_global_reconnect_status(true);
@@ -404,14 +490,14 @@ int nopoll_connect (create_connection_ctx_t *ctx, int is_ipv6)
//--------------------------------------------------------------------
// Return codes for wait_connection_ready
#define WAIT_SUCCESS 0
#define WAIT_ACTION_RETRY 1 // if wait_status is 307, 302, 303 or 403
#define WAIT_ACTION_RETRY 1 // if wait_status is 307, 302, 303, or 403
#define WAIT_FAIL 2
#define FREE_NON_NULL_PTR(ptr) if (NULL != ptr) free(ptr)
int wait_connection_ready (create_connection_ctx_t *ctx)
{
int wait_status;
int wait_status = 0;
char *redirectURL = NULL;
if(nopoll_conn_wait_for_status_until_connection_ready(get_global_conn(), 10,
@@ -423,7 +509,7 @@ int wait_connection_ready (create_connection_ctx_t *ctx)
if(wait_status == 307 || wait_status == 302 || wait_status == 303) // only when there is a http redirect
{
char *redirect_ptr = redirectURL;
ParodusError("Received temporary redirection response message %s\n", redirectURL);
ParodusInfo("Received temporary redirection response message %s\n", redirectURL);
// Extract server Address and port from the redirectURL
if (strncmp (redirect_ptr, "Redirect:", 9) == 0)
redirect_ptr += 9;
@@ -440,10 +526,12 @@ int wait_connection_ready (create_connection_ctx_t *ctx)
FREE_NON_NULL_PTR (redirectURL);
if(wait_status == 403)
{
ParodusError("Received Unauthorized response with status: %d\n", wait_status);
free_extra_headers (ctx);
set_extra_headers (ctx, true);
return WAIT_ACTION_RETRY;
ParodusCfg *cfg = get_parodus_cfg();
/* clear auth token in cfg so that we will refetch auth token */
memset (cfg->webpa_auth_token, 0, sizeof(cfg->webpa_auth_token));
ParodusError("Received Unauthorized response with status: %d\n", wait_status);
OnboardLog("Received Unauthorized response with status: %d\n", wait_status);
return WAIT_ACTION_RETRY;
}
ParodusError("Client connection timeout\n");
ParodusError("RDK-10037 - WebPA Connection Lost\n");
@@ -453,9 +541,9 @@ int wait_connection_ready (create_connection_ctx_t *ctx)
//--------------------------------------------------------------------
// Return codes for connect_and_wait
#define CONN_WAIT_SUCCESS 0
#define CONN_WAIT_ACTION_RETRY 1 // if wait_status is 307, 302, 303 or 403
#define CONN_WAIT_RETRY_DNS 2
#define CONN_WAIT_SUCCESS 0
#define CONN_WAIT_ACTION_RETRY 1 // if wait_status is 307, 302, 303, or 403
#define CONN_WAIT_RETRY_DNS 2
int connect_and_wait (create_connection_ctx_t *ctx)
{
@@ -512,20 +600,60 @@ int keep_trying_to_connect (create_connection_ctx_t *ctx,
{
int rtn;
while (true)
while (!g_shutdown)
{
set_extra_headers (ctx);
rtn = connect_and_wait (ctx);
if (rtn == CONN_WAIT_SUCCESS)
return true;
if (rtn == CONN_WAIT_ACTION_RETRY) // if redirected or build_headers
continue;
backoff_delay (backoff_timer); // 3,7,15,31 ..
// If interface down event is set, stop retry
// and wait till interface is up again.
if(get_interface_down_event()) {
if (0 != wait_while_interface_down())
return false;
start_conn_in_progress();
ParodusInfo("Interface is back up, re-initializing the convey header\n");
// Reset the reconnect reason by initializing the convey header again
((header_info_t *)(&ctx->header_info))->conveyHeader = getWebpaConveyHeader();
ParodusInfo("Received reconnect_reason as:%s\n", reconnect_reason);
} else {
if (backoff_delay (backoff_timer) // 3,7,15,31 ..
!= BACKOFF_DELAY_TAKEN) // shutdown or cond wait error
return false;
}
if (rtn == CONN_WAIT_RETRY_DNS)
return false; //find_server again
// else retry
}
return false;
}
int wait_while_interface_down()
{
int rtn;
ParodusError("Interface is down, hence waiting until its up\n");
close_and_unref_connection (get_global_conn());
set_global_conn(NULL);
while (get_interface_down_event ()) {
pthread_mutex_lock(get_interface_down_mut());
rtn = pthread_cond_wait(get_interface_down_con(), get_interface_down_mut());
pthread_mutex_unlock (get_interface_down_mut());
if (rtn != 0)
ParodusError
("Error on pthread_cond_wait (%d) in wait_while_interface_down\n", rtn);
if ((rtn != 0) || g_shutdown) {
return -1;
}
}
return 0;
}
//--------------------------------------------------------------------
@@ -552,11 +680,11 @@ int createNopollConnection(noPollCtx *ctx)
max_retry_count = (int) get_parodus_cfg()->webpa_backoff_max;
ParodusPrint("max_retry_count is %d\n", max_retry_count );
memset (&conn_ctx, 0, sizeof(create_connection_ctx_t));
conn_ctx.nopoll_ctx = ctx;
init_expire_timer (&conn_ctx.connect_timer);
init_header_info (&conn_ctx.header_info);
set_extra_headers (&conn_ctx, false);
set_server_list_null (&conn_ctx.server_list);
init_backoff_timer (&backoff_timer, max_retry_count);
@@ -574,15 +702,23 @@ int createNopollConnection(noPollCtx *ctx)
if(conn_ctx.current_server->allow_insecure <= 0)
{
ParodusInfo("Connected to server over SSL\n");
OnboardLog("Connected to server over SSL\n");
}
else
{
ParodusInfo("Connected to server\n");
OnboardLog("Connected to server\n");
}
get_parodus_cfg()->cloud_status = CLOUD_STATUS_ONLINE;
ParodusInfo("cloud_status set as %s after successful connection\n", get_parodus_cfg()->cloud_status);
// Invoke the ping status change event callback as "received" ping
if(NULL != on_ping_status_change)
{
on_ping_status_change("received");
}
if((get_parodus_cfg()->boot_time != 0) && init) {
getCurrentTime(connectTimePtr);
ParodusInfo("connect_time-diff-boot_time=%d\n", connectTimePtr->tv_sec - get_parodus_cfg()->boot_time);
@@ -655,10 +791,16 @@ static noPollConnOpts * createConnOpts (char * extra_headers, bool secure)
void close_and_unref_connection(noPollConn *conn)
{
if (conn) {
nopoll_conn_close(conn);
if (0 < nopoll_conn_ref_count (conn)) {
nopoll_conn_unref(conn);
}
const char *reason = get_global_shutdown_reason();
int reason_len = 0;
int status = CloseNoStatus;
if (NULL != reason) {
reason_len = (int) strlen (reason);
status = CloseNormalClosure;
}
nopoll_conn_close_ext(conn, status, reason, reason_len);
get_parodus_cfg()->cloud_status = CLOUD_STATUS_OFFLINE;
ParodusInfo("cloud_status set as %s after connection close\n", get_parodus_cfg()->cloud_status);
}
}
@@ -697,3 +839,9 @@ void stop_conn_in_progress (void)
write_conn_in_prog_file ("STOP");
}
void registerParodusOnPingStatusChangeHandler(parodusOnPingStatusChangeHandler callback_func)
{
on_ping_status_change = callback_func;
}

View File

@@ -33,7 +33,17 @@ extern "C" {
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
#define SHUTDOWN_REASON_PARODUS_STOP "parodus_stopping"
#define SHUTDOWN_REASON_SYSTEM_RESTART "system_restarting"
/**
* parodusOnPingStatusChangeHandler - Function pointer
* Used to define callback function to do additional processing
* when websocket Ping status change event
* i.e. ping_miss or ping receive after miss
*/
typedef void (*parodusOnPingStatusChangeHandler) (char * status);
parodusOnPingStatusChangeHandler on_ping_status_change;
/*----------------------------------------------------------------------------*/
/* Function Prototypes */
@@ -49,6 +59,9 @@ void close_and_unref_connection(noPollConn *);
noPollConn *get_global_conn(void);
void set_global_conn(noPollConn *);
char *get_global_shutdown_reason();
void set_global_shutdown_reason(char *reason);
char *get_global_reconnect_reason();
void set_global_reconnect_reason(char *reason);
@@ -64,6 +77,14 @@ void set_cloud_disconnect_time(int disconnTime);
void start_conn_in_progress (void);
void stop_conn_in_progress (void);
// To Register parodusOnPingStatusChangeHandler Callback function
void registerParodusOnPingStatusChangeHandler(parodusOnPingStatusChangeHandler on_ping_status_change);
// To stop connection and wait duing interface down state
int wait_while_interface_down (void);
void terminate_backoff_delay (void);
#ifdef __cplusplus
}
#endif

View File

@@ -1346,6 +1346,7 @@ static int ConnDisconnectFromCloud(char *disconn_reason)
if(!close_retry)
{
ParodusInfo("Reconnect detected, setting reason %s for Reconnect\n", disconn_reason);
OnboardLog("Reconnect detected, setting reason %s for Reconnect\n", disconn_reason);
set_global_reconnect_reason(disconn_reason);
set_global_reconnect_status(true);
set_close_retry();

View File

@@ -121,6 +121,9 @@ void listenerOnMessage(void * msg, size_t msgSize)
ParodusInfo("Received downstream dest as :%s and transaction_uuid :%s\n", dest,
((WRP_MSG_TYPE__REQ == msgType) ? message->u.req.transaction_uuid :
((WRP_MSG_TYPE__EVENT == msgType) ? "NA" : message->u.crud.transaction_uuid)));
OnboardLog("%s\n",
((WRP_MSG_TYPE__REQ == msgType) ? message->u.req.transaction_uuid :
((WRP_MSG_TYPE__EVENT == msgType) ? "NA" : message->u.crud.transaction_uuid)));
free(destVal);

View File

@@ -22,8 +22,10 @@
*/
#include "heartBeat.h"
#include <stdbool.h>
volatile unsigned int heartBeatTimer = 0;
volatile bool paused = false;
pthread_mutex_t heartBeat_mut=PTHREAD_MUTEX_INITIALIZER;
@@ -49,8 +51,27 @@ void reset_heartBeatTimer()
void increment_heartBeatTimer(unsigned int inc_time_ms)
{
pthread_mutex_lock (&heartBeat_mut);
heartBeatTimer += inc_time_ms;
if (!paused)
heartBeatTimer += inc_time_ms;
pthread_mutex_unlock (&heartBeat_mut);
}
// Pause heartBeatTimer, i.e. stop incrementing
void pause_heartBeatTimer()
{
pthread_mutex_lock (&heartBeat_mut);
heartBeatTimer = 0;
paused = true;
pthread_mutex_unlock (&heartBeat_mut);
}
// Resume heartBeatTimer, i.e. resume incrementing
void resume_heartBeatTimer()
{
pthread_mutex_lock (&heartBeat_mut);
paused = false;
pthread_mutex_unlock (&heartBeat_mut);
}

View File

@@ -39,6 +39,12 @@ void reset_heartBeatTimer();
// Increment value of heartBeatTimer to desired value
void increment_heartBeatTimer(unsigned int inc_time_ms);
// Pause heartBeatTimer, i.e. stop incrementing
void pause_heartBeatTimer();
// Resume heartBeatTimer, i.e. resume incrementing
void resume_heartBeatTimer();
#ifdef __cplusplus
}
#endif

View File

@@ -19,14 +19,14 @@
#include "stdlib.h"
#include "config.h"
#include "auth_token.h"
#include "connection.h"
#include "conn_interface.h"
#include "parodus_log.h"
#include <curl/curl.h>
#ifdef INCLUDE_BREAKPAD
#include "breakpad_wrapper.h"
#else
#include "signal.h"
#endif
#include "signal.h"
/*----------------------------------------------------------------------------*/
/* Macros */
@@ -36,7 +36,7 @@
/*----------------------------------------------------------------------------*/
/* Data Structures */
/*----------------------------------------------------------------------------*/
/* none */
typedef void Sigfunc(int);
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
@@ -46,30 +46,53 @@
/*----------------------------------------------------------------------------*/
/* Function Prototypes */
/*----------------------------------------------------------------------------*/
#ifndef INCLUDE_BREAKPAD
static void sig_handler(int sig);
Sigfunc *
signal (int signo, Sigfunc *func)
{
struct sigaction act, oact;
act.sa_handler = func;
sigemptyset (&act.sa_mask);
act.sa_flags = 0;
if (signo == SIGALRM) {
#ifdef SA_INTERRUPT
act.sa_flags |= SA_INTERRUPT; /* SunOS 4.x */
#endif
} else {
#ifdef SA_RESTART
act.sa_flags |= SA_RESTART; /* SVR4, 4.4BSD */
#endif
}
if (sigaction (signo, &act, &oact) < 0) {
ParodusError ("Signal Handler for signal %d not installed!\n", signo);
return (SIG_ERR);
}
return (oact.sa_handler);
}
/*----------------------------------------------------------------------------*/
/* External Functions */
/*----------------------------------------------------------------------------*/
int main( int argc, char **argv)
{
#ifdef INCLUDE_BREAKPAD
breakpad_ExceptionHandler();
#else
set_global_shutdown_reason (SHUTDOWN_REASON_PARODUS_STOP);
signal(SIGTERM, sig_handler);
signal(SIGINT, sig_handler);
signal(SIGINT, sig_handler);
signal(SIGUSR1, sig_handler);
signal(SIGUSR2, sig_handler);
signal(SIGQUIT, sig_handler);
signal(SIGHUP, sig_handler);
signal(SIGALRM, sig_handler);
#ifdef INCLUDE_BREAKPAD
/* breakpad handles the signals SIGSEGV, SIGBUS, SIGFPE, and SIGILL */
breakpad_ExceptionHandler();
#else
signal(SIGSEGV, sig_handler);
signal(SIGBUS, sig_handler);
signal(SIGKILL, sig_handler);
signal(SIGFPE, sig_handler);
signal(SIGILL, sig_handler);
signal(SIGQUIT, sig_handler);
signal(SIGHUP, sig_handler);
signal(SIGALRM, sig_handler);
#endif
ParodusCfg *cfg;
@@ -83,7 +106,6 @@ int main( int argc, char **argv)
abort();
}
curl_global_init(CURL_GLOBAL_DEFAULT);
getAuthToken(cfg);
createSocketConnection( NULL);
@@ -98,7 +120,6 @@ const char *rdk_logger_module_fetch(void)
/*----------------------------------------------------------------------------*/
/* Internal functions */
/*----------------------------------------------------------------------------*/
#ifndef INCLUDE_BREAKPAD
static void sig_handler(int sig)
{
@@ -106,12 +127,13 @@ static void sig_handler(int sig)
{
signal(SIGINT, sig_handler); /* reset it to this function */
ParodusInfo("SIGINT received!\n");
shutdownSocketConnection();
shutdownSocketConnection(SHUTDOWN_REASON_PARODUS_STOP);
}
else if ( sig == SIGUSR1 )
{
signal(SIGUSR1, sig_handler); /* reset it to this function */
ParodusInfo("SIGUSR1 received!\n");
shutdownSocketConnection(SHUTDOWN_REASON_SYSTEM_RESTART);
}
else if ( sig == SIGUSR2 )
{
@@ -135,8 +157,7 @@ static void sig_handler(int sig)
else
{
ParodusInfo("Signal %d received!\n", sig);
shutdownSocketConnection();
shutdownSocketConnection(SHUTDOWN_REASON_PARODUS_STOP);
}
}
#endif

View File

@@ -70,6 +70,7 @@ int checkHostIp(char * serverIP)
if (retVal != 0)
{
ParodusError("getaddrinfo: %s\n", gai_strerror(retVal));
OnboardLog("getaddrinfo: %s\n", gai_strerror(retVal));
}
else
{

View File

@@ -167,16 +167,25 @@ void listenerOnCloseMessage (noPollCtx * ctx, noPollConn * conn, noPollPtr user_
if( closeStatus == 1006 && !get_global_reconnect_status())
{
ParodusInfo("Reconnect detected, setting default Reconnect reason %s\n",defaultReason);
OnboardLog("Reconnect detected, setting default Reconnect reason %s\n",defaultReason);
set_global_reconnect_reason(defaultReason);
set_global_reconnect_status(true);
}
else if(!get_global_reconnect_status())
{
ParodusInfo("Reconnect detected, setting Reconnect reason as Unknown\n");
OnboardLog("Reconnect detected, setting Reconnect reason as Unknown\n");
set_global_reconnect_reason("Unknown");
}
if(!get_interface_down_event())
{
ParodusInfo("Setting the close and retry connection\n");
set_close_retry();
}
else
ParodusInfo("Not Setting the close and retry connection as interface is down\n");
set_close_retry();
ParodusPrint("listenerOnCloseMessage(): mutex unlock in producer thread\n");
}

View File

@@ -73,25 +73,35 @@ void sendMessage(noPollConn *conn, void *msg, size_t len)
else
{
ParodusError("Failed to send msg upstream as connection is not OK\n");
if (connErr == 0)
{
getCurrentTime(connStuck_startPtr);
ParodusInfo("Conn got stuck, initialized the first timer\n");
connErr = 1;
}
else
{
getCurrentTime(connStuck_endPtr);
timeDiff = timeValDiff(connStuck_startPtr, connStuck_endPtr);
ParodusPrint("checking timeout difference:%ld\n", timeDiff);
OnboardLog("Failed to send msg upstream as connection is not OK\n");
if( timeDiff >= (10*60*1000))
if(get_interface_down_event())
{
ParodusError("Unable to connect to server since interface is down\n");
}
else
{
if (connErr == 0)
{
ParodusError("conn got stuck for over 10 minutes; crashing service.\n");
kill(getpid(),SIGTERM);
getCurrentTime(connStuck_startPtr);
ParodusInfo("Conn got stuck, initialized the first timer\n");
connErr = 1;
}
else
{
getCurrentTime(connStuck_endPtr);
timeDiff = timeValDiff(connStuck_startPtr, connStuck_endPtr);
ParodusPrint("checking timeout difference:%ld\n", timeDiff);
}
if( timeDiff >= (10*60*1000))
{
ParodusError("conn got stuck for over 10 minutes; crashing service.\n");
OnboardLog("conn got stuck for over 10 minutes; crashing service.\n");
kill(getpid(),SIGTERM);
}
}
}
}
}
@@ -136,7 +146,7 @@ void __report_log (noPollCtx * ctx, noPollDebugLevel level, const char * log_msg
if (level == NOPOLL_LEVEL_DEBUG)
{
//ParodusPrint("%s\n", log_msg);
ParodusInfo("%s\n", log_msg);
}
if (level == NOPOLL_LEVEL_INFO)
{
@@ -144,11 +154,12 @@ void __report_log (noPollCtx * ctx, noPollDebugLevel level, const char * log_msg
}
if (level == NOPOLL_LEVEL_WARNING)
{
ParodusPrint("%s\n", log_msg);
ParodusInfo("%s\n", log_msg);
}
if (level == NOPOLL_LEVEL_CRITICAL)
{
ParodusError("%s\n", log_msg );
OnboardLog("%s\n", log_msg );
}
return;
}

View File

@@ -33,3 +33,9 @@
#define ParodusError(...) cimplog_error(LOGGING_MODULE, __VA_ARGS__)
#define ParodusInfo(...) cimplog_info(LOGGING_MODULE, __VA_ARGS__)
#define ParodusPrint(...) cimplog_debug(LOGGING_MODULE, __VA_ARGS__)
#ifdef FEATURE_SUPPORT_ONBOARD_LOGGING
#define OnboardLog(...) onboarding_log(LOGGING_MODULE, __VA_ARGS__)
#else
#define OnboardLog(...)
#endif

View File

@@ -178,6 +178,7 @@ int validate_partner_id(wrp_msg_t *msg, partners_t **partnerIds)
if(matchFlag != 1)
{
ParodusError("Invalid partner_id %s\n",temp);
OnboardLog("Invalid partner_id %s\n",temp);
if(partnersList != NULL)
{
for(j=0; j<partnersList->count; j++)

View File

@@ -139,6 +139,7 @@ int analyze_jwt (const cjwt_t *jwt, char **url_buf, unsigned int *port)
show_times (exp_time, cur_time);
if (exp_time < cur_time) {
ParodusError ("JWT has expired\n");
OnboardLog ("JWT has expired\n");
return TOKEN_ERR_JWT_EXPIRED;
}
}
@@ -146,6 +147,7 @@ int analyze_jwt (const cjwt_t *jwt, char **url_buf, unsigned int *port)
url_buf, port);
if (http_match < 0) {
ParodusError ("Invalid endpoint claim in JWT\n");
OnboardLog("Invalid endpoint claim in JWT\n");
return TOKEN_ERR_BAD_ENDPOINT;
}
ParodusInfo ("JWT is_http strncmp: %d\n", http_match);

View File

@@ -589,6 +589,7 @@ void sendUpstreamMsgToServer(void **resp_bytes, size_t resp_size)
else
{
ParodusInfo("close_retry is %d, unable to send response as connection retry is in progress\n", close_retry);
OnboardLog("close_retry is %d, unable to send response as connection retry is in progress\n", close_retry);
}
free(appendData);
appendData =NULL;

View File

@@ -193,6 +193,17 @@ target_link_libraries (test_auth_token -lcmocka
-Wl,--no-as-needed -lcimplog
-lcjson -lcjwt -ltrower-base64 -lssl -lcrypto -lrt -lm -lcurl -luuid
)
#-------------------------------------------------------------------------------
# test_auth_token_more
#-------------------------------------------------------------------------------
add_test(NAME test_auth_token_more COMMAND ${MEMORY_CHECK} ./test_auth_token_more)
add_executable(test_auth_token_more test_auth_token_more.c ../src/config.c ../src/auth_token.c ../src/string_helpers.c)
target_link_libraries (test_auth_token_more -lcmocka
-Wl,--no-as-needed -lcimplog
-lcjson -lcjwt -ltrower-base64 -lssl -lcrypto -lrt -lm -lcurl -luuid
)
#-------------------------------------------------------------------------------
# test_crud_interface
#-------------------------------------------------------------------------------
@@ -224,6 +235,17 @@ target_link_libraries (test_upstream -lcmocka gcov -lcunit -lcimplog
-Wl,--no-as-needed -lcjson -lcjwt -ltrower-base64
-lssl -lcrypto -lrt -lm)
#-------------------------------------------------------------------------------
# test_upstream_sock
#-------------------------------------------------------------------------------
add_test(NAME test_upstream_sock COMMAND ${MEMORY_CHECK} ./test_upstream_sock)
add_executable(test_upstream_sock test_upstream_sock.c ../src/upstream.c
../src/client_list.c ../src/close_retry.c ../src/string_helpers.c)
target_link_libraries (test_upstream_sock -lcmocka gcov -lcunit -lcimplog
-lwrp-c -luuid -lpthread -lmsgpackc -lnopoll -lnanomsg
-Wl,--no-as-needed -lcjson -lcjwt -ltrower-base64
-lssl -lcrypto -lrt -lm)
#-------------------------------------------------------------------------------
# test_downstream
#-------------------------------------------------------------------------------

View File

@@ -40,11 +40,19 @@ typedef enum {
CURLINFO_TOTAL_TIME
} CURLINFO;
struct token_data test_data;
int curl_easy_perform(CURL *curl)
{
UNUSED(curl);
char *msg = "response";
int rtn;
function_called();
return (int) mock();
rtn = (int) mock();
if (0 == rtn)
write_callback_fn (msg, 1, strlen(msg), &test_data);
return rtn;
}
int curl_easy_getinfo(CURL *curl, CURLINFO CURLINFO_RESPONSE_CODE, long response_code)
@@ -67,6 +75,7 @@ void getAuthToken_Null()
getAuthToken(&cfg);
set_parodus_cfg(&cfg);
assert( cfg.client_cert_path == NULL);
assert_int_equal (0, (int) cfg.webpa_auth_token[0]);
}
void getAuthToken_MacNull()
@@ -77,8 +86,10 @@ void getAuthToken_MacNull()
getAuthToken(&cfg);
set_parodus_cfg(&cfg);
assert( cfg.client_cert_path == NULL);
assert_int_equal (0, (int) cfg.webpa_auth_token[0]);
}
#if 0
void test_requestNewAuthToken_init_fail ()
{
char token[32];
@@ -106,7 +117,7 @@ void test_requestNewAuthToken_init_fail ()
assert_int_equal (output, -1);
free(cfg.token_server_url);
}
#endif
void test_requestNewAuthToken_failure ()
{
@@ -121,6 +132,8 @@ void test_requestNewAuthToken_failure ()
parStrncpy(cfg.hw_mac , "123567892366", sizeof(cfg.hw_mac));
set_parodus_cfg(&cfg);
test_data.size = 0;
test_data.data = token;
will_return (curl_easy_perform, -1);
expect_function_calls (curl_easy_perform, 1);
@@ -132,6 +145,7 @@ void test_requestNewAuthToken_failure ()
requestNewAuthToken (token, sizeof(token), 2);
assert_int_equal (output, -1);
assert_int_equal (0, (int) token[0]);
free(cfg.token_server_url);
}
@@ -150,6 +164,8 @@ void test_requestNewAuthToken ()
parStrncpy(cfg.hw_mac , "123567892366", sizeof(cfg.hw_mac));
set_parodus_cfg(&cfg);
test_data.size = 0;
test_data.data = token;
will_return (curl_easy_perform, 0);
expect_function_calls (curl_easy_perform, 1);
will_return (curl_easy_getinfo, 0);
@@ -160,6 +176,7 @@ void test_requestNewAuthToken ()
output = requestNewAuthToken (token, sizeof(token), 1);
assert_int_equal (output, 0);
assert_string_equal (token, "response");
free(cfg.token_server_url);
}
@@ -197,6 +214,8 @@ void test_getAuthToken ()
expect_function_calls (curl_easy_getinfo, 1);
/* To test curl success case */
test_data.size = 0;
test_data.data = cfg.webpa_auth_token;
will_return (curl_easy_perform, 0);
expect_function_calls (curl_easy_perform, 1);
@@ -207,7 +226,7 @@ void test_getAuthToken ()
expect_function_calls (curl_easy_getinfo, 1);
getAuthToken(&cfg);
assert_string_equal (cfg.webpa_auth_token, "response");
free(cfg.client_cert_path);
free(cfg.token_server_url);
}
@@ -224,6 +243,7 @@ void test_getAuthTokenFailure ()
parStrncpy(cfg.hw_serial_number, "Fer23u948590", sizeof(cfg.hw_serial_number));
parStrncpy(cfg.hw_mac , "123567892366", sizeof(cfg.hw_mac));
set_parodus_cfg(&cfg);
will_return (curl_easy_perform, -1);
expect_function_calls (curl_easy_perform, 1);
@@ -261,20 +281,35 @@ void test_getAuthTokenFailure ()
void test_write_callback_fn ()
{
void *buffer;
size_t size = 1;
size_t nmemb =8;
ParodusCfg *cfg;
size_t max_data_size = sizeof (cfg->webpa_auth_token);
char *buffer1 = "response1";
size_t buf1len = strlen(buffer1);
char *buffer2 = "R2";
size_t buf2len = strlen(buffer2);
char buffer3[max_data_size];
int out_len=0;
struct token_data data;
data.size = 0;
buffer = strdup("response");
data.data = (char *) malloc(sizeof(char) * 5);
data.data = (char *) malloc(max_data_size);
data.data[0] = '\0';
out_len = write_callback_fn(buffer, size, nmemb, &data);
assert_string_equal(data.data, buffer);
assert_int_equal( out_len, strlen(buffer));
out_len = write_callback_fn(buffer1, 1, buf1len, &data);
assert_string_equal(data.data, buffer1);
assert_int_equal (out_len, buf1len);
assert_int_equal (data.size, buf1len);
out_len = write_callback_fn(buffer2, 1, buf2len, &data);
assert_string_equal(data.data, "response1R2");
assert_int_equal (out_len, buf2len);
assert_int_equal (data.size, buf1len+buf2len);
memset (buffer3, 'x', max_data_size);
out_len = write_callback_fn(buffer3, 1, max_data_size, &data);
assert_int_equal (out_len, 0);
assert_int_equal (data.size, 0);
free(data.data);
}
@@ -285,14 +320,14 @@ void test_write_callback_fn ()
int main(void)
{
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_write_callback_fn),
cmocka_unit_test(test_requestNewAuthToken),
cmocka_unit_test(test_requestNewAuthToken_init_fail),
// cmocka_unit_test(test_requestNewAuthToken_init_fail),
cmocka_unit_test(test_requestNewAuthToken_failure),
cmocka_unit_test(getAuthToken_Null),
cmocka_unit_test(getAuthToken_MacNull),
cmocka_unit_test(test_getAuthToken),
cmocka_unit_test(test_getAuthTokenFailure),
cmocka_unit_test(test_write_callback_fn),
};
return cmocka_run_group_tests(tests, NULL, NULL);

View File

@@ -0,0 +1,109 @@
/**
* 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 <malloc.h>
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <CUnit/Basic.h>
#include "../src/config.h"
#include "../src/auth_token.h"
#include "../src/ParodusInternal.h"
extern int requestNewAuthToken(char *newToken, size_t len, int r_count);
/*----------------------------------------------------------------------------*/
/* Mocks */
/*----------------------------------------------------------------------------*/
typedef void CURL;
typedef enum {
CURLINFO_RESPONSE_CODE = 2,
CURLINFO_TOTAL_TIME
} CURLINFO;
struct token_data test_data;
CURL *curl_easy_init ()
{
function_called();
return (CURL *) mock();
}
int curl_easy_perform(CURL *curl)
{
UNUSED(curl);
char *msg = "response";
int rtn;
function_called();
rtn = (int) mock();
if (0 == rtn)
write_callback_fn (msg, 1, strlen(msg), &test_data);
return rtn;
}
int curl_easy_getinfo(CURL *curl, CURLINFO CURLINFO_RESPONSE_CODE, long response_code)
{
UNUSED(curl);
UNUSED(CURLINFO_RESPONSE_CODE);
UNUSED(response_code);
function_called();
return (int) mock();
}
/*----------------------------------------------------------------------------*/
/* Tests */
/*----------------------------------------------------------------------------*/
void test_requestNewAuthToken_init_fail ()
{
char token[32];
ParodusCfg cfg;
int output = -1;
memset(&cfg,0,sizeof(cfg));
cfg.token_server_url = strdup("https://dev.comcast.net/token");
parStrncpy(cfg.cert_path , "/etc/ssl/certs/ca-certificates.crt", sizeof(cfg.cert_path));
parStrncpy(cfg.hw_serial_number, "Fer23u948590", sizeof(cfg.hw_serial_number));
parStrncpy(cfg.hw_mac , "123567892366", sizeof(cfg.hw_mac));
set_parodus_cfg(&cfg);
will_return (curl_easy_init, NULL);
expect_function_calls (curl_easy_init, 1);
requestNewAuthToken (token, sizeof(token), 2);
assert_int_equal (output, -1);
assert_int_equal (0, (int) token[0]);
free(cfg.token_server_url);
}
/*----------------------------------------------------------------------------*/
/* External Functions */
/*----------------------------------------------------------------------------*/
int main(void)
{
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_requestNewAuthToken_init_fail)
};
return cmocka_run_group_tests(tests, NULL, NULL);
}

View File

@@ -33,6 +33,7 @@
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
static char *reconnect_reason = "webpa_process_starts";
UpStreamMsg *UpStreamMsgQ;
ParodusMsg *ParodusMsgQ;
pthread_mutex_t g_mutex=PTHREAD_MUTEX_INITIALIZER;
@@ -75,6 +76,21 @@ noPollMutexUnlock mutex_unlock
function_called();
}
char *get_global_reconnect_reason()
{
return reconnect_reason;
}
char *get_global_shutdown_reason()
{
return SHUTDOWN_REASON_PARODUS_STOP;
}
void set_global_shutdown_reason(char *reason)
{
UNUSED(reason);
}
void start_conn_in_progress (void)
{
}
@@ -83,6 +99,24 @@ void stop_conn_in_progress (void)
{
}
void reset_interface_down_event (void)
{
}
bool get_interface_down_event (void)
{
return false;
}
int wait_while_interface_down (void)
{
return 0;
}
void terminate_backoff_delay (void)
{
}
void packMetaData()
{
function_called();
@@ -309,7 +343,6 @@ void test_createSocketConnection1()
expect_function_call(nopoll_ctx_unref);
expect_function_call(nopoll_cleanup_library);
createSocketConnection(NULL);
assert_string_equal(get_parodus_cfg()->cloud_status, CLOUD_STATUS_OFFLINE);
}

View File

@@ -24,6 +24,7 @@
#include <assert.h>
#include <CUnit/Basic.h>
#include <nopoll.h>
#include <pthread.h>
#include "../src/ParodusInternal.h"
#include "../src/connection.h"
@@ -60,7 +61,10 @@ extern int keep_trying_to_connect (create_connection_ctx_t *ctx,
bool close_retry;
bool LastReasonStatus;
pthread_mutex_t close_mut;
bool interface_down_event = false;
pthread_mutex_t close_mut;
pthread_mutex_t interface_down_mut=PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t interface_down_con=PTHREAD_COND_INITIALIZER;
// Mock values
bool g_shutdown = false;
@@ -80,6 +84,35 @@ char* getWebpaConveyHeader()
return (char*) "WebPA-1.6 (TG1682)";
}
void set_interface_down_event()
{
interface_down_event = true;
}
void reset_interface_down_event()
{
pthread_mutex_lock (&interface_down_mut);
interface_down_event = false;
pthread_cond_signal(&interface_down_con);
pthread_mutex_unlock (&interface_down_mut);
}
bool get_interface_down_event()
{
return interface_down_event;
}
pthread_cond_t *get_interface_down_con(void)
{
return &interface_down_con;
}
pthread_mutex_t *get_interface_down_mut(void)
{
return &interface_down_mut;
}
noPollConn * nopoll_conn_new_opts (noPollCtx * ctx, noPollConnOpts * opts, const char * host_ip, const char * host_port, const char * host_name,const char * get_url,const char * protocols, const char * origin)
{
UNUSED(host_port); UNUSED(host_name); UNUSED(get_url); UNUSED(protocols);
@@ -117,6 +150,8 @@ nopoll_bool nopoll_conn_wait_for_status_until_connection_ready (noPollConn * co
int timeout, int *status, char ** message)
{
UNUSED(conn); UNUSED(timeout);
*message = NULL;
if (mock_wait_status >= 1000) {
*status = mock_wait_status / 1000;
mock_wait_status = mock_wait_status % 1000;
@@ -146,11 +181,9 @@ void nopoll_conn_close (noPollConn *conn)
UNUSED(conn);
}
int nopoll_conn_ref_count (noPollConn *conn)
void nopoll_conn_close_ext (noPollConn *conn, int status, const char *reason, int reason_size)
{
UNUSED(conn);
function_called ();
return (nopoll_bool) mock();
UNUSED(conn); UNUSED(status); UNUSED(reason); UNUSED(reason_size);
}
int checkHostIp(char * serverIP)
@@ -198,6 +231,7 @@ int allow_insecure_conn (char **server_addr, unsigned int *port)
/* Tests */
/*----------------------------------------------------------------------------*/
void test_get_global_conn()
{
assert_null(get_global_conn());
@@ -375,6 +409,15 @@ void test_set_current_server()
assert_ptr_equal (&ctx.server_list.defaults, ctx.current_server);
}
void init_cfg_header_info (ParodusCfg *cfg)
{
parStrncpy(cfg->hw_mac , "123567892366", sizeof(cfg->hw_mac));
parStrncpy(cfg->hw_model, "TG1682", sizeof(cfg->hw_model));
parStrncpy(cfg->hw_manufacturer , "ARRISGroup,Inc.", sizeof(cfg->hw_manufacturer));
parStrncpy(cfg->fw_name , "2.364s2", sizeof(cfg->fw_name));
parStrncpy(cfg->webpa_protocol , "WebPA-1.6", sizeof(cfg->webpa_protocol));
}
void test_set_extra_headers ()
{
int rtn;
@@ -391,12 +434,8 @@ void test_set_extra_headers ()
cfg.client_cert_path = strdup("testcert");
parStrncpy(cfg.hw_serial_number, "Fer23u948590", sizeof(cfg.hw_serial_number));
parStrncpy(cfg.hw_mac , "123567892366", sizeof(cfg.hw_mac));
parStrncpy(cfg.hw_model, "TG1682", sizeof(cfg.hw_model));
parStrncpy(cfg.hw_manufacturer , "ARRISGroup,Inc.", sizeof(cfg.hw_manufacturer));
parStrncpy(cfg.fw_name , "2.364s2", sizeof(cfg.fw_name));
init_cfg_header_info (&cfg);
parStrncpy(cfg.cert_path , "/etc/ssl/certs/ca-certificates.crt", sizeof(cfg.cert_path));
parStrncpy(cfg.webpa_protocol , "WebPA-1.6", sizeof(cfg.webpa_protocol));
set_parodus_cfg(&cfg);
rtn = init_header_info (&ctx.header_info);
@@ -578,19 +617,12 @@ void test_nopoll_connect ()
// Return codes for wait_connection_ready
#define WAIT_SUCCESS 0
#define WAIT_ACTION_RETRY 1 // if wait_status is 307, 302, 303 or 403
#define WAIT_ACTION_RETRY 1 // if wait_status is 307, 302, 303, or 403
#define WAIT_FAIL 2
void test_wait_connection_ready ()
{
create_connection_ctx_t ctx;
ParodusCfg Cfg;
const char *expected_extra_headers =
"\r\nAuthorization: Bearer Auth---"
"\r\nX-WebPA-Device-Name: mac:123567892366"
"\r\nX-WebPA-Device-Protocols: wrp-0.11,getset-0.1"
"\r\nUser-Agent: WebPA-1.6 (2.364s2; TG1682/ARRISGroup,Inc.;)"
"\r\nX-WebPA-Convey: WebPA-1.6 (TG1682)";
memset(&ctx,0,sizeof(ctx));
set_server_list_null (&ctx.server_list);
@@ -605,7 +637,7 @@ void test_wait_connection_ready ()
will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_false);
expect_function_call (nopoll_conn_wait_for_status_until_connection_ready);
assert_int_equal (wait_connection_ready (&ctx), WAIT_FAIL);
mock_wait_status = 503;
will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_false);
expect_function_call (nopoll_conn_wait_for_status_until_connection_ready);
@@ -640,30 +672,18 @@ void test_wait_connection_ready ()
free_server (&ctx.server_list.redirect);
mock_wait_status = 403;
memset(&Cfg, 0, sizeof(ParodusCfg));
parStrncpy (Cfg.webpa_auth_token, "Auth---", sizeof (Cfg.webpa_auth_token));
parStrncpy(Cfg.hw_model, "TG1682", sizeof(Cfg.hw_model));
parStrncpy(Cfg.hw_manufacturer , "ARRISGroup,Inc.", sizeof(Cfg.hw_manufacturer));
parStrncpy(Cfg.hw_mac , "123567892366", sizeof(Cfg.hw_mac));
parStrncpy(Cfg.fw_name , "2.364s2", sizeof(Cfg.fw_name));
parStrncpy(Cfg.webpa_protocol , "WebPA-1.6", sizeof(Cfg.webpa_protocol));
set_parodus_cfg(&Cfg);
init_header_info (&ctx.header_info);
will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_false);
expect_function_call (nopoll_conn_wait_for_status_until_connection_ready);
assert_int_equal (wait_connection_ready (&ctx), WAIT_ACTION_RETRY);
assert_string_equal (ctx.extra_headers, expected_extra_headers);
free_extra_headers (&ctx);
free_header_info (&ctx.header_info);
}
// Return codes for connect_and_wait
#define CONN_WAIT_SUCCESS 0
#define CONN_WAIT_ACTION_RETRY 1 // if wait_status is 307, 302, 303 or 403
#define CONN_WAIT_RETRY_DNS 2
#define CONN_WAIT_ACTION_RETRY 1 // if wait_status is 307, 302, 303, or 403
#define CONN_WAIT_RETRY_DNS 2
void test_connect_and_wait ()
{
@@ -707,8 +727,6 @@ void test_connect_and_wait ()
expect_function_call (nopoll_conn_is_ok);
will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_false);
expect_function_call (nopoll_conn_wait_for_status_until_connection_ready);
will_return (nopoll_conn_ref_count, 0);
expect_function_call (nopoll_conn_ref_count);
assert_int_equal (connect_and_wait (&ctx), CONN_WAIT_RETRY_DNS);
Cfg.flags = 0;
@@ -718,8 +736,6 @@ void test_connect_and_wait ()
expect_function_call (nopoll_conn_new_opts);
will_return (nopoll_conn_is_ok, nopoll_false);
expect_function_call (nopoll_conn_is_ok);
will_return (nopoll_conn_ref_count, 0);
expect_function_call (nopoll_conn_ref_count);
assert_int_equal (connect_and_wait (&ctx), CONN_WAIT_RETRY_DNS);
will_return (nopoll_conn_new_opts, &connection1);
@@ -757,8 +773,6 @@ void test_connect_and_wait ()
expect_function_call (nopoll_conn_tls_new6);
will_return (nopoll_conn_is_ok, nopoll_false);
expect_function_call (nopoll_conn_is_ok);
will_return (nopoll_conn_ref_count, 0);
expect_function_call (nopoll_conn_ref_count);
will_return (nopoll_conn_tls_new, NULL);
expect_function_call (nopoll_conn_tls_new);
will_return (checkHostIp, 0);
@@ -769,8 +783,6 @@ void test_connect_and_wait ()
expect_function_call (nopoll_conn_tls_new6);
will_return (nopoll_conn_is_ok, nopoll_false);
expect_function_call (nopoll_conn_is_ok);
will_return (nopoll_conn_ref_count, 0);
expect_function_call (nopoll_conn_ref_count);
will_return (nopoll_conn_tls_new, &connection1);
expect_function_call (nopoll_conn_tls_new);
will_return (nopoll_conn_is_ok, nopoll_true);
@@ -790,8 +802,6 @@ void test_connect_and_wait ()
mock_redirect = "mydns.mycom.net";
will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_false);
expect_function_call (nopoll_conn_wait_for_status_until_connection_ready);
will_return (nopoll_conn_ref_count, 0);
expect_function_call (nopoll_conn_ref_count);
assert_int_equal (connect_and_wait (&ctx), CONN_WAIT_RETRY_DNS);
will_return (nopoll_conn_tls_new, &connection1);
@@ -802,8 +812,6 @@ void test_connect_and_wait ()
mock_redirect = "https://mydns.mycom.net";
will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_false);
expect_function_call (nopoll_conn_wait_for_status_until_connection_ready);
will_return (nopoll_conn_ref_count, 0);
expect_function_call (nopoll_conn_ref_count);
assert_int_equal (connect_and_wait (&ctx), CONN_WAIT_ACTION_RETRY);
}
@@ -815,22 +823,16 @@ void test_keep_trying ()
server_t test_server;
backoff_timer_t backoff_timer;
ParodusCfg Cfg;
char *test_extra_headers =
"\r\nAuthorization: Bearer SER_MAC Fer23u948590 123567892366"
"\r\nX-WebPA-Device-Name: mac:123567892366"
"\r\nX-WebPA-Device-Protocols: wrp-0.11,getset-0.1"
"\r\nUser-Agent: WebPA-1.6 (2.364s2; TG1682/ARRISGroup,Inc.;)"
"\r\nX-WebPA-Convey: WebPA-1.6 (TG1682)";
memset(&Cfg, 0, sizeof(ParodusCfg));
parStrncpy (Cfg.webpa_url, "http://mydns.mycom.net:8080", sizeof(Cfg.webpa_url));
init_cfg_header_info (&Cfg);
mock_wait_status = 0;
memset(&ctx,0,sizeof(ctx));
ctx.nopoll_ctx = &test_nopoll_ctx;
ctx.current_server = &test_server;
ctx.extra_headers = test_extra_headers;
test_server.allow_insecure = 1;
test_server.server_addr = "mydns.mycom.net";
@@ -861,8 +863,6 @@ void test_keep_trying ()
mock_redirect = "https://mydns.mycom.net";
will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_false);
expect_function_call (nopoll_conn_wait_for_status_until_connection_ready);
will_return (nopoll_conn_ref_count, 0);
expect_function_call (nopoll_conn_ref_count);
will_return (nopoll_conn_tls_new, &connection1);
expect_function_call (nopoll_conn_tls_new);
will_return (nopoll_conn_is_ok, nopoll_true);
@@ -881,16 +881,12 @@ void test_keep_trying ()
mock_redirect = "https://mydns.mycom.net";
will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_false);
expect_function_call (nopoll_conn_wait_for_status_until_connection_ready);
will_return (nopoll_conn_ref_count, 0);
expect_function_call (nopoll_conn_ref_count);
will_return (nopoll_conn_tls_new, &connection1);
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_for_status_until_connection_ready, nopoll_false);
expect_function_call (nopoll_conn_wait_for_status_until_connection_ready);
will_return (nopoll_conn_ref_count, 0);
expect_function_call (nopoll_conn_ref_count);
init_backoff_timer (&backoff_timer, 5);
rtn = keep_trying_to_connect (&ctx, &backoff_timer);
assert_int_equal (rtn, false);
@@ -913,8 +909,6 @@ void test_keep_trying ()
expect_function_call (nopoll_conn_is_ok);
will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_false);
expect_function_call (nopoll_conn_wait_for_status_until_connection_ready);
will_return (nopoll_conn_ref_count, 0);
expect_function_call (nopoll_conn_ref_count);
init_backoff_timer (&backoff_timer, 5);
rtn = keep_trying_to_connect (&ctx, &backoff_timer);
assert_int_equal (rtn, false);
@@ -964,8 +958,6 @@ void test_create_nopoll_connection()
expect_function_call (nopoll_conn_tls_new6);
will_return (nopoll_conn_is_ok, nopoll_false);
expect_function_call (nopoll_conn_is_ok);
will_return (nopoll_conn_ref_count, 0);
expect_function_call (nopoll_conn_ref_count);
will_return (nopoll_conn_tls_new, &connection1);
expect_function_call (nopoll_conn_tls_new);
will_return (nopoll_conn_is_ok, nopoll_true);
@@ -979,8 +971,6 @@ void test_create_nopoll_connection()
expect_function_call (nopoll_conn_tls_new6);
will_return (nopoll_conn_is_ok, nopoll_false);
expect_function_call (nopoll_conn_is_ok);
will_return (nopoll_conn_ref_count, 0);
expect_function_call (nopoll_conn_ref_count);
will_return (nopoll_conn_tls_new, &connection1);
expect_function_call (nopoll_conn_tls_new);
will_return (nopoll_conn_is_ok, nopoll_true);
@@ -989,15 +979,11 @@ void test_create_nopoll_connection()
mock_redirect = "https://mydns.mycom.net";
will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_false);
expect_function_call (nopoll_conn_wait_for_status_until_connection_ready);
will_return (nopoll_conn_ref_count, 0);
expect_function_call (nopoll_conn_ref_count);
will_return (nopoll_conn_tls_new6, &connection1);
expect_function_call (nopoll_conn_tls_new6);
will_return (nopoll_conn_is_ok, nopoll_false);
expect_function_call (nopoll_conn_is_ok);
will_return (nopoll_conn_ref_count, 0);
expect_function_call (nopoll_conn_ref_count);
will_return (nopoll_conn_tls_new, &connection1);
expect_function_call (nopoll_conn_tls_new);
will_return (nopoll_conn_is_ok, nopoll_true);
@@ -1041,8 +1027,6 @@ void test_create_nopoll_connection()
expect_function_call (nopoll_conn_tls_new6);
will_return (nopoll_conn_is_ok, nopoll_false);
expect_function_call (nopoll_conn_is_ok);
will_return (nopoll_conn_ref_count, 0);
expect_function_call (nopoll_conn_ref_count);
mock_wait_status = 0;
will_return (nopoll_conn_tls_new, &connection1);
expect_function_call (nopoll_conn_tls_new);
@@ -1056,6 +1040,149 @@ void test_create_nopoll_connection()
}
void test_get_interface_down_event()
{
assert_false(get_interface_down_event());
set_interface_down_event();
}
void *a()
{
sleep(15);
reset_interface_down_event();
pthread_exit(0);
return NULL;
}
void test_interface_down_retry()
{
int rtn;
ParodusCfg cfg;
noPollCtx test_nopoll_ctx;
pthread_t thread_a;
pthread_create(&thread_a, NULL, a, NULL);
memset(&cfg,0,sizeof(cfg));
cfg.flags = 0;
parStrncpy (cfg.webpa_url, "mydns.mycom.net:8080", sizeof(cfg.webpa_url));
cfg.boot_time = 25;
parStrncpy (cfg.hw_last_reboot_reason, "Test reason", sizeof(cfg.hw_last_reboot_reason));
cfg.webpa_backoff_max = 30;
parStrncpy (cfg.webpa_auth_token, "Auth---", sizeof (cfg.webpa_auth_token));
parStrncpy(cfg.hw_model, "TG1682", sizeof(cfg.hw_model));
parStrncpy(cfg.hw_manufacturer , "ARRISGroup,Inc.", sizeof(cfg.hw_manufacturer));
parStrncpy(cfg.hw_mac , "123567892366", sizeof(cfg.hw_mac));
parStrncpy(cfg.fw_name , "2.364s2", sizeof(cfg.fw_name));
parStrncpy(cfg.webpa_protocol , "WebPA-1.6", sizeof(cfg.webpa_protocol));
set_parodus_cfg(&cfg);
rtn = createNopollConnection (&test_nopoll_ctx);
assert_int_equal (rtn, nopoll_false);
parStrncpy (cfg.webpa_url, "http://mydns.mycom.net:8080", sizeof(cfg.webpa_url));
set_parodus_cfg(&cfg);
mock_wait_status = 0;
will_return (nopoll_conn_new_opts, &connection1);
expect_function_call (nopoll_conn_new_opts);
will_return (nopoll_conn_is_ok, nopoll_true);
expect_function_call (nopoll_conn_is_ok);
will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_true);
expect_function_call (nopoll_conn_wait_for_status_until_connection_ready);
rtn = createNopollConnection (&test_nopoll_ctx);
assert_int_equal (rtn, nopoll_true);
parStrncpy (cfg.webpa_url, "https://mydns.mycom.net:8080", sizeof(cfg.webpa_url));
cfg.flags = 0;
set_parodus_cfg(&cfg);
will_return (nopoll_conn_tls_new6, &connection1);
expect_function_call (nopoll_conn_tls_new6);
will_return (nopoll_conn_is_ok, nopoll_false);
expect_function_call (nopoll_conn_is_ok);
will_return (nopoll_conn_tls_new, &connection1);
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_for_status_until_connection_ready, nopoll_true);
expect_function_call (nopoll_conn_wait_for_status_until_connection_ready);
rtn = createNopollConnection (&test_nopoll_ctx);
assert_int_equal (rtn, nopoll_true);
will_return (nopoll_conn_tls_new6, &connection1);
expect_function_call (nopoll_conn_tls_new6);
will_return (nopoll_conn_is_ok, nopoll_false);
expect_function_call (nopoll_conn_is_ok);
will_return (nopoll_conn_tls_new, &connection1);
expect_function_call (nopoll_conn_tls_new);
will_return (nopoll_conn_is_ok, nopoll_true);
expect_function_call (nopoll_conn_is_ok);
mock_wait_status = 302;
mock_redirect = "https://mydns.mycom.net";
will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_false);
expect_function_call (nopoll_conn_wait_for_status_until_connection_ready);
will_return (nopoll_conn_tls_new6, &connection1);
expect_function_call (nopoll_conn_tls_new6);
will_return (nopoll_conn_is_ok, nopoll_false);
expect_function_call (nopoll_conn_is_ok);
will_return (nopoll_conn_tls_new, &connection1);
expect_function_call (nopoll_conn_tls_new);
will_return (nopoll_conn_is_ok, nopoll_true);
expect_function_call (nopoll_conn_is_ok);
mock_wait_status = 0;
will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_true);
expect_function_call (nopoll_conn_wait_for_status_until_connection_ready);
rtn = createNopollConnection (&test_nopoll_ctx);
assert_int_equal (rtn, nopoll_true);
#ifdef FEATURE_DNS_QUERY
cfg.acquire_jwt = 1;
cfg.flags = FLAGS_IPV4_ONLY;
set_parodus_cfg(&cfg);
will_return (allow_insecure_conn, -1);
expect_function_call (allow_insecure_conn);
will_return (nopoll_conn_tls_new, NULL);
expect_function_call (nopoll_conn_tls_new);
will_return (checkHostIp, 0);
expect_function_call (checkHostIp);
mock_server_addr = "mydns.myjwtcom.net";
mock_port = 80;
will_return (allow_insecure_conn, 0);
expect_function_call (allow_insecure_conn);
will_return (nopoll_conn_tls_new, &connection1);
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_for_status_until_connection_ready, nopoll_true);
expect_function_call (nopoll_conn_wait_for_status_until_connection_ready);
rtn = createNopollConnection (&test_nopoll_ctx);
assert_int_equal (rtn, nopoll_true);
cfg.flags = 0;
set_parodus_cfg(&cfg);
will_return (allow_insecure_conn, -1);
expect_function_call (allow_insecure_conn);
will_return (nopoll_conn_tls_new6, &connection1);
expect_function_call (nopoll_conn_tls_new6);
will_return (nopoll_conn_is_ok, nopoll_false);
expect_function_call (nopoll_conn_is_ok);
mock_wait_status = 0;
will_return (nopoll_conn_tls_new, &connection1);
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_for_status_until_connection_ready, nopoll_true);
expect_function_call (nopoll_conn_wait_for_status_until_connection_ready);
rtn = createNopollConnection (&test_nopoll_ctx);
assert_int_equal (rtn, nopoll_true);
#endif
pthread_join(thread_a, NULL);
}
/*----------------------------------------------------------------------------*/
/* External Functions */
@@ -1083,7 +1210,9 @@ int main(void)
cmocka_unit_test(test_wait_connection_ready),
cmocka_unit_test(test_connect_and_wait),
cmocka_unit_test(test_keep_trying),
cmocka_unit_test(test_create_nopoll_connection)
cmocka_unit_test(test_create_nopoll_connection),
cmocka_unit_test(test_get_interface_down_event),
cmocka_unit_test(test_interface_down_retry)
};
return cmocka_run_group_tests(tests, NULL, NULL);

View File

@@ -21,6 +21,7 @@
#include <nopoll_private.h>
#include <pthread.h>
#include "../src/ParodusInternal.h"
#include "../src/nopoll_handlers.h"
#include "../src/parodus_log.h"
@@ -29,8 +30,11 @@
/*----------------------------------------------------------------------------*/
volatile unsigned int heartBeatTimer;
bool LastReasonStatus;
bool interface_down_event = false;
int closeReason = 0;
pthread_mutex_t close_mut;
pthread_mutex_t close_mut;
pthread_mutex_t interface_down_mut=PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t interface_down_con=PTHREAD_COND_INITIALIZER;
bool close_retry;
/*----------------------------------------------------------------------------*/
/* Mocks */
@@ -46,6 +50,24 @@ bool get_global_reconnect_status()
return LastReasonStatus;
}
void set_interface_down_event()
{
interface_down_event = true;
}
void reset_interface_down_event()
{
pthread_mutex_lock (&interface_down_mut);
interface_down_event = false;
pthread_cond_signal(&interface_down_con);
pthread_mutex_unlock (&interface_down_mut);
}
bool get_interface_down_event()
{
return interface_down_event;
}
void set_global_reconnect_status(bool status)
{
(void) status ;
@@ -179,6 +201,30 @@ void test_listenerOnPingMessage()
listenerOnPingMessage(NULL, NULL, NULL, NULL);
}
void test_getInterfaceDownEvent()
{
set_interface_down_event();
CU_ASSERT_TRUE(get_interface_down_event());
}
void test_interfaceDownEvent()
{
char str[] = "SSL_Socket_Close";
set_global_reconnect_status(true);
set_interface_down_event();
listenerOnCloseMessage(NULL, NULL, (noPollPtr) str);
}
void test_noInterfaceDownEvent()
{
char str[] = "SSL_Socket_Close";
set_global_reconnect_status(true);
reset_interface_down_event();
listenerOnCloseMessage(NULL, NULL, (noPollPtr) str);
}
void add_suites( CU_pSuite *suite )
{
ParodusInfo("--------Start of Test Cases Execution ---------\n");
@@ -186,6 +232,9 @@ void add_suites( CU_pSuite *suite )
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 );
CU_add_test( *suite, "Test 4", test_getInterfaceDownEvent );
CU_add_test( *suite, "Test 5", test_interfaceDownEvent );
CU_add_test( *suite, "Test 6", test_noInterfaceDownEvent );
}
/*----------------------------------------------------------------------------*/

View File

@@ -48,6 +48,11 @@ bool get_global_reconnect_status()
return LastReasonStatus;
}
bool get_interface_down_event()
{
return false;
}
void set_global_reconnect_status(bool status)
{
(void) status ;

View File

@@ -16,6 +16,7 @@
#include <stdarg.h>
#include <stddef.h>
#include <stdbool.h>
#include <setjmp.h>
#include <cmocka.h>
#include <nopoll.h>
@@ -116,6 +117,11 @@ int kill(pid_t pid, int sig)
return (int) mock();
}
bool get_interface_down_event()
{
return false;
}
/*----------------------------------------------------------------------------*/
/* Tests */
/*----------------------------------------------------------------------------*/

249
tests/test_upstream_sock.c Normal file
View File

@@ -0,0 +1,249 @@
/**
* 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 <malloc.h>
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <nopoll.h>
#include <wrp-c.h>
#include <nanomsg/nn.h>
#include "../src/upstream.h"
#include "../src/config.h"
#include "../src/client_list.h"
#include "../src/ParodusInternal.h"
#include "../src/partners_check.h"
#include "../src/close_retry.h"
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
#define GOOD_CLIENT_URL "tcp://127.0.0.1:6667"
static noPollConn *conn;
static char *reconnect_reason = "webpa_process_starts";
bool g_shutdown = false;
static ParodusCfg parodusCfg;
extern size_t metaPackSize;
extern UpStreamMsg *UpStreamMsgQ;
int numLoops = 1;
int deviceIDNull =0;
wrp_msg_t *reg_msg = NULL;
extern pthread_mutex_t nano_mut;
extern pthread_cond_t nano_con;
/*----------------------------------------------------------------------------*/
/* Mocks */
/*----------------------------------------------------------------------------*/
reg_list_item_t *get_reg_list()
{
reg_list_item_t *item = get_global_node();
release_global_node();
return item;
}
noPollConn *get_global_conn()
{
return conn;
}
char *get_global_reconnect_reason()
{
return reconnect_reason;
}
void addCRUDmsgToQueue(wrp_msg_t *crudMsg)
{
(void)crudMsg;
function_called();
return;
}
void sendMessage(noPollConn *conn, void *msg, size_t len)
{
(void) conn; (void) msg; (void) len;
function_called();
}
void set_parodus_cfg(ParodusCfg *cfg)
{
memcpy(&parodusCfg, cfg, sizeof(ParodusCfg));
}
ParodusCfg *get_parodus_cfg(void)
{
ParodusCfg cfg;
memset(&cfg,0,sizeof(cfg));
parStrncpy(cfg.hw_mac , "14cfe2142xxx", sizeof(cfg.hw_mac));
if(deviceIDNull)
{
parStrncpy(cfg.hw_mac , "", sizeof(cfg.hw_mac));
}
set_parodus_cfg(&cfg);
return &parodusCfg;
}
/*-------------------------------------------
int nn_connect (int s, const char *addr)
{
(void) s; (void) addr;
printf ("nn_connect, socket %d\n", s);
return 1;
}
---------------------------------------------*/
ssize_t wrp_pack_metadata( const data_t *packData, void **data )
{
(void) packData; (void) data;
function_called();
return (ssize_t)mock();
}
size_t appendEncodedData( void **appendData, void *encodedBuffer, size_t encodedSize, void *metadataPack, size_t metadataSize )
{
(void) encodedBuffer; (void) encodedSize; (void) metadataPack; (void) metadataSize;
function_called();
char *data = (char *) malloc (sizeof(char) * 100);
parStrncpy(data, "AAAAAAAAYYYYIGkYTUYFJH", 100);
*appendData = data;
return (size_t)mock();
}
int nn_send (int s, const void *buf, size_t len, int flags)
{
UNUSED(s); UNUSED(buf); UNUSED(len); UNUSED(flags);
function_called();
return (int)mock();
}
int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex)
{
UNUSED(cond); UNUSED(mutex);
function_called();
return (int)mock();
}
ssize_t wrp_to_struct( const void *bytes, const size_t length, const enum wrp_format fmt, wrp_msg_t **msg )
{
UNUSED(bytes); UNUSED(length); UNUSED(fmt);
function_called();
*msg = reg_msg;
return (ssize_t)mock();
}
void wrp_free_struct( wrp_msg_t *msg )
{
UNUSED(msg);
function_called();
}
int nn_freemsg (void *msg)
{
UNUSED(msg);
function_called();
return (int)mock();
}
int validate_partner_id(wrp_msg_t *msg, partners_t **partnerIds)
{
UNUSED(msg); UNUSED(partnerIds);
function_called();
return (int) mock();
}
/*----------------------------------------------------------------------------*/
/* Tests */
/*----------------------------------------------------------------------------*/
void test_message()
{
metaPackSize = 20;
UpStreamMsgQ = (UpStreamMsg *) malloc(sizeof(UpStreamMsg));
UpStreamMsgQ->msg = "First Message";
UpStreamMsgQ->len = 13;
UpStreamMsgQ->next = NULL;
numLoops = 1;
reg_msg = (wrp_msg_t *) malloc(sizeof(wrp_msg_t));
memset(reg_msg,0,sizeof(wrp_msg_t));
reg_msg->msg_type = WRP_MSG_TYPE__SVC_REGISTRATION;
reg_msg->u.reg.service_name = "config";
reg_msg->u.reg.url = GOOD_CLIENT_URL;
will_return(wrp_to_struct, 12);
expect_function_call(wrp_to_struct);
will_return(nn_send, 1);
expect_function_call(nn_send);
will_return(nn_freemsg, 0);
expect_function_call(nn_freemsg);
expect_function_call(wrp_free_struct);
processUpstreamMessage();
free(reg_msg);
free(UpStreamMsgQ);
}
void test_processUpstreamMessage()
{
int last_sock = -1;
reg_list_item_t * reg_item = get_reg_list ();
assert_null (reg_item);
test_message();
reg_item = get_reg_list ();
assert_non_null (reg_item);
if (NULL == reg_item)
return;
last_sock = reg_item->sock;
test_message ();
assert_int_equal (get_numOfClients(), 1);
if (get_numOfClients() != 1)
return;
reg_item = get_reg_list ();
assert_int_equal (last_sock, reg_item->sock);
if (last_sock != reg_item->sock)
return;
test_message ();
assert_int_equal (get_numOfClients(), 1);
if (get_numOfClients() != 1)
return;
reg_item = get_reg_list ();
assert_int_equal (last_sock, reg_item->sock);
}
/*----------------------------------------------------------------------------*/
/* External Functions */
/*----------------------------------------------------------------------------*/
int main(void)
{
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_processUpstreamMessage)
};
return cmocka_run_group_tests(tests, NULL, NULL);
}