diff options
Diffstat (limited to 'tests/fdstream/driver.cxx')
-rw-r--r-- | tests/fdstream/driver.cxx | 172 |
1 files changed, 135 insertions, 37 deletions
diff --git a/tests/fdstream/driver.cxx b/tests/fdstream/driver.cxx index 3215e02..ec0c54e 100644 --- a/tests/fdstream/driver.cxx +++ b/tests/fdstream/driver.cxx @@ -5,9 +5,6 @@ # include <libbutl/win32-utility.hxx> #endif -#include <cassert> - -#ifndef __cpp_lib_modules_ts #ifndef _WIN32 # include <chrono> #endif @@ -15,38 +12,28 @@ #include <ios> #include <string> #include <vector> -#include <thread> #include <iomanip> #include <sstream> #include <fstream> #include <utility> // move() #include <iostream> #include <exception> -#endif -// Other includes. - -#ifdef __cpp_modules_ts -#ifdef __cpp_lib_modules_ts -import std.core; -import std.io; -#ifndef _WIN32 -import std.threading; -#endif -#endif -import butl.path; -import butl.process; -import butl.fdstream; -import butl.timestamp; -import butl.filesystem; +#ifndef LIBBUTL_MINGW_STDTHREAD +# include <thread> #else -#include <libbutl/path.mxx> -#include <libbutl/process.mxx> -#include <libbutl/fdstream.mxx> -#include <libbutl/timestamp.mxx> -#include <libbutl/filesystem.mxx> +# include <libbutl/mingw-thread.hxx> #endif +#include <libbutl/path.hxx> +#include <libbutl/process.hxx> +#include <libbutl/fdstream.hxx> +#include <libbutl/timestamp.hxx> +#include <libbutl/filesystem.hxx> + +#undef NDEBUG +#include <cassert> + using namespace std; using namespace butl; @@ -55,7 +42,9 @@ static const string text2 ("12"); // Keep shorter than text1. // Windows text mode write-translated form of text1. // +#ifdef _WIN32 static const string text3 ("ABCDEF\r\nXYZ"); +#endif static string from_stream (ifdstream& is) @@ -133,6 +122,12 @@ read_time (const path& p, const T& s, size_t n) int main (int argc, const char* argv[]) { +#ifndef LIBBUTL_MINGW_STDTHREAD + using std::thread; +#else + using mingw_stdthread::thread; +#endif + bool v (false); bool child (false); @@ -470,12 +465,12 @@ main (int argc, const char* argv[]) // { string s; - for (size_t i (0); i < 100; ++i) + for (size_t i (0); i < 300; ++i) s += "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\n"; const char* args[] = {argv[0], "-c", nullptr}; - auto test_read = [&args, &s] () + auto test_read = [&args, &s] (bool timeout) { try { @@ -491,11 +486,29 @@ main (int argc, const char* argv[]) string r; char buf[300]; + bool timedout (false); while (!is.eof ()) { - pair<size_t, size_t> nd (fdselect (rds, wds)); - - assert (nd.first == 1 && nd.second == 0 && rds[0].ready); + if (timeout) + { + pair<size_t, size_t> nd ( + fdselect (rds, wds, chrono::milliseconds (3))); + + assert (((nd.first == 0 && !rds[0].ready) || + (nd.first == 1 && rds[0].ready)) && + nd.second == 0); + + if (nd.first == 0) + { + timedout = true; + continue; + } + } + else + { + pair<size_t, size_t> nd (fdselect (rds, wds)); + assert (nd.first == 1 && nd.second == 0 && rds[0].ready); + } for (streamsize n; (n = is.readsome (buf, sizeof (buf))) != 0; ) r.append (buf, static_cast<size_t> (n)); @@ -504,6 +517,10 @@ main (int argc, const char* argv[]) is.close (); assert (r == s); + + // If timeout is used, then it most likely timedout, at least once. + // + assert (timedout == timeout); } catch (const ios::failure&) { @@ -517,7 +534,10 @@ main (int argc, const char* argv[]) vector<thread> threads; for (size_t i (0); i < 10; ++i) - threads.emplace_back (test_read); + { + threads.emplace_back ([&test_read] {test_read (true /* timeout */);}); + threads.emplace_back ([&test_read] {test_read (false /* timeout */);}); + } // While the threads are busy, let's test the skip/non_blocking modes // combination. @@ -550,7 +570,85 @@ main (int argc, const char* argv[]) t.join (); } - // Test setting and getting position via the non-standard fdbuf interface. + // Test (non-blocking) reading with getline_non_blocking(). + // + { + const string ln ( + "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"); + + string s; + for (size_t i (0); i < 300; ++i) + { + s += ln; + s += '\n'; + } + + const char* args[] = {argv[0], "-c", nullptr}; + + auto test_read = [&args, &s, &ln] () + { + try + { + process pr (args, -1, -1); + ofdstream os (move (pr.out_fd)); + + ifdstream is (move (pr.in_ofd), + fdstream_mode::non_blocking, + ios_base::badbit); + + os << s; + os.close (); + + fdselect_set fds {is.fd ()}; + fdselect_state& ist (fds[0]); + + string r; + for (string l; ist.fd != nullfd; ) + { + if (ist.fd != nullfd && getline_non_blocking (is, l)) + { + if (eof (is)) + ist.fd = nullfd; + else + { + assert (l == ln); + + r += l; + r += '\n'; + + l.clear (); + } + + continue; + } + + ifdselect (fds); + } + + is.close (); + + assert (r == s); + } + catch (const ios::failure&) + { + assert (false); + } + catch (const process_error&) + { + assert (false); + } + }; + + vector<thread> threads; + for (size_t i (0); i < 20; ++i) + threads.emplace_back (test_read); + + for (thread& t: threads) + t.join (); + } + + // Test setting and getting position via the non-standard fdstreambuf + // interface. // // Seek for read. // @@ -559,7 +657,7 @@ main (int argc, const char* argv[]) ifdstream is (f); - fdbuf* buf (dynamic_cast<fdbuf*> (is.rdbuf ())); + fdstreambuf* buf (dynamic_cast<fdstreambuf*> (is.rdbuf ())); assert (buf != nullptr); char c; @@ -602,7 +700,7 @@ main (int argc, const char* argv[]) { ifdstream is (f, fdopen_mode::in | fdopen_mode::out); - fdbuf* buf (dynamic_cast<fdbuf*> (is.rdbuf ())); + fdstreambuf* buf (dynamic_cast<fdstreambuf*> (is.rdbuf ())); assert (buf != nullptr); // Read till the end of the fragment. @@ -660,7 +758,7 @@ main (int argc, const char* argv[]) assert (static_cast<streamoff> (is.tellg ()) == 8); - const fdbuf* buf (dynamic_cast<const fdbuf*> (is.rdbuf ())); + const fdstreambuf* buf (dynamic_cast<const fdstreambuf*> (is.rdbuf ())); assert (buf != nullptr && buf->tellg () == 8); assert (from_stream (is) == "89"); @@ -679,7 +777,7 @@ main (int argc, const char* argv[]) assert (static_cast<streamoff> (os.tellp ()) == 2); - const fdbuf* buf (dynamic_cast<const fdbuf*> (os.rdbuf ())); + const fdstreambuf* buf (dynamic_cast<const fdstreambuf*> (os.rdbuf ())); assert (buf != nullptr && buf->tellp () == 2); os.close (); @@ -732,7 +830,7 @@ main (int argc, const char* argv[]) assert (static_cast<streamoff> (is.tellg ()) == 8); - const fdbuf* buf (dynamic_cast<const fdbuf*> (is.rdbuf ())); + const fdstreambuf* buf (dynamic_cast<const fdstreambuf*> (is.rdbuf ())); assert (buf != nullptr && buf->tellp () == 8); assert (from_stream (is) == "6789"); |