diff options
author | Stefan Vacek <stefan.vacek@intel.com> | 2015-08-26 17:28:54 +0200 |
---|---|---|
committer | Alexander Wenzel <Alexander.AW.Wenzel@bmw.de> | 2015-10-07 10:35:41 +0200 |
commit | c3b53f8805236cb7c72eb62ef04866f34de33103 (patch) | |
tree | 956eec44e2d0b2ec309904f15321565a3fae4e3d | |
parent | 2f334a851fa1b39cab74724f3d0a0565f86c27b4 (diff) | |
download | DLT-daemon-c3b53f8805236cb7c72eb62ef04866f34de33103.tar.gz |
Add env-var to set initial log-levels
name of environment variable: DLT_INITIAL_LOG_LEVEL
Syntax:
<apid1>:<ctid1>:<loglevel1>;<apid2>:<ctid2>:<loglevel2>;...
apid: application id (up to 4 chars), if empty all applications will match
ctid: context id (up to 4 chars), if empty all contexts will match
loglevel: either -1..6 or a symbolic name (default, off, fatal, error,
warning, info, debug, verbose)
Examples:
DLT_INITIAL_LOG_LEVEL=TEST:LOG:0
-> turn off logging for appid TEST and contextid LOG
DLT_INITIAL_LOG_LEVEL=:LOG:warn
-> for contexts with name "LOG" set log-level to warning (3)
DLT_INITIAL_LOG_LEVEL=::VERBOSE
-> set log-level of all contexts to VERBOSE
DLT_INITIAL_LOG_LEVEL=::VERBOSE;TEST:LOG:3
-> set log-level of all contexts to VERBOSE except TEST:LOG, set this to WARNING
dlt-example-user: add option -l to specify log-level to be used when sending messages
Signed-off-by: Stefan Vacek <stefan.vacek@intel.com>
-rw-r--r-- | include/dlt/dlt_user.h | 74 | ||||
-rw-r--r-- | src/examples/dlt-example-user.c | 21 | ||||
-rw-r--r-- | src/lib/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/lib/dlt_env_ll.c | 560 | ||||
-rw-r--r-- | src/lib/dlt_user.c | 42 | ||||
-rwxr-xr-x | src/tests/dlt-test-change-ll-through-env.sh | 59 | ||||
-rw-r--r-- | tests/CMakeLists.txt | 2 | ||||
-rw-r--r-- | tests/dlt_env_ll_unit_test.cpp | 540 |
8 files changed, 1264 insertions, 36 deletions
diff --git a/include/dlt/dlt_user.h b/include/dlt/dlt_user.h index 66a869b..baa5746 100644 --- a/include/dlt/dlt_user.h +++ b/include/dlt/dlt_user.h @@ -176,11 +176,11 @@ typedef enum */ typedef struct { - char contextID[4]; /**< context id */ - int32_t log_level_pos; /**< offset in user-application context field */ - int8_t *log_level_ptr; /**< pointer to the log level */ - int8_t *trace_status_ptr; /**< pointer to the trace status */ - uint8_t mcnt; /**< message counter */ + char contextID[DLT_ID_SIZE]; /**< context id */ + int32_t log_level_pos; /**< offset in user-application context field */ + int8_t *log_level_ptr; /**< pointer to the log level */ + int8_t *trace_status_ptr; /**< pointer to the trace status */ + uint8_t mcnt; /**< message counter */ } DltContext; /** @@ -231,6 +231,28 @@ typedef struct } dlt_ll_ts_type; /** + * @brief holds initial log-level for given appId:ctxId pair + */ +typedef struct +{ + char appId[DLT_ID_SIZE]; + char ctxId[DLT_ID_SIZE]; + int8_t ll; +} dlt_env_ll_item; + + +/** + * @brief holds all initial log-levels given via environment variable DLT_INITIAL_LOG_LEVEL + */ +typedef struct +{ + dlt_env_ll_item * item; + size_t array_size; + size_t num_elem; +} dlt_env_ll_set; + + +/** * This structure is used once for one application. */ typedef struct @@ -278,6 +300,8 @@ typedef struct // Buffer used for resending, locked by DLT semaphore uint8_t resend_buffer[DLT_USER_RESENDBUF_MAX_SIZE]; + dlt_env_ll_set initial_ll_set; + #ifdef DLT_SHM_ENABLE DltShm dlt_shm; #endif @@ -491,7 +515,7 @@ int dlt_user_trace_network_truncated(DltContext *handle, DltNetworkTraceType nw_ int dlt_user_trace_network_segmented(DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len, void *payload); /************************************************************************************************** - * The folowing API functions define a high level function interface for DLT + * The following API functions define a high level function interface for DLT **************************************************************************************************/ /** @@ -556,9 +580,9 @@ int dlt_register_context(DltContext *handle, const char *contextid, const char * * @param contextid four byte long character array with the context id * @param description long name of the context * @param loglevel This is the log level to be pre-set for this context - (DLT_LOG_DEFAULT is not allowed here) + (DLT_LOG_DEFAULT is not allowed here) * @param tracestatus This is the trace status to be pre-set for this context - (DLT_TRACE_STATUS_DEFAULT is not allowed here) + (DLT_TRACE_STATUS_DEFAULT is not allowed here) * @return negative value if there was an error */ int dlt_register_context_ll_ts(DltContext *handle, const char *contextid, const char * description, int loglevel, int tracestatus); @@ -670,6 +694,40 @@ int dlt_with_ecu_id(int8_t with_ecu_id); */ int dlt_set_application_ll_ts_limit(DltLogLevelType loglevel, DltTraceStatusType tracestatus); + +/** + * @brief adjust log-level based on values given through environment + * + * Iterate over the set of items, and find the best match. + * For any item that matches, the one with the highest priority is selected and that + * log-level is returned. + * + * Priorities are determined as follows: + * - no apid, no ctid only ll given in item: use ll with prio 1 + * - no apid, ctid matches: use ll with prio 2 + * - no ctid, apid matches: use ll with prio 3 + * - apid, ctid matches: use ll with prio 4 + * + * If no item matches or in case of error, the original log-level (\param ll) is returned + */ +int dlt_env_adjust_ll_from_env(dlt_env_ll_set const * const ll_set, char const * const apid, char const * const ctid, int const ll); + +/** + * @brief extract log-level settings from given string + * + * Scan \param env for setttings like apid:ctid:log-level and store them + * in given \param ll_set + * + * @param env reference to a string to be parsed, after parsing env will point after the last parse character + * @param ll_set set of log-level extracted from given string + * + * @return 0 on success + * @return -1 on failure + */ +int dlt_env_extract_ll_set(char ** const env, dlt_env_ll_set * const ll_set); + +void dlt_env_free_ll_set(dlt_env_ll_set * const ll_set); + /** * Enable local printing of messages * diff --git a/src/examples/dlt-example-user.c b/src/examples/dlt-example-user.c index e428047..5f4abc9 100644 --- a/src/examples/dlt-example-user.c +++ b/src/examples/dlt-example-user.c @@ -101,6 +101,7 @@ void usage() printf(" -a Enable local printing of DLT messages (Default: disabled)\n"); printf(" -k Send marker message\n"); printf(" -m mode Set log mode 0=off,1=external,2=internal,3=both\n"); + printf(" -l level Set log level to <level>, level=-1..6\n"); #ifdef DLT_TEST_ENABLE printf(" -c Corrupt user header\n"); printf(" -s size Corrupt message size\n"); @@ -126,6 +127,7 @@ int main(int argc, char* argv[]) char *nvalue = 0; char *mvalue = 0; char *message = 0; + int lvalue = DLT_LOG_WARN; int index; int c; @@ -138,9 +140,9 @@ int main(int argc, char* argv[]) opterr = 0; #ifdef DLT_TEST_ENABLE - while ((c = getopt (argc, argv, "vgakcd:f:n:m:z:s:")) != -1) + while ((c = getopt (argc, argv, "vgakcd:f:n:m:z:s:l:")) != -1) #else - while ((c = getopt (argc, argv, "vgakd:f:n:m:")) != -1) + while ((c = getopt (argc, argv, "vgakd:f:n:m:l:")) != -1) #endif /* DLT_TEST_ENABLE */ { switch (c) @@ -197,9 +199,14 @@ int main(int argc, char* argv[]) mvalue = optarg; break; } + case 'l': + { + lvalue = atoi(optarg); + break; + } case '?': { - if (optopt == 'd' || optopt == 'f' || optopt == 'n') + if (optopt == 'd' || optopt == 'f' || optopt == 'n'|| optopt == 'l') { fprintf (stderr, "Option -%c requires an argument.\n", optopt); } @@ -239,7 +246,7 @@ int main(int argc, char* argv[]) if (fvalue) { - /* DLT is intialised automatically, except another output target will be used */ + /* DLT is initialized automatically, except another output target will be used */ if (dlt_init_file(fvalue)<0) /* log to file */ { return -1; @@ -262,7 +269,7 @@ int main(int argc, char* argv[]) if(mvalue) { printf("Set log mode to %d\n",atoi(mvalue)); - dlt_set_log_mode(atoi(mvalue)); + dlt_set_log_mode(atoi(mvalue)); } @@ -354,12 +361,12 @@ int main(int argc, char* argv[]) if (gflag) { /* Non-verbose mode */ - DLT_LOG_ID(mycontext,DLT_LOG_WARN,num,DLT_INT(num),DLT_STRING(text)); + DLT_LOG_ID(mycontext,lvalue,num,DLT_INT(num),DLT_STRING(text)); } else { /* Verbose mode */ - DLT_LOG(mycontext,DLT_LOG_WARN,DLT_INT(num),DLT_STRING(text)); + DLT_LOG(mycontext,lvalue,DLT_INT(num),DLT_STRING(text)); } if (delay>0) diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 11f314b..02b39fe 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -15,7 +15,7 @@ # @licence end@ ####### -set(dlt_LIB_SRCS dlt_user dlt_client dlt_filetransfer ${CMAKE_SOURCE_DIR}/src/shared/dlt_common.c ${CMAKE_SOURCE_DIR}/src/shared/dlt_user_shared.c ${CMAKE_SOURCE_DIR}/src/shared/dlt_shm.c) +set(dlt_LIB_SRCS dlt_user dlt_client dlt_filetransfer dlt_env_ll ${CMAKE_SOURCE_DIR}/src/shared/dlt_common.c ${CMAKE_SOURCE_DIR}/src/shared/dlt_user_shared.c ${CMAKE_SOURCE_DIR}/src/shared/dlt_shm.c) add_library(dlt ${dlt_LIB_SRCS}) target_link_libraries(dlt rt ${CMAKE_THREAD_LIBS_INIT}) diff --git a/src/lib/dlt_env_ll.c b/src/lib/dlt_env_ll.c new file mode 100644 index 0000000..d2ef7b1 --- /dev/null +++ b/src/lib/dlt_env_ll.c @@ -0,0 +1,560 @@ +/** + * @licence app begin@ + * Copyright (C) 2015 Intel Corporation + * + * This file is part of GENIVI Project Dlt - Diagnostic Log and Trace console apps. + * + * Contributions are licensed to the GENIVI Alliance under one or more + * Contribution License Agreements. + * + * \copyright + * This Source Code Form is subject to the terms of the + * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with + * this file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * + * \author Stefan Vacek <stefan.vacek@intel.com> Intel Corporation + * + * \file dlt_env_ll.c + * For further information see http://www.genivi.org/. + * @licence end@ + */ + +#include "dlt_user.h" +#include <string.h> +#include <stdlib.h> + +#define DLT_ENV_LL_SET_INCREASE 10 + + +/* a generic entry looks like: + * ll_item ::= apid:ctid:ll + * ll_set ::= ll_item | + * ll_set;ll_item + */ + +/** + * @brief extract id out of given string + * + * Extract 4-byte string out of given environment string, the pointer of the + * environment string is moved to the next un-used character and the extracted + * id is copied into \param id + * + * Example: + * env[] = "abcd:1234:3" + * char res[4u]; + * char * tmp = &env[0]; + * int ret = extract_id(&tmp, res); + * assert(ret == 0); + * assert(*tmp == ':'); + * assert(res[3] == 'd'); + * + * @return 0 if successful, -1 else + */ +int dlt_env_extract_id(char ** const env, char * id) +{ + int i; + if (!env || !id) + { + return -1; + } + + if (!(*env)) + { + return -1; + } + + memset(id, 0, 4); + + for (i = 0; (i<4) && (**env != ':') && (**env != 0); ++i) + { + *id++ = *((*env)++); + } + + /* the next/last character must be ':' */ + if ((0 != **env) && (':' == **env)) + { + return 0; + } + + return -1; +} + + +/** + * @brief convert a given string to lower-case + * + * Stops end of string or if ';' is detected + */ +int dlt_env_helper_to_lower(char ** const env, char *result, int const res_len) +{ + int count = 0; + char ch = *(*env); + + if (!env || !result) + { + return -1; + } + + if (!(*env)) + { + return -1; + } + + count = 0; + ch = *(*env); + while (ch && (count < res_len-1) && (ch != ';')) + { + if (ch >= 'A' && ch <= 'Z') + { + result[count] = ch + 'a' - 'A'; + } + else + { + result[count] = ch; + } + ch = *(++(*env)); + ++count; + } + + result[count] = 0; + if (!ch || (ch == ';')) /* full input was parsed */ + { + return 0; + } + else + { + return -1; + } +} + + +int dlt_env_extract_symbolic_ll(char ** const env, int8_t * ll) +{ + char result[strlen("verbose")+1]; + if (!env || !ll) + { + return -1; + } + + if (!(*env)) + { + return -1; + } + + if (dlt_env_helper_to_lower(env, &result[0], sizeof(result)) == 0) + { + if (strncmp("default", result, sizeof(result)) == 0) + { + *ll = -1; + } + else if (strncmp("off", result, sizeof(result)) == 0) + { + *ll = 0; + } + else if (strncmp("fatal", result, sizeof(result)) == 0) + { + *ll = 1; + } + else if (strncmp("error", result, sizeof(result)) == 0) + { + *ll = 2; + } + else if (strncmp("warning", result, sizeof(result)) == 0) + { + *ll = 3; + } + else if (strncmp("info", result, sizeof(result)) == 0) + { + *ll = 4; + } + else if (strncmp("debug", result, sizeof(result)) == 0) + { + *ll = 5; + } + else if (strncmp("verbose", result, sizeof(result)) == 0) + { + *ll = 6; + } + else + { + return -1; + } + + if (**env != 0) + { + (*env)++; + } + return 0; + } + else + { + return -1; + } + +} + + +/** + * @brief extract log-level out of given string + * + * A valid log-level is a numeric value in the range of -1 .. 6, with: + * -1: default + * 0: off + * 1: fatal + * 2: error + * 3: warning + * 4: info + * 5: debug + * 6: verbose + * During parsing, the environment string is moved to the next un-used character and the extracted + * log-level is written into \param ll + * + * Example: + * env[] = "abcd:1234:6" + * int ll; + * char ** tmp = &env[10]; // tmp points to '6'! + * int ret = extract_ll(&tmp, &ll); + * assert(ret == 0); + * assert(*tmp == NULL); + * assert(ll == 6); + * + * @return 0 if successful, -1 else + */ +int dlt_env_extract_ll(char ** const env, int8_t * ll) +{ + if (!env || !ll) + { + return -1; + } + + if (!(*env)) + { + return -1; + } + + /* extract number */ + if (**env == '-') + { + (*env)++; + if (**env == '1') + { + *ll = -1; + (*env)++; + } + } + else + { + if ((**env >= '0') && (**env < '7')) + { + *ll = **env - '0'; + (*env)++; + } + else + { + if (dlt_env_extract_symbolic_ll(env, ll) != 0) + { + return -1; + } + } + } + + /* check end, either next char is NULL or ';' */ + if ((**env == ';') || (**env == 0)) + { + return 0; + } + + return -1; +} + + +/** + * @brief extract one item out of string + * + * @return 0 if successful, -1 else + */ +int dlt_env_extract_ll_item(char ** const env, dlt_env_ll_item * const item) +{ + int ret = -1; + if (!env || !item) + { + return -1; + } + + if (!(*env)) + { + return -1; + } + + memset(item, 0, sizeof(dlt_env_ll_item)); + ret = dlt_env_extract_id(env, item->appId); + if (ret == -1) + { + return -1; + } + + (*env)++; + ret = dlt_env_extract_id(env, item->ctxId); + if (ret == -1) + { + return -1; + } + + (*env)++; + ret = dlt_env_extract_ll(env, &item->ll); + if (ret == -1) + { + return -1; + } + + return 0; +} + + +/** + * @brief initialize ll_set + * + * Must call release_ll_set before exit to release all memory + * + * @return -1 if memory could not be allocated + * @return 0 on success + */ +int dlt_env_init_ll_set(dlt_env_ll_set * const ll_set) +{ + if (!ll_set) + { + return -1; + } + + ll_set->array_size = DLT_ENV_LL_SET_INCREASE; + ll_set->item = (dlt_env_ll_item *)malloc(sizeof(dlt_env_ll_item) * ll_set->array_size); + if (!ll_set->item) + { + /* should trigger a warning: no memory left */ + ll_set->array_size = 0; + return -1; + } + ll_set->num_elem = 0u; + return 0; +} + + +/** + * @brief release ll_set + */ +void dlt_env_free_ll_set(dlt_env_ll_set * const ll_set) +{ + if (!ll_set) + { + return; + } + + free(ll_set->item); + ll_set->item = NULL; + ll_set->array_size = 0u; + ll_set->num_elem = 0u; +} + + +/** + * @brief increase size of ll_set by LL_SET_INCREASE elements + * + * @return -1 if memory could not be allocated + * @return 0 on success + */ +int dlt_env_increase_ll_set(dlt_env_ll_set * const ll_set) +{ + dlt_env_ll_item * old_set; + size_t old_size; + + if (!ll_set) + { + return -1; + } + + old_set = ll_set->item; + old_size = ll_set->array_size; + + ll_set->array_size += DLT_ENV_LL_SET_INCREASE; + ll_set->item = (dlt_env_ll_item *)malloc(sizeof(dlt_env_ll_item) * ll_set->array_size); + if (!ll_set->item) + { + /* should trigger a warning: no memory left */ + ll_set->array_size -= DLT_ENV_LL_SET_INCREASE; + return -1; + } + else + { + memcpy(ll_set->item, old_set, sizeof(dlt_env_ll_item)*old_size); + free(old_set); + return 0; + } +} + + +/** + * @brief extract all items out of string + * + * The given set is initialized within this function (memory is allocated). + * Make sure, that the caller frees this memory when it is no longer needed! + * + * @return 0 if successful, -1 else + */ +int dlt_env_extract_ll_set(char ** const env, dlt_env_ll_set * const ll_set) +{ + if (!env || !ll_set) + { + return -1; + } + + if (!(*env)) + { + return -1; + } + + if (dlt_env_init_ll_set(ll_set) == -1) + { + return -1; + } + + do + { + if (ll_set->num_elem == ll_set->array_size) + { + if (dlt_env_increase_ll_set(ll_set) == -1) + { + return -1; + } + } + + if (dlt_env_extract_ll_item(env, &ll_set->item[ll_set->num_elem++]) == -1) + { + return -1; + } + if (**env == ';') + { + (*env)++; + } + } while (**env != 0); + + return 0; +} + + +/** + * @brief check if two ids match + * + * @return 1 if matching, 0 if not + */ +int dlt_env_ids_match(char const * const a, char const * const b) +{ + if (a[0] != b[0]) + { + return 0; + } + if (a[1] != b[1]) + { + return 0; + } + if (a[2] != b[2]) + { + return 0; + } + if (a[3] != b[3]) + { + return 0; + } + + return 1; +} + + +/** + * @brief check if (and how) apid and ctid match with given item + * + * Resulting priorities: + * - no apid, no ctid only ll given in item: use ll with prio 1 + * - no apid, ctid matches: use ll with prio 2 + * - no ctid, apid matches: use ll with prio 3 + * - apid, ctid matches: use ll with prio 4 + * + * In case of error, -1 is returned. + */ +int dlt_env_ll_item_get_matching_prio(dlt_env_ll_item const * const item, char const * const apid, char const * const ctid) +{ + if ((!item) || (!apid) || (!ctid)) + { + return -1; + } + + if (item->appId[0] == 0) + { + if (item->ctxId[0] == 0) + { + return 1; + } + else + { + if (dlt_env_ids_match(item->ctxId, ctid)) + { + return 2; + } + } + } + else + { + if (dlt_env_ids_match(item->appId, apid)) + { + if (item->ctxId[0] == 0) + { + return 3; + } + else if (dlt_env_ids_match(item->ctxId, ctid)) + { + return 4; + } + } + } + + return 0; +} + + +/** + * @brief adjust log-level based on values given through environment + * + * Iterate over the set of items, and find the best match (\see ll_item_get_matching_prio) + * For any item that matches, the one with the highest priority is selected and that + * log-level is returned. + * + * If no item matches or in case of error, the original log-level (\param ll) is returned + */ +int dlt_env_adjust_ll_from_env(dlt_env_ll_set const * const ll_set, char const * const apid, char const * const ctid, int const ll) +{ + if ((!ll_set) || (!apid) || (!ctid)) + { + return ll; + } + + int res = ll; + int prio = 0; /* no match so far */ + size_t i; + for (i = 0; i<ll_set->num_elem; ++i) + { + int p = dlt_env_ll_item_get_matching_prio(&ll_set->item[i], apid, ctid); + if (p > prio) + { + prio = p; + res = ll_set->item[i].ll; + if (p == 4) /* maximum reached, immediate return */ + { + return res; + } + } + } + + return res; +} + + diff --git a/src/lib/dlt_user.c b/src/lib/dlt_user.c index e1f46ca..e4d13bb 100644 --- a/src/lib/dlt_user.c +++ b/src/lib/dlt_user.c @@ -411,6 +411,7 @@ int dlt_init_message_queue(void) int dlt_init_common(void) { char *env_local_print; + char * env_initial_log_level; /* Binary semaphore for threads */ if (sem_init(&dlt_mutex, 0, 1)==-1) @@ -467,6 +468,16 @@ int dlt_init_common(void) } } + env_initial_log_level = getenv("DLT_INITIAL_LOG_LEVEL"); + if( env_initial_log_level != NULL ) + { + if (dlt_env_extract_ll_set(&env_initial_log_level, &dlt_user.initial_ll_set) != 0) + { + snprintf(str, DLT_USER_BUFFER_LENGTH, "Unable to parse initial set of log-levels from environment! Env:\n%s\n", getenv("DLT_INITIAL_LOG_LEVEL")); + dlt_log(LOG_WARNING, str); + } + } + /* Initialize LogLevel/TraceStatus field */ DLT_SEM_LOCK(); dlt_user.dlt_ll_ts = 0; @@ -650,6 +661,8 @@ int dlt_free(void) dlt_user.dlt_ll_ts_max_num_entries = 0; dlt_user.dlt_ll_ts_num_entries = 0; } + + dlt_env_free_ll_set(&dlt_user.initial_ll_set); DLT_SEM_FREE(); char queue_name[NAME_MAX]; @@ -982,9 +995,13 @@ int dlt_register_context_ll_ts(DltContext *handle, const char *contextid, const } if (loglevel!=DLT_USER_LOG_LEVEL_NOT_SET) - { - dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].log_level = loglevel; - } + { + dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].log_level = dlt_env_adjust_ll_from_env(&dlt_user.initial_ll_set, dlt_user.appID, contextid, loglevel); + } + else + { + dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].log_level = dlt_env_adjust_ll_from_env(&dlt_user.initial_ll_set, dlt_user.appID, contextid, dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].log_level); + } if (tracestatus!=DLT_USER_TRACE_STATUS_NOT_SET) { @@ -1004,23 +1021,8 @@ int dlt_register_context_ll_ts(DltContext *handle, const char *contextid, const *(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].log_level_ptr) = dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].log_level; *(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].trace_status_ptr) = dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].trace_status = tracestatus; - if (loglevel!=DLT_USER_LOG_LEVEL_NOT_SET) - { - log.log_level = loglevel; - } - else - { - log.log_level = DLT_USER_LOG_LEVEL_NOT_SET; - } - - if (tracestatus!=DLT_USER_TRACE_STATUS_NOT_SET) - { - log.trace_status = tracestatus; - } - else - { - log.trace_status = DLT_USER_TRACE_STATUS_NOT_SET; - } + log.log_level = dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].log_level; + log.trace_status = dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].trace_status; dlt_user.dlt_ll_ts_num_entries++; diff --git a/src/tests/dlt-test-change-ll-through-env.sh b/src/tests/dlt-test-change-ll-through-env.sh new file mode 100755 index 0000000..0a469cc --- /dev/null +++ b/src/tests/dlt-test-change-ll-through-env.sh @@ -0,0 +1,59 @@ +#!/bin/bash + +# check if dlt-daemon is running +daemon_running=`/usr/bin/ps -C dlt-daemon | wc -l` +daemon_pid=0 + +if [ "$daemon_running" -lt "2" ]; then + echo "No daemon running, starting one myself" + /usr/bin/dlt-daemon > /tmp/dlt_daemon_dlt_receiver_test.txt & + daemon_pid=$! + echo "daemon pid: " ${daemon_pid} +else + echo "dlt-daemon already running" +fi + +# create a directory in /tmp where all logs will be stored +output_dir=`mktemp -d /tmp/DLT_TESTING_XXXXXX` +echo "Using directory " ${output_dir} + +# start dlt-receive (in background) and store PID +echo "Starting dlt-receive" +/usr/bin/dlt-receive -o ${output_dir}/dlt_test.dlt localhost & +dlt_receive_pid=$! +disown + +# start dlt-example-user to create some logs +# sleep time: 100ms +# number of messages: 10 +/usr/bin/dlt-example-user -d 100 -n 10 TEST_MESSAGE_ONE + +# stop dlt-receive +kill ${dlt_receive_pid} + +# show content of /tmp +echo "log-file after first run" +ls -l ${output_dir} + +# start dlt-receive (in background) and store PID +echo "Starting dlt-receive" +/usr/bin/dlt-receive -o ${output_dir}/dlt_test_no_log.dlt localhost & +dlt_receive_pid=$! +disown + +# start dlt-example-user to create some logs, disable logging through environment variable +DLT_INITIAL_LOG_LEVEL=::-1 /usr/bin/dlt-example-user -d 100 -n 10 TEST_MESSAGE_TWO + +# show content of /tmp, log should not contain log messages from dlt-example-user (TEST_MESSAGE_TWO) +kill ${dlt_receive_pid} +echo "log-file after second run" +ls -l ${output_dir} + +# directory will not be cleaned up +echo "Used directory " ${output_dir} + + +if [ "${daemon_pid}" -ne "0" ]; then + sleep 1 + kill ${daemon_pid} +fi diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 5cdc25f..c40e681 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -12,7 +12,9 @@ add_executable(gtest_dlt_common gtest_dlt_common.cpp) add_executable(gtest_dlt_user gtest_dlt_user.cpp) add_executable(gtest_dlt_daemon_common gtest_dlt_daemon_common.cpp ../src/daemon/dlt_daemon_common.c) add_executable(dlt_test_receiver dlt_test_receiver.c) +add_executable(dlt_env_ll_unit_test dlt_env_ll_unit_test.cpp) target_link_libraries(gtest_dlt_common gtest gtest_main dlt) target_link_libraries(gtest_dlt_user gtest gtest_main dlt) target_link_libraries(gtest_dlt_daemon_common gtest gtest_main dlt) target_link_libraries(dlt_test_receiver dlt) +target_link_libraries(dlt_env_ll_unit_test gtest gtest_main dlt) diff --git a/tests/dlt_env_ll_unit_test.cpp b/tests/dlt_env_ll_unit_test.cpp new file mode 100644 index 0000000..f50e603 --- /dev/null +++ b/tests/dlt_env_ll_unit_test.cpp @@ -0,0 +1,540 @@ +/* +@COPYRIGHT_TAG@ + */ +/** + * @file + */ + + +#include "gtest/gtest.h" +#include "dlt_user.h" +#include "dlt_common.h" /* needed for dlt_set_id */ + +/* simply include the whole file to allow testing it */ +#include "src/lib/dlt_env_ll.c" + + +int main(int argc, char* argv[]) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} + + +TEST(DltExtensionTests, extract_id) +{ + /* testing valid input */ + char id[4u]; + + char env0[] = "abcd:1234:3"; + char *tmp = &env0[0]; + ASSERT_EQ(dlt_env_extract_id(&tmp, id), 0); + ASSERT_EQ(tmp - &env0[0], 4); // moved 4 bytes + ASSERT_EQ(id[0], 'a'); + ASSERT_EQ(id[1], 'b'); + ASSERT_EQ(id[2], 'c'); + ASSERT_EQ(id[3], 'd'); + + char env1[] = "abc:1234:3"; + tmp = &env1[0]; + ASSERT_EQ(dlt_env_extract_id(&tmp, id), 0); + ASSERT_EQ(tmp - &env1[0], 3); // moved 3 bytes + ASSERT_EQ(id[0], 'a'); + ASSERT_EQ(id[1], 'b'); + ASSERT_EQ(id[2], 'c'); + ASSERT_EQ(id[3], 0); + + char env2[] = "ab:1234:3"; + tmp = &env2[0]; + ASSERT_EQ(dlt_env_extract_id(&tmp, id), 0); + ASSERT_EQ(tmp - &env2[0], 2); // moved 2 bytes + ASSERT_EQ(id[0], 'a'); + ASSERT_EQ(id[1], 'b'); + ASSERT_EQ(id[2], 0); + ASSERT_EQ(id[3], 0); + + char env3[] = "a:1234:3"; + tmp = &env3[0]; + ASSERT_EQ(dlt_env_extract_id(&tmp, id), 0); + ASSERT_EQ(tmp - &env3[0], 1); // moved 1 byte + ASSERT_EQ(id[0], 'a'); + ASSERT_EQ(id[1], 0); + ASSERT_EQ(id[2], 0); + ASSERT_EQ(id[3], 0); + + char env4[] = ":1234:3"; + tmp = &env4[0]; + ASSERT_EQ(dlt_env_extract_id(&tmp, id), 0); + ASSERT_EQ(tmp - &env4[0], 0); // moved 1 byte + ASSERT_EQ(id[0], 0); + ASSERT_EQ(id[1], 0); + ASSERT_EQ(id[2], 0); + ASSERT_EQ(id[3], 0); + + char env5[] = "abcd:1234:3;"; + tmp = &env5[0]; + ASSERT_EQ(dlt_env_extract_id(&tmp, id), 0); + ASSERT_EQ(tmp - &env5[0], 4); // moved 4 bytes + ASSERT_EQ(id[0], 'a'); + ASSERT_EQ(id[1], 'b'); + ASSERT_EQ(id[2], 'c'); + ASSERT_EQ(id[3], 'd'); + + + /* testing invalid input */ + /* - string too long: abcde: + * - string too short/missing end: abc + * - NULL string: <null> + */ + tmp = NULL; + ASSERT_EQ(dlt_env_extract_id(&tmp, id), -1); + + char env6[] = "abcd:1234:3"; + tmp = &env6[0]; + ASSERT_EQ(dlt_env_extract_id(&tmp, NULL), -1); + + char invalid0[] = ""; + tmp = &invalid0[0]; + ASSERT_EQ(dlt_env_extract_id(&tmp, id), -1); + + char invalid1[] = "abcd"; /* missing delimiter */ + tmp = &invalid1[0]; + ASSERT_EQ(dlt_env_extract_id(&tmp, id), -1); + + char invalid2[] = "abcde"; /* id too long */ + tmp = &invalid2[0]; + ASSERT_EQ(dlt_env_extract_id(&tmp, id), -1); +} + + +TEST(DltExtensionTests, extract_ll) +{ + /* testing valid input */ + int8_t ll; + + char env_1[] = "-1"; + char *tmp = &env_1[0]; + ASSERT_EQ(dlt_env_extract_ll(&tmp, &ll), 0); + ASSERT_EQ(tmp - &env_1[0], 2); // moved 2 bytes + ASSERT_EQ(ll, -1); + + char env0[] = "0;"; + tmp = &env0[0]; + ASSERT_EQ(dlt_env_extract_ll(&tmp, &ll), 0); + ASSERT_EQ(tmp - &env0[0], 1); // moved 1 byte + ASSERT_EQ(ll, 0); + + char env1[] = "1;"; + tmp = &env1[0]; + ASSERT_EQ(dlt_env_extract_ll(&tmp, &ll), 0); + ASSERT_EQ(tmp - &env1[0], 1); // moved 1 byte + ASSERT_EQ(ll, 1); + + char env2[] = "2;"; + tmp = &env2[0]; + ASSERT_EQ(dlt_env_extract_ll(&tmp, &ll), 0); + ASSERT_EQ(tmp - &env2[0], 1); // moved 1 byte + ASSERT_EQ(ll, 2); + + char env3[] = "3;"; + tmp = &env3[0]; + ASSERT_EQ(dlt_env_extract_ll(&tmp, &ll), 0); + ASSERT_EQ(tmp - &env3[0], 1); // moved 1 byte + ASSERT_EQ(ll, 3); + + char env4[] = "4;"; + tmp = &env4[0]; + ASSERT_EQ(dlt_env_extract_ll(&tmp, &ll), 0); + ASSERT_EQ(tmp - &env4[0], 1); // moved 1 byte + ASSERT_EQ(ll, 4); + + char env5[] = "5;"; + tmp = &env5[0]; + ASSERT_EQ(dlt_env_extract_ll(&tmp, &ll), 0); + ASSERT_EQ(tmp - &env5[0], 1); // moved 1 byte + ASSERT_EQ(ll, 5); + + char env6[] = "6;"; + tmp = &env6[0]; + ASSERT_EQ(dlt_env_extract_ll(&tmp, &ll), 0); + ASSERT_EQ(tmp - &env6[0], 1); // moved 1 byte + ASSERT_EQ(ll, 6); + + /* testing invalid input */ + /* - number outside range, e.g. -2, 103 + * - missing delimiter + * - NULL string: <null> + */ + tmp = NULL; + ASSERT_EQ(dlt_env_extract_ll(&tmp, &ll), -1); + + char env7[] = "abcd:1234:3"; + tmp = &env7[0]; + ASSERT_EQ(dlt_env_extract_id(&tmp, NULL), -1); + + char invalid0[] = ""; + tmp = &invalid0[0]; + ASSERT_EQ(dlt_env_extract_ll(&tmp, &ll), -1); + + char invalid1[] = "-2"; /* outside range */ + tmp = &invalid1[0]; + ASSERT_EQ(dlt_env_extract_ll(&tmp, &ll), -1); + + char invalid2[] = "8"; /* outside range */ + tmp = &invalid2[0]; + ASSERT_EQ(dlt_env_extract_ll(&tmp, &ll), -1); + + char invalid3[] = "1e"; /* missing delimiter */ + tmp = &invalid3[0]; + ASSERT_EQ(dlt_env_extract_ll(&tmp, &ll), -1); +} + + +TEST(DltExtensionTests, extract_ll_item) +{ + /* testing valid input */ + dlt_env_ll_item item; + + char env0[] = "abcd:1234:3"; + char *tmp = &env0[0]; + ASSERT_EQ(dlt_env_extract_ll_item(&tmp, &item), 0); + ASSERT_EQ(tmp - &env0[0], 11); // moved 11 bytes + ASSERT_EQ(item.appId[0], 'a'); + ASSERT_EQ(item.appId[1], 'b'); + ASSERT_EQ(item.appId[2], 'c'); + ASSERT_EQ(item.appId[3], 'd'); + ASSERT_EQ(item.ctxId[0], '1'); + ASSERT_EQ(item.ctxId[1], '2'); + ASSERT_EQ(item.ctxId[2], '3'); + ASSERT_EQ(item.ctxId[3], '4'); + ASSERT_EQ(item.ll, 3); + + char env1[] = "::-1;"; + tmp = &env1[0]; + ASSERT_EQ(dlt_env_extract_ll_item(&tmp, &item), 0); + ASSERT_EQ(tmp - &env1[0], 4); // moved 4 bytes + ASSERT_EQ(item.appId[0], 0); + ASSERT_EQ(item.appId[1], 0); + ASSERT_EQ(item.appId[2], 0); + ASSERT_EQ(item.appId[3], 0); + ASSERT_EQ(item.ctxId[0], 0); + ASSERT_EQ(item.ctxId[1], 0); + ASSERT_EQ(item.ctxId[2], 0); + ASSERT_EQ(item.ctxId[3], 0); + ASSERT_EQ(item.ll, -1); + + /* testing invalid input */ + /* - string too long: abcde: + * - string too short/missing end: abc + * - NULL string: <null> + */ + tmp = NULL; + ASSERT_EQ(dlt_env_extract_ll_item(&tmp, &item), -1); + + char env2[] = "abcd:1234:3"; + tmp = &env2[0]; + ASSERT_EQ(dlt_env_extract_ll_item(&tmp, NULL), -1); + + char invalid0[] = ""; + tmp = &invalid0[0]; + ASSERT_EQ(dlt_env_extract_ll_item(&tmp, &item), -1); + + char invalid1[] = "abcd:1234:"; /* missing ll */ + tmp = &invalid1[0]; + ASSERT_EQ(dlt_env_extract_ll_item(&tmp, &item), -1); + + char invalid2[] = "abcd:1234"; /* missing ll, missing delimiter in ctxId */ + tmp = &invalid2[0]; + ASSERT_EQ(dlt_env_extract_ll_item(&tmp, &item), -1); + + char invalid3[] = "abcd:"; /* missing ll, missing delimiter in appId */ + tmp = &invalid3[0]; + ASSERT_EQ(dlt_env_extract_ll_item(&tmp, &item), -1); + + char invalid4[] = "abcd"; /* missing ll, missing delimiter in appId */ + tmp = &invalid4[0]; + ASSERT_EQ(dlt_env_extract_ll_item(&tmp, &item), -1); +} + + +TEST(DltExtensionTests, basic_ll_set_handling) +{ + dlt_env_init_ll_set(NULL); // must not crash + dlt_env_free_ll_set(NULL); // must not crash + dlt_env_increase_ll_set(NULL); // must not crash + + dlt_env_ll_set ll_set; + dlt_env_init_ll_set(&ll_set); + EXPECT_TRUE(NULL != ll_set.item); + EXPECT_EQ(DLT_ENV_LL_SET_INCREASE, ll_set.array_size); + EXPECT_EQ(0, ll_set.num_elem); + + dlt_env_free_ll_set(&ll_set); + EXPECT_TRUE(NULL == ll_set.item); + EXPECT_EQ(0, ll_set.array_size); + EXPECT_EQ(0, ll_set.num_elem); + + dlt_env_init_ll_set(&ll_set); + for (int i = 0; i<DLT_ENV_LL_SET_INCREASE; ++i) + { + ll_set.item[i].ll = i; + } + dlt_env_increase_ll_set(&ll_set); + EXPECT_EQ(2 * DLT_ENV_LL_SET_INCREASE, ll_set.array_size); + for (int i = 0; i<DLT_ENV_LL_SET_INCREASE; ++i) + { + EXPECT_EQ(ll_set.item[i].ll, i); + } + dlt_env_free_ll_set(&ll_set); + EXPECT_TRUE(NULL == ll_set.item); + EXPECT_EQ(0, ll_set.array_size); + EXPECT_EQ(0, ll_set.num_elem); +} + + +TEST(DltExtensionTests, extract_ll_set) +{ + /* testing valid input */ + dlt_env_ll_set ll_set; + + char env0[] = "abcd:1234:3"; + char *tmp = &env0[0]; + + ASSERT_EQ(dlt_env_extract_ll_set(&tmp, &ll_set), 0); + EXPECT_EQ(ll_set.array_size, DLT_ENV_LL_SET_INCREASE); + EXPECT_EQ(ll_set.num_elem, 1); + EXPECT_EQ(ll_set.item[0].ll, 3); + + dlt_env_free_ll_set(&ll_set); + + /* force increasing the list */ + char env1[] = "abcd:0000:3;abcd:0001:3;abcd:0002:3;abcd:0003:3;abcd:0004:3;abcd:0005:3;abcd:0006:3;abcd:0007:3;abcd:0008:3;abcd:0009:3;abcd:0010:3"; + tmp = &env1[0]; + ASSERT_EQ(dlt_env_extract_ll_set(&tmp, &ll_set), 0); + EXPECT_EQ(ll_set.array_size, 2 * DLT_ENV_LL_SET_INCREASE); + EXPECT_EQ(ll_set.num_elem, 11); + for (size_t i = 0; i<ll_set.num_elem; ++i) + { + EXPECT_EQ(ll_set.item[i].ctxId[3], i%10 + '0'); + } + + dlt_env_free_ll_set(&ll_set); + + char env2[] = "SINA:SINC:FATAL"; + tmp = &env2[0]; + + ASSERT_EQ(dlt_env_extract_ll_set(&tmp, &ll_set), 0); + EXPECT_EQ(ll_set.array_size, DLT_ENV_LL_SET_INCREASE); + EXPECT_EQ(ll_set.num_elem, 1); + EXPECT_EQ(ll_set.item[0].ll, 1); + + dlt_env_free_ll_set(&ll_set); +} + + +TEST(DltExtensionTests, ids_match) +{ + ASSERT_EQ(1, dlt_env_ids_match("abcd", "abcd")); + ASSERT_EQ(0, dlt_env_ids_match("abcd", "abce")); + ASSERT_EQ(0, dlt_env_ids_match("abcd", "abee")); + ASSERT_EQ(0, dlt_env_ids_match("abcd", "aeee")); + ASSERT_EQ(0, dlt_env_ids_match("abcd", "eeee")); + + ASSERT_TRUE(dlt_env_ids_match("abcd", "abcd")); + ASSERT_FALSE(dlt_env_ids_match("abcd", "abce")); +} + + +TEST(DltExtensionTests, get_matching_prio) +{ + char apid[5] = "ABCD"; + char ctid[5] = "1234"; + + dlt_env_ll_item test0; + dlt_set_id(test0.appId, ""); + dlt_set_id(test0.ctxId, ""); + ASSERT_EQ(1, dlt_env_ll_item_get_matching_prio(&test0, apid, ctid)); + + dlt_set_id(test0.appId, ""); + dlt_set_id(test0.ctxId, ctid); + ASSERT_EQ(2, dlt_env_ll_item_get_matching_prio(&test0, apid, ctid)); + + dlt_set_id(test0.appId, apid); + dlt_set_id(test0.ctxId, ""); + ASSERT_EQ(3, dlt_env_ll_item_get_matching_prio(&test0, apid, ctid)); + + dlt_set_id(test0.appId, apid); + dlt_set_id(test0.ctxId, ctid); + ASSERT_EQ(4, dlt_env_ll_item_get_matching_prio(&test0, apid, ctid)); + + dlt_set_id(test0.appId, "EFGH"); /* appId should not match */ + dlt_set_id(test0.ctxId, ctid); + ASSERT_EQ(0, dlt_env_ll_item_get_matching_prio(&test0, apid, ctid)); + + ASSERT_EQ(-1, dlt_env_ll_item_get_matching_prio(NULL, apid, ctid)); + ASSERT_EQ(-1, dlt_env_ll_item_get_matching_prio(&test0, NULL, ctid)); + ASSERT_EQ(-1, dlt_env_ll_item_get_matching_prio(&test0, apid, NULL)); +} + + +TEST(DltExtensionTests, adjust_ll_from_env) +{ + char apid[5] = "ABCD"; + char ctid[5] = "1234"; + int ll = 42; /* unrealistic value to see that the ll was not touched */ + + dlt_env_ll_set ll_set; + dlt_env_init_ll_set(&ll_set); + EXPECT_EQ(ll, dlt_env_adjust_ll_from_env(NULL, apid, ctid, ll)); /* orig value in case of error */ + EXPECT_EQ(ll, dlt_env_adjust_ll_from_env(&ll_set, NULL, ctid, ll)); /* orig value in case of error */ + EXPECT_EQ(ll, dlt_env_adjust_ll_from_env(&ll_set, apid, NULL, ll)); /* orig value in case of error */ + + EXPECT_EQ(ll, dlt_env_adjust_ll_from_env(&ll_set, apid, ctid, ll)); /* an empty set should not match anything */ + + dlt_set_id(ll_set.item[0].appId, "DEAD"); /* not matching */ + dlt_set_id(ll_set.item[0].ctxId, "BEEF"); + ll_set.item[0].ll = 0; + ll_set.num_elem = 1; + EXPECT_EQ(ll, dlt_env_adjust_ll_from_env(&ll_set, apid, ctid, ll)); /* not matching anything */ + + dlt_set_id(ll_set.item[1].appId, ""); /* empty rule, weakest */ + dlt_set_id(ll_set.item[1].ctxId, ""); + ll_set.item[1].ll = 1; + ll_set.num_elem = 2; + EXPECT_EQ(1, dlt_env_adjust_ll_from_env(&ll_set, apid, ctid, ll)); + + dlt_set_id(ll_set.item[2].appId, ""); /* prio 2 */ + dlt_set_id(ll_set.item[2].ctxId, ctid); + ll_set.item[2].ll = 2; + ll_set.num_elem = 3; + EXPECT_EQ(2, dlt_env_adjust_ll_from_env(&ll_set, apid, ctid, ll)); + + dlt_set_id(ll_set.item[3].appId, apid); /* prio 3 */ + dlt_set_id(ll_set.item[3].ctxId, ""); + ll_set.item[3].ll = 3; + ll_set.num_elem = 4; + EXPECT_EQ(3, dlt_env_adjust_ll_from_env(&ll_set, apid, ctid, ll)); + + dlt_set_id(ll_set.item[4].appId, apid); /* prio 4 */ + dlt_set_id(ll_set.item[4].ctxId, ctid); + ll_set.item[4].ll = 4; + ll_set.num_elem = 5; + EXPECT_EQ(4, dlt_env_adjust_ll_from_env(&ll_set, apid, ctid, ll)); + + dlt_set_id(ll_set.item[5].appId, apid); /* does not matter item[4] will always match */ + dlt_set_id(ll_set.item[5].ctxId, ""); + ll_set.item[5].ll = 5; + ll_set.num_elem = 6; + EXPECT_EQ(4, dlt_env_adjust_ll_from_env(&ll_set, apid, ctid, ll)); /* remember, item[4] matches */ + + dlt_env_free_ll_set(&ll_set); +} + + +// int dlt_env_helper_to_lower(char **env, char *result, int res_len) +TEST(DltExtensionTests, dlt_env_helper_to_lower) +{ + // default behavior + char env0[] = "1238<><<>>>>#$//abcdABCDEDFGHIJKLMNOPQRSTUVWXYZpo;ABcd"; + char res0[] = "1238<><<>>>>#$//abcdabcdedfghijklmnopqrstuvwxyzpo"; + char *tmp0 = &env0[0]; + + char result0[sizeof(res0)]; + ASSERT_EQ(0, dlt_env_helper_to_lower(&tmp0, result0, sizeof(result0))); + ASSERT_EQ(';', *tmp0); // next char is ';' + ASSERT_STREQ(res0, result0); // stops at ';' and is correctly converted + + // default behavior with end of string + char env1[] = "1238<><<>>>>#$//abcdABCDEDFGHIJKLMNOPQRSTUVWXYZpo"; + char res1[] = "1238<><<>>>>#$//abcdabcdedfghijklmnopqrstuvwxyzpo"; + char *tmp1 = &env1[0]; + + char result1[sizeof(res1)]; + ASSERT_EQ(0, dlt_env_helper_to_lower(&tmp1, result1, sizeof(result1))); + ASSERT_EQ(0, *tmp1); // next char is void + ASSERT_STREQ(res1, result1); // stops at end-of-string and is correctly converted + + // result string too short + char env2[] = "2238<><<>>>>#$//abcdABCDEDFGHIJKLMNOPQRSTUVWXYZpo"; + char res2[] = "2238<><<>>>>#$//abcdabcdedfg"; + char *tmp2 = &env2[0]; + + char result2[sizeof(res2)]; + ASSERT_EQ(-1, dlt_env_helper_to_lower(&tmp2, result2, sizeof(result2))); + ASSERT_EQ('H', *tmp2); // next char is void + ASSERT_STREQ(res2, result2); // stops at end-of-string and is partially converted + + // input string shorter than result + char env3[] = "3338<><<>>>>#$//abcdABCDEDFGHIJKLMNOPQRSTUVWXYZpo"; + char res3[] = "3338<><<>>>>#$//abcdabcdedfghijklmnopqrstuvwxyzpo"; + char *tmp3 = &env3[0]; + + char result3[sizeof(res3)+5]; + ASSERT_EQ(0, dlt_env_helper_to_lower(&tmp3, result3, sizeof(result3))); + ASSERT_EQ(0, *tmp3); // next char is void + ASSERT_STREQ(res3, result3); // stops at end-of-string and is correctly converted +} + + +// int dlt_env_extract_symbolic_ll(char **env, int8_t * ll) +TEST(DltExtensionTests, dlt_env_extract_symbolic_ll) +{ + int8_t result; + + // correct behavior + char env0[] = "DEFAULT;off;fatal;error;warning;info;DeBuG;verbose"; + char *tmp0 = &env0[0]; + + ASSERT_EQ(0, dlt_env_extract_symbolic_ll(&tmp0, &result)); + ASSERT_EQ('o', *tmp0); + ASSERT_EQ(-1, result); + + ASSERT_EQ(0, dlt_env_extract_symbolic_ll(&tmp0, &result)); + ASSERT_EQ('f', *tmp0); + ASSERT_EQ(0, result); + + ASSERT_EQ(0, dlt_env_extract_symbolic_ll(&tmp0, &result)); + ASSERT_EQ('e', *tmp0); + ASSERT_EQ(1, result); + + ASSERT_EQ(0, dlt_env_extract_symbolic_ll(&tmp0, &result)); + ASSERT_EQ('w', *tmp0); + ASSERT_EQ(2, result); + + ASSERT_EQ(0, dlt_env_extract_symbolic_ll(&tmp0, &result)); + ASSERT_EQ('i', *tmp0); + ASSERT_EQ(3, result); + + ASSERT_EQ(0, dlt_env_extract_symbolic_ll(&tmp0, &result)); + ASSERT_EQ('D', *tmp0); + ASSERT_EQ(4, result); + + ASSERT_EQ(0, dlt_env_extract_symbolic_ll(&tmp0, &result)); + ASSERT_EQ('v', *tmp0); + ASSERT_EQ(5, result); + + ASSERT_EQ(0, dlt_env_extract_symbolic_ll(&tmp0, &result)); + ASSERT_EQ(0, *tmp0); + ASSERT_EQ(6, result); + + + // incorrect behavior + char env1[] = "DEF"; + char *tmp1 = &env1[0]; + + result = 18; + ASSERT_EQ(-1, dlt_env_extract_symbolic_ll(&tmp1, &result)); + ASSERT_EQ(NULL, *tmp1); + ASSERT_EQ(18, result); /* 'result' is not touched */ + + + // incorrect behavior + char env2[] = "DEFaultingfBa"; + char *tmp2 = &env2[0]; + + result = 28; + ASSERT_EQ(-1, dlt_env_extract_symbolic_ll(&tmp2, &result)); + ASSERT_EQ('i', *tmp2); + ASSERT_EQ(28, result); /* 'result' is not touched */ +} + |