1/* 2 * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24#include "precompiled.hpp" 25#include "logging/logDecorators.hpp" 26#include "prims/jvm.h" 27#include "unittest.hpp" 28 29static LogDecorators::Decorator decorator_array[] = { 30#define DECORATOR(name, abbr) LogDecorators::name##_decorator, 31 DECORATOR_LIST 32#undef DECORATOR 33}; 34 35static const char* decorator_name_array[] = { 36#define DECORATOR(name, abbr) #name, 37 DECORATOR_LIST 38#undef DECORATOR 39}; 40 41static const char* decorator_abbr_array[] = { 42#define DECORATOR(name, abbr) #abbr, 43 DECORATOR_LIST 44#undef DECORATOR 45}; 46 47// Assert that the given decorators object has the default decorators (uptime, level, tags) 48// If exclusive = true, also assert that no other decorators are selected 49static void assert_default_decorators(LogDecorators* decorators, bool exclusive = true) { 50 for (int i = 0; i < LogDecorators::Count; i++) { 51 LogDecorators::Decorator decorator = decorator_array[i]; 52 if (decorator == LogDecorators::uptime_decorator || 53 decorator == LogDecorators::level_decorator || 54 decorator == LogDecorators::tags_decorator) { 55 EXPECT_TRUE(decorators->is_decorator(decorator)); 56 } else if (exclusive) { 57 EXPECT_FALSE(decorators->is_decorator(decorator)); 58 } 59 } 60} 61 62TEST(LogDecorators, defaults) { 63 LogDecorators decorators; 64 assert_default_decorators(&decorators); 65} 66 67// Test converting between name and decorator (string and enum) 68TEST(LogDecorators, from_and_to_name) { 69 EXPECT_EQ(LogDecorators::Invalid, LogDecorators::from_string("unknown")); 70 EXPECT_EQ(LogDecorators::Invalid, LogDecorators::from_string("")); 71 72 for (int i = 0; i < LogDecorators::Count; i++) { 73 LogDecorators::Decorator decorator = decorator_array[i]; 74 75 const char* name = LogDecorators::name(decorator); 76 EXPECT_STREQ(decorator_name_array[i], name); 77 78 LogDecorators::Decorator decorator2 = LogDecorators::from_string(name); 79 EXPECT_EQ(decorator, decorator2); 80 81 // Test case insensitivity 82 char* name_cpy = strdup(name); 83 name_cpy[0] = toupper(name_cpy[0]); 84 decorator2 = LogDecorators::from_string(name_cpy); 85 free(name_cpy); 86 EXPECT_EQ(decorator, decorator2); 87 } 88} 89 90// Test decorator abbreviations 91TEST(LogDecorators, from_and_to_abbr) { 92 for (int i = 0; i < LogDecorators::Count; i++) { 93 LogDecorators::Decorator decorator = decorator_array[i]; 94 95 const char* abbr = LogDecorators::abbreviation(decorator); 96 EXPECT_STREQ(decorator_abbr_array[i], abbr); 97 98 LogDecorators::Decorator decorator2 = LogDecorators::from_string(abbr); 99 ASSERT_EQ(decorator, decorator2); 100 101 // Test case insensitivity 102 char* abbr_cpy = strdup(abbr); 103 abbr_cpy[0] = toupper(abbr_cpy[0]); 104 decorator2 = LogDecorators::from_string(abbr_cpy); 105 free(abbr_cpy); 106 EXPECT_EQ(decorator, decorator2); 107 } 108} 109 110TEST(LogDecorators, parse_default) { 111 LogDecorators decorators; 112 decorators.parse(""); // Empty string means we should use the default decorators 113 assert_default_decorators(&decorators); 114} 115 116// Test that "none" gives no decorators at all 117TEST(LogDecorators, parse_none) { 118 LogDecorators decorators; 119 decorators.parse("none"); 120 for (int i = 0; i < LogDecorators::Count; i++) { 121 EXPECT_FALSE(decorators.is_decorator(decorator_array[i])); 122 } 123} 124 125// Test a few invalid decorator selections 126TEST(LogDecorators, parse_invalid) { 127 LogDecorators decorators; 128 EXPECT_FALSE(decorators.parse("invalid")); 129 EXPECT_FALSE(decorators.parse(",invalid")); 130 EXPECT_FALSE(decorators.parse(",invalid,")); 131 assert_default_decorators(&decorators); 132} 133 134// Assert that the given decorator has all decorators between first and last 135static void assert_decorations_between(const LogDecorators* decorator, size_t first, size_t last) { 136 for (size_t i = 0; i < ARRAY_SIZE(decorator_array); i++) { 137 if (i >= first && i <= last) { 138 EXPECT_TRUE(decorator->is_decorator(decorator_array[i])); 139 } else { 140 EXPECT_FALSE(decorator->is_decorator(decorator_array[i])); 141 } 142 } 143} 144 145TEST(LogDecorators, parse) { 146 LogDecorators decorators; 147 148 // Verify a bunch of different decorator selections 149 char decstr[1 * K]; 150 decstr[0] = '\0'; 151 size_t written = 0; 152 for (size_t i = 0; i < ARRAY_SIZE(decorator_array); i++) { 153 for (size_t j = i; j < ARRAY_SIZE(decorator_array); j++) { 154 for (size_t k = i; k <= j; k++) { 155 ASSERT_LT(written, sizeof(decstr)) << "decstr overflow"; 156 int ret = jio_snprintf(decstr + written, sizeof(decstr) - written, "%s%s", 157 written == 0 ? "" : ",", 158 ((k + j) % 2 == 0) ? decorator_name_array[k] : decorator_abbr_array[k]); 159 ASSERT_NE(-1, ret); 160 written += ret; 161 } 162 EXPECT_TRUE(decorators.parse(decstr)) << "Valid decorator selection did not parse: " << decstr; 163 assert_decorations_between(&decorators, i, j); 164 written = 0; 165 decstr[0] = '\0'; 166 } 167 } 168} 169 170TEST(LogDecorators, combine_with) { 171 LogDecorators dec1; 172 LogDecorators dec2; 173 174 // Select first and third decorator for dec1 175 char input[64]; 176 sprintf(input, "%s,%s", decorator_name_array[0], decorator_name_array[3]); 177 dec1.parse(input); 178 EXPECT_TRUE(dec1.is_decorator(decorator_array[0])); 179 EXPECT_TRUE(dec1.is_decorator(decorator_array[3])); 180 181 // Select the default decorators for dec2 182 EXPECT_FALSE(dec2.is_decorator(decorator_array[0])); 183 EXPECT_FALSE(dec2.is_decorator(decorator_array[3])); 184 assert_default_decorators(&dec2); 185 186 // Combine and verify that the combination includes first, third and default decorators 187 dec2.combine_with(dec1); 188 EXPECT_TRUE(dec2.is_decorator(decorator_array[0])); 189 EXPECT_TRUE(dec2.is_decorator(decorator_array[3])); 190 assert_default_decorators(&dec2, false); 191} 192 193TEST(LogDecorators, clear) { 194 // Start with default decorators and then clear it 195 LogDecorators dec; 196 EXPECT_FALSE(dec.is_empty()); 197 198 dec.clear(); 199 EXPECT_TRUE(dec.is_empty()); 200 for (size_t i = 0; i < LogDecorators::Count; i++) { 201 EXPECT_FALSE(dec.is_decorator(decorator_array[i])); 202 } 203} 204 205// Test the decorator constant None 206TEST(LogDecorators, none) { 207 LogDecorators dec = LogDecorators::None; 208 for (size_t i = 0; i < LogDecorators::Count; i++) { 209 EXPECT_FALSE(dec.is_decorator(decorator_array[i])); 210 } 211} 212 213TEST(LogDecorators, is_empty) { 214 LogDecorators def, none = LogDecorators::None; 215 EXPECT_FALSE(def.is_empty()); 216 EXPECT_TRUE(none.is_empty()); 217} 218