LCOV - code coverage report
Current view: top level - io_errors_pointers - io_errors.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 52 64 81.2 %
Date: 2023-02-14 20:10:26 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /* Simulate IO errors after each byte in a stream.
       2             :  * Verifies proper error propagation.
       3             :  */
       4             : 
       5             : #include <stdio.h>
       6             : #include <pb_decode.h>
       7             : #include <pb_encode.h>
       8             : #include "alltypes.pb.h"
       9             : #include "test_helpers.h"
      10             : 
      11             : typedef struct
      12             : {
      13             :     uint8_t *buffer;
      14             :     size_t fail_after;
      15             : } faulty_stream_t;
      16             : 
      17      149472 : bool read_callback(pb_istream_t *stream, uint8_t *buf, size_t count)
      18             : {
      19      149472 :     faulty_stream_t *state = stream->state;
      20             :     
      21      390637 :     while (count--)
      22             :     {
      23      242283 :         if (state->fail_after == 0)
      24        1118 :             PB_RETURN_ERROR(stream, "simulated");
      25      241165 :         state->fail_after--;
      26      241165 :         *buf++ = *state->buffer++;
      27             :     }
      28             :     
      29      148354 :     return true;
      30             : }
      31       99370 : bool write_callback(pb_ostream_t *stream, const uint8_t *buf, size_t count)
      32             : {
      33       99370 :     faulty_stream_t *state = stream->state;
      34             :     
      35      340535 :     while (count--)
      36             :     {
      37      241859 :         if (state->fail_after == 0)
      38         694 :             PB_RETURN_ERROR(stream, "simulated");
      39      241165 :         state->fail_after--;
      40      241165 :         *state->buffer++ = *buf++;
      41             :     }
      42             :     
      43       98676 :     return true;
      44             : }
      45             : 
      46           1 : int main()
      47             : {
      48             :     uint8_t buffer[2048];
      49             :     size_t msglen;
      50           1 :     AllTypes msg = AllTypes_init_zero;
      51             :     
      52             :     /* Get some base data to run the tests with */
      53             :     SET_BINARY_MODE(stdin);
      54           1 :     msglen = fread(buffer, 1, sizeof(buffer), stdin);
      55             :     
      56             :     /* Test IO errors on decoding */
      57             :     {
      58             :         bool status;
      59           1 :         pb_istream_t stream = {&read_callback, NULL, SIZE_MAX};
      60             :         faulty_stream_t fs;
      61             :         size_t i;
      62             :         
      63         695 :         for (i = 0; i < msglen; i++)
      64             :         {
      65         694 :             stream.bytes_left = msglen;
      66         694 :             stream.state = &fs;
      67         694 :             fs.buffer = buffer;
      68         694 :             fs.fail_after = i;
      69             : 
      70         694 :             status = pb_decode(&stream, AllTypes_fields, &msg);
      71         694 :             if (status != false)
      72             :             {
      73           0 :                 fprintf(stderr, "Unexpected success in decode\n");
      74           0 :                 return 2;
      75             :             }
      76         694 :             else if (strcmp(stream.errmsg, "simulated") != 0)
      77             :             {
      78           0 :                 fprintf(stderr, "Wrong error in decode: %s\n", stream.errmsg);
      79           0 :                 return 3;
      80             :             }
      81             :         }
      82             :         
      83           1 :         stream.bytes_left = msglen;
      84           1 :         stream.state = &fs;
      85           1 :         fs.buffer = buffer;
      86           1 :         fs.fail_after = msglen;
      87           1 :         status = pb_decode(&stream, AllTypes_fields, &msg);
      88             :         
      89           1 :         if (!status)
      90             :         {
      91           0 :             fprintf(stderr, "Decoding failed: %s\n", stream.errmsg);
      92           0 :             return 4;
      93             :         }
      94             :     }
      95             :     
      96             :     /* Test IO errors on encoding */
      97             :     {
      98             :         bool status;
      99           1 :         pb_ostream_t stream = {&write_callback, NULL, SIZE_MAX, 0};
     100             :         faulty_stream_t fs;
     101             :         size_t i;
     102             :         
     103         695 :         for (i = 0; i < msglen; i++)
     104             :         {
     105         694 :             stream.max_size = msglen;
     106         694 :             stream.bytes_written = 0;
     107         694 :             stream.state = &fs;
     108         694 :             fs.buffer = buffer;
     109         694 :             fs.fail_after = i;
     110             : 
     111         694 :             status = pb_encode(&stream, AllTypes_fields, &msg);
     112         694 :             if (status != false)
     113             :             {
     114           0 :                 fprintf(stderr, "Unexpected success in encode\n");
     115           0 :                 return 5;
     116             :             }
     117         694 :             else if (strcmp(stream.errmsg, "simulated") != 0)
     118             :             {
     119           0 :                 fprintf(stderr, "Wrong error in encode: %s\n", stream.errmsg);
     120           0 :                 return 6;
     121             :             }
     122             :         }
     123             :         
     124           1 :         stream.max_size = msglen;
     125           1 :         stream.bytes_written = 0;
     126           1 :         stream.state = &fs;
     127           1 :         fs.buffer = buffer;
     128           1 :         fs.fail_after = msglen;
     129           1 :         status = pb_encode(&stream, AllTypes_fields, &msg);
     130             :         
     131           1 :         if (!status)
     132             :         {
     133           0 :             fprintf(stderr, "Encoding failed: %s\n", stream.errmsg);
     134           0 :             return 7;
     135             :         }
     136             :     }
     137             : 
     138           1 :     return 0;   
     139             : }
     140             : 

Generated by: LCOV version 1.14