1 /* 2 * Copyright (c) 2005, 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 /** 25 * @test 26 * @bug 6348045 27 * @summary GZipOutputStream/InputStream goes critical(calls JNI_Get*Critical) 28 * and causes slowness. This test uses Deflater and Inflater directly. 29 */ 30 31 import java.io.*; 32 import java.nio.*; 33 import java.util.*; 34 import java.util.zip.*; 35 36 /** 37 * This test runs Inflater and Defalter in a number of simultaneous threads, 38 * validating that the deflated & then inflated data matches the original 39 * data. 40 */ 41 public class FlaterTest extends Thread { 42 private static final int DATA_LEN = 1024 * 128; 43 private static byte[] data; 44 45 // If true, print extra info. 46 private static final boolean debug = false; 47 48 // Set of Flater threads running. 49 private static Set flaters = 50 Collections.synchronizedSet(new HashSet()); 51 52 /** Fill in {@code data} with random values. */ 53 static void createData() { 54 ByteBuffer bb = ByteBuffer.allocate(8); 55 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 56 for (int i = 0; i < DATA_LEN; i++) { 57 bb.putDouble(0, Math.random()); 58 baos.write(bb.array(), 0, 8); 59 } 60 data = baos.toByteArray(); 61 if (debug) System.out.println("data length is " + data.length); 62 } 63 64 /** @return the length of the deflated {@code data}. */ 65 private static int getDeflatedLength() throws Throwable { 66 int rc = 0; 67 Deflater deflater = new Deflater(); 68 deflater.setInput(data); 69 deflater.finish(); 70 byte[] out = new byte[data.length]; 71 rc = deflater.deflate(out); 72 deflater.end(); 73 if (debug) System.out.println("deflatedLength is " + rc); 74 return rc; 75 } 76 77 /** Compares given bytes with those in {@code data}. 78 * @throws Exception if given bytes don't match {@code data}. 79 */ 80 private static void validate(byte[] buf, int offset, int len) throws Exception { 81 for (int i = 0; i < len; i++ ) { 82 if (buf[i] != data[offset+i]) { 83 throw new Exception("mismatch at " + (offset + i)); 84 } 85 } 86 } 87 88 public static void realMain(String[] args) throws Throwable { 89 createData(); 90 int numThreads = args.length > 0 ? Integer.parseInt(args[0]) : 5; 91 new FlaterTest().go(numThreads); 92 } 93 94 synchronized private void go(int numThreads) throws Throwable { 95 int deflatedLength = getDeflatedLength(); 96 97 long time = System.currentTimeMillis(); 98 for (int i = 0; i < numThreads; i++) { 99 Flater f = new Flater(deflatedLength); 100 flaters.add(f); 101 f.start(); 102 } 103 while (flaters.size() != 0) { 104 try { 105 Thread.currentThread().sleep(10); 106 } catch (InterruptedException ex) { 107 unexpected(ex); 108 } 109 } 110 time = System.currentTimeMillis() - time; 111 System.out.println("Time needed for " + numThreads 112 + " threads to deflate/inflate: " + time + " ms."); 113 } 114 115 /** Deflates and inflates data. */ 116 static class Flater extends Thread { 117 private final int deflatedLength; 118 119 private Flater(int length) { 120 this.deflatedLength = length; 121 } 122 123 /** Deflates and inflates {@code data}. */ 124 public void run() { 125 if (debug) System.out.println(getName() + " starting run()"); 126 try { 127 byte[] deflated = DeflateData(deflatedLength); 128 InflateData(deflated); 129 } catch (Throwable t) { 130 t.printStackTrace(); 131 fail(getName() + " failed"); 132 } finally { 133 flaters.remove(this); 134 } 135 } 136 137 /** Returns a copy of {@code data} in deflated form. */ 138 private byte[] DeflateData(int length) throws Throwable { 139 Deflater deflater = new Deflater(); 140 deflater.setInput(data); 141 deflater.finish(); 142 byte[] out = new byte[length]; 143 deflater.deflate(out); 144 return out; 145 } 146 147 /** Inflate a byte array, comparing it with {@code data} during 148 * inflation. 149 * @throws Exception if inflated bytes don't match {@code data}. 150 */ 151 private void InflateData(byte[] bytes) throws Throwable { 152 Inflater inflater = new Inflater(); 153 inflater.setInput(bytes, 0, bytes.length); 154 int len = 1024 * 8; 155 int offset = 0; 156 while (inflater.getRemaining() > 0) { 157 byte[] buf = new byte[len]; 158 int inflated = inflater.inflate(buf, 0, len); 159 validate(buf, offset, inflated); 160 offset += inflated; 161 } 162 } 163 } 164 165 //--------------------- Infrastructure --------------------------- 166 static volatile int passed = 0, failed = 0; 167 static void pass() {passed++;} 168 static void fail() {failed++; Thread.dumpStack();} 169 static void fail(String msg) {System.out.println(msg); fail();} 170 static void unexpected(Throwable t) {failed++; t.printStackTrace();} 171 static void check(boolean cond) {if (cond) pass(); else fail();} 172 static void equal(Object x, Object y) { 173 if (x == null ? y == null : x.equals(y)) pass(); 174 else fail(x + " not equal to " + y);} 175 public static void main(String[] args) throws Throwable { 176 try {realMain(args);} catch (Throwable t) {unexpected(t);} 177 System.out.println("\nPassed = " + passed + " failed = " + failed); 178 if (failed > 0) throw new AssertionError("Some tests failed");} 179 }