mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-20 00:51:42 +00:00
Updates the AbstractComsSetup message to report JUnits multiple exceptions correctly.
Adds a simple logger to the AbstractComsSetup that prints messages to the console based on the log level. Replaces all System.out prints with TestBench.out() Change-Id: Ieb7acfe51aa2febe9cfd3883f8a33094c9b72a6e
This commit is contained in:
@@ -6,14 +6,17 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
package edu.wpi.first.wpilibj.test;
|
||||
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Rule;
|
||||
import org.junit.rules.TestWatcher;
|
||||
import org.junit.runner.Description;
|
||||
import org.junit.runners.model.MultipleFailureException;
|
||||
|
||||
import edu.wpi.first.wpilibj.DriverStation;
|
||||
import edu.wpi.first.wpilibj.Timer;
|
||||
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary;
|
||||
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
|
||||
|
||||
@@ -24,6 +27,7 @@ import edu.wpi.first.wpilibj.livewindow.LiveWindow;
|
||||
* from this class, to ensure that all of the hardware will be able to run.
|
||||
*
|
||||
* @author Fredric Silberberg
|
||||
* @author Jonathan Leitschuh
|
||||
*/
|
||||
public abstract class AbstractComsSetup {
|
||||
/** Stores whether network coms have been initialized */
|
||||
@@ -43,7 +47,7 @@ public abstract class AbstractComsSetup {
|
||||
FRCNetworkCommunicationsLibrary
|
||||
.FRCNetworkCommunicationObserveUserProgramStarting();
|
||||
LiveWindow.setEnabled(false);
|
||||
System.out.println("Started coms");
|
||||
TestBench.out().println("Started coms");
|
||||
|
||||
// Wait until the robot is enabled before starting the tests
|
||||
int i = 0;
|
||||
@@ -54,13 +58,13 @@ public abstract class AbstractComsSetup {
|
||||
e.printStackTrace();
|
||||
}
|
||||
//Prints the message on one line overwriting itself each time
|
||||
System.out.print("\rWaiting for enable: " + i++);
|
||||
TestBench.out().print("\rWaiting for enable: " + i++);
|
||||
}
|
||||
System.out.println();
|
||||
TestBench.out().println();
|
||||
|
||||
// Ready to go!
|
||||
initialized = true;
|
||||
System.out.println("Running!");
|
||||
TestBench.out().println("Running!");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,21 +73,125 @@ public abstract class AbstractComsSetup {
|
||||
|
||||
/** This causes a stack trace to be printed as the test is running as well as at the end */
|
||||
@Rule
|
||||
public TestWatcher testWatcher = new TestWatcher() {
|
||||
@Override
|
||||
protected void failed(Throwable e, Description description) {
|
||||
System.out.println();
|
||||
getClassLogger().severe("" + description.getDisplayName() + " failed " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
public final TestWatcher getTestWatcher(){
|
||||
return getOverridenTestWatcher();
|
||||
}
|
||||
|
||||
/**
|
||||
* Given as a way to provide a custom test watcher for a test or set of tests
|
||||
* @return the test watcher to use
|
||||
*/
|
||||
protected TestWatcher getOverridenTestWatcher(){
|
||||
return new DefaultTestWatcher();
|
||||
}
|
||||
|
||||
protected class DefaultTestWatcher extends TestWatcher {
|
||||
/**
|
||||
* Allows a failure to supply a custom status message to be displayed along with the stack trace.
|
||||
*/
|
||||
protected void failed(Throwable e, Description description, String status){
|
||||
TestBench.out().println();
|
||||
//Instance of is the best way I know to retrieve this data.
|
||||
if(e instanceof MultipleFailureException){
|
||||
/* MultipleFailureExceptions hold multiple exceptions in one exception. In order to properly display these stack traces
|
||||
* we have to cast the throwable and work with the list of thrown exceptions stored within it.
|
||||
*/
|
||||
int i = 1; //Running exception count
|
||||
int failureCount = ((MultipleFailureException)e).getFailures().size();
|
||||
for(Throwable singleThrown : ((MultipleFailureException)e).getFailures()){
|
||||
getClassLogger().logp(Level.SEVERE, description.getClassName(), description.getMethodName(), (i++) + "/" + failureCount
|
||||
+ " "+ description.getDisplayName() + " failed " + singleThrown.getMessage() + "\n" + status, singleThrown);
|
||||
}
|
||||
|
||||
} else {
|
||||
getClassLogger().logp(Level.SEVERE, description.getClassName(), description.getMethodName(), description.getDisplayName() + " failed " + e.getMessage() + "\n" + status, e);
|
||||
}
|
||||
super.failed(e, description);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.junit.rules.TestWatcher#failed(java.lang.Throwable, org.junit.runner.Description)
|
||||
*/
|
||||
@Override
|
||||
protected void starting( Description description ) {
|
||||
System.out.println();
|
||||
getClassLogger().info( description.getDisplayName());
|
||||
protected void failed(Throwable e, Description description) {
|
||||
failed(e, description, "");
|
||||
}
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.junit.rules.TestWatcher#starting(org.junit.runner.Description)
|
||||
*/
|
||||
@Override
|
||||
protected void starting(Description description ) {
|
||||
TestBench.out().println();
|
||||
// Wait until the robot is enabled before starting the next tests
|
||||
int i = 0;
|
||||
while (!DriverStation.getInstance().isEnabled()) {
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
//Prints the message on one line overwriting itself each time
|
||||
TestBench.out().print("\rWaiting for enable: " + i++);
|
||||
}
|
||||
getClassLogger().logp(Level.INFO, description.getClassName(), description.getMethodName(), description.getDisplayName());
|
||||
super.starting(description);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void succeeded(Description description) {
|
||||
simpleLog(Level.INFO, "TEST PASSED!");
|
||||
super.succeeded(description);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Logs a simple message without the logger formatting associated with it.
|
||||
* @param level The level to log the message at
|
||||
* @param message The message to log
|
||||
*/
|
||||
protected void simpleLog(Level level, String message){
|
||||
if(getClassLogger().isLoggable(level)){
|
||||
TestBench.out().println(message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provided as a replacement to lambda functions to allow for repeatable checks to see if a correct state is reached
|
||||
* @author Jonathan Leitschuh
|
||||
*
|
||||
*/
|
||||
public abstract class BooleanCheck{
|
||||
public BooleanCheck(){}
|
||||
/**
|
||||
* Runs the enclosed code and evaluates it to determine what state it should return.
|
||||
* @return true if the code provided within the method returns true
|
||||
*/
|
||||
abstract public boolean getAsBoolean();
|
||||
};
|
||||
|
||||
/**
|
||||
* Delays until either the correct state is reached or we reach the timeout.
|
||||
* @param level The level to log the message at.
|
||||
* @param timeout How long the delay should run before it should timeout and allow the test to continue
|
||||
* @param message The message to accompany the delay. The message will display 'message' took 'timeout' seconds if it passed.
|
||||
* @param correctState A method to determine if the test has reached a state where it is valid to continue
|
||||
* @return a double representing how long the delay took to run in seconds.
|
||||
*/
|
||||
public double delayTillInCorrectStateWithMessage(Level level, double timeout, String message, BooleanCheck correctState){
|
||||
int i = 0;
|
||||
//As long as we are not in the correct state and the timeout has not been reached then continue to run this loop
|
||||
for(i = 0; i < (timeout * 100) && !correctState.getAsBoolean(); i++){
|
||||
Timer.delay(.01);
|
||||
}
|
||||
if(correctState.getAsBoolean()){
|
||||
simpleLog(level, message + " took " + (i * .01) + " seconds");
|
||||
} else {
|
||||
simpleLog(level, message + " timed out after " + (i * .01) + " seconds");
|
||||
}
|
||||
return i*.01;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user