1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/indexedDB/test/unit/test_writer_starvation.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,104 @@ 1.4 +/** 1.5 + * Any copyright is dedicated to the Public Domain. 1.6 + * http://creativecommons.org/publicdomain/zero/1.0/ 1.7 + */ 1.8 + 1.9 +if (!this.window) { 1.10 + this.runTest = function() { 1.11 + todo(false, "Test disabled in xpcshell test suite for now"); 1.12 + finishTest(); 1.13 + } 1.14 +} 1.15 + 1.16 +var testGenerator = testSteps(); 1.17 + 1.18 +function testSteps() 1.19 +{ 1.20 + const name = this.window ? window.location.pathname : "Splendid Test"; 1.21 + 1.22 + // Needs to be enough to saturate the thread pool. 1.23 + const SYNC_REQUEST_COUNT = 25; 1.24 + 1.25 + let request = indexedDB.open(name, 1); 1.26 + request.onerror = errorHandler; 1.27 + request.onupgradeneeded = grabEventAndContinueHandler; 1.28 + request.onsuccess = grabEventAndContinueHandler; 1.29 + let event = yield undefined; 1.30 + 1.31 + let db = event.target.result; 1.32 + db.onerror = errorHandler; 1.33 + 1.34 + is(event.target.transaction.mode, "versionchange", "Correct mode"); 1.35 + 1.36 + let objectStore = db.createObjectStore("foo", { autoIncrement: true }); 1.37 + 1.38 + request = objectStore.add({}); 1.39 + request.onerror = errorHandler; 1.40 + request.onsuccess = grabEventAndContinueHandler; 1.41 + event = yield undefined; 1.42 + 1.43 + let key = event.target.result; 1.44 + ok(key, "Got a key"); 1.45 + 1.46 + yield undefined; 1.47 + 1.48 + let continueReading = true; 1.49 + let readerCount = 0; 1.50 + let writerCount = 0; 1.51 + let callbackCount = 0; 1.52 + 1.53 + // Generate a bunch of reads right away without returning to the event 1.54 + // loop. 1.55 + info("Generating " + SYNC_REQUEST_COUNT + " readonly requests"); 1.56 + 1.57 + for (let i = 0; i < SYNC_REQUEST_COUNT; i++) { 1.58 + readerCount++; 1.59 + let request = db.transaction("foo").objectStore("foo").get(key); 1.60 + request.onsuccess = function(event) { 1.61 + is(event.target.transaction.mode, "readonly", "Correct mode"); 1.62 + callbackCount++; 1.63 + }; 1.64 + } 1.65 + 1.66 + while (continueReading) { 1.67 + readerCount++; 1.68 + info("Generating additional readonly request (" + readerCount + ")"); 1.69 + let request = db.transaction("foo").objectStore("foo").get(key); 1.70 + request.onsuccess = function(event) { 1.71 + callbackCount++; 1.72 + info("Received readonly request callback (" + callbackCount + ")"); 1.73 + is(event.target.transaction.mode, "readonly", "Correct mode"); 1.74 + if (callbackCount == SYNC_REQUEST_COUNT) { 1.75 + writerCount++; 1.76 + info("Generating 1 readwrite request with " + readerCount + 1.77 + " previous readonly requests"); 1.78 + let request = db.transaction("foo", "readwrite") 1.79 + .objectStore("foo") 1.80 + .add({}, readerCount); 1.81 + request.onsuccess = function(event) { 1.82 + callbackCount++; 1.83 + info("Received readwrite request callback (" + callbackCount + ")"); 1.84 + is(event.target.transaction.mode, "readwrite", "Correct mode"); 1.85 + is(event.target.result, callbackCount, 1.86 + "write callback came before later reads"); 1.87 + } 1.88 + } 1.89 + else if (callbackCount == SYNC_REQUEST_COUNT + 5) { 1.90 + continueReading = false; 1.91 + } 1.92 + }; 1.93 + 1.94 + setTimeout(function() { testGenerator.next(); }, writerCount ? 1000 : 100); 1.95 + yield undefined; 1.96 + } 1.97 + 1.98 + while (callbackCount < (readerCount + writerCount)) { 1.99 + executeSoon(function() { testGenerator.next(); }); 1.100 + yield undefined; 1.101 + } 1.102 + 1.103 + is(callbackCount, readerCount + writerCount, "All requests accounted for"); 1.104 + 1.105 + finishTest(); 1.106 + yield undefined; 1.107 +}