/*
* #%L
* OME Bio-Formats manual and automated test suite.
* %%
* Copyright (C) 2006 - 2015 Open Microscopy Environment:
* - Board of Regents of the University of Wisconsin-Madison
* - Glencoe Software, Inc.
* - University of Dundee
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-2.0.html>.
* #L%
*/
package loci.tests.testng;
import static org.testng.AssertJUnit.*;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.util.ArrayList;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
import loci.common.Constants;
import loci.formats.FormatException;
import loci.formats.IFormatReader;
import loci.formats.ImageReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Checks that no file handles are open after closing a reader.
* This will not work on Windows, as it depends upon the 'lsof' command.
*
* @author Melissa Linkert melissa at glencoesoftware.com
*/
public class FileHandleTest {
private static final Logger LOGGER =
LoggerFactory.getLogger(FileHandleTest.class);
private String id;
private IFormatReader reader;
@Parameters({"id"})
@BeforeClass
public void init(String id) {
this.id = id;
}
@Test
public void testHandleCount() throws FormatException, IOException {
ArrayList<String> initialHandles = getHandles();
reader = new ImageReader();
reader.setId(id);
ArrayList<String> intermediateHandles = getHandles();
reader.close();
ArrayList<String> finalHandles = getHandles();
int intermediateHandleCount = intermediateHandles.size();
for (int i=0; i<initialHandles.size(); i++) {
String s = initialHandles.get(i);
initialHandles.remove(s);
finalHandles.remove(s);
intermediateHandles.remove(s);
i--;
}
for (int i=0; i<finalHandles.size(); i++) {
String s = finalHandles.get(i);
if (s.endsWith("libnio.so") || s.endsWith("resources.jar") ||
s.startsWith("/usr/lib") || s.startsWith("/opt/") ||
s.startsWith("/usr/share/locale") || s.startsWith("/lib") ||
s.indexOf("turbojpeg") > 0 || s.indexOf("/jre/") > 0)
{
finalHandles.remove(s);
i--;
}
else {
LOGGER.warn(s);
}
}
assertEquals(finalHandles.size(), initialHandles.size());
assertTrue(intermediateHandles.size() >= initialHandles.size());
assertTrue(intermediateHandleCount < 1024);
}
private ArrayList<String> getHandles() throws IOException {
ArrayList<String> names = new ArrayList<String>();
String pid = ManagementFactory.getRuntimeMXBean().getName();
pid = pid.substring(0, pid.indexOf("@"));
Runtime rt = Runtime.getRuntime();
Process p = rt.exec("lsof -Ftn -p " + pid);
BufferedReader s = new BufferedReader(
new InputStreamReader(p.getInputStream(), Constants.ENCODING));
String line = s.readLine();
boolean valid = false;
while (true) {
try {
p.exitValue();
if (line == null) {
break;
}
}
catch (IllegalThreadStateException e) {
LOGGER.trace("", e);
}
catch (Exception e) {
LOGGER.warn("", e);
}
if (line != null && line.endsWith("REG")) {
valid = true;
}
else if (line != null && line.startsWith("n") && valid) {
names.add(line.substring(1, line.length()));
valid = false;
}
line = s.readLine();
}
s.close();
p.getInputStream().close();
p.getOutputStream().close();
p.getErrorStream().close();
return names;
}
}