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
assert_default_decorators(LogDecorators * decorators,bool exclusive=true)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 
TEST(LogDecorators,defaults)62 TEST(LogDecorators, defaults) {
63   LogDecorators decorators;
64   assert_default_decorators(&decorators);
65 }
66 
67 // Test converting between name and decorator (string and enum)
TEST(LogDecorators,from_and_to_name)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
TEST(LogDecorators,from_and_to_abbr)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 
TEST(LogDecorators,parse_default)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
TEST(LogDecorators,parse_none)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
TEST(LogDecorators,parse_invalid)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
assert_decorations_between(const LogDecorators * decorator,size_t first,size_t 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 
TEST(LogDecorators,parse)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 
TEST(LogDecorators,combine_with)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 
TEST(LogDecorators,clear)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
TEST(LogDecorators,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 
TEST(LogDecorators,is_empty)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