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
|