write_failure_test.cpp 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. // (C) COPYRIGHT 2017 ARM Limited
  2. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  3. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
  4. #include <boost/iostreams/categories.hpp> // tags.
  5. #include <boost/iostreams/detail/adapter/non_blocking_adapter.hpp>
  6. #include <boost/iostreams/filter/gzip.hpp>
  7. #include <boost/iostreams/filtering_stream.hpp>
  8. #include <boost/iostreams/write.hpp>
  9. #include <boost/test/unit_test.hpp>
  10. using namespace boost;
  11. using namespace boost::iostreams;
  12. using boost::unit_test::test_suite;
  13. struct limit_device {
  14. typedef char char_type;
  15. typedef sink_tag category;
  16. int written, overflow_count, limit;
  17. explicit limit_device(int limit = 20) : written(0), overflow_count(0), limit(limit) {}
  18. std::streamsize write(const char_type *, std::streamsize n)
  19. {
  20. if (written > limit) {
  21. // first return partial writes, then an error
  22. ++overflow_count;
  23. if (overflow_count > 2 || n < 2)
  24. {
  25. return -1;
  26. }
  27. n /= 2;
  28. }
  29. written += n;
  30. return n;
  31. }
  32. };
  33. static void disk_full_test()
  34. {
  35. // non_blocking_adapter used to handle write returning
  36. // -1 correctly, usually hanging (see ticket 2557).
  37. // As non_blocking_adapter is used for ofstream, this
  38. // would happen for ordinary files when reaching quota,
  39. // disk full or rlimits.
  40. // Could be tested without gzip_compressor,
  41. // but this tests a bit better that the whole path can handle it.
  42. // TODO: should there be some check on error bit being set
  43. // or should an exception be triggered?
  44. limit_device outdev;
  45. non_blocking_adapter<limit_device> nonblock_outdev(outdev);
  46. filtering_ostream out;
  47. out.push(gzip_compressor());
  48. out.push(nonblock_outdev);
  49. write(out, "teststring0123456789", 20);
  50. out.flush();
  51. write(out, "secondwrite123456789", 20);
  52. close(out);
  53. }
  54. test_suite* init_unit_test_suite(int, char* [])
  55. {
  56. test_suite* test = BOOST_TEST_SUITE("disk full test");
  57. test->add(BOOST_TEST_CASE(&disk_full_test));
  58. return test;
  59. }