Bug 1446178 [wpt PR 10018] - ReadableStream: Readable byte stream must call pull if needed after receiving new chunk, a=testonly
authorMattias Buelens <mattias@buelens.com>
Mon, 09 Apr 2018 17:25:09 +0000
changeset 467125 8e8f01fceede8303971ee587d79e87c3942382e9
parent 467124 ef900452e4c1c5f6b39c8679c716155a88295745
child 467126 837e711f0c2dd1087b3346e6462afe81d0a38597
push id9165
push userasasaki@mozilla.com
push dateThu, 26 Apr 2018 21:04:54 +0000
treeherdermozilla-beta@064c3804de2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstestonly
bugs1446178, 10018
milestone61.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1446178 [wpt PR 10018] - ReadableStream: Readable byte stream must call pull if needed after receiving new chunk, a=testonly Automatic update from web-platform-testsReadableStream: Readable byte stream must call pull if needed after receiving new chunk (#10018) * Fix test that allows too much pulling * Test that byte stream pulls after enqueue wpt-commits: 6e1b5f44943705380487dc73b96b4c959487ee4d wpt-pr: 10018 wpt-commits: 6e1b5f44943705380487dc73b96b4c959487ee4d wpt-pr: 10018
testing/web-platform/meta/MANIFEST.json
testing/web-platform/tests/streams/readable-byte-streams/general.js
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -595496,17 +595496,17 @@
    "8583d80450b090c16ed0795170340d040449bbc1",
    "testharness"
   ],
   "streams/readable-byte-streams/general.html": [
    "d459dc11abad3162f0c412f1346820541df38d53",
    "testharness"
   ],
   "streams/readable-byte-streams/general.js": [
-   "a7262a490c4a913811c8d0c489b06a567a448fc6",
+   "ce3c72f3a552a6b9a42b4f37be7e6a053cad10a1",
    "support"
   ],
   "streams/readable-byte-streams/general.serviceworker.https.html": [
    "1792d6c45a5687777291a4dab031a954aa053752",
    "testharness"
   ],
   "streams/readable-byte-streams/general.sharedworker.html": [
    "44f9ceaa3bfc9d8b92885997d322486bd0f237a6",
--- a/testing/web-platform/tests/streams/readable-byte-streams/general.js
+++ b/testing/web-platform/tests/streams/readable-byte-streams/general.js
@@ -295,64 +295,94 @@ function extractViewInfo(view) {
     byteOffset: view.byteOffset,
     byteLength: view.byteLength
   };
 }
 
 promise_test(() => {
   let pullCount = 0;
   let controller;
-  let byobRequest;
-  let viewDefined = false;
-  let viewInfo;
+  const byobRequests = [];
 
   const stream = new ReadableStream({
     start(c) {
       controller = c;
     },
     pull() {
-      byobRequest = controller.byobRequest;
+      const byobRequest = controller.byobRequest;
       const view = byobRequest.view;
-      viewDefined = view !== undefined;
-      viewInfo = extractViewInfo(view);
-
-      view[0] = 0x01;
-      byobRequest.respond(1);
+      byobRequests[pullCount] = {
+        defined: byobRequest !== undefined,
+        viewDefined: view !== undefined,
+        viewInfo: extractViewInfo(view)
+      };
+      if (pullCount === 0) {
+        view[0] = 0x01;
+        byobRequest.respond(1);
+      } else if (pullCount === 1) {
+        view[0] = 0x02;
+        view[1] = 0x03;
+        byobRequest.respond(2);
+      }
 
       ++pullCount;
     },
     type: 'bytes',
     autoAllocateChunkSize: 16
   }, {
     highWaterMark: 0
   });
 
   const reader = stream.getReader();
-  const readPromise = reader.read();
-  const ignoredReadPromise = reader.read();
+  const p0 = reader.read();
+  const p1 = reader.read();
 
   assert_equals(pullCount, 0, 'No pull() as start() just finished and is not yet reflected to the state of the stream');
 
   return Promise.resolve().then(() => {
     assert_equals(pullCount, 1, 'pull() must have been invoked once');
-    assert_not_equals(byobRequest, undefined, 'byobRequest must not be undefined');
-    assert_true(viewDefined, 'byobRequest.view must not be undefined');
-    assert_equals(viewInfo.constructor, Uint8Array, 'view.constructor should be Uint8Array');
-    assert_equals(viewInfo.bufferByteLength, 16, 'view.buffer.byteLength should be 16');
-    assert_equals(viewInfo.byteOffset, 0, 'view.byteOffset should be 0');
-    assert_equals(viewInfo.byteLength, 16, 'view.byteLength should be 16');
-    return readPromise;
+    const byobRequest = byobRequests[0];
+    assert_true(byobRequest.defined, 'first byobRequest must not be undefined');
+    assert_true(byobRequest.viewDefined, 'first byobRequest.view must not be undefined');
+    const viewInfo = byobRequest.viewInfo;
+    assert_equals(viewInfo.constructor, Uint8Array, 'first view.constructor should be Uint8Array');
+    assert_equals(viewInfo.bufferByteLength, 16, 'first view.buffer.byteLength should be 16');
+    assert_equals(viewInfo.byteOffset, 0, 'first view.byteOffset should be 0');
+    assert_equals(viewInfo.byteLength, 16, 'first view.byteLength should be 16');
+
+    return p0;
   }).then(result => {
-    assert_not_equals(result.value, undefined);
-    assert_equals(result.value.constructor, Uint8Array);
-    assert_equals(result.value.buffer.byteLength, 16);
-    assert_equals(result.value.byteOffset, 0);
-    assert_equals(result.value.byteLength, 1);
-    assert_equals(result.value[0], 0x01);
-    assert_equals(pullCount, 1, 'pull() should only be invoked once');
+    assert_equals(pullCount, 2, 'pull() must have been invoked twice');
+    const value = result.value;
+    assert_not_equals(value, undefined, 'first read should have a value');
+    assert_equals(value.constructor, Uint8Array, 'first value should be a Uint8Array');
+    assert_equals(value.buffer.byteLength, 16, 'first value.buffer.byteLength should be 16');
+    assert_equals(value.byteOffset, 0, 'first value.byteOffset should be 0');
+    assert_equals(value.byteLength, 1, 'first value.byteLength should be 1');
+    assert_equals(value[0], 0x01, 'first value[0] should be 0x01');
+    const byobRequest = byobRequests[1];
+    assert_true(byobRequest.defined, 'second byobRequest must not be undefined');
+    assert_true(byobRequest.viewDefined, 'second byobRequest.view must not be undefined');
+    const viewInfo = byobRequest.viewInfo;
+    assert_equals(viewInfo.constructor, Uint8Array, 'second view.constructor should be Uint8Array');
+    assert_equals(viewInfo.bufferByteLength, 16, 'second view.buffer.byteLength should be 16');
+    assert_equals(viewInfo.byteOffset, 0, 'second view.byteOffset should be 0');
+    assert_equals(viewInfo.byteLength, 16, 'second view.byteLength should be 16');
+
+    return p1;
+  }).then(result => {
+    assert_equals(pullCount, 2, 'pull() should only be invoked twice');
+    const value = result.value;
+    assert_not_equals(value, undefined, 'second read should have a value');
+    assert_equals(value.constructor, Uint8Array, 'second value should be a Uint8Array');
+    assert_equals(value.buffer.byteLength, 16, 'second value.buffer.byteLength should be 16');
+    assert_equals(value.byteOffset, 0, 'second value.byteOffset should be 0');
+    assert_equals(value.byteLength, 2, 'second value.byteLength should be 2');
+    assert_equals(value[0], 0x02, 'second value[0] should be 0x02');
+    assert_equals(value[1], 0x03, 'second value[1] should be 0x03');
   });
 }, 'ReadableStream with byte source: autoAllocateChunkSize');
 
 promise_test(() => {
   let pullCount = 0;
   let controller;
   const byobRequests = [];
 
@@ -382,42 +412,44 @@ promise_test(() => {
     type: 'bytes',
     autoAllocateChunkSize: 16
   }, {
     highWaterMark: 0
   });
 
   const reader = stream.getReader();
   return reader.read().then(result => {
-    assert_not_equals(result.value, undefined);
-    assert_equals(result.value.constructor, Uint8Array);
-    assert_equals(result.value.buffer.byteLength, 16);
-    assert_equals(result.value.byteOffset, 0);
-    assert_equals(result.value.byteLength, 1);
-    assert_equals(result.value[0], 0x01);
+    const value = result.value;
+    assert_not_equals(value, undefined, 'first read should have a value');
+    assert_equals(value.constructor, Uint8Array, 'first value should be a Uint8Array');
+    assert_equals(value.buffer.byteLength, 16, 'first value.buffer.byteLength should be 16');
+    assert_equals(value.byteOffset, 0, 'first value.byteOffset should be 0');
+    assert_equals(value.byteLength, 1, 'first value.byteLength should be 1');
+    assert_equals(value[0], 0x01, 'first value[0] should be 0x01');
     const byobRequest = byobRequests[0];
     assert_true(byobRequest.defined, 'first byobRequest must not be undefined');
     assert_true(byobRequest.viewDefined, 'first byobRequest.view must not be undefined');
     const viewInfo = byobRequest.viewInfo;
     assert_equals(viewInfo.constructor, Uint8Array, 'first view.constructor should be Uint8Array');
     assert_equals(viewInfo.bufferByteLength, 16, 'first view.buffer.byteLength should be 16');
     assert_equals(viewInfo.byteOffset, 0, 'first view.byteOffset should be 0');
     assert_equals(viewInfo.byteLength, 16, 'first view.byteLength should be 16');
 
     reader.releaseLock();
     const byobReader = stream.getReader({ mode: 'byob' });
     return byobReader.read(new Uint8Array(32));
   }).then(result => {
-    assert_not_equals(result.value, undefined);
-    assert_equals(result.value.constructor, Uint8Array);
-    assert_equals(result.value.buffer.byteLength, 32);
-    assert_equals(result.value.byteOffset, 0);
-    assert_equals(result.value.byteLength, 2);
-    assert_equals(result.value[0], 0x02);
-    assert_equals(result.value[1], 0x03);
+    const value = result.value;
+    assert_not_equals(value, undefined, 'second read should have a value');
+    assert_equals(value.constructor, Uint8Array, 'second value should be a Uint8Array');
+    assert_equals(value.buffer.byteLength, 32, 'second value.buffer.byteLength should be 32');
+    assert_equals(value.byteOffset, 0, 'second value.byteOffset should be 0');
+    assert_equals(value.byteLength, 2, 'second value.byteLength should be 2');
+    assert_equals(value[0], 0x02, 'second value[0] should be 0x02');
+    assert_equals(value[1], 0x03, 'second value[1] should be 0x03');
     const byobRequest = byobRequests[1];
     assert_true(byobRequest.defined, 'second byobRequest must not be undefined');
     assert_true(byobRequest.viewDefined, 'second byobRequest.view must not be undefined');
     const viewInfo = byobRequest.viewInfo;
     assert_equals(viewInfo.constructor, Uint8Array, 'second view.constructor should be Uint8Array');
     assert_equals(viewInfo.bufferByteLength, 32, 'second view.buffer.byteLength should be 32');
     assert_equals(viewInfo.byteOffset, 0, 'second view.byteOffset should be 0');
     assert_equals(viewInfo.byteLength, 32, 'second view.byteLength should be 32');
@@ -688,17 +720,17 @@ promise_test(() => {
       desiredSizes.push(controller.desiredSize);
       controller.enqueue(new Uint8Array(1));
       desiredSizes.push(controller.desiredSize);
 
       ++pullCount;
     },
     type: 'bytes'
   }, {
-    highWaterMark: 256
+    highWaterMark: 0
   });
 
   const reader = stream.getReader();
 
   const p0 = reader.read();
   const p1 = reader.read();
   const p2 = reader.read();
 
@@ -712,22 +744,71 @@ promise_test(() => {
 
     assert_equals(result[0].done, false, 'result[0].done');
     assert_equals(result[0].value.byteLength, 1, 'result[0].value.byteLength');
     assert_equals(result[1].done, false, 'result[1].done');
     assert_equals(result[1].value.byteLength, 1, 'result[1].value.byteLength');
     assert_equals(result[2].done, false, 'result[2].done');
     assert_equals(result[2].value.byteLength, 1, 'result[2].value.byteLength');
     assert_equals(byobRequest, undefined, 'byobRequest should be undefined');
+    assert_equals(desiredSizes[0], 0, 'desiredSize on pull should be 0');
+    assert_equals(desiredSizes[1], 0, 'desiredSize after 1st enqueue() should be 0');
+    assert_equals(desiredSizes[2], 0, 'desiredSize after 2nd enqueue() should be 0');
+    assert_equals(pullCount, 1, 'pull() should only be called once');
+  });
+}, 'ReadableStream with byte source: Respond to pull() by enqueue() asynchronously');
+
+promise_test(() => {
+  let pullCount = 0;
+
+  let byobRequest;
+  const desiredSizes = [];
+
+  const stream = new ReadableStream({
+    pull(c) {
+      byobRequest = c.byobRequest;
+      desiredSizes.push(c.desiredSize);
+
+      if (pullCount < 3) {
+        c.enqueue(new Uint8Array(1));
+      } else {
+        c.close();
+      }
+
+      ++pullCount;
+    },
+    type: 'bytes'
+  }, {
+    highWaterMark: 256
+  });
+
+  const reader = stream.getReader();
+
+  const p0 = reader.read();
+  const p1 = reader.read();
+  const p2 = reader.read();
+
+  assert_equals(pullCount, 0, 'No pull as start() just finished and is not yet reflected to the state of the stream');
+
+  return Promise.all([p0, p1, p2]).then(result => {
+    assert_equals(pullCount, 4, 'pullCount after completion of all read()s');
+
+    assert_equals(result[0].done, false, 'result[0].done');
+    assert_equals(result[0].value.byteLength, 1, 'result[0].value.byteLength');
+    assert_equals(result[1].done, false, 'result[1].done');
+    assert_equals(result[1].value.byteLength, 1, 'result[1].value.byteLength');
+    assert_equals(result[2].done, false, 'result[2].done');
+    assert_equals(result[2].value.byteLength, 1, 'result[2].value.byteLength');
+    assert_equals(byobRequest, undefined, 'byobRequest should be undefined');
     assert_equals(desiredSizes[0], 256, 'desiredSize on pull should be 256');
     assert_equals(desiredSizes[1], 256, 'desiredSize after 1st enqueue() should be 256');
     assert_equals(desiredSizes[2], 256, 'desiredSize after 2nd enqueue() should be 256');
-    assert_equals(pullCount, 1, 'pull() should only be called once');
+    assert_equals(desiredSizes[3], 256, 'desiredSize after 3rd enqueue() should be 256');
   });
-}, 'ReadableStream with byte source: Respond to pull() by enqueue() asynchronously');
+}, 'ReadableStream with byte source: Respond to multiple pull() by separate enqueue()');
 
 promise_test(() => {
   let controller;
 
   let pullCount = 0;
   const byobRequestDefined = [];
 
   const stream = new ReadableStream({