Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(157)

Side by Side Diff: media/blink/multibuffer_unittest.cc

Issue 1165903002: Multi reader/writer cache/buffer (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: more tests Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 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 <deque>
6 #include <string>
7 #include <vector>
8
9 #include "base/bind.h"
10 #include "base/callback_helpers.h"
11 #include "media/blink/multibuffer.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13
14 const int kBlockSizeShift = 8;
15 const size_t kBlockSize = 1UL << kBlockSizeShift;
16
17 namespace media {
18 class TestMultiBufferDataProvider;
19
20 std::vector<TestMultiBufferDataProvider*> writers;
21
22 class TestMultiBufferDataProvider : public media::MultiBufferDataProvider {
23 public:
24 TestMultiBufferDataProvider(MultiBufferBlockId pos) :
25 pos_(pos),
26 deferred_(false) {
27 writers.push_back(this);
28 }
29
30 ~TestMultiBufferDataProvider() override {
31 for (size_t i = 0; i < writers.size(); i++) {
32 if (writers[i] == this) {
33 writers[i] = writers.back();
34 writers.pop_back();
35 return;
36 }
37 }
38 LOG(FATAL) << "Couldn't find myself in writers!";
39 }
40
41 MultiBufferBlockId Tell() const override {
42 return pos_;
43 }
44
45 bool Available() const override {
46 return !fifo_.empty();
47 }
48
49 scoped_refptr<DataBuffer> Read() override {
50 DCHECK(Available());
51 scoped_refptr<DataBuffer> ret = fifo_.front();
52 fifo_.pop_front();
53 ++pos_;
54 return ret;
55 }
56
57 void SetAvailableCallback(base::Closure cb) override {
58 DCHECK(!Available());
59 cb_ = cb;
60 }
61
62 void SetDeferred(bool deferred) override {
63 deferred_ = deferred;
64 }
65
66 bool Advance() {
67 // TODO(hubbe): simulate that we sometimes get data even
68 // after we're deferred.
69 // TODO(hubbe): Add EOF block.
70 // TODO(hubbe): Let last block be smaller.
71 if (deferred_) return false;
72
73 scoped_refptr<media::DataBuffer> block = new media::DataBuffer(kBlockSize);
74 for (size_t x = 0; x < kBlockSize; x++) {
75 size_t byte_pos = (pos_.block_num() * kBlockSize) + x;
76 block->writable_data()[x] = (byte_pos * 15485863) >> 16;
77 }
78 block->set_data_size(kBlockSize);
79 fifo_.push_back(block);
80 cb_.Run();
81 return true;
82 }
83
84 private:
85 std::deque<scoped_refptr<media::DataBuffer> > fifo_;
86 MultiBufferBlockId pos_;
87 bool deferred_;
88 base::Closure cb_;
89 };
90
91 class TestMultiBuffer : public media::MultiBuffer {
92 public:
93 explicit TestMultiBuffer(int32_t shift) :
94 media::MultiBuffer(shift),
95 max_writers_(10000) {
96 }
97
98 void SetMaxWriters(size_t max_writers) {
99 max_writers_ = max_writers;
100 }
101
102 void CheckLRUState() {
103 for (DataMap::iterator i = data_.begin();
104 i != data_.end();
105 ++i) {
106 CHECK(i->second); // Null poineters are not allowed in data_
107 CHECK_NE(!!pinned_[i->first], lru_.Contains(i->first))
108 << " i->first = " << i->first;
109 }
110 }
111
112 protected:
113 MultiBufferDataProvider* CreateWriter(MultiBufferBlockId pos) override {
114 CHECK_LE(writers.size(), max_writers_);
115 CheckLRUState();
116 return new TestMultiBufferDataProvider(pos);
117 }
118 private:
119 size_t max_writers_;
120 };
121
122 }
123
124 class MultiBufferTest : public testing::Test {
125 public:
126 MultiBufferTest() :
127 multibuffer_(kBlockSizeShift) {
128 }
129
130 void Advance() {
131 CHECK(media::writers.size());
132 media::writers[rand() % media::writers.size()]->Advance();
133 multibuffer_.CheckLRUState();
134 }
135
136 bool AdvanceAll() {
137 bool advanced = false;
138 for (size_t i = 0; i < media::writers.size(); i++) {
139 advanced |= media::writers[i]->Advance();
140 }
141 multibuffer_.CheckLRUState();
142 return advanced;
143 }
144
145 scoped_refptr<media::UrlData> GetUrl() {
146 return url_index_.GetByUrl(GURL("http://x"), media::UrlData::kUnspecified);
147 }
148
149 protected:
150 media::TestMultiBuffer multibuffer_;
151 media::UrlIndex url_index_;
152 };
153
154 TEST_F(MultiBufferTest, ReadAll) {
155 multibuffer_.SetMaxWriters(1);
156 size_t pos = 0;
157 size_t end = 10000;
158 media::MultiBufferReader reader(&multibuffer_,
159 GetUrl(),
160 pos,
161 end,
162 1000,
163 1000,
164 5000,
165 2000,
166 base::Callback<void(int64_t, int64_t)>());
167 while (pos < end) {
168 unsigned char buffer[27];
169 buffer[17] = 17;
170 size_t to_read = std::min<size_t>(end - pos, 17);
171 int64 bytes_read = reader.TryRead(buffer, to_read);
172 if (bytes_read) {
173 EXPECT_EQ(buffer[17], 17);
174 for (size_t i = 0; i < bytes_read; i++) {
175 unsigned char expected = (pos * 15485863) >> 16;
176 EXPECT_EQ(expected, buffer[i]) << " pos = " << pos;
177 pos++;
178 }
179 } else {
180 Advance();
181 }
182 }
183 }
184
185 TEST_F(MultiBufferTest, ReadAllAdvanceFirst) {
186 multibuffer_.SetMaxWriters(1);
187 size_t pos = 0;
188 size_t end = 10000;
189 media::MultiBufferReader reader(&multibuffer_,
190 GetUrl(),
191 pos,
192 end,
193 1000,
194 1000,
195 5000,
196 2000,
197 base::Callback<void(int64_t, int64_t)>());
198 while (pos < end) {
199 unsigned char buffer[27];
200 buffer[17] = 17;
201 size_t to_read = std::min<size_t>(end - pos, 17);
202 while (AdvanceAll());
203 EXPECT_TRUE(reader.TryRead(buffer, to_read));
204 EXPECT_EQ(buffer[17], 17);
205 for (size_t i = 0; i < to_read; i++) {
206 unsigned char expected = (pos * 15485863) >> 16;
207 EXPECT_EQ(expected, buffer[i]) << " pos = " << pos;
208 pos++;
209 }
210 }
211 }
212
213 class ReadHelper {
214 public:
215 ReadHelper(scoped_refptr<media::UrlData> url,
216 size_t end,
217 size_t max_read_size,
218 media::MultiBuffer* multibuffer) :
219 pos_(0),
220 end_(end),
221 max_read_size_(max_read_size),
222 read_size_(0),
223 reader_(multibuffer,
224 url,
225 pos_,
226 end_,
227 1000,
228 1000,
229 5000,
230 2000,
231 base::Callback<void(int64_t, int64_t)>()) {
232 }
233
234 bool Read() {
235 if (read_size_ == 0) return true;
236 unsigned char buffer[read_size_];
237 CHECK_EQ(pos_, reader_.Tell());
238 int64 bytes_read = reader_.TryRead(buffer, read_size_);
239 if (bytes_read) {
240 for (size_t i = 0; i < bytes_read; i++) {
241 unsigned char expected = (pos_ * 15485863) >> 16;
242 EXPECT_EQ(expected, buffer[i]) << " pos = " << pos_;
243 pos_++;
244 }
245 CHECK_EQ(pos_, reader_.Tell());
246 return true;
247 }
248 return false;
249 }
250
251 void StartRead() {
252 CHECK_EQ(pos_, reader_.Tell());
253 read_size_ = std::min(1 + rand() % (max_read_size_ - 1), end_ - pos_);
254 if (!Read()) {
255 reader_.Wait(read_size_,
256 base::Bind(&ReadHelper::WaitCB, base::Unretained(this)));
257 }
258 }
259
260 void WaitCB() {
261 CHECK(Read());
262 }
263
264 void Seek() {
265 pos_ = rand() % end_;
266 reader_.Seek(pos_);
267 CHECK_EQ(pos_, reader_.Tell());
268 }
269
270 private:
271 size_t pos_;
272 size_t end_;
273 size_t max_read_size_;
274 size_t read_size_;
275 media::MultiBufferReader reader_;
276 };
277
278 TEST_F(MultiBufferTest, RandomTest) {
279 std::vector<ReadHelper*> read_helpers;
280 scoped_refptr<media::UrlData> url = GetUrl();
281 for (size_t i = 0; i < 20; i++) {
282 read_helpers.push_back(new ReadHelper(url, 1000000, 1000, &multibuffer_));
283 }
284 for (int i = 0; i < 10000; i++) {
285 if (rand() & 1) {
286 if (!media::writers.empty()) Advance();
287 } else {
288 size_t j = rand() % read_helpers.size();
289 if (rand() % 100 < 3) {
290 read_helpers[j]->Seek();
291 multibuffer_.CheckLRUState();
292 }
293 read_helpers[j]->StartRead();
294 multibuffer_.CheckLRUState();
295 }
296 }
297 while (!read_helpers.empty()) {
298 delete read_helpers.back();
299 read_helpers.pop_back();
300 }
301 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698