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 "jvm.h" |
26 | #include "logging/logDecorators.hpp" |
27 | #include "unittest.hpp" |
28 | |
29 | static LogDecorators::Decorator decorator_array[] = { |
30 | #define DECORATOR(name, abbr) LogDecorators::name##_decorator, |
31 | DECORATOR_LIST |
32 | #undef DECORATOR |
33 | }; |
34 | |
35 | static const char* decorator_name_array[] = { |
36 | #define DECORATOR(name, abbr) #name, |
37 | DECORATOR_LIST |
38 | #undef DECORATOR |
39 | }; |
40 | |
41 | static 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 |
49 | static 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 | |
62 | TEST(LogDecorators, defaults) { |
63 | LogDecorators decorators; |
64 | assert_default_decorators(&decorators); |
65 | } |
66 | |
67 | // Test converting between name and decorator (string and enum) |
68 | TEST(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 |
91 | TEST(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 | |
110 | TEST(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 |
117 | TEST(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 |
126 | TEST(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 |
135 | static 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 | |
145 | TEST(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 | |
170 | TEST(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 | |
193 | TEST(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 |
206 | TEST(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 | |
213 | TEST(LogDecorators, is_empty) { |
214 | LogDecorators def, none = LogDecorators::None; |
215 | EXPECT_FALSE(def.is_empty()); |
216 | EXPECT_TRUE(none.is_empty()); |
217 | } |
218 | |