/******************************************************************************* * Copyright (c) 2016 Alena Laskavaia and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Alena Laskavaia - initial API and implementation *******************************************************************************/ package org.eclipse.cdt.tests.dsf.gdb.framework; import org.junit.rules.MethodRule; import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.Statement; /** * This is the rule to add to tests that rarely fail randomly and you want to keep them but cannot figure out they fail. * It is safe to use it in any class, it will only apply to tests which have @Intermittent annotation <code> import org.eclipse.cdt.tests.dsf.gdb.framework.Intermittent import org.eclipse.cdt.tests.dsf.gdb.framework.IntermittentRule class SomeTest { public @Rule IntermittentRule rule = new IntermittentRule(); @Test @Intermittent(repetition = 3) public void someTest (){...} } </code> You can also ally this to the whole class <code> import org.eclipse.cdt.tests.dsf.gdb.framework.Intermittent import org.eclipse.cdt.tests.dsf.gdb.framework.IntermittentRule @Intermittent(repetition = 3) class SomeTest { public @Rule IntermittentRule rule = new IntermittentRule(); ... } </code> */ public class IntermittentRule implements MethodRule { public static class RunIntermittent extends Statement { private final FrameworkMethod method; private final Statement statement; public RunIntermittent(FrameworkMethod method, Statement statement) { this.method = method; this.statement = statement; } @Override public void evaluate() throws Throwable { int repetition = 1; Intermittent methodAnnot = method.getAnnotation(Intermittent.class); if (methodAnnot != null) { repetition = methodAnnot.repetition(); } else { Intermittent classAnnot = method.getDeclaringClass().getAnnotation(Intermittent.class); if (classAnnot != null) { repetition = classAnnot.repetition(); } } if (repetition > 1) { for (int i = 0; i < repetition; i++) { try { statement.evaluate(); break; // did not fail yay, we are done } catch (Throwable e) { if (i < repetition - 1) continue; // try again throw e; } } } else statement.evaluate(); } } @Override public Statement apply(Statement base, final FrameworkMethod method, final Object target) { return new RunIntermittent(method, base); } }