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