• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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