/* * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ #include "precompiled.hpp" #include "logging/logDecorators.hpp" #include "prims/jvm.h" #include "unittest.hpp" static LogDecorators::Decorator decorator_array[] = { #define DECORATOR(name, abbr) LogDecorators::name##_decorator, DECORATOR_LIST #undef DECORATOR }; static const char* decorator_name_array[] = { #define DECORATOR(name, abbr) #name, DECORATOR_LIST #undef DECORATOR }; static const char* decorator_abbr_array[] = { #define DECORATOR(name, abbr) #abbr, DECORATOR_LIST #undef DECORATOR }; // Assert that the given decorators object has the default decorators (uptime, level, tags) // If exclusive = true, also assert that no other decorators are selected static void assert_default_decorators(LogDecorators* decorators, bool exclusive = true) { for (int i = 0; i < LogDecorators::Count; i++) { LogDecorators::Decorator decorator = decorator_array[i]; if (decorator == LogDecorators::uptime_decorator || decorator == LogDecorators::level_decorator || decorator == LogDecorators::tags_decorator) { EXPECT_TRUE(decorators->is_decorator(decorator)); } else if (exclusive) { EXPECT_FALSE(decorators->is_decorator(decorator)); } } } TEST(LogDecorators, defaults) { LogDecorators decorators; assert_default_decorators(&decorators); } // Test converting between name and decorator (string and enum) TEST(LogDecorators, from_and_to_name) { EXPECT_EQ(LogDecorators::Invalid, LogDecorators::from_string("unknown")); EXPECT_EQ(LogDecorators::Invalid, LogDecorators::from_string("")); for (int i = 0; i < LogDecorators::Count; i++) { LogDecorators::Decorator decorator = decorator_array[i]; const char* name = LogDecorators::name(decorator); EXPECT_STREQ(decorator_name_array[i], name); LogDecorators::Decorator decorator2 = LogDecorators::from_string(name); EXPECT_EQ(decorator, decorator2); // Test case insensitivity char* name_cpy = strdup(name); name_cpy[0] = toupper(name_cpy[0]); decorator2 = LogDecorators::from_string(name_cpy); free(name_cpy); EXPECT_EQ(decorator, decorator2); } } // Test decorator abbreviations TEST(LogDecorators, from_and_to_abbr) { for (int i = 0; i < LogDecorators::Count; i++) { LogDecorators::Decorator decorator = decorator_array[i]; const char* abbr = LogDecorators::abbreviation(decorator); EXPECT_STREQ(decorator_abbr_array[i], abbr); LogDecorators::Decorator decorator2 = LogDecorators::from_string(abbr); ASSERT_EQ(decorator, decorator2); // Test case insensitivity char* abbr_cpy = strdup(abbr); abbr_cpy[0] = toupper(abbr_cpy[0]); decorator2 = LogDecorators::from_string(abbr_cpy); free(abbr_cpy); EXPECT_EQ(decorator, decorator2); } } TEST(LogDecorators, parse_default) { LogDecorators decorators; decorators.parse(""); // Empty string means we should use the default decorators assert_default_decorators(&decorators); } // Test that "none" gives no decorators at all TEST(LogDecorators, parse_none) { LogDecorators decorators; decorators.parse("none"); for (int i = 0; i < LogDecorators::Count; i++) { EXPECT_FALSE(decorators.is_decorator(decorator_array[i])); } } // Test a few invalid decorator selections TEST(LogDecorators, parse_invalid) { LogDecorators decorators; EXPECT_FALSE(decorators.parse("invalid")); EXPECT_FALSE(decorators.parse(",invalid")); EXPECT_FALSE(decorators.parse(",invalid,")); assert_default_decorators(&decorators); } // Assert that the given decorator has all decorators between first and last static void assert_decorations_between(const LogDecorators* decorator, size_t first, size_t last) { for (size_t i = 0; i < ARRAY_SIZE(decorator_array); i++) { if (i >= first && i <= last) { EXPECT_TRUE(decorator->is_decorator(decorator_array[i])); } else { EXPECT_FALSE(decorator->is_decorator(decorator_array[i])); } } } TEST(LogDecorators, parse) { LogDecorators decorators; // Verify a bunch of different decorator selections char decstr[1 * K]; decstr[0] = '\0'; size_t written = 0; for (size_t i = 0; i < ARRAY_SIZE(decorator_array); i++) { for (size_t j = i; j < ARRAY_SIZE(decorator_array); j++) { for (size_t k = i; k <= j; k++) { ASSERT_LT(written, sizeof(decstr)) << "decstr overflow"; int ret = jio_snprintf(decstr + written, sizeof(decstr) - written, "%s%s", written == 0 ? "" : ",", ((k + j) % 2 == 0) ? decorator_name_array[k] : decorator_abbr_array[k]); ASSERT_NE(-1, ret); written += ret; } EXPECT_TRUE(decorators.parse(decstr)) << "Valid decorator selection did not parse: " << decstr; assert_decorations_between(&decorators, i, j); written = 0; decstr[0] = '\0'; } } } TEST(LogDecorators, combine_with) { LogDecorators dec1; LogDecorators dec2; // Select first and third decorator for dec1 char input[64]; sprintf(input, "%s,%s", decorator_name_array[0], decorator_name_array[3]); dec1.parse(input); EXPECT_TRUE(dec1.is_decorator(decorator_array[0])); EXPECT_TRUE(dec1.is_decorator(decorator_array[3])); // Select the default decorators for dec2 EXPECT_FALSE(dec2.is_decorator(decorator_array[0])); EXPECT_FALSE(dec2.is_decorator(decorator_array[3])); assert_default_decorators(&dec2); // Combine and verify that the combination includes first, third and default decorators dec2.combine_with(dec1); EXPECT_TRUE(dec2.is_decorator(decorator_array[0])); EXPECT_TRUE(dec2.is_decorator(decorator_array[3])); assert_default_decorators(&dec2, false); } TEST(LogDecorators, clear) { // Start with default decorators and then clear it LogDecorators dec; EXPECT_FALSE(dec.is_empty()); dec.clear(); EXPECT_TRUE(dec.is_empty()); for (size_t i = 0; i < LogDecorators::Count; i++) { EXPECT_FALSE(dec.is_decorator(decorator_array[i])); } } // Test the decorator constant None TEST(LogDecorators, none) { LogDecorators dec = LogDecorators::None; for (size_t i = 0; i < LogDecorators::Count; i++) { EXPECT_FALSE(dec.is_decorator(decorator_array[i])); } } TEST(LogDecorators, is_empty) { LogDecorators def, none = LogDecorators::None; EXPECT_FALSE(def.is_empty()); EXPECT_TRUE(none.is_empty()); }