test_quotaExceeded_recovery.js (3653B)
1 /** 2 * Any copyright is dedicated to the Public Domain. 3 * http://creativecommons.org/publicdomain/zero/1.0/ 4 */ 5 6 /* exported testGenerator, disableWorkerTest */ 7 var disableWorkerTest = "Need a way to set temporary prefs from a worker"; 8 9 var testGenerator = testSteps(); 10 11 function* testSteps() { 12 const spec = "http://foo.com"; 13 const name = this.window 14 ? window.location.pathname 15 : "test_quotaExceeded_recovery"; 16 const objectStoreName = "foo"; 17 18 const android = mozinfo.os == "android"; 19 20 // We want 512 KB database on Android and 4 MB database on other platforms. 21 const groupLimitKB = android ? 512 : 4096; 22 23 // The group limit is calculated as 20% of the global temporary storage limit. 24 const tempStorageLimitKB = groupLimitKB * 5; 25 26 // We want 64 KB chunks on Android and 512 KB chunks on other platforms. 27 const dataSizeKB = android ? 64 : 512; 28 const dataSize = dataSizeKB * 1024; 29 30 const maxIter = 5; 31 32 for (let blobs of [false, true]) { 33 setTemporaryStorageLimit(tempStorageLimitKB); 34 35 clearAllDatabases(continueToNextStepSync); 36 yield undefined; 37 38 info("Opening database"); 39 40 let request = indexedDB.openForPrincipal(getPrincipal(spec), name); 41 request.onerror = errorHandler; 42 request.onupgradeneeded = grabEventAndContinueHandler; 43 request.onsuccess = unexpectedSuccessHandler; 44 45 yield undefined; 46 47 // upgradeneeded 48 request.onupgradeneeded = unexpectedSuccessHandler; 49 request.onsuccess = grabEventAndContinueHandler; 50 51 info("Creating objectStore"); 52 53 request.result.createObjectStore(objectStoreName, { autoIncrement: true }); 54 55 yield undefined; 56 57 // success 58 let db = request.result; 59 db.onerror = errorHandler; 60 61 ok(true, "Filling database"); 62 63 let obj = { 64 name: "foo", 65 }; 66 67 if (!blobs) { 68 obj.data = getRandomView(dataSize); 69 } 70 71 let iter = 1; 72 let i = 1; 73 let j = 1; 74 while (true) { 75 if (blobs) { 76 obj.data = getBlob(getView(dataSize)); 77 } 78 79 let trans = db.transaction(objectStoreName, "readwrite"); 80 request = trans.objectStore(objectStoreName).add(obj); 81 request.onerror = function (event) { 82 event.stopPropagation(); 83 }; 84 85 trans.oncomplete = function () { 86 if (iter == 1) { 87 i++; 88 } 89 j++; 90 testGenerator.next(true); 91 }; 92 trans.onabort = function () { 93 is(trans.error.name, "QuotaExceededError", "Reached quota limit"); 94 testGenerator.next(false); 95 }; 96 97 let completeFired = yield undefined; 98 if (completeFired) { 99 ok(true, "Got complete event"); 100 continue; 101 } 102 103 ok(true, "Got abort event"); 104 105 if (iter++ == maxIter) { 106 break; 107 } 108 109 if (iter > 1) { 110 ok(i == j, "Recycled entire database"); 111 j = 1; 112 } 113 114 trans = db.transaction(objectStoreName, "readwrite"); 115 116 // Don't use a cursor for deleting stored blobs (Cursors prolong live 117 // of stored files since each record must be fetched from the database 118 // first which creates a memory reference to the stored blob.) 119 if (blobs) { 120 request = trans.objectStore(objectStoreName).clear(); 121 } else { 122 request = trans.objectStore(objectStoreName).openCursor(); 123 request.onsuccess = function (event) { 124 let cursor = event.target.result; 125 if (cursor) { 126 cursor.delete(); 127 cursor.continue(); 128 } 129 }; 130 } 131 132 trans.onabort = unexpectedSuccessHandler; 133 trans.oncomplete = grabEventAndContinueHandler; 134 135 yield undefined; 136 } 137 } 138 139 finishTest(); 140 yield undefined; 141 }