aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/junit/rules/DisableOnDebug.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/junit/rules/DisableOnDebug.java')
-rw-r--r--src/main/java/org/junit/rules/DisableOnDebug.java125
1 files changed, 125 insertions, 0 deletions
diff --git a/src/main/java/org/junit/rules/DisableOnDebug.java b/src/main/java/org/junit/rules/DisableOnDebug.java
new file mode 100644
index 0000000..3bca103
--- /dev/null
+++ b/src/main/java/org/junit/rules/DisableOnDebug.java
@@ -0,0 +1,125 @@
+package org.junit.rules;
+
+import java.util.List;
+
+import org.junit.internal.management.ManagementFactory;
+import org.junit.internal.management.RuntimeMXBean;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+/**
+ * The {@code DisableOnDebug} Rule allows you to label certain rules to be
+ * disabled when debugging.
+ * <p>
+ * The most illustrative use case is for tests that make use of the
+ * {@link Timeout} rule, when ran in debug mode the test may terminate on
+ * timeout abruptly during debugging. Developers may disable the timeout, or
+ * increase the timeout by making a code change on tests that need debugging and
+ * remember revert the change afterwards or rules such as {@link Timeout} that
+ * may be disabled during debugging may be wrapped in a {@code DisableOnDebug}.
+ * <p>
+ * The important benefit of this feature is that you can disable such rules
+ * without any making any modifications to your test class to remove them during
+ * debugging.
+ * <p>
+ * This does nothing to tackle timeouts or time sensitive code under test when
+ * debugging and may make this less useful in such circumstances.
+ * <p>
+ * Example usage:
+ *
+ * <pre>
+ * public static class DisableTimeoutOnDebugSampleTest {
+ *
+ * &#064;Rule
+ * public TestRule timeout = new DisableOnDebug(new Timeout(20));
+ *
+ * &#064;Test
+ * public void myTest() {
+ * int i = 0;
+ * assertEquals(0, i); // suppose you had a break point here to inspect i
+ * }
+ * }
+ * </pre>
+ *
+ * @since 4.12
+ */
+public class DisableOnDebug implements TestRule {
+ private final TestRule rule;
+ private final boolean debugging;
+
+ /**
+ * Create a {@code DisableOnDebug} instance with the timeout specified in
+ * milliseconds.
+ *
+ * @param rule to disable during debugging
+ */
+ public DisableOnDebug(TestRule rule) {
+ this(rule, ManagementFactory.getRuntimeMXBean()
+ .getInputArguments());
+ }
+
+ /**
+ * Visible for testing purposes only.
+ *
+ * @param rule the rule to disable during debugging
+ * @param inputArguments
+ * arguments provided to the Java runtime
+ */
+ DisableOnDebug(TestRule rule, List<String> inputArguments) {
+ this.rule = rule;
+ debugging = isDebugging(inputArguments);
+ }
+
+ /**
+ * @see TestRule#apply(Statement, Description)
+ */
+ public Statement apply(Statement base, Description description) {
+ if (debugging) {
+ return base;
+ } else {
+ return rule.apply(base, description);
+ }
+ }
+
+ /**
+ * Parses arguments passed to the runtime environment for debug flags
+ * <p>
+ * Options specified in:
+ * <ul>
+ * <li>
+ * <a href="http://docs.oracle.com/javase/6/docs/technotes/guides/jpda/conninv.html#Invocation"
+ * >javase-6</a></li>
+ * <li><a href="http://docs.oracle.com/javase/7/docs/technotes/guides/jpda/conninv.html#Invocation"
+ * >javase-7</a></li>
+ * <li><a href="http://docs.oracle.com/javase/8/docs/technotes/guides/jpda/conninv.html#Invocation"
+ * >javase-8</a></li>
+ *
+ *
+ * @param arguments
+ * the arguments passed to the runtime environment, usually this
+ * will be {@link RuntimeMXBean#getInputArguments()}
+ * @return true if the current JVM was started in debug mode, false
+ * otherwise.
+ */
+ private static boolean isDebugging(List<String> arguments) {
+ for (final String argument : arguments) {
+ if ("-Xdebug".equals(argument) || argument.startsWith("-agentlib:jdwp")) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns {@code true} if the JVM is in debug mode. This method may be used
+ * by test classes to take additional action to disable code paths that
+ * interfere with debugging if required.
+ *
+ * @return {@code true} if the current JVM is in debug mode, {@code false}
+ * otherwise
+ */
+ public boolean isDebugging() {
+ return debugging;
+ }
+
+}