199 lines · cpp
1//===-- StreamTeeTest.cpp -------------------------------------------------===//2//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-exception6//7//===----------------------------------------------------------------------===//8 9#include "lldb/Utility/StreamTee.h"10#include "lldb/Utility/StreamString.h"11#include "gtest/gtest.h"12 13using namespace lldb_private;14 15TEST(StreamTeeTest, DefaultConstructor) {16 // Test the default constructor.17 StreamTee tee;18 ASSERT_EQ(0U, tee.GetNumStreams());19}20 21TEST(StreamTeeTest, Constructor1Stream) {22 // Test the constructor for a single stream.23 lldb::StreamSP s1(std::make_shared<StreamString>());24 StreamTee tee(s1);25 26 ASSERT_EQ(1U, tee.GetNumStreams());27 EXPECT_EQ(s1, tee.GetStreamAtIndex(0U));28}29 30TEST(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);35 36 ASSERT_EQ(2U, tee.GetNumStreams());37 EXPECT_EQ(s1, tee.GetStreamAtIndex(0U));38 EXPECT_EQ(s2, tee.GetStreamAtIndex(1U));39}40 41TEST(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);46 StreamTee tee2(tee1);47 48 ASSERT_EQ(2U, tee2.GetNumStreams());49 EXPECT_EQ(s1, tee2.GetStreamAtIndex(0U));50 EXPECT_EQ(s2, tee2.GetStreamAtIndex(1U));51}52 53TEST(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;59 60 ASSERT_EQ(2U, tee2.GetNumStreams());61 EXPECT_EQ(s1, tee2.GetStreamAtIndex(0U));62 EXPECT_EQ(s2, tee2.GetStreamAtIndex(1U));63}64 65TEST(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);72 73 tee << "foo";74 tee.Flush();75 76 ASSERT_EQ(2U, tee.GetNumStreams());77 EXPECT_EQ("foo", ss1->GetString().str());78 EXPECT_EQ("foo", ss2->GetString().str());79 80 tee << "bar";81 tee.Flush();82 EXPECT_EQ("foobar", ss1->GetString().str());83 EXPECT_EQ("foobar", ss2->GetString().str());84}85 86namespace {87 struct FlushTestStream : public Stream {88 unsigned m_flush_count = false;89 void Flush() override {90 ++m_flush_count;91 }92 size_t WriteImpl(const void *src, size_t src_len) override {93 return src_len;94 }95 };96}97 98TEST(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);105 106 tee << "foo";107 tee.Flush();108 109 ASSERT_EQ(2U, tee.GetNumStreams());110 EXPECT_EQ(1U, fs1->m_flush_count);111 EXPECT_EQ(1U, fs2->m_flush_count);112 113 tee << "bar";114 tee.Flush();115 EXPECT_EQ(2U, fs1->m_flush_count);116 EXPECT_EQ(2U, fs2->m_flush_count);117}118 119TEST(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);125 126 StreamTee tee;127 128 ASSERT_EQ(0U, tee.GetNumStreams());129 130 tee.AppendStream(s1);131 ASSERT_EQ(1U, tee.GetNumStreams());132 EXPECT_EQ(s1, tee.GetStreamAtIndex(0U));133 134 tee.AppendStream(s2);135 ASSERT_EQ(2U, tee.GetNumStreams());136 EXPECT_EQ(s1, tee.GetStreamAtIndex(0U));137 EXPECT_EQ(s2, tee.GetStreamAtIndex(1U));138}139 140TEST(StreamTeeTest, GetStreamAtIndexOutOfBounds) {141 // The index we check for is not in the bounds of the StreamTee.142 lldb::StreamSP s1(std::make_shared<StreamString>());143 StreamTee tee(s1);144 145 ASSERT_EQ(1U, tee.GetNumStreams());146 EXPECT_EQ(lldb::StreamSP(), tee.GetStreamAtIndex(1));147}148 149TEST(StreamTeeTest, GetStreamAtIndexOutOfBoundsEmpty) {150 // Same as above, but with an empty StreamTee.151 StreamTee tee;152 ASSERT_EQ(0U, tee.GetNumStreams());153 EXPECT_EQ(lldb::StreamSP(), tee.GetStreamAtIndex(0U));154 EXPECT_EQ(lldb::StreamSP(), tee.GetStreamAtIndex(1U));155}156 157TEST(StreamTeeTest, SetStreamAtIndexOverwrite) {158 // We overwrite an existing stream at a given index.159 lldb::StreamSP s1(std::make_shared<StreamString>());160 StreamTee tee(s1);161 162 ASSERT_EQ(1U, tee.GetNumStreams());163 EXPECT_EQ(s1, tee.GetStreamAtIndex(0U));164 EXPECT_EQ(lldb::StreamSP(), tee.GetStreamAtIndex(1U));165 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));171}172 173TEST(StreamTeeTest, SetStreamAtIndexOutOfBounds) {174 // We place a new stream out of the bounds of the current StreamTee.175 lldb::StreamSP s1(std::make_shared<StreamString>());176 StreamTee tee(s1);177 178 ASSERT_EQ(1U, tee.GetNumStreams());179 EXPECT_EQ(s1, tee.GetStreamAtIndex(0U));180 EXPECT_EQ(lldb::StreamSP(), tee.GetStreamAtIndex(1U));181 182 // Place a new stream out of bounds of the current array. The StreamTee should183 // 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));190 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));198}199