Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(141)

Side by Side Diff: third_party/WebKit/Source/bindings/core/v8/ScriptStreamerTest.cpp

Issue 2830533002: Split ScriptStreamer and ScriptStreamerImpl, preparing for unit testing (Closed)
Patch Set: Rebase Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "bindings/core/v8/ScriptStreamer.h" 5 #include "bindings/core/v8/ScriptStreamer.h"
6 6
7 #include <memory> 7 #include <memory>
8 8
9 #include "bindings/core/v8/ScriptSourceCode.h" 9 #include "bindings/core/v8/ScriptSourceCode.h"
10 #include "bindings/core/v8/ScriptStreamerImpl.h"
10 #include "bindings/core/v8/ScriptStreamerThread.h" 11 #include "bindings/core/v8/ScriptStreamerThread.h"
11 #include "bindings/core/v8/V8Binding.h" 12 #include "bindings/core/v8/V8Binding.h"
12 #include "bindings/core/v8/V8BindingForTesting.h" 13 #include "bindings/core/v8/V8BindingForTesting.h"
13 #include "bindings/core/v8/V8ScriptRunner.h" 14 #include "bindings/core/v8/V8ScriptRunner.h"
14 #include "core/dom/ClassicScript.h" 15 #include "core/dom/ClassicScript.h"
15 #include "core/dom/Element.h"
16 #include "core/dom/PendingScript.h" 16 #include "core/dom/PendingScript.h"
17 #include "core/frame/Settings.h" 17 #include "core/frame/Settings.h"
18 #include "platform/heap/Handle.h" 18 #include "platform/heap/Handle.h"
19 #include "platform/testing/UnitTestHelpers.h" 19 #include "platform/testing/UnitTestHelpers.h"
20 #include "public/platform/Platform.h" 20 #include "public/platform/Platform.h"
21 #include "public/platform/WebScheduler.h" 21 #include "public/platform/WebScheduler.h"
22 #include "testing/gtest/include/gtest/gtest.h" 22 #include "testing/gtest/include/gtest/gtest.h"
23 #include "v8/include/v8.h" 23 #include "v8/include/v8.h"
24 24
25 namespace blink { 25 namespace blink {
26 26
27 namespace { 27 namespace {
28 28
29 class ScriptStreamingTest : public ::testing::Test { 29 class ScriptStreamingTest : public ::testing::Test {
30 public: 30 public:
31 ScriptStreamingTest() 31 ScriptStreamingTest()
32 : loading_task_runner_(Platform::Current() 32 : loading_task_runner_(Platform::Current()
33 ->CurrentThread() 33 ->CurrentThread()
34 ->Scheduler() 34 ->Scheduler()
35 ->LoadingTaskRunner()), 35 ->LoadingTaskRunner()),
36 settings_(Settings::Create()), 36 settings_(Settings::Create()),
37 resource_request_("http://www.streaming-test.com/"), 37 resource_request_("http://www.streaming-test.com/"),
38 resource_(ScriptResource::Create(resource_request_, "UTF-8")), 38 resource_(ScriptResource::Create(resource_request_, "UTF-8")),
39 pending_script_(PendingScript::CreateForTesting(resource_.Get())) { 39 pending_script_(PendingScript::CreateForTesting(resource_.Get())) {
40 resource_->SetStatus(ResourceStatus::kPending); 40 resource_->SetStatus(ResourceStatus::kPending);
41 pending_script_ = PendingScript::CreateForTesting(resource_.Get()); 41 pending_script_ = PendingScript::CreateForTesting(resource_.Get());
42 ScriptStreamer::SetSmallScriptThresholdForTesting(0); 42 ScriptStreamerImpl::SetSmallScriptThresholdForTesting(0);
43 } 43 }
44 44
45 ~ScriptStreamingTest() { 45 ~ScriptStreamingTest() {
46 if (pending_script_) 46 if (pending_script_)
47 pending_script_->Dispose(); 47 pending_script_->Dispose();
48 } 48 }
49 49
50 PendingScript* GetPendingScript() const { return pending_script_.Get(); } 50 PendingScript* GetPendingScript() const { return pending_script_.Get(); }
51 51
52 protected: 52 protected:
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 void PendingScriptFinished(PendingScript*) override { finished_ = true; } 103 void PendingScriptFinished(PendingScript*) override { finished_ = true; }
104 bool Finished() const { return finished_; } 104 bool Finished() const { return finished_; }
105 105
106 private: 106 private:
107 bool finished_; 107 bool finished_;
108 }; 108 };
109 109
110 TEST_F(ScriptStreamingTest, CompilingStreamedScript) { 110 TEST_F(ScriptStreamingTest, CompilingStreamedScript) {
111 // Test that we can successfully compile a streamed script. 111 // Test that we can successfully compile a streamed script.
112 V8TestingScope scope; 112 V8TestingScope scope;
113 ScriptStreamer::StartStreaming( 113 ScriptStreamerImpl::StartStreaming(
114 GetPendingScript(), ScriptStreamer::kParsingBlocking, settings_.get(), 114 GetPendingScript(), ScriptStreamer::kParsingBlocking, settings_.get(),
115 scope.GetScriptState(), loading_task_runner_); 115 scope.GetScriptState(), loading_task_runner_);
116 TestPendingScriptClient* client = new TestPendingScriptClient; 116 TestPendingScriptClient* client = new TestPendingScriptClient;
117 GetPendingScript()->WatchForLoad(client); 117 GetPendingScript()->WatchForLoad(client);
118 118
119 AppendData("function foo() {"); 119 AppendData("function foo() {");
120 AppendPadding(); 120 AppendPadding();
121 AppendData("return 5; }"); 121 AppendData("return 5; }");
122 AppendPadding(); 122 AppendPadding();
123 AppendData("foo();"); 123 AppendData("foo();");
(...skipping 17 matching lines...) Expand all
141 kV8CacheOptionsDefault) 141 kV8CacheOptionsDefault)
142 .ToLocal(&script)); 142 .ToLocal(&script));
143 EXPECT_FALSE(try_catch.HasCaught()); 143 EXPECT_FALSE(try_catch.HasCaught());
144 } 144 }
145 145
146 TEST_F(ScriptStreamingTest, CompilingStreamedScriptWithParseError) { 146 TEST_F(ScriptStreamingTest, CompilingStreamedScriptWithParseError) {
147 // Test that scripts with parse errors are handled properly. In those cases, 147 // Test that scripts with parse errors are handled properly. In those cases,
148 // the V8 side typically finished before loading finishes: make sure we 148 // the V8 side typically finished before loading finishes: make sure we
149 // handle it gracefully. 149 // handle it gracefully.
150 V8TestingScope scope; 150 V8TestingScope scope;
151 ScriptStreamer::StartStreaming( 151 ScriptStreamerImpl::StartStreaming(
152 GetPendingScript(), ScriptStreamer::kParsingBlocking, settings_.get(), 152 GetPendingScript(), ScriptStreamer::kParsingBlocking, settings_.get(),
153 scope.GetScriptState(), loading_task_runner_); 153 scope.GetScriptState(), loading_task_runner_);
154 TestPendingScriptClient* client = new TestPendingScriptClient; 154 TestPendingScriptClient* client = new TestPendingScriptClient;
155 GetPendingScript()->WatchForLoad(client); 155 GetPendingScript()->WatchForLoad(client);
156 AppendData("function foo() {"); 156 AppendData("function foo() {");
157 AppendData("this is the part which will be a parse error"); 157 AppendData("this is the part which will be a parse error");
158 // V8 won't realize the parse error until it actually starts parsing the 158 // V8 won't realize the parse error until it actually starts parsing the
159 // script, and this happens only when its buffer is filled. 159 // script, and this happens only when its buffer is filled.
160 AppendPadding(); 160 AppendPadding();
161 161
(...skipping 18 matching lines...) Expand all
180 kSharableCrossOrigin, 180 kSharableCrossOrigin,
181 kV8CacheOptionsDefault) 181 kV8CacheOptionsDefault)
182 .ToLocal(&script)); 182 .ToLocal(&script));
183 EXPECT_TRUE(try_catch.HasCaught()); 183 EXPECT_TRUE(try_catch.HasCaught());
184 } 184 }
185 185
186 TEST_F(ScriptStreamingTest, CancellingStreaming) { 186 TEST_F(ScriptStreamingTest, CancellingStreaming) {
187 // Test that the upper layers (PendingScript and up) can be ramped down 187 // Test that the upper layers (PendingScript and up) can be ramped down
188 // while streaming is ongoing, and ScriptStreamer handles it gracefully. 188 // while streaming is ongoing, and ScriptStreamer handles it gracefully.
189 V8TestingScope scope; 189 V8TestingScope scope;
190 ScriptStreamer::StartStreaming( 190 ScriptStreamerImpl::StartStreaming(
191 GetPendingScript(), ScriptStreamer::kParsingBlocking, settings_.get(), 191 GetPendingScript(), ScriptStreamer::kParsingBlocking, settings_.get(),
192 scope.GetScriptState(), loading_task_runner_); 192 scope.GetScriptState(), loading_task_runner_);
193 TestPendingScriptClient* client = new TestPendingScriptClient; 193 TestPendingScriptClient* client = new TestPendingScriptClient;
194 GetPendingScript()->WatchForLoad(client); 194 GetPendingScript()->WatchForLoad(client);
195 AppendData("function foo() {"); 195 AppendData("function foo() {");
196 196
197 // In general, we cannot control what the background thread is doing 197 // In general, we cannot control what the background thread is doing
198 // (whether it's parsing or waiting for more data). In this test, we have 198 // (whether it's parsing or waiting for more data). In this test, we have
199 // given it so little data that it's surely waiting for more. 199 // given it so little data that it's surely waiting for more.
200 200
201 // Simulate cancelling the network load (e.g., because the user navigated 201 // Simulate cancelling the network load (e.g., because the user navigated
202 // away). 202 // away).
203 EXPECT_FALSE(client->Finished()); 203 EXPECT_FALSE(client->Finished());
204 GetPendingScript()->Dispose(); 204 GetPendingScript()->Dispose();
205 pending_script_ = nullptr; // This will destroy m_resource. 205 pending_script_ = nullptr; // This will destroy m_resource.
206 resource_ = nullptr; 206 resource_ = nullptr;
207 207
208 // The V8 side will complete too. This should not crash. We don't receive 208 // The V8 side will complete too. This should not crash. We don't receive
209 // any results from the streaming and the client doesn't get notified. 209 // any results from the streaming and the client doesn't get notified.
210 ProcessTasksUntilStreamingComplete(); 210 ProcessTasksUntilStreamingComplete();
211 EXPECT_FALSE(client->Finished()); 211 EXPECT_FALSE(client->Finished());
212 } 212 }
213 213
214 TEST_F(ScriptStreamingTest, SuppressingStreaming) { 214 TEST_F(ScriptStreamingTest, SuppressingStreaming) {
215 // If we notice during streaming that there is a code cache, streaming 215 // If we notice during streaming that there is a code cache, streaming
216 // is suppressed (V8 doesn't parse while the script is loading), and the 216 // is suppressed (V8 doesn't parse while the script is loading), and the
217 // upper layer (ScriptResourceClient) should get a notification when the 217 // upper layer (ScriptResourceClient) should get a notification when the
218 // script is loaded. 218 // script is loaded.
219 V8TestingScope scope; 219 V8TestingScope scope;
220 ScriptStreamer::StartStreaming( 220 ScriptStreamerImpl::StartStreaming(
221 GetPendingScript(), ScriptStreamer::kParsingBlocking, settings_.get(), 221 GetPendingScript(), ScriptStreamer::kParsingBlocking, settings_.get(),
222 scope.GetScriptState(), loading_task_runner_); 222 scope.GetScriptState(), loading_task_runner_);
223 TestPendingScriptClient* client = new TestPendingScriptClient; 223 TestPendingScriptClient* client = new TestPendingScriptClient;
224 GetPendingScript()->WatchForLoad(client); 224 GetPendingScript()->WatchForLoad(client);
225 AppendData("function foo() {"); 225 AppendData("function foo() {");
226 AppendPadding(); 226 AppendPadding();
227 227
228 CachedMetadataHandler* cache_handler = resource_->CacheHandler(); 228 CachedMetadataHandler* cache_handler = resource_->CacheHandler();
229 EXPECT_TRUE(cache_handler); 229 EXPECT_TRUE(cache_handler);
230 cache_handler->SetCachedMetadata( 230 cache_handler->SetCachedMetadata(
(...skipping 14 matching lines...) Expand all
245 // the streaming and resumed the non-streaming code path for script 245 // the streaming and resumed the non-streaming code path for script
246 // compilation. 246 // compilation.
247 EXPECT_FALSE(source_code.Streamer()); 247 EXPECT_FALSE(source_code.Streamer());
248 } 248 }
249 249
250 TEST_F(ScriptStreamingTest, EmptyScripts) { 250 TEST_F(ScriptStreamingTest, EmptyScripts) {
251 // Empty scripts should also be streamed properly, that is, the upper layer 251 // Empty scripts should also be streamed properly, that is, the upper layer
252 // (ScriptResourceClient) should be notified when an empty script has been 252 // (ScriptResourceClient) should be notified when an empty script has been
253 // loaded. 253 // loaded.
254 V8TestingScope scope; 254 V8TestingScope scope;
255 ScriptStreamer::StartStreaming( 255 ScriptStreamerImpl::StartStreaming(
256 GetPendingScript(), ScriptStreamer::kParsingBlocking, settings_.get(), 256 GetPendingScript(), ScriptStreamer::kParsingBlocking, settings_.get(),
257 scope.GetScriptState(), loading_task_runner_); 257 scope.GetScriptState(), loading_task_runner_);
258 TestPendingScriptClient* client = new TestPendingScriptClient; 258 TestPendingScriptClient* client = new TestPendingScriptClient;
259 GetPendingScript()->WatchForLoad(client); 259 GetPendingScript()->WatchForLoad(client);
260 260
261 // Finish the script without sending any data. 261 // Finish the script without sending any data.
262 Finish(); 262 Finish();
263 // The finished notification should arrive immediately and not be cycled 263 // The finished notification should arrive immediately and not be cycled
264 // through a background thread. 264 // through a background thread.
265 EXPECT_TRUE(client->Finished()); 265 EXPECT_TRUE(client->Finished());
266 266
267 bool error_occurred = false; 267 bool error_occurred = false;
268 ScriptSourceCode source_code = GetPendingScript() 268 ScriptSourceCode source_code = GetPendingScript()
269 ->GetSource(KURL(), error_occurred) 269 ->GetSource(KURL(), error_occurred)
270 ->GetScriptSourceCode(); 270 ->GetScriptSourceCode();
271 EXPECT_FALSE(error_occurred); 271 EXPECT_FALSE(error_occurred);
272 EXPECT_FALSE(source_code.Streamer()); 272 EXPECT_FALSE(source_code.Streamer());
273 } 273 }
274 274
275 TEST_F(ScriptStreamingTest, SmallScripts) { 275 TEST_F(ScriptStreamingTest, SmallScripts) {
276 // Small scripts shouldn't be streamed. 276 // Small scripts shouldn't be streamed.
277 V8TestingScope scope; 277 V8TestingScope scope;
278 ScriptStreamer::SetSmallScriptThresholdForTesting(100); 278 ScriptStreamerImpl::SetSmallScriptThresholdForTesting(100);
279 279
280 ScriptStreamer::StartStreaming( 280 ScriptStreamerImpl::StartStreaming(
281 GetPendingScript(), ScriptStreamer::kParsingBlocking, settings_.get(), 281 GetPendingScript(), ScriptStreamer::kParsingBlocking, settings_.get(),
282 scope.GetScriptState(), loading_task_runner_); 282 scope.GetScriptState(), loading_task_runner_);
283 TestPendingScriptClient* client = new TestPendingScriptClient; 283 TestPendingScriptClient* client = new TestPendingScriptClient;
284 GetPendingScript()->WatchForLoad(client); 284 GetPendingScript()->WatchForLoad(client);
285 285
286 AppendData("function foo() { }"); 286 AppendData("function foo() { }");
287 287
288 Finish(); 288 Finish();
289 289
290 // The finished notification should arrive immediately and not be cycled 290 // The finished notification should arrive immediately and not be cycled
291 // through a background thread. 291 // through a background thread.
292 EXPECT_TRUE(client->Finished()); 292 EXPECT_TRUE(client->Finished());
293 293
294 bool error_occurred = false; 294 bool error_occurred = false;
295 ScriptSourceCode source_code = GetPendingScript() 295 ScriptSourceCode source_code = GetPendingScript()
296 ->GetSource(KURL(), error_occurred) 296 ->GetSource(KURL(), error_occurred)
297 ->GetScriptSourceCode(); 297 ->GetScriptSourceCode();
298 EXPECT_FALSE(error_occurred); 298 EXPECT_FALSE(error_occurred);
299 EXPECT_FALSE(source_code.Streamer()); 299 EXPECT_FALSE(source_code.Streamer());
300 } 300 }
301 301
302 TEST_F(ScriptStreamingTest, ScriptsWithSmallFirstChunk) { 302 TEST_F(ScriptStreamingTest, ScriptsWithSmallFirstChunk) {
303 // If a script is long enough, if should be streamed, even if the first data 303 // If a script is long enough, if should be streamed, even if the first data
304 // chunk is small. 304 // chunk is small.
305 V8TestingScope scope; 305 V8TestingScope scope;
306 ScriptStreamer::SetSmallScriptThresholdForTesting(100); 306 ScriptStreamerImpl::SetSmallScriptThresholdForTesting(100);
307 307
308 ScriptStreamer::StartStreaming( 308 ScriptStreamerImpl::StartStreaming(
309 GetPendingScript(), ScriptStreamer::kParsingBlocking, settings_.get(), 309 GetPendingScript(), ScriptStreamer::kParsingBlocking, settings_.get(),
310 scope.GetScriptState(), loading_task_runner_); 310 scope.GetScriptState(), loading_task_runner_);
311 TestPendingScriptClient* client = new TestPendingScriptClient; 311 TestPendingScriptClient* client = new TestPendingScriptClient;
312 GetPendingScript()->WatchForLoad(client); 312 GetPendingScript()->WatchForLoad(client);
313 313
314 // This is the first data chunk which is small. 314 // This is the first data chunk which is small.
315 AppendData("function foo() { }"); 315 AppendData("function foo() { }");
316 AppendPadding(); 316 AppendPadding();
317 AppendPadding(); 317 AppendPadding();
318 AppendPadding(); 318 AppendPadding();
(...skipping 16 matching lines...) Expand all
335 .ToLocal(&script)); 335 .ToLocal(&script));
336 EXPECT_FALSE(try_catch.HasCaught()); 336 EXPECT_FALSE(try_catch.HasCaught());
337 } 337 }
338 338
339 TEST_F(ScriptStreamingTest, EncodingChanges) { 339 TEST_F(ScriptStreamingTest, EncodingChanges) {
340 // It's possible that the encoding of the Resource changes after we start 340 // It's possible that the encoding of the Resource changes after we start
341 // loading it. 341 // loading it.
342 V8TestingScope scope; 342 V8TestingScope scope;
343 resource_->SetEncoding("windows-1252"); 343 resource_->SetEncoding("windows-1252");
344 344
345 ScriptStreamer::StartStreaming( 345 ScriptStreamerImpl::StartStreaming(
346 GetPendingScript(), ScriptStreamer::kParsingBlocking, settings_.get(), 346 GetPendingScript(), ScriptStreamer::kParsingBlocking, settings_.get(),
347 scope.GetScriptState(), loading_task_runner_); 347 scope.GetScriptState(), loading_task_runner_);
348 TestPendingScriptClient* client = new TestPendingScriptClient; 348 TestPendingScriptClient* client = new TestPendingScriptClient;
349 GetPendingScript()->WatchForLoad(client); 349 GetPendingScript()->WatchForLoad(client);
350 350
351 resource_->SetEncoding("UTF-8"); 351 resource_->SetEncoding("UTF-8");
352 // \xec\x92\x81 are the raw bytes for \uc481. 352 // \xec\x92\x81 are the raw bytes for \uc481.
353 AppendData( 353 AppendData(
354 "function foo() { var foob\xec\x92\x81r = 13; return foob\xec\x92\x81r; " 354 "function foo() { var foob\xec\x92\x81r = 13; return foob\xec\x92\x81r; "
355 "} foo();"); 355 "} foo();");
(...skipping 16 matching lines...) Expand all
372 .ToLocal(&script)); 372 .ToLocal(&script));
373 EXPECT_FALSE(try_catch.HasCaught()); 373 EXPECT_FALSE(try_catch.HasCaught());
374 } 374 }
375 375
376 TEST_F(ScriptStreamingTest, EncodingFromBOM) { 376 TEST_F(ScriptStreamingTest, EncodingFromBOM) {
377 // Byte order marks should be removed before giving the data to V8. They 377 // Byte order marks should be removed before giving the data to V8. They
378 // will also affect encoding detection. 378 // will also affect encoding detection.
379 V8TestingScope scope; 379 V8TestingScope scope;
380 resource_->SetEncoding("windows-1252"); // This encoding is wrong on purpose. 380 resource_->SetEncoding("windows-1252"); // This encoding is wrong on purpose.
381 381
382 ScriptStreamer::StartStreaming( 382 ScriptStreamerImpl::StartStreaming(
383 GetPendingScript(), ScriptStreamer::kParsingBlocking, settings_.get(), 383 GetPendingScript(), ScriptStreamer::kParsingBlocking, settings_.get(),
384 scope.GetScriptState(), loading_task_runner_); 384 scope.GetScriptState(), loading_task_runner_);
385 TestPendingScriptClient* client = new TestPendingScriptClient; 385 TestPendingScriptClient* client = new TestPendingScriptClient;
386 GetPendingScript()->WatchForLoad(client); 386 GetPendingScript()->WatchForLoad(client);
387 387
388 // \xef\xbb\xbf is the UTF-8 byte order mark. \xec\x92\x81 are the raw bytes 388 // \xef\xbb\xbf is the UTF-8 byte order mark. \xec\x92\x81 are the raw bytes
389 // for \uc481. 389 // for \uc481.
390 AppendData( 390 AppendData(
391 "\xef\xbb\xbf function foo() { var foob\xec\x92\x81r = 13; return " 391 "\xef\xbb\xbf function foo() { var foob\xec\x92\x81r = 13; return "
392 "foob\xec\x92\x81r; } foo();"); 392 "foob\xec\x92\x81r; } foo();");
(...skipping 12 matching lines...) Expand all
405 EXPECT_TRUE(V8ScriptRunner::CompileScript(source_code, scope.GetIsolate(), 405 EXPECT_TRUE(V8ScriptRunner::CompileScript(source_code, scope.GetIsolate(),
406 kSharableCrossOrigin, 406 kSharableCrossOrigin,
407 kV8CacheOptionsDefault) 407 kV8CacheOptionsDefault)
408 .ToLocal(&script)); 408 .ToLocal(&script));
409 EXPECT_FALSE(try_catch.HasCaught()); 409 EXPECT_FALSE(try_catch.HasCaught());
410 } 410 }
411 411
412 } // namespace 412 } // namespace
413 413
414 } // namespace blink 414 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698