summaryrefslogtreecommitdiff
path: root/tests/gtest_dlt_daemon_multiple_files_logging.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/gtest_dlt_daemon_multiple_files_logging.cpp')
-rw-r--r--tests/gtest_dlt_daemon_multiple_files_logging.cpp277
1 files changed, 277 insertions, 0 deletions
diff --git a/tests/gtest_dlt_daemon_multiple_files_logging.cpp b/tests/gtest_dlt_daemon_multiple_files_logging.cpp
new file mode 100644
index 0000000..05b58f2
--- /dev/null
+++ b/tests/gtest_dlt_daemon_multiple_files_logging.cpp
@@ -0,0 +1,277 @@
+/*
+ * SPDX license identifier: MPL-2.0
+ *
+ * Copyright (C) 2011-2015, BMW AG
+ *
+ * This file is part of GENIVI Project DLT - Diagnostic Log and Trace.
+ *
+ * This Source Code Form is subject to the terms of the
+ * Mozilla Public License (MPL), 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/.
+ *
+ * For further information see http://www.genivi.org/.
+ */
+
+/*!
+ * \author
+ * Oleg Tropmann <oleg.tropmann@daimler.com>
+ * Daniel Weber <daniel.w.weber@daimler.com>
+ *
+ * \copyright Copyright © 2022 Daimler TSS GmbH. \n
+ * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/.
+ *
+ * \file gtest_dlt_daemon_multiple_files_logging.ccpp
+ */
+
+#include <gtest/gtest.h>
+
+int connectServer(void);
+
+extern "C"
+{
+#include "dlt_common.h"
+#include <syslog.h>
+#include <dirent.h>
+#include <string.h>
+}
+
+// publish prototypes
+void configure(const char* path, const char* file_name, bool enable_limit, int file_size, int max_files_size);
+void write_log_message();
+void verify_multiple_files(const char* path, const char* file_name, int file_size, int max_files_size);
+void verify_single_file(const char* path, const char* file_name);
+void verify_in_one_file(const char* path, const char* file_name, const char* log1, const char* log2);
+bool file_contains_strings(const char* abs_file_path, const char* str1, const char* str2);
+int get_file_index(char* file_name);
+int compare_int(const void* a, const void* b);
+
+/**
+ * Configure dlt logging using file size limits.
+ */
+TEST(t_dlt_logging_multiple_files, normal)
+{
+ const char* path = "/tmp";
+ const char* file_name = "dlt.log";
+ const int file_size = 128;
+ const int max_file_size = 512;
+ configure(path, file_name, true, file_size, max_file_size);
+ write_log_message();
+ EXPECT_NO_THROW(dlt_log_free());
+ verify_multiple_files(path, file_name, file_size, max_file_size);
+}
+
+/**
+ * Configure dlt logging using file size limits.
+ * Though, due to an error during initialization dlt logging defaults to one file logging.
+ */
+TEST(t_dlt_logging_one_file_as_fallback, normal)
+{
+ const char* path = "/tmp";
+ const char* file_name = "dltlog";
+ configure(path, file_name, true, 128, 512);
+ write_log_message();
+ EXPECT_NO_THROW(dlt_log_free());
+ verify_single_file(path, file_name);
+}
+
+/**
+ * Configure dlt logging without file size limits resulting in one file logging.
+ */
+TEST(t_dlt_logging_one_file, normal)
+{
+ const char* path = "/tmp";
+ const char* file_name = "dlt.log";
+ configure(path, file_name, false, 128, 512);
+ write_log_message();
+ EXPECT_NO_THROW(dlt_log_free());
+ verify_single_file(path, file_name);
+}
+
+/**
+ * The dlt_daemon calls dlt_log_init multiple times. In the past, so we create
+ * unnecessary two files. The reinit have to append to the first file.
+ */
+TEST(t_dlt_logging_multiple_files_append_reinit, normal)
+{
+ const char* path = "/tmp";
+ const char* file_name = "dlt.log";
+ const int file_size = 256;
+ const int max_file_size = 512;
+
+ const char* log1 = "ONE\n";
+ const char* log2 = "TWO\n";
+
+ configure(path, file_name, true, file_size, max_file_size);
+ dlt_vlog(LOG_INFO, "%s", log1);
+ EXPECT_NO_THROW(dlt_log_free());
+
+ configure(path, file_name, true, file_size, max_file_size);
+ dlt_vlog(LOG_INFO, "%s", log2);
+ EXPECT_NO_THROW(dlt_log_free());
+ verify_in_one_file(path, file_name, log1, log2);
+}
+
+void configure(const char *path, const char* file_name, const bool enable_limit, const int file_size, const int max_files_size)
+{
+ char abs_file_path[PATH_MAX];
+ snprintf(abs_file_path, sizeof(abs_file_path), "%s/%s", path, file_name);
+ printf("debug test: %s\n", abs_file_path);
+
+ EXPECT_NO_THROW(dlt_log_set_filename(abs_file_path));
+ EXPECT_NO_THROW(dlt_log_set_level(6));
+ EXPECT_NO_THROW(dlt_log_init_multiple_logfiles_support(DLT_LOG_TO_FILE, enable_limit, file_size, max_files_size));
+}
+
+void write_log_message()
+{
+ for (unsigned int i = 0; i < 10; i++) {
+ dlt_vlog(LOG_INFO, "%d. Unit test logging into multiple files if configured.\n", i);
+ }
+}
+
+void verify_multiple_files(const char* path, const char* file_name, const int file_size, const int max_files_size)
+{
+ int sum_size = 0;
+ int num_files = 0;
+ int file_indices[100];
+
+ char filename[PATH_MAX + 1];
+ struct dirent *dp;
+ struct stat status;
+
+ char file_name_copy[NAME_MAX];
+ strncpy(file_name_copy, file_name, NAME_MAX);
+ char filename_base[NAME_MAX];
+ EXPECT_TRUE(dlt_extract_base_name_without_ext(file_name_copy, filename_base, sizeof(filename_base)));
+ const char *filename_ext = get_filename_ext(file_name);
+ EXPECT_TRUE(filename_ext);
+
+ DIR *dir = opendir(path);
+ while ((dp = readdir(dir)) != NULL) {
+ if (strstr(dp->d_name, filename_base) &&
+ strstr(dp->d_name, filename_ext)) {
+
+ snprintf(filename, sizeof(filename), "%s/%s", path, dp->d_name);
+
+ if (0 == stat(filename, &status)) {
+ EXPECT_LE(status.st_size, file_size);
+ EXPECT_GE(status.st_size, file_size/2);
+ sum_size += status.st_size;
+ file_indices[num_files++] = get_file_index(filename);
+ } else {
+ EXPECT_TRUE(false);
+ }
+ }
+ }
+
+ EXPECT_LE(sum_size, max_files_size);
+ EXPECT_GT(sum_size, 0);
+ EXPECT_GT(num_files, 0);
+
+ //check that file indices are successive in ascending order
+ qsort(file_indices, num_files, sizeof(int), compare_int);
+ int index = file_indices[0];
+ for (int i=1; i<num_files; i++) {
+ EXPECT_EQ(file_indices[i], ++index);
+ }
+}
+
+void verify_single_file(const char* path, const char* file_name)
+{
+ char abs_file_path[PATH_MAX];
+ snprintf(abs_file_path, sizeof(abs_file_path), "%s/%s", path, file_name);
+
+ struct stat status;
+ if (0 == stat(abs_file_path, &status)) {
+ EXPECT_GT(status.st_size, 0);
+ } else {
+ EXPECT_TRUE(false);
+ }
+}
+
+void verify_in_one_file(const char* path, const char* file_name, const char* log1, const char* log2)
+{
+ char abs_file_path[PATH_MAX + 1];
+ struct dirent *dp;
+
+ char file_name_copy[NAME_MAX];
+ strncpy(file_name_copy, file_name, NAME_MAX);
+ char filename_base[NAME_MAX];
+ EXPECT_TRUE(dlt_extract_base_name_without_ext(file_name_copy, filename_base, sizeof(filename_base)));
+ const char *filename_ext = get_filename_ext(file_name);
+ EXPECT_TRUE(filename_ext);
+
+ bool found = false;
+
+ DIR *dir = opendir(path);
+ while ((dp = readdir(dir)) != NULL) {
+ if (strstr(dp->d_name, filename_base) &&
+ strstr(dp->d_name, filename_ext)) {
+
+ snprintf(abs_file_path, sizeof(abs_file_path), "%s/%s", path, dp->d_name);
+
+ if (file_contains_strings(abs_file_path, log1, log2)) {
+ found = true;
+ break;
+ }
+ }
+ }
+
+ EXPECT_TRUE(found);
+}
+
+bool file_contains_strings(const char* abs_file_path, const char* str1, const char* str2)
+{
+ bool found = false;
+ FILE *file = fopen(abs_file_path, "r");
+ if (file != nullptr) {
+ fseek (file , 0 , SEEK_END);
+ long size = ftell (file);
+ rewind (file);
+
+ char* buffer = (char*) malloc(size);
+ long read_bytes = fread(buffer, 1, size, file);
+
+ EXPECT_EQ(size, read_bytes);
+
+ if ((strstr(buffer, str1) != nullptr) &&
+ (strstr(buffer, str2) != nullptr)) {
+
+ found = true;
+ }
+
+ fclose(file);
+ free(buffer);
+ }
+ return found;
+}
+
+int get_file_index(char* file_name)
+{
+ char *dot = strrchr(file_name, '.');
+ *dot = '\0';
+
+ //start with the first zero
+ char *iterator = strchr(file_name, '0');
+ do {} while (*(++iterator) == '0');
+ //now iterator points to the first character after 0
+
+ return atoi(iterator);
+}
+
+int compare_int(const void* a, const void* b)
+{
+ if (*((int*)a) == *((int*)b)) return 0;
+ else if (*((int*)a) < *((int*)b)) return -1;
+ else return 1;
+}
+
+int main(int argc, char **argv)
+{
+ ::testing::InitGoogleTest(&argc, argv);
+ ::testing::FLAGS_gtest_break_on_failure = true;
+ /*::testing::FLAGS_gtest_filter = "*.normal"; */
+ /*::testing::FLAGS_gtest_repeat = 10000; */
+ return RUN_ALL_TESTS();
+}