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}