/* * #%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 java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; import loci.common.DataTools; import loci.formats.FileStitcher; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.testng.annotations.Factory; /** * Factory for scanning a directory structure and generating instances of * {@link FormatReaderTest} based on the image files found. * <p> * Note that this approach works due to an implementation detail of TestNG. * Ideally we would use the lazy iterator approach instead, but it does not * execute methods in the correct order. For details, see <a * href="http://code.google.com/p/testng/issues/detail?id=19#c6">this * issue</a>. * </p> */ public class FormatReaderTestFactory { // -- Constants -- private static final Logger LOGGER = LoggerFactory.getLogger(FormatReaderTestFactory.class); // -- TestNG factory methods -- /** * Safely return a system property by key excluding default Ant values */ public String getProperty(String key) { String value = System.getProperty(key); if (value == null || value.equals("${" + key + "}")) { return null; } return value; } @Factory public Object[] createInstances() { List files = new ArrayList(); // parse explicit filename, if any final String nameProp = "testng.filename"; String filename = getProperty(nameProp); if (filename != null && !new File(filename).exists()) { LOGGER.error("Invalid filename: {}", filename); return new Object[0]; } String baseDir = null; String[] validSubdirs = null; if (filename == null) { // parse base directory final String baseDirProp = "testng.directory"; baseDir = getProperty(baseDirProp); if (baseDir == null) { baseDir = getProperty("testng.directory-prefix"); String dirList = System.getProperty("testng.directory-list"); try { validSubdirs = DataTools.readFile(dirList).split("\n"); } catch (IOException e) { LOGGER.debug("", e); } } // Return early if no base directory is supplied if (baseDir == null) { LOGGER.error("No base directory specified."); LOGGER.error("Please specify a directory containing files to test:"); LOGGER.error(" ant -D{}=\"/path/to/data\" test-all", baseDirProp); return new Object[0]; } // Test base directory validity File baseDirFile = new File(baseDir); if (!baseDirFile.isDirectory()) { LOGGER.info("Directory: {}", baseDir); LOGGER.info(" exists?: {}", baseDirFile.exists()); LOGGER.info(" readable?: {}", baseDirFile.canRead()); LOGGER.info(" is a directory?: {}", baseDirFile.isDirectory()); LOGGER.error("Please specify a directory containing files to test:"); LOGGER.error(" ant -D{}=\"/path/to/data\" test-all", baseDirProp); return new Object[0]; } // check for an alternate configuration directory final String configDirProperty = "testng.configDirectory"; String configDir = getProperty(configDirProperty); LOGGER.info("testng.directory = {}", baseDir); if (configDir != null) { LOGGER.info("testng.configDirectory = {}", configDir); } FormatReaderTest.configTree = new ConfigurationTree(baseDir, configDir); } // parse multiplier final String multProp = "testng.multiplier"; String mult = getProperty(multProp); float multiplier = 1; if (mult != null) { try { multiplier = Float.parseFloat(mult); } catch (NumberFormatException exc) { LOGGER.warn("Invalid multiplier: {}", mult); } } LOGGER.info("testng.multiplier = {}", multiplier); // detect whether or not the map the files into memory final String inMemoryProp = "testng.in-memory"; String inMemoryValue = getProperty(inMemoryProp); boolean inMemory = Boolean.parseBoolean(inMemoryValue); LOGGER.info("testng.in-memory = {}", inMemory); // check for an alternate top level configuration file final String toplevelConfig = "testng.toplevel-config"; String configFile = getProperty(toplevelConfig); if (configFile != null) { LOGGER.info("testng.toplevel-config = {}", configFile); } // check for a configuration file suffix final String configSuffixProperty = "testng.configSuffix"; String configSuffix = getProperty(configSuffixProperty); if (configSuffix == null) { configSuffix = ""; } // display local information LOGGER.info("user.language = {}", System.getProperty("user.language")); LOGGER.info("user.country = {}", System.getProperty("user.country")); // detect maximum heap size long maxMemory = Runtime.getRuntime().maxMemory() >> 20; LOGGER.info("Maximum heap size = {} MB", maxMemory); if (filename == null) { // scan for files System.out.println("Scanning for files..."); long start = System.currentTimeMillis(); try { TestTools.getFiles(baseDir, files, FormatReaderTest.configTree, configFile, validSubdirs, configSuffix); } catch (Exception e) { LOGGER.info("Failed to retrieve complete list of files", e); } long end = System.currentTimeMillis(); double time = (end - start) / 1000.0; LOGGER.info(TestTools.DIVIDER); LOGGER.info("Total files: {}", files.size()); long avg = (end - start); if (files.size() > 0) avg /= files.size(); LOGGER.info("Scan time: {} s ({} ms/file)", time, avg); LOGGER.info(TestTools.DIVIDER); } else { files.add(filename); } // remove duplicates int index = 0; FileStitcher reader = new FileStitcher(TestTools.getTestImageReader()); while (index < files.size()) { String file = (String) files.get(index); try { reader.setId(file); String[] usedFiles = reader.getUsedFiles(); for (int q=0; q<usedFiles.length; q++) { if (files.indexOf(usedFiles[q]) > index) { files.remove(usedFiles[q]); } } } catch (Exception e) { } finally { try { reader.close(); } catch (IOException e) { } } index++; } // create test class instances System.out.println("Building list of tests..."); Object[] tests = new Object[files.size()]; for (int i=0; i<tests.length; i++) { String id = (String) files.get(i); try { if (FormatReaderTest.configTree.get(id) == null) { LOGGER.error("{} not configured.", id); } } catch (Exception e) { LOGGER.warn("", e); } tests[i] = new FormatReaderTest(id, multiplier, inMemory); } if (tests.length == 1) System.out.println("Ready to test " + files.get(0)); else System.out.println("Ready to test " + tests.length + " files"); return tests; } }