001 /*--------------------------------------------------------------------------+ 002 $Id: TestDataManager.java 26268 2010-02-18 10:44:30Z juergens $ 003 | | 004 | Copyright 2005-2010 Technische Universitaet Muenchen | 005 | | 006 | Licensed under the Apache License, Version 2.0 (the "License"); | 007 | you may not use this file except in compliance with the License. | 008 | You may obtain a copy of the License at | 009 | | 010 | http://www.apache.org/licenses/LICENSE-2.0 | 011 | | 012 | Unless required by applicable law or agreed to in writing, software | 013 | distributed under the License is distributed on an "AS IS" BASIS, | 014 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 015 | See the License for the specific language governing permissions and | 016 | limitations under the License. | 017 +--------------------------------------------------------------------------*/ 018 package edu.tum.cs.commons.test; 019 020 import java.io.File; 021 import java.io.FileWriter; 022 import java.io.IOException; 023 import java.io.PrintWriter; 024 import java.util.ArrayList; 025 import java.util.Collections; 026 import java.util.HashMap; 027 import java.util.HashSet; 028 import java.util.Map; 029 030 import junit.framework.TestCase; 031 import edu.tum.cs.commons.collections.TwoDimHashMap; 032 import edu.tum.cs.commons.filesystem.FileSystemUtils; 033 034 /** 035 * Support class for identifying unused test data files. This class provides a 036 * method to access test data files and logs which test cases access which test 037 * files. On every access to a file, access statistic for used and unused files 038 * are written to {@value #REPORT_DIRECTORY_NAME}. 039 * <p> 040 * This class is best used via inheriting from {@link CCSMTestCaseBase}. 041 * 042 * @author Florian Deissenboeck 043 * @author Benjamin Hummel 044 * @author $Author: juergens $ 045 * @version $Rev: 26268 $ 046 * @levd.rating GREEN Hash: 4E808795FAB1BE3BBDA0729E21312104 047 */ 048 public class TestDataManager { 049 050 /** Name of the directory to write reports to. */ 051 public static final String REPORT_DIRECTORY_NAME = "test-tmp"; 052 053 /** Map of all instances (which is indexed by managed directory). */ 054 private static Map<File, TestDataManager> instances = new HashMap<File, TestDataManager>(); 055 056 /** Returns the instance of the test data manager for the given directory. */ 057 public static TestDataManager getInstance(File directory) { 058 if (!instances.containsKey(directory)) { 059 instances.put(directory, new TestDataManager(directory)); 060 } 061 return instances.get(directory); 062 } 063 064 /** The set of unused files. */ 065 private final HashSet<String> unusedFiles = new HashSet<String>(); 066 067 /** Storage for all test files used so far. */ 068 private final TwoDimHashMap<Class<?>, TestCase, HashSet<String>> usedFiles = new TwoDimHashMap<Class<?>, TestCase, HashSet<String>>(); 069 070 /** The directory this manager works in. */ 071 private final File directory; 072 073 /** Private constructor. */ 074 private TestDataManager(File directory) { 075 this.directory = directory; 076 077 if (!directory.exists() || !directory.isDirectory()) { 078 return; 079 } 080 081 for (File file : directory.listFiles()) { 082 if (file.isFile()) { 083 unusedFiles.add(file.getName()); 084 } 085 } 086 } 087 088 /** 089 * Marks the given file as used and returns the complete file (with 090 * directory). 091 */ 092 public File getTestFile(String filename, TestCase testCase) { 093 094 HashSet<String> set = usedFiles.getValue(testCase.getClass(), testCase); 095 if (set == null) { 096 set = new HashSet<String>(); 097 usedFiles.putValue(testCase.getClass(), testCase, set); 098 } 099 100 set.add(filename); 101 unusedFiles.remove(filename); 102 updateUsageReports(); 103 104 return new File(directory, filename); 105 } 106 107 /** 108 * Print a summary on used and unused test data files into a directory 109 * specific log file. 110 */ 111 private void updateUsageReports() { 112 try { 113 File baseDir = new File(REPORT_DIRECTORY_NAME); 114 FileSystemUtils.ensureDirectoryExists(baseDir); 115 String fname = directory.toString().replaceAll("[\\\\/]", "_"); 116 117 PrintWriter pw = new PrintWriter(new FileWriter(new File(baseDir, 118 fname + "_usage.txt"))); 119 printUsedFiles(pw); 120 pw.close(); 121 122 pw = new PrintWriter(new FileWriter(new File(baseDir, fname 123 + "_unusage.txt"))); 124 printUnusedFiles(pw); 125 pw.close(); 126 } catch (IOException e) { 127 // This is the best we can do (as we are in testing) 128 e.printStackTrace(); 129 } 130 } 131 132 /** Print a report on all files not used. */ 133 public void printUnusedFiles(PrintWriter pw) { 134 pw.println("Unused files for directory " + directory + ": " 135 + unusedFiles.size()); 136 ArrayList<String> fileList = new ArrayList<String>(unusedFiles); 137 Collections.sort(fileList); 138 for (String filename : fileList) { 139 pw.print(" "); 140 pw.println(filename); 141 } 142 143 pw.flush(); 144 } 145 146 /** Print a report on all files used. */ 147 public void printUsedFiles(PrintWriter pw) { 148 pw.println("Used files for directory " + directory); 149 150 for (Class<?> clazz : usedFiles.getFirstKeys()) { 151 pw.print(" "); 152 pw.println(clazz.getName()); 153 for (TestCase testCase : usedFiles.getSecondKeys(clazz)) { 154 pw.print(" "); 155 pw.println(testCase.getName()); 156 for (String filename : usedFiles.getValue(clazz, testCase)) { 157 pw.print(" "); 158 pw.println(filename); 159 } 160 } 161 pw.println(); 162 } 163 164 pw.flush(); 165 } 166 167 }