1/* 2 * Copyright (c) 1997, 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 4094889 26 * @summary rmid can have a corrupted log 27 * 28 * @modules java.rmi/sun.rmi.log 29 * @run main/othervm LogAlignmentTest 30 */ 31 32/* Fault: ReliableLog used RandomAccessFile.skipBytes() to seek past the end 33 * of a file. Unfortunately, skipBytes() doesn't do that, so the file was 34 * being misaligned. 35 * 36 * Reproduced by writing an odd number of bytes into an update, and then 37 * reloading. 38 */ 39 40import java.io.File; 41import java.io.PrintStream; 42import java.io.Serializable; 43import sun.rmi.log.LogHandler; 44import sun.rmi.log.ReliableLog; 45 46//import javasoft.sqe.harness.Status; 47//import javasoft.sqe.harness.Test; 48 49public class LogAlignmentTest 50 extends LogHandler 51 implements Serializable //, Test 52{ 53 static public void main (String[] argv) 54 { 55 LogAlignmentTest test = new LogAlignmentTest(); 56 //Status status = test.run (argv, System.err, System.out); 57 //status.exit(); 58 test.run (argv, System.err, System.out); 59 } 60 61 //public Status run (String argv[], PrintStream log, PrintStream out) 62 public void run (String argv[], PrintStream log, PrintStream out) 63 { 64 try { 65 regtest(130, "./logalign_tmp", log, out); 66 regtest(131, "./logalign_tmp", log, out); 67 } catch (Exception e) { 68 e.printStackTrace (log); 69 //return (Status.failed 70 throw (new RuntimeException 71 ("Exception in regression test for bugid 4094889")); 72 } 73 //return (Status.passed ("OKAY")); 74 } 75 76 static private void regtest(int updatesz, String dir, PrintStream lg, PrintStream out) 77 throws Exception 78 { 79 try { 80 LogAlignmentTest handler = new LogAlignmentTest(); 81 ReliableLog log = new ReliableLog (dir, handler, false); 82 83 // Write a preamble update 84 String c = "["; 85 handler.basicUpdate (c); 86 log.update (c, true); 87 88 // Generate the requested size update (single chars) 89 char[] up = new char[updatesz]; 90 int i; 91 for (i = 0; i < updatesz; i++) { 92 up[i] = (char)(65 + (i % 26)); 93 } 94 c = new String (up); 95 handler.basicUpdate (c); 96 log.update (c, true); 97 98 // Write it again, so we can misalign 99 handler.basicUpdate (c); 100 log.update (c, true); 101 102 // Write the suffix 103 c = "]"; 104 handler.basicUpdate (c); 105 log.update (c, true); 106 107 // Read it back using a new context. 108 LogAlignmentTest handler2 = new LogAlignmentTest(); 109 ReliableLog carbon = new ReliableLog (dir, handler2, false); 110 Object thingy = carbon.recover(); 111 112 // The report bit 113 String orig = handler.contents; 114 String news = ((LogAlignmentTest)thingy).contents; 115 lg.println ("Original as saved: " + orig); 116 lg.println ("As restored : " + news); 117 if (orig.compareTo (news) != 0) { 118 throw new RuntimeException ("Restored string was different from saved string"); 119 } else { 120 lg.println ("Matched OK. Test element passed."); 121 } 122 } finally { 123 // Trash the log directory, so a new snap will be taken in the next test 124 try { 125 File vs = new File (dir, "Version_Number"); 126 vs.delete(); 127 } catch (Exception e) { 128 } 129 try { 130 File vs = new File (dir, "New_Version_Number"); 131 vs.delete(); 132 } catch (Exception e) { 133 } 134 } 135 } 136 137 private String contents; 138 139 public LogAlignmentTest() 140 { 141 super(); 142 this.contents = "?"; 143 } 144 145 // implements LogHandler.initialSnapshot() 146 public Object initialSnapshot() 147 throws Exception 148 { 149 this.contents = ""; 150 return (this); 151 } 152 153 // implements LogHandler.applyUpdate() 154 public Object applyUpdate (Object update, Object state) 155 throws Exception 156 { 157 // basicUpdate appends the string 158 ((LogAlignmentTest)state).basicUpdate ((String)update); 159 return (state); 160 } 161 162 // an "update" is a short string to append to this.contents (must ignore state) 163 public void basicUpdate (String extra) 164 { 165 this.contents = this.contents + extra; 166 } 167} 168