LCOV - code coverage report
Current view: directory - tests/srpc_message - srpc_message.c (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 266 263 98.9 %
Date: 2014-09-25 Functions: 0 0 -

       1                 : /*
       2                 :  * Copyright (c) 2012 The Native Client Authors. All rights reserved.
       3                 :  * Use of this source code is governed by a BSD-style license that can be
       4                 :  * found in the LICENSE file.
       5                 :  */
       6                 : 
       7                 : /* This test uses asserts, which are disabled whenever NDEBUG is defined. */
       8                 : #if defined(NDEBUG)
       9                 : #undef NDEBUG
      10                 : #endif
      11                 : 
      12                 : #include <assert.h>
      13                 : #include <errno.h>
      14                 : #include <stdio.h>
      15                 : #include <stdlib.h>
      16                 : #include <string.h>
      17                 : #if defined(__native_client__)
      18                 : #include <pthread.h>
      19                 : #include <stdint.h>
      20                 : #include "native_client/src/public/imc_syscalls.h"
      21                 : #include "native_client/src/shared/srpc/nacl_srpc.h"
      22                 : #else
      23                 : #include "native_client/src/include/portability.h"
      24                 : #include "native_client/src/shared/platform/nacl_threads.h"
      25                 : #include "native_client/src/shared/platform/platform_init.h"
      26                 : #include "native_client/src/shared/srpc/nacl_srpc.h"
      27                 : #include "native_client/src/trusted/desc/nacl_desc_invalid.h"
      28                 : #include "native_client/src/trusted/desc/nrd_all_modules.h"
      29                 : #include "native_client/src/trusted/desc/nrd_xfer.h"
      30                 : #endif
      31                 : #include "native_client/src/shared/srpc/nacl_srpc_message.h"
      32                 : 
      33                 : /*
      34                 :  * Tests the NaClSrpcMessageChannel component.  This component is a layer
      35                 :  * over IMC that provides the ability to send and receive messages that are
      36                 :  * larger than the size limits imposed by IMC.  In particular, IMC imposes
      37                 :  * two limits:
      38                 :  *   IMC_USER_BYTES_MAX is the maximum number of bytes that imc_sendmsg
      39                 :  *                      can possibly send.  The actual value may be lower.
      40                 :  *   IMC_USER_DESC_MAX is the maximum number of descriptors that imc_sedmsg
      41                 :  *                     can possibly send.
      42                 :  *  There remain, furthermore, limitations on the number of IOV entries that
      43                 :  *  a header can have.
      44                 :  *
      45                 :  *  main sends and receives various combinations of bytes and descriptors and
      46                 :  *  checks the return values.
      47                 :  */
      48                 : 
      49                 : #if defined(__native_client__)
      50                 : #define NaClImcMsgIoVec NaClAbiNaClImcMsgIoVec
      51                 : #endif
      52                 : 
      53                 : /* TODO(sehr): test larger than IMC_IOVEC_MAX / 2 iov entries. */
      54                 : #define kIovEntryCount        (NACL_ABI_IMC_IOVEC_MAX / 2)
      55                 : #define kDescCount            (4 * NACL_ABI_IMC_USER_DESC_MAX)
      56                 : 
      57                 : #define ARRAY_SIZE(a)         (sizeof a / sizeof a[0])
      58                 : 
      59                 : #define MAX(a, b)             (((a) > (b)) ? (a) : (b))
      60                 : #define MIN(a, b)             (((a) < (b)) ? (a) : (b))
      61                 : 
      62                 : /* The largest message to be tested. */
      63                 : size_t g_max_message_size;
      64                 : /* The size of a fragment. */
      65                 : size_t g_fragment_bytes;
      66                 : /* The size of the neighborhood around k * g_fragment_bytes to consider. */
      67                 : size_t g_message_delta;
      68                 : 
      69                 : /* An array filled with 0, 1, 2, ... for sending and comparison. */
      70                 : int32_t* gTestArray;
      71                 : 
      72                 : /* An array used for recieving messages smaller than a fragment. */
      73                 : int32_t* gShortBuf;
      74                 : /* The length of the messages smaller than a fragment. */
      75                 : size_t g_short_message_length;
      76                 : 
      77                 : /* An array used for recieving messages larger than a fragment. */
      78                 : int32_t* gLongBuf;
      79                 : /* The length of the messages larger than a fragment. */
      80                 : size_t g_long_message_length;
      81                 : 
      82                 : /*
      83                 :  * The size of an IOV chunk for a long message. Long messages will be
      84                 :  * uniformly chunked.
      85                 :  */
      86                 : size_t g_long_message_iov_chunk_size;
      87                 : 
      88                 : /* An invalid descriptor to be transferred back and forth. */
      89                 : NaClSrpcMessageDesc g_bogus_desc;
      90                 : 
      91               1 : void SendShortMessage(struct NaClSrpcMessageChannel* channel) {
      92                 :   NaClSrpcMessageHeader header;
      93                 :   struct NaClImcMsgIoVec iovec[1];
      94                 :   NaClSrpcMessageDesc descs[1];
      95                 : 
      96                 :   /* One iov entry, short enough to pass in one fragment. */
      97               1 :   header.iov_length = ARRAY_SIZE(iovec);
      98               1 :   header.iov = iovec;
      99               1 :   iovec[0].base = (void*) gTestArray;
     100               1 :   iovec[0].length = g_short_message_length;
     101                 :   /* One descriptor. */
     102               1 :   header.NACL_SRPC_MESSAGE_HEADER_DESC_LENGTH = ARRAY_SIZE(descs);
     103               1 :   header.NACL_SRPC_MESSAGE_HEADER_DESCV = descs;
     104               1 :   descs[0] = g_bogus_desc;
     105               1 :   assert(header.NACL_SRPC_MESSAGE_HEADER_DESC_LENGTH != 0);
     106                 :   /* Check that the entire message was sent. */
     107                 :   assert(NaClSrpcMessageChannelSend(channel, &header) ==
     108               1 :          (ssize_t) g_short_message_length);
     109               1 : }
     110                 : 
     111               1 : void ReceiveShortMessage(struct NaClSrpcMessageChannel* channel) {
     112                 :   NaClSrpcMessageHeader header;
     113                 :   struct NaClImcMsgIoVec iovec[1];
     114                 :   NaClSrpcMessageDesc descs[NACL_ABI_IMC_USER_DESC_MAX];
     115                 : 
     116                 :   /*
     117                 :    * One iov entry pointing to a buffer large enough to read the expected
     118                 :    * result.
     119                 :    */
     120               1 :   header.iov_length = ARRAY_SIZE(iovec);
     121               1 :   header.iov = iovec;
     122               1 :   iovec[0].base = (void*) gShortBuf;
     123               1 :   iovec[0].length = g_short_message_length;
     124                 :   /* Accept some descriptors. */
     125               1 :   header.NACL_SRPC_MESSAGE_HEADER_DESC_LENGTH = ARRAY_SIZE(descs);
     126               1 :   header.NACL_SRPC_MESSAGE_HEADER_DESCV = descs;
     127                 :   /* Clear the receive buffer. */
     128               1 :   memset(gShortBuf, 0, g_short_message_length);
     129                 :   /* Check that all of it was received. */
     130                 :   assert(NaClSrpcMessageChannelReceive(channel, &header) ==
     131               1 :          (ssize_t) g_short_message_length);
     132                 :   /* Check that the data bytes are as expected. */
     133               1 :   assert(memcmp(header.iov[0].base, gTestArray, header.iov[0].length) == 0);
     134                 :   /* Check that one descriptor was received. */
     135               1 :   assert(header.NACL_SRPC_MESSAGE_HEADER_DESC_LENGTH == 1);
     136               1 :   assert(header.flags == 0);
     137               1 : }
     138                 : 
     139                 : void PeekShortMessage(struct NaClSrpcMessageChannel* channel,
     140               1 :                       int expected_flags) {
     141                 :   NaClSrpcMessageHeader header;
     142                 :   struct NaClImcMsgIoVec iovec[1];
     143                 :   NaClSrpcMessageDesc descs[NACL_ABI_IMC_USER_DESC_MAX];
     144                 :   size_t i;
     145                 : 
     146                 :   /*
     147                 :    * One iov entry pointing to a buffer large enough to read the expected
     148                 :    * result.
     149                 :    */
     150               1 :   header.iov_length = ARRAY_SIZE(iovec);
     151               1 :   header.iov = iovec;
     152               1 :   iovec[0].base = (void*) gShortBuf;
     153               1 :   iovec[0].length = g_short_message_length;
     154                 :   /* Accept some descriptors. */
     155               1 :   header.NACL_SRPC_MESSAGE_HEADER_DESC_LENGTH = ARRAY_SIZE(descs);
     156               1 :   header.NACL_SRPC_MESSAGE_HEADER_DESCV = descs;
     157                 :   /* Clear the receive buffer. */
     158               1 :   memset(gShortBuf, 0, g_short_message_length);
     159                 :   /* Check that all of it was received. */
     160                 :   assert(NaClSrpcMessageChannelPeek(channel, &header) ==
     161               1 :          (ssize_t) g_short_message_length);
     162                 :   /* Check that the data bytes are as expected. */
     163               1 :   for (i = 0; i < header.iov[0].length / sizeof(int32_t); ++i) {
     164               1 :     assert(gShortBuf[i] == (int32_t) i);
     165               1 :   }
     166                 :   /* Check that one descriptor was received. */
     167               1 :   assert(header.NACL_SRPC_MESSAGE_HEADER_DESC_LENGTH == 1);
     168               1 :   assert(header.flags == expected_flags);
     169               1 : }
     170                 : 
     171               1 : void SendLongMessage(struct NaClSrpcMessageChannel* channel) {
     172                 :   NaClSrpcMessageHeader header;
     173                 :   struct NaClImcMsgIoVec iovec[1];
     174                 :   NaClSrpcMessageDesc descs[1];
     175                 : 
     176                 :   /* One iov entry, with enough bytes to require fragmentation. */
     177               1 :   header.iov_length = ARRAY_SIZE(iovec);
     178               1 :   header.iov = iovec;
     179               1 :   iovec[0].base = (void*) gTestArray;
     180               1 :   iovec[0].length = g_long_message_length;
     181                 :   /* One descriptor. */
     182               1 :   header.NACL_SRPC_MESSAGE_HEADER_DESC_LENGTH = ARRAY_SIZE(descs);
     183               1 :   header.NACL_SRPC_MESSAGE_HEADER_DESCV = descs;
     184               1 :   descs[0] = g_bogus_desc;
     185               1 :   assert(header.NACL_SRPC_MESSAGE_HEADER_DESC_LENGTH != 0);
     186                 :   assert(NaClSrpcMessageChannelSend(channel, &header) ==
     187               1 :          (ssize_t) g_long_message_length);
     188               1 : }
     189                 : 
     190               1 : void ReceiveLongMessage(struct NaClSrpcMessageChannel* channel) {
     191                 :   NaClSrpcMessageHeader header;
     192                 :   struct NaClImcMsgIoVec iovec[1];
     193                 :   NaClSrpcMessageDesc descs[NACL_ABI_IMC_USER_DESC_MAX];
     194                 : 
     195                 :   /*
     196                 :    * One iov entry pointing to a buffer large enough to read the expected
     197                 :    * result.
     198                 :    */
     199               1 :   header.iov_length = ARRAY_SIZE(iovec);
     200               1 :   header.iov = iovec;
     201               1 :   iovec[0].base = gLongBuf;
     202               1 :   iovec[0].length = g_long_message_length;
     203                 :   /* Accept some descriptors. */
     204               1 :   header.NACL_SRPC_MESSAGE_HEADER_DESC_LENGTH = ARRAY_SIZE(descs);
     205               1 :   header.NACL_SRPC_MESSAGE_HEADER_DESCV = descs;
     206                 :   /* Clear the receive buffer. */
     207               1 :   memset(gLongBuf, 0, g_long_message_length);
     208                 :   /* Check that all of it was received. */
     209                 :   assert(NaClSrpcMessageChannelReceive(channel, &header) ==
     210               1 :          (ssize_t) g_long_message_length);
     211                 :   /* Check that the data bytes are as expected. */
     212               1 :   assert(memcmp(header.iov[0].base, gTestArray, header.iov[0].length) == 0);
     213                 :   /* Check that one descriptor was received. */
     214               1 :   assert(header.NACL_SRPC_MESSAGE_HEADER_DESC_LENGTH == 1);
     215               1 :   assert(header.flags == 0);
     216               1 : }
     217                 : 
     218                 : void SendMessageOfLength(struct NaClSrpcMessageChannel* channel,
     219               1 :                          size_t message_bytes) {
     220                 :   NaClSrpcMessageHeader header;
     221                 :   struct NaClImcMsgIoVec iovec[1];
     222                 :   NaClSrpcMessageDesc descs[1];
     223                 : 
     224                 :   /* One iov entry, with the given number of bytes. */
     225               1 :   header.iov_length = ARRAY_SIZE(iovec);
     226               1 :   header.iov = iovec;
     227               1 :   assert(message_bytes < g_max_message_size);
     228               1 :   iovec[0].base = (void*) gTestArray;
     229               1 :   iovec[0].length = message_bytes;
     230                 :   /* One descriptor. */
     231               1 :   header.NACL_SRPC_MESSAGE_HEADER_DESC_LENGTH = ARRAY_SIZE(descs);
     232               1 :   header.NACL_SRPC_MESSAGE_HEADER_DESCV = descs;
     233               1 :   descs[0] = g_bogus_desc;
     234                 :   assert(NaClSrpcMessageChannelSend(channel, &header) ==
     235               1 :          (ssize_t) message_bytes);
     236               1 : }
     237                 : 
     238                 : void ReceiveMessageOfLength(struct NaClSrpcMessageChannel* channel,
     239               1 :                             size_t message_bytes) {
     240                 :   NaClSrpcMessageHeader header;
     241                 :   struct NaClImcMsgIoVec iovec[1];
     242                 :   NaClSrpcMessageDesc descs[NACL_ABI_IMC_USER_DESC_MAX];
     243                 : 
     244                 :   /*
     245                 :    * One iov entry pointing to a buffer large enough to read the expected
     246                 :    * result.
     247                 :    */
     248               1 :   header.iov_length = ARRAY_SIZE(iovec);
     249               1 :   header.iov = iovec;
     250               1 :   iovec[0].base = gLongBuf;
     251               1 :   iovec[0].length = message_bytes;
     252               1 :   assert(message_bytes < g_max_message_size);
     253                 :   /* Accept some descriptors. */
     254               1 :   header.NACL_SRPC_MESSAGE_HEADER_DESC_LENGTH = ARRAY_SIZE(descs);
     255               1 :   header.NACL_SRPC_MESSAGE_HEADER_DESCV = descs;
     256                 :   /* Clear the receive buffer. */
     257               1 :   memset(gLongBuf, 0, g_long_message_length);
     258                 :   /* Check that all of it was received. */
     259                 :   assert(NaClSrpcMessageChannelReceive(channel, &header) ==
     260               1 :          (ssize_t) message_bytes);
     261                 :   /* Check that the data bytes are as expected. */
     262               1 :   assert(memcmp(header.iov[0].base, gTestArray, header.iov[0].length) == 0);
     263                 :   /* Check that one descriptor was received. */
     264               1 :   assert(header.NACL_SRPC_MESSAGE_HEADER_DESC_LENGTH == 1);
     265               1 :   assert(header.flags == 0);
     266               1 : }
     267                 : 
     268               1 : void ReceiveShorterMessage(struct NaClSrpcMessageChannel* channel) {
     269                 :   NaClSrpcMessageHeader header;
     270                 :   struct NaClImcMsgIoVec iovec[1];
     271                 :   NaClSrpcMessageDesc descs[NACL_ABI_IMC_USER_DESC_MAX];
     272                 : 
     273                 :   /*
     274                 :    * One iov entry pointing to a buffer large enough to read the expected
     275                 :    * result.
     276                 :    */
     277               1 :   header.iov_length = ARRAY_SIZE(iovec);
     278               1 :   header.iov = iovec;
     279               1 :   iovec[0].base = gLongBuf;
     280               1 :   iovec[0].length = g_long_message_length / 2;
     281                 :   /* Accept some descriptors. */
     282               1 :   header.NACL_SRPC_MESSAGE_HEADER_DESC_LENGTH = ARRAY_SIZE(descs);
     283               1 :   header.NACL_SRPC_MESSAGE_HEADER_DESCV = descs;
     284                 :   /* Clear the receive buffer. */
     285               1 :   memset(gLongBuf, 0, g_long_message_length);
     286                 :   /* Check that all of it was received. */
     287                 :   assert(NaClSrpcMessageChannelReceive(channel, &header) ==
     288               1 :          (ssize_t) g_long_message_length / 2);
     289                 :   /* Check that the data bytes are as expected. */
     290               1 :   assert(memcmp(header.iov[0].base, gTestArray, header.iov[0].length) == 0);
     291                 :   /* Check that one descriptor was received. */
     292               1 :   assert(header.NACL_SRPC_MESSAGE_HEADER_DESC_LENGTH == 1);
     293               1 :   assert(header.flags == NACL_ABI_RECVMSG_DATA_TRUNCATED);
     294               1 : }
     295                 : 
     296               1 : void SendLotsOfIovs(struct NaClSrpcMessageChannel* channel) {
     297                 :   NaClSrpcMessageHeader header;
     298                 :   struct NaClImcMsgIoVec iovec[kIovEntryCount];
     299                 :   NaClSrpcMessageDesc descs[1];
     300                 :   size_t i;
     301                 : 
     302                 :   /*
     303                 :    * kIovEntryCount iov entries, each of g_long_message_iov_chunk_size.
     304                 :    * The total data payload fills gTestArray.
     305                 :    */
     306               1 :   header.iov_length = ARRAY_SIZE(iovec);
     307               1 :   header.iov = iovec;
     308               1 :   for(i = 0; i < kIovEntryCount; ++i) {
     309                 :     iovec[i].base =
     310               1 :         (void*) ((char*) gTestArray + i * g_long_message_iov_chunk_size);
     311               1 :     iovec[i].length = g_long_message_iov_chunk_size;
     312               1 :   }
     313                 :   /* And one descriptor. */
     314               1 :   header.NACL_SRPC_MESSAGE_HEADER_DESC_LENGTH = ARRAY_SIZE(descs);
     315               1 :   header.NACL_SRPC_MESSAGE_HEADER_DESCV = descs;
     316               1 :   descs[0] = g_bogus_desc;
     317                 :   /* Make sure that the entire message was sent. */
     318                 :   assert(NaClSrpcMessageChannelSend(channel, &header) ==
     319               1 :          (ssize_t) g_long_message_length);
     320               1 : }
     321                 : 
     322               1 : void ReceiveLotsOfIovs(struct NaClSrpcMessageChannel* channel) {
     323                 :   NaClSrpcMessageHeader header;
     324                 :   struct NaClImcMsgIoVec iovec[kIovEntryCount];
     325                 :   NaClSrpcMessageDesc descs[NACL_ABI_IMC_USER_DESC_MAX];
     326                 :   char* buf_chunk;
     327                 :   char* test_chunk;
     328                 :   size_t i;
     329                 : 
     330                 :   /*
     331                 :    * kIovEntryCount iov entries, each of g_long_message_iov_chunk_size.
     332                 :    * The total data payload fills gLongBuf.
     333                 :    */
     334               1 :   header.iov_length = ARRAY_SIZE(iovec);
     335               1 :   header.iov = iovec;
     336               1 :   buf_chunk = (char*) gLongBuf;
     337               1 :   for(i = 0; i < kIovEntryCount; ++i) {
     338               1 :     iovec[i].base = buf_chunk;
     339               1 :     iovec[i].length = g_long_message_iov_chunk_size;
     340               1 :     buf_chunk += iovec[i].length;
     341               1 :   }
     342                 :   /* Accept some descriptors. */
     343               1 :   header.NACL_SRPC_MESSAGE_HEADER_DESC_LENGTH = ARRAY_SIZE(descs);
     344               1 :   header.NACL_SRPC_MESSAGE_HEADER_DESCV = descs;
     345                 :   /* Clear the receive buffer. */
     346               1 :   memset(gLongBuf, 0, g_long_message_length);
     347                 :   /* Check that all of it was received. */
     348                 :   assert(NaClSrpcMessageChannelReceive(channel, &header) ==
     349               1 :          (ssize_t) g_long_message_length);
     350                 :   /* Check that the data bytes are as expected. */
     351               1 :   test_chunk = (char*) gTestArray;
     352               1 :   for(i = 0; i < kIovEntryCount; ++i) {
     353               1 :     assert(memcmp(header.iov[i].base, test_chunk, header.iov[i].length) == 0);
     354               1 :     test_chunk += header.iov[i].length;
     355               1 :   }
     356                 :   /* Check that one descriptor was received. */
     357               1 :   assert(header.NACL_SRPC_MESSAGE_HEADER_DESC_LENGTH == 1);
     358               1 :   assert(header.flags == 0);
     359               1 : }
     360                 : 
     361               1 : void SendLotsOfDescs(struct NaClSrpcMessageChannel* channel) {
     362                 :   NaClSrpcMessageHeader header;
     363                 :   NaClSrpcMessageDesc descs[kDescCount];
     364                 :   size_t i;
     365                 : 
     366                 :   /* No iov entries. */
     367               1 :   header.iov_length = 0;
     368               1 :   header.iov = 0;
     369                 :   /* kDescCount descriptors. */
     370               1 :   header.NACL_SRPC_MESSAGE_HEADER_DESC_LENGTH = kDescCount;
     371               1 :   header.NACL_SRPC_MESSAGE_HEADER_DESCV = descs;
     372               1 :   for (i = 0; i < kDescCount; ++i) {
     373               1 :     descs[i] = g_bogus_desc;
     374               1 :   }
     375                 :   /* Check that no error was returned. */
     376               1 :   assert(NaClSrpcMessageChannelSend(channel, &header) == 0);
     377               1 : }
     378                 : 
     379               1 : void ReceiveLotsOfDescs(struct NaClSrpcMessageChannel* channel) {
     380                 :   NaClSrpcMessageHeader header;
     381                 :   NaClSrpcMessageDesc descs[4 * kDescCount];
     382                 :   size_t i;
     383                 : 
     384                 :   /* No iov entries. */
     385               1 :   header.iov_length = 0;
     386               1 :   header.iov = 0;
     387                 :   /* Accept descriptors than we expect to get. */
     388               1 :   header.NACL_SRPC_MESSAGE_HEADER_DESC_LENGTH = ARRAY_SIZE(descs);
     389               1 :   header.NACL_SRPC_MESSAGE_HEADER_DESCV = descs;
     390                 :   /* Clear the receive descriptor array. */
     391               1 :   memset(descs, 0, sizeof descs);
     392                 :   /* Make sure there were no errors. */
     393               1 :   assert(NaClSrpcMessageChannelReceive(channel, &header) == 0);
     394                 :   /*
     395                 :    * Check that the right number of descriptors was passed and that they have
     396                 :    * the correct value.
     397                 :    */
     398               1 :   assert(header.NACL_SRPC_MESSAGE_HEADER_DESC_LENGTH == kDescCount);
     399               1 :   for (i = 0; i < kDescCount; ++i) {
     400               1 :     assert(descs[i] == g_bogus_desc);
     401               1 :   }
     402               1 :   assert(header.flags == 0);
     403               1 : }
     404                 : 
     405               1 : void ReceiveFewerDescs(struct NaClSrpcMessageChannel* channel) {
     406                 :   NaClSrpcMessageHeader header;
     407                 :   NaClSrpcMessageDesc descs[kDescCount / 2];
     408                 :   size_t i;
     409                 : 
     410                 :   /* No iov entries. */
     411               1 :   header.iov_length = 0;
     412               1 :   header.iov = 0;
     413                 :   /* Accept descriptors than we expect to get. */
     414               1 :   header.NACL_SRPC_MESSAGE_HEADER_DESC_LENGTH = ARRAY_SIZE(descs);
     415               1 :   header.NACL_SRPC_MESSAGE_HEADER_DESCV = descs;
     416                 :   /* Clear the receive descriptor array. */
     417               1 :   memset(descs, 0, sizeof descs);
     418                 :   /* Make sure there were no errors. */
     419               1 :   assert(NaClSrpcMessageChannelReceive(channel, &header) == 0);
     420                 :   /*
     421                 :    * Check that the right number of descriptors was passed and that they have
     422                 :    * the correct value.
     423                 :    */
     424               1 :   assert(header.NACL_SRPC_MESSAGE_HEADER_DESC_LENGTH == ARRAY_SIZE(descs));
     425               1 :   for (i = 0; i < ARRAY_SIZE(descs); ++i) {
     426               1 :     assert(descs[i] == g_bogus_desc);
     427               1 :   }
     428               1 :   assert(header.flags == NACL_ABI_RECVMSG_DESC_TRUNCATED);
     429               1 : }
     430                 : 
     431               1 : void InitArrays(size_t large_array_size) {
     432                 :   /* Round up to a multiple of sizeof(int32_t). */
     433                 :   size_t long_size =
     434               1 :       (large_array_size + sizeof(int32_t) - 1) & ~(sizeof(int32_t) - 1);
     435                 :   size_t short_size =
     436               1 :       ((large_array_size / 2) + sizeof(int32_t) - 1) & ~(sizeof(int32_t) - 1);
     437                 :   size_t i;
     438                 :   /*
     439                 :    * An array filled with monotonically increasing values.  Used to check
     440                 :    * payload sanity.
     441                 :    */
     442               1 :   gTestArray = (int32_t*) malloc(long_size);
     443               1 :   assert(gTestArray != NULL);
     444               1 :   for (i = 0; i < long_size / sizeof(int32_t); ++i) {
     445               1 :     gTestArray[i] = (int32_t) i;
     446               1 :   }
     447                 :   /* Large buffer used for receiving messages. */
     448               1 :   gLongBuf = (int32_t*) malloc(long_size);
     449               1 :   assert(gLongBuf != NULL);
     450                 :   /* Small buffer used for receiving messages. */
     451               1 :   gShortBuf = (int32_t*) malloc(short_size);
     452               1 :   assert(gShortBuf != NULL);
     453               1 : }
     454                 : 
     455                 : NaClSrpcMessageDesc g_bound_sock_pair[2];
     456                 : /* Forward declarations. */
     457                 : static NaClSrpcMessageDesc Connect(void);
     458                 : static NaClSrpcMessageDesc Accept(void);
     459                 : 
     460               1 : static void Sender(void) {
     461                 :   size_t msg_len;
     462                 :   size_t fragments;
     463                 :   size_t max_fragment_count;
     464                 :   struct NaClSrpcMessageChannel* send_channel =
     465               1 :       NaClSrpcMessageChannelNew(Connect());
     466               1 :   assert(send_channel != NULL);
     467                 :   /*
     468                 :    * Test values within g_message_delta of n * g_max_fragment_count on
     469                 :    * either side.  Tests for header sizes and boundary cases.
     470                 :    * If g_max_message_size == g_message_delta / 2, this will cover all
     471                 :    * values from 0 to g_max_message_size.
     472                 :    */
     473               1 :   max_fragment_count = g_max_message_size / g_fragment_bytes;
     474               1 :   for (fragments = 0; fragments <= max_fragment_count; ++fragments) {
     475                 :     size_t lower =
     476               1 :         MAX((fragments * g_fragment_bytes) - g_message_delta, 0);
     477                 :     size_t upper =
     478                 :         MIN((fragments * g_fragment_bytes) + g_message_delta,
     479               1 :             g_max_message_size);
     480               1 :     for (msg_len = lower; msg_len < upper; ++msg_len) {
     481               1 :       SendMessageOfLength(send_channel, msg_len);
     482               1 :     }
     483               1 :   }
     484                 :   /* Test send/receive of message that fits in one message. */
     485               1 :   SendShortMessage(send_channel);
     486                 :   /* Test send/receive of message that requires multiple messages. */
     487               1 :   SendLongMessage(send_channel);
     488                 :   /* Test that fragmentation sets data truncated flag. */
     489               1 :   SendLongMessage(send_channel);
     490                 :   /* Test send with lots of iov entries that equals one long send. */
     491               1 :   SendLotsOfIovs(send_channel);
     492                 :   /* Test receive with lots of iov entries that equals one long receive. */
     493               1 :   SendLongMessage(send_channel);
     494                 :   /* Test fragmentation of large numbers of descriptors. */
     495               1 :   SendLotsOfDescs(send_channel);
     496                 :   /* Test that fragmentation sets descriptor truncated flag. */
     497               1 :   SendLotsOfDescs(send_channel);
     498                 :   /* Clean up the channel. */
     499               1 :   NaClSrpcMessageChannelDelete(send_channel);
     500               1 : }
     501                 : 
     502               1 : static void Receiver(void* arg) {
     503                 :   size_t msg_len;
     504                 :   size_t fragments;
     505                 :   size_t max_fragment_count;
     506                 :   struct NaClSrpcMessageChannel* recv_channel =
     507               1 :       NaClSrpcMessageChannelNew(Accept());
     508               1 :   assert(recv_channel != NULL);
     509                 : 
     510                 : #if !defined(__native_client__)
     511                 :   UNREFERENCED_PARAMETER(arg);
     512                 : #endif
     513                 :   /*
     514                 :    * Test values within g_message_delta of n * g_max_fragment_count on
     515                 :    * either side.  Tests for header sizes and boundary cases.
     516                 :    * If g_max_message_size == g_message_delta / 2, this will cover all
     517                 :    * values from 0 to g_max_message_size.
     518                 :    */
     519               1 :   max_fragment_count = g_max_message_size / g_fragment_bytes;
     520               1 :   for (fragments = 0; fragments <= max_fragment_count; ++fragments) {
     521                 :     size_t lower =
     522               1 :         MAX((fragments * g_fragment_bytes) - g_message_delta, 0);
     523                 :     size_t upper =
     524                 :         MIN((fragments * g_fragment_bytes) + g_message_delta,
     525               1 :             g_max_message_size);
     526               1 :     for (msg_len = lower; msg_len < upper; ++msg_len) {
     527               1 :       ReceiveMessageOfLength(recv_channel, msg_len);
     528               1 :     }
     529               1 :   }
     530                 :   /* Test send/receive of message that fits in one message. */
     531               1 :   PeekShortMessage(recv_channel, 0);
     532               1 :   ReceiveShortMessage(recv_channel);
     533                 :   /* Test send/receive of message that requires multiple messages. */
     534               1 :   PeekShortMessage(recv_channel, NACL_ABI_RECVMSG_DATA_TRUNCATED);
     535               1 :   ReceiveLongMessage(recv_channel);
     536                 :   /* Test that fragmentation sets data truncated flag. */
     537               1 :   ReceiveShorterMessage(recv_channel);
     538                 :   /* Test send with lots of iov entries that equals one long send. */
     539               1 :   ReceiveLongMessage(recv_channel);
     540                 :   /* Test receive with lots of iov entries that equals one long receive. */
     541               1 :   ReceiveLotsOfIovs(recv_channel);
     542                 :   /* Test fragmentation of large numbers of descriptors. */
     543               1 :   ReceiveLotsOfDescs(recv_channel);
     544                 :   /* Test that fragmentation sets descriptor truncated flag. */
     545               1 :   ReceiveFewerDescs(recv_channel);
     546                 :   /* Clean up the channel. */
     547               1 :   NaClSrpcMessageChannelDelete(recv_channel);
     548               1 : }
     549                 : 
     550                 : #if defined(__native_client__)
     551                 : static int InitBoundSock(void) {
     552                 :   return (imc_makeboundsock(g_bound_sock_pair) == 0);
     553                 : }
     554                 : 
     555                 : static int RunTests(void) {
     556                 :   pthread_t recv_thread;
     557                 :   void* result;
     558                 :   void* (*fp)(void* arg) = (void *(*)(void*)) Receiver;
     559                 :   if (pthread_create(&recv_thread, NULL, fp, NULL) != 0) {
     560                 :     return 0;
     561                 :   }
     562                 :   /* Send a bunch of messages. */
     563                 :   Sender();
     564                 :   /* Close down the receive thread. */
     565                 :   pthread_join(recv_thread, &result);
     566                 :   return 1;
     567                 : }
     568                 : 
     569                 : static NaClSrpcMessageDesc Connect(void) {
     570                 :   NaClSrpcMessageDesc desc = imc_connect(g_bound_sock_pair[1]);
     571                 :   assert(desc != -1);
     572                 :   return desc;
     573                 : }
     574                 : 
     575                 : static NaClSrpcMessageDesc Accept(void) {
     576                 :   NaClSrpcMessageDesc desc = imc_accept(g_bound_sock_pair[0]);
     577                 :   assert(desc != -1);
     578                 :   return desc;
     579                 : }
     580                 : 
     581                 : #else
     582                 : 
     583               1 : static int InitBoundSock(void) {
     584               1 :   return (NaClCommonDescMakeBoundSock(g_bound_sock_pair) == 0);
     585               1 : }
     586                 : 
     587               1 : static int RunTests(void) {
     588                 :   struct NaClThread recv_thread;
     589               1 :   void (WINAPI *fp)(void* arg) = (void (WINAPI *)(void*)) Receiver;
     590               1 :   if (NaClThreadCreateJoinable(&recv_thread, fp, NULL, 1024 * 1024) == 0) {
     591               0 :     return 0;
     592                 :   }
     593                 :   /* Send a bunch of messages. */
     594               1 :   Sender();
     595                 :   /* Close down the receive thread. */
     596               1 :   NaClThreadJoin(&recv_thread);
     597               1 :   return 1;
     598               1 : }
     599                 : 
     600               1 : static NaClSrpcMessageDesc Connect(void) {
     601                 :   NaClSrpcMessageDesc desc;
     602                 :   int result =
     603                 :       (*NACL_VTBL(NaClDesc, g_bound_sock_pair[1])->ConnectAddr)(
     604               1 :           g_bound_sock_pair[1], &desc);
     605               1 :   assert(result == 0);
     606               1 :   return desc;
     607               1 : }
     608                 : 
     609               1 : static NaClSrpcMessageDesc Accept(void) {
     610                 :   NaClSrpcMessageDesc desc;
     611                 :   int result =
     612                 :       (*NACL_VTBL(NaClDesc, g_bound_sock_pair[0])->AcceptConn)(
     613               1 :           g_bound_sock_pair[0], &desc);
     614               1 :   assert(result == 0);
     615               1 :   return desc;
     616               1 : }
     617                 : #endif
     618                 : 
     619               1 : int main(int argc, char* argv[]) {
     620               1 :   if (argc < 4) {
     621               0 :     fprintf(stderr, "usage: srpc_message max_msg_sz frag_sz delta\n");
     622               0 :     return 1;
     623                 :   }
     624               1 :   g_max_message_size = atoi(argv[1]);
     625               1 :   g_fragment_bytes = atoi(argv[2]);
     626               1 :   g_message_delta = atoi(argv[3]);
     627                 : 
     628               1 :   g_short_message_length = g_fragment_bytes / 2;
     629               1 :   g_long_message_length = 4 * g_fragment_bytes;
     630               1 :   g_long_message_iov_chunk_size = g_long_message_length / kIovEntryCount;
     631                 : 
     632                 : #if defined(__native_client__)
     633                 :   assert(NaClSrpcModuleInit());
     634                 :   g_bogus_desc = (NaClSrpcMessageDesc) -1;
     635                 : #else
     636               1 :   NaClPlatformInit();
     637               1 :   NaClNrdAllModulesInit();
     638               1 :   NaClSrpcModuleInit();
     639               1 :   g_bogus_desc = (NaClSrpcMessageDesc) NaClDescInvalidMake();
     640                 : #endif
     641                 :   /* Create the bound socket / socket address pair used to connect. */
     642               1 :   assert(InitBoundSock());
     643                 :   /* Set up arrays for sending/receiving messages. */
     644               1 :   InitArrays(g_max_message_size + g_message_delta + sizeof(int32_t));
     645               1 :   assert(RunTests());
     646               1 :   NaClSrpcModuleFini();
     647               1 :   return 0;
     648               1 : }

Generated by: LCOV version 1.7