tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ring_buffer_unittest.cc (5419B)


      1 /*
      2 *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
      3 *
      4 *  Use of this source code is governed by a BSD-style license
      5 *  that can be found in the LICENSE file in the root of the source
      6 *  tree. An additional intellectual property rights grant can be found
      7 *  in the file PATENTS.  All contributing project authors may
      8 *  be found in the AUTHORS file in the root of the source tree.
      9 */
     10 
     11 #include "common_audio/ring_buffer.h"
     12 
     13 #include <algorithm>
     14 #include <cstdio>
     15 #include <cstdlib>
     16 #include <ctime>
     17 #include <memory>
     18 
     19 #include "test/gtest.h"
     20 
     21 namespace webrtc {
     22 
     23 struct FreeBufferDeleter {
     24  inline void operator()(void* ptr) const { WebRtc_FreeBuffer(ptr); }
     25 };
     26 typedef std::unique_ptr<RingBuffer, FreeBufferDeleter> scoped_ring_buffer;
     27 
     28 static void AssertElementEq(int expected, int actual) {
     29  ASSERT_EQ(expected, actual);
     30 }
     31 
     32 static int SetIncrementingData(int* data,
     33                               int num_elements,
     34                               int starting_value) {
     35  for (int i = 0; i < num_elements; i++) {
     36    data[i] = starting_value++;
     37  }
     38  return starting_value;
     39 }
     40 
     41 static int CheckIncrementingData(int* data,
     42                                 int num_elements,
     43                                 int starting_value) {
     44  for (int i = 0; i < num_elements; i++) {
     45    AssertElementEq(starting_value++, data[i]);
     46  }
     47  return starting_value;
     48 }
     49 
     50 // We use ASSERTs in this test to avoid obscuring the seed in the case of a
     51 // failure.
     52 static void RandomStressTest(int** data_ptr) {
     53  const int kNumTests = 10;
     54  const int kNumOps = 1000;
     55  const int kMaxBufferSize = 1000;
     56 
     57  unsigned int seed = time(nullptr);
     58  printf("seed=%u\n", seed);
     59  srand(seed);
     60  for (int i = 0; i < kNumTests; i++) {
     61    // rand_r is not supported on many platforms, so rand is used.
     62    const int buffer_size = std::max(rand() % kMaxBufferSize, 1);  // NOLINT
     63    std::unique_ptr<int[]> write_data(new int[buffer_size]);
     64    std::unique_ptr<int[]> read_data(new int[buffer_size]);
     65    scoped_ring_buffer buffer(WebRtc_CreateBuffer(buffer_size, sizeof(int)));
     66    ASSERT_TRUE(buffer.get() != nullptr);
     67    WebRtc_InitBuffer(buffer.get());
     68    int buffer_consumed = 0;
     69    int write_element = 0;
     70    int read_element = 0;
     71    for (int j = 0; j < kNumOps; j++) {
     72      const bool write = rand() % 2 == 0 ? true : false;  // NOLINT
     73      const int num_elements = rand() % buffer_size;      // NOLINT
     74      if (write) {
     75        const int buffer_available = buffer_size - buffer_consumed;
     76        ASSERT_EQ(static_cast<size_t>(buffer_available),
     77                  WebRtc_available_write(buffer.get()));
     78        const int expected_elements = std::min(num_elements, buffer_available);
     79        write_element = SetIncrementingData(write_data.get(), expected_elements,
     80                                            write_element);
     81        ASSERT_EQ(
     82            static_cast<size_t>(expected_elements),
     83            WebRtc_WriteBuffer(buffer.get(), write_data.get(), num_elements));
     84        buffer_consumed =
     85            std::min(buffer_consumed + expected_elements, buffer_size);
     86      } else {
     87        const int expected_elements = std::min(num_elements, buffer_consumed);
     88        ASSERT_EQ(static_cast<size_t>(buffer_consumed),
     89                  WebRtc_available_read(buffer.get()));
     90        ASSERT_EQ(
     91            static_cast<size_t>(expected_elements),
     92            WebRtc_ReadBuffer(buffer.get(), reinterpret_cast<void**>(data_ptr),
     93                              read_data.get(), num_elements));
     94        int* check_ptr = read_data.get();
     95        if (data_ptr) {
     96          check_ptr = *data_ptr;
     97        }
     98        read_element =
     99            CheckIncrementingData(check_ptr, expected_elements, read_element);
    100        buffer_consumed = std::max(buffer_consumed - expected_elements, 0);
    101      }
    102    }
    103  }
    104 }
    105 
    106 TEST(RingBufferTest, RandomStressTest) {
    107  int* data_ptr = nullptr;
    108  RandomStressTest(&data_ptr);
    109 }
    110 
    111 TEST(RingBufferTest, RandomStressTestWithNullPtr) {
    112  RandomStressTest(nullptr);
    113 }
    114 
    115 TEST(RingBufferTest, PassingNulltoReadBufferForcesMemcpy) {
    116  const size_t kDataSize = 2;
    117  int write_data[kDataSize];
    118  int read_data[kDataSize];
    119  int* data_ptr;
    120 
    121  scoped_ring_buffer buffer(WebRtc_CreateBuffer(kDataSize, sizeof(int)));
    122  ASSERT_TRUE(buffer.get() != nullptr);
    123  WebRtc_InitBuffer(buffer.get());
    124 
    125  SetIncrementingData(write_data, kDataSize, 0);
    126  EXPECT_EQ(kDataSize, WebRtc_WriteBuffer(buffer.get(), write_data, kDataSize));
    127  SetIncrementingData(read_data, kDataSize, kDataSize);
    128  EXPECT_EQ(kDataSize,
    129            WebRtc_ReadBuffer(buffer.get(), reinterpret_cast<void**>(&data_ptr),
    130                              read_data, kDataSize));
    131  // Copying was not necessary, so `read_data` has not been updated.
    132  CheckIncrementingData(data_ptr, kDataSize, 0);
    133  CheckIncrementingData(read_data, kDataSize, kDataSize);
    134 
    135  EXPECT_EQ(kDataSize, WebRtc_WriteBuffer(buffer.get(), write_data, kDataSize));
    136  EXPECT_EQ(kDataSize,
    137            WebRtc_ReadBuffer(buffer.get(), nullptr, read_data, kDataSize));
    138  // Passing null forces a memcpy, so `read_data` is now updated.
    139  CheckIncrementingData(read_data, kDataSize, 0);
    140 }
    141 
    142 TEST(RingBufferTest, CreateHandlesErrors) {
    143  EXPECT_TRUE(WebRtc_CreateBuffer(0, 1) == nullptr);
    144  EXPECT_TRUE(WebRtc_CreateBuffer(1, 0) == nullptr);
    145  RingBuffer* buffer = WebRtc_CreateBuffer(1, 1);
    146  EXPECT_TRUE(buffer != nullptr);
    147  WebRtc_FreeBuffer(buffer);
    148 }
    149 
    150 }  // namespace webrtc