- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / test / data / nacl / ppapi / ppb_core / ppapi_ppb_core.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <pthread.h>
6 #include <stdio.h>
7 #include <string.h>
8 #include <unistd.h>
9
10 #include "native_client/src/shared/platform/nacl_check.h"
11 #include "ppapi/native_client/tests/ppapi_test_lib/get_browser_interface.h"
12 #include "ppapi/native_client/tests/ppapi_test_lib/test_interface.h"
13
14 #include "ppapi/c/pp_errors.h"
15 #include "ppapi/c/ppb_core.h"
16 #include "ppapi/c/ppb_url_request_info.h"
17
18 namespace {
19
20 const int32_t kNotPPError = 12345;
21 const int kStressChecksum = 0x12345678;
22
23 void EmptyCompletionCallback(void* data, int32_t /*result*/) {
24   CHECK(data == NULL);
25 }
26
27 // Calls PPB_Core::CallOnMainThread(). To be invoked off the main thread.
28 void* InvokeCallOnMainThread(void* thread_argument) {
29   PPB_Core* ppb_core = reinterpret_cast<PPB_Core*>(thread_argument);
30   PP_CompletionCallback callback = MakeTestableCompletionCallback(
31       "CallOnMainThreadCallback_FromNonMainThread",
32       EmptyCompletionCallback,
33       NULL /*user_data*/);
34   ppb_core->CallOnMainThread(0 /*delay*/, callback, PP_OK);
35   return NULL;
36 }
37
38 struct StressData {
39   const PPB_Core* ppb_core_;
40   const int callbacks_per_thread_;
41   int callback_counter_;
42   const int checksum_;
43   StressData(const PPB_Core* ppb_core, int callbacks_per_thread, int total)
44       : ppb_core_(ppb_core),
45         callbacks_per_thread_(callbacks_per_thread),
46         callback_counter_(total),
47         checksum_(kStressChecksum) {
48   }
49 };
50
51 // When passed in stress->callback_counter_ reaches zero, notify JS via
52 // MakeTestableCompletionCallback.
53 void ThreadStressCompletionCallback(void* data, int32_t result) {
54   if (PP_OK == result) {
55     StressData* stress = reinterpret_cast<StressData*>(data);
56     CHECK(kStressChecksum == stress->checksum_);
57     CHECK(NULL != stress->ppb_core_);
58     stress->callback_counter_ -= 1;
59     if (0 == stress->callback_counter_) {
60       // All the callbacks triggered, so now report back that this test passed.
61       PP_CompletionCallback callback = MakeTestableCompletionCallback(
62           "CallOnMainThreadCallback_ThreadStress",
63           EmptyCompletionCallback, NULL);
64       stress->ppb_core_->CallOnMainThread(0, callback, PP_OK);
65       // At this point we're done with the structure, so set it to zero.
66       // If anyone from here on out tries to access it, either the pointer
67       // check or the checksum should trip. It is intentionally left on the
68       // heap to prevent re-use of the memory.
69       memset(stress, 0, sizeof(*stress));
70     }
71   }
72 }
73
74 // Calls PPB_Core::CallOnMainThread(). To be invoked off the main thread.
75 // This is a stess test version.
76 void* InvokeCallOnMainThreadStress(void* thread_argument) {
77   StressData* stress = reinterpret_cast<StressData*>(thread_argument);
78   PP_CompletionCallback callback = PP_MakeCompletionCallback(
79       ThreadStressCompletionCallback, stress);
80   for (int i = 0; i < stress->callbacks_per_thread_; ++i) {
81     CHECK(NULL != stress->ppb_core_);
82     CHECK(kStressChecksum == stress->checksum_);
83     stress->ppb_core_->CallOnMainThread(0, callback, PP_OK);
84   }
85   return NULL;
86 }
87
88 // Calls PPB_Core::IsMainThread(). To be invoked off the main thread.
89 void* InvokeIsMainThread(void* thread_argument) {
90   PPB_Core* ppb_core = reinterpret_cast<PPB_Core*>(thread_argument);
91   return reinterpret_cast<void*>(ppb_core->IsMainThread());
92 }
93
94 // Tests PPB_Core::GetTime().
95 void TestGetTime() {
96   PP_Time time1 = PPBCore()->GetTime();
97   EXPECT(time1 > 0);
98
99   usleep(100000);  // 0.1 second
100
101   PP_Time time2 = PPBCore()->GetTime();
102   EXPECT(time2 > time1);
103
104   TEST_PASSED;
105 }
106
107 // Tests PPB_Core::GetTimeTicks().
108 void TestGetTimeTicks() {
109   PP_TimeTicks time_ticks1 = PPBCore()->GetTimeTicks();
110   EXPECT(time_ticks1 > 0);
111
112   usleep(100000);  // 0.1 second
113
114   PP_TimeTicks time_ticks2 = PPBCore()->GetTimeTicks();
115   EXPECT(time_ticks2 > time_ticks1);
116
117   TEST_PASSED;
118 }
119
120 // Tests PPB_Core::CallOnMainThread() from the main thread.
121 void TestCallOnMainThread_FromMainThread() {
122   PP_CompletionCallback callback = MakeTestableCompletionCallback(
123       "CallOnMainThreadCallback_FromMainThread",
124       EmptyCompletionCallback,
125       NULL /*user_data*/);
126   PPBCore()->CallOnMainThread(0 /*delay*/, callback, kNotPPError);
127
128   TEST_PASSED;
129 }
130
131 // Tests PPB_Core::CallOnMainThread() from the main thread after a long delay.
132 // This is useful for surf-away/reload tests where the nexe is aborted
133 // after the callback was scheduled, but before it was fired.
134 void TestCallOnMainThread_FromMainThreadDelayed() {
135   PP_CompletionCallback callback = MakeTestableCompletionCallback(
136       "CallOnMainThreadCallback_FromMainThreadDelayed",
137       EmptyCompletionCallback,
138       NULL /*user_data*/);
139   PPBCore()->CallOnMainThread(1000 /*delay in ms*/, callback, kNotPPError);
140
141   TEST_PASSED;
142 }
143
144 // Tests PPB_Core::CallOnMainThread from non-main thread.
145 void TestCallOnMainThread_FromNonMainThread() {
146   pthread_t tid;
147   void* ppb_core = reinterpret_cast<void*>(const_cast<PPB_Core*>(PPBCore()));
148   CHECK(pthread_create(&tid, NULL, InvokeCallOnMainThread, ppb_core) == 0);
149   // Use a non-joined thread.  This is a more useful test than
150   // joining the thread: we want to test CallOnMainThread() when it
151   // is called concurrently with the main thread.
152   CHECK(pthread_detach(tid) == 0);
153
154   TEST_PASSED;
155 }
156
157 // Tests PPB_Core::CallOnMainThread from non-main thread.
158 // This is a stress test version that calls many times from many threads.
159 void TestCallOnMainThread_FromNonMainThreadStress() {
160   const int kNumThreads = 10;
161   const int kNumPerThread = 100;
162   const int kNumCallbacks = kNumThreads * kNumPerThread;
163   StressData* stress = new StressData(PPBCore(), kNumPerThread, kNumCallbacks);
164   for (int i = 0; i < kNumThreads; ++i) {
165     pthread_t tid;
166     CHECK(pthread_create(
167         &tid, NULL, InvokeCallOnMainThreadStress, stress) == 0);
168     CHECK(pthread_detach(tid) == 0);
169   }
170   TEST_PASSED;
171 }
172
173 // Tests PPB_Core::IsMainThread() from the main thread.
174 void TestIsMainThread_FromMainThread() {
175   EXPECT(PPBCore()->IsMainThread() == PP_TRUE);
176   TEST_PASSED;
177 }
178
179 // Tests PPB_Core::IsMainThread() from non-main thread.
180 void TestIsMainThread_FromNonMainThread() {
181   pthread_t tid;
182   void* thread_result;
183   void* ppb_core = reinterpret_cast<void*>(const_cast<PPB_Core*>(PPBCore()));
184   CHECK(pthread_create(&tid, NULL, InvokeIsMainThread, ppb_core) == 0);
185   CHECK(pthread_join(tid, &thread_result) == 0);
186   EXPECT(reinterpret_cast<int>(thread_result) == PP_FALSE);
187
188   TEST_PASSED;
189 }
190
191
192 // Tests PPB_Core::AddRefResource() and PPB_Core::ReleaseResource() with
193 // a valid resource.
194 void TestAddRefAndReleaseResource() {
195   PP_Resource valid_resource = PPBURLRequestInfo()->Create(pp_instance());
196   EXPECT(valid_resource != kInvalidResource);
197   EXPECT(PPBURLRequestInfo()->IsURLRequestInfo(valid_resource) == PP_TRUE);
198
199   // Adjusting ref count should not delete the resource.
200   for (size_t j = 0; j < 100; ++j) PPBCore()->AddRefResource(valid_resource);
201   EXPECT(PPBURLRequestInfo()->IsURLRequestInfo(valid_resource) == PP_TRUE);
202   for (size_t j = 0; j < 100; ++j) PPBCore()->ReleaseResource(valid_resource);
203   EXPECT(PPBURLRequestInfo()->IsURLRequestInfo(valid_resource) == PP_TRUE);
204
205   // Releasing the ref count from Create() must delete the resource.
206   PPBCore()->ReleaseResource(valid_resource);
207   EXPECT(PPBURLRequestInfo()->IsURLRequestInfo(valid_resource) != PP_TRUE);
208
209   TEST_PASSED;
210 }
211
212 // Tests PPB_Core::AddRefResource() and PPB_Core::ReleaseResource() with
213 // an invalid resource.
214 void TestAddRefAndReleaseInvalidResource() {
215   for (size_t j = 0; j < 100; ++j) {
216     PPBCore()->AddRefResource(kInvalidResource);
217     PPBCore()->ReleaseResource(kInvalidResource);
218   }
219
220   TEST_PASSED;
221 }
222
223 }  // namespace
224
225 void SetupTests() {
226   RegisterTest("TestGetTime", TestGetTime);
227   RegisterTest("TestGetTimeTicks", TestGetTimeTicks);
228   RegisterTest("TestIsMainThread_FromMainThread",
229                TestIsMainThread_FromMainThread);
230   RegisterTest("TestIsMainThread_FromNonMainThread",
231                TestIsMainThread_FromNonMainThread);
232   RegisterTest("TestAddRefAndReleaseResource",
233                TestAddRefAndReleaseResource);
234   RegisterTest("TestAddRefAndReleaseInvalidResource",
235                TestAddRefAndReleaseInvalidResource);
236   RegisterTest("TestCallOnMainThread_FromMainThread",
237                TestCallOnMainThread_FromMainThread);
238   RegisterTest("TestCallOnMainThread_FromMainThreadDelayed",
239                TestCallOnMainThread_FromMainThreadDelayed);
240   RegisterTest("TestCallOnMainThread_FromNonMainThread",
241                TestCallOnMainThread_FromNonMainThread);
242   RegisterTest("TestCallOnMainThread_FromNonMainThreadStress",
243                TestCallOnMainThread_FromNonMainThreadStress);
244 }
245
246 void SetupPluginInterfaces() {
247   // none
248 }