/
PatienceConfiguration.scala
151 lines (141 loc) · 5.89 KB
/
PatienceConfiguration.scala
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/*
* Copyright 2001-2013 Artima, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.scalatest.concurrent
import org.scalatest._
import time.Span
import PatienceConfiguration._
import org.scalactic.Requirements._
/**
* Trait providing methods and classes used to configure timeouts and, where relevant, the interval
* between retries.
*
* <p>
* This trait is called <code>PatienceConfiguration</code> because it allows configuration of two
* values related to patience: The timeout specifies how much time asynchronous operations will be given
* to succeed before giving up. The interval specifies how much time to wait between checks to determine
* success when polling.
* </p>
*
* <p>
* The default values for timeout and interval provided by trait <code>PatienceConfiguration</code> are tuned for unit testing,
* where running tests as fast as
* possible is a high priority and subsystems requiring asynchronous operations are therefore often replaced
* by mocks. This table shows the default values:
* </p>
*
* <table style="border-collapse: collapse; border: 1px solid black">
* <tr><th style="background-color: #CCCCCC; border-width: 1px; padding: 3px; text-align: center; border: 1px solid black"><strong>Configuration Parameter</strong></th><th style="background-color: #CCCCCC; border-width: 1px; padding: 3px; text-align: center; border: 1px solid black"><strong>Default Value</strong></th></tr>
* <tr>
* <td style="border-width: 1px; padding: 3px; border: 1px solid black; text-align: center">
* <code>timeout</code>
* </td>
* <td style="border-width: 1px; padding: 3px; border: 1px solid black; text-align: center">
* <code>scaled(150 milliseconds)</code>
* </td>
* </tr>
* <tr>
* <td style="border-width: 1px; padding: 3px; border: 1px solid black; text-align: center">
* <code>interval</code>
* </td>
* <td style="border-width: 1px; padding: 3px; border: 1px solid black; text-align: center">
* <code>scaled(15 milliseconds)</code>
* </td>
* </tr>
* </table>
*
* <p>
* Values more appropriate to integration testing, where asynchronous operations tend to take longer because the tests are run
* against the actual subsytems (not mocks), can be obtained by mixing in trait <a href="IntegrationPatience.html"><code>IntegrationPatience</code></a>.
* </p>
*
* <p>
* The default values of both timeout and interval are passed to the <code>scaled</code> method, inherited
* from <code>ScaledTimeSpans</code>, so that the defaults can be scaled up
* or down together with other scaled time spans. See the documentation for trait <a href="ScaledTimeSpans.html"><code>ScaledTimeSpans</code></a>
* for more information.
* </p>
*
* <p>
* Timeouts are used by the <code>eventually</code> methods of trait
* <a href="Eventually.html"><code>Eventually</code></a> and the <code>await</code> method of class
* <code>Waiter</code>, a member of trait
* <a href="Waiters.html"><code>Waiters</code></a>. Intervals are used by
* the <code>eventually</code> methods.
* </p>
*
* @author Bill Venners
*/
trait PatienceConfiguration extends AbstractPatienceConfiguration {
private val defaultPatienceConfig = PatienceConfig()
/**
* Implicit <code>PatienceConfig</code> value providing default configuration values.
*
* <p>
* To change the default configuration, override or hide this <code>def</code> with another implicit
* <code>PatienceConfig</code> containing your desired default configuration values.
* </p>
*/
implicit def patienceConfig: PatienceConfig = defaultPatienceConfig
/**
* Returns a <code>Timeout</code> configuration parameter containing the passed value, which
* specifies the maximum amount to wait for an asynchronous operation to complete.
*/
def timeout(value: Span) = Timeout(value)
/**
* Returns an <code>Interval</code> configuration parameter containing the passed value, which
* specifies the amount of time to sleep after a retry.
*/
def interval(value: Span) = Interval(value) // TODO: Throw NPE
}
object PatienceConfiguration {
/**
* Abstract class defining a family of configuration parameters for traits <code>Eventually</code> and <code>Waiters</code>.
*
* <p>
* The subclasses of this abstract class are used to pass configuration information to
* the <code>eventually</code> methods of trait <code>Eventually</code> and the <code>await</code> methods of trait <code>Waiters</code>.
* </p>
*
* @author Bill Venners
* @author Chua Chee Seng
*/
sealed abstract class PatienceConfigParam extends Product with Serializable
/**
* A <code>PatienceConfigParam</code> that specifies the maximum amount of time to wait for an asynchronous operation to
* complete.
*
* @param value the maximum amount of time to retry before giving up and throwing
* <code>TestFailedException</code>.
* @throws NullArgumentException if passed <code>value</code> is <code>null</code>
*
* @author Bill Venners
*/
final case class Timeout(value: Span) extends PatienceConfigParam {
requireNonNull(value)
}
/**
* A <code>PatienceConfigParam</code> that specifies the amount of time to sleep after
* a retry.
*
* @param value the amount of time to sleep between each attempt
* @throws NullArgumentException if passed <code>value</code> is <code>null</code>
*
* @author Bill Venners
*/
final case class Interval(value: Span) extends PatienceConfigParam {
requireNonNull(value)
}
}