< prev index next >

test/hotspot/jtreg/runtime/8176717/TestInheritFD.java

changes after first review

0 import static java.io.File.createTempFile;                                                                                 
1 import static java.lang.Long.parseLong;                                                                                    
2 import static java.lang.System.getProperty;                                                                                
3 import static java.lang.management.ManagementFactory.getOperatingSystemMXBean;                                             
4 import static java.nio.file.Files.readAllBytes;                                                                            
5 import static java.nio.file.Files.readSymbolicLink;                                                                        
6 import static java.util.Arrays.stream;                                                                                     
                                                                                                                           
                                                                                                                           
7 import static java.util.stream.Collectors.joining;                                                                         
8 import static jdk.test.lib.process.ProcessTools.createJavaProcessBuilder;                                                  
9 
10 import java.io.File;                                                                                                       
                                                                                                                           
                                                                                                                           
11 import java.io.IOException;                                                                                                
                                                                                                                           
12 
13 import com.sun.management.UnixOperatingSystemMXBean;                                                                       
14 
15 /*                                                                                                                         
16  * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.                                                  
17  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.                                                           
18  *                                                                                                                         
19  * This code is free software; you can redistribute it and/or modify it                                                    
20  * under the terms of the GNU General Public License version 2 only, as                                                    
21  * published by the Free Software Foundation.                                                                              
22  *                                                                                                                         
23  * This code is distributed in the hope that it will be useful, but WITHOUT                                                
24  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or                                                   
25  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License                                                   
26  * version 2 for more details (a copy is included in the LICENSE file that                                                 
27  * accompanied this code).                                                                                                 
28  *                                                                                                                         
29  * You should have received a copy of the GNU General Public License version                                               
30  * 2 along with this work; if not, write to the Free Software Foundation,                                                  

0 import static java.io.File.createTempFile;
1 import static java.lang.Long.parseLong;
2 import static java.lang.System.getProperty;
3 import static java.lang.management.ManagementFactory.getOperatingSystemMXBean;
4 import static java.nio.file.Files.readAllBytes;
5 import static java.nio.file.Files.readSymbolicLink;
6 import static java.util.Arrays.stream;
7 import static java.util.Optional.empty;
8 import static java.util.Optional.of;
9 import static java.util.stream.Collectors.joining;
10 import static jdk.test.lib.process.ProcessTools.createJavaProcessBuilder;
11 
12 import java.io.File;
13 import java.io.FileNotFoundException;
14 import java.io.FileOutputStream;
15 import java.io.IOException;
16 import java.util.Optional;
17 
18 import com.sun.management.UnixOperatingSystemMXBean;
19 
20 /*
21  * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
22  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
23  *
24  * This code is free software; you can redistribute it and/or modify it
25  * under the terms of the GNU General Public License version 2 only, as
26  * published by the Free Software Foundation.
27  *
28  * This code is distributed in the hope that it will be useful, but WITHOUT
29  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
30  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
31  * version 2 for more details (a copy is included in the LICENSE file that
32  * accompanied this code).
33  *
34  * You should have received a copy of the GNU General Public License version
35  * 2 along with this work; if not, write to the Free Software Foundation,

106             ProcessBuilder pb = createJavaProcessBuilder(                                                                  
107                 "-Dtest.jdk=" + getProperty("test.jdk"),                                                                   
108                 VMShouldNotInheritFileDescriptors.class.getName(),                                                         
109                 args[0],                                                                                                   
110                 "" + ProcessHandle.current().pid(),                                                                        
111                 "" + (supportsUnixMXBean()?+unixNrFD():-1));                                                               
112             pb.inheritIO(); // in future, redirect information from third VM to first VM                                   
113             pb.start();                                                                                                    
114 
115             findOpenLogFile();                                                                                             
116         }                                                                                                                  
117     }                                                                                                                      
118 
119     static class VMShouldNotInheritFileDescriptors {                                                                       
120         // third VM                                                                                                        
121         public static void main(String[] args) throws InterruptedException {                                               
122             File logFile = new File(args[0]);                                                                              
123             long parentPid = parseLong(args[1]);                                                                           
124             long parentFDCount = parseLong(args[2]);                                                                       
125 
                                                                                                                           
                                                                                                                           
126             if(supportsUnixMXBean()){                                                                                      
127                 long thisFDCount = unixNrFD();                                                                             
128                 System.out.println("This VM FD-count ("                                                                    
129                         + thisFDCount                                                                                      
130                         + ") should be strictly less than parent VM FD-count ("                                            
131                         + parentFDCount                                                                                    
132                         + ") as log file should have been closed, HOWEVER, THIS CAN NOT BE RELIED"                         
133                         + " ON as files in /proc and /sys is opened by the JVM");                                          
134                 System.out.println(findOpenLogFile()?LEAKS_FD:RETAINS_FD);                                                 
135             } else if (getProperty("os.name").toLowerCase().contains("win")) {                                             
136                 windows(logFile, parentPid);                                                                               
137             } else {                                                                                                       
138                 System.out.println(LEAKS_FD); // default fail on unknown configuration                                     
139             }                                                                                                              
140             System.out.println(EXIT);                                                                                      
141         }                                                                                                                  
142     }                                                                                                                      
143 
144     static boolean supportsUnixMXBean() {                                                                                  
145         return getOperatingSystemMXBean() instanceof UnixOperatingSystemMXBean;                                            
146     }                                                                                                                      
147 
148     static long unixNrFD() {                                                                                               
149         UnixOperatingSystemMXBean osBean = (UnixOperatingSystemMXBean) getOperatingSystemMXBean();                         
150         return osBean.getOpenFileDescriptorCount();                                                                        
151     }                                                                                                                      
152 
153     static File linkTarget(File f) {                                                                                       
154         try {                                                                                                              
155             return readSymbolicLink(f.toPath()).toFile();                                                                  
156         } catch (IOException e) {                                                                                          
157             return new File("Error: could not read symbolic link (last link can not be read as it points to the /proc/self/
                                                                                                                           
                                                                                                                           
                                                                                                                           
                                                                                                                           
                                                                                                                           
                                                                                                                           
                                                                                                                           
                                                                                                                           
                                                                                                                           
                                                                                                                           
158         }                                                                                                                  
159     }                                                                                                                      
160 
161     static boolean findOpenLogFile() {                                                                                     
162         File dir = new File("/proc/self/fd");                                                                              
163 
164         System.out.println("Open file descriptors:\n" + stream(dir.listFiles())                                            
165             .map(f -> "###" + f.getAbsolutePath() + " -> " + linkTarget(f))                                                
166             .collect(joining("\n")));                                                                                      
167 
168         return stream(dir.listFiles())                                                                                     
169             .map(TestInheritFD::linkTarget)                                                                                
170             .filter(f -> f.getName().endsWith(LOG_SUFFIX))                                                                 
                                                                                                                           
171             .findAny()                                                                                                     
172             .isPresent();                                                                                                  
173     }                                                                                                                      
174 
175     static void windows(File f, long parentPid) throws InterruptedException {                                              
176         System.out.println("waiting for pid: " + parentPid);                                                               
177         ProcessHandle.of(parentPid).ifPresent(handle -> handle.onExit().join());                                           
178         System.out.println("trying to rename file to the same name: " + f);                                                
179         System.out.println(f.renameTo(f)?RETAINS_FD:LEAKS_FD); // this parts communicates a closed file descriptor by print
180     }                                                                                                                      

111             ProcessBuilder pb = createJavaProcessBuilder(
112                 "-Dtest.jdk=" + getProperty("test.jdk"),
113                 VMShouldNotInheritFileDescriptors.class.getName(),
114                 args[0],
115                 "" + ProcessHandle.current().pid(),
116                 "" + (supportsUnixMXBean()?+unixNrFD():-1));
117             pb.inheritIO(); // in future, redirect information from third VM to first VM
118             pb.start();
119 
120             findOpenLogFile();
121         }
122     }
123 
124     static class VMShouldNotInheritFileDescriptors {
125         // third VM
126         public static void main(String[] args) throws InterruptedException {
127             File logFile = new File(args[0]);
128             long parentPid = parseLong(args[1]);
129             long parentFDCount = parseLong(args[2]);
130 
131             fakeLeakyJVM(false);
132 
133             if(supportsUnixMXBean()){
134                 long thisFDCount = unixNrFD();
135                 System.out.println("This VM FD-count ("
136                         + thisFDCount
137                         + ") should be strictly less than parent VM FD-count ("
138                         + parentFDCount
139                         + ") as log file should have been closed, HOWEVER, THIS CAN NOT BE RELIED"
140                         + " ON as files in /proc and /sys are opened by the JVM");
141                 System.out.println(findOpenLogFile() ? LEAKS_FD : RETAINS_FD);
142             } else if (getProperty("os.name").toLowerCase().contains("win")) {
143                 windows(logFile, parentPid);
144             } else {
145                 System.out.println(LEAKS_FD); // default fail on unknown configuration
146             }
147             System.out.println(EXIT);
148         }
149     }
150 
151     static boolean supportsUnixMXBean() {
152         return getOperatingSystemMXBean() instanceof UnixOperatingSystemMXBean;
153     }
154 
155     static long unixNrFD() {
156         UnixOperatingSystemMXBean osBean = (UnixOperatingSystemMXBean) getOperatingSystemMXBean();
157         return osBean.getOpenFileDescriptorCount();
158     }
159 
160     static Optional<String> linkTargetName(File f) {
161         try {
162             return of(readSymbolicLink(f.toPath()).toFile().getName());
163         } catch (IOException e) {
164             return empty();
165         }
166     }
167 
168     @SuppressWarnings("resource")
169     static void fakeLeakyJVM(boolean fake) {
170         if (fake) {
171             try {
172                 new FileOutputStream("fakeLeakyJVM" + LOG_SUFFIX, false);
173             } catch (FileNotFoundException e) {
174             }
175         }
176     }
177 
178     static boolean findOpenLogFile() {
179         File dir = new File("/proc/self/fd");
180 
181         System.out.println("Open file descriptors:\n" + stream(dir.listFiles())
182             .map(f -> f.getAbsolutePath() + " maps to: " + linkTargetName(f).orElse("?"))
183             .collect(joining("\n")));
184 
185         return stream(dir.listFiles())
186             .map(TestInheritFD::linkTargetName)
187             .flatMap(Optional::stream)
188             .filter(fileName -> fileName.endsWith(LOG_SUFFIX))
189             .findAny()
190             .isPresent();
191     }
192 
193     static void windows(File f, long parentPid) throws InterruptedException {
194         System.out.println("waiting for pid: " + parentPid);
195         ProcessHandle.of(parentPid).ifPresent(handle -> handle.onExit().join());
196         System.out.println("trying to rename file to the same name: " + f);
197         System.out.println(f.renameTo(f) ? RETAINS_FD : LEAKS_FD); // this parts communicates a closed file descriptor by p
198     }
< prev index next >