OLD | NEW |
| (Empty) |
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 "webrtc/common_audio/ring_buffer.h" | |
12 | |
13 #include <stdlib.h> | |
14 #include <time.h> | |
15 | |
16 #include <algorithm> | |
17 #include <memory> | |
18 | |
19 #include "testing/gtest/include/gtest/gtest.h" | |
20 | |
21 namespace webrtc { | |
22 | |
23 struct FreeBufferDeleter { | |
24 inline void operator()(void* ptr) const { | |
25 WebRtc_FreeBuffer(ptr); | |
26 } | |
27 }; | |
28 typedef std::unique_ptr<RingBuffer, FreeBufferDeleter> scoped_ring_buffer; | |
29 | |
30 static void AssertElementEq(int expected, int actual) { | |
31 ASSERT_EQ(expected, actual); | |
32 } | |
33 | |
34 static int SetIncrementingData(int* data, int num_elements, | |
35 int starting_value) { | |
36 for (int i = 0; i < num_elements; i++) { | |
37 data[i] = starting_value++; | |
38 } | |
39 return starting_value; | |
40 } | |
41 | |
42 static int CheckIncrementingData(int* data, 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(NULL); | |
58 printf("seed=%u\n", seed); | |
59 srand(seed); | |
60 for (int i = 0; i < kNumTests; i++) { | |
61 const int buffer_size = std::max(rand() % kMaxBufferSize, 1); | |
62 std::unique_ptr<int[]> write_data(new int[buffer_size]); | |
63 std::unique_ptr<int[]> read_data(new int[buffer_size]); | |
64 scoped_ring_buffer buffer(WebRtc_CreateBuffer(buffer_size, sizeof(int))); | |
65 ASSERT_TRUE(buffer.get() != NULL); | |
66 WebRtc_InitBuffer(buffer.get()); | |
67 int buffer_consumed = 0; | |
68 int write_element = 0; | |
69 int read_element = 0; | |
70 for (int j = 0; j < kNumOps; j++) { | |
71 const bool write = rand() % 2 == 0 ? true : false; | |
72 const int num_elements = rand() % buffer_size; | |
73 if (write) { | |
74 const int buffer_available = buffer_size - buffer_consumed; | |
75 ASSERT_EQ(static_cast<size_t>(buffer_available), | |
76 WebRtc_available_write(buffer.get())); | |
77 const int expected_elements = std::min(num_elements, buffer_available); | |
78 write_element = SetIncrementingData(write_data.get(), expected_elements, | |
79 write_element); | |
80 ASSERT_EQ(static_cast<size_t>(expected_elements), | |
81 WebRtc_WriteBuffer(buffer.get(), write_data.get(), | |
82 num_elements)); | |
83 buffer_consumed = std::min(buffer_consumed + expected_elements, | |
84 buffer_size); | |
85 } else { | |
86 const int expected_elements = std::min(num_elements, | |
87 buffer_consumed); | |
88 ASSERT_EQ(static_cast<size_t>(buffer_consumed), | |
89 WebRtc_available_read(buffer.get())); | |
90 ASSERT_EQ(static_cast<size_t>(expected_elements), | |
91 WebRtc_ReadBuffer(buffer.get(), | |
92 reinterpret_cast<void**>(data_ptr), | |
93 read_data.get(), | |
94 num_elements)); | |
95 int* check_ptr = read_data.get(); | |
96 if (data_ptr) { | |
97 check_ptr = *data_ptr; | |
98 } | |
99 read_element = CheckIncrementingData(check_ptr, expected_elements, | |
100 read_element); | |
101 buffer_consumed = std::max(buffer_consumed - expected_elements, 0); | |
102 } | |
103 } | |
104 } | |
105 } | |
106 | |
107 TEST(RingBufferTest, RandomStressTest) { | |
108 int* data_ptr = NULL; | |
109 RandomStressTest(&data_ptr); | |
110 } | |
111 | |
112 TEST(RingBufferTest, RandomStressTestWithNullPtr) { | |
113 RandomStressTest(NULL); | |
114 } | |
115 | |
116 TEST(RingBufferTest, PassingNulltoReadBufferForcesMemcpy) { | |
117 const size_t kDataSize = 2; | |
118 int write_data[kDataSize]; | |
119 int read_data[kDataSize]; | |
120 int* data_ptr; | |
121 | |
122 scoped_ring_buffer buffer(WebRtc_CreateBuffer(kDataSize, sizeof(int))); | |
123 ASSERT_TRUE(buffer.get() != NULL); | |
124 WebRtc_InitBuffer(buffer.get()); | |
125 | |
126 SetIncrementingData(write_data, kDataSize, 0); | |
127 EXPECT_EQ(kDataSize, WebRtc_WriteBuffer(buffer.get(), write_data, kDataSize)); | |
128 SetIncrementingData(read_data, kDataSize, kDataSize); | |
129 EXPECT_EQ(kDataSize, WebRtc_ReadBuffer(buffer.get(), | |
130 reinterpret_cast<void**>(&data_ptr), 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, WebRtc_ReadBuffer(buffer.get(), NULL, read_data, | |
137 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) == NULL); | |
144 EXPECT_TRUE(WebRtc_CreateBuffer(1, 0) == NULL); | |
145 RingBuffer* buffer = WebRtc_CreateBuffer(1, 1); | |
146 EXPECT_TRUE(buffer != NULL); | |
147 WebRtc_FreeBuffer(buffer); | |
148 } | |
149 | |
150 } // namespace webrtc | |
OLD | NEW |