LCOV - code coverage report
Current view: top level - tests/aux - write_buffer_test.cpp (source / functions) Hit Total Coverage
Test: iow-coverage.info Lines: 113 188 60.1 %
Date: 2019-09-16 Functions: 31 33 93.9 %

          Line data    Source code
       1             : #include <iostream>
       2             : #include <iow/io/aux/write_buffer.hpp>
       3             : #include <fas/testing.hpp>
       4             : #include <algorithm>
       5             : #include <cstring>
       6             : 
       7             : typedef ::iow::io::data_type data_type;
       8             : typedef ::iow::io::data_ptr  data_ptr;
       9             : 
      10             : struct _data_line_;
      11             : struct _generator_;
      12             : struct _init_line_;
      13             : 
      14             : struct _data_size_;
      15             : struct _data_line_init_;
      16             : struct _test_options_;
      17             : 
      18          34 : struct data_line_test_options: iow::io::write_buffer_options
      19             : {
      20             :   size_t data_size;
      21             :   size_t data_count;
      22             : };
      23             : 
      24             : data_line_test_options getopt(size_t bufsize, size_t maxbuf, size_t minbuf, bool  first_as_is, size_t data_size, size_t data_count);
      25             : 
      26           6 : data_line_test_options getopt(
      27             :   size_t bufsize,
      28             :   size_t maxbuf, 
      29             :   size_t minbuf, 
      30             :   //size_t wrnsize,
      31             :   //size_t maxsize,
      32             :   bool  first_as_is,
      33             :   size_t data_size,
      34             :   size_t data_count
      35             : )
      36             : {
      37           6 :   data_line_test_options dlto;
      38           6 :   dlto.bufsize = bufsize;
      39           6 :   dlto.maxbuf = maxbuf; 
      40           6 :   dlto.minbuf = minbuf;
      41           6 :   dlto.sep="";
      42             :   // dlto.wrnsize = wrnsize;
      43             :   //dlto.maxsize = maxsize;
      44           6 :   dlto.first_as_is = first_as_is;
      45           6 :   dlto.data_size = data_size;
      46           6 :   dlto.data_count = data_count;
      47           6 :   return dlto;
      48             : }
      49             : 
      50           2 : struct generator
      51             : {
      52             :   template<typename T>
      53           0 :   data_ptr operator()(T&, size_t offset, size_t size) 
      54             :   {
      55             :     //typedef typename T::aspect::template advice_cast<_data_line_>::type data_line_t;
      56             :         
      57           0 :     data_ptr d = std::make_unique<data_type>();
      58           0 :     for ( size_t j = offset; j < offset + size; j++)
      59           0 :       d->push_back( static_cast<char>('A'+j%10) );
      60             :     
      61           0 :     return d;
      62             :   }
      63             : };
      64             : 
      65             : template<typename T>
      66           0 : data_ptr generate(T& t, size_t offset, size_t size)
      67             : {
      68           0 :   return t.get_aspect().template get<_generator_>()(t, offset, size);
      69             : }
      70             : 
      71           2 : struct init_line
      72             : {
      73             :   template<typename T>
      74           7 :   void operator()(T& t)
      75             :   {
      76             :     using namespace fas::testing;
      77           7 :     auto& data_line = t.get_aspect().template get<_data_line_>();
      78             :     //typedef typename std::remove_reference<decltype(data_line)>::type data_line_t;
      79             :     
      80             : 
      81           7 :     auto opt = t.get_aspect().template get<_test_options_>();
      82           7 :     data_line.clear();
      83           7 :     data_line.set_options( *opt );
      84          14 :     data_ptr first;
      85           7 :     for (size_t i = 0; i < opt->data_count; i++ )
      86             :     {
      87             :       //t << message("generate: ") << i;
      88           0 :       data_ptr d = t.get_aspect().template get<_generator_>()( t, i, opt->data_size );
      89           0 :       data_line.attach( std::move(d) );
      90           7 :     }
      91           7 :   }
      92             : };
      93             : 
      94          11 : UNIT(init_test, "")
      95             : {
      96             :   using namespace fas::testing;
      97             :   
      98             :   
      99           7 :   auto test_opt = std::make_shared<data_line_test_options>();
     100           7 :   t.get_aspect().template get<_test_options_>() = test_opt;
     101           7 :   t.get_aspect().template get<_init_line_>()(t);
     102             : 
     103           7 :   auto& data_line = t.get_aspect().template get<_data_line_>();
     104             :   typedef typename std::remove_reference<decltype(data_line)>::type data_line_t;
     105           7 :   data_line.set_options(*test_opt);
     106          14 :   typename data_line_t::options_type dl_opt;
     107           7 :   data_line.get_options(dl_opt);
     108             :   
     109             :   /*
     110             :   const char* buf1 = reinterpret_cast<const char*>( &*test_opt);
     111             :   const char* buf2 = reinterpret_cast<const char*>( &dl_opt );
     112             :   
     113             :   int cmpres = std::memcmp( buf1,  buf2, sizeof(dl_opt) );
     114             :   bool opt_test = ( 0 ==  cmpres) ;
     115             :   t << is_true<assert>( opt_test ) << FAS_TESTING_FILE_LINE;
     116             :   t << stop;
     117             :   */
     118             : 
     119           7 :   size_t linesize = data_line.size();
     120           7 :   size_t testsize = test_opt->data_size * test_opt->data_count;
     121           7 :   t << is_true<assert>( linesize == testsize ) << " " << linesize << "!=" << testsize << ":" << FAS_TESTING_FILE_LINE;
     122             :   
     123           7 :   linesize = 0;
     124           7 :   size_t linecount = 0;
     125           7 :   size_t initcount = data_line.count();
     126           7 :   auto d = data_line.next();
     127             :   
     128          14 :   while ( d.first != nullptr )
     129             :   {
     130           0 :     linesize += d.second;
     131           0 :     data_line.confirm(d);
     132           0 :     if ( data_line.offset()==0 )
     133           0 :       ++linecount;
     134             : 
     135           0 :     t << equal<assert>( data_line.size()  + linesize,  testsize  ) << data_line.size()  + linesize << "!=" << testsize << FAS_TESTING_FILE_LINE;
     136           0 :     t << equal<assert>( data_line.count() + linecount, initcount ) << data_line.count() + linecount<< "!=" << initcount << FAS_TESTING_FILE_LINE;
     137           0 :     t << stop;
     138           0 :     d = data_line.next();
     139             :   }
     140           7 :   t << equal<assert, size_t>( data_line.size(),  0 ) << data_line.size() << FAS_TESTING_FILE_LINE;
     141          14 :   t << equal<assert, size_t>( data_line.count(), 0 ) << data_line.count() << FAS_TESTING_FILE_LINE;
     142           7 : }
     143             : 
     144          11 : UNIT(nobuf_test, "non-buffering mode")
     145             : {
     146             :   using namespace fas::testing;
     147           7 :   auto& data_line = t.get_aspect().template get<_data_line_>();
     148             :   typedef typename std::remove_reference<decltype(data_line)>::type data_line_t;
     149           7 :   auto test_opt = t.get_aspect().template get<_test_options_>();
     150             :     
     151           7 :   data_line.clear();
     152           7 :   data_line.set_options( *test_opt);
     153          14 :   typename data_line_t::options_type dl_opt;
     154           7 :   data_line.get_options(dl_opt);
     155             :   //auto dl_opt = data_line.get_options();
     156             : 
     157           7 :   size_t maxbuf = dl_opt.maxbuf;
     158           7 :   size_t cursize = 1;
     159           7 :   for (size_t c = 0; c < test_opt->data_count; ++c)
     160             :   {
     161           0 :     auto d1 = generate(t, c, cursize);
     162           0 :     auto d2 = generate(t, c, cursize);
     163           0 :     data_line.attach( std::move(d1) );
     164           0 :     auto d3 = data_line.next();
     165           0 :     t << is_true<assert>( d3.first!=nullptr ) << "c: " << c << ": " << FAS_TESTING_FILE_LINE;
     166           0 :     t << stop;
     167           0 :     t << equal<assert, data_type>( data_type( d3.first, d3.first + d3.second), *d2 ) << "c: " << c << ", " << FAS_TESTING_FILE_LINE;
     168           0 :     data_line.confirm(d3);
     169           0 :     t << is_true<assert>( data_line.size()==0 )  << FAS_TESTING_FILE_LINE;
     170           0 :     t << is_true<assert>( data_line.count()==0 ) << FAS_TESTING_FILE_LINE;
     171           0 :     t << stop;
     172           0 :     cursize += 1;
     173           0 :     if ( cursize > maxbuf )
     174           0 :       cursize = 1;
     175           7 :   }
     176           7 : }
     177             : 
     178          11 : UNIT(fullbuf_test, "full-buffering mode")
     179             : {
     180             :   // Отключены опции:
     181             :   // except_first = false
     182             :   // except_confirm = false
     183             : 
     184             :   using namespace fas::testing;
     185             :   typedef typename T::aspect::template advice_cast<_data_line_>::type data_line_t;
     186             :   
     187           7 :   data_line_t& data_line = t.get_aspect().template get<_data_line_>();
     188             :   //typedef typename decltype(data_line)::data_ptr data_ptr;
     189             : 
     190           7 :   auto test_opt = t.get_aspect().template get<_test_options_>();
     191             :   //!!! test_opt.except_first = false;
     192             :   //!!! test_opt.except_confirm = false;
     193             : 
     194           7 :   data_line.clear();
     195           7 :   data_line.set_options( *test_opt);
     196          14 :   typename data_line_t::options_type dl_opt;
     197           7 :   data_line.get_options(dl_opt);
     198             :   //auto dl_opt = data_line.get_options();
     199             : 
     200           7 :   size_t maxbuf = dl_opt.maxbuf*2;
     201           7 :   size_t cursize = 1;
     202           7 :   for (size_t c = 0; c < test_opt->data_count; ++c)
     203             :   {
     204           0 :     auto d1 = generate(t, 0, cursize); // исходные данные и результат
     205           0 :     auto d2 = generate(t, 0, cursize); // для проверки
     206           0 :     data_line.attach( std::move(d1) );  // следующая порция
     207           0 :     auto d3 = data_line.next();        // следующая порция
     208           0 :     while ( d3.first != nullptr )
     209             :     {
     210           0 :       if ( d1==nullptr )
     211             :       {
     212           0 :         d1 = std::make_unique<data_type>( d3.first, d3.first + d3.second );
     213             :       }
     214             :       else
     215             :       {
     216           0 :         std::copy( d3.first, d3.first + d3.second, std::back_inserter(*d1) );
     217             :       }
     218           0 :       data_line.confirm(d3);
     219           0 :       d3 = data_line.next();
     220             :     }
     221             :     
     222           0 :     if ( d1!=nullptr )
     223             :     {
     224           0 :       t << equal<assert, data_type>( *d1, *d2 ) << "c: " << c << ", " << FAS_TESTING_FILE_LINE;
     225           0 :       t << stop;
     226             :     }
     227             :     else
     228             :     {
     229           0 :       t << fatal("d1==nullptr");
     230             :     }
     231           0 :     cursize += 1;
     232           0 :     if ( cursize > maxbuf )
     233           0 :       cursize = 1;
     234           7 :   }
     235           7 : }
     236             : 
     237          11 : UNIT(ignore_first_test, "buffering with ignore first flag mode")
     238             : {
     239             :   using namespace fas::testing;
     240             :   typedef typename T::aspect::template advice_cast<_data_line_>::type data_line_t;
     241           7 :   auto& data_line = t.get_aspect().template get<_data_line_>();
     242           7 :   auto test_opt = t.get_aspect().template get<_test_options_>();
     243           7 :   test_opt->first_as_is = true;
     244             :   //!! test_opt.except_confirm = true;
     245           7 :   data_line.clear();
     246           7 :   data_line.set_options(*test_opt);
     247          14 :   typename data_line_t::options_type dl_opt;
     248           7 :   data_line.get_options(dl_opt);
     249             :   
     250           7 :   size_t cursize = 1;
     251           7 :   size_t maxbuf = (dl_opt.maxbuf * 3) / 2;
     252           7 :   for (size_t c = 0; c < test_opt->data_count; ++c)
     253             :   {
     254           0 :     auto d1 = generate(t, c, cursize);
     255           0 :     auto d2 = generate(t, c, cursize);
     256           0 :     data_line.attach( std::move(d1) );
     257           0 :     auto d3 = data_line.next();
     258           0 :     t << is_true<assert>( d3.first!=nullptr ) << "c: " << c << ": " << FAS_TESTING_FILE_LINE;
     259           0 :     t << stop;
     260           0 :     t << equal<assert, data_type>( data_type(d3.first, d3.first + d3.second), *d2 ) << "c: " << c << ", " << FAS_FL;
     261           0 :     data_line.confirm(d3);
     262           0 :     t << is_true<assert>( data_line.size()==0 )  << FAS_TESTING_FILE_LINE;
     263           0 :     t << is_true<assert>( data_line.count()==0 ) << FAS_TESTING_FILE_LINE;
     264           0 :     t << stop;
     265           0 :     cursize += 1;
     266           0 :     if ( cursize > maxbuf )
     267           0 :       cursize = 1;
     268             :     
     269           7 :   }
     270           7 : }
     271             : 
     272          11 : UNIT(partconfirm_test, "partconfirm_test")
     273             : {
     274             :   using namespace fas::testing;
     275             :   typedef typename T::aspect::template advice_cast<_data_line_>::type data_line_t;
     276           7 :   auto& data_line = t.get_aspect().template get<_data_line_>();
     277           7 :   auto test_opt = t.get_aspect().template get<_test_options_>();
     278             :     
     279             :   //!! test_opt.except_first   = false;
     280             :   //!! test_opt.except_confirm = false;
     281           7 :   data_line.clear();
     282           7 :   data_line.set_options(*test_opt);
     283          14 :   typename data_line_t::options_type dl_opt;
     284           7 :   data_line.get_options(dl_opt);
     285             : 
     286             :   
     287           7 :   size_t cursize = 1;
     288           7 :   size_t maxbuf = (dl_opt.maxbuf * 3) / 2;
     289          14 :   data_type result1, result2;
     290           7 :   for (size_t c = 0; c < test_opt->data_count; ++c)
     291             :   {
     292           0 :     auto d1 = generate(t, c, cursize);
     293           0 :     std::copy( d1->begin(), d1->end(), std::back_inserter(result1));
     294           0 :     data_line.attach( std::move(d1) );
     295           0 :     cursize += 1;
     296           0 :     if ( cursize > maxbuf )
     297           0 :       cursize = 1;
     298             :   }
     299             :   
     300           7 :   auto d2 = data_line.next();
     301          14 :   while( d2.first!=nullptr )
     302             :   {
     303           0 :     size_t size = d2.second/3;
     304           0 :     if ( size==0 && d2.second!=0 )
     305           0 :       size = 1;
     306           0 :     std::copy( d2.first, d2.first + size, std::back_inserter(result2) );
     307           0 :     d2.second = size;
     308           0 :     data_line.confirm(d2);
     309           0 :     d2 = data_line.next();
     310             :   }
     311             :   
     312           7 :   t <<   equal<assert>( result1, result2 ) << FAS_TESTING_FILE_LINE;
     313           7 :   t << is_true<assert>( data_line.size()==0 )  << data_line.size() << FAS_TESTING_FILE_LINE;
     314          14 :   t << is_true<assert>( data_line.count()==0 ) << FAS_TESTING_FILE_LINE;
     315           7 : }
     316             : 
     317           1 : BEGIN_SUITE(aux,"aux suite")
     318             :   ADD_UNIT(init_test)
     319             :   ADD_UNIT(nobuf_test)
     320             :   ADD_UNIT(fullbuf_test)
     321             :   ADD_UNIT(ignore_first_test)
     322             :   ADD_UNIT(partconfirm_test)
     323             :   ADD_VALUE(_test_options_, std::shared_ptr<data_line_test_options> )
     324             :   ADD_VALUE(_data_line_, ::iow::io::write_buffer )
     325             :   ADD_ADVICE(_generator_, generator)
     326             :   ADD_ADVICE(_init_line_, init_line)
     327          12 : END_SUITE(aux)
     328             : 
     329             : ::fas::testing::suite_counts fas_my_suite_run(int , char*[]);
     330           1 : ::fas::testing::suite_counts fas_my_suite_run(int argc, char* argv[])
     331             : {
     332             :   data_line_test_options optlist[]={
     333             :   //       bufsize maxbuf minbuf first_as_is data_size data_count
     334             :     getopt( 0,      0,     0,    false,      10,       10   ),
     335             :     getopt( 10,     0,     0,    false,      100,      100  ),
     336             :     getopt( 10,     10,    10,   false,      11,       1    ),
     337             :     getopt( 10,     20,    5,    false,      11,       33   ),
     338             :     getopt( 10,     20,    5,    false,      100,      100  ),
     339             :     getopt( 33,     34,    32,   false,      1000,     1000 ),
     340           7 :   };
     341             : 
     342           1 :   ::fas::testing::suite_counts sc;
     343           2 :   fas_aux_suite as;
     344             :   
     345           1 :   as.get_aspect().get<_test_options_>() 
     346           2 :     = std::make_shared<data_line_test_options>();
     347             :     
     348           2 :   auto opt = as.get_aspect().get<_test_options_>();
     349           7 :   for (size_t i =0 ; i < std::extent< decltype(optlist) >::value; i++)
     350             :   {
     351           6 :     *opt=optlist[i];
     352           6 :     as.run(argc, argv);
     353           6 :     sc += as.counts();
     354             :   }
     355           8 :   return sc;
     356             : }
     357             : 
     358             : 
     359           1 : BEGIN_TEST
     360           1 :   RUN_SUITE(aux)
     361           1 :   RUN_SUITE(my)
     362           4 : END_TEST

Generated by: LCOV version 1.10