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 }