summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/iostreams/test/write_failure_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/iostreams/test/write_failure_test.cpp')
-rw-r--r--src/boost/libs/iostreams/test/write_failure_test.cpp65
1 files changed, 65 insertions, 0 deletions
diff --git a/src/boost/libs/iostreams/test/write_failure_test.cpp b/src/boost/libs/iostreams/test/write_failure_test.cpp
new file mode 100644
index 00000000..f4552e88
--- /dev/null
+++ b/src/boost/libs/iostreams/test/write_failure_test.cpp
@@ -0,0 +1,65 @@
+// (C) COPYRIGHT 2017 ARM Limited
+
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
+
+#include <boost/iostreams/categories.hpp> // tags.
+#include <boost/iostreams/detail/adapter/non_blocking_adapter.hpp>
+#include <boost/iostreams/filter/gzip.hpp>
+#include <boost/iostreams/filtering_stream.hpp>
+#include <boost/iostreams/write.hpp>
+#include <boost/test/unit_test.hpp>
+
+using namespace boost;
+using namespace boost::iostreams;
+using boost::unit_test::test_suite;
+
+struct limit_device {
+ typedef char char_type;
+ typedef sink_tag category;
+ int written, overflow_count, limit;
+ explicit limit_device(int limit = 20) : written(0), overflow_count(0), limit(limit) {}
+ std::streamsize write(const char_type *, std::streamsize n)
+ {
+ if (written > limit) {
+ // first return partial writes, then an error
+ ++overflow_count;
+ if (overflow_count > 2 || n < 2)
+ {
+ return -1;
+ }
+ n /= 2;
+ }
+ written += n;
+ return n;
+ }
+};
+
+static void disk_full_test()
+{
+ // non_blocking_adapter used to handle write returning
+ // -1 correctly, usually hanging (see ticket 2557).
+ // As non_blocking_adapter is used for ofstream, this
+ // would happen for ordinary files when reaching quota,
+ // disk full or rlimits.
+ // Could be tested without gzip_compressor,
+ // but this tests a bit better that the whole path can handle it.
+ // TODO: should there be some check on error bit being set
+ // or should an exception be triggered?
+ limit_device outdev;
+ non_blocking_adapter<limit_device> nonblock_outdev(outdev);
+ filtering_ostream out;
+ out.push(gzip_compressor());
+ out.push(nonblock_outdev);
+ write(out, "teststring0123456789", 20);
+ out.flush();
+ write(out, "secondwrite123456789", 20);
+ close(out);
+}
+
+test_suite* init_unit_test_suite(int, char* [])
+{
+ test_suite* test = BOOST_TEST_SUITE("disk full test");
+ test->add(BOOST_TEST_CASE(&disk_full_test));
+ return test;
+}