1 // Copyright (c) 2012 The Chromium OS 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 <gtest/gtest.h>
6 #include <stdio.h>
7
8 extern "C" {
9 #include "cras_shm.h"
10 #include "cras_types.h"
11 }
12
13 namespace {
14
15 class ShmTestSuite : public testing::Test {
16 protected:
SetUp()17 virtual void SetUp() {
18 memset(&shm_, 0, sizeof(shm_));
19 shm_.header =
20 static_cast<cras_audio_shm_header*>(calloc(1, sizeof(*shm_.header)));
21 shm_.samples = static_cast<uint8_t*>(calloc(1, 2048));
22 shm_.samples_info.length = 2048;
23 cras_shm_set_frame_bytes(&shm_, 4);
24
25 cras_shm_set_used_size(&shm_, 1024);
26 memcpy(&shm_.header->config, &shm_.config, sizeof(shm_.config));
27
28 frames_ = 0;
29 }
30
TearDown()31 virtual void TearDown() {
32 free(shm_.header);
33 free(shm_.samples);
34 }
35
36 struct cras_audio_shm shm_;
37 uint8_t* buf_;
38 size_t frames_;
39 };
40
41 // Test that and empty buffer returns 0 readable bytes.
TEST_F(ShmTestSuite,NoneReadableWhenEmpty)42 TEST_F(ShmTestSuite, NoneReadableWhenEmpty) {
43 buf_ = cras_shm_get_readable_frames(&shm_, 0, &frames_);
44 EXPECT_EQ(0, frames_);
45 cras_shm_buffer_read(&shm_, frames_);
46 EXPECT_EQ(0, shm_.header->read_offset[0]);
47 }
48
49 // Buffer with 100 frames filled.
TEST_F(ShmTestSuite,OneHundredFilled)50 TEST_F(ShmTestSuite, OneHundredFilled) {
51 shm_.header->write_offset[0] = 100 * shm_.header->config.frame_bytes;
52 buf_ = cras_shm_get_readable_frames(&shm_, 0, &frames_);
53 EXPECT_EQ(100, frames_);
54 EXPECT_EQ(shm_.samples, buf_);
55 cras_shm_buffer_read(&shm_, frames_ - 9);
56 EXPECT_EQ((frames_ - 9) * shm_.config.frame_bytes,
57 shm_.header->read_offset[0]);
58 cras_shm_buffer_read(&shm_, 9);
59 EXPECT_EQ(0, shm_.header->read_offset[0]);
60 EXPECT_EQ(1, shm_.header->read_buf_idx);
61 }
62
63 // Buffer with 100 frames filled, 50 read.
TEST_F(ShmTestSuite,OneHundredFilled50Read)64 TEST_F(ShmTestSuite, OneHundredFilled50Read) {
65 shm_.header->write_offset[0] = 100 * shm_.config.frame_bytes;
66 shm_.header->read_offset[0] = 50 * shm_.config.frame_bytes;
67 buf_ = cras_shm_get_readable_frames(&shm_, 0, &frames_);
68 EXPECT_EQ(50, frames_);
69 EXPECT_EQ((shm_.samples + shm_.header->read_offset[0]), buf_);
70 cras_shm_buffer_read(&shm_, frames_ - 10);
71 EXPECT_EQ(shm_.header->write_offset[0] - 10 * shm_.config.frame_bytes,
72 shm_.header->read_offset[0]);
73 cras_shm_buffer_read(&shm_, 10);
74 EXPECT_EQ(0, shm_.header->read_offset[0]);
75 }
76
77 // Buffer with 100 frames filled, 50 read, offset by 25.
TEST_F(ShmTestSuite,OneHundredFilled50Read25offset)78 TEST_F(ShmTestSuite, OneHundredFilled50Read25offset) {
79 shm_.header->write_offset[0] = 100 * shm_.config.frame_bytes;
80 shm_.header->read_offset[0] = 50 * shm_.config.frame_bytes;
81 buf_ = cras_shm_get_readable_frames(&shm_, 25, &frames_);
82 EXPECT_EQ(25, frames_);
83 EXPECT_EQ(shm_.samples + shm_.header->read_offset[0] +
84 25 * shm_.header->config.frame_bytes,
85 (uint8_t*)buf_);
86 }
87
88 // Test wrapping across buffers.
TEST_F(ShmTestSuite,WrapToNextBuffer)89 TEST_F(ShmTestSuite, WrapToNextBuffer) {
90 uint32_t used_size = cras_shm_used_size(&shm_);
91 uint32_t used_frames = used_size / cras_shm_frame_bytes(&shm_);
92 shm_.header->write_offset[0] = (used_size / 2);
93 shm_.header->read_offset[0] = (used_size / 4);
94 shm_.header->write_offset[1] = (used_size / 2);
95 buf_ = cras_shm_get_readable_frames(&shm_, 0, &frames_);
96 EXPECT_EQ(used_frames / 4, frames_);
97 EXPECT_EQ(cras_shm_buff_for_idx(&shm_, 0) + (used_size / 4), (uint8_t*)buf_);
98 buf_ = cras_shm_get_readable_frames(&shm_, frames_, &frames_);
99 EXPECT_EQ(used_frames / 2, frames_);
100 EXPECT_EQ(cras_shm_buff_for_idx(&shm_, 1), (uint8_t*)buf_);
101 /* Mark all but 10 frames as read */
102 cras_shm_buffer_read(&shm_, (used_frames / 2) + (used_frames / 4) - 10);
103 EXPECT_EQ(0, shm_.header->read_offset[0]);
104 EXPECT_EQ(((used_frames / 2) - 10) * shm_.config.frame_bytes,
105 shm_.header->read_offset[1]);
106 EXPECT_EQ(1, shm_.header->read_buf_idx);
107 }
108
109 // Test wrapping across buffers reading all samples.
TEST_F(ShmTestSuite,WrapToNextBufferReadAll)110 TEST_F(ShmTestSuite, WrapToNextBufferReadAll) {
111 uint32_t used_size = cras_shm_used_size(&shm_);
112 uint32_t used_frames = used_size / cras_shm_frame_bytes(&shm_);
113 shm_.header->write_offset[0] = (used_size / 2);
114 shm_.header->read_offset[0] = (used_size / 4);
115 shm_.header->write_offset[1] = (used_size / 2);
116 buf_ = cras_shm_get_readable_frames(&shm_, 0, &frames_);
117 EXPECT_EQ(used_frames / 4, frames_);
118 EXPECT_EQ(cras_shm_buff_for_idx(&shm_, 0) + (used_size / 4), (uint8_t*)buf_);
119 buf_ = cras_shm_get_readable_frames(&shm_, frames_, &frames_);
120 EXPECT_EQ(used_frames / 2, frames_);
121 EXPECT_EQ(cras_shm_buff_for_idx(&shm_, 1), (uint8_t*)buf_);
122 /* Mark all frames as read */
123 cras_shm_buffer_read(&shm_, (used_frames / 2) + (used_frames / 4));
124 EXPECT_EQ(0, shm_.header->read_offset[0]);
125 EXPECT_EQ(0, shm_.header->read_offset[1]);
126 EXPECT_EQ(0, shm_.header->read_buf_idx);
127 }
128
129 // Test wrapping last buffer.
TEST_F(ShmTestSuite,WrapFromFinalBuffer)130 TEST_F(ShmTestSuite, WrapFromFinalBuffer) {
131 uint32_t used_size = cras_shm_used_size(&shm_);
132 uint32_t used_frames = used_size / cras_shm_frame_bytes(&shm_);
133 uint32_t buf_idx = CRAS_NUM_SHM_BUFFERS - 1;
134
135 shm_.header->read_buf_idx = buf_idx;
136 shm_.header->write_offset[buf_idx] = (used_size / 2);
137 shm_.header->read_offset[buf_idx] = (used_size / 4);
138 shm_.header->write_offset[0] = (used_size / 2);
139 buf_ = cras_shm_get_readable_frames(&shm_, 0, &frames_);
140 EXPECT_EQ(used_frames / 4, frames_);
141 EXPECT_EQ(cras_shm_buff_for_idx(&shm_, buf_idx) + (used_size / 4),
142 (uint8_t*)buf_);
143
144 buf_ = cras_shm_get_readable_frames(&shm_, frames_, &frames_);
145 EXPECT_EQ(used_frames / 2, frames_);
146 EXPECT_EQ(cras_shm_buff_for_idx(&shm_, 0), (uint8_t*)buf_);
147 /* Mark all but 10 frames as read */
148 cras_shm_buffer_read(&shm_, (used_frames / 2) + (used_frames / 4) - 10);
149 EXPECT_EQ(0, shm_.header->read_offset[buf_idx]);
150 EXPECT_EQ(((used_frames / 2) - 10) * shm_.config.frame_bytes,
151 shm_.header->read_offset[0]);
152 EXPECT_EQ(0, shm_.header->read_buf_idx);
153 }
154
155 // Test Check available to write returns 0 if not free buffer.
TEST_F(ShmTestSuite,WriteAvailNotFree)156 TEST_F(ShmTestSuite, WriteAvailNotFree) {
157 size_t ret;
158 shm_.header->write_buf_idx = 0;
159 shm_.header->write_offset[0] = 100 * shm_.config.frame_bytes;
160 shm_.header->read_offset[0] = 50 * shm_.config.frame_bytes;
161 ret = cras_shm_get_num_writeable(&shm_);
162 EXPECT_EQ(0, ret);
163 }
164
165 // Test Check available to write returns num_frames if free buffer.
TEST_F(ShmTestSuite,WriteAvailValid)166 TEST_F(ShmTestSuite, WriteAvailValid) {
167 size_t ret;
168 shm_.header->write_buf_idx = 0;
169 shm_.config.used_size = 480 * shm_.config.frame_bytes;
170 shm_.header->write_offset[0] = 0;
171 shm_.header->read_offset[0] = 0;
172 ret = cras_shm_get_num_writeable(&shm_);
173 EXPECT_EQ(480, ret);
174 }
175
176 // Test get frames_written returns the number of frames written.
TEST_F(ShmTestSuite,GetNumWritten)177 TEST_F(ShmTestSuite, GetNumWritten) {
178 size_t ret;
179 shm_.header->write_buf_idx = 0;
180 shm_.config.used_size = 480 * shm_.config.frame_bytes;
181 shm_.header->write_offset[0] = 200 * shm_.config.frame_bytes;
182 shm_.header->read_offset[0] = 0;
183 ret = cras_shm_frames_written(&shm_);
184 EXPECT_EQ(200, ret);
185 }
186
187 // Test that getting the base of the write buffer returns the correct pointer.
TEST_F(ShmTestSuite,GetWriteBufferBase)188 TEST_F(ShmTestSuite, GetWriteBufferBase) {
189 uint8_t* ret;
190
191 shm_.header->write_buf_idx = 0;
192 shm_.header->write_offset[0] = 128 * shm_.config.frame_bytes;
193 shm_.header->write_offset[1] = 128 * shm_.config.frame_bytes;
194 shm_.header->read_offset[0] = 0;
195 shm_.header->read_offset[1] = 0;
196 ret = cras_shm_get_write_buffer_base(&shm_);
197 EXPECT_EQ(shm_.samples, ret);
198
199 shm_.header->write_buf_idx = 1;
200 ret = cras_shm_get_write_buffer_base(&shm_);
201 EXPECT_EQ(shm_.samples + shm_.config.used_size, ret);
202 }
203
TEST_F(ShmTestSuite,SetVolume)204 TEST_F(ShmTestSuite, SetVolume) {
205 cras_shm_set_volume_scaler(&shm_, 1.0);
206 EXPECT_EQ(shm_.header->volume_scaler, 1.0);
207 cras_shm_set_volume_scaler(&shm_, 1.4);
208 EXPECT_EQ(shm_.header->volume_scaler, 1.0);
209 cras_shm_set_volume_scaler(&shm_, -0.5);
210 EXPECT_EQ(shm_.header->volume_scaler, 0.0);
211 cras_shm_set_volume_scaler(&shm_, 0.5);
212 EXPECT_EQ(shm_.header->volume_scaler, 0.5);
213 }
214
215 // Test that invalid read/write offsets are detected.
216
TEST_F(ShmTestSuite,InvalidWriteOffset)217 TEST_F(ShmTestSuite, InvalidWriteOffset) {
218 shm_.header->write_offset[0] = shm_.config.used_size + 50;
219 shm_.header->read_offset[0] = 0;
220 buf_ = cras_shm_get_readable_frames(&shm_, 0, &frames_);
221 EXPECT_EQ(shm_.config.used_size / 4, frames_);
222 }
223
TEST_F(ShmTestSuite,InvalidReadOffset)224 TEST_F(ShmTestSuite, InvalidReadOffset) {
225 // Should ignore read+_offset and assume 0.
226 shm_.header->write_offset[0] = 44;
227 shm_.header->read_offset[0] = shm_.config.used_size + 25;
228 buf_ = cras_shm_get_readable_frames(&shm_, 0, &frames_);
229 EXPECT_EQ(shm_.header->write_offset[0] / shm_.config.frame_bytes, frames_);
230 EXPECT_EQ(shm_.samples, (uint8_t*)buf_);
231 }
232
TEST_F(ShmTestSuite,InvalidReadAndWriteOffset)233 TEST_F(ShmTestSuite, InvalidReadAndWriteOffset) {
234 shm_.header->write_offset[0] = shm_.config.used_size + 50;
235 shm_.header->read_offset[0] = shm_.config.used_size + 25;
236 buf_ = cras_shm_get_readable_frames(&shm_, 0, &frames_);
237 EXPECT_EQ(shm_.config.used_size / 4, frames_);
238 }
239
TEST_F(ShmTestSuite,InputBufferOverrun)240 TEST_F(ShmTestSuite, InputBufferOverrun) {
241 int rc;
242 shm_.header->write_offset[0] = 0;
243 shm_.header->read_offset[0] = 0;
244 shm_.header->write_offset[1] = 0;
245 shm_.header->read_offset[1] = 0;
246
247 shm_.header->write_buf_idx = 0;
248 shm_.header->read_buf_idx = 0;
249
250 EXPECT_EQ(0, cras_shm_num_overruns(&shm_));
251 rc = cras_shm_check_write_overrun(&shm_);
252 EXPECT_EQ(0, rc);
253 cras_shm_buffer_written(&shm_, 100);
254 cras_shm_buffer_write_complete(&shm_);
255
256 rc = cras_shm_check_write_overrun(&shm_);
257 EXPECT_EQ(0, rc);
258 cras_shm_buffer_written(&shm_, 100);
259 cras_shm_buffer_write_complete(&shm_);
260
261 // Assert two consecutive writes causes overrun.
262 rc = cras_shm_check_write_overrun(&shm_);
263 EXPECT_EQ(1, rc);
264 EXPECT_EQ(1, cras_shm_num_overruns(&shm_));
265 }
266
TEST_F(ShmTestSuite,GetWritableFramesNeedToWrite)267 TEST_F(ShmTestSuite, GetWritableFramesNeedToWrite) {
268 unsigned buffer_size = 480;
269 unsigned limit = 480;
270 unsigned written = 200;
271 unsigned frames;
272 shm_.header->write_buf_idx = 0;
273 shm_.config.used_size = buffer_size * shm_.config.frame_bytes;
274 shm_.header->write_offset[0] = written * shm_.config.frame_bytes;
275 buf_ = cras_shm_get_writeable_frames(&shm_, limit, &frames);
276 EXPECT_EQ(limit - written, frames);
277 EXPECT_EQ(shm_.samples + shm_.header->write_offset[0], buf_);
278 }
279
TEST_F(ShmTestSuite,GetWritableFramesNoNeedToWrite)280 TEST_F(ShmTestSuite, GetWritableFramesNoNeedToWrite) {
281 unsigned buffer_size = 480;
282 unsigned limit = 240;
283 unsigned written = 300;
284 unsigned frames;
285 shm_.header->write_buf_idx = 0;
286 shm_.config.used_size = buffer_size * shm_.config.frame_bytes;
287 shm_.header->write_offset[0] = written * shm_.config.frame_bytes;
288 buf_ = cras_shm_get_writeable_frames(&shm_, limit, &frames);
289 EXPECT_EQ(0, frames);
290 EXPECT_EQ(shm_.samples + shm_.header->write_offset[0], buf_);
291 }
292
293 // Test wrapping of buffers that don't start at normal offsets.
TEST_F(ShmTestSuite,WrapWithNonstandardBufferLocations)294 TEST_F(ShmTestSuite, WrapWithNonstandardBufferLocations) {
295 uint32_t frame_bytes = cras_shm_frame_bytes(&shm_);
296 uint32_t used_frames = 24;
297 uint32_t used_size = used_frames * frame_bytes;
298 cras_shm_set_used_size(&shm_, used_size);
299 cras_shm_set_buffer_offset(&shm_, 0, 15);
300 cras_shm_set_buffer_offset(&shm_, 1, 479);
301
302 shm_.header->read_offset[0] = (used_frames / 4) * shm_.config.frame_bytes;
303 shm_.header->write_offset[0] = (used_frames / 2) * shm_.config.frame_bytes;
304 shm_.header->read_offset[1] = 0;
305 shm_.header->write_offset[1] = (used_frames / 3) * shm_.config.frame_bytes;
306 buf_ = cras_shm_get_readable_frames(&shm_, 0, &frames_);
307 EXPECT_EQ(used_frames / 4, frames_);
308 EXPECT_EQ(cras_shm_buff_for_idx(&shm_, 0) + shm_.header->read_offset[0],
309 (uint8_t*)buf_);
310 buf_ = cras_shm_get_readable_frames(&shm_, frames_, &frames_);
311 EXPECT_EQ(used_frames / 3, frames_);
312 EXPECT_EQ(cras_shm_buff_for_idx(&shm_, 1), (uint8_t*)buf_);
313 /* Mark all but 5 frames as read */
314 cras_shm_buffer_read(&shm_, (used_frames / 4) + (used_frames / 3) - 5);
315 EXPECT_EQ(0, shm_.header->read_offset[0]);
316 EXPECT_EQ(((used_frames / 3) - 5) * shm_.config.frame_bytes,
317 shm_.header->read_offset[1]);
318 }
319
TEST_F(ShmTestSuite,PlaybackWithDifferentSequentialBufferLocations)320 TEST_F(ShmTestSuite, PlaybackWithDifferentSequentialBufferLocations) {
321 uint32_t frame_bytes = cras_shm_frame_bytes(&shm_);
322 uint32_t used_frames = 24;
323 uint32_t used_size = used_frames * frame_bytes;
324 cras_shm_set_used_size(&shm_, used_size);
325
326 uint32_t first_offset = 2.7 * used_size;
327 /* Make samples area long enough to hold all of the buffers starting from
328 * first_offset, with an extra 'used_size' bytes of free space at the end. */
329 uint32_t samples_length =
330 first_offset + used_size * (CRAS_NUM_SHM_BUFFERS + 1);
331 free(shm_.samples);
332 shm_.samples = static_cast<uint8_t*>(calloc(1, samples_length));
333 shm_.samples_info.length = samples_length;
334 uint32_t total_frames_written = 0;
335
336 // Fill all of the buffers.
337 for (unsigned int i = 0; i < CRAS_NUM_SHM_BUFFERS; i++) {
338 cras_shm_set_buffer_offset(&shm_, i, first_offset + i * used_size);
339 shm_.header->write_in_progress[i] = 1;
340 shm_.header->write_offset[i] = 0;
341 frames_ = MIN(10 + i, used_frames);
342 cras_shm_buffer_written(&shm_, frames_);
343 total_frames_written += frames_;
344 cras_shm_buffer_write_complete(&shm_);
345 }
346
347 uint32_t total_frames_available = 0;
348
349 // Consume all available frames.
350 while ((buf_ = cras_shm_get_readable_frames(&shm_, 0, &frames_))) {
351 total_frames_available += frames_;
352
353 EXPECT_GE(buf_, shm_.samples);
354 EXPECT_LE(buf_ + frames_, shm_.samples + samples_length);
355 cras_shm_buffer_read(&shm_, frames_);
356 }
357
358 EXPECT_EQ(total_frames_written, total_frames_available);
359
360 uint32_t second_offset = 1.2 * used_size;
361
362 // Fill half of the buffers.
363 for (unsigned int i = 0; i < CRAS_NUM_SHM_BUFFERS / 2; i++) {
364 cras_shm_set_buffer_offset(&shm_, i, second_offset + i * used_size);
365 shm_.header->write_in_progress[i] = 1;
366 shm_.header->write_offset[i] = 0;
367 frames_ = MIN(3 + 2 * i, used_frames);
368 cras_shm_buffer_written(&shm_, frames_);
369 total_frames_written += frames_;
370 cras_shm_buffer_write_complete(&shm_);
371 }
372
373 // Consume all available frames.
374 while ((buf_ = cras_shm_get_readable_frames(&shm_, 0, &frames_))) {
375 total_frames_available += frames_;
376
377 EXPECT_GE(buf_, shm_.samples);
378 EXPECT_LE(buf_ + frames_, shm_.samples + samples_length);
379 cras_shm_buffer_read(&shm_, frames_);
380 }
381
382 EXPECT_EQ(total_frames_written, total_frames_available);
383
384 // Fill rest of the buffers.
385 for (unsigned int i = CRAS_NUM_SHM_BUFFERS / 2; i < CRAS_NUM_SHM_BUFFERS;
386 i++) {
387 cras_shm_set_buffer_offset(&shm_, i, second_offset + i * used_size);
388 shm_.header->write_in_progress[i] = 1;
389 shm_.header->write_offset[i] = 0;
390 frames_ = MIN(3 + 2 * i, used_frames);
391 cras_shm_buffer_written(&shm_, frames_);
392 total_frames_written += frames_;
393 cras_shm_buffer_write_complete(&shm_);
394 }
395
396 // Consume all available frames.
397 while ((buf_ = cras_shm_get_readable_frames(&shm_, 0, &frames_))) {
398 total_frames_available += frames_;
399
400 EXPECT_GE(buf_, shm_.samples);
401 EXPECT_LE(buf_ + frames_, shm_.samples + samples_length);
402 cras_shm_buffer_read(&shm_, frames_);
403 }
404
405 EXPECT_EQ(total_frames_written, total_frames_available);
406 }
407
TEST_F(ShmTestSuite,GetCheckedBufferOffset)408 TEST_F(ShmTestSuite, GetCheckedBufferOffset) {
409 uint32_t used_size = cras_shm_used_size(&shm_);
410 uint32_t samples_length = used_size * 8;
411 shm_.samples_info.length = samples_length;
412
413 uint32_t offset;
414
415 for (unsigned int i = 0; i < CRAS_NUM_SHM_BUFFERS; i++) {
416 shm_.header->buffer_offset[i] = 0;
417 offset = cras_shm_get_checked_buffer_offset(&shm_, i);
418 EXPECT_EQ(0, offset) << "Expected valid buffer offset for buffer " << i;
419
420 shm_.header->buffer_offset[i] = used_size;
421 offset = cras_shm_get_checked_buffer_offset(&shm_, i);
422 EXPECT_EQ(used_size, offset)
423 << "Expected valid buffer offset for buffer " << i;
424
425 shm_.header->buffer_offset[i] = samples_length - 1;
426 offset = cras_shm_get_checked_buffer_offset(&shm_, i);
427 EXPECT_EQ(samples_length - 1, offset)
428 << "Expected valid buffer offset for buffer " << i;
429
430 shm_.header->buffer_offset[i] = samples_length;
431 offset = cras_shm_get_checked_buffer_offset(&shm_, i);
432 EXPECT_EQ(samples_length, offset)
433 << "Expected valid buffer offset for buffer " << i;
434
435 shm_.header->buffer_offset[i] = samples_length + 1;
436 offset = cras_shm_get_checked_buffer_offset(&shm_, i);
437 EXPECT_EQ(samples_length, offset)
438 << "Expected invalid buffer offset for buffer " << i;
439
440 shm_.header->buffer_offset[i] = samples_length + used_size;
441 offset = cras_shm_get_checked_buffer_offset(&shm_, i);
442 EXPECT_EQ(samples_length, offset)
443 << "Expected invalid buffer offset for buffer " << i;
444 }
445 }
446
TEST_F(ShmTestSuite,GetCheckedReadOffset)447 TEST_F(ShmTestSuite, GetCheckedReadOffset) {
448 uint32_t used_size = cras_shm_used_size(&shm_);
449 uint32_t samples_length = used_size * 8;
450 shm_.samples_info.length = samples_length;
451
452 uint32_t offset;
453
454 for (unsigned int i = 0; i < CRAS_NUM_SHM_BUFFERS; i++) {
455 shm_.header->read_offset[i] = 0;
456 offset = cras_shm_get_checked_read_offset(&shm_, i);
457 EXPECT_EQ(0, offset) << "Expected valid read offset for buffer " << i;
458
459 shm_.header->read_offset[i] = used_size / 2;
460 offset = cras_shm_get_checked_read_offset(&shm_, i);
461 EXPECT_EQ(used_size / 2, offset)
462 << "Expected valid read offset for buffer " << i;
463
464 shm_.header->read_offset[i] = used_size;
465 offset = cras_shm_get_checked_read_offset(&shm_, i);
466 EXPECT_EQ(used_size, offset)
467 << "Expected valid read offset for buffer " << i;
468
469 // Read offsets should not be greater than used_size.
470 shm_.header->read_offset[i] = used_size + 1;
471 offset = cras_shm_get_checked_read_offset(&shm_, i);
472 EXPECT_EQ(0, offset) << "Expected invalid read offset for buffer " << i;
473
474 shm_.header->buffer_offset[i] = samples_length - used_size / 2;
475
476 shm_.header->read_offset[i] = 0;
477 offset = cras_shm_get_checked_read_offset(&shm_, i);
478 EXPECT_EQ(0, offset) << "Expected valid read offset for buffer " << i;
479
480 shm_.header->read_offset[i] = used_size / 4;
481 offset = cras_shm_get_checked_read_offset(&shm_, i);
482 EXPECT_EQ(used_size / 4, offset)
483 << "Expected valid read offset for buffer " << i;
484
485 shm_.header->read_offset[i] = used_size / 2;
486 offset = cras_shm_get_checked_read_offset(&shm_, i);
487 EXPECT_EQ(used_size / 2, offset)
488 << "Expected valid read offset for buffer " << i;
489
490 shm_.header->read_offset[i] = used_size / 2 + 1;
491 offset = cras_shm_get_checked_read_offset(&shm_, i);
492 EXPECT_EQ(0, offset) << "Expected invalid read offset for buffer " << i;
493
494 shm_.header->read_offset[i] = used_size;
495 offset = cras_shm_get_checked_read_offset(&shm_, i);
496 EXPECT_EQ(0, offset) << "Expected invalid read offset for buffer " << i;
497
498 shm_.header->read_offset[i] = used_size + 1;
499 offset = cras_shm_get_checked_read_offset(&shm_, i);
500 EXPECT_EQ(0, offset) << "Expected invalid read offset for buffer " << i;
501 }
502 }
503
TEST_F(ShmTestSuite,GetCheckedWriteOffset)504 TEST_F(ShmTestSuite, GetCheckedWriteOffset) {
505 uint32_t used_size = cras_shm_used_size(&shm_);
506 uint32_t samples_length = used_size * 8;
507 shm_.samples_info.length = samples_length;
508
509 uint32_t offset;
510
511 for (unsigned int i = 0; i < CRAS_NUM_SHM_BUFFERS; i++) {
512 shm_.header->write_offset[i] = 0;
513 offset = cras_shm_get_checked_write_offset(&shm_, i);
514 EXPECT_EQ(0, offset) << "Expected valid write offset for buffer " << i;
515
516 shm_.header->write_offset[i] = used_size / 2;
517 offset = cras_shm_get_checked_write_offset(&shm_, i);
518 EXPECT_EQ(used_size / 2, offset)
519 << "Expected valid write offset for buffer " << i;
520
521 shm_.header->write_offset[i] = used_size;
522 offset = cras_shm_get_checked_write_offset(&shm_, i);
523 EXPECT_EQ(used_size, offset)
524 << "Expected valid write offset for buffer " << i;
525
526 // Write offsets should not be greater than used_size.
527 shm_.header->write_offset[i] = used_size + 1;
528 offset = cras_shm_get_checked_write_offset(&shm_, i);
529 EXPECT_EQ(used_size, offset)
530 << "Expected invalid write offset for buffer " << i;
531
532 uint32_t buffer_offset = samples_length - used_size / 2;
533 shm_.header->buffer_offset[i] = buffer_offset;
534
535 shm_.header->write_offset[i] = 0;
536 offset = cras_shm_get_checked_write_offset(&shm_, i);
537 EXPECT_EQ(0, offset) << "Expected valid write offset for buffer " << i;
538
539 shm_.header->write_offset[i] = used_size / 4;
540 offset = cras_shm_get_checked_write_offset(&shm_, i);
541 EXPECT_EQ(used_size / 4, offset)
542 << "Expected valid write offset for buffer " << i;
543
544 shm_.header->write_offset[i] = used_size / 2;
545 offset = cras_shm_get_checked_write_offset(&shm_, i);
546 EXPECT_EQ(used_size / 2, offset)
547 << "Expected valid write offset for buffer " << i;
548
549 // Write offsets should not be longer than the samples area.
550 shm_.header->write_offset[i] = used_size / 2 + 1;
551 offset = cras_shm_get_checked_write_offset(&shm_, i);
552 EXPECT_EQ(samples_length - buffer_offset, offset)
553 << "Expected invalid write offset for buffer " << i;
554
555 shm_.header->write_offset[i] = used_size;
556 offset = cras_shm_get_checked_write_offset(&shm_, i);
557 EXPECT_EQ(samples_length - buffer_offset, offset)
558 << "Expected invalid write offset for buffer " << i;
559
560 shm_.header->write_offset[i] = used_size + 1;
561 offset = cras_shm_get_checked_write_offset(&shm_, i);
562 EXPECT_EQ(samples_length - buffer_offset, offset)
563 << "Expected invalid write offset for buffer " << i;
564 }
565 }
566
567 } // namespace
568
main(int argc,char ** argv)569 int main(int argc, char** argv) {
570 ::testing::InitGoogleTest(&argc, argv);
571 return RUN_ALL_TESTS();
572 }
573