1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.hosted.node.admin.integrationTests;
import java.util.Iterator;
import java.util.LinkedList;
import static org.junit.Assert.assertTrue;
/**
* Takes in strings representing function calls with their parameters and allows to check whether a subset of calls
* occurred in a specific order. For example, by calling {@link CallOrderVerifier#add(String)}
* with A, B, C, D, E, D, A, F, D and G, then {@link CallOrderVerifier#verifyInOrder(String...)} with
* A, B, D => true,
* A, D, A => true,
* C, D, F => true,
* B, D, A => true
* B, F, D, A => false,
* C, B => false
*
* @author freva
*/
public class CallOrderVerifier {
private static final int waitForCallOrderTimeout = 600; //ms
private final LinkedList<String> callOrder = new LinkedList<>();
private final Object monitor = new Object();
public void add(String call) {
synchronized (monitor) {
callOrder.add(call);
}
}
public void assertInOrder(String... functionCalls) {
assertInOrderWithAssertMessage("", functionCalls);
}
public void assertInOrderWithAssertMessage(String assertMessage, String... functionCalls) {
boolean inOrder = verifyInOrder(waitForCallOrderTimeout, functionCalls);
if ( ! inOrder && ! assertMessage.isEmpty())
System.err.println(assertMessage);
assertTrue(toString(), inOrder);
}
/**
* Checks if list of function calls occur in order given within a timeout
* @param timeout Max number of milliseconds to check for if function calls occur in order
* @param functionCalls The expected order of function calls
* @return true if the actual order of calls was equal to the order provided within timeout, false otherwise.
*/
private boolean verifyInOrder(long timeout, String... functionCalls) {
final long startTime = System.currentTimeMillis();
while (System.currentTimeMillis() - startTime < timeout) {
if (verifyInOrder(functionCalls)) {
return true;
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return false;
}
private boolean verifyInOrder(String... functionCalls) {
int pos = 0;
synchronized (monitor) {
for (String functionCall : functionCalls) {
int temp = indexOf(callOrder.listIterator(pos), functionCall);
if (temp == -1) {
return false;
}
pos += temp;
}
}
return true;
}
/**
* Finds the first index of needle in haystack after a given position.
* @param iter Iterator to search in
* @param search Element to find in iterator
* @return Index of the next search in after startPos, -1 if not found
*/
private int indexOf(Iterator<String> iter, String search) {
for (int i = 0; iter.hasNext(); i++) {
if (search.equals(iter.next())) {
return i;
}
}
return -1;
}
@Override
public String toString() {
synchronized (monitor) {
return callOrder.toString();
}
}
}
|