1 
   2 /*
   3  * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
   4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5  *
   6  * This code is free software; you can redistribute it and/or modify it
   7  * under the terms of the GNU General Public License version 2 only, as
   8  * published by the Free Software Foundation.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  */
  24 
  25 import java.io.ByteArrayOutputStream;
  26 import java.util.Arrays;
  27 import java.util.List;
  28 import java.util.concurrent.CopyOnWriteArrayList;
  29 import java.util.logging.Handler;
  30 import java.util.logging.Level;
  31 import java.util.logging.LogRecord;
  32 import java.util.logging.Logger;
  33 import java.util.logging.SimpleFormatter;
  34 import java.util.logging.StreamHandler;
  35 
  36 /**
  37  * @test
  38  * @bug 8028788
  39  * @summary tests that the message format string is correctly constructed
  40  *          by Logger.entering
  41  * @run main/othervm LoggerEnteringWithParams
  42  * @author daniel fuchs
  43  */
  44 public class LoggerEnteringWithParams {
  45 
  46     static final Object[] data = {
  47         "one", "two", "three", "four", "five", "six", "seven", "eight"
  48     };
  49 
  50     static final class TestHandler extends Handler {
  51         final List<LogRecord> events = new CopyOnWriteArrayList<>();
  52         final ByteArrayOutputStream bytes = new ByteArrayOutputStream();
  53         final StreamHandler wrapped = new StreamHandler(bytes, new SimpleFormatter());
  54 
  55         @Override
  56         public void publish(LogRecord record) {
  57             events.add(record);
  58             wrapped.publish(record);
  59             wrapped.flush();
  60         }
  61         @Override
  62         public void flush() {
  63             wrapped.flush();
  64         }
  65         @Override
  66         public void close() throws SecurityException {
  67             wrapped.close();
  68         }
  69 
  70         @Override
  71         public synchronized void setLevel(Level newLevel) throws SecurityException {
  72             super.setLevel(newLevel);
  73             wrapped.setLevel(newLevel);
  74         }
  75 
  76         public void reset() {
  77             bytes.reset();
  78             events.clear();
  79         }
  80 
  81     }
  82 
  83     public static void main(String[] args) {
  84         Logger logger = Logger.getLogger("some.logger");
  85         TestHandler handler = new TestHandler();
  86         logger.setUseParentHandlers(false);
  87         handler.setLevel(Level.ALL);
  88         logger.setLevel(Level.FINEST);
  89         logger.addHandler(handler);
  90 
  91         // Auto-detect the line termination used by SimpleFormatter - (CR vs CRLF)
  92         logger.entering("test", "test");
  93         final String test = handler.bytes.toString();
  94         System.out.println(test);
  95         final String lineEnd = test.substring(test.indexOf("ENTRY")+"ENTRY".length());
  96         System.out.print("Line termination is " + lineEnd.length() + " char(s) long:");
  97         for (int i=0; i<lineEnd.length(); i++) {
  98             System.out.print(" code="+(int)lineEnd.charAt(i));
  99         }
 100         System.out.println();
 101         handler.reset();
 102 
 103         for (int i=0 ; i<=data.length; i++) {
 104             final StringBuilder b = new StringBuilder("ENTRY");
 105             final StringBuilder f = new StringBuilder("ENTRY");
 106             final Object[] params = new Object[i];
 107             for (int k=0; k<i; k++) {
 108                 params[k] = data[k];
 109                 b.append(' ').append(String.valueOf(params[k]));
 110                 f.append(" {").append(String.valueOf(k)).append('}');
 111             }
 112 
 113             final String expected = b.toString();
 114             final String format = f.toString();
 115             final String className = "class"+i;
 116             final String methodName = "method"+i;
 117 
 118             logger.entering(className, methodName, params);
 119             final String logged = handler.bytes.toString();
 120             System.out.println("got:\n" + logged);
 121 
 122             if (!logged.contains(className)) {
 123                 throw new RuntimeException("Marker for " + className
 124                         + " not found."
 125                         + "\n\tgot: <<\n" + logged + "\t     >>");
 126             }
 127             if (!logged.contains(methodName)) {
 128                 throw new RuntimeException("Marker for " + methodName
 129                         + " not found."
 130                         + "\n\tgot: <<\n" + logged + "\t     >>");
 131             }
 132             if (!logged.contains(expected)) {
 133                 throw new RuntimeException("Marker for parameters[size="
 134                         + i + "] not found"
 135                         + "\n\tgot: <<\n" + logged + "\t     >>");
 136             }
 137             if (!logged.contains(expected+lineEnd)) {
 138                 throw new RuntimeException("Marker for parameters[size="
 139                         + i + "] has extra characters"
 140                         + "\n\tgot: <<\n" + logged + "\t     >>");
 141             }
 142 
 143             LogRecord record = handler.events.remove(0);
 144             if (!handler.events.isEmpty()) {
 145                 throw new RuntimeException("Handler has more log records: "
 146                         + handler.events.toString());
 147             }
 148             if (!className.equals(record.getSourceClassName())) {
 149                 throw new RuntimeException("Unexpected class name in LogRecord."
 150                         + "\n\texpected: " + className
 151                         + "\n\tgot: " + record.getSourceClassName());
 152             }
 153             if (!methodName.equals(record.getSourceMethodName())) {
 154                 throw new RuntimeException("Unexpected method name in LogRecord."
 155                         + "\n\texpected: " + methodName
 156                         + "\n\tgot: " + record.getSourceMethodName());
 157             }
 158             if (!format.equals(record.getMessage())) {
 159                 throw new RuntimeException("Unexpected message format in LogRecord."
 160                         + "\n\texpected: " + format
 161                         + "\n\tgot: " + record.getMessage());
 162             }
 163             if (!Arrays.deepEquals(params, record.getParameters())) {
 164                 throw new RuntimeException("Unexpected parameter array in LogRecord."
 165                         + "\n\texpected: " + Arrays.toString(params)
 166                         + "\n\tgot: " + Arrays.toString(record.getParameters()));
 167             }
 168 
 169             handler.reset();
 170         }
 171     }
 172 
 173 }