mirror of
https://github.com/outbackdingo/parodus.git
synced 2026-01-27 10:20:04 +00:00
Merge pull request #342 from bill1600/cloudstat
check cloud status for sendMessage
This commit is contained in:
@@ -27,6 +27,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
||||
- on connect retry, requery jwt only if it failed before
|
||||
- put two timestamps in connection health file; start conn and current
|
||||
- change health file update interval to 240sec
|
||||
- sendMessage to check cloud status == ONLINE before sending
|
||||
|
||||
## [1.0.2] - 2019-02-08
|
||||
- Refactored connection.c and updated corresponding unit tests
|
||||
|
||||
@@ -815,8 +815,8 @@ void close_and_unref_connection(noPollConn *conn)
|
||||
reason_len = (int) strlen (reason);
|
||||
status = CloseNormalClosure;
|
||||
}
|
||||
nopoll_conn_close_ext(conn, status, reason, reason_len);
|
||||
get_parodus_cfg()->cloud_status = CLOUD_STATUS_OFFLINE;
|
||||
nopoll_conn_close_ext(conn, status, reason, reason_len);
|
||||
ParodusInfo("cloud_status set as %s after connection close\n", get_parodus_cfg()->cloud_status);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "nopoll_helpers.h"
|
||||
#include "nopoll_handlers.h"
|
||||
#include "time.h"
|
||||
#include "config.h"
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Macros */
|
||||
@@ -49,59 +50,33 @@ void setMessageHandlers()
|
||||
nopoll_conn_set_on_close(get_global_conn(), (noPollOnCloseHandler)listenerOnCloseMessage, NULL);
|
||||
}
|
||||
|
||||
static int cloud_status_is_online (void)
|
||||
{
|
||||
const char *status = get_parodus_cfg()->cloud_status;
|
||||
if (NULL == status)
|
||||
return false;
|
||||
return (strcmp (status, CLOUD_STATUS_ONLINE) == 0);
|
||||
}
|
||||
|
||||
/** To send upstream msgs to server ***/
|
||||
|
||||
void sendMessage(noPollConn *conn, void *msg, size_t len)
|
||||
{
|
||||
int bytesWritten = 0;
|
||||
static int connErr=0;
|
||||
long timeDiff = 0;
|
||||
|
||||
if (!cloud_status_is_online ()) {
|
||||
ParodusError("Failed to send msg upstream as connection is not OK\n");
|
||||
OnboardLog("Failed to send msg upstream as connection is not OK\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ParodusInfo("sendMessage length %zu\n", len);
|
||||
|
||||
if(nopoll_conn_is_ok(conn) && nopoll_conn_is_ready(conn))
|
||||
bytesWritten = sendResponse(conn, msg, len);
|
||||
ParodusPrint("Number of bytes written: %d\n", bytesWritten);
|
||||
if (bytesWritten != (int) len)
|
||||
{
|
||||
//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));
|
||||
}
|
||||
connErr = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ParodusError("Failed to send msg upstream as connection is not OK\n");
|
||||
OnboardLog("Failed to send msg upstream as connection is not OK\n");
|
||||
|
||||
if(get_interface_down_event())
|
||||
{
|
||||
ParodusError("Unable to connect to server since interface is down\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
ParodusError("Failed to send bytes %zu, bytes written were=%d (errno=%d, %s)..\n", len, bytesWritten, errno, strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
104
tests/mock_event_handler.c
Normal file
104
tests/mock_event_handler.c
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* If not stated otherwise in this file or this component's Licenses.txt file the
|
||||
* following copyright and licenses apply:
|
||||
*
|
||||
* Copyright 2016 RDK Management
|
||||
* Copyright [2014] [Cisco Systems, Inc.]
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* This is a test version of event_handler.c that can be used
|
||||
* to simulate interface down, interface up event
|
||||
* You overwrite event_handler.c in the src diectory with this
|
||||
* version. It will generate interface down / interface up events
|
||||
* at random intervals between 60 secs and 124 secs
|
||||
*/
|
||||
|
||||
#include "parodus_log.h"
|
||||
#include "event_handler.h"
|
||||
#include "connection.h"
|
||||
#include "config.h"
|
||||
#include "heartBeat.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include "time.h"
|
||||
#include "close_retry.h"
|
||||
|
||||
extern bool g_shutdown;
|
||||
|
||||
static pthread_t sysevent_tid;
|
||||
|
||||
static void start_interface_down (void)
|
||||
{
|
||||
set_interface_down_event();
|
||||
ParodusInfo("Interface_down_event is set\n");
|
||||
pause_heartBeatTimer();
|
||||
}
|
||||
|
||||
static void end_interface_down (void)
|
||||
{
|
||||
reset_interface_down_event();
|
||||
ParodusInfo("Interface_down_event is reset\n");
|
||||
resume_heartBeatTimer();
|
||||
set_close_retry();
|
||||
}
|
||||
|
||||
// waits from 60 to 124 secs
|
||||
int wait_random (const char *msg)
|
||||
{
|
||||
#define HALF_SEC 500000l
|
||||
long delay = (random() >> 5) + 60000000l;
|
||||
long secs, usecs;
|
||||
struct timeval timeout;
|
||||
|
||||
secs = delay / 1000000;
|
||||
usecs = delay % 1000000;
|
||||
ParodusInfo ("Waiting %ld secs %ld usecs for %s\n", secs, usecs, msg);
|
||||
|
||||
while (!g_shutdown) {
|
||||
timeout.tv_sec = 0;
|
||||
if (delay <= HALF_SEC) {
|
||||
timeout.tv_usec = delay;
|
||||
select (0, NULL, NULL, NULL, &timeout);
|
||||
return 0;
|
||||
}
|
||||
timeout.tv_usec = HALF_SEC;
|
||||
delay -= HALF_SEC;
|
||||
select (0, NULL, NULL, NULL, &timeout);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static void *parodus_sysevent_handler (void *data)
|
||||
{
|
||||
while (!g_shutdown) {
|
||||
if (wait_random ("interface down") != 0)
|
||||
break;
|
||||
start_interface_down ();
|
||||
wait_random ("interface up");
|
||||
end_interface_down ();
|
||||
}
|
||||
ParodusInfo ("Exiting event handler\n");
|
||||
return data;
|
||||
}
|
||||
|
||||
void EventHandler()
|
||||
{
|
||||
ParodusInfo ("RAND_MAX is %ld (0x%lx)\n", RAND_MAX, RAND_MAX);
|
||||
srandom (getpid());
|
||||
|
||||
pthread_create(&sysevent_tid, NULL, parodus_sysevent_handler, NULL);
|
||||
}
|
||||
@@ -120,6 +120,10 @@ bool get_interface_down_event (void)
|
||||
return false;
|
||||
}
|
||||
|
||||
void set_interface_down_event (void)
|
||||
{
|
||||
}
|
||||
|
||||
int wait_while_interface_down (void)
|
||||
{
|
||||
return 0;
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include "../src/parodus_log.h"
|
||||
#include "../src/nopoll_helpers.h"
|
||||
#include "../src/config.h"
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Macros */
|
||||
@@ -32,7 +33,9 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* File Scoped Variables */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static noPollConn *conn;
|
||||
static noPollConn *conn = NULL;
|
||||
static ParodusCfg cfg;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Mocks */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
@@ -54,6 +57,12 @@ nopoll_bool nopoll_conn_is_ready( noPollConn *conn )
|
||||
return (nopoll_bool)mock();
|
||||
}
|
||||
|
||||
ParodusCfg *get_parodus_cfg(void)
|
||||
{
|
||||
function_called();
|
||||
return &cfg;
|
||||
}
|
||||
|
||||
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);
|
||||
@@ -212,13 +221,8 @@ 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);
|
||||
cfg.cloud_status = CLOUD_STATUS_ONLINE;
|
||||
expect_function_calls (get_parodus_cfg, 1);
|
||||
|
||||
expect_value(__nopoll_conn_send_common, (intptr_t)conn, (intptr_t)conn);
|
||||
expect_value(__nopoll_conn_send_common, length, len);
|
||||
@@ -228,81 +232,23 @@ void test_sendMessage()
|
||||
sendMessage(conn, "Hello Parodus!", len);
|
||||
}
|
||||
|
||||
void connStuck_sendMessage()
|
||||
void test_sendMessageOffline()
|
||||
{
|
||||
int len = strlen("Hello Parodus!");
|
||||
|
||||
/* Initialize the timer when connection gets stuck */
|
||||
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);
|
||||
|
||||
expect_function_call(getCurrentTime);
|
||||
sendMessage(NULL, "Hello Parodus!", len);
|
||||
|
||||
/* When connection recovers within 10 mins, it should be able to re-connect */
|
||||
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);
|
||||
|
||||
expect_function_call(getCurrentTime);
|
||||
|
||||
will_return(timeValDiff, 5*60*1000);
|
||||
expect_function_call(timeValDiff);
|
||||
|
||||
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);
|
||||
|
||||
int len = strlen("Hello Parodus!");
|
||||
|
||||
cfg.cloud_status = CLOUD_STATUS_OFFLINE;
|
||||
expect_function_calls (get_parodus_cfg, 1);
|
||||
sendMessage(conn, "Hello Parodus!", len);
|
||||
|
||||
/* When timer exceeds more than 10 mins kill the process */
|
||||
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);
|
||||
|
||||
expect_function_call(getCurrentTime);
|
||||
|
||||
sendMessage(NULL, "Hello Parodus!", len);
|
||||
|
||||
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);
|
||||
|
||||
expect_function_call(getCurrentTime);
|
||||
|
||||
will_return(timeValDiff, 10*60*1000);
|
||||
expect_function_call(timeValDiff);
|
||||
|
||||
will_return(kill, 1);
|
||||
expect_function_call(kill);
|
||||
|
||||
sendMessage(NULL, "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);
|
||||
|
||||
cfg.cloud_status = CLOUD_STATUS_ONLINE;
|
||||
expect_function_calls (get_parodus_cfg, 1);
|
||||
|
||||
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);
|
||||
@@ -320,11 +266,13 @@ 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);
|
||||
cfg.cloud_status = CLOUD_STATUS_ONLINE;
|
||||
expect_function_calls (get_parodus_cfg, 1);
|
||||
|
||||
expect_function_call(getCurrentTime);
|
||||
expect_value(__nopoll_conn_send_common, (intptr_t)conn, NULL);
|
||||
expect_value(__nopoll_conn_send_common, length, len);
|
||||
will_return(__nopoll_conn_send_common, len);
|
||||
expect_function_calls(__nopoll_conn_send_common, 1);
|
||||
|
||||
sendMessage(NULL, "Hello Parodus!", len);
|
||||
}
|
||||
@@ -349,7 +297,7 @@ int main(void)
|
||||
cmocka_unit_test(err_sendResponseFlushWrites),
|
||||
cmocka_unit_test(err_sendResponseConnNull),
|
||||
cmocka_unit_test(test_sendMessage),
|
||||
cmocka_unit_test(connStuck_sendMessage),
|
||||
cmocka_unit_test(test_sendMessageOffline),
|
||||
cmocka_unit_test(err_sendMessage),
|
||||
cmocka_unit_test(err_sendMessageConnNull),
|
||||
cmocka_unit_test(test_reportLog),
|
||||
|
||||
Reference in New Issue
Block a user