1 //===-- StreamTeeTest.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/Utility/StreamTee.h"
10 #include "lldb/Utility/StreamString.h"
11 #include "gtest/gtest.h"
13 using namespace lldb_private
;
15 TEST(StreamTeeTest
, DefaultConstructor
) {
16 // Test the default constructor.
18 ASSERT_EQ(0U, tee
.GetNumStreams());
21 TEST(StreamTeeTest
, Constructor1Stream
) {
22 // Test the constructor for a single stream.
23 lldb::StreamSP
s1(std::make_shared
<StreamString
>());
26 ASSERT_EQ(1U, tee
.GetNumStreams());
27 EXPECT_EQ(s1
, tee
.GetStreamAtIndex(0U));
30 TEST(StreamTeeTest
, Constructor2Streams
) {
31 // Test the constructor for two streams.
32 lldb::StreamSP
s1(std::make_shared
<StreamString
>());
33 lldb::StreamSP
s2(std::make_shared
<StreamString
>());
34 StreamTee
tee(s1
, s2
);
36 ASSERT_EQ(2U, tee
.GetNumStreams());
37 EXPECT_EQ(s1
, tee
.GetStreamAtIndex(0U));
38 EXPECT_EQ(s2
, tee
.GetStreamAtIndex(1U));
41 TEST(StreamTeeTest
, CopyConstructor
) {
42 // Test the copy constructor.
43 lldb::StreamSP
s1(std::make_shared
<StreamString
>());
44 lldb::StreamSP
s2(std::make_shared
<StreamString
>());
45 StreamTee
tee1(s1
, s2
);
48 ASSERT_EQ(2U, tee2
.GetNumStreams());
49 EXPECT_EQ(s1
, tee2
.GetStreamAtIndex(0U));
50 EXPECT_EQ(s2
, tee2
.GetStreamAtIndex(1U));
53 TEST(StreamTeeTest
, Assignment
) {
54 // Test the assignment of StreamTee.
55 lldb::StreamSP
s1(std::make_shared
<StreamString
>());
56 lldb::StreamSP
s2(std::make_shared
<StreamString
>());
57 StreamTee
tee1(s1
, s2
);
58 StreamTee tee2
= tee1
;
60 ASSERT_EQ(2U, tee2
.GetNumStreams());
61 EXPECT_EQ(s1
, tee2
.GetStreamAtIndex(0U));
62 EXPECT_EQ(s2
, tee2
.GetStreamAtIndex(1U));
65 TEST(StreamTeeTest
, Write
) {
66 // Test that write is sent out to all children.
67 auto ss1
= new StreamString();
68 auto ss2
= new StreamString();
69 lldb::StreamSP
s1(ss1
);
70 lldb::StreamSP
s2(ss2
);
71 StreamTee
tee(s1
, s2
);
76 ASSERT_EQ(2U, tee
.GetNumStreams());
77 EXPECT_EQ("foo", ss1
->GetString().str());
78 EXPECT_EQ("foo", ss2
->GetString().str());
82 EXPECT_EQ("foobar", ss1
->GetString().str());
83 EXPECT_EQ("foobar", ss2
->GetString().str());
87 struct FlushTestStream
: public Stream
{
88 unsigned m_flush_count
= false;
89 void Flush() override
{
92 size_t WriteImpl(const void *src
, size_t src_len
) override
{
98 TEST(StreamTeeTest
, Flush
) {
99 // Check that Flush is distributed to all streams.
100 auto fs1
= new FlushTestStream();
101 auto fs2
= new FlushTestStream();
102 lldb::StreamSP
s1(fs1
);
103 lldb::StreamSP
s2(fs2
);
104 StreamTee
tee(s1
, s2
);
109 ASSERT_EQ(2U, tee
.GetNumStreams());
110 EXPECT_EQ(1U, fs1
->m_flush_count
);
111 EXPECT_EQ(1U, fs2
->m_flush_count
);
115 EXPECT_EQ(2U, fs1
->m_flush_count
);
116 EXPECT_EQ(2U, fs2
->m_flush_count
);
119 TEST(StreamTeeTest
, AppendStream
) {
120 // Append new streams to our StreamTee.
121 auto ss1
= new StreamString();
122 auto ss2
= new StreamString();
123 lldb::StreamSP
s1(ss1
);
124 lldb::StreamSP
s2(ss2
);
128 ASSERT_EQ(0U, tee
.GetNumStreams());
130 tee
.AppendStream(s1
);
131 ASSERT_EQ(1U, tee
.GetNumStreams());
132 EXPECT_EQ(s1
, tee
.GetStreamAtIndex(0U));
134 tee
.AppendStream(s2
);
135 ASSERT_EQ(2U, tee
.GetNumStreams());
136 EXPECT_EQ(s1
, tee
.GetStreamAtIndex(0U));
137 EXPECT_EQ(s2
, tee
.GetStreamAtIndex(1U));
140 TEST(StreamTeeTest
, GetStreamAtIndexOutOfBounds
) {
141 // The index we check for is not in the bounds of the StreamTee.
142 lldb::StreamSP
s1(std::make_shared
<StreamString
>());
145 ASSERT_EQ(1U, tee
.GetNumStreams());
146 EXPECT_EQ(lldb::StreamSP(), tee
.GetStreamAtIndex(1));
149 TEST(StreamTeeTest
, GetStreamAtIndexOutOfBoundsEmpty
) {
150 // Same as above, but with an empty StreamTee.
152 ASSERT_EQ(0U, tee
.GetNumStreams());
153 EXPECT_EQ(lldb::StreamSP(), tee
.GetStreamAtIndex(0U));
154 EXPECT_EQ(lldb::StreamSP(), tee
.GetStreamAtIndex(1U));
157 TEST(StreamTeeTest
, SetStreamAtIndexOverwrite
) {
158 // We overwrite an existing stream at a given index.
159 lldb::StreamSP
s1(std::make_shared
<StreamString
>());
162 ASSERT_EQ(1U, tee
.GetNumStreams());
163 EXPECT_EQ(s1
, tee
.GetStreamAtIndex(0U));
164 EXPECT_EQ(lldb::StreamSP(), tee
.GetStreamAtIndex(1U));
166 lldb::StreamSP
s2(std::make_shared
<StreamString
>());
167 tee
.SetStreamAtIndex(0U, s2
);
168 EXPECT_EQ(1U, tee
.GetNumStreams());
169 EXPECT_EQ(s2
, tee
.GetStreamAtIndex(0U));
170 EXPECT_EQ(lldb::StreamSP(), tee
.GetStreamAtIndex(1));
173 TEST(StreamTeeTest
, SetStreamAtIndexOutOfBounds
) {
174 // We place a new stream out of the bounds of the current StreamTee.
175 lldb::StreamSP
s1(std::make_shared
<StreamString
>());
178 ASSERT_EQ(1U, tee
.GetNumStreams());
179 EXPECT_EQ(s1
, tee
.GetStreamAtIndex(0U));
180 EXPECT_EQ(lldb::StreamSP(), tee
.GetStreamAtIndex(1U));
182 // Place a new stream out of bounds of the current array. The StreamTee should
183 // resize itself until it can contain this index.
184 lldb::StreamSP
s2(std::make_shared
<StreamString
>());
185 tee
.SetStreamAtIndex(4U, s2
);
186 // Check that the vector has been resized.
187 EXPECT_EQ(5U, tee
.GetNumStreams());
188 // Is our stream at the right place?
189 EXPECT_EQ(s2
, tee
.GetStreamAtIndex(4U));
191 // Existing stream should still be there.
192 EXPECT_EQ(s1
, tee
.GetStreamAtIndex(0U));
193 // Other elements are all invalid StreamSPs.
194 EXPECT_EQ(lldb::StreamSP(), tee
.GetStreamAtIndex(1U));
195 EXPECT_EQ(lldb::StreamSP(), tee
.GetStreamAtIndex(2U));
196 EXPECT_EQ(lldb::StreamSP(), tee
.GetStreamAtIndex(3U));
197 EXPECT_EQ(lldb::StreamSP(), tee
.GetStreamAtIndex(5U));