LCOV - code coverage report
Current view: directory - src/trusted/debug_stub - session_test.cc (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 141 101 71.6 %
Date: 2014-09-25 Functions: 0 0 -

       1                 : /*
       2                 :  * Copyright (c) 2010 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                 : #include <assert.h>
       8                 : #include <stdio.h>
       9                 : #include <stdlib.h>
      10                 : #include <string.h>
      11                 : 
      12                 : #include <string>
      13                 : #include <sstream>
      14                 : #include <vector>
      15                 : 
      16                 : #include "native_client/src/trusted/debug_stub/platform.h"
      17                 : #include "native_client/src/trusted/debug_stub/session.h"
      18                 : #include "native_client/src/trusted/debug_stub/test.h"
      19                 : 
      20                 : using gdb_rsp::Session;
      21                 : using gdb_rsp::Packet;
      22                 : 
      23                 : // Transport simulation class, this stores data and a r/w index
      24                 : // to simulate one direction of a pipe, or a pipe to self.
      25                 : class SharedVector {
      26                 :  public:
      27               1 :   SharedVector() : rd(0), wr(0) {}
      28                 : 
      29                 :  public:
      30                 :   std::vector<char> data;
      31                 :   volatile uint32_t rd;
      32                 :   volatile uint32_t wr;
      33                 : };
      34                 : 
      35                 : // Simulates a transport (such as a socket), the reports "ready"
      36                 : // when polled, but fails on TX/RX.
      37                 : class DCSocketTransport : public port::ITransport {
      38                 :  public:
      39               1 :   virtual bool Read(void *ptr, int32_t len) {
      40                 :     (void) ptr;
      41                 :     (void) len;
      42               1 :     return false;
      43               1 :   }
      44                 : 
      45               0 :   virtual bool Write(const void *ptr, int32_t len) {
      46                 :     (void) ptr;
      47                 :     (void) len;
      48               0 :     return false;
      49               0 :   }
      50                 : 
      51               0 :   virtual bool IsDataAvailable() {
      52               0 :     return true;
      53               0 :   }
      54                 : 
      55                 :   virtual void WaitForDebugStubEvent(struct NaClApp *nap,
      56               0 :                                      bool ignore_gdb) {
      57                 :     UNREFERENCED_PARAMETER(nap);
      58                 :     UNREFERENCED_PARAMETER(ignore_gdb);
      59               0 :   }
      60                 : 
      61               1 :   virtual void Disconnect() {}
      62                 : };
      63                 : 
      64                 : 
      65                 : // Simulate a transport transmitting data Q'd in TX and verifying that
      66                 : // inbound data matches expected "golden" string.
      67                 : class GoldenTransport : public DCSocketTransport {
      68                 :  public:
      69               1 :   GoldenTransport(const char *rx, const char *tx, int cnt) {
      70               1 :     rx_ = rx;
      71               1 :     tx_ = tx;
      72               1 :     cnt_ = cnt;
      73               1 :     txCnt_ = 0;
      74               1 :     rxCnt_ = 0;
      75               1 :     errs_ = 0;
      76               1 :     disconnected_ = false;
      77               1 :   }
      78                 : 
      79               1 :   virtual bool Read(void *ptr, int32_t len) {
      80               1 :     if (disconnected_) return false;
      81               1 :     memcpy(ptr, &rx_[rxCnt_], len);
      82               1 :     rxCnt_ += len;
      83               1 :     if (static_cast<int>(strlen(rx_)) < rxCnt_) {
      84               0 :       printf("End of RX\n");
      85               0 :       errs_++;
      86                 :     }
      87               1 :     return true;
      88               1 :   }
      89                 : 
      90                 :   //  Read from this link, return a negative value if there is an error
      91               1 :   virtual bool Write(const void *ptr, int32_t len) {
      92               1 :     const char *str = reinterpret_cast<const char *>(ptr);
      93               1 :     if (disconnected_) return false;
      94               1 :     if (strncmp(str, &tx_[txCnt_], len) != 0) {
      95               0 :       printf("TX mismatch in %s vs %s.\n", str, &tx_[txCnt_]);
      96               0 :       errs_++;
      97                 :     }
      98               1 :     txCnt_ += len;
      99               1 :     return true;
     100               1 :   }
     101                 : 
     102               0 :   virtual bool IsDataAvailable() {
     103               0 :     if (disconnected_) return true;
     104                 : 
     105               0 :     return rxCnt_ < static_cast<int>(strlen(rx_));
     106               0 :   }
     107                 : 
     108               1 :   virtual void Disconnect() {
     109               1 :     disconnected_ = true;
     110               1 :   }
     111                 : 
     112               1 :   int errs() { return errs_; }
     113                 : 
     114                 : 
     115                 :  protected:
     116                 :   const char *rx_;
     117                 :   const char *tx_;
     118                 :   int cnt_;
     119                 :   int rxCnt_;
     120                 :   int txCnt_;
     121                 :   int errs_;
     122                 :   bool disconnected_;
     123                 : };
     124                 : 
     125                 : 
     126                 : class TestTransport : public DCSocketTransport {
     127                 :  public:
     128               1 :   TestTransport(SharedVector *rvec, SharedVector *wvec) {
     129               1 :     rvector_ = rvec;
     130               1 :     wvector_ = wvec;
     131               1 :     disconnected_ = false;
     132               1 :   }
     133                 : 
     134               1 :   virtual bool Read(void *ptr, int32_t len) {
     135               1 :     if (disconnected_) return false;
     136                 : 
     137               1 :     int max = rvector_->wr - rvector_->rd;
     138               1 :     if (max > len) {
     139               1 :       max = len;
     140               1 :     } else {
     141               1 :       return false;
     142                 :     }
     143                 : 
     144               1 :     if (max > 0) {
     145               1 :       char *src = &rvector_->data[rvector_->rd];
     146               1 :       memcpy(ptr, src, max);
     147                 :     }
     148               1 :     rvector_->rd += max;
     149               1 :     return true;
     150               1 :   }
     151                 : 
     152               1 :   virtual bool Write(const void *ptr, int32_t len) {
     153               1 :     if (disconnected_) return false;
     154                 : 
     155               1 :     wvector_->data.resize(wvector_->wr + len);
     156               1 :     memcpy(&wvector_->data[wvector_->wr], ptr, len);
     157               1 :     wvector_->wr += len;
     158               1 :     return true;
     159               1 :   }
     160                 : 
     161               0 :   virtual bool IsDataAvailable() {
     162               0 :     if (disconnected_) return true;
     163                 : 
     164               0 :     return rvector_->rd < rvector_->wr;
     165               0 :   }
     166                 : 
     167               1 :   virtual void Disconnect() {
     168               1 :     disconnected_ = true;
     169               1 :   }
     170                 : 
     171                 :  protected:
     172                 :   SharedVector *rvector_;
     173                 :   SharedVector *wvector_;
     174                 :   bool disconnected_;
     175                 : };
     176                 : 
     177                 : 
     178               1 : int TestSession() {
     179               1 :   int errs = 0;
     180               1 :   Packet pktOut;
     181               1 :   Packet pktIn;
     182               1 :   SharedVector vec;
     183                 : 
     184                 :   // Create a "loopback" session by using the same
     185                 :   // FIFO for ingress and egress.
     186               1 :   Session cli(new TestTransport(&vec, &vec));
     187               1 :   Session srv(new TestTransport(&vec, &vec));
     188                 : 
     189                 :   // Check, Set,Clear,Get flags.
     190               1 :   cli.ClearFlags(static_cast<uint32_t>(-1));
     191               1 :   cli.SetFlags(Session::IGNORE_ACK | Session::DEBUG_RECV);
     192               1 :   if (cli.GetFlags() != (Session::IGNORE_ACK + Session::DEBUG_RECV)) {
     193               0 :     printf("SetFlag failed.\n");
     194               0 :     errs++;
     195                 :   }
     196               1 :   cli.ClearFlags(Session::IGNORE_ACK | Session::DEBUG_SEND);
     197               1 :   if (cli.GetFlags() != Session::DEBUG_RECV) {
     198               0 :     printf("ClearFlag failed.\n");
     199               0 :     errs++;
     200                 :   }
     201                 : 
     202                 :   // Check Send Packet of known value.
     203               1 :   const char *str = "1234";
     204                 : 
     205               1 :   pktOut.AddString(str);
     206               1 :   cli.SendPacketOnly(&pktOut);
     207               1 :   srv.GetPacket(&pktIn);
     208               1 :   std::string out;
     209               1 :   pktIn.GetString(&out);
     210               1 :   if (out != str) {
     211               0 :     printf("Send Only failed.\n");
     212               0 :     errs++;
     213                 :   }
     214                 : 
     215                 :   // Check send against golden transactions
     216               1 :   const char tx[] = { "$1234#ca+" };
     217               1 :   const char rx[] = { "+$OK#9a" };
     218               1 :   GoldenTransport gold(rx, tx, 2);
     219               1 :   Session uni(&gold);
     220                 : 
     221               1 :   pktOut.Clear();
     222               1 :   pktOut.AddString(str);
     223               1 :   if (!uni.SendPacket(&pktOut)) {
     224               0 :     printf("Send failed.\n");
     225               0 :     errs++;
     226                 :   }
     227               1 :   if (!uni.GetPacket(&pktIn)) {
     228               0 :     printf("Get failed.\n");
     229               0 :     errs++;
     230                 :   }
     231               1 :   pktIn.GetString(&out);
     232               1 :   if (out != "OK") {
     233               0 :     printf("Send/Get failed.\n");
     234               0 :     errs++;
     235                 :   }
     236                 : 
     237                 :   // Check that a closed Transport reports to session
     238               1 :   if (!uni.Connected()) {
     239               0 :     printf("Expecting uni to be connected.\n");
     240               0 :     errs++;
     241                 :   }
     242               1 :   gold.Disconnect();
     243               1 :   uni.GetPacket(&pktIn);
     244               1 :   if (uni.Connected()) {
     245               0 :     printf("Expecting uni to be disconnected.\n");
     246               0 :     errs++;
     247                 :   }
     248                 : 
     249                 :   // Check that a failed read/write reports DC
     250               1 :   DCSocketTransport dctrans;
     251               1 :   Session dctest(&dctrans);
     252               1 :   if (!dctest.Connected()) {
     253               0 :     printf("Expecting dctest to be connected.\n");
     254               0 :     errs++;
     255                 :   }
     256               1 :   dctest.GetPacket(&pktIn);
     257               1 :   if (dctest.Connected()) {
     258               0 :     printf("Expecting dctest to be disconnected.\n");
     259               0 :     errs++;
     260                 :   }
     261                 : 
     262               1 :   errs += gold.errs();
     263               1 :   return errs;
     264               1 : }
     265                 : 

Generated by: LCOV version 1.7