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