1 //===-- PipeTest.cpp ------------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "lldb/Host/Pipe.h"
10 #include "TestingSupport/SubsystemRAII.h"
11 #include "lldb/Host/FileSystem.h"
12 #include "lldb/Host/HostInfo.h"
13 #include "gtest/gtest.h"
18 using namespace lldb_private
;
20 class PipeTest
: public testing::Test
{
22 SubsystemRAII
<FileSystem
, HostInfo
> subsystems
;
25 TEST_F(PipeTest
, CreateWithUniqueName
) {
27 llvm::SmallString
<0> name
;
28 ASSERT_THAT_ERROR(pipe
.CreateWithUniqueName("PipeTest-CreateWithUniqueName",
29 /*child_process_inherit=*/false,
37 TEST_F(PipeTest
, OpenAsReader
) {
39 llvm::SmallString
<0> name
;
40 ASSERT_THAT_ERROR(pipe
.CreateWithUniqueName("PipeTest-OpenAsReader",
41 /*child_process_inherit=*/false,
46 // Ensure name is not null-terminated
47 size_t name_len
= name
.size();
49 llvm::StringRef
name_ref(name
.data(), name_len
);
51 pipe
.OpenAsReader(name_ref
, /*child_process_inherit=*/false).ToError(),
54 ASSERT_TRUE(pipe
.CanRead());
58 TEST_F(PipeTest
, WriteWithTimeout
) {
60 ASSERT_THAT_ERROR(pipe
.CreateNew(false).ToError(), llvm::Succeeded());
62 // The pipe buffer is 1024 for PipeWindows and at least 512 on Darwin.
63 // In Linux versions before 2.6.11, the capacity of a pipe was the same as the
64 // system page size (e.g., 4096 bytes on i386).
65 // Since Linux 2.6.11, the pipe capacity is 16 pages (i.e., 65,536 bytes in a
66 // system with a page size of 4096 bytes).
67 // Since Linux 2.6.35, the default pipe capacity is 16 pages, but the capacity
68 // can be queried and set using the fcntl(2) F_GETPIPE_SZ and F_SETPIPE_SZ
71 #if !defined(_WIN32) && defined(F_SETPIPE_SZ)
72 ::fcntl(pipe
.GetWriteFileDescriptor(), F_SETPIPE_SZ
, 4096);
75 const size_t buf_size
= 66000;
77 // Note write_chunk_size must be less than the pipe buffer.
78 const size_t write_chunk_size
= 234;
80 std::vector
<int32_t> write_buf(buf_size
/ sizeof(int32_t));
81 std::iota(write_buf
.begin(), write_buf
.end(), 0);
82 std::vector
<int32_t> read_buf(write_buf
.size() + 100, -1);
84 char *write_ptr
= reinterpret_cast<char *>(write_buf
.data());
85 char *read_ptr
= reinterpret_cast<char *>(read_buf
.data());
86 size_t write_bytes
= 0;
87 size_t read_bytes
= 0;
90 // Write to the pipe until it is full.
91 while (write_bytes
+ write_chunk_size
<= buf_size
) {
93 pipe
.WriteWithTimeout(write_ptr
+ write_bytes
, write_chunk_size
,
94 std::chrono::milliseconds(10), num_bytes
);
96 break; // The write buffer is full.
97 write_bytes
+= num_bytes
;
99 ASSERT_LE(write_bytes
+ write_chunk_size
, buf_size
)
100 << "Pipe buffer larger than expected";
102 // Attempt a write with a long timeout.
103 auto start_time
= std::chrono::steady_clock::now();
104 ASSERT_THAT_ERROR(pipe
.WriteWithTimeout(write_ptr
+ write_bytes
,
106 std::chrono::seconds(2), num_bytes
)
109 auto dur
= std::chrono::steady_clock::now() - start_time
;
110 ASSERT_GE(dur
, std::chrono::seconds(2));
112 // Attempt a write with a short timeout.
113 start_time
= std::chrono::steady_clock::now();
115 pipe
.WriteWithTimeout(write_ptr
+ write_bytes
, write_chunk_size
,
116 std::chrono::milliseconds(200), num_bytes
)
119 dur
= std::chrono::steady_clock::now() - start_time
;
120 ASSERT_GE(dur
, std::chrono::milliseconds(200));
121 ASSERT_LT(dur
, std::chrono::seconds(2));
124 while (read_bytes
< write_bytes
) {
126 pipe
.ReadWithTimeout(read_ptr
+ read_bytes
, write_bytes
- read_bytes
,
127 std::chrono::milliseconds(10), num_bytes
)
130 read_bytes
+= num_bytes
;
133 // Be sure the pipe is empty.
134 ASSERT_THAT_ERROR(pipe
.ReadWithTimeout(read_ptr
+ read_bytes
, 100,
135 std::chrono::milliseconds(10),
140 // Check that we got what we wrote.
141 ASSERT_EQ(write_bytes
, read_bytes
);
142 ASSERT_TRUE(std::equal(write_buf
.begin(),
143 write_buf
.begin() + write_bytes
/ sizeof(uint32_t),
146 // Write to the pipe again and check that it succeeds.
147 ASSERT_THAT_ERROR(pipe
.WriteWithTimeout(write_ptr
, write_chunk_size
,
148 std::chrono::milliseconds(10),