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

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

Issue 2549143009: Create PendingScriptClient as a separate client interface for PendingScript. (Closed)
Patch Set: . Created 4 years 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 "bindings/core/v8/ScriptSourceCode.h" 7 #include "bindings/core/v8/ScriptSourceCode.h"
8 #include "bindings/core/v8/ScriptStreamerThread.h" 8 #include "bindings/core/v8/ScriptStreamerThread.h"
9 #include "bindings/core/v8/V8Binding.h" 9 #include "bindings/core/v8/V8Binding.h"
10 #include "bindings/core/v8/V8BindingForTesting.h" 10 #include "bindings/core/v8/V8BindingForTesting.h"
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 WebTaskRunner* m_loadingTaskRunner; // NOT OWNED 84 WebTaskRunner* m_loadingTaskRunner; // NOT OWNED
85 std::unique_ptr<Settings> m_settings; 85 std::unique_ptr<Settings> m_settings;
86 // The Resource and PendingScript where we stream from. These don't really 86 // The Resource and PendingScript where we stream from. These don't really
87 // fetch any data outside the test; the test controls the data by calling 87 // fetch any data outside the test; the test controls the data by calling
88 // ScriptResource::appendData. 88 // ScriptResource::appendData.
89 ResourceRequest m_resourceRequest; 89 ResourceRequest m_resourceRequest;
90 Persistent<ScriptResource> m_resource; 90 Persistent<ScriptResource> m_resource;
91 Persistent<PendingScript> m_pendingScript; 91 Persistent<PendingScript> m_pendingScript;
92 }; 92 };
93 93
94 class TestScriptResourceClient 94 class TestPendingScriptClient
95 : public GarbageCollectedFinalized<TestScriptResourceClient>, 95 : public GarbageCollectedFinalized<TestPendingScriptClient>,
96 public ScriptResourceClient { 96 public PendingScriptClient {
97 USING_GARBAGE_COLLECTED_MIXIN(TestScriptResourceClient); 97 USING_GARBAGE_COLLECTED_MIXIN(TestPendingScriptClient);
98 98
99 public: 99 public:
100 TestScriptResourceClient() : m_finished(false) {} 100 TestPendingScriptClient() : m_finished(false) {}
101 101 void pendingScriptFinished(PendingScript*) override { m_finished = true; }
102 void notifyFinished(Resource*) override { m_finished = true; }
103 String debugName() const override { return "TestScriptResourceClient"; }
104
105 bool finished() const { return m_finished; } 102 bool finished() const { return m_finished; }
106 103
107 private: 104 private:
108 bool m_finished; 105 bool m_finished;
109 }; 106 };
110 107
111 TEST_F(ScriptStreamingTest, CompilingStreamedScript) { 108 TEST_F(ScriptStreamingTest, CompilingStreamedScript) {
112 // Test that we can successfully compile a streamed script. 109 // Test that we can successfully compile a streamed script.
113 V8TestingScope scope; 110 V8TestingScope scope;
114 ScriptStreamer::startStreaming( 111 ScriptStreamer::startStreaming(
115 getPendingScript(), ScriptStreamer::ParsingBlocking, m_settings.get(), 112 getPendingScript(), ScriptStreamer::ParsingBlocking, m_settings.get(),
116 scope.getScriptState(), m_loadingTaskRunner); 113 scope.getScriptState(), m_loadingTaskRunner);
117 TestScriptResourceClient* client = new TestScriptResourceClient; 114 TestPendingScriptClient* client = new TestPendingScriptClient;
118 getPendingScript()->watchForLoad(client); 115 getPendingScript()->watchForLoad(client);
119 116
120 appendData("function foo() {"); 117 appendData("function foo() {");
121 appendPadding(); 118 appendPadding();
122 appendData("return 5; }"); 119 appendData("return 5; }");
123 appendPadding(); 120 appendPadding();
124 appendData("foo();"); 121 appendData("foo();");
125 EXPECT_FALSE(client->finished()); 122 EXPECT_FALSE(client->finished());
126 finish(); 123 finish();
127 124
(...skipping 14 matching lines...) Expand all
142 } 139 }
143 140
144 TEST_F(ScriptStreamingTest, CompilingStreamedScriptWithParseError) { 141 TEST_F(ScriptStreamingTest, CompilingStreamedScriptWithParseError) {
145 // Test that scripts with parse errors are handled properly. In those cases, 142 // Test that scripts with parse errors are handled properly. In those cases,
146 // the V8 side typically finished before loading finishes: make sure we 143 // the V8 side typically finished before loading finishes: make sure we
147 // handle it gracefully. 144 // handle it gracefully.
148 V8TestingScope scope; 145 V8TestingScope scope;
149 ScriptStreamer::startStreaming( 146 ScriptStreamer::startStreaming(
150 getPendingScript(), ScriptStreamer::ParsingBlocking, m_settings.get(), 147 getPendingScript(), ScriptStreamer::ParsingBlocking, m_settings.get(),
151 scope.getScriptState(), m_loadingTaskRunner); 148 scope.getScriptState(), m_loadingTaskRunner);
152 TestScriptResourceClient* client = new TestScriptResourceClient; 149 TestPendingScriptClient* client = new TestPendingScriptClient;
153 getPendingScript()->watchForLoad(client); 150 getPendingScript()->watchForLoad(client);
154 appendData("function foo() {"); 151 appendData("function foo() {");
155 appendData("this is the part which will be a parse error"); 152 appendData("this is the part which will be a parse error");
156 // V8 won't realize the parse error until it actually starts parsing the 153 // V8 won't realize the parse error until it actually starts parsing the
157 // script, and this happens only when its buffer is filled. 154 // script, and this happens only when its buffer is filled.
158 appendPadding(); 155 appendPadding();
159 156
160 EXPECT_FALSE(client->finished()); 157 EXPECT_FALSE(client->finished());
161 158
162 // Force the V8 side to finish before the loading. 159 // Force the V8 side to finish before the loading.
(...skipping 15 matching lines...) Expand all
178 EXPECT_TRUE(tryCatch.HasCaught()); 175 EXPECT_TRUE(tryCatch.HasCaught());
179 } 176 }
180 177
181 TEST_F(ScriptStreamingTest, CancellingStreaming) { 178 TEST_F(ScriptStreamingTest, CancellingStreaming) {
182 // Test that the upper layers (PendingScript and up) can be ramped down 179 // Test that the upper layers (PendingScript and up) can be ramped down
183 // while streaming is ongoing, and ScriptStreamer handles it gracefully. 180 // while streaming is ongoing, and ScriptStreamer handles it gracefully.
184 V8TestingScope scope; 181 V8TestingScope scope;
185 ScriptStreamer::startStreaming( 182 ScriptStreamer::startStreaming(
186 getPendingScript(), ScriptStreamer::ParsingBlocking, m_settings.get(), 183 getPendingScript(), ScriptStreamer::ParsingBlocking, m_settings.get(),
187 scope.getScriptState(), m_loadingTaskRunner); 184 scope.getScriptState(), m_loadingTaskRunner);
188 TestScriptResourceClient* client = new TestScriptResourceClient; 185 TestPendingScriptClient* client = new TestPendingScriptClient;
189 getPendingScript()->watchForLoad(client); 186 getPendingScript()->watchForLoad(client);
190 appendData("function foo() {"); 187 appendData("function foo() {");
191 188
192 // In general, we cannot control what the background thread is doing 189 // In general, we cannot control what the background thread is doing
193 // (whether it's parsing or waiting for more data). In this test, we have 190 // (whether it's parsing or waiting for more data). In this test, we have
194 // given it so little data that it's surely waiting for more. 191 // given it so little data that it's surely waiting for more.
195 192
196 // Simulate cancelling the network load (e.g., because the user navigated 193 // Simulate cancelling the network load (e.g., because the user navigated
197 // away). 194 // away).
198 EXPECT_FALSE(client->finished()); 195 EXPECT_FALSE(client->finished());
199 getPendingScript()->dispose(); 196 getPendingScript()->dispose();
200 m_pendingScript = nullptr; // This will destroy m_resource. 197 m_pendingScript = nullptr; // This will destroy m_resource.
201 m_resource = nullptr; 198 m_resource = nullptr;
202 199
203 // The V8 side will complete too. This should not crash. We don't receive 200 // The V8 side will complete too. This should not crash. We don't receive
204 // any results from the streaming and the client doesn't get notified. 201 // any results from the streaming and the client doesn't get notified.
205 processTasksUntilStreamingComplete(); 202 processTasksUntilStreamingComplete();
206 EXPECT_FALSE(client->finished()); 203 EXPECT_FALSE(client->finished());
207 } 204 }
208 205
209 TEST_F(ScriptStreamingTest, SuppressingStreaming) { 206 TEST_F(ScriptStreamingTest, SuppressingStreaming) {
210 // If we notice during streaming that there is a code cache, streaming 207 // If we notice during streaming that there is a code cache, streaming
211 // is suppressed (V8 doesn't parse while the script is loading), and the 208 // is suppressed (V8 doesn't parse while the script is loading), and the
212 // upper layer (ScriptResourceClient) should get a notification when the 209 // upper layer (ScriptResourceClient) should get a notification when the
213 // script is loaded. 210 // script is loaded.
214 V8TestingScope scope; 211 V8TestingScope scope;
215 ScriptStreamer::startStreaming( 212 ScriptStreamer::startStreaming(
216 getPendingScript(), ScriptStreamer::ParsingBlocking, m_settings.get(), 213 getPendingScript(), ScriptStreamer::ParsingBlocking, m_settings.get(),
217 scope.getScriptState(), m_loadingTaskRunner); 214 scope.getScriptState(), m_loadingTaskRunner);
218 TestScriptResourceClient* client = new TestScriptResourceClient; 215 TestPendingScriptClient* client = new TestPendingScriptClient;
219 getPendingScript()->watchForLoad(client); 216 getPendingScript()->watchForLoad(client);
220 appendData("function foo() {"); 217 appendData("function foo() {");
221 appendPadding(); 218 appendPadding();
222 219
223 CachedMetadataHandler* cacheHandler = m_resource->cacheHandler(); 220 CachedMetadataHandler* cacheHandler = m_resource->cacheHandler();
224 EXPECT_TRUE(cacheHandler); 221 EXPECT_TRUE(cacheHandler);
225 cacheHandler->setCachedMetadata(V8ScriptRunner::tagForCodeCache(cacheHandler), 222 cacheHandler->setCachedMetadata(V8ScriptRunner::tagForCodeCache(cacheHandler),
226 "X", 1, CachedMetadataHandler::CacheLocally); 223 "X", 1, CachedMetadataHandler::CacheLocally);
227 224
228 appendPadding(); 225 appendPadding();
(...skipping 12 matching lines...) Expand all
241 } 238 }
242 239
243 TEST_F(ScriptStreamingTest, EmptyScripts) { 240 TEST_F(ScriptStreamingTest, EmptyScripts) {
244 // Empty scripts should also be streamed properly, that is, the upper layer 241 // Empty scripts should also be streamed properly, that is, the upper layer
245 // (ScriptResourceClient) should be notified when an empty script has been 242 // (ScriptResourceClient) should be notified when an empty script has been
246 // loaded. 243 // loaded.
247 V8TestingScope scope; 244 V8TestingScope scope;
248 ScriptStreamer::startStreaming( 245 ScriptStreamer::startStreaming(
249 getPendingScript(), ScriptStreamer::ParsingBlocking, m_settings.get(), 246 getPendingScript(), ScriptStreamer::ParsingBlocking, m_settings.get(),
250 scope.getScriptState(), m_loadingTaskRunner); 247 scope.getScriptState(), m_loadingTaskRunner);
251 TestScriptResourceClient* client = new TestScriptResourceClient; 248 TestPendingScriptClient* client = new TestPendingScriptClient;
252 getPendingScript()->watchForLoad(client); 249 getPendingScript()->watchForLoad(client);
253 250
254 // Finish the script without sending any data. 251 // Finish the script without sending any data.
255 finish(); 252 finish();
256 // The finished notification should arrive immediately and not be cycled 253 // The finished notification should arrive immediately and not be cycled
257 // through a background thread. 254 // through a background thread.
258 EXPECT_TRUE(client->finished()); 255 EXPECT_TRUE(client->finished());
259 256
260 bool errorOccurred = false; 257 bool errorOccurred = false;
261 ScriptSourceCode sourceCode = 258 ScriptSourceCode sourceCode =
262 getPendingScript()->getSource(KURL(), errorOccurred); 259 getPendingScript()->getSource(KURL(), errorOccurred);
263 EXPECT_FALSE(errorOccurred); 260 EXPECT_FALSE(errorOccurred);
264 EXPECT_FALSE(sourceCode.streamer()); 261 EXPECT_FALSE(sourceCode.streamer());
265 } 262 }
266 263
267 TEST_F(ScriptStreamingTest, SmallScripts) { 264 TEST_F(ScriptStreamingTest, SmallScripts) {
268 // Small scripts shouldn't be streamed. 265 // Small scripts shouldn't be streamed.
269 V8TestingScope scope; 266 V8TestingScope scope;
270 ScriptStreamer::setSmallScriptThresholdForTesting(100); 267 ScriptStreamer::setSmallScriptThresholdForTesting(100);
271 268
272 ScriptStreamer::startStreaming( 269 ScriptStreamer::startStreaming(
273 getPendingScript(), ScriptStreamer::ParsingBlocking, m_settings.get(), 270 getPendingScript(), ScriptStreamer::ParsingBlocking, m_settings.get(),
274 scope.getScriptState(), m_loadingTaskRunner); 271 scope.getScriptState(), m_loadingTaskRunner);
275 TestScriptResourceClient* client = new TestScriptResourceClient; 272 TestPendingScriptClient* client = new TestPendingScriptClient;
276 getPendingScript()->watchForLoad(client); 273 getPendingScript()->watchForLoad(client);
277 274
278 appendData("function foo() { }"); 275 appendData("function foo() { }");
279 276
280 finish(); 277 finish();
281 278
282 // The finished notification should arrive immediately and not be cycled 279 // The finished notification should arrive immediately and not be cycled
283 // through a background thread. 280 // through a background thread.
284 EXPECT_TRUE(client->finished()); 281 EXPECT_TRUE(client->finished());
285 282
286 bool errorOccurred = false; 283 bool errorOccurred = false;
287 ScriptSourceCode sourceCode = 284 ScriptSourceCode sourceCode =
288 getPendingScript()->getSource(KURL(), errorOccurred); 285 getPendingScript()->getSource(KURL(), errorOccurred);
289 EXPECT_FALSE(errorOccurred); 286 EXPECT_FALSE(errorOccurred);
290 EXPECT_FALSE(sourceCode.streamer()); 287 EXPECT_FALSE(sourceCode.streamer());
291 } 288 }
292 289
293 TEST_F(ScriptStreamingTest, ScriptsWithSmallFirstChunk) { 290 TEST_F(ScriptStreamingTest, ScriptsWithSmallFirstChunk) {
294 // If a script is long enough, if should be streamed, even if the first data 291 // If a script is long enough, if should be streamed, even if the first data
295 // chunk is small. 292 // chunk is small.
296 V8TestingScope scope; 293 V8TestingScope scope;
297 ScriptStreamer::setSmallScriptThresholdForTesting(100); 294 ScriptStreamer::setSmallScriptThresholdForTesting(100);
298 295
299 ScriptStreamer::startStreaming( 296 ScriptStreamer::startStreaming(
300 getPendingScript(), ScriptStreamer::ParsingBlocking, m_settings.get(), 297 getPendingScript(), ScriptStreamer::ParsingBlocking, m_settings.get(),
301 scope.getScriptState(), m_loadingTaskRunner); 298 scope.getScriptState(), m_loadingTaskRunner);
302 TestScriptResourceClient* client = new TestScriptResourceClient; 299 TestPendingScriptClient* client = new TestPendingScriptClient;
303 getPendingScript()->watchForLoad(client); 300 getPendingScript()->watchForLoad(client);
304 301
305 // This is the first data chunk which is small. 302 // This is the first data chunk which is small.
306 appendData("function foo() { }"); 303 appendData("function foo() { }");
307 appendPadding(); 304 appendPadding();
308 appendPadding(); 305 appendPadding();
309 appendPadding(); 306 appendPadding();
310 307
311 finish(); 308 finish();
312 309
(...skipping 13 matching lines...) Expand all
326 323
327 TEST_F(ScriptStreamingTest, EncodingChanges) { 324 TEST_F(ScriptStreamingTest, EncodingChanges) {
328 // It's possible that the encoding of the Resource changes after we start 325 // It's possible that the encoding of the Resource changes after we start
329 // loading it. 326 // loading it.
330 V8TestingScope scope; 327 V8TestingScope scope;
331 m_resource->setEncoding("windows-1252"); 328 m_resource->setEncoding("windows-1252");
332 329
333 ScriptStreamer::startStreaming( 330 ScriptStreamer::startStreaming(
334 getPendingScript(), ScriptStreamer::ParsingBlocking, m_settings.get(), 331 getPendingScript(), ScriptStreamer::ParsingBlocking, m_settings.get(),
335 scope.getScriptState(), m_loadingTaskRunner); 332 scope.getScriptState(), m_loadingTaskRunner);
336 TestScriptResourceClient* client = new TestScriptResourceClient; 333 TestPendingScriptClient* client = new TestPendingScriptClient;
337 getPendingScript()->watchForLoad(client); 334 getPendingScript()->watchForLoad(client);
338 335
339 m_resource->setEncoding("UTF-8"); 336 m_resource->setEncoding("UTF-8");
340 // \xec\x92\x81 are the raw bytes for \uc481. 337 // \xec\x92\x81 are the raw bytes for \uc481.
341 appendData( 338 appendData(
342 "function foo() { var foob\xec\x92\x81r = 13; return foob\xec\x92\x81r; " 339 "function foo() { var foob\xec\x92\x81r = 13; return foob\xec\x92\x81r; "
343 "} foo();"); 340 "} foo();");
344 341
345 finish(); 342 finish();
346 343
(...skipping 14 matching lines...) Expand all
361 TEST_F(ScriptStreamingTest, EncodingFromBOM) { 358 TEST_F(ScriptStreamingTest, EncodingFromBOM) {
362 // Byte order marks should be removed before giving the data to V8. They 359 // Byte order marks should be removed before giving the data to V8. They
363 // will also affect encoding detection. 360 // will also affect encoding detection.
364 V8TestingScope scope; 361 V8TestingScope scope;
365 m_resource->setEncoding( 362 m_resource->setEncoding(
366 "windows-1252"); // This encoding is wrong on purpose. 363 "windows-1252"); // This encoding is wrong on purpose.
367 364
368 ScriptStreamer::startStreaming( 365 ScriptStreamer::startStreaming(
369 getPendingScript(), ScriptStreamer::ParsingBlocking, m_settings.get(), 366 getPendingScript(), ScriptStreamer::ParsingBlocking, m_settings.get(),
370 scope.getScriptState(), m_loadingTaskRunner); 367 scope.getScriptState(), m_loadingTaskRunner);
371 TestScriptResourceClient* client = new TestScriptResourceClient; 368 TestPendingScriptClient* client = new TestPendingScriptClient;
372 getPendingScript()->watchForLoad(client); 369 getPendingScript()->watchForLoad(client);
373 370
374 // \xef\xbb\xbf is the UTF-8 byte order mark. \xec\x92\x81 are the raw bytes 371 // \xef\xbb\xbf is the UTF-8 byte order mark. \xec\x92\x81 are the raw bytes
375 // for \uc481. 372 // for \uc481.
376 appendData( 373 appendData(
377 "\xef\xbb\xbf function foo() { var foob\xec\x92\x81r = 13; return " 374 "\xef\xbb\xbf function foo() { var foob\xec\x92\x81r = 13; return "
378 "foob\xec\x92\x81r; } foo();"); 375 "foob\xec\x92\x81r; } foo();");
379 376
380 finish(); 377 finish();
381 processTasksUntilStreamingComplete(); 378 processTasksUntilStreamingComplete();
382 EXPECT_TRUE(client->finished()); 379 EXPECT_TRUE(client->finished());
383 bool errorOccurred = false; 380 bool errorOccurred = false;
384 ScriptSourceCode sourceCode = 381 ScriptSourceCode sourceCode =
385 getPendingScript()->getSource(KURL(), errorOccurred); 382 getPendingScript()->getSource(KURL(), errorOccurred);
386 EXPECT_FALSE(errorOccurred); 383 EXPECT_FALSE(errorOccurred);
387 EXPECT_TRUE(sourceCode.streamer()); 384 EXPECT_TRUE(sourceCode.streamer());
388 v8::TryCatch tryCatch(scope.isolate()); 385 v8::TryCatch tryCatch(scope.isolate());
389 v8::Local<v8::Script> script; 386 v8::Local<v8::Script> script;
390 EXPECT_TRUE(V8ScriptRunner::compileScript(sourceCode, scope.isolate()) 387 EXPECT_TRUE(V8ScriptRunner::compileScript(sourceCode, scope.isolate())
391 .ToLocal(&script)); 388 .ToLocal(&script));
392 EXPECT_FALSE(tryCatch.HasCaught()); 389 EXPECT_FALSE(tryCatch.HasCaught());
393 } 390 }
394 391
395 } // namespace 392 } // namespace
396 393
397 } // namespace blink 394 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698