LCOV - code coverage report
Current view: directory - xpcom/tests - TestPipe.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 103 71 68.9 %
Date: 2012-06-02 Functions: 15 11 73.3 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is mozilla.org code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is
      18                 :  * Jeff Walden <jwalden+code@mit.edu>.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 2007
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *
      24                 :  * Alternatively, the contents of this file may be used under the terms of
      25                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      26                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      27                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      28                 :  * of those above. If you wish to allow use of your version of this file only
      29                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      30                 :  * use your version of this file under the terms of the MPL, indicate your
      31                 :  * decision by deleting the provisions above and replace them with the notice
      32                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      33                 :  * the provisions above, a recipient may use your version of this file under
      34                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      35                 :  *
      36                 :  * ***** END LICENSE BLOCK ***** */
      37                 : 
      38                 : #include "TestHarness.h"
      39                 : 
      40                 : #include "nsIPipe.h"
      41                 : #include "nsIMemory.h"
      42                 : 
      43                 : /** NS_NewPipe2 reimplemented, because it's not exported by XPCOM */
      44               1 : nsresult TP_NewPipe2(nsIAsyncInputStream** input,
      45                 :                      nsIAsyncOutputStream** output,
      46                 :                      bool nonBlockingInput,
      47                 :                      bool nonBlockingOutput,
      48                 :                      PRUint32 segmentSize,
      49                 :                      PRUint32 segmentCount,
      50                 :                      nsIMemory* segmentAlloc)
      51                 : {
      52               2 :   nsCOMPtr<nsIPipe> pipe = do_CreateInstance("@mozilla.org/pipe;1");
      53               1 :   if (!pipe)
      54               0 :     return NS_ERROR_OUT_OF_MEMORY;
      55                 : 
      56               1 :   nsresult rv = pipe->Init(nonBlockingInput,
      57                 :                            nonBlockingOutput,
      58                 :                            segmentSize,
      59                 :                            segmentCount,
      60               1 :                            segmentAlloc);
      61                 : 
      62               1 :   if (NS_FAILED(rv))
      63               0 :     return rv;
      64                 : 
      65               1 :   pipe->GetInputStream(input);
      66               1 :   pipe->GetOutputStream(output);
      67               1 :   return NS_OK;
      68                 : }
      69                 : 
      70                 : /**
      71                 :  * Allocator can allocate exactly count * size bytes, stored at mMemory;
      72                 :  * immediately after the end of this is a byte-map of 0/1 values indicating
      73                 :  * which <size>-byte locations in mMemory are empty and which are filled.
      74                 :  * Pretty stupid, but enough to test bug 394692.
      75                 :  */
      76                 : class BackwardsAllocator : public nsIMemory
      77                 : {
      78                 :   public:
      79               1 :     BackwardsAllocator()
      80                 :       : mMemory(0),
      81                 :         mIndex(0xFFFFFFFF),
      82                 :         mCount(0xFFFFFFFF),
      83               1 :         mSize(0)
      84               1 :     { }
      85               1 :     ~BackwardsAllocator()
      86               1 :     {
      87               1 :       delete [] mMemory;
      88               1 :     }
      89                 : 
      90                 :     nsresult Init(PRUint32 count, size_t size);
      91                 : 
      92                 :     NS_DECL_ISUPPORTS
      93                 :     NS_DECL_NSIMEMORY
      94                 : 
      95                 :   private:
      96              10 :     PRUint32 previous(PRUint32 i)
      97                 :     {
      98              10 :       if (i == 0)
      99               1 :         return mCount - 1;
     100               9 :       return i - 1;
     101                 :     }
     102                 : 
     103                 :   private:
     104                 :     PRUint8* mMemory;
     105                 :     PRUint32 mIndex;
     106                 :     PRUint32 mCount;
     107                 :     size_t mSize;
     108                 : };
     109                 : 
     110               5 : NS_IMPL_ISUPPORTS1(BackwardsAllocator, nsIMemory)
     111                 : 
     112               1 : nsresult BackwardsAllocator::Init(PRUint32 count, size_t size)
     113                 : {
     114               1 :   if (mMemory)
     115                 :   {
     116               0 :     fail("allocator already initialized!");
     117               0 :     return NS_ERROR_ALREADY_INITIALIZED;
     118                 :   }
     119                 : 
     120               2 :   mMemory = new PRUint8[count * size + count];
     121               1 :   if (!mMemory)
     122                 :   {
     123               0 :     fail("failed to allocate mMemory!");
     124               0 :     return NS_ERROR_OUT_OF_MEMORY;
     125                 :   }
     126               1 :   memset(mMemory, 0, count * size + count);
     127                 : 
     128               1 :   mIndex = 0;
     129               1 :   mCount = count;
     130               1 :   mSize = size;
     131                 : 
     132               1 :   return NS_OK;
     133                 : }
     134                 : 
     135              10 : NS_IMETHODIMP_(void*) BackwardsAllocator::Alloc(size_t size)
     136                 : {
     137              10 :   if (size != mSize)
     138                 :   {
     139               0 :     NS_ERROR("umm, why would this be reached for this test?");
     140               0 :     return NULL;
     141                 :   }
     142                 : 
     143              10 :   PRUint32 index = mIndex;
     144                 : 
     145              20 :   while ((index = previous(index)) != mIndex)
     146                 :   {
     147              10 :     if (mMemory[mSize * mCount + index] == 1)
     148               0 :       continue;
     149              10 :     mMemory[mSize * mCount + index] = 1;
     150              10 :     mIndex = index;
     151              10 :     return &mMemory[mSize * index];
     152                 :   }
     153                 : 
     154               0 :   NS_ERROR("shouldn't reach here in this test");
     155               0 :   return NULL;
     156                 : }
     157                 : 
     158               0 : NS_IMETHODIMP_(void*) BackwardsAllocator::Realloc(void* ptr, size_t newSize)
     159                 : {
     160               0 :   NS_ERROR("shouldn't reach here in this test");
     161               0 :   return NULL;
     162                 : }
     163                 : 
     164              10 : NS_IMETHODIMP_(void) BackwardsAllocator::Free(void* ptr)
     165                 : {
     166              10 :   PRUint8* p = static_cast<PRUint8*>(ptr);
     167              10 :   if (p)
     168              10 :     mMemory[mCount * mSize + (p - mMemory) / mSize] = 0;
     169              10 : }
     170                 : 
     171               0 : NS_IMETHODIMP BackwardsAllocator::HeapMinimize(bool immediate)
     172                 : {
     173               0 :   return NS_OK;
     174                 : }
     175                 : 
     176               0 : NS_IMETHODIMP BackwardsAllocator::IsLowMemory(bool* retval)
     177                 : {
     178               0 :   *retval = false;
     179               0 :   return NS_OK;
     180                 : }
     181                 : 
     182                 : 
     183               1 : nsresult TestBackwardsAllocator()
     184                 : {
     185               1 :   const PRUint32 SEGMENT_COUNT = 10;
     186               1 :   const PRUint32 SEGMENT_SIZE = 10;
     187                 : 
     188               2 :   nsRefPtr<BackwardsAllocator> allocator = new BackwardsAllocator();
     189               1 :   if (!allocator)
     190                 :   {
     191               0 :     fail("Allocation of BackwardsAllocator failed!");
     192               0 :     return NS_ERROR_OUT_OF_MEMORY;
     193                 :   }
     194               1 :   nsresult rv = allocator->Init(SEGMENT_COUNT, SEGMENT_SIZE);
     195               1 :   if (NS_FAILED(rv))
     196               0 :     return rv;
     197                 : 
     198               2 :   nsCOMPtr<nsIAsyncInputStream> input;
     199               2 :   nsCOMPtr<nsIAsyncOutputStream> output;
     200               1 :   rv = TP_NewPipe2(getter_AddRefs(input),
     201               1 :                    getter_AddRefs(output),
     202                 :                    false,
     203                 :                    false,
     204               1 :                    SEGMENT_SIZE, SEGMENT_COUNT, allocator); 
     205               1 :   if (NS_FAILED(rv))
     206                 :   {
     207               0 :     fail("TP_NewPipe2 failed: %x", rv);
     208               0 :     return rv;
     209                 :   }
     210                 : 
     211               1 :   const PRUint32 BUFFER_LENGTH = 100;
     212                 :   const char written[] =
     213                 :     "0123456789"
     214                 :     "1123456789"
     215                 :     "2123456789"
     216                 :     "3123456789"
     217                 :     "4123456789"
     218                 :     "5123456789"
     219                 :     "6123456789"
     220                 :     "7123456789"
     221                 :     "8123456789"
     222               1 :     "9123456789"; // not just a memset, to ensure the allocator works correctly
     223                 :   if (sizeof(written) < BUFFER_LENGTH)
     224                 :   {
     225                 :     fail("test error with string size");
     226                 :     return NS_ERROR_FAILURE;
     227                 :   }
     228                 : 
     229                 :   PRUint32 writeCount;
     230               1 :   rv = output->Write(written, BUFFER_LENGTH, &writeCount);
     231               1 :   if (NS_FAILED(rv) || writeCount != BUFFER_LENGTH)
     232                 :   {
     233                 :     fail("writing %d bytes (wrote %d bytes) to output failed: %x",
     234               0 :          BUFFER_LENGTH, writeCount, rv);
     235               0 :     return rv;
     236                 :   }
     237                 : 
     238                 :   char read[BUFFER_LENGTH];
     239                 :   PRUint32 readCount;
     240               1 :   rv = input->Read(read, BUFFER_LENGTH, &readCount);
     241               1 :   if (NS_FAILED(rv) || readCount != BUFFER_LENGTH)
     242                 :   {
     243                 :     fail("reading %d bytes (got %d bytes) from input failed: %x",
     244               0 :          BUFFER_LENGTH, readCount,  rv);
     245               0 :     return rv;
     246                 :   }
     247                 : 
     248               1 :   if (0 != memcmp(written, read, BUFFER_LENGTH))
     249                 :   {
     250               0 :     fail("didn't read the written data correctly!");
     251               0 :     return NS_ERROR_FAILURE;
     252                 :   }
     253                 : 
     254               1 :   passed("TestBackwardsAllocator");
     255               1 :   return NS_OK;
     256                 : }
     257                 : 
     258               1 : int main(int argc, char** argv)
     259                 : {
     260               2 :   ScopedXPCOM xpcom("nsPipe");
     261               1 :   if (xpcom.failed())
     262               0 :     return 1;
     263                 : 
     264               1 :   int rv = 0;
     265                 : 
     266               1 :   if (NS_FAILED(TestBackwardsAllocator()))
     267               0 :     rv = 1;
     268                 : 
     269               1 :   return rv;
     270                 : }

Generated by: LCOV version 1.7