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 
  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 }