1 /*
   2  * Copyright (c) 2014, 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 import java.io.File;
  25 import java.io.FileOutputStream;
  26 import java.io.IOException;
  27 import java.io.InputStream;
  28 import java.lang.reflect.InvocationTargetException;
  29 import java.lang.reflect.Method;
  30 import java.lang.reflect.UndeclaredThrowableException;
  31 import java.util.Arrays;
  32 
  33 /**
  34  * @test a unit test for sun.security.provider.FileInputStreamPool
  35  * @bug 8047769
  36  * @summary test behaviour of sun.security.provider.FileInputStreamPool
  37  */
  38 
  39 public class FileInputStreamPoolTest {
  40 
  41     static final byte[] bytes = new byte[]{1, 2, 3, 4, 5, 6, 7, 8};
  42 
  43     static void testCaching(File file) throws IOException {
  44         InputStream in1 = FileInputStreamPoolProxy.getInputStream(file);
  45         InputStream in2 = FileInputStreamPoolProxy.getInputStream(file);
  46         assert in1 == in2;
  47 
  48         byte[] readBytes = new byte[bytes.length];
  49         int nread = in1.read(readBytes);
  50         assert nread == bytes.length; // if this fails then we are already at EOF?
  51         assert Arrays.equals(readBytes, bytes);
  52     }
  53 
  54     public static void main(String[] args) throws Exception {
  55         // 1st create temporary file
  56         File file = File.createTempFile("test", ".dat");
  57         try {
  58             try (FileOutputStream out = new FileOutputStream(file)) {
  59                 out.write(bytes);
  60             }
  61 
  62             // test caching 1t time
  63             testCaching(file);
  64 
  65             // make GC process WeakReferences
  66             System.gc();
  67             // wait a while for ReferenceHandler to enqueue WeakReferences
  68             // if this fails on slow or busy machines, sleep should be
  69             // replaced with:
  70             //   while (java.lang.ref.Reference.tryHandlePending(false)) {}
  71             Thread.sleep(500L);
  72 
  73             // test caching 2nd time - this should only succeed if
  74             // the stream has been closed and re-opened as a consequence
  75             // of cleared WeakReference
  76             testCaching(file);
  77         } finally {
  78             file.delete();
  79         }
  80     }
  81 
  82     /**
  83      * A proxy for package-private sun.security.provider.FileInputStreamPool
  84      */
  85     static class FileInputStreamPoolProxy {
  86         private static final Method getInputStreamMethod;
  87 
  88         static {
  89             try {
  90                 Class<?> fileInputStreamPoolClass = Class.forName("sun.security.provider.FileInputStreamPool");
  91                 getInputStreamMethod = fileInputStreamPoolClass.getDeclaredMethod("getInputStream", File.class);
  92                 getInputStreamMethod.setAccessible(true);
  93             } catch (Exception e) {
  94                 throw new Error(e);
  95             }
  96         }
  97 
  98         static InputStream getInputStream(File file) throws IOException {
  99             try {
 100                 return (InputStream) getInputStreamMethod.invoke(null, file);
 101             } catch (InvocationTargetException e) {
 102                 Throwable te = e.getTargetException();
 103                 if (te instanceof IOException) {
 104                     throw (IOException) te;
 105                 } else if (te instanceof RuntimeException) {
 106                     throw (RuntimeException) te;
 107                 } else if (te instanceof Error) {
 108                     throw (Error) te;
 109                 } else {
 110                     throw new UndeclaredThrowableException(te);
 111                 }
 112             } catch (IllegalAccessException e) {
 113                 throw new RuntimeException(e);
 114             }
 115         }
 116     }
 117 }