================ @@ -47,5 +50,92 @@ TEST_F(PipeTest, OpenAsReader) { ASSERT_THAT_ERROR( pipe.OpenAsReader(name_ref, /*child_process_inherit=*/false).ToError(), llvm::Succeeded()); + + ASSERT_TRUE(pipe.CanRead()); } #endif + +TEST_F(PipeTest, WriteWithTimeout) { + Pipe pipe; + ASSERT_THAT_ERROR(pipe.CreateNew(false).ToError(), llvm::Succeeded()); + // Note write_chunk_size must be less than the pipe buffer. + // The pipe buffer is 1024 for PipeWindows and at least 512 on Darwin. + const size_t buf_size = 8192; + const size_t write_chunk_size = 234; + + std::vector<int32_t> write_buf(buf_size / sizeof(int32_t)); + std::iota(write_buf.begin(), write_buf.end(), 0); + std::vector<int32_t> read_buf(write_buf.size() + 100, -1); + + char *write_ptr = (char *)&write_buf.front(); + char *read_ptr = (char *)&read_buf.front(); + size_t write_bytes = 0; + size_t read_bytes = 0; + size_t num_bytes = 0; + + // Write to the pipe until it is full. + while (write_bytes < buf_size) { + Status error = + pipe.WriteWithTimeout(write_ptr + write_bytes, write_chunk_size, + std::chrono::milliseconds(10), num_bytes); + if (error.Fail()) + break; // The write buffer is full + write_bytes += num_bytes; + } + ASSERT_TRUE(write_bytes + write_chunk_size <= buf_size); + + // Attempt a write with a long timeout. + auto start_time = std::chrono::steady_clock::now(); + ASSERT_THAT_ERROR( + pipe.WriteWithTimeout(write_ptr + write_bytes, write_chunk_size, + std::chrono::milliseconds(2000), num_bytes) + .ToError(), + llvm::Failed()); + auto dur = std::chrono::duration_cast<std::chrono::milliseconds>( + std::chrono::steady_clock::now() - start_time) + .count(); + ASSERT_GE(dur, 2000); + + // Attempt a write with a short timeout + start_time = std::chrono::steady_clock::now(); + ASSERT_THAT_ERROR( + pipe.WriteWithTimeout(write_ptr + write_bytes, write_chunk_size, + std::chrono::milliseconds(200), num_bytes) + .ToError(), + llvm::Failed()); + dur = std::chrono::duration_cast<std::chrono::milliseconds>( + std::chrono::steady_clock::now() - start_time) + .count(); + ASSERT_GE(dur, 200); + ASSERT_LT(dur, 300); ---------------- labath wrote:
This is going to be flaky when the test is run on a loaded machine. To be safe, this needs to be at least an order of magnitude larger than the expected timeout (so e.g. to check that this took less than 2 seconds). But that's fine, the main thing I wanted to check by this is that it does not wait ~forever (like with the bug you found where we multiplied by 1000 instead of dividing). https://github.com/llvm/llvm-project/pull/101383 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits