LCOV - code coverage report
Current view: directory - src/trusted/gdb_rsp - session_test.cc (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 150 113 75.3 %
Date: 2012-02-16 Functions: 0 0 -

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

Generated by: LCOV version 1.7