1 /* 2 * Copyright (c) 2007 Mockito contributors 3 * This program is made available under the terms of the MIT License. 4 */ 5 package org.mockito.internal.verification; 6 7 import org.mockito.exceptions.base.MockitoAssertionError; 8 import org.mockito.internal.util.Timer; 9 import org.mockito.internal.verification.api.VerificationData; 10 import org.mockito.verification.VerificationMode; 11 12 /** 13 * Verifies that another verification mode (the delegate) is satisfied within a certain timeframe 14 * (before timeoutMillis has passed, measured from the call to verify()), and either returns immediately 15 * once it does, or waits until it is definitely satisfied once the full time has passed. 16 */ 17 public class VerificationOverTimeImpl implements VerificationMode { 18 19 private final long pollingPeriodMillis; 20 private final VerificationMode delegate; 21 private final boolean returnOnSuccess; 22 private final Timer timer; 23 24 /** 25 * Create this verification mode, to be used to verify invocation ongoing data later. 26 * 27 * @param pollingPeriodMillis The frequency to poll delegate.verify(), to check whether the delegate has been satisfied 28 * @param durationMillis The max time to wait (in millis) for the delegate verification mode to be satisfied 29 * @param delegate The verification mode to delegate overall success or failure to 30 * @param returnOnSuccess Whether to immediately return successfully once the delegate is satisfied (as in 31 * {@link org.mockito.verification.VerificationWithTimeout}, or to only return once 32 * the delegate is satisfied and the full duration has passed (as in 33 * {@link org.mockito.verification.VerificationAfterDelay}). 34 */ VerificationOverTimeImpl(long pollingPeriodMillis, long durationMillis, VerificationMode delegate, boolean returnOnSuccess)35 public VerificationOverTimeImpl(long pollingPeriodMillis, long durationMillis, VerificationMode delegate, boolean returnOnSuccess) { 36 this(pollingPeriodMillis, delegate, returnOnSuccess, new Timer(durationMillis)); 37 } 38 39 /** 40 * Create this verification mode, to be used to verify invocation ongoing data later. 41 * 42 * @param pollingPeriodMillis The frequency to poll delegate.verify(), to check whether the delegate has been satisfied 43 * @param delegate The verification mode to delegate overall success or failure to 44 * @param returnOnSuccess Whether to immediately return successfully once the delegate is satisfied (as in 45 * {@link org.mockito.verification.VerificationWithTimeout}, or to only return once 46 * the delegate is satisfied and the full duration has passed (as in 47 * {@link org.mockito.verification.VerificationAfterDelay}). 48 * @param timer Checker of whether the duration of the verification is still acceptable 49 */ VerificationOverTimeImpl(long pollingPeriodMillis, VerificationMode delegate, boolean returnOnSuccess, Timer timer)50 public VerificationOverTimeImpl(long pollingPeriodMillis, VerificationMode delegate, boolean returnOnSuccess, Timer timer) { 51 this.pollingPeriodMillis = pollingPeriodMillis; 52 this.delegate = delegate; 53 this.returnOnSuccess = returnOnSuccess; 54 this.timer = timer; 55 } 56 57 /** 58 * Verify the given ongoing verification data, and confirm that it satisfies the delegate verification mode 59 * before the full duration has passed. 60 * 61 * In practice, this polls the delegate verification mode until it is satisfied. If it is not satisfied once 62 * the full duration has passed, the last error returned by the delegate verification mode will be thrown 63 * here in turn. This may be thrown early if the delegate is unsatisfied and the verification mode is known 64 * to never recover from this situation (e.g. {@link AtMost}). 65 * 66 * If it is satisfied before the full duration has passed, behaviour is dependent on the returnOnSuccess parameter 67 * given in the constructor. If true, this verification mode is immediately satisfied once the delegate is. If 68 * false, this verification mode is not satisfied until the delegate is satisfied and the full time has passed. 69 * 70 * @throws MockitoAssertionError if the delegate verification mode does not succeed before the timeout 71 */ verify(VerificationData data)72 public void verify(VerificationData data) { 73 AssertionError error = null; 74 75 timer.start(); 76 while (timer.isCounting()) { 77 try { 78 delegate.verify(data); 79 80 if (returnOnSuccess) { 81 return; 82 } else { 83 error = null; 84 } 85 } catch (MockitoAssertionError e) { 86 error = handleVerifyException(e); 87 } 88 catch (AssertionError e) { 89 error = handleVerifyException(e); 90 } 91 } 92 93 if (error != null) { 94 throw error; 95 } 96 } 97 handleVerifyException(AssertionError e)98 private AssertionError handleVerifyException(AssertionError e) { 99 if (canRecoverFromFailure(delegate)) { 100 sleep(pollingPeriodMillis); 101 return e; 102 } else { 103 throw e; 104 } 105 } 106 canRecoverFromFailure(VerificationMode verificationMode)107 protected boolean canRecoverFromFailure(VerificationMode verificationMode) { 108 return !(verificationMode instanceof AtMost || verificationMode instanceof NoMoreInteractions); 109 } 110 copyWithVerificationMode(VerificationMode verificationMode)111 public VerificationOverTimeImpl copyWithVerificationMode(VerificationMode verificationMode) { 112 return new VerificationOverTimeImpl(pollingPeriodMillis, timer.duration(), verificationMode, returnOnSuccess); 113 } 114 sleep(long sleep)115 private void sleep(long sleep) { 116 try { 117 Thread.sleep(sleep); 118 } catch (InterruptedException ie) { 119 throw new RuntimeException("Thread sleep has been interrupted", ie); 120 } 121 } 122 123 @Override description(String description)124 public VerificationMode description(String description) { 125 return VerificationModeFactory.description(this, description); 126 } 127 isReturnOnSuccess()128 public boolean isReturnOnSuccess() { 129 return returnOnSuccess; 130 } 131 getPollingPeriodMillis()132 public long getPollingPeriodMillis() { 133 return pollingPeriodMillis; 134 } 135 getTimer()136 public Timer getTimer() { 137 return timer; 138 } 139 getDelegate()140 public VerificationMode getDelegate() { 141 return delegate; 142 } 143 } 144