1// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "base/message_loop/message_loop.h" 6#include "base/test/test_simple_task_runner.h" 7#include "content/browser/streams/stream.h" 8#include "content/browser/streams/stream_read_observer.h" 9#include "content/browser/streams/stream_registry.h" 10#include "content/browser/streams/stream_write_observer.h" 11#include "testing/gtest/include/gtest/gtest.h" 12 13namespace content { 14 15class StreamTest : public testing::Test { 16 public: 17 StreamTest() : producing_seed_key_(0) {} 18 19 virtual void SetUp() OVERRIDE { 20 registry_.reset(new StreamRegistry()); 21 } 22 23 // Create a new IO buffer of the given |buffer_size| and fill it with random 24 // data. 25 scoped_refptr<net::IOBuffer> NewIOBuffer(size_t buffer_size) { 26 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(buffer_size)); 27 char *bufferp = buffer->data(); 28 for (size_t i = 0; i < buffer_size; i++) 29 bufferp[i] = (i + producing_seed_key_) % (1 << sizeof(char)); 30 ++producing_seed_key_; 31 return buffer; 32 } 33 34 protected: 35 base::MessageLoop message_loop_; 36 scoped_ptr<StreamRegistry> registry_; 37 38 private: 39 int producing_seed_key_; 40}; 41 42class TestStreamReader : public StreamReadObserver { 43 public: 44 TestStreamReader() : buffer_(new net::GrowableIOBuffer()) { 45 } 46 virtual ~TestStreamReader() {} 47 48 void Read(Stream* stream) { 49 const size_t kBufferSize = 32768; 50 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize)); 51 52 int bytes_read = 0; 53 while (stream->ReadRawData(buffer.get(), kBufferSize, &bytes_read) == 54 Stream::STREAM_HAS_DATA) { 55 size_t old_capacity = buffer_->capacity(); 56 buffer_->SetCapacity(old_capacity + bytes_read); 57 memcpy(buffer_->StartOfBuffer() + old_capacity, 58 buffer->data(), bytes_read); 59 } 60 } 61 62 virtual void OnDataAvailable(Stream* stream) OVERRIDE { 63 Read(stream); 64 } 65 66 scoped_refptr<net::GrowableIOBuffer> buffer() { return buffer_; } 67 68 private: 69 scoped_refptr<net::GrowableIOBuffer> buffer_; 70}; 71 72class TestStreamWriter : public StreamWriteObserver { 73 public: 74 TestStreamWriter() {} 75 virtual ~TestStreamWriter() {} 76 77 void Write(Stream* stream, 78 scoped_refptr<net::IOBuffer> buffer, 79 size_t buffer_size) { 80 stream->AddData(buffer, buffer_size); 81 } 82 83 virtual void OnSpaceAvailable(Stream* stream) OVERRIDE { 84 } 85 86 virtual void OnClose(Stream* stream) OVERRIDE { 87 } 88}; 89 90TEST_F(StreamTest, SetReadObserver) { 91 TestStreamReader reader; 92 TestStreamWriter writer; 93 94 GURL url("blob://stream"); 95 scoped_refptr<Stream> stream( 96 new Stream(registry_.get(), &writer, url)); 97 EXPECT_TRUE(stream->SetReadObserver(&reader)); 98} 99 100TEST_F(StreamTest, SetReadObserver_SecondFails) { 101 TestStreamReader reader1; 102 TestStreamReader reader2; 103 TestStreamWriter writer; 104 105 GURL url("blob://stream"); 106 scoped_refptr<Stream> stream( 107 new Stream(registry_.get(), &writer, url)); 108 EXPECT_TRUE(stream->SetReadObserver(&reader1)); 109 EXPECT_FALSE(stream->SetReadObserver(&reader2)); 110} 111 112TEST_F(StreamTest, SetReadObserver_TwoReaders) { 113 TestStreamReader reader1; 114 TestStreamReader reader2; 115 TestStreamWriter writer; 116 117 GURL url("blob://stream"); 118 scoped_refptr<Stream> stream( 119 new Stream(registry_.get(), &writer, url)); 120 EXPECT_TRUE(stream->SetReadObserver(&reader1)); 121 122 // Once the first read observer is removed, a new one can be added. 123 stream->RemoveReadObserver(&reader1); 124 EXPECT_TRUE(stream->SetReadObserver(&reader2)); 125} 126 127TEST_F(StreamTest, Stream) { 128 TestStreamReader reader; 129 TestStreamWriter writer; 130 131 GURL url("blob://stream"); 132 scoped_refptr<Stream> stream( 133 new Stream(registry_.get(), &writer, url)); 134 EXPECT_TRUE(stream->SetReadObserver(&reader)); 135 136 const int kBufferSize = 1000000; 137 scoped_refptr<net::IOBuffer> buffer(NewIOBuffer(kBufferSize)); 138 writer.Write(stream.get(), buffer, kBufferSize); 139 stream->Finalize(); 140 reader.Read(stream.get()); 141 base::MessageLoop::current()->RunUntilIdle(); 142 143 ASSERT_EQ(reader.buffer()->capacity(), kBufferSize); 144 for (int i = 0; i < kBufferSize; i++) 145 EXPECT_EQ(buffer->data()[i], reader.buffer()->data()[i]); 146} 147 148TEST_F(StreamTest, GetStream) { 149 TestStreamWriter writer; 150 151 GURL url("blob://stream"); 152 scoped_refptr<Stream> stream1( 153 new Stream(registry_.get(), &writer, url)); 154 155 scoped_refptr<Stream> stream2 = registry_->GetStream(url); 156 ASSERT_EQ(stream1, stream2); 157} 158 159TEST_F(StreamTest, GetStream_Missing) { 160 TestStreamWriter writer; 161 162 GURL url1("blob://stream"); 163 scoped_refptr<Stream> stream1( 164 new Stream(registry_.get(), &writer, url1)); 165 166 GURL url2("blob://stream2"); 167 scoped_refptr<Stream> stream2 = registry_->GetStream(url2); 168 ASSERT_FALSE(stream2.get()); 169} 170 171TEST_F(StreamTest, CloneStream) { 172 TestStreamWriter writer; 173 174 GURL url1("blob://stream"); 175 scoped_refptr<Stream> stream1( 176 new Stream(registry_.get(), &writer, url1)); 177 178 GURL url2("blob://stream2"); 179 ASSERT_TRUE(registry_->CloneStream(url2, url1)); 180 scoped_refptr<Stream> stream2 = registry_->GetStream(url2); 181 ASSERT_EQ(stream1, stream2); 182} 183 184TEST_F(StreamTest, CloneStream_Missing) { 185 TestStreamWriter writer; 186 187 GURL url1("blob://stream"); 188 scoped_refptr<Stream> stream1( 189 new Stream(registry_.get(), &writer, url1)); 190 191 GURL url2("blob://stream2"); 192 GURL url3("blob://stream3"); 193 ASSERT_FALSE(registry_->CloneStream(url2, url3)); 194 scoped_refptr<Stream> stream2 = registry_->GetStream(url2); 195 ASSERT_FALSE(stream2.get()); 196} 197 198TEST_F(StreamTest, UnregisterStream) { 199 TestStreamWriter writer; 200 201 GURL url("blob://stream"); 202 scoped_refptr<Stream> stream1( 203 new Stream(registry_.get(), &writer, url)); 204 205 registry_->UnregisterStream(url); 206 scoped_refptr<Stream> stream2 = registry_->GetStream(url); 207 ASSERT_FALSE(stream2.get()); 208} 209 210} // namespace content 211