/
ScaledTimeSpans.scala
201 lines (183 loc) · 8.04 KB
/
ScaledTimeSpans.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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
/*
* 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.time.Span
// SKIP-SCALATESTJS,NATIVE-START
import org.scalatest.tools.Runner
// SKIP-SCALATESTJS,NATIVE-END
/*
I have checked in the PoC at the following branch:-
https://scalatest.googlecode.com/svn/branches/akka-span-factor
The overriding is pretty straight forward (though it did take some time for me to read through akka's doc to figure out how to get the akka.test.timefactor correctly):-
import org.scalatest.concurrent.Eventually
import akka.actor.ActorSystem
import akka.testkit.TestKitExtension
object AkkaEventually extends Eventually {
override def spanScaleFactor: Double = TestKitExtension.get(ActorSystem()).TestTimeFactor
}
and the TestTimeFactor is defined in application.conf:-
akka {
test {
timefactor = 2.0
}
}
I have checked in AkkaEventuallySpec that checks the behavior, you can open and run the project using eclipse, with dependency to jars (couldn't find akka maven configuration in their download page) I attached and scalatest 1.8 RC2 that built from to-release-as-1.8 branch.
Hope this helps.
Thanks!
*/
/*
import org.scalatest.concurrent.SpanScaleFactor
import akka.actor.ActorSystem
import akka.testkit.TestKitExtension
trait AkkaSpanScaleFactor extends SpanScaleFactor {
override def spanScaleFactor: Double = TestKitExtension.get(ActorSystem()).TestTimeFactor
}
and the TestTimeFactor is defined in application.conf:-
akka {
test {
timefactor = 2.0
}
}
class MySpec extends FunSpec with Eventually with AkkaSpanScaleFactor {
// ..
}
*/
/**
* Trait providing a <code>scaled</code> method that can be used to scale time
* <code>Span</code>s used during the testing of asynchronous operations.
*
* <p>
* The <code>scaled</code> method allows tests of asynchronous operations to be tuned
* according to need. For example, <code>Span</code>s can be scaled larger when running
* tests on slower continuous integration servers or smaller when running on faster
* development machines.
* </p>
*
* <p>
* The <code>Double</code> factor by which to scale the <code>Span</code>s passed to
* <code>scaled</code> is obtained from the <code>spanScaleFactor</code> method, also declared
* in this trait. By default this method returns 1.0, but can be configured to return
* a different value by passing a <code>-F</code> argument to <a href="../tools/Runner$.html"><code>Runner</code></a> (or
* an equivalent mechanism in an ant, sbt, or Maven build file).
* </p>
*
* <p>
* The default timeouts and intervals defined for traits <a href="Eventually.html"><code>Eventually</code></a> and
* <a href="Waiters.html"><code>Waiters</code></a> invoke <code>scaled</code>, so those defaults
* will be scaled automatically. Other than such defaults, however, to get a <code>Span</code>
* to scale you'll need to explicitly pass it to <code>scaled</code>.
* For example, here's how you would scale a <code>Span</code> you supply to
* the <code>failAfter</code> method from trait <code>Timeouts</code>:
* </p>
*
* <pre class="stHighlighted">
* failAfter(scaled(<span class="stLiteral">150</span> millis)) {
* <span class="stLineComment">// ...</span>
* }
* </pre>
*
* <p>
* The reason <code>Span</code>s are not scaled automatically in the general case is
* to make code obvious. If a reader sees <code>failAfter(1 second)</code>, it will
* mean exactly that: fail after one second. And if a <code>Span</code> will be scaled,
* the reader will clearly see that as well: <code>failAfter(scaled(1 second))</code>.
* </p>
*
* <h2>Overriding <code>spanScaleFactor</code></h2>
*
* </p>
* You can override the <code>spanScaleFactor</code> method to configure the factor by a
* different means. For example, to configure the factor from Akka
* TestKit's test time factor you might create a trait like this:
* </p>
*
* <pre class="stHighlighted">
* <span class="stReserved">import</span> org.scalatest.concurrent.ScaledTimeSpans
* <span class="stReserved">import</span> akka.actor.ActorSystem
* <span class="stReserved">import</span> akka.testkit.TestKitExtension
* <br/><span class="stReserved">trait</span> <span class="stType">AkkaSpanScaleFactor</span> <span class="stReserved">extends</span> <span class="stType">ScaledTimeSpans</span> {
* <span class="stReserved">override</span> <span class="stReserved">def</span> spanScaleFactor: <span class="stType">Double</span> =
* TestKitExtension.get(<span class="stType">ActorSystem</span>()).TestTimeFactor
* }
* </pre>
*
* <p>
* This trait overrides <code>spanScaleFactor</code> so that it takes its
* scale factor from Akka's <code>application.conf</code> file.
* You could then scale <code>Span</code>s tenfold in Akka's configuration file
* like this:
* </p>
*
* <pre>
* akka {
* test {
* timefactor = 10.0
* }
* }
* </pre>
*
* <p>
* Armed with this trait and configuration file, you can simply mix trait
* <code>AkkaSpanScaleFactor</code> into any test class whose <code>Span</code>s
* you want to scale, like this:
*
* <pre class="stHighlighted">
* <span class="stReserved">class</span> <span class="stType">MySpec</span> <span class="stReserved">extends</span> <span class="stType">FunSpec</span> <span class="stReserved">with</span> <span class="stType">Eventually</span> <span class="stReserved">with</span> <span class="stType">AkkaSpanScaleFactor</span> {
* <span class="stLineComment">// ..</span>
* }
* </pre>
*
* @author Bill Venners
*/
trait ScaledTimeSpans {
// TODO: Verify the example works. I just now changed concurrent.SpanScaleFactor into ScaledTimeSpans, because we
// don't actually have a SpanScaleFactor. It was an intermediate trait that was never released final. I'd rather have
// an example that may work than one I know does not work, but better yet is one I know actually does work!
/**
* Scales the passed <code>Span</code> by the <code>Double</code> factor returned
* by <code>spanScaleFactor</code>.
*
* <p>
* The <code>Span</code> is scaled by invoking its <code>scaledBy</code> method,
* thus this method has the same behavior:
* The value returned by <code>spanScaleFactor</code> can be any positive number or zero,
* including a fractional number. A number greater than one will scale the <code>Span</code>
* up to a larger value. A fractional number will scale it down to a smaller value. A
* factor of 1.0 will cause the exact same <code>Span</code> to be returned. A
* factor of zero will cause <code>Span.ZeroLength</code> to be returned.
* If overflow occurs, <code>Span.Max</code> will be returned. If underflow occurs,
* <code>Span.ZeroLength</code> will be returned.
* </p>
*
* @throws IllegalArgumentException if the value returned from <code>spanScaleFactor</code>
* is less than zero
*/
final def scaled(span: Span): Span = span scaledBy spanScaleFactor
/**
* The factor by which the <code>scaled</code> method will scale <code>Span</code>s.
*
* <p>
* The default implementation of this method will return the <em>span scale factor</em> that
* was specified for the run, or 1.0 if no factor was specified. For example, you can specify a span scale factor when invoking ScalaTest
* via the command line by passing a <a href="../tools/Runner$.html#scalingTimeSpans"><code>-F</code> argument</a> to <a href="../tools/Runner$.html"><code>Runner</code></a>.
* </p>
*/
def spanScaleFactor: Double =
// SKIP-SCALATESTJS,NATIVE-START
Runner.spanScaleFactor
// SKIP-SCALATESTJS,NATIVE-END
//SCALATESTJS,NATIVE-ONLY 1.0
}