Home | History | Annotate | Download | only in tests
      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 <stdio.h>
      6 #include <gtest/gtest.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:
     17     virtual void SetUp() {
     18       memset(&shm_, 0, sizeof(shm_));
     19       shm_.area =
     20           static_cast<cras_audio_shm_area *>(
     21               calloc(1, sizeof(*shm_.area) + 2048));
     22       cras_shm_set_frame_bytes(&shm_, 4);
     23       cras_shm_set_used_size(&shm_, 1024);
     24       memcpy(&shm_.area->config, &shm_.config, sizeof(shm_.config));
     25 
     26       frames_ = 0;
     27     }
     28 
     29     virtual void TearDown() {
     30       free(shm_.area);
     31     }
     32 
     33     struct cras_audio_shm shm_;
     34     uint8_t *buf_;
     35     size_t frames_;
     36 };
     37 
     38 // Test that and empty buffer returns 0 readable bytes.
     39 TEST_F(ShmTestSuite, NoneReadableWhenEmpty) {
     40   buf_ = cras_shm_get_readable_frames(&shm_, 0, &frames_);
     41   EXPECT_EQ(0, frames_);
     42   cras_shm_buffer_read(&shm_, frames_);
     43   EXPECT_EQ(0, shm_.area->read_offset[0]);
     44 }
     45 
     46 // Buffer with 100 frames filled.
     47 TEST_F(ShmTestSuite, OneHundredFilled) {
     48   shm_.area->write_offset[0] = 100 * shm_.area->config.frame_bytes;
     49   buf_ = cras_shm_get_readable_frames(&shm_, 0, &frames_);
     50   EXPECT_EQ(100, frames_);
     51   EXPECT_EQ(shm_.area->samples, buf_);
     52   cras_shm_buffer_read(&shm_, frames_ - 9);
     53   EXPECT_EQ((frames_ - 9) * shm_.config.frame_bytes, shm_.area->read_offset[0]);
     54   cras_shm_buffer_read(&shm_, 9);
     55   EXPECT_EQ(0, shm_.area->read_offset[0]);
     56   EXPECT_EQ(1, shm_.area->read_buf_idx);
     57 }
     58 
     59 // Buffer with 100 frames filled, 50 read.
     60 TEST_F(ShmTestSuite, OneHundredFilled50Read) {
     61   shm_.area->write_offset[0] = 100 * shm_.config.frame_bytes;
     62   shm_.area->read_offset[0] = 50 * shm_.config.frame_bytes;
     63   buf_ = cras_shm_get_readable_frames(&shm_, 0, &frames_);
     64   EXPECT_EQ(50, frames_);
     65   EXPECT_EQ((shm_.area->samples + shm_.area->read_offset[0]), buf_);
     66   cras_shm_buffer_read(&shm_, frames_ - 10);
     67   EXPECT_EQ(shm_.area->write_offset[0] - 10 * shm_.config.frame_bytes,
     68             shm_.area->read_offset[0]);
     69   cras_shm_buffer_read(&shm_, 10);
     70   EXPECT_EQ(0, shm_.area->read_offset[0]);
     71 }
     72 
     73 // Buffer with 100 frames filled, 50 read, offset by 25.
     74 TEST_F(ShmTestSuite, OneHundredFilled50Read25offset) {
     75   shm_.area->write_offset[0] = 100 * shm_.config.frame_bytes;
     76   shm_.area->read_offset[0] = 50 * shm_.config.frame_bytes;
     77   buf_ = cras_shm_get_readable_frames(&shm_, 25, &frames_);
     78   EXPECT_EQ(25, frames_);
     79   EXPECT_EQ(shm_.area->samples + shm_.area->read_offset[0] +
     80                 25 * shm_.area->config.frame_bytes,
     81             (uint8_t *)buf_);
     82 }
     83 
     84 // Test wrapping across buffers.
     85 TEST_F(ShmTestSuite, WrapToNextBuffer) {
     86   shm_.config.used_size = 480 * shm_.config.frame_bytes;
     87   shm_.area->write_offset[0] = 240 * shm_.config.frame_bytes;
     88   shm_.area->read_offset[0] = 120 * shm_.config.frame_bytes;
     89   shm_.area->write_offset[1] = 240 * shm_.config.frame_bytes;
     90   buf_ = cras_shm_get_readable_frames(&shm_, 0, &frames_);
     91   EXPECT_EQ(120, frames_);
     92   EXPECT_EQ(shm_.area->samples + shm_.area->read_offset[0], (uint8_t *)buf_);
     93   buf_ = cras_shm_get_readable_frames(&shm_, frames_, &frames_);
     94   EXPECT_EQ(240, frames_);
     95   EXPECT_EQ(shm_.area->samples + shm_.config.used_size, (uint8_t *)buf_);
     96   cras_shm_buffer_read(&shm_, 350); /* Mark all-10 as read */
     97   EXPECT_EQ(0, shm_.area->read_offset[0]);
     98   EXPECT_EQ(230 * shm_.config.frame_bytes, shm_.area->read_offset[1]);
     99 }
    100 
    101 // Test wrapping across buffers reading all samples.
    102 TEST_F(ShmTestSuite, WrapToNextBufferReadAll) {
    103   shm_.config.used_size = 480 * shm_.config.frame_bytes;
    104   shm_.area->write_offset[0] = 240 * shm_.config.frame_bytes;
    105   shm_.area->read_offset[0] = 120 * shm_.config.frame_bytes;
    106   shm_.area->write_offset[1] = 240 * shm_.config.frame_bytes;
    107   buf_ = cras_shm_get_readable_frames(&shm_, 0, &frames_);
    108   EXPECT_EQ(120, frames_);
    109   EXPECT_EQ(shm_.area->samples + shm_.area->read_offset[0], (uint8_t *)buf_);
    110   buf_ = cras_shm_get_readable_frames(&shm_, frames_, &frames_);
    111   EXPECT_EQ(240, frames_);
    112   EXPECT_EQ(shm_.area->samples + shm_.config.used_size, (uint8_t *)buf_);
    113   cras_shm_buffer_read(&shm_, 360); /* Mark all as read */
    114   EXPECT_EQ(0, shm_.area->read_offset[0]);
    115   EXPECT_EQ(0, shm_.area->read_offset[1]);
    116   EXPECT_EQ(0, shm_.area->read_buf_idx);
    117 }
    118 
    119 // Test wrapping last buffer.
    120 TEST_F(ShmTestSuite, WrapFromFinalBuffer) {
    121   shm_.area->read_buf_idx = CRAS_NUM_SHM_BUFFERS - 1;
    122   shm_.config.used_size = 480 * shm_.config.frame_bytes;
    123   shm_.area->write_offset[shm_.area->read_buf_idx] =
    124       240 * shm_.config.frame_bytes;
    125   shm_.area->read_offset[shm_.area->read_buf_idx] =
    126       120 * shm_.config.frame_bytes;
    127   shm_.area->write_offset[0] = 240 * shm_.config.frame_bytes;
    128   buf_ = cras_shm_get_readable_frames(&shm_, 0, &frames_);
    129   EXPECT_EQ(120, frames_);
    130   EXPECT_EQ((uint8_t *)buf_, shm_.area->samples +
    131       shm_.config.used_size * shm_.area->read_buf_idx +
    132       shm_.area->read_offset[shm_.area->read_buf_idx]);
    133   buf_ = cras_shm_get_readable_frames(&shm_, frames_, &frames_);
    134   EXPECT_EQ(240, frames_);
    135   EXPECT_EQ(shm_.area->samples, (uint8_t *)buf_);
    136   cras_shm_buffer_read(&shm_, 350); /* Mark all-10 as read */
    137   EXPECT_EQ(0, shm_.area->read_offset[1]);
    138   EXPECT_EQ(230 * shm_.config.frame_bytes, shm_.area->read_offset[0]);
    139 }
    140 
    141 // Test Check available to write returns 0 if not free buffer.
    142 TEST_F(ShmTestSuite, WriteAvailNotFree) {
    143   size_t ret;
    144   shm_.area->write_buf_idx = 0;
    145   shm_.area->write_offset[0] = 100 * shm_.config.frame_bytes;
    146   shm_.area->read_offset[0] = 50 * shm_.config.frame_bytes;
    147   ret = cras_shm_get_num_writeable(&shm_);
    148   EXPECT_EQ(0, ret);
    149 }
    150 
    151 // Test Check available to write returns num_frames if free buffer.
    152 TEST_F(ShmTestSuite, WriteAvailValid) {
    153   size_t ret;
    154   shm_.area->write_buf_idx = 0;
    155   shm_.config.used_size = 480 * shm_.config.frame_bytes;
    156   shm_.area->write_offset[0] = 0;
    157   shm_.area->read_offset[0] = 0;
    158   ret = cras_shm_get_num_writeable(&shm_);
    159   EXPECT_EQ(480, ret);
    160 }
    161 
    162 // Test get frames_written returns the number of frames written.
    163 TEST_F(ShmTestSuite, GetNumWritten) {
    164   size_t ret;
    165   shm_.area->write_buf_idx = 0;
    166   shm_.config.used_size = 480 * shm_.config.frame_bytes;
    167   shm_.area->write_offset[0] = 200 * shm_.config.frame_bytes;
    168   shm_.area->read_offset[0] = 0;
    169   ret = cras_shm_frames_written(&shm_);
    170   EXPECT_EQ(200, ret);
    171 }
    172 
    173 // Test that getting the base of the write buffer returns the correct pointer.
    174 TEST_F(ShmTestSuite, GetWriteBufferBase) {
    175   uint8_t* ret;
    176 
    177   shm_.area->write_buf_idx = 0;
    178   shm_.config.used_size = 480 * shm_.config.frame_bytes;
    179   shm_.area->write_offset[0] = 200 * shm_.config.frame_bytes;
    180   shm_.area->write_offset[1] = 200 * shm_.config.frame_bytes;
    181   shm_.area->read_offset[0] = 0;
    182   shm_.area->read_offset[1] = 0;
    183   ret = cras_shm_get_write_buffer_base(&shm_);
    184   EXPECT_EQ(shm_.area->samples, ret);
    185 
    186   shm_.area->write_buf_idx = 1;
    187   ret = cras_shm_get_write_buffer_base(&shm_);
    188   EXPECT_EQ(shm_.area->samples + shm_.config.used_size, ret);
    189 }
    190 
    191 TEST_F(ShmTestSuite, SetVolume) {
    192   cras_shm_set_volume_scaler(&shm_, 1.0);
    193   EXPECT_EQ(shm_.area->volume_scaler, 1.0);
    194   cras_shm_set_volume_scaler(&shm_, 1.4);
    195   EXPECT_EQ(shm_.area->volume_scaler, 1.0);
    196   cras_shm_set_volume_scaler(&shm_, -0.5);
    197   EXPECT_EQ(shm_.area->volume_scaler, 0.0);
    198   cras_shm_set_volume_scaler(&shm_, 0.5);
    199   EXPECT_EQ(shm_.area->volume_scaler, 0.5);
    200 }
    201 
    202 // Test that invalid read/write offsets are detected.
    203 
    204 TEST_F(ShmTestSuite, InvalidWriteOffset) {
    205   shm_.area->write_offset[0] = shm_.config.used_size + 50;
    206   shm_.area->read_offset[0] = 0;
    207   buf_ = cras_shm_get_readable_frames(&shm_, 0, &frames_);
    208   EXPECT_EQ(shm_.config.used_size / 4, frames_);
    209 }
    210 
    211 TEST_F(ShmTestSuite, InvalidReadOffset) {
    212   // Should ignore read+_offset and assume 0.
    213   shm_.area->write_offset[0] = 44;
    214   shm_.area->read_offset[0] = shm_.config.used_size + 25;
    215   buf_ = cras_shm_get_readable_frames(&shm_, 0, &frames_);
    216   EXPECT_EQ(shm_.area->write_offset[0] / shm_.config.frame_bytes, frames_);
    217   EXPECT_EQ(shm_.area->samples, (uint8_t *)buf_);
    218 }
    219 
    220 TEST_F(ShmTestSuite, InvalidReadAndWriteOffset) {
    221   shm_.area->write_offset[0] = shm_.config.used_size + 50;
    222   shm_.area->read_offset[0] = shm_.config.used_size + 25;
    223   buf_ = cras_shm_get_readable_frames(&shm_, 0, &frames_);
    224   EXPECT_EQ(shm_.config.used_size / 4, frames_);
    225 }
    226 
    227 TEST_F(ShmTestSuite, InputBufferOverrun) {
    228   int rc;
    229   shm_.area->write_offset[0] = 0;
    230   shm_.area->read_offset[0] = 0;
    231   shm_.area->write_offset[1] = 0;
    232   shm_.area->read_offset[1] = 0;
    233 
    234   shm_.area->write_buf_idx = 0;
    235   shm_.area->read_buf_idx = 0;
    236 
    237   EXPECT_EQ(0, cras_shm_num_overruns(&shm_));
    238   rc = cras_shm_check_write_overrun(&shm_);
    239   EXPECT_EQ(0, rc);
    240   cras_shm_buffer_written(&shm_, 100);
    241   cras_shm_buffer_write_complete(&shm_);
    242 
    243   rc = cras_shm_check_write_overrun(&shm_);
    244   EXPECT_EQ(0, rc);
    245   cras_shm_buffer_written(&shm_, 100);
    246   cras_shm_buffer_write_complete(&shm_);
    247 
    248   // Assert two consecutive writes causes overrun.
    249   rc = cras_shm_check_write_overrun(&shm_);
    250   EXPECT_EQ(1, rc);
    251   EXPECT_EQ(1, cras_shm_num_overruns(&shm_));
    252 }
    253 
    254 TEST_F(ShmTestSuite, GetWritableFramesNeedToWrite) {
    255   unsigned buffer_size = 480;
    256   unsigned limit = 480;
    257   unsigned written = 200;
    258   unsigned frames;
    259   shm_.area->write_buf_idx = 0;
    260   shm_.config.used_size = buffer_size * shm_.config.frame_bytes;
    261   shm_.area->write_offset[0] = written * shm_.config.frame_bytes;
    262   buf_ = cras_shm_get_writeable_frames(&shm_, limit, &frames);
    263   EXPECT_EQ(limit - written, frames);
    264   EXPECT_EQ(shm_.area->samples + shm_.area->write_offset[0], buf_);
    265 }
    266 
    267 TEST_F(ShmTestSuite, GetWritableFramesNoNeedToWrite) {
    268   unsigned buffer_size = 480;
    269   unsigned limit = 240;
    270   unsigned written = 300;
    271   unsigned frames;
    272   shm_.area->write_buf_idx = 0;
    273   shm_.config.used_size = buffer_size * shm_.config.frame_bytes;
    274   shm_.area->write_offset[0] = written * shm_.config.frame_bytes;
    275   buf_ = cras_shm_get_writeable_frames(&shm_, limit, &frames);
    276   EXPECT_EQ(0, frames);
    277   EXPECT_EQ(shm_.area->samples + shm_.area->write_offset[0], buf_);
    278 }
    279 
    280 }  //  namespace
    281 
    282 int main(int argc, char **argv) {
    283   ::testing::InitGoogleTest(&argc, argv);
    284   return RUN_ALL_TESTS();
    285 }
    286