Skip to content

Commit

Permalink
Merge branch 'task/#24161-Implement_new_message_log_find_event_v2_in_…
Browse files Browse the repository at this point in the history
…libelos' into 'integration'

task/#24161-Implement_new_message_log_find_event_v2_in_libelos

See merge request elektrobit/base-os/elos!131
  • Loading branch information
gehwolf committed Sep 26, 2024
2 parents 699de44 + 2d8e953 commit 0ebb07b
Show file tree
Hide file tree
Showing 21 changed files with 854 additions and 49 deletions.
26 changes: 25 additions & 1 deletion ci/run_utest.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,23 @@
#!/bin/bash
###############################################################################
print_info() {
echo "
Run the unit test suite or parts of it. Default is to run all unit
tests for the Debug build.
Usage: ${0} [build type] [--test-regex|-R <test name pattern>] [-h|--help]
build type: usually Debug or Release but can be any other build type
--test-regex|-R: execute all tests matching the pattern
-h|--help: print this help
Examples:
${0} Release # run all unit test on Release build
${0} Release -R elosRpn # run all unit test containing elosRpn in
the name for the Release build.
"
}
###############################################################################
set -e -u -o pipefail

CMD_PATH="$(realpath "$(dirname "$0")")"
Expand All @@ -12,8 +31,13 @@ while [ $# -gt 0 ]; do
TESTS_REGEX="--tests-regex ${2}"
shift
;;
-h|--help)
print_info
exit 0 ;;
-*)
echo "error: unknown option: $1"; exit 1 ;;
echo "error: unknown option: $1"
print_info
exit 1 ;;
*)
PARAM="$PARAM ${1}" ;;
esac
Expand Down
2 changes: 1 addition & 1 deletion cmake/project.cmake
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: MIT
set(ELOS_VERSION 0.64.1)
set(ELOS_VERSION 0.64.2)

# Attention: Aside from the version, as many things as possible in this file
# should be put into functions, as this solves potential issues with commands
Expand Down
6 changes: 4 additions & 2 deletions src/demos/elosc.c
Original file line number Diff line number Diff line change
Expand Up @@ -338,9 +338,11 @@ static safuResultE_t _commandLogFindEvent(elosSession_t *session, elosConfig_t *
elosEventVector_t *eventVector = NULL;
int retVal;

retVal = elosLogFindEvent(session, config->commandArgs, &eventVector);
struct timespec newest = {0};
struct timespec oldest = {0};
retVal = elosFindEvents(session, config->commandArgs, &newest, &oldest, &eventVector);
if (retVal < 0) {
fprintf(stderr, "log event find failed!\n");
fprintf(stderr, "event find failed!\n");
} else if (eventVector == NULL) {
printf("No matching events returned\n");
result = SAFU_RESULT_OK;
Expand Down
150 changes: 106 additions & 44 deletions src/libelos/private/libelos.c
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
// SPDX-License-Identifier: MIT

#include <bits/stdint-uintn.h>
#include <json-c/json_object.h>
#include <safu/common.h>
#include <json-c/json_types.h>
#include <safu/result.h>
#include <safu/vector.h>
#include <safu/vector_types.h>
#include <stddef.h>
#include <stdint.h>
#include <time.h>

#include "elos/event/event_types.h"
#include "elos/event/event_vector.h"
#define _DEFAULT_SOURCE 1

#include <arpa/inet.h>
#include <errno.h>
#include <json-c/json.h>
#include <netdb.h>
#include <safu/json.h>
#include <safu/log.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
#include <unistd.h>

Expand All @@ -25,9 +29,6 @@
#include "elos/libelos/libelos.h"
#include "libelos_communication.h"
#include "libelos_constructor.h"
#include "safu/common.h"
#include "safu/json.h"
#include "safu/log.h"

#define VERSION_DATA_LEN 128

Expand Down Expand Up @@ -212,57 +213,118 @@ safuResultE_t elosGetVersion(elosSession_t *session, char const **version) {
return result;
}

// Deprecated
safuResultE_t elosLogFindEvent(elosSession_t *session, const char *filterRule, elosEventVector_t **eventVector) {
return elosFindEvents(session, filterRule, &(struct timespec){0}, &(struct timespec){0}, eventVector);
}

static safuResultE_t _createFindEventRequest(const char *filterRule, struct timespec const *newest,
struct timespec const *oldest, json_object **jRequest) {
safuResultE_t result = SAFU_RESULT_FAILED;
bool retBool;

retBool = elosSessionValid(session);
if (retBool == false) {
if (elosLoggingEnabled) safuLogErr("Invalid session");
} else if ((filterRule == NULL) || (eventVector == NULL)) {
if (elosLoggingEnabled) safuLogErr("Invalid parameter");
json_object *newJsonRequest = json_object_new_object();
if (newJsonRequest == NULL) {
if (elosLoggingEnabled) safuLogErr("json_object_new_object failed!");
} else {
json_object *jRequest = NULL;
json_object *jsonAttribute = NULL;
jsonAttribute = safuJsonAddNewString(newJsonRequest, "filter", filterRule);
if (jsonAttribute == NULL) {
if (elosLoggingEnabled) safuLogErr("safuJsonAddNewString failed!");
} else {
jsonAttribute = safuJsonAddNewTimestamp(newJsonRequest, "newest", newest);
if (jsonAttribute == NULL) {
if (elosLoggingEnabled) safuLogErr("safuJsonAddNewTimestamp failed!");
} else {
jsonAttribute = safuJsonAddNewTimestamp(newJsonRequest, "oldest", oldest);
if (jsonAttribute == NULL) {
if (elosLoggingEnabled) safuLogErr("safuJsonAddNewTimestamp failed!");
}
}
}

jRequest = json_object_new_object();
if (!jRequest) {
if (elosLoggingEnabled) safuLogErr("json_object_new_object failed!");
if (jsonAttribute == NULL) {
json_object_put(newJsonRequest);
} else {
json_object *filterRuleComplete = NULL;
*jRequest = newJsonRequest;
result = SAFU_RESULT_OK;
}
}

return result;
}

static safuResultE_t _readFindEventResponse(json_object *jResponse, elosEventVector_t **eventVector,
bool *isTruncated) {
safuResultE_t result = SAFU_RESULT_FAILED;

filterRuleComplete = safuJsonAddNewString(jRequest, "filter", filterRule);
if (!filterRuleComplete) {
if (elosLoggingEnabled) safuLogErr("safuJsonAddNewString failed!");
json_object *jIsTruncated = safuJsonGetObject(jResponse, "isTruncated", 0);
if (jIsTruncated != NULL && json_object_get_type(jIsTruncated) == json_type_boolean) {
*isTruncated = json_object_get_boolean(jIsTruncated);
} else {
*isTruncated = false;
}

json_object *eventVecJarr = safuJsonGetArray(jResponse, "eventArray", 0, NULL);
if (!eventVecJarr) {
if (elosLoggingEnabled) safuLogErr("Failed to read event vector json object!");
} else {
elosEventVector_t *newEventVector = NULL;

result = elosEventVectorFromJsonArray(eventVecJarr, &newEventVector);
if (result == SAFU_RESULT_FAILED) {
if (elosLoggingEnabled) safuLogErr("Failed to read event vector json object!");
} else {
if (*eventVector == NULL) {
*eventVector = newEventVector;
} else {
uint8_t const messageId = ELOS_MESSAGE_LOG_FIND_EVENT;
json_object *jResponse;
safuResultE_t retResult;
size_t eventCount = safuVecElements(newEventVector);
for (size_t i = 0; i < eventCount; i++) {
elosEventVectorPush(*eventVector, safuVecGet(newEventVector, i));
}
safuVecFree(newEventVector);
free(newEventVector);
}
result = SAFU_RESULT_OK;
}
}
return result;
}

safuResultE_t elosFindEvents(elosSession_t *session, const char *filterRule, struct timespec const *newest,
struct timespec const *oldest, elosEventVector_t **eventVector) {
safuResultE_t result = SAFU_RESULT_FAILED;
bool retBool;
bool isTruncated = false;

retBool = elosSessionValid(session);
if (retBool == false) {
if (elosLoggingEnabled) safuLogErr("Invalid session");
} else if ((filterRule == NULL) || (eventVector == NULL) || (newest == NULL) || (oldest == NULL)) {
if (elosLoggingEnabled) safuLogErr("Invalid parameter");
} else {
struct timespec currentOldest = *oldest;
do {
json_object *jRequest = NULL;
result = _createFindEventRequest(filterRule, newest, &currentOldest, &jRequest);
if (result == SAFU_RESULT_OK) {
if (elosLoggingEnabled) safuLogDebugF("will send filter rule: %s", filterRule);
retResult = elosSendAndReceiveJsonMessage(session, messageId, jRequest, &jResponse);
if (retResult != SAFU_RESULT_OK) {

json_object *jResponse = NULL;
result = elosSendAndReceiveJsonMessage(session, ELOS_MESSAGE_LOG_FIND_EVENT, jRequest, &jResponse);
if (result != SAFU_RESULT_OK) {
if (elosLoggingEnabled) safuLogErr("Communication with elosd failed!");
} else {
json_object *eventVecJarr = safuJsonGetArray(jResponse, "eventArray", 0, NULL);
if (!eventVecJarr) {
if (elosLoggingEnabled) safuLogErr("Failed to read event vector json object!");
} else {
elosEventVector_t *newEventVector = NULL;

retResult = elosEventVectorFromJsonArray(eventVecJarr, &newEventVector);
if (retResult == SAFU_RESULT_FAILED) {
if (elosLoggingEnabled) safuLogErr("Failed to read event vector json object!");
} else {
*eventVector = newEventVector;
result = SAFU_RESULT_OK;
}
result = _readFindEventResponse(jResponse, eventVector, &isTruncated);
if (result == SAFU_RESULT_OK && isTruncated) {
elosEvent_t *lastEvent = safuVecGetLast(*eventVector);
currentOldest = lastEvent->date;
}
json_object_put(jResponse);
}
}

json_object_put(jRequest);
}
json_object_put(jRequest);
}
} while (isTruncated);
}

return result;
Expand Down
27 changes: 27 additions & 0 deletions src/libelos/public/elos/libelos/libelos.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,9 @@ safuResultE_t elosEventQueueRead(elosSession_t *session, elosEventQueueId_t even
* - In case no events are in the log, the vector parameter won't be changed.
* - The memory of the event vector will be allocated by the library
* and must be freed afterwards with elosEventVectorDelete().
*
* Warning: Deprecated and can be removed without further notice. Use `elosFindEvents` instead.
*
* Input:
* - **session**: session data structure
* - **filterRule**: filter rule for entry selection
Expand All @@ -167,6 +170,30 @@ safuResultE_t elosEventQueueRead(elosSession_t *session, elosEventQueueId_t even
******************************************************************/
safuResultE_t elosLogFindEvent(elosSession_t *session, const char *filterRule, elosEventVector_t **eventVector);

/*******************************************************************
* Function: elosFindEvents
*------------------------------------------------------------------
* Description:
* Fetches all logged events based on the used filter (e.g. based on payload or other data).
*
* - In case no events are in the log, the vector parameter won't be changed.
* - The memory of the event vector will be allocated by the library
* and must be freed afterwards with elosEventVectorDelete().
*
*
* Input:
* - **session**: session data structure
* - **filterRule**: filter rule for entry selection
* - **newest**: time of the earliest event to look for
* - **oldest**: time of the oldest event to look for
* Output:
* - **vector**: list of event structs
* Returns:
* - `SAFU_RESULT_OK` for success or `SAFU_RESULT_FAILED` on failure
******************************************************************/
safuResultE_t elosFindEvents(elosSession_t *session, const char *filterRule, struct timespec const *newest,
struct timespec const *oldest, elosEventVector_t **eventVector);

/*******************************************************************
* Function: elosSessionValid
*------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Suite Teardown Close All Connections
@{MESSAGES} {"messageCode": 4,"payload":"testEventFiltering"}
... {"messageCode": 40,"payload":"testEventFiltering"}
... {"messageCode": 400,"payload":"testEventFiltering"}
${SEARCH_STRING} "log event find failed"
${SEARCH_STRING} "event find failed"
@{PUBLISH_LOG} @{EMPTY}


Expand Down
1 change: 1 addition & 0 deletions test/utest/libelos/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ add_subdirectory(elosEventQueueRead)
add_subdirectory(elosEventSubscribe)
add_subdirectory(elosEventUnsubscribe)
add_subdirectory(elosLogFindEvent)
add_subdirectory(elosFindEvents)
add_subdirectory(elosSessionValid)

add_subdirectory(private)
24 changes: 24 additions & 0 deletions test/utest/libelos/elosFindEvents/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# SPDX-License-Identifier: MIT
find_package(safu 0.56.2 REQUIRED)
find_package(cmocka_mocks 0.54.2 REQUIRED)

create_unit_test(
NAME
test_libelos_elosFindEvents_utest
SOURCES
case_err_invalid_parameter.c
case_exterr_verify_session.c
case_exterr_new_object.c
case_exterr_add_new_string.c
case_exterr_add_new_timestamp.c
case_exterr_comm_failed.c
case_exterr_vector_from_json_arr.c
case_success.c
case_success_truncated.c
elosFindEvents_utest.c
LIBRARIES
mock_elos_event_static
mock_libelos_static
cmocka_mocks::mock_jsonc
safu::mock_safu
)
41 changes: 41 additions & 0 deletions test/utest/libelos/elosFindEvents/case_err_invalid_parameter.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// SPDX-License-Identifier: MIT

#include "elosFindEvents_utest.h"

int elosTestElosFindEventsErrInvalidParameterSetup(UNUSED void **state) {
return 0;
}

int elosTestElosFindEventsErrInvalidParameterTeardown(UNUSED void **state) {
return 0;
}

void elosTestElosFindEventsErrInvalidParameter(UNUSED void **state) {
TEST("elosFindEvents");
SHOULD("%s", "return SAFU_RESULT_FAILED when any of the parameters is null");

elosSession_t session = {.connected = true};
const char filterRule[] = ".event.name 'sshd' STRCMP";
struct timespec newest = {.tv_sec = 0, .tv_nsec = 0};
struct timespec oldest = {.tv_sec = 0, .tv_nsec = 0};
elosEventVector_t *eventVector = NULL;
safuResultE_t result = SAFU_RESULT_FAILED;

PARAM("'session' is NULL");
result = elosFindEvents(NULL, filterRule, &newest, &oldest, &eventVector);
assert_int_equal(result, SAFU_RESULT_FAILED);

PARAM("'filterRule' is NULL");
result = elosFindEvents(&session, NULL, &newest, &oldest, &eventVector);
assert_int_equal(result, SAFU_RESULT_FAILED);

PARAM("'newest' is NULL");
result = elosFindEvents(&session, filterRule, NULL, &oldest, &eventVector);
assert_int_equal(result, SAFU_RESULT_FAILED);
PARAM("'oldest' is NULL");
result = elosFindEvents(&session, filterRule, &newest, NULL, &eventVector);
assert_int_equal(result, SAFU_RESULT_FAILED);
PARAM("'eventVector' is NULL");
result = elosFindEvents(&session, filterRule, &newest, &oldest, NULL);
assert_int_equal(result, SAFU_RESULT_FAILED);
}
Loading

0 comments on commit 0ebb07b

Please sign in to comment.