summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Vacek <stefan.vacek@intel.com>2015-08-26 17:28:54 +0200
committerAlexander Wenzel <Alexander.AW.Wenzel@bmw.de>2015-10-07 10:35:41 +0200
commitc3b53f8805236cb7c72eb62ef04866f34de33103 (patch)
tree956eec44e2d0b2ec309904f15321565a3fae4e3d
parent2f334a851fa1b39cab74724f3d0a0565f86c27b4 (diff)
downloadDLT-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.h74
-rw-r--r--src/examples/dlt-example-user.c21
-rw-r--r--src/lib/CMakeLists.txt2
-rw-r--r--src/lib/dlt_env_ll.c560
-rw-r--r--src/lib/dlt_user.c42
-rwxr-xr-xsrc/tests/dlt-test-change-ll-through-env.sh59
-rw-r--r--tests/CMakeLists.txt2
-rw-r--r--tests/dlt_env_ll_unit_test.cpp540
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 */
+}
+