1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.compatibility.common.util; 17 18 import android.os.SystemClock; 19 20 import org.mockito.Mockito; 21 import org.mockito.exceptions.base.MockitoAssertionError; 22 import org.mockito.internal.verification.api.VerificationData; 23 import org.mockito.invocation.Invocation; 24 import org.mockito.verification.VerificationMode; 25 26 import java.util.List; 27 28 /** 29 * Custom verification mode that allows waiting for the specific invocation to happen within 30 * a certain time interval. Not that unlike {@link Mockito#timeout(int)}, this mode will not 31 * return early and throw exception if the expected method was called with a different set of 32 * parameters before the call that we're waiting for. 33 */ 34 public class Within implements VerificationMode { 35 private static final long TIME_SLICE = 50; 36 private final long mTimeout; 37 Within(long timeout)38 public Within(long timeout) { 39 mTimeout = timeout; 40 } 41 42 @Override verify(VerificationData data)43 public void verify(VerificationData data) { 44 long timeout = mTimeout; 45 MockitoAssertionError errorToRethrow = null; 46 // Loop in the same way we do in PollingCheck, sleeping and then testing for the target 47 // invocation 48 while (timeout > 0) { 49 SystemClock.sleep(TIME_SLICE); 50 51 try { 52 final List<Invocation> actualInvocations = data.getAllInvocations(); 53 // Iterate over all invocations so far to see if we have a match 54 for (Invocation invocation : actualInvocations) { 55 if (data.getTarget().matches(invocation)) { 56 // Found our match within our timeout. Mark all invocations as verified 57 markAllInvocationsAsVerified(data); 58 // and return 59 return; 60 } 61 } 62 } catch (MockitoAssertionError assertionError) { 63 errorToRethrow = assertionError; 64 } 65 66 timeout -= TIME_SLICE; 67 } 68 69 if (errorToRethrow != null) { 70 throw errorToRethrow; 71 } 72 73 throw new MockitoAssertionError( 74 "Timed out while waiting " + mTimeout + "ms for " + data.getTarget().toString()); 75 } 76 77 // TODO: Uncomment once upgraded to 2.7.13 78 // @Override description(String description)79 public VerificationMode description(String description) { 80 // Return this for now. 81 // TODO: Return wrapper once upgraded to 2.7.13 82 return this; 83 } 84 markAllInvocationsAsVerified(VerificationData data)85 private void markAllInvocationsAsVerified(VerificationData data) { 86 for (Invocation invocation : data.getAllInvocations()) { 87 invocation.markVerified(); 88 data.getTarget().captureArgumentsFrom(invocation); 89 } 90 } 91 } 92