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

Generated by: LCOV version 1.7