LCOV - code coverage report
Current view: top level - util/test - multi_buffer.cpp (source / functions) Hit Total Coverage
Test: CoherentDB code coverage Lines: 60 60 100.0 %
Date: 2011-02-13 Functions: 9 9 100.0 %

          Line data    Source code
       1             : /*
       2             :  * (C) Copyright 2010 Marek Dopiera
       3             :  * 
       4             :  * This file is part of CoherentDB.
       5             :  * 
       6             :  * CoherentDB is free software: you can redistribute it and/or modify it
       7             :  * under the terms of the GNU General Public License as published by
       8             :  * the Free Software Foundation, either version 3 of the License, or
       9             :  * (at your option) any later version.
      10             :  * 
      11             :  * CoherentDB is distributed in the hope that it will be useful, but
      12             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
      14             :  * General Public License for more details.
      15             :  * 
      16             :  * You should have received a copy of the GNU General Public
      17             :  * License along with CoherentDB. If not, see
      18             :  * http://www.gnu.org/licenses/.
      19             :  */
      20             : 
      21             : #include <cstring>
      22             : #include <cstdlib>
      23             : 
      24             : #include <util/multi_buffer.h>
      25             : #include <config/config.h>
      26             : #include <debug/asserts.h>
      27             : #include <log/log.h>
      28             : 
      29             : namespace coherent {
      30             : namespace util {
      31             : namespace unittests {
      32             : 
      33             : using namespace log4cxx;
      34             : using namespace coherent::config;
      35             : using namespace coherent::log;
      36             : 
      37             : static uint32_t const buf_size = 32000;
      38             : 
      39             : struct test_pattern
      40             : {
      41           1 :         test_pattern() : buf(new char[buf_size])
      42             :         {
      43       32001 :                 for (uint32_t i = 0; i < buf_size; ++i)
      44       32000 :                         buf[i] = random();
      45           1 :         }
      46             : 
      47          21 :         test_pattern(test_pattern const & o) : buf(new char[buf_size])
      48             :         {
      49          21 :                 memcpy(this->buf, o.buf, buf_size);
      50          21 :         }
      51             : 
      52          22 :         ~test_pattern()
      53             :         {
      54          22 :                 delete[] buf;
      55          22 :         }
      56             : 
      57             :         char * buf;
      58             : };
      59             : 
      60           1 : test_pattern pattern;
      61             : 
      62        2142 : static void check_buffers(char const * b1, char const * b2, uint32_t size)
      63             : {
      64    17524428 :         for (uint32_t i = 0; i < size; ++i)
      65             :                 r_assert(
      66             :                         b1[i] == b2[i],
      67             :                         "mismatch at byte " << i << " expected " << static_cast<int>(b1[i])
      68             :                         << " but got " << static_cast<int>(b2[i])
      69             :                 );
      70        2142 : }
      71             : 
      72          21 : void single_test(uint32_t left_off)
      73             : {
      74          21 :         uint32_t cur_off = left_off;
      75          42 :         multi_buffer::buffer_list bufs;
      76          21 :         uint32_t total_size = 0;
      77             : 
      78          42 :         test_pattern pattern_save(pattern);
      79             : 
      80        4455 :         while (true) {
      81        4476 :                 uint32_t const size = random() % 300 + 1;
      82        4476 :                 if (cur_off + size > buf_size)
      83             :                         break;
      84        4455 :                 if (cur_off == left_off) {
      85             :                         //first frame
      86          42 :                         multi_buffer::buffer_ptr buf(new buffer(size + left_off));
      87          21 :                         memcpy(buf->get_data(), pattern.buf, size + left_off);
      88          21 :                         bufs.push_back(buf);
      89             :                         LOG(TRACE, "Added buffer off=0" << " size=" << size + left_off);
      90             :                 }
      91             :                 else
      92             :                 {
      93        8868 :                         multi_buffer::buffer_ptr buf(new buffer(size));
      94        4434 :                         memcpy(buf->get_data(), pattern.buf + cur_off, size);
      95        4434 :                         bufs.push_back(buf);
      96             :                         LOG(TRACE, "Added buffer off=" << cur_off << " size=" << size);
      97             :                 }
      98        4455 :                 total_size += size;
      99        4455 :                 cur_off += size;
     100             :         }
     101             :         LOG(TRACE, "left_off=" << left_off << ", total_size=" << total_size <<
     102             :                 " cur_off=" << cur_off
     103             :         );
     104          42 :         multi_buffer mbuf(bufs, total_size, left_off);
     105          42 :         multi_buffer mbuf2(mbuf);
     106             : 
     107             :         //read whole mbuf
     108             :         {
     109          21 :                 char tmp[total_size];
     110          21 :                 mbuf.read(tmp, total_size, 0);
     111          21 :                 check_buffers(pattern.buf + left_off, tmp, total_size);
     112             :         }
     113             : 
     114        4221 :         for (uint32_t i = 0; i < 200; ++i)
     115             :         {
     116        4200 :                 uint32_t const start = random() % total_size + 1;
     117        4200 :                 uint32_t const size = (i == 100) ? 0 : (random() % (total_size - start));
     118             :                         
     119        4200 :                 char buf[size];
     120        4200 :                 if (i % 2) {
     121    16500953 :                         for (uint32_t i = 0; i < size; ++i)
     122    16498853 :                                 pattern.buf[i+left_off + start] = buf[i] = random();
     123        2100 :                         mbuf.write(buf, size, start);
     124             :                 }
     125             :                 else
     126             :                 {
     127        2100 :                         mbuf.read(buf, size, start);
     128        2100 :                         check_buffers(pattern.buf + left_off + start, buf, size);
     129             :                 }
     130             : 
     131             :         }
     132             :         {
     133             :                 //verify c-o-w
     134          21 :                 char tmp[total_size];
     135          21 :                 mbuf2.read(tmp, total_size, 0);
     136          21 :                 check_buffers(pattern_save.buf + left_off, tmp, total_size);
     137             :         }
     138          21 : }
     139           1 : int start_test(const int argc, const char *const *const argv)
     140             : {
     141           2 :         scoped_test_enabler test_setup(argc, argv);
     142             : 
     143           1 :         Logger::getLogger("coherent.util")->setLevel(log_TRACE);   
     144             : 
     145           1 :         single_test(0);
     146          21 :         for (uint32_t i = 0; i < 20; ++i)
     147          20 :                 single_test(random() % 100 + 1);
     148             : 
     149           1 :         return 0;
     150             : }
     151             : 
     152             : } // namespace unittests
     153             : } // namespace util
     154             : } // namespace coherent
     155             : 
     156           1 : int main(const int argc, const char * const * const argv)
     157             : {
     158           1 :         return coherent::util::unittests::start_test(argc, argv);
     159           3 : }

Generated by: LCOV version 1.9