1 /* 2 * Copyright (c) 2001, 2013, 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 /* @test 25 * @bug 4402649 26 * @summary RMI should use new logging APIs. Unit test to exercise 27 * RMI's use of the java.util.logging API. 28 * @author Laird Dornin 29 * 30 * @library ../../../../../java/rmi/testlibrary 31 * @modules java.rmi/sun.rmi.registry 32 * java.rmi/sun.rmi.server 33 * java.rmi/sun.rmi.transport 34 * java.rmi/sun.rmi.transport.tcp 35 * @build TestLibrary 36 * @run main/othervm CheckLogging 37 */ 38 39 import java.util.logging.Level; 40 import java.util.logging.LogRecord; 41 import java.util.logging.Logger; 42 import java.util.logging.SimpleFormatter; 43 import java.util.logging.StreamHandler; 44 45 import java.io.ByteArrayOutputStream; 46 import java.io.IOException; 47 import java.io.PrintStream; 48 import java.io.OutputStream; 49 50 import java.rmi.RemoteException; 51 import java.rmi.Remote; 52 import java.rmi.Naming; 53 import java.rmi.registry.LocateRegistry; 54 import java.rmi.server.LogStream; 55 import java.rmi.server.RemoteServer; 56 57 import java.rmi.registry.Registry; 58 59 /** 60 * Perform following checks: 61 * 62 * 1. If using java.util.logging, turn on client call logger using 63 * system property, "sun.rmi.client.logCalls". Collect client call 64 * output using a custom stream handler. Verify client call output is 65 * generated and contains the string "outbound call". 66 * 67 * 2. Turn on server call using 68 * RemoteServer.setLog(ByteArrayOutputStream). Invoke some remote 69 * method calls verify logger output is non-null. 70 * 71 * Turn off server call log by doing setLog(null), verify output is 72 * zero length. Verify that RemoteServer.getLog == null 73 * 74 * Use setLog to turn call log back on. Invoke remote method that 75 * throws an exception and contains the string "exception". 76 * 77 * 3. Print directly to return value of RemoteServer.getLog(), verify 78 * logger output is non-null. 79 */ 80 public class CheckLogging { 81 private static int REGISTRY_PORT = -1; 82 private static String LOCATION; 83 private static Logger logger; 84 85 private static final ByteArrayOutputStream clientCallOut = 86 new ByteArrayOutputStream(); 87 88 private static final boolean usingOld = 89 Boolean.getBoolean("sun.rmi.log.useOld"); 90 91 static { 92 System.setProperty("sun.rmi.client.logCalls", "true"); 93 if (usingOld) { 94 System.err.println("set default stream"); 95 LogStream.setDefaultStream(new PrintStream(clientCallOut)); 96 } else { 97 logger = Logger.getLogger("sun.rmi.client.call"); 98 logger.addHandler(new InternalStreamHandler(clientCallOut)); 99 } 100 } 101 102 /* use registry to generate client & server call log info */ 103 private static Registry registry; 104 static { 105 try { 106 registry = TestLibrary.createRegistryOnUnusedPort(); 107 REGISTRY_PORT = TestLibrary.getRegistryPort(registry); 108 LOCATION = "rmi://localhost:" + REGISTRY_PORT + "/"; 109 } catch (Exception e) { 110 TestLibrary.bomb("could not create registry"); 111 } 112 } 113 114 /** 115 * Used to collect output from specific loggers 116 */ 117 private static class InternalStreamHandler extends StreamHandler { 118 private InternalStreamHandler(OutputStream out) { 119 super(out, new SimpleFormatter()); 120 setLevel(Level.ALL); 121 } 122 123 public void publish(LogRecord record) { 124 super.publish(record); 125 flush(); 126 } 127 128 public void close() { 129 flush(); 130 } 131 } 132 133 /** 134 * Ensure that a log has some output and that it contains a 135 * certain string 136 */ 137 private static void verifyLog(ByteArrayOutputStream bout, 138 String mustContain) 139 { 140 byte[] bytes = bout.toByteArray(); 141 if (bytes.length == 0) { 142 TestLibrary.bomb("log data length is zero"); 143 } else if ((mustContain != null) && 144 (bout.toString().indexOf(mustContain) < 0)) 145 { 146 TestLibrary.bomb("log output did not contain: " + mustContain); 147 } 148 } 149 150 /** 151 * Check serverCallLog output 152 */ 153 private static void checkServerCallLog() throws Exception { 154 ByteArrayOutputStream serverCallLog = new ByteArrayOutputStream(); 155 RemoteServer.setLog(serverCallLog); 156 Naming.list(LOCATION); 157 verifyLog(serverCallLog, "list"); 158 159 serverCallLog.reset(); 160 RemoteServer.setLog(null); 161 PrintStream callStream = RemoteServer.getLog(); 162 if (callStream != null) { 163 TestLibrary.bomb("call stream not null after calling " + 164 "setLog(null)"); 165 } else { 166 System.err.println("call stream should be null and it is"); 167 } 168 Naming.list(LOCATION); 169 170 if (usingOld) { 171 if (serverCallLog.toString().indexOf("UnicastServerRef") >= 0) { 172 TestLibrary.bomb("server call logging not turned off"); 173 } 174 } else if (serverCallLog.toByteArray().length != 0) { 175 TestLibrary.bomb("call log contains output but it " + 176 "should be empty"); 177 } 178 179 serverCallLog.reset(); 180 RemoteServer.setLog(serverCallLog); 181 try { 182 // generates a notbound exception 183 Naming.lookup(LOCATION + "notthere"); 184 } catch (Exception e) { 185 } 186 verifyLog(serverCallLog, "exception"); 187 188 serverCallLog.reset(); 189 RemoteServer.setLog(serverCallLog); 190 callStream = RemoteServer.getLog(); 191 callStream.println("bingo, this is a getLog test"); 192 verifyLog(serverCallLog, "bingo"); 193 } 194 195 private static void checkPermissions() { 196 SecurityException ex = null; 197 try { 198 // should fail for lack of LoggingPermission "control" 199 RemoteServer.setLog(System.err); 200 } catch (SecurityException e) { 201 System.err.println("security excepton caught correctly"); 202 ex = e; 203 } 204 if (ex == null) { 205 TestLibrary.bomb("able to set log without permission"); 206 } 207 } 208 209 public static void main(String[] args) { 210 try { 211 checkServerCallLog(); 212 213 if (!usingOld) { 214 verifyLog(clientCallOut, "outbound call"); 215 System.setSecurityManager(new java.lang.SecurityManager()); 216 checkPermissions(); 217 } 218 System.err.println("TEST PASSED"); 219 220 } catch (Exception e) { 221 if (e instanceof RuntimeException) { 222 throw (RuntimeException) e; 223 } 224 TestLibrary.bomb("unexpected exception", e); 225 } finally { 226 TestLibrary.unexport(registry); 227 } 228 } 229 }