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

Side by Side Diff: content/browser/renderer_host/media/audio_input_sync_writer_unittest.cc

Issue 1302423006: Ensure that data is not overwritten in the audio input shared memory ring buffer that sits on the b… (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Code review. Created 5 years, 3 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 "base/memory/scoped_ptr.h"
6 #include "base/sync_socket.h"
7 #include "base/time/time.h"
8 #include "content/browser/renderer_host/media/audio_input_sync_writer.h"
9 #include "content/public/test/test_browser_thread_bundle.h"
10 #include "media/audio/audio_parameters.h"
11 #include "media/base/audio_bus.h"
12 #include "media/base/channel_layout.h"
13 #include "testing/gmock/include/gmock/gmock.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15
16 using ::testing::_;
17 using base::TimeDelta;
18 using media::AudioBus;
19 using media::AudioParameters;
20
21 namespace content {
22
23 // Mocked out sockets used for Send/ReceiveWithTimeout. Counts the number of
24 // outstanding reads, i.e. the diff between send and receive calls.
25 class MockCancelableSyncSocket : public base::CancelableSyncSocket {
26 public:
27 MockCancelableSyncSocket(int buffer_size)
28 : in_failure_mode_(false),
29 writes_(0),
30 reads_(0),
31 receives_(0),
32 buffer_size_(buffer_size),
33 read_buffer_index_(0) {}
34
35 size_t Send(const void* buffer, size_t length) override {
36 EXPECT_EQ(length, sizeof(uint32_t));
37
38 ++writes_;
39 EXPECT_LE(NumberOfBuffersFilled(), buffer_size_);
40 return length;
41 }
42
43 size_t ReceiveWithTimeout(void* buffer, size_t length,
44 TimeDelta timeout) override {
45 EXPECT_EQ(length, sizeof(uint32_t));
46
47 if (in_failure_mode_)
48 return 0;
49 if (receives_ == reads_)
50 return 0;
51
52 ++receives_;
53 EXPECT_LE(receives_, reads_);
54 ++read_buffer_index_;
55 *static_cast<uint32_t*>(buffer) = read_buffer_index_;
56 return length;
57 }
58
59 size_t Peek() override {
60 return (reads_ - receives_) * sizeof(uint32_t);
61 }
62
63 // Simluates reading |buffers| number of buffers from the ring buffer.
64 void Read(int buffers) {
65 reads_ += buffers;
66 EXPECT_LE(reads_, writes_);
67 }
68
69 // When |in_failure_mode_| == true, the socket fails to receive.
70 void SetFailureMode(bool in_failure_mode) {
71 in_failure_mode_ = in_failure_mode;
72 }
73
74 int NumberOfBuffersFilled() { return writes_ - reads_; }
75
76 private:
77 bool in_failure_mode_;
78 int writes_;
79 int reads_;
80 int receives_;
81 int buffer_size_;
82 uint32_t read_buffer_index_;
83
84 DISALLOW_COPY_AND_ASSIGN(MockCancelableSyncSocket);
85 };
86
87 class AudioInputSyncWriterUnderTest : public AudioInputSyncWriter {
88 public:
89 AudioInputSyncWriterUnderTest(void* shared_memory,
90 size_t shared_memory_size,
91 int shared_memory_segment_count,
92 const media::AudioParameters& params,
93 base::CancelableSyncSocket* socket)
94 : AudioInputSyncWriter(shared_memory, shared_memory_size,
95 shared_memory_segment_count, params) {
96 socket_.reset(socket);
97 }
98
99 ~AudioInputSyncWriterUnderTest() override {}
100
101 MOCK_METHOD1(AddToNativeLog, void(const std::string& message));
102 };
103
104 class AudioInputSyncWriterTest : public testing::Test {
105 public:
106 AudioInputSyncWriterTest()
107 : socket_(nullptr) {
108 const media::ChannelLayout layout =
109 media::ChannelLayout::CHANNEL_LAYOUT_MONO;
110 const int channels = media::ChannelLayoutToChannelCount(layout);
111 const int sampling_frequency_hz = 16000;
112 const int frames = sampling_frequency_hz / 100; // 10 ms
113 const int bits_per_sample = 16;
114
115 AudioParameters audio_params(
116 AudioParameters::AUDIO_FAKE, layout, channels,
117 sampling_frequency_hz, bits_per_sample, frames);
118
119 const uint32 segment_size =
120 sizeof(media::AudioInputBufferParameters) +
121 AudioBus::CalculateMemorySize(audio_params);
122 size_t data_size = kSegments * segment_size;
123 data_.reset(new uint8[data_size]);
124
125 socket_ = new MockCancelableSyncSocket(kSegments);
126 writer_.reset(new AudioInputSyncWriterUnderTest(
127 data_.get(), data_size, kSegments, audio_params, socket_));
128 audio_bus_ = AudioBus::Create(audio_params);
129 }
130
131 ~AudioInputSyncWriterTest() override {
132 }
133
134 protected:
135 const int kSegments = 10;
136
137 scoped_ptr<AudioInputSyncWriterUnderTest> writer_;
138 MockCancelableSyncSocket* socket_;
139 scoped_ptr<AudioBus> audio_bus_;
140 scoped_ptr<uint8[]> data_;
141
142 private:
143 TestBrowserThreadBundle thread_bundle_;
144
145 DISALLOW_COPY_AND_ASSIGN(AudioInputSyncWriterTest);
146 };
147
148 TEST_F(AudioInputSyncWriterTest, SingleWriteAndRead) {
149 // We always expect one log call at first write.
150 EXPECT_CALL(*writer_.get(), AddToNativeLog(_));
151
152 writer_->Write(audio_bus_.get(), 0, false, 0);
153 EXPECT_EQ(1, socket_->NumberOfBuffersFilled());
154 EXPECT_EQ(0u, socket_->Peek());
155
156 socket_->Read(1);
157 EXPECT_EQ(0, socket_->NumberOfBuffersFilled());
158 EXPECT_EQ(sizeof(uint32_t), socket_->Peek());
159 }
160
161 TEST_F(AudioInputSyncWriterTest, MultipleWritesAndReads) {
162 EXPECT_CALL(*writer_.get(), AddToNativeLog(_));
163
164 for (int i = 1; i <= 2 * kSegments; ++i) {
165 writer_->Write(audio_bus_.get(), 0, false, 0);
166 EXPECT_EQ(1, socket_->NumberOfBuffersFilled());
167 EXPECT_EQ(0u, socket_->Peek());
168
169 socket_->Read(1);
170 EXPECT_EQ(0, socket_->NumberOfBuffersFilled());
171 EXPECT_EQ(sizeof(uint32_t), socket_->Peek());
172 }
173 }
174
175 TEST_F(AudioInputSyncWriterTest, MultipleWritesNoReads) {
176 EXPECT_CALL(*writer_.get(), AddToNativeLog(_)).Times(1 + kSegments);
177
178 for (int i = 1; i <= kSegments; ++i) {
179 writer_->Write(audio_bus_.get(), 0, false, 0);
180 EXPECT_EQ(i, socket_->NumberOfBuffersFilled());
181 EXPECT_EQ(0u, socket_->Peek());
182 }
183
184 // Now the ring buffer is full, do more writes. We should get an extra error
185 // log call for each write. See top EXPECT_CALL.
186 for (int i = 1; i <= kSegments; ++i) {
187 writer_->Write(audio_bus_.get(), 0, false, 0);
188 EXPECT_EQ(kSegments, socket_->NumberOfBuffersFilled());
189 EXPECT_EQ(0u, socket_->Peek());
190 }
191 }
192
193 TEST_F(AudioInputSyncWriterTest, FillAndEmptyRingBuffer) {
194 EXPECT_CALL(*writer_.get(), AddToNativeLog(_)).Times(2);
195
196 // Fill ring buffer.
197 for (int i = 1; i <= kSegments; ++i) {
198 writer_->Write(audio_bus_.get(), 0, false, 0);
199 }
200 EXPECT_EQ(kSegments, socket_->NumberOfBuffersFilled());
201 EXPECT_EQ(0u, socket_->Peek());
202
203 // Empty half of the ring buffer.
204 int buffers_to_read = kSegments / 2;
205 socket_->Read(buffers_to_read);
206 EXPECT_EQ(kSegments - buffers_to_read, socket_->NumberOfBuffersFilled());
207 EXPECT_EQ(buffers_to_read * sizeof(uint32_t), socket_->Peek());
208
209 // Fill up again. The first write should do receive until that queue is
210 // empty.
211 for (int i = kSegments - buffers_to_read + 1; i <= kSegments; ++i) {
212 writer_->Write(audio_bus_.get(), 0, false, 0);
213 EXPECT_EQ(i, socket_->NumberOfBuffersFilled());
214 EXPECT_EQ(0u, socket_->Peek());
215 }
216
217 // Another write, should render and extra error log call.
218 writer_->Write(audio_bus_.get(), 0, false, 0);
219 EXPECT_EQ(kSegments, socket_->NumberOfBuffersFilled());
220 EXPECT_EQ(0u, socket_->Peek());
221
222 // Empty the ring buffer.
223 socket_->Read(kSegments);
224 EXPECT_EQ(0, socket_->NumberOfBuffersFilled());
225 EXPECT_EQ(kSegments * sizeof(uint32_t), socket_->Peek());
226
227 // Another write, should do receive until that queue is empty.
228 writer_->Write(audio_bus_.get(), 0, false, 0);
229 EXPECT_EQ(1, socket_->NumberOfBuffersFilled());
230 EXPECT_EQ(0u, socket_->Peek());
231 }
232
233 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698