001: /*
002:
003: Derby - Class org.apache.derbyTesting.functionTests.harness.GenerateReport
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to You under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derbyTesting.functionTests.harness;
023:
024: import java.util.Properties;
025: import java.util.Calendar;
026: import java.util.GregorianCalendar;
027: import java.io.File;
028: import java.io.FileReader;
029: import java.io.FilenameFilter;
030: import java.io.FileWriter;
031: import java.io.IOException;
032: import java.io.BufferedReader;
033: import java.io.PrintWriter;
034: import java.sql.Date;
035: import java.sql.Time;
036: import java.sql.Timestamp;
037:
038: /**
039: Generate summary information from a RunSuite run.
040: Can be called separately, if given the suite name.
041: Will be called from RunSuite if System property genrep=true.
042:
043: Condenses run information down, prints out result stats,
044: and shows details of failures (.diff files).
045:
046: @author ames
047: **/
048: public class GenerateReport {
049:
050: static void CollectProperties() {
051: Properties ps = System.getProperties();
052: char[] newline = { ' ' };
053: propFile.println(PropertyUtil.sortProperties(ps, newline));
054: }
055:
056: static void CalculateRunLength() {
057: // read suite.sum for start/end timestamps,
058: // report start date and full duration of run
059: String odn = System.getProperty("outputdir");
060: if (odn == null)
061: odn = System.getProperty("user.dir");
062:
063: BufferedReader sumFile = null;
064: String firstLine = null;
065: String lastLine = null;
066: try {
067: sumFile = new BufferedReader(new FileReader(new File(
068: new File(odn), SuiteName + ".sum")));
069: firstLine = sumFile.readLine();
070: String aLine = firstLine;
071: while (aLine != null) {
072: lastLine = aLine;
073: aLine = sumFile.readLine();
074: }
075: sumFile.close();
076: } catch (IOException ioe) {
077: ioe.printStackTrace(System.out);
078: }
079:
080: // have firstLine and lastLine.
081: // format is:
082: // ******* Start Suite: <suite> <timestamp> *******
083: // ******* End Suite: <suite> <timestamp> *******
084: int tsStart = 22 + SuiteName.length();
085: int tsEnd = firstLine.length() - 8;
086: TestStart = Timestamp.valueOf(firstLine.substring(tsStart,
087: tsEnd));
088: // last line is two shorter
089: tsStart -= 2;
090: tsEnd -= 2;
091: Timestamp testEnd = Timestamp.valueOf(lastLine.substring(
092: tsStart, tsEnd));
093:
094: long testLen = testEnd.getTime() - TestStart.getTime();
095: // Time isn't really a duration, so we have to set the fields
096: int sec = (int) (testLen / 1000);
097: int min = sec / 60;
098: int hr = min / 60;
099: sec = sec - (min * 60); // adjust for part removed
100: min = min - (hr * 60); // adjust for part removed
101: Calendar cal = new GregorianCalendar();
102: cal.set(Calendar.HOUR_OF_DAY, hr);
103: cal.set(Calendar.MINUTE, min);
104: cal.set(Calendar.SECOND, sec);
105: TestDuration = new Time(cal.getTime().getTime());
106: }
107:
108: static void CollectPassFailStats() {
109: // need to ensure outputdir is set...
110: String odn = System.getProperty("outputdir");
111: if (odn == null)
112: odn = System.getProperty("user.dir");
113: CollectPassFailStats(new File(odn), "");
114: }
115:
116: static void addLines(PrintWriter outFile, File inFile,
117: String relativeName) {
118: BufferedReader readFile = null;
119: try {
120: readFile = new BufferedReader(new FileReader(inFile));
121: String aLine = readFile.readLine();
122: while (aLine != null) {
123: outFile.print(relativeName);
124: outFile.print(":");
125: outFile.println(aLine);
126: aLine = readFile.readLine();
127: }
128: readFile.close();
129: } catch (IOException ioe) {
130: ioe.printStackTrace(System.out);
131: }
132:
133: }
134:
135: static void addDiff(PrintWriter outFile, File inFile,
136: String relativeName) {
137: BufferedReader readFile = null;
138: try {
139: readFile = new BufferedReader(new FileReader(inFile));
140: outFile.print("********* Diff file ");
141: outFile.println(relativeName);
142: String aLine = readFile.readLine();
143: while (aLine != null) {
144: outFile.println(aLine);
145: aLine = readFile.readLine();
146: }
147: readFile.close();
148: } catch (IOException ioe) {
149: ioe.printStackTrace(System.out);
150: }
151: }
152:
153: static void CollectPassFailStats(File dir, String relativeName) {
154: // starting in specified dir,
155: String[] fileList = dir.list(fileFilter);
156: int l = fileList.length;
157: for (int i = 0; i < l; i++) {
158: String fileName = fileList[i];
159: File file = new File(dir, fileName);
160:
161: // collect all .pass files into suite_pass.txt (passFile)
162: if (fileName.endsWith(".pass")) {
163: addLines(passFile, file, relativeName + "/" + fileName);
164: }
165: // collect all .fail files into suite_fail.txt (failFile)
166: else if (fileName.endsWith(".fail")) {
167: addLines(failFile, file, relativeName + "/" + fileName);
168: }
169: // collect all .skip files into suite_skip.txt (skipFile)
170: else if (fileName.endsWith(".skip")) {
171: addLines(skipFile, file, relativeName + "/" + fileName);
172: }
173: // collect all .diff files into suite_diff.txt (diffFile)
174: else if (fileName.endsWith(".diff")) {
175: addDiff(diffFile, file, relativeName + "/" + fileName);
176: }
177:
178: // recurse on all directories
179: else // it's a directory
180: {
181: String newDir;
182: if (relativeName.length() > 0)
183: newDir = relativeName + "/" + fileName;
184: else
185: newDir = fileName;
186: CollectPassFailStats(file, newDir);
187: }
188: }
189: }
190:
191: static void CalculatePassFailStats() {
192: // total tests run
193: // #, % failures
194: // #, % passed
195: NumPass = CountLines(passFileName);
196: NumFail = CountLines(failFileName);
197: NumRun = NumPass + NumFail;
198: NumSkip = CountLines(skipFileName);
199: PercentPass = (int) Math
200: .floor(100 * ((double) NumPass / (double) NumRun));
201: PercentFail = (int) Math
202: .ceil(100 * ((double) NumFail / (double) NumRun));
203: }
204:
205: static int CountLines(String fileName) {
206: BufferedReader readFile = null;
207: int line = 0;
208: try {
209: readFile = new BufferedReader(new FileReader(fileName));
210: String aLine = readFile.readLine();
211: while (aLine != null) {
212: line++;
213: aLine = readFile.readLine();
214: }
215: readFile.close();
216: } catch (IOException ioe) {
217: ioe.printStackTrace(System.out);
218: }
219: return line;
220: }
221:
222: static void OutputFile(String fileName) {
223: BufferedReader readFile = null;
224: try {
225: readFile = new BufferedReader(new FileReader(fileName));
226: String aLine = readFile.readLine();
227: while (aLine != null) {
228: reportFile.println(aLine);
229: aLine = readFile.readLine();
230: }
231: readFile.close();
232: } catch (IOException ioe) {
233: ioe.printStackTrace(System.out);
234: }
235: }
236:
237: static PrintWriter setupFile(String fn) {
238: File f = null;
239: PrintWriter pw = null;
240: try {
241: f = new File(fn);
242: if (f.exists()) {
243: System.out.println("WARNING: removing " + fn);
244: f.delete();
245: }
246: pw = new PrintWriter(new FileWriter(fn, true));
247: } catch (IOException ioe) {
248: ioe.printStackTrace(System.out);
249: }
250: return pw;
251: }
252:
253: public static void main(String[] args) {
254: SuiteName = args[0];
255: String jvmName = args[1];
256: String javaCmd = args[2];
257: String classpath = args[3];
258: String framework = args[4];
259: String processexec = args[5];
260: boolean useprocess = true;
261: if ((processexec.toLowerCase()).startsWith("false"))
262: useprocess = false;
263: String reportFileName = SuiteName + "_report.txt";
264: reportFile = setupFile(reportFileName);
265: reportFile.print("Generating report for RunSuite ");
266: for (int i = 0; i < args.length; i++)
267: reportFile.print(args[i] + " ");
268: reportFile.println();
269: passFileName = SuiteName + "_pass.txt";
270: failFileName = SuiteName + "_fail.txt";
271: diffFileName = SuiteName + "_diff.txt";
272: skipFileName = SuiteName + "_skip.txt";
273: propFileName = SuiteName + "_prop.txt";
274: passFile = setupFile(passFileName);
275: failFile = setupFile(failFileName);
276: diffFile = setupFile(diffFileName);
277: skipFile = setupFile(skipFileName);
278: propFile = setupFile(propFileName);
279:
280: // sysinfo printout
281: SysInfoLog sysLog = new SysInfoLog();
282: try {
283: sysLog.exec(jvmName, javaCmd, classpath, framework,
284: reportFile, useprocess);
285: //SysInfoMain.getMainInfo(reportFile,false,false);
286: } catch (Exception e) {
287: System.out.println("SysInfoLog Exception: "
288: + e.getMessage());
289: }
290:
291: reportFile.println("Test environment information:");
292: reportFile.print("COMMAND LINE STYLE: ");
293: String jvm = System.getProperty("jvm");
294: if (jvm == null)
295: jvm = "jdk13";
296: reportFile.println(jvm);
297: reportFile.print("TEST CANONS: ");
298: String canondir = System.getProperty("canondir");
299: if (canondir == null)
300: canondir = "master";
301: reportFile.println(canondir);
302: reportFile.println(DASHLINE);
303:
304: reportFile.println(DASHLINE);
305: reportFile.println("Summary results:");
306: CalculateRunLength();
307: CollectPassFailStats();
308: CollectProperties();
309: passFile.close();
310: failFile.close();
311: skipFile.close();
312: diffFile.close();
313: propFile.close();
314: CalculatePassFailStats();
315: reportFile.println();
316: reportFile.println("Test Run Started: " + TestStart);
317: reportFile.println("Test Run Duration: " + TestDuration);
318: reportFile.println();
319: reportFile.println(NumRun + " Tests Run");
320: if (PercentPass < 10)
321: reportFile.print(" ");
322: reportFile.println(PercentPass + "% Pass (" + NumPass
323: + " tests passed)");
324: if (PercentFail < 10)
325: reportFile.print(" ");
326: reportFile.println(PercentFail + "% Fail (" + NumFail
327: + " tests failed)");
328: reportFile.println(NumSkip + " Suites skipped");
329: reportFile.println(DASHLINE);
330:
331: if (NumFail > 0) {
332: reportFile.println("Failed tests in: " + failFileName);
333: reportFile.println(DASHLINE);
334: }
335:
336: if (NumPass > 0) {
337: reportFile.println("Passed tests in: " + passFileName);
338: reportFile.println(DASHLINE);
339: }
340:
341: if (NumSkip > 0) {
342: reportFile.println("Skipped suites in: " + skipFileName);
343: reportFile.println(DASHLINE);
344: }
345:
346: reportFile.println("System properties in: " + propFileName);
347: reportFile.println(DASHLINE);
348:
349: reportFile.println(DASHLINE);
350: if (NumFail > 0) {
351: reportFile.println("Failure Details:");
352: // cat each .diff file with full test name
353: OutputFile(diffFileName);
354: } else
355: reportFile.println("No Failures.");
356: reportFile.println(DASHLINE);
357: reportFile.close();
358:
359: System.out.println("Generated report: " + reportFileName);
360: }
361:
362: static final String DASHLINE = "------------------------------------------------------";
363: static String passFileName, failFileName, diffFileName,
364: skipFileName, propFileName;
365: static PrintWriter passFile, failFile, diffFile, skipFile,
366: propFile;
367: static PrintWriter reportFile;
368: static FilenameFilter fileFilter = new GRFileFilter();
369: static int NumPass, NumFail, NumRun, NumSkip;
370: static int PercentPass, PercentFail;
371: static Timestamp TestStart;
372: static Time TestDuration;
373: static String SuiteName;
374: }
|