xpcom/tests/TestPipes.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #include "TestHarness.h"
     8 #include "nsIThread.h"
     9 #include "nsIRunnable.h"
    10 #include "nsThreadUtils.h"
    11 #include "prprf.h"
    12 #include "prinrval.h"
    13 #include "nsCRT.h"
    14 #include "nsIPipe.h"    // new implementation
    16 #include "mozilla/Monitor.h"
    17 using namespace mozilla;
    19 /** NS_NewPipe2 reimplemented, because it's not exported by XPCOM */
    20 nsresult TP_NewPipe2(nsIAsyncInputStream** input,
    21                      nsIAsyncOutputStream** output,
    22                      bool nonBlockingInput,
    23                      bool nonBlockingOutput,
    24                      uint32_t segmentSize,
    25                      uint32_t segmentCount,
    26                      nsIMemory* segmentAlloc)
    27 {
    28   nsCOMPtr<nsIPipe> pipe = do_CreateInstance("@mozilla.org/pipe;1");
    29   if (!pipe)
    30     return NS_ERROR_OUT_OF_MEMORY;
    32   nsresult rv = pipe->Init(nonBlockingInput,
    33                            nonBlockingOutput,
    34                            segmentSize,
    35                            segmentCount,
    36                            segmentAlloc);
    38   if (NS_FAILED(rv))
    39     return rv;
    41   pipe->GetInputStream(input);
    42   pipe->GetOutputStream(output);
    43   return NS_OK;
    44 }
    46 /** NS_NewPipe reimplemented, because it's not exported by XPCOM */
    47 #define TP_DEFAULT_SEGMENT_SIZE  4096
    48 nsresult TP_NewPipe(nsIInputStream **pipeIn,
    49                     nsIOutputStream **pipeOut,
    50                     uint32_t segmentSize = 0,
    51                     uint32_t maxSize = 0,
    52                     bool nonBlockingInput = false,
    53                     bool nonBlockingOutput = false,
    54                     nsIMemory *segmentAlloc = nullptr);
    55 nsresult TP_NewPipe(nsIInputStream **pipeIn,
    56                     nsIOutputStream **pipeOut,
    57                     uint32_t segmentSize,
    58                     uint32_t maxSize,
    59                     bool nonBlockingInput,
    60                     bool nonBlockingOutput,
    61                     nsIMemory *segmentAlloc)
    62 {
    63     if (segmentSize == 0)
    64         segmentSize = TP_DEFAULT_SEGMENT_SIZE;
    66     // Handle maxSize of UINT32_MAX as a special case
    67     uint32_t segmentCount;
    68     if (maxSize == UINT32_MAX)
    69         segmentCount = UINT32_MAX;
    70     else
    71         segmentCount = maxSize / segmentSize;
    73     nsIAsyncInputStream *in;
    74     nsIAsyncOutputStream *out;
    75     nsresult rv = TP_NewPipe2(&in, &out, nonBlockingInput, nonBlockingOutput,
    76                               segmentSize, segmentCount, segmentAlloc);
    77     if (NS_FAILED(rv)) return rv;
    79     *pipeIn = in;
    80     *pipeOut = out;
    81     return NS_OK;
    82 }
    85 #define KEY             0xa7
    86 #define ITERATIONS      33333
    87 char kTestPattern[] = "My hovercraft is full of eels.\n";
    89 bool gTrace = false;
    91 static nsresult
    92 WriteAll(nsIOutputStream *os, const char *buf, uint32_t bufLen, uint32_t *lenWritten)
    93 {
    94     const char *p = buf;
    95     *lenWritten = 0;
    96     while (bufLen) {
    97         uint32_t n;
    98         nsresult rv = os->Write(p, bufLen, &n);
    99         if (NS_FAILED(rv)) return rv;
   100         p += n;
   101         bufLen -= n;
   102         *lenWritten += n;
   103     }
   104     return NS_OK;
   105 }
   107 class nsReceiver : public nsIRunnable {
   108 public:
   109     NS_DECL_THREADSAFE_ISUPPORTS
   111     NS_IMETHOD Run() {
   112         nsresult rv;
   113         char buf[101];
   114         uint32_t count;
   115         PRIntervalTime start = PR_IntervalNow();
   116         while (true) {
   117             rv = mIn->Read(buf, 100, &count);
   118             if (NS_FAILED(rv)) {
   119                 printf("read failed\n");
   120                 break;
   121             }
   122             if (count == 0) {
   123 //                printf("EOF count = %d\n", mCount);
   124                 break;
   125             }
   127             if (gTrace) {
   128                 buf[count] = '\0';
   129                 printf("read: %s\n", buf);
   130             }
   131             mCount += count;
   132         }
   133         PRIntervalTime end = PR_IntervalNow();
   134         printf("read  %d bytes, time = %dms\n", mCount,
   135                PR_IntervalToMilliseconds(end - start));
   136         return rv;
   137     }
   139     nsReceiver(nsIInputStream* in) : mIn(in), mCount(0) {
   140     }
   142     uint32_t GetBytesRead() { return mCount; }
   144 protected:
   145     nsCOMPtr<nsIInputStream> mIn;
   146     uint32_t            mCount;
   147 };
   149 NS_IMPL_ISUPPORTS(nsReceiver, nsIRunnable)
   151 nsresult
   152 TestPipe(nsIInputStream* in, nsIOutputStream* out)
   153 {
   154     nsCOMPtr<nsReceiver> receiver = new nsReceiver(in);
   155     if (!receiver)
   156         return NS_ERROR_OUT_OF_MEMORY;
   158     nsresult rv;
   160     nsCOMPtr<nsIThread> thread;
   161     rv = NS_NewThread(getter_AddRefs(thread), receiver);
   162     if (NS_FAILED(rv)) return rv;
   164     uint32_t total = 0;
   165     PRIntervalTime start = PR_IntervalNow();
   166     for (uint32_t i = 0; i < ITERATIONS; i++) {
   167         uint32_t writeCount;
   168         char *buf = PR_smprintf("%d %s", i, kTestPattern);
   169         uint32_t len = strlen(buf);
   170         rv = WriteAll(out, buf, len, &writeCount);
   171         if (gTrace) {
   172             printf("wrote: ");
   173             for (uint32_t j = 0; j < writeCount; j++) {
   174                 putc(buf[j], stdout);
   175             }
   176             printf("\n");
   177         }
   178         PR_smprintf_free(buf);
   179         if (NS_FAILED(rv)) return rv;
   180         total += writeCount;
   181     }
   182     rv = out->Close();
   183     if (NS_FAILED(rv)) return rv;
   185     PRIntervalTime end = PR_IntervalNow();
   187     thread->Shutdown();
   189     printf("wrote %d bytes, time = %dms\n", total,
   190            PR_IntervalToMilliseconds(end - start));
   191     NS_ASSERTION(receiver->GetBytesRead() == total, "didn't read everything");
   193     return NS_OK;
   194 }
   196 ////////////////////////////////////////////////////////////////////////////////
   198 class nsShortReader : public nsIRunnable {
   199 public:
   200     NS_DECL_THREADSAFE_ISUPPORTS
   202     NS_IMETHOD Run() {
   203         nsresult rv;
   204         char buf[101];
   205         uint32_t count;
   206         uint32_t total = 0;
   207         while (true) {
   208             //if (gTrace)
   209             //    printf("calling Read\n");
   210             rv = mIn->Read(buf, 100, &count);
   211             if (NS_FAILED(rv)) {
   212                 printf("read failed\n");
   213                 break;
   214             }
   215             if (count == 0) {
   216                 break;
   217             }
   219             if (gTrace) {
   220                 // For next |printf()| call and possible others elsewhere.
   221                 buf[count] = '\0';
   223                 printf("read %d bytes: %s\n", count, buf);
   224             }
   226             Received(count);
   227             total += count;
   228         }
   229         printf("read  %d bytes\n", total);
   230         return rv;
   231     }
   233     nsShortReader(nsIInputStream* in) : mIn(in), mReceived(0) {
   234         mMon = new Monitor("nsShortReader");
   235     }
   237     void Received(uint32_t count) {
   238         MonitorAutoEnter mon(*mMon);
   239         mReceived += count;
   240         mon.Notify();
   241     }
   243     uint32_t WaitForReceipt(const uint32_t aWriteCount) {
   244         MonitorAutoEnter mon(*mMon);
   245         uint32_t result = mReceived;
   247         while (result < aWriteCount) {
   248             mon.Wait();
   250             NS_ASSERTION(mReceived > result, "failed to receive");
   251             result = mReceived;
   252         }
   254         mReceived = 0;
   255         return result;
   256     }
   258 protected:
   259     nsCOMPtr<nsIInputStream> mIn;
   260     uint32_t                 mReceived;
   261     Monitor*                 mMon;
   262 };
   264 NS_IMPL_ISUPPORTS(nsShortReader, nsIRunnable)
   266 nsresult
   267 TestShortWrites(nsIInputStream* in, nsIOutputStream* out)
   268 {
   269     nsCOMPtr<nsShortReader> receiver = new nsShortReader(in);
   270     if (!receiver)
   271         return NS_ERROR_OUT_OF_MEMORY;
   273     nsresult rv;
   275     nsCOMPtr<nsIThread> thread;
   276     rv = NS_NewThread(getter_AddRefs(thread), receiver);
   277     if (NS_FAILED(rv)) return rv;
   279     uint32_t total = 0;
   280     for (uint32_t i = 0; i < ITERATIONS; i++) {
   281         uint32_t writeCount;
   282         char* buf = PR_smprintf("%d %s", i, kTestPattern);
   283         uint32_t len = strlen(buf);
   284         len = len * rand() / RAND_MAX;
   285         len = XPCOM_MAX(1, len);
   286         rv = WriteAll(out, buf, len, &writeCount);
   287         if (NS_FAILED(rv)) return rv;
   288         NS_ASSERTION(writeCount == len, "didn't write enough");
   289         total += writeCount;
   291         if (gTrace)
   292             printf("wrote %d bytes: %s\n", writeCount, buf);
   293         PR_smprintf_free(buf);
   294         //printf("calling Flush\n");
   295         out->Flush();
   296         //printf("calling WaitForReceipt\n");
   298 #ifdef DEBUG
   299         const uint32_t received =
   300 #endif
   301           receiver->WaitForReceipt(writeCount);
   302         NS_ASSERTION(received == writeCount, "received wrong amount");
   303     }
   304     rv = out->Close();
   305     if (NS_FAILED(rv)) return rv;
   307     thread->Shutdown();
   309     printf("wrote %d bytes\n", total);
   311     return NS_OK;
   312 }
   314 ////////////////////////////////////////////////////////////////////////////////
   316 class nsPump : public nsIRunnable
   317 {
   318 public:
   319     NS_DECL_THREADSAFE_ISUPPORTS
   321     NS_IMETHOD Run() {
   322         nsresult rv;
   323         uint32_t count;
   324         while (true) {
   325             rv = mOut->WriteFrom(mIn, ~0U, &count);
   326             if (NS_FAILED(rv)) {
   327                 printf("Write failed\n");
   328                 break;
   329             }
   330             if (count == 0) {
   331                 printf("EOF count = %d\n", mCount);
   332                 break;
   333             }
   335             if (gTrace) {
   336                 printf("Wrote: %d\n", count);
   337             }
   338             mCount += count;
   339         }
   340         mOut->Close();
   341         return rv;
   342     }
   344     nsPump(nsIInputStream* in,
   345            nsIOutputStream* out)
   346         : mIn(in), mOut(out), mCount(0) {
   347     }
   349 protected:
   350     nsCOMPtr<nsIInputStream>      mIn;
   351     nsCOMPtr<nsIOutputStream>     mOut;
   352     uint32_t                            mCount;
   353 };
   355 NS_IMPL_ISUPPORTS(nsPump, nsIRunnable)
   357 nsresult
   358 TestChainedPipes()
   359 {
   360     nsresult rv;
   361     printf("TestChainedPipes\n");
   363     nsCOMPtr<nsIInputStream> in1;
   364     nsCOMPtr<nsIOutputStream> out1;
   365     rv = TP_NewPipe(getter_AddRefs(in1), getter_AddRefs(out1), 20, 1999);
   366     if (NS_FAILED(rv)) return rv;
   368     nsCOMPtr<nsIInputStream> in2;
   369     nsCOMPtr<nsIOutputStream> out2;
   370     rv = TP_NewPipe(getter_AddRefs(in2), getter_AddRefs(out2), 200, 401);
   371     if (NS_FAILED(rv)) return rv;
   373     nsCOMPtr<nsPump> pump = new nsPump(in1, out2);
   374     if (pump == nullptr) return NS_ERROR_OUT_OF_MEMORY;
   376     nsCOMPtr<nsIThread> thread;
   377     rv = NS_NewThread(getter_AddRefs(thread), pump);
   378     if (NS_FAILED(rv)) return rv;
   380     nsCOMPtr<nsReceiver> receiver = new nsReceiver(in2);
   381     if (receiver == nullptr) return NS_ERROR_OUT_OF_MEMORY;
   383     nsCOMPtr<nsIThread> receiverThread;
   384     rv = NS_NewThread(getter_AddRefs(receiverThread), receiver);
   385     if (NS_FAILED(rv)) return rv;
   387     uint32_t total = 0;
   388     for (uint32_t i = 0; i < ITERATIONS; i++) {
   389         uint32_t writeCount;
   390         char* buf = PR_smprintf("%d %s", i, kTestPattern);
   391         uint32_t len = strlen(buf);
   392         len = len * rand() / RAND_MAX;
   393         len = XPCOM_MAX(1, len);
   394         rv = WriteAll(out1, buf, len, &writeCount);
   395         if (NS_FAILED(rv)) return rv;
   396         NS_ASSERTION(writeCount == len, "didn't write enough");
   397         total += writeCount;
   399         if (gTrace)
   400             printf("wrote %d bytes: %s\n", writeCount, buf);
   402         PR_smprintf_free(buf);
   403     }
   404     printf("wrote total of %d bytes\n", total);
   405     rv = out1->Close();
   406     if (NS_FAILED(rv)) return rv;
   408     thread->Shutdown();
   409     receiverThread->Shutdown();
   411     return NS_OK;
   412 }
   414 ////////////////////////////////////////////////////////////////////////////////
   416 void
   417 RunTests(uint32_t segSize, uint32_t segCount)
   418 {
   419     nsresult rv;
   420     nsCOMPtr<nsIInputStream> in;
   421     nsCOMPtr<nsIOutputStream> out;
   422     uint32_t bufSize = segSize * segCount;
   423     printf("Testing New Pipes: segment size %d buffer size %d\n", segSize, bufSize);
   425     printf("Testing long writes...\n");
   426     rv = TP_NewPipe(getter_AddRefs(in), getter_AddRefs(out), segSize, bufSize);
   427     NS_ASSERTION(NS_SUCCEEDED(rv), "TP_NewPipe failed");
   428     rv = TestPipe(in, out);
   429     NS_ASSERTION(NS_SUCCEEDED(rv), "TestPipe failed");
   431     printf("Testing short writes...\n");
   432     rv = TP_NewPipe(getter_AddRefs(in), getter_AddRefs(out), segSize, bufSize);
   433     NS_ASSERTION(NS_SUCCEEDED(rv), "TP_NewPipe failed");
   434     rv = TestShortWrites(in, out);
   435     NS_ASSERTION(NS_SUCCEEDED(rv), "TestPipe failed");
   436 }
   438 ////////////////////////////////////////////////////////////////////////////////
   440 #if 0
   441 extern void
   442 TestSegmentedBuffer();
   443 #endif
   445 int
   446 main(int argc, char* argv[])
   447 {
   448     nsresult rv;
   450     nsCOMPtr<nsIServiceManager> servMgr;
   451     rv = NS_InitXPCOM2(getter_AddRefs(servMgr), nullptr, nullptr);
   452     if (NS_FAILED(rv)) return rv;
   454     if (argc > 1 && nsCRT::strcmp(argv[1], "-trace") == 0)
   455         gTrace = true;
   457     rv = TestChainedPipes();
   458     NS_ASSERTION(NS_SUCCEEDED(rv), "TestChainedPipes failed");
   459     RunTests(16, 1);
   460     RunTests(4096, 16);
   462     servMgr = 0;
   463     rv = NS_ShutdownXPCOM(nullptr);
   464     NS_ASSERTION(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM failed");
   466     return 0;
   467 }
   469 ////////////////////////////////////////////////////////////////////////////////

mercurial