ffd8d6493f8483c56f97e7cdc671d488a4a4ca92
[WebKit-https.git] / Tools / TestWebKitAPI / Tests / WTF / WorkQueue.cpp
1 /*
2  * Copyright (C) 2015 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27
28 #include "Test.h"
29 #include <wtf/Vector.h>
30 #include <wtf/WorkQueue.h>
31 #include <string>
32 #include <thread>
33
34 namespace TestWebKitAPI {
35
36 static const char* simpleTestLabel = "simpleTest";
37 static const char* longTestLabel = "longTest";
38 static const char* thirdTestLabel = "thirdTest";
39 static const char* dispatchAfterLabel = "dispatchAfter";
40     
41 TEST(WTF_WorkQueue, Simple)
42 {
43     DeprecatedMutex m_lock;
44     ThreadCondition m_testCompleted;
45     Vector<std::string> m_functionCallOrder;
46
47     bool calledSimpleTest = false;
48     bool calledLongTest = false;
49     bool calledThirdTest = false;
50
51     static const char* simpleTestLabel = "simpleTest";
52     static const char* longTestLabel = "longTest";
53     static const char* thirdTestLabel = "thirdTest";
54
55     auto queue = WorkQueue::create("com.apple.WebKit.Test.simple");
56     int initialRefCount = queue->refCount();
57     EXPECT_EQ(1, initialRefCount);
58
59     DeprecatedMutexLocker locker(m_lock);
60     queue->dispatch([&](void) {
61         m_functionCallOrder.append(simpleTestLabel);
62         calledSimpleTest = true;
63     });
64
65     queue->dispatch([&](void) {
66         m_functionCallOrder.append(longTestLabel);
67         std::this_thread::sleep_for(std::chrono::nanoseconds(100));
68         calledLongTest = true;
69     });
70
71     queue->dispatch([&](void) {
72         DeprecatedMutexLocker locker(m_lock);
73         m_functionCallOrder.append(thirdTestLabel);
74         calledThirdTest = true;
75
76         EXPECT_TRUE(calledSimpleTest);
77         EXPECT_TRUE(calledLongTest);
78         EXPECT_TRUE(calledThirdTest);
79         
80         m_testCompleted.signal();
81     });
82
83     EXPECT_GT(queue->refCount(), 1);
84
85     m_testCompleted.wait(m_lock);
86
87     EXPECT_TRUE(calledSimpleTest);
88     EXPECT_TRUE(calledLongTest);
89     EXPECT_TRUE(calledThirdTest);
90
91     EXPECT_EQ(static_cast<size_t>(3), m_functionCallOrder.size());
92     EXPECT_STREQ(simpleTestLabel, m_functionCallOrder[0].c_str());
93     EXPECT_STREQ(longTestLabel, m_functionCallOrder[1].c_str());
94     EXPECT_STREQ(thirdTestLabel, m_functionCallOrder[2].c_str());
95 }
96
97 TEST(WTF_WorkQueue, TwoQueues)
98 {
99     DeprecatedMutex m_lock;
100     ThreadCondition m_testQueue1Completed, m_testQueue2Completed;
101     Vector<std::string> m_functionCallOrder;
102
103     bool calledSimpleTest = false;
104     bool calledLongTest = false;
105     bool calledThirdTest = false;
106     
107     auto queue1 = WorkQueue::create("com.apple.WebKit.Test.twoQueues1");
108     auto queue2 = WorkQueue::create("com.apple.WebKit.Test.twoQueues2");
109
110     EXPECT_EQ(1, queue1->refCount());
111     EXPECT_EQ(1, queue2->refCount());
112
113     DeprecatedMutexLocker locker(m_lock);
114     
115     queue1->dispatch([&](void) {
116         m_functionCallOrder.append(simpleTestLabel);
117         calledSimpleTest = true;
118     });
119
120     queue2->dispatch([&](void) {
121         std::this_thread::sleep_for(std::chrono::milliseconds(50));
122
123         DeprecatedMutexLocker locker(m_lock);
124
125         // Will fail if queue2 took the mutex before queue1.
126         EXPECT_TRUE(calledThirdTest);
127
128         m_functionCallOrder.append(longTestLabel);
129         calledLongTest = true;
130         m_testQueue2Completed.signal();
131     });
132
133     queue1->dispatch([&](void) {
134         DeprecatedMutexLocker locker(m_lock);
135         m_functionCallOrder.append(thirdTestLabel);
136         calledThirdTest = true;
137         
138         m_testQueue1Completed.signal();
139     });
140
141     m_testQueue1Completed.wait(m_lock);
142
143     EXPECT_TRUE(calledSimpleTest);
144     EXPECT_FALSE(calledLongTest);
145     EXPECT_TRUE(calledThirdTest);
146
147     m_testQueue2Completed.wait(m_lock);
148
149     EXPECT_TRUE(calledSimpleTest);
150     EXPECT_TRUE(calledLongTest);
151     EXPECT_TRUE(calledThirdTest);
152
153     EXPECT_EQ(static_cast<size_t>(3), m_functionCallOrder.size());
154     EXPECT_STREQ(simpleTestLabel, m_functionCallOrder[0].c_str());
155     EXPECT_STREQ(thirdTestLabel, m_functionCallOrder[1].c_str());
156     EXPECT_STREQ(longTestLabel, m_functionCallOrder[2].c_str());
157 }
158
159 TEST(WTF_WorkQueue, DispatchAfter)
160 {
161     DeprecatedMutex m_lock;
162     ThreadCondition m_testCompleted, m_dispatchAfterTestCompleted;
163     Vector<std::string> m_functionCallOrder;
164
165     bool calledSimpleTest = false;
166     bool calledDispatchAfterTest = false;
167
168     auto queue = WorkQueue::create("com.apple.WebKit.Test.dispatchAfter");
169
170     DeprecatedMutexLocker locker(m_lock);
171
172     queue->dispatch([&](void) {
173         DeprecatedMutexLocker locker(m_lock);
174         m_functionCallOrder.append(simpleTestLabel);
175         calledSimpleTest = true;
176         m_testCompleted.signal();
177     });
178
179     queue->dispatchAfter(std::chrono::milliseconds(500), [&](void) {
180         DeprecatedMutexLocker locker(m_lock);
181         m_functionCallOrder.append(dispatchAfterLabel);
182         calledDispatchAfterTest = true;
183         m_dispatchAfterTestCompleted.signal();
184     });
185
186     m_testCompleted.wait(m_lock);
187
188     EXPECT_TRUE(calledSimpleTest);
189     EXPECT_FALSE(calledDispatchAfterTest);
190     
191     m_dispatchAfterTestCompleted.wait(m_lock);
192
193     EXPECT_TRUE(calledSimpleTest);
194     EXPECT_TRUE(calledDispatchAfterTest);
195
196     EXPECT_EQ(static_cast<size_t>(2), m_functionCallOrder.size());
197     EXPECT_STREQ(simpleTestLabel, m_functionCallOrder[0].c_str());
198     EXPECT_STREQ(dispatchAfterLabel, m_functionCallOrder[1].c_str());
199 }
200
201 } // namespace TestWebKitAPI