~ubuntu-branches/ubuntu/wily/gs-collections/wily

« back to all changes in this revision

Viewing changes to scala-unit-tests/src/test/scala/com/gs/collections/impl/ThreadSafetyTestTrait.scala

  • Committer: Package Import Robot
  • Author(s): Emmanuel Bourg
  • Date: 2015-07-23 12:42:30 UTC
  • Revision ID: package-import@ubuntu.com-20150723124230-2rjvfv6elyn2m7d4
Tags: upstream-5.1.0
ImportĀ upstreamĀ versionĀ 5.1.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright 2013 Goldman Sachs.
 
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
 
 
17
package com.gs.collections.impl
 
18
 
 
19
import java.util.concurrent.TimeUnit
 
20
import org.junit.Assert
 
21
 
 
22
trait ThreadSafetyTestTrait
 
23
{
 
24
    def createReadLockHolderThread(gate: Gate): Thread
 
25
 
 
26
    def createWriteLockHolderThread(gate: Gate): Thread
 
27
 
 
28
    class Gate
 
29
    {
 
30
        val latch = new java.util.concurrent.CountDownLatch(1)
 
31
 
 
32
        def open()
 
33
        {
 
34
            this.latch.countDown()
 
35
        }
 
36
 
 
37
        def await()
 
38
        {
 
39
            this.latch.await()
 
40
        }
 
41
    }
 
42
 
 
43
    def sleep(gate: Gate)
 
44
    {
 
45
        gate.open()
 
46
 
 
47
        try
 
48
        {
 
49
            Thread.sleep(java.lang.Long.MAX_VALUE)
 
50
        }
 
51
        catch
 
52
        {
 
53
            case ignore: InterruptedException => Thread.currentThread.interrupt
 
54
        }
 
55
    }
 
56
 
 
57
    def time(code: => Unit) =
 
58
    {
 
59
        val before = System.currentTimeMillis
 
60
        code
 
61
        val after = System.currentTimeMillis
 
62
        after - before
 
63
    }
 
64
 
 
65
    def spawn(code: => Unit) =
 
66
    {
 
67
        val result = new Thread
 
68
        {
 
69
            override def run = code
 
70
        }
 
71
        result.start()
 
72
        result
 
73
    }
 
74
 
 
75
    def assertReadersBlocked(code: => Unit)
 
76
    {
 
77
        this.assertReadSafety(threadSafe = true, 10L, TimeUnit.MILLISECONDS, code)
 
78
    }
 
79
 
 
80
    def assertReadersNotBlocked(code: => Unit)
 
81
    {
 
82
        this.assertReadSafety(threadSafe = false, 60L, TimeUnit.SECONDS, code)
 
83
    }
 
84
 
 
85
    def assertWritersBlocked(code: => Unit)
 
86
    {
 
87
        this.assertWriteSafety(threadSafe = true, 10L, TimeUnit.MILLISECONDS, code)
 
88
    }
 
89
 
 
90
    def assertWritersNotBlocked(code: => Unit)
 
91
    {
 
92
        this.assertWriteSafety(threadSafe = false, 60L, TimeUnit.SECONDS, code)
 
93
    }
 
94
 
 
95
    def assertReadSafety(threadSafe: Boolean, timeout: Long, timeUnit: TimeUnit, code: => Unit)
 
96
    {
 
97
        val gate = new Gate
 
98
        assertThreadSafety(timeout, timeUnit, gate, code, threadSafe, createReadLockHolderThread(gate))
 
99
    }
 
100
 
 
101
    def assertWriteSafety(threadSafe: Boolean, timeout: Long, timeUnit: TimeUnit, code: => Unit)
 
102
    {
 
103
        val gate = new Gate
 
104
        assertThreadSafety(timeout, timeUnit, gate, code, threadSafe, createWriteLockHolderThread(gate))
 
105
    }
 
106
 
 
107
    def assertThreadSafety(timeout: Long, timeUnit: TimeUnit, gate: ThreadSafetyTestTrait.this.type#Gate, code: => Unit, threadSafe: Boolean, lockHolderThread: Thread)
 
108
    {
 
109
        val millisTimeout = TimeUnit.MILLISECONDS.convert(timeout, timeUnit)
 
110
        val measuredTime = time
 
111
        {
 
112
            // Don't start until the other thread is synchronized on classUnderTest
 
113
            gate.await()
 
114
            spawn(code).join(millisTimeout, 0)
 
115
        }
 
116
 
 
117
        Assert.assertEquals(
 
118
            "Measured " + measuredTime + " ms but timeout was " + millisTimeout + " ms.",
 
119
            threadSafe,
 
120
            measuredTime >= millisTimeout)
 
121
 
 
122
        lockHolderThread.interrupt()
 
123
        lockHolderThread.join()
 
124
    }
 
125
}