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

Side by Side Diff: third_party/WebKit/LayoutTests/external/wpt/IndexedDB/request-event-ordering.html

Issue 2822453003: Wrap large IndexedDB values into Blobs before writing to LevelDB. (Closed)
Patch Set: Fixed compilation errors on Windows and no-DCHECKs. Created 3 years, 7 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
(Empty)
1 <!doctype html>
2 <meta charset="utf8">
3 <title>IndexedDB: request result events are delivered in order</title>
4 <link rel="help" href="https://w3c.github.io/IndexedDB/#abort-transaction">
5 <link rel="author" href="pwnall@chromium.org" title="Victor Costan">
6 <script src="/resources/testharness.js"></script>
7 <script src="/resources/testharnessreport.js"></script>
8 <script src="support-promises.js"></script>
9 <script>
10 'use strict';
11
12 // Should be large enough to trigger value wrapping in the IndexedDB engines
13 // that implement wrapping.
14 const wrapThreshold = 128 * 1024;
15
16 // Returns an Uint8Array with pseudorandom data.
17 function largeValue(size, seed) {
18 const buffer = new Uint8Array(size);
19
20 // 32-bit xorshift - the seed can't be zero
21 let state = 1000 + seed;
22
23 for (let i = 0; i < size; ++i) {
24 state ^= state << 13;
25 state ^= state >> 17;
26 state ^= state << 5;
27 buffer[i] = state & 0xff;
28 }
29
30 return buffer;
31 }
32
33 function populateStore(store) {
34 store.put({id: 1, key: 'k1', value: largeValue(wrapThreshold, 1) });
35 store.put({id: 2, key: 'k2', value: ['small-2'] });
36 store.put({id: 3, key: 'k3', value: largeValue(wrapThreshold, 3) });
37 store.put({id: 4, key: 'k4', value: ['small-4'] });
38 }
39
40 function doOperation(
41 testCase, store, index, cursor, operation, requestId, results) {
42 const opcode = operation[0];
43 const primaryKey = operation[1];
44
45 return new Promise((resolve, reject) => {
46 let request;
47 switch (opcode) {
48 case 'put': // Tests returning a primary key.
49 request = store.put(
50 { key: `k${primaryKey}`, value: [`small-${primaryKey}`] });
51 break;
52 case 'get': // Tests returning a value.
53 request = store.get(primaryKey);
54 break;
55 case 'error': // Tests returning an error.
56 request = store.put(
57 { key: `k${primaryKey}`, value: [`small-${primaryKey}`] });
58 request.onerror = testCase.step_func(event => {
59 results.push([requestId, request.error]);
60 resolve();
61 event.preventDefault();
62 });
63 request.onsuccess = testCase.step_func(() => {
64 reject(new Error('put with duplicate primary key succeded'));
65 });
66 break;
67 case 'continue': // Tests returning a key, primary key, and value.
68 request = cursor;
69 cursor.result.continue(`k${primaryKey}`);
70 request.onsuccess = testCase.step_func(() => {
71 const result = request.result;
72 results.push(
73 [requestId, result.key, result.primaryKey, result.value]);
74 resolve();
75 });
76 request.onerror = null;
77 break;
78 case 'open': // Tests returning a cursor, key, primary key, and value.
79 request = index.openCursor(IDBKeyRange.lowerBound(`k${primaryKey}`));
80 request.onsuccess = testCase.step_func(() => {
81 const result = request.result;
82 results.push(
83 [requestId, result.key, result.primaryKey, result.value]);
84 resolve();
85 });
86 break;
87 };
88
89 if (!request.onsuccess) {
90 request.onsuccess = testCase.step_func(() => {
91 results.push([requestId, request.result]);
92 resolve();
93 });
94 }
95 if (!request.onerror)
96 request.onerror = testCase.step_func(event => {
97 reject(request.error);
98 event.preventDefault();
99 });
100 });
101 }
102
103 function checkOperationResult(operation, result, requestId) {
104 const opcode = operation[0];
105 const primaryKey = operation[1];
106
107 const expectedValue = (primaryKey == 1 || primaryKey == 3) ?
108 largeValue(wrapThreshold, primaryKey) : [`small-${primaryKey}`];
109
110 const requestIndex = result[0];
111 assert_equals(
112 requestIndex, requestId, 'result event order should match request order');
113 switch (opcode) {
114 case 'put':
115 assert_equals(
116 result[1], primaryKey,
117 "put result should be the new object's primary key");
118 break;
119 case 'get':
120 assert_equals(
121 result[1].id, primaryKey,
122 'get result should match put value (primary key)');
123 assert_equals(
124 result[1].key, `k${primaryKey}`,
125 'get result should match put value (key)');
126 assert_equals(
127 result[1].value.join(','), expectedValue.join(','),
128 'get result should match put value (nested value)');
129 break;
130 case 'error':
131 assert_equals(
132 result[1].name, 'ConstraintError',
133 'incorrect error from put with duplicate primary key');
134 break;
135 case 'continue':
136 case 'open':
137 assert_equals(
138 result[1], `k${primaryKey}`,
139 `${opcode} key should match the key in the put value`);
140 assert_equals(
141 result[2], primaryKey,
142 `${opcode} primary key should the primary key in the put value`);
143 assert_equals(
144 result[3].id, primaryKey,
145 `${opcode} value should match put value (primary key)`);
146 assert_equals(
147 result[3].key, `k${primaryKey}`,
148 `${opcode} value should match put value (key)`);
149 assert_equals(
150 result[3].value.join(','), expectedValue.join(','),
151 `${opcode} value should match put value (nested value)`);
152 break;
153
154 }
155 }
156
157 function eventsTest(label, operations) {
158 promise_test(testCase => {
159 return createDatabase(testCase, (database, transaction) => {
160 const store = database.createObjectStore(
161 'test-store', { autoIncrement: true, keyPath: 'id' });
162 store.createIndex('test-index', 'key', { unique: true });
163 populateStore(store);
164 }).then(database => {
165 const transaction = database.transaction(['test-store'], 'readwrite');
166 const store = transaction.objectStore('test-store');
167 const index = store.index('test-index');
168 const cursor = index.openCursor();
169 return new Promise((resolve, reject) => {
170 const results = [];
171 const promises = [];
172 cursor.onsuccess = testCase.step_func(() => {
173 for (let i = 0; i < operations.length; ++i) {
174 const promise = doOperation(
175 testCase, store, index, cursor, operations[i], i, results);
176 promises.push(promise);
177 };
178 resolve(Promise.all(promises).then(() => results));
179 });
180 cursor.onerror = () => { reject(cursor.error); };
181 });
182 }).then(results => {
183 assert_equals(
184 results.length, operations.length,
185 'Promise.all should resolve after all sub-promises resolve');
186 for (let i = 0; i < operations.length; ++i)
187 checkOperationResult(operations[i], results[i], i);
188 });
189 }, label);
190 }
191
192 eventsTest('small values', [
193 ['get', 2],
194 ['put', 5],
195 ['open', 2],
196 ['get', 4],
197 ['put', 6],
198 ['error', 3],
199 ['continue', 2],
200 ['open', 4],
201 ]);
202
203 eventsTest('large values', [
204 ['open', 1],
205 ['get', 1],
206 ['get', 3],
207 ['continue', 3],
208 ['open', 3],
209 ]);
210
211 eventsTest('large value followed by small values', [
212 ['get', 1],
213 ['open', 2],
214 ['get', 2],
215 ['put', 5],
216 ['error', 1],
217 ['continue', 2],
218 ]);
219
220 eventsTest('large values mixed with small values', [
221 ['get', 1],
222 ['get', 2],
223 ['open', 1],
224 ['open', 2],
225 ['put', 5],
226 ['get', 3],
227 ['put', 6],
228 ['error', 1],
229 ['continue', 2],
230 ['open', 4],
231 ['error', 3],
232 ]);
233
234 </script>
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698