Tests for bug 634534 (destroy a stream while a part-request has been requested but OnStartRequest has not yet fired). Fixed test_pluginstream_seek_close.html so that the first iframe onload (for about:blank) is not used with the test. a=blocker-test
authorBenjamin Smedberg <benjamin@smedbergs.us>
Wed, 23 Feb 2011 10:47:17 -0500
changeset 63059 4806e2c8554ea5070126480070badc31f6dd4a27
parent 63058 25e1f247b7c26b61216babadf2eed502a51875da
child 63060 cd17f857b8c0901dd6493859edea91a1faf3286b
push id1
push userroot
push dateTue, 10 Dec 2013 15:46:25 +0000
reviewersblocker-test
bugs634534
milestone2.0b13pre
Tests for bug 634534 (destroy a stream while a part-request has been requested but OnStartRequest has not yet fired). Fixed test_pluginstream_seek_close.html so that the first iframe onload (for about:blank) is not used with the test. a=blocker-test
modules/plugin/test/mochitest/Makefile.in
modules/plugin/test/mochitest/test_pluginstream_seek_close.html
modules/plugin/test/testplugin/nptest.cpp
modules/plugin/test/testplugin/nptest.h
--- a/modules/plugin/test/mochitest/Makefile.in
+++ b/modules/plugin/test/mochitest/Makefile.in
@@ -65,16 +65,17 @@ include $(topsrcdir)/config/rules.mk
   test_pluginstream_geturl.html \
   test_pluginstream_geturlnotify.html \
   test_pluginstream_asfile.html \
   test_pluginstream_asfileonly.html \
   test_pluginstream_post.html \
   test_pluginstream_poststream.html \
   test_pluginstream_seek.html \
   test_pluginstream_newstream.html \
+  test_pluginstream_seek_close.html \
   test_fullpage.html \
   loremipsum.xtest \
   loremipsum.xtest^headers^ \
   test_multipleinstanceobjects.html \
   test_streamNotify.html \
   test_instantiation.html \
   test_cookies.html \
   test_npn_timers.html \
new file mode 100644
--- /dev/null
+++ b/modules/plugin/test/mochitest/test_pluginstream_seek_close.html
@@ -0,0 +1,44 @@
+<body>
+<head>
+  <title>NPAPI Seekable NPStream Test</title>
+  <script type="text/javascript" 
+          src="/MochiKit/packed.js"></script>
+  <script type="text/javascript" 
+          src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" 
+        href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+  <p id="display"></p>
+
+  <iframe id="testframe" name="testframe" onload="frameLoaded()"></iframe>
+
+  <!--
+   - Tests a seekable stream.  Calls NPN_RequestRead with the specified
+   - range, and verifies that an NPP_Write call is made with the correct 
+   - parameters, including the buffer data for the byte range.  Once all 
+   - calls to NPP_Write have finished, the plugin calls NPN_DestroyStream 
+   - and then displays the entire stream's content in a browser frame via 
+   - NPN_GetURL.
+   -->
+  <embed src="neverending.sjs" streammode="seek" closestream
+         frame="testframe" streamchunksize="1024" range="100,100"
+         id="embedtest" style="width: 400px; height: 100px;"
+         type="application/x-test"></embed>
+
+  <script class="testbody" type="application/javascript">
+  SimpleTest.waitForExplicitFinish();
+
+  var testframe = document.getElementById('testframe');
+
+  function frameLoaded() {
+    var content = testframe.contentDocument.body.innerHTML;
+    if (!content.length)
+      return;
+
+    ok(true, "We didn't crash");
+    SimpleTest.finish();
+  }
+  </script>
+</body>
+</html>
--- a/modules/plugin/test/testplugin/nptest.cpp
+++ b/modules/plugin/test/testplugin/nptest.cpp
@@ -734,16 +734,17 @@ NPP_New(NPMIMEType pluginType, NPP insta
   memset(&instanceData->window, 0, sizeof(instanceData->window));
   instanceData->crashOnDestroy = false;
   instanceData->cleanupWidget = true; // only used by nptest_gtk
   instanceData->topLevelWindowActivationState = ACTIVATION_STATE_UNKNOWN;
   instanceData->topLevelWindowActivationEventCount = 0;
   instanceData->focusState = ACTIVATION_STATE_UNKNOWN;
   instanceData->focusEventCount = 0;
   instanceData->eventModel = 0;
+  instanceData->closeStream = false;
   instance->pdata = instanceData;
 
   TestNPObject* scriptableObject = (TestNPObject*)NPN_CreateObject(instance, &sNPClass);
   if (!scriptableObject) {
     printf("NPN_CreateObject failed to create an object, can't create a plugin instance\n");
     free(instanceData);
     return NPERR_GENERIC_ERROR;
   }
@@ -849,16 +850,19 @@ NPP_New(NPMIMEType pluginType, NPP insta
     // "cleanupwidget" is only used with nptest_gtk, defaulting to true.  It
     // indicates whether the plugin should destroy its window in response to
     // NPP_Destroy (or let the platform destroy the widget when the parent
     // window gets destroyed).
     if (strcmp(argn[i], "cleanupwidget") == 0 &&
         strcmp(argv[i], "false") == 0) {
       instanceData->cleanupWidget = false;
     }
+    if (!strcmp(argn[i], "closestream")) {
+      instanceData->closeStream = true;
+    }
   }
 
   if (!browserSupportsWindowless || !pluginSupportsWindowlessMode()) {
     requestWindow = true;
   } else if (!pluginSupportsWindowMode()) {
     requestWindow = false;
   }
   if (requestWindow) {
@@ -1111,17 +1115,16 @@ NPP_WriteReady(NPP instance, NPStream* s
   //}
 
   return instanceData->streamChunkSize;
 }
 
 int32_t
 NPP_Write(NPP instance, NPStream* stream, int32_t offset, int32_t len, void* buffer)
 {
-  printf("NPP_Write, offset=%d, len=%d, end=%d\n", offset, len, stream->end);
   InstanceData* instanceData = (InstanceData*)(instance->pdata);
   instanceData->writeCount++;
 
   // temporarily disabled per bug 519870
   //if (instanceData->writeReadyCount == 1) {
   //  instanceData->err << "NPP_Write called even though NPP_WriteReady " <<
   //      "returned 0";
   //}
@@ -1158,21 +1161,28 @@ NPP_Write(NPP instance, NPStream* stream
   if (nd && nd != &kNotifyData) {
     uint32_t newsize = nd->size + len;
     nd->data = (char*) realloc(nd->data, newsize);
     memcpy(nd->data + nd->size, buffer, len);
     nd->size = newsize;
     return len;
   }
 
-  // If the complete stream has been written, and we're doing a seek test,
-  // then call NPN_RequestRead.
-  if (instanceData->streamMode == NP_SEEK &&
+  if (instanceData->closeStream) {
+    instanceData->closeStream = false;
+    if (instanceData->testrange != NULL) {
+      NPError err = NPN_RequestRead(stream, instanceData->testrange);
+    }
+    NPN_DestroyStream(instance, stream, NPRES_USER_BREAK);
+  }
+  else if (instanceData->streamMode == NP_SEEK &&
       stream->end != 0 && 
       stream->end == ((uint32_t)instanceData->streamBufSize + len)) {
+    // If the complete stream has been written, and we're doing a seek test,
+    // then call NPN_RequestRead.
     // prevent recursion
     instanceData->streamMode = NP_NORMAL;
 
     if (instanceData->testrange != NULL) {
       NPError err = NPN_RequestRead(stream, instanceData->testrange);
       if (err != NPERR_NO_ERROR) {
         instanceData->err << "NPN_RequestRead returned error %d" << err;
       }
--- a/modules/plugin/test/testplugin/nptest.h
+++ b/modules/plugin/test/testplugin/nptest.h
@@ -132,13 +132,14 @@ typedef struct InstanceData {
   void* fileBuf;
   bool crashOnDestroy;
   bool cleanupWidget;
   ActivationState topLevelWindowActivationState;
   int32_t topLevelWindowActivationEventCount;
   ActivationState focusState;
   int32_t focusEventCount;
   int32_t eventModel;
+  bool closeStream;
 } InstanceData;
 
 void notifyDidPaint(InstanceData* instanceData);
 
 #endif // nptest_h_