]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/iostreams/test/file_descriptor_test.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / iostreams / test / file_descriptor_test.cpp
1 // (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
2 // (C) Copyright 2004-2007 Jonathan Turkanis
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
5
6 // See http://www.boost.org/libs/iostreams for documentation.
7
8 #include <fstream>
9 #include <fcntl.h>
10 #include <boost/iostreams/device/file_descriptor.hpp>
11 #include <boost/iostreams/stream.hpp>
12 #include <boost/test/test_tools.hpp>
13 #include <boost/test/unit_test.hpp>
14 #include "detail/temp_file.hpp"
15 #include "detail/verification.hpp"
16 #include "detail/file_handle.hpp"
17
18 using namespace boost;
19 using namespace boost::iostreams;
20 using namespace boost::iostreams::test;
21 namespace boost_ios = boost::iostreams;
22 using std::ifstream;
23 using boost::unit_test::test_suite;
24
25 void file_descriptor_test()
26 {
27
28 typedef stream<file_descriptor_source> fdistream;
29 typedef stream<file_descriptor_sink> fdostream;
30 typedef stream<file_descriptor> fdstream;
31
32 test_file test1;
33 test_file test2;
34
35 //--------------Test file_descriptor_source-------------------------------//
36
37 {
38 fdistream first(file_descriptor_source(test1.name()), 0);
39 ifstream second(test2.name().c_str());
40 BOOST_CHECK(first->is_open());
41 BOOST_CHECK_MESSAGE(
42 compare_streams_in_chars(first, second),
43 "failed reading from file_descriptor_source in chars with no buffer"
44 );
45 first->close();
46 BOOST_CHECK(!first->is_open());
47 }
48
49 {
50 fdistream first(file_descriptor_source(test1.name()), 0);
51 ifstream second(test2.name().c_str());
52 BOOST_CHECK(first->is_open());
53 BOOST_CHECK_MESSAGE(
54 compare_streams_in_chunks(first, second),
55 "failed reading from file_descriptor_source in chunks with no buffer"
56 );
57 first->close();
58 BOOST_CHECK(!first->is_open());
59 }
60
61 {
62 file_descriptor_source file(test1.name());
63 fdistream first(file);
64 ifstream second(test2.name().c_str());
65 BOOST_CHECK(first->is_open());
66 BOOST_CHECK_MESSAGE(
67 compare_streams_in_chars(first, second),
68 "failed reading from file_descriptor_source in chars with buffer"
69 );
70 first->close();
71 BOOST_CHECK(!first->is_open());
72 }
73
74 {
75 file_descriptor_source file(test1.name());
76 fdistream first(file);
77 ifstream second(test2.name().c_str());
78 BOOST_CHECK(first->is_open());
79 BOOST_CHECK_MESSAGE(
80 compare_streams_in_chunks(first, second),
81 "failed reading from file_descriptor_source in chunks with buffer"
82 );
83 first->close();
84 BOOST_CHECK(!first->is_open());
85 }
86
87 // test illegal flag combinations
88 {
89 BOOST_CHECK_THROW(
90 file_descriptor_source(test1.name(),
91 BOOST_IOS::app),
92 BOOST_IOSTREAMS_FAILURE);
93 BOOST_CHECK_THROW(
94 file_descriptor_source(test1.name(),
95 BOOST_IOS::trunc),
96 BOOST_IOSTREAMS_FAILURE);
97 BOOST_CHECK_THROW(
98 file_descriptor_source(test1.name(),
99 BOOST_IOS::app | BOOST_IOS::trunc),
100 BOOST_IOSTREAMS_FAILURE);
101 BOOST_CHECK_THROW(
102 file_descriptor_source(test1.name(),
103 BOOST_IOS::out),
104 BOOST_IOSTREAMS_FAILURE);
105 BOOST_CHECK_THROW(
106 file_descriptor_source(test1.name(),
107 BOOST_IOS::out | BOOST_IOS::app),
108 BOOST_IOSTREAMS_FAILURE);
109 BOOST_CHECK_THROW(
110 file_descriptor_source(test1.name(),
111 BOOST_IOS::out | BOOST_IOS::trunc),
112 BOOST_IOSTREAMS_FAILURE);
113 BOOST_CHECK_THROW(
114 file_descriptor_source(test1.name(),
115 BOOST_IOS::out | BOOST_IOS::app | BOOST_IOS::trunc),
116 BOOST_IOSTREAMS_FAILURE);
117 }
118
119 //--------------Test file_descriptor_sink---------------------------------//
120
121 {
122 temp_file temp;
123 file_descriptor_sink file(temp.name(), BOOST_IOS::trunc);
124 fdostream out(file, 0);
125 BOOST_CHECK(out->is_open());
126 write_data_in_chars(out);
127 out.close();
128 BOOST_CHECK_MESSAGE(
129 compare_files(test1.name(), temp.name()),
130 "failed writing to file_descriptor_sink in chars with no buffer"
131 );
132 file.close();
133 BOOST_CHECK(!file.is_open());
134 }
135
136 {
137 temp_file temp;
138 file_descriptor_sink file(temp.name(), BOOST_IOS::trunc);
139 fdostream out(file, 0);
140 BOOST_CHECK(out->is_open());
141 write_data_in_chunks(out);
142 out.close();
143 BOOST_CHECK_MESSAGE(
144 compare_files(test1.name(), temp.name()),
145 "failed writing to file_descriptor_sink in chunks with no buffer"
146 );
147 file.close();
148 BOOST_CHECK(!file.is_open());
149 }
150
151 {
152 temp_file temp;
153 file_descriptor_sink file(temp.name(), BOOST_IOS::trunc);
154 fdostream out(file);
155 BOOST_CHECK(out->is_open());
156 write_data_in_chars(out);
157 out.close();
158 BOOST_CHECK_MESSAGE(
159 compare_files(test1.name(), temp.name()),
160 "failed writing to file_descriptor_sink in chars with buffer"
161 );
162 file.close();
163 BOOST_CHECK(!file.is_open());
164 }
165
166 {
167 temp_file temp;
168 file_descriptor_sink file(temp.name(), BOOST_IOS::trunc);
169 fdostream out(file);
170 BOOST_CHECK(out->is_open());
171 write_data_in_chunks(out);
172 out.close();
173 BOOST_CHECK_MESSAGE(
174 compare_files(test1.name(), temp.name()),
175 "failed writing to file_descriptor_sink in chunks with buffer"
176 );
177 file.close();
178 BOOST_CHECK(!file.is_open());
179 }
180
181 {
182 temp_file temp;
183 // set up the tests
184 {
185 file_descriptor_sink file(temp.name(), BOOST_IOS::trunc);
186 fdostream out(file);
187 write_data_in_chunks(out);
188 out.close();
189 file.close();
190 }
191 // test std::ios_base::app
192 {
193 file_descriptor_sink file(temp.name(), BOOST_IOS::app);
194 fdostream out(file);
195 BOOST_CHECK(out->is_open());
196 write_data_in_chars(out);
197 out.close();
198 std::string expected(narrow_data());
199 expected += narrow_data();
200 BOOST_CHECK_MESSAGE(
201 compare_container_and_file(expected, temp.name()),
202 "failed writing to file_descriptor_sink in append mode"
203 );
204 file.close();
205 BOOST_CHECK(!file.is_open());
206 }
207 // test std::ios_base::trunc
208 {
209 file_descriptor_sink file(temp.name(), BOOST_IOS::trunc);
210 fdostream out(file);
211 BOOST_CHECK(out->is_open());
212 write_data_in_chars(out);
213 out.close();
214 BOOST_CHECK_MESSAGE(
215 compare_files(test1.name(), temp.name()),
216 "failed writing to file_descriptor_sink in trunc mode"
217 );
218 file.close();
219 BOOST_CHECK(!file.is_open());
220 }
221
222 // test illegal flag combinations
223 {
224 BOOST_CHECK_THROW(
225 file_descriptor_sink(temp.name(),
226 BOOST_IOS::trunc | BOOST_IOS::app),
227 BOOST_IOSTREAMS_FAILURE);
228 BOOST_CHECK_THROW(
229 file_descriptor_sink(temp.name(),
230 BOOST_IOS::in),
231 BOOST_IOSTREAMS_FAILURE);
232 BOOST_CHECK_THROW(
233 file_descriptor_sink(temp.name(),
234 BOOST_IOS::in | BOOST_IOS::app),
235 BOOST_IOSTREAMS_FAILURE);
236 BOOST_CHECK_THROW(
237 file_descriptor_sink(temp.name(),
238 BOOST_IOS::in | BOOST_IOS::trunc),
239 BOOST_IOSTREAMS_FAILURE);
240 BOOST_CHECK_THROW(
241 file_descriptor_sink(temp.name(),
242 BOOST_IOS::in | BOOST_IOS::trunc | BOOST_IOS::app),
243 BOOST_IOSTREAMS_FAILURE);
244 }
245 }
246
247 //--Test seeking with file_descriptor_source and file_descriptor_sink-----//
248
249 test_file test3;
250 {
251 file_descriptor_sink sink(test3.name());
252 fdostream out(sink);
253 BOOST_CHECK(out->is_open());
254 BOOST_CHECK_MESSAGE(
255 test_output_seekable(out),
256 "failed seeking within a file_descriptor_sink"
257 );
258 out->close();
259 BOOST_CHECK(!out->is_open());
260
261 file_descriptor_source source(test3.name());
262 fdistream in(source);
263 BOOST_CHECK(in->is_open());
264 BOOST_CHECK_MESSAGE(
265 test_input_seekable(in),
266 "failed seeking within a file_descriptor_source"
267 );
268 in->close();
269 BOOST_CHECK(!in->is_open());
270 }
271
272 //--------------Test file_descriptor--------------------------------------//
273
274 {
275 temp_file temp;
276 file_descriptor file( temp.name(),
277 BOOST_IOS::in |
278 BOOST_IOS::out |
279 BOOST_IOS::trunc |
280 BOOST_IOS::binary );
281 fdstream io(file, BUFSIZ);
282 BOOST_CHECK_MESSAGE(
283 test_seekable_in_chars(io),
284 "failed seeking within a file_descriptor, in chars"
285 );
286 }
287
288 {
289 temp_file temp;
290 file_descriptor file( temp.name(),
291 BOOST_IOS::in |
292 BOOST_IOS::out |
293 BOOST_IOS::trunc |
294 BOOST_IOS::binary );
295 fdstream io(file, BUFSIZ);
296 BOOST_CHECK_MESSAGE(
297 test_seekable_in_chunks(io),
298 "failed seeking within a file_descriptor, in chunks"
299 );
300 }
301
302 //--------------Test read-only file_descriptor----------------------------//
303
304 {
305 fdstream first(file_descriptor(test1.name(), BOOST_IOS::in), 0);
306 ifstream second(test2.name().c_str());
307 BOOST_CHECK(first->is_open());
308 write_data_in_chars(first);
309 BOOST_CHECK(first.fail());
310 first.clear();
311 BOOST_CHECK_MESSAGE(
312 compare_streams_in_chars(first, second),
313 "failed reading from file_descriptor in chars with no buffer"
314 );
315 first->close();
316 BOOST_CHECK(!first->is_open());
317 }
318
319 {
320 fdstream first(file_descriptor(test1.name(), BOOST_IOS::in), 0);
321 ifstream second(test2.name().c_str());
322 BOOST_CHECK(first->is_open());
323 write_data_in_chunks(first);
324 BOOST_CHECK(first.fail());
325 first.clear();
326 BOOST_CHECK_MESSAGE(
327 compare_streams_in_chunks(first, second),
328 "failed reading from file_descriptor in chunks with no buffer"
329 );
330 first->close();
331 BOOST_CHECK(!first->is_open());
332 }
333
334 {
335 file_descriptor file(test1.name(), BOOST_IOS::in);
336 fdstream first(file);
337 ifstream second(test2.name().c_str());
338 BOOST_CHECK(first->is_open());
339 write_data_in_chars(first);
340 BOOST_CHECK(first.fail());
341 first.clear();
342 first.seekg(0, BOOST_IOS::beg);
343 BOOST_CHECK_MESSAGE(
344 compare_streams_in_chars(first, second),
345 "failed reading from file_descriptor in chars with buffer"
346 );
347 first->close();
348 BOOST_CHECK(!first->is_open());
349 }
350
351 {
352 file_descriptor file(test1.name(), BOOST_IOS::in);
353 fdstream first(file);
354 ifstream second(test2.name().c_str());
355 BOOST_CHECK(first->is_open());
356 write_data_in_chunks(first);
357 BOOST_CHECK(first.fail());
358 first.clear();
359 first.seekg(0, BOOST_IOS::beg);
360 BOOST_CHECK_MESSAGE(
361 compare_streams_in_chunks(first, second),
362 "failed reading from file_descriptor in chunks with buffer"
363 );
364 first->close();
365 BOOST_CHECK(!first->is_open());
366 }
367
368 //--------------Test write-only file_descriptor---------------------------//
369 {
370 temp_file temp;
371 file_descriptor file( temp.name(),
372 BOOST_IOS::out |
373 BOOST_IOS::trunc );
374 fdstream out(file, 0);
375 BOOST_CHECK(out->is_open());
376 out.get();
377 BOOST_CHECK(out.fail());
378 out.clear();
379 write_data_in_chars(out);
380 out.seekg(0, BOOST_IOS::beg);
381 out.get();
382 BOOST_CHECK(out.fail());
383 out.clear();
384 out.close();
385 BOOST_CHECK_MESSAGE(
386 compare_files(test1.name(), temp.name()),
387 "failed writing to file_descriptor in chars with no buffer"
388 );
389 file.close();
390 BOOST_CHECK(!file.is_open());
391 }
392
393 {
394 temp_file temp;
395 file_descriptor file( temp.name(),
396 BOOST_IOS::out |
397 BOOST_IOS::trunc );
398 fdstream out(file, 0);
399 BOOST_CHECK(out->is_open());
400 out.get();
401 BOOST_CHECK(out.fail());
402 out.clear();
403 write_data_in_chunks(out);
404 out.seekg(0, BOOST_IOS::beg);
405 out.get();
406 BOOST_CHECK(out.fail());
407 out.clear();
408 out.close();
409 BOOST_CHECK_MESSAGE(
410 compare_files(test1.name(), temp.name()),
411 "failed writing to file_descriptor_sink in chunks with no buffer"
412 );
413 file.close();
414 BOOST_CHECK(!file.is_open());
415 }
416
417 {
418 temp_file temp;
419 file_descriptor file( temp.name(),
420 BOOST_IOS::out |
421 BOOST_IOS::trunc );
422 fdstream out(file);
423 BOOST_CHECK(out->is_open());
424 out.get();
425 BOOST_CHECK(out.fail());
426 out.clear();
427 write_data_in_chars(out);
428 out.seekg(0, BOOST_IOS::beg);
429 out.get();
430 BOOST_CHECK(out.fail());
431 out.clear();
432 out.close();
433 BOOST_CHECK_MESSAGE(
434 compare_files(test1.name(), temp.name()),
435 "failed writing to file_descriptor_sink in chars with buffer"
436 );
437 file.close();
438 BOOST_CHECK(!file.is_open());
439 }
440
441 {
442 temp_file temp;
443 file_descriptor file( temp.name(),
444 BOOST_IOS::out |
445 BOOST_IOS::trunc );
446 fdstream out(file);
447 BOOST_CHECK(out->is_open());
448 out.get();
449 BOOST_CHECK(out.fail());
450 out.clear();
451 write_data_in_chunks(out);
452 out.seekg(0, BOOST_IOS::beg);
453 out.get();
454 BOOST_CHECK(out.fail());
455 out.clear();
456 out.close();
457 BOOST_CHECK_MESSAGE(
458 compare_files(test1.name(), temp.name()),
459 "failed writing to file_descriptor_sink in chunks with buffer"
460 );
461 file.close();
462 BOOST_CHECK(!file.is_open());
463 }
464
465 // test illegal flag combinations
466 {
467 BOOST_CHECK_THROW(
468 file_descriptor(test1.name(),
469 BOOST_IOS::openmode(0)),
470 BOOST_IOSTREAMS_FAILURE);
471 BOOST_CHECK_THROW(
472 file_descriptor(test1.name(),
473 BOOST_IOS::app),
474 BOOST_IOSTREAMS_FAILURE);
475 BOOST_CHECK_THROW(
476 file_descriptor(test1.name(),
477 BOOST_IOS::trunc),
478 BOOST_IOSTREAMS_FAILURE);
479 BOOST_CHECK_THROW(
480 file_descriptor(test1.name(),
481 BOOST_IOS::app | BOOST_IOS::trunc),
482 BOOST_IOSTREAMS_FAILURE);
483 BOOST_CHECK_THROW(
484 file_descriptor(test1.name(),
485 BOOST_IOS::in | BOOST_IOS::app),
486 BOOST_IOSTREAMS_FAILURE);
487 BOOST_CHECK_THROW(
488 file_descriptor(test1.name(),
489 BOOST_IOS::in | BOOST_IOS::trunc),
490 BOOST_IOSTREAMS_FAILURE);
491 BOOST_CHECK_THROW(
492 file_descriptor(test1.name(),
493 BOOST_IOS::in | BOOST_IOS::app | BOOST_IOS::trunc),
494 BOOST_IOSTREAMS_FAILURE);
495 BOOST_CHECK_THROW(
496 file_descriptor(test1.name(),
497 BOOST_IOS::out | BOOST_IOS::app | BOOST_IOS::trunc),
498 BOOST_IOSTREAMS_FAILURE);
499 BOOST_CHECK_THROW(
500 file_descriptor(test1.name(),
501 BOOST_IOS::in | BOOST_IOS::out | BOOST_IOS::app),
502 BOOST_IOSTREAMS_FAILURE);
503 BOOST_CHECK_THROW(
504 file_descriptor(test1.name(),
505 BOOST_IOS::in |
506 BOOST_IOS::out |
507 BOOST_IOS::app |
508 BOOST_IOS::trunc),
509 BOOST_IOSTREAMS_FAILURE);
510 }
511 }
512
513 template <class FileDescriptor>
514 void file_handle_test_impl(FileDescriptor*)
515 {
516 test_file test1;
517 test_file test2;
518
519 {
520 boost_ios::detail::file_handle handle = open_file_handle(test1.name());
521 {
522 FileDescriptor device1(handle, boost_ios::never_close_handle);
523 BOOST_CHECK(device1.handle() == handle);
524 }
525 BOOST_CHECK_HANDLE_OPEN(handle);
526 close_file_handle(handle);
527 }
528
529 {
530 boost_ios::detail::file_handle handle = open_file_handle(test1.name());
531 {
532 FileDescriptor device1(handle, boost_ios::close_handle);
533 BOOST_CHECK(device1.handle() == handle);
534 }
535 BOOST_CHECK_HANDLE_CLOSED(handle);
536 }
537
538 {
539 boost_ios::detail::file_handle handle = open_file_handle(test1.name());
540 FileDescriptor device1(handle, boost_ios::never_close_handle);
541 BOOST_CHECK(device1.handle() == handle);
542 device1.close();
543 BOOST_CHECK(!device1.is_open());
544 BOOST_CHECK_HANDLE_OPEN(handle);
545 close_file_handle(handle);
546 }
547
548 {
549 boost_ios::detail::file_handle handle = open_file_handle(test1.name());
550 FileDescriptor device1(handle, boost_ios::close_handle);
551 BOOST_CHECK(device1.handle() == handle);
552 device1.close();
553 BOOST_CHECK(!device1.is_open());
554 BOOST_CHECK_HANDLE_CLOSED(handle);
555 }
556
557 {
558 boost_ios::detail::file_handle handle1 = open_file_handle(test1.name());
559 boost_ios::detail::file_handle handle2 = open_file_handle(test2.name());
560 {
561 FileDescriptor device1(handle1, boost_ios::never_close_handle);
562 BOOST_CHECK(device1.handle() == handle1);
563 device1.open(handle2, boost_ios::never_close_handle);
564 BOOST_CHECK(device1.handle() == handle2);
565 }
566 BOOST_CHECK_HANDLE_OPEN(handle1);
567 BOOST_CHECK_HANDLE_OPEN(handle2);
568 close_file_handle(handle1);
569 close_file_handle(handle2);
570 }
571
572 {
573 boost_ios::detail::file_handle handle1 = open_file_handle(test1.name());
574 boost_ios::detail::file_handle handle2 = open_file_handle(test2.name());
575 {
576 FileDescriptor device1(handle1, boost_ios::close_handle);
577 BOOST_CHECK(device1.handle() == handle1);
578 device1.open(handle2, boost_ios::close_handle);
579 BOOST_CHECK(device1.handle() == handle2);
580 BOOST_CHECK_HANDLE_CLOSED(handle1);
581 BOOST_CHECK_HANDLE_OPEN(handle2);
582 }
583 BOOST_CHECK_HANDLE_CLOSED(handle1);
584 BOOST_CHECK_HANDLE_CLOSED(handle2);
585 }
586
587 {
588 boost_ios::detail::file_handle handle1 = open_file_handle(test1.name());
589 boost_ios::detail::file_handle handle2 = open_file_handle(test2.name());
590 {
591 FileDescriptor device1(handle1, boost_ios::close_handle);
592 BOOST_CHECK(device1.handle() == handle1);
593 device1.open(handle2, boost_ios::never_close_handle);
594 BOOST_CHECK(device1.handle() == handle2);
595 BOOST_CHECK_HANDLE_CLOSED(handle1);
596 BOOST_CHECK_HANDLE_OPEN(handle2);
597 }
598 BOOST_CHECK_HANDLE_CLOSED(handle1);
599 BOOST_CHECK_HANDLE_OPEN(handle2);
600 close_file_handle(handle2);
601 }
602
603 {
604 boost_ios::detail::file_handle handle = open_file_handle(test1.name());
605 {
606 FileDescriptor device1;
607 BOOST_CHECK(!device1.is_open());
608 device1.open(handle, boost_ios::never_close_handle);
609 BOOST_CHECK(device1.handle() == handle);
610 BOOST_CHECK_HANDLE_OPEN(handle);
611 }
612 BOOST_CHECK_HANDLE_OPEN(handle);
613 close_file_handle(handle);
614 }
615
616 {
617 boost_ios::detail::file_handle handle = open_file_handle(test1.name());
618 {
619 FileDescriptor device1;
620 BOOST_CHECK(!device1.is_open());
621 device1.open(handle, boost_ios::close_handle);
622 BOOST_CHECK(device1.handle() == handle);
623 BOOST_CHECK_HANDLE_OPEN(handle);
624 }
625 BOOST_CHECK_HANDLE_CLOSED(handle);
626 }
627 }
628
629 void file_handle_test()
630 {
631 file_handle_test_impl((boost_ios::file_descriptor*) 0);
632 file_handle_test_impl((boost_ios::file_descriptor_source*) 0);
633 file_handle_test_impl((boost_ios::file_descriptor_sink*) 0);
634 }
635
636 test_suite* init_unit_test_suite(int, char* [])
637 {
638 test_suite* test = BOOST_TEST_SUITE("file_descriptor test");
639 test->add(BOOST_TEST_CASE(&file_descriptor_test));
640 test->add(BOOST_TEST_CASE(&file_handle_test));
641 return test;
642 }