001/* 002 * Copyright (c) 2012, 2013, Werner Keil, Credit Suisse (Anatole Tresch). Licensed under the Apache 003 * License, Version 2.0 (the "License"); you may not use this file except in compliance with the 004 * License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 005 * Unless required by applicable law or agreed to in writing, software distributed under the License 006 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 007 * or implied. See the License for the specific language governing permissions and limitations under 008 * the License. Contributors: Anatole Tresch - initial version. 009 */ 010package org.javamoney.tck; 011 012import org.javamoney.tck.tests.AccessingCurrenciesAmountsRoundingsTest; 013import org.javamoney.tck.tests.CreatingMonetaryAmountsTest; 014import org.javamoney.tck.tests.ExternalizingNumericValueTest; 015import org.javamoney.tck.tests.FunctionalExtensionPointsTest; 016import org.javamoney.tck.tests.ModellingCurrenciesTest; 017import org.javamoney.tck.tests.ModellingMonetaryAmountsTest; 018import org.javamoney.tck.tests.conversion.ConvertingAmountsTest; 019import org.javamoney.tck.tests.conversion.ExchangeRatesAndRateProvidersTest; 020import org.javamoney.tck.tests.conversion.MonetaryConversionsTest; 021import org.javamoney.tck.tests.conversion.ProviderChainsTest; 022import org.javamoney.tck.tests.format.FormattingMonetaryAmountsTest; 023import org.testng.ITestResult; 024import org.testng.TestListenerAdapter; 025import org.testng.TestNG; 026import org.testng.annotations.Test; 027import org.testng.reporters.VerboseReporter; 028import org.testng.xml.XmlClass; 029import org.testng.xml.XmlSuite; 030import org.testng.xml.XmlTest; 031 032import java.io.File; 033import java.io.FileWriter; 034import java.io.IOException; 035import java.io.PrintWriter; 036import java.io.StringWriter; 037import java.lang.reflect.Method; 038import java.util.ArrayList; 039import java.util.List; 040 041/** 042 * Main class for executing the JSR 354 TCK. 043 * Created by Anatole on 12.06.2014. 044 */ 045@SuppressWarnings("UseOfSystemOutOrSystemErr") 046public final class TCKRunner extends XmlSuite { 047 /** 048 * Constructor. 049 */ 050 public TCKRunner() { 051 setName("JSR354-TCK, version 1.0"); 052 XmlTest test = new XmlTest(this); 053 test.setName("TCK/Test Setup - Java 7"); 054 List<XmlClass> classes = new ArrayList<>(); 055 classes.add(new XmlClass(TCKTestSetup.class)); 056 classes.add(new XmlClass(ModellingCurrenciesTest.class)); 057 classes.add(new XmlClass(ModellingMonetaryAmountsTest.class)); 058 classes.add(new XmlClass(CreatingMonetaryAmountsTest.class)); 059 classes.add(new XmlClass(ExternalizingNumericValueTest.class)); 060 classes.add(new XmlClass(FunctionalExtensionPointsTest.class)); 061 classes.add(new XmlClass(AccessingCurrenciesAmountsRoundingsTest.class)); 062 classes.add(new XmlClass(MonetaryConversionsTest.class)); 063 classes.add(new XmlClass(ExchangeRatesAndRateProvidersTest.class)); 064 classes.add(new XmlClass(ConvertingAmountsTest.class)); 065 classes.add(new XmlClass(ProviderChainsTest.class)); 066 classes.add(new XmlClass(FormattingMonetaryAmountsTest.class)); 067 test.setXmlClasses(classes); 068 } 069 070 /** 071 * Mein method to start the TCK. Optional arguments are: 072 * <ul> 073 * <li>-DoutputDir for defining the output directory TestNG uses (default: ./target/tck-output).</li> 074 * <li>-Dverbose=true to enable TestNG verbose mode.</li> 075 * <li>-DreportFile=targetFile.txt for defining the TCK result summary report target file 076 * (default: ./target/tck-results.txt).</li> 077 * </ul> 078 * @param args 079 */ 080 public static void main(String... args) { 081 System.out.println("-- JSR 354 TCK started --"); 082 List<XmlSuite> suites = new ArrayList<>(); 083 suites.add(new TCKRunner()); 084 TestNG tng = new TestNG(); 085 tng.setXmlSuites(suites); 086 String outDir = System.getProperty("outputDir"); 087 if(outDir!=null) { 088 tng.setOutputDirectory(outDir); 089 } 090 else{ 091 tng.setOutputDirectory("./target/tck-output"); 092 } 093 String verbose = System.getProperty("verbose"); 094 if("true".equalsIgnoreCase(verbose)){ 095 tng.addListener(new VerboseReporter()); 096 } 097 String reportFile = System.getProperty("reportFile"); 098 File file = null; 099 if(reportFile!=null) { 100 file = new File(reportFile); 101 } 102 else{ 103 file = new File("./target/tck-results.txt"); 104 } 105 TCKReporter rep = new TCKReporter(file); 106 System.out.println("Writing to file " + file.getAbsolutePath() + " ..."); 107 tng.addListener(rep); 108 tng.run(); 109 rep.writeSummary(); 110 System.out.println("-- JSR 354 TCK finished --"); 111 } 112 113 /** 114 * Reporter implementation. 115 */ 116 public static final class TCKReporter extends TestListenerAdapter { 117 private int count = 0; 118 private int skipped = 0; 119 private int failed = 0; 120 private int success = 0; 121 122 private StringWriter internalBuffer = new StringWriter(3000); 123 private FileWriter w; 124 125 /** 126 * Constructor of the TCK reporter, writing to the given file. 127 * @param file the target file, not null. 128 */ 129 @SuppressWarnings("CallToPrintStackTrace") 130 public TCKReporter(File file) { 131 try { 132 if (!file.exists()) { 133 file.createNewFile(); 134 } 135 w = new FileWriter(file); 136 w.write("********************************************************************************************\n"); 137 w.write("**** JSR 354 - Money & Currency, Technical Compatibility Kit, version 1.0\n"); 138 w.write("********************************************************************************************\n\n"); 139 w.write("Executed on " + new java.util.Date() + "\n\n"); 140 141 // System.out: 142 internalBuffer.write("********************************************************************************\n"); 143 internalBuffer.write("**** JSR 354 - Money & Currency, Technical Compatibility Kit, version 1.0.\n"); 144 internalBuffer.write("********************************************************************************\n\n"); 145 internalBuffer.write("Executed on " + new java.util.Date() + "\n\n"); 146 } catch (IOException e) { 147 e.printStackTrace(); 148 System.exit(-1); 149 } 150 } 151 152 @Override 153 public void onTestFailure(ITestResult tr) { 154 failed++; 155 count++; 156 String location = tr.getTestClass().getRealClass().getSimpleName() + '#' + tr.getMethod().getMethodName(); 157 try { 158 Method realTestMethod = tr.getMethod().getMethod(); 159 Test testAnnot = realTestMethod.getAnnotation(Test.class); 160 if (testAnnot != null && testAnnot.description() != null && !testAnnot.description().isEmpty()) { 161 if (tr.getThrowable() != null) { 162 StringWriter sw = new StringWriter(); 163 PrintWriter w = new PrintWriter(sw); 164 tr.getThrowable().printStackTrace(w); 165 w.flush(); 166 log("[FAILED] " + testAnnot.description() + "(" + location + "):\n" + sw.toString()); 167 } else { 168 log("[FAILED] " + testAnnot.description() + "(" + location + ")"); 169 } 170 } else { 171 172 if (tr.getThrowable() != null) { 173 StringWriter sw = new StringWriter(); 174 PrintWriter w = new PrintWriter(sw); 175 tr.getThrowable().printStackTrace(w); 176 w.flush(); 177 log("[FAILED] " + location + ":\n" + sw.toString()); 178 } else { 179 log("[FAILED] " + location); 180 } 181 } 182 } catch (IOException e) { 183 throw new IllegalStateException("IO Error", e); 184 } 185 } 186 187 @Override 188 public void onTestSkipped(ITestResult tr) { 189 skipped++; 190 count++; 191 String location = tr.getTestClass().getRealClass().getSimpleName() + '#' + tr.getMethod().getMethodName(); 192 try { 193 Method realTestMethod = tr.getMethod().getMethod(); 194 Test specAssert = realTestMethod.getAnnotation(Test.class); 195 if (specAssert != null && specAssert.description() != null && !specAssert.description().isEmpty()) { 196 log("[SKIPPED] " + specAssert.description() + "(" + location + ")"); 197 } else { 198 log("[SKIPPED] " + location); 199 } 200 } catch (IOException e) { 201 throw new IllegalStateException("IO Error", e); 202 } 203 } 204 205 @Override 206 public void onTestSuccess(ITestResult tr) { 207 success++; 208 count++; 209 String location = tr.getTestClass().getRealClass().getSimpleName() + '#' + tr.getMethod().getMethodName(); 210 try { 211 Method realTestMethod = tr.getMethod().getMethod(); 212 Test specAssert = realTestMethod.getAnnotation(Test.class); 213 if (specAssert != null && specAssert.description() != null && !specAssert.description().isEmpty()) { 214 log("[SUCCESS] " + specAssert.description() + "(" + location + ")"); 215 } else { 216 log("[SUCCESS] " + location); 217 } 218 } catch (IOException e) { 219 throw new IllegalStateException("IO Error", e); 220 } 221 } 222 223 224 225 private void log(String text) throws IOException { 226 w.write(text); 227 w.write('\n'); 228 internalBuffer.write(text); 229 internalBuffer.write('\n'); 230 } 231 232 public void writeSummary() { 233 try { 234 log("\nJSR 354 TCK, version 1.0 Summary"); 235 log("------------------------------------------"); 236 log("\nTOTAL TESTS EXECUTED : " + count); 237 log("TOTAL TESTS SKIPPED : " + skipped); 238 log("TOTAL TESTS SUCCESS : " + success); 239 log("TOTAL TESTS FAILED : " + failed); 240 w.flush(); 241 w.close(); 242 internalBuffer.flush(); 243 System.out.println(); 244 System.out.println(internalBuffer); 245 } catch (IOException e) { 246 throw new IllegalStateException("IO Error", e); 247 } 248 } 249 } 250 251 252}