1 // Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
2 //  This source code is licensed under both the GPLv2 (found in the
3 //  COPYING file in the root directory) and Apache 2.0 License
4 //  (found in the LICENSE.Apache file in the root directory).
5 package org.rocksdb.test;
6 
7 import org.junit.internal.JUnitSystem;
8 import org.junit.internal.RealSystem;
9 import org.junit.internal.TextListener;
10 import org.junit.runner.Description;
11 import org.junit.runner.JUnitCore;
12 import org.junit.runner.Result;
13 import org.junit.runner.notification.Failure;
14 import org.rocksdb.RocksDB;
15 
16 import java.io.PrintStream;
17 import java.text.DecimalFormat;
18 import java.text.NumberFormat;
19 import java.util.ArrayList;
20 import java.util.List;
21 
22 import static org.rocksdb.test.RocksJunitRunner.RocksJunitListener.Status.*;
23 
24 /**
25  * Custom Junit Runner to print also Test classes
26  * and executed methods to command prompt.
27  */
28 public class RocksJunitRunner {
29 
30   /**
31    * Listener which overrides default functionality
32    * to print class and method to system out.
33    */
34   static class RocksJunitListener extends TextListener {
35 
36     private final static NumberFormat secsFormat =
37         new DecimalFormat("###,###.###");
38 
39     private final PrintStream writer;
40 
41     private String currentClassName = null;
42     private String currentMethodName = null;
43     private Status currentStatus = null;
44     private long currentTestsStartTime;
45     private int currentTestsCount = 0;
46     private int currentTestsIgnoredCount = 0;
47     private int currentTestsFailureCount = 0;
48     private int currentTestsErrorCount = 0;
49 
50     enum Status {
51       IGNORED,
52       FAILURE,
53       ERROR,
54       OK
55     }
56 
57     /**
58      * RocksJunitListener constructor
59      *
60      * @param system JUnitSystem
61      */
RocksJunitListener(final JUnitSystem system)62     public RocksJunitListener(final JUnitSystem system) {
63       this(system.out());
64     }
65 
RocksJunitListener(final PrintStream writer)66     public RocksJunitListener(final PrintStream writer) {
67       super(writer);
68       this.writer = writer;
69     }
70 
71     @Override
testRunStarted(final Description description)72     public void testRunStarted(final Description description) {
73       writer.format("Starting RocksJava Tests...%n");
74 
75     }
76 
77     @Override
testStarted(final Description description)78     public void testStarted(final Description description) {
79       if(currentClassName == null
80           || !currentClassName.equals(description.getClassName())) {
81         if(currentClassName !=  null) {
82           printTestsSummary();
83         } else {
84           currentTestsStartTime = System.currentTimeMillis();
85         }
86         writer.format("%nRunning: %s%n", description.getClassName());
87         currentClassName = description.getClassName();
88       }
89       currentMethodName = description.getMethodName();
90       currentStatus = OK;
91       currentTestsCount++;
92     }
93 
printTestsSummary()94     private void printTestsSummary() {
95       // print summary of last test set
96       writer.format("Tests run: %d, Failures: %d, Errors: %d, Ignored: %d, Time elapsed: %s sec%n",
97           currentTestsCount,
98           currentTestsFailureCount,
99           currentTestsErrorCount,
100           currentTestsIgnoredCount,
101           formatSecs(System.currentTimeMillis() - currentTestsStartTime));
102 
103       // reset counters
104       currentTestsCount = 0;
105       currentTestsFailureCount = 0;
106       currentTestsErrorCount = 0;
107       currentTestsIgnoredCount = 0;
108       currentTestsStartTime = System.currentTimeMillis();
109     }
110 
formatSecs(final double milliseconds)111     private static String formatSecs(final double milliseconds) {
112       final double seconds = milliseconds / 1000;
113       return secsFormat.format(seconds);
114     }
115 
116     @Override
testFailure(final Failure failure)117     public void testFailure(final Failure failure) {
118       if (failure.getException() != null
119           && failure.getException() instanceof AssertionError) {
120         currentStatus = FAILURE;
121         currentTestsFailureCount++;
122       } else {
123         currentStatus = ERROR;
124         currentTestsErrorCount++;
125       }
126     }
127 
128     @Override
testIgnored(final Description description)129     public void testIgnored(final Description description) {
130       currentStatus = IGNORED;
131       currentTestsIgnoredCount++;
132     }
133 
134     @Override
testFinished(final Description description)135     public void testFinished(final Description description) {
136       if(currentStatus == OK) {
137         writer.format("\t%s OK%n",currentMethodName);
138       } else {
139         writer.format("  [%s] %s%n", currentStatus.name(), currentMethodName);
140       }
141     }
142 
143     @Override
testRunFinished(final Result result)144     public void testRunFinished(final Result result) {
145       printTestsSummary();
146       super.testRunFinished(result);
147     }
148   }
149 
150   /**
151    * Main method to execute tests
152    *
153    * @param args Test classes as String names
154    */
main(final String[] args)155   public static void main(final String[] args){
156     final JUnitCore runner = new JUnitCore();
157     final JUnitSystem system = new RealSystem();
158     runner.addListener(new RocksJunitListener(system));
159     try {
160       final List<Class<?>> classes = new ArrayList<>();
161       for (final String arg : args) {
162         classes.add(Class.forName(arg));
163       }
164       final Class[] clazzes = classes.toArray(new Class[classes.size()]);
165       final Result result = runner.run(clazzes);
166       if(!result.wasSuccessful()) {
167         System.exit(-1);
168       }
169     } catch (final ClassNotFoundException e) {
170       e.printStackTrace();
171       System.exit(-2);
172     }
173   }
174 }
175