• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <android/log.h>
2 #include <android/native_window.h>
3 #include <android-base/unique_fd.h>
4 #include <dvr/dvr_api.h>
5 #include <dvr/dvr_buffer_queue.h>
6 
7 #include <gtest/gtest.h>
8 
9 #include <array>
10 #include <unordered_map>
11 
12 #ifndef ALOGD
13 #define ALOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
14 #endif
15 
16 #ifndef ALOGD_IF
17 #define ALOGD_IF(cond, ...) \
18   ((__predict_false(cond)) ? ((void)ALOGD(__VA_ARGS__)) : (void)0)
19 #endif
20 
21 namespace {
22 
23 static constexpr uint32_t kBufferWidth = 100;
24 static constexpr uint32_t kBufferHeight = 1;
25 static constexpr uint32_t kLayerCount = 1;
26 static constexpr uint32_t kBufferFormat = AHARDWAREBUFFER_FORMAT_BLOB;
27 static constexpr uint64_t kBufferUsage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN;
28 static constexpr size_t kQueueCapacity = 3;
29 
30 class DvrBufferQueueTest : public ::testing::Test {
31  public:
BufferAvailableCallback(void * context)32   static void BufferAvailableCallback(void* context) {
33     DvrBufferQueueTest* thiz = static_cast<DvrBufferQueueTest*>(context);
34     thiz->HandleBufferAvailable();
35   }
36 
BufferRemovedCallback(DvrReadBuffer * buffer,void * context)37   static void BufferRemovedCallback(DvrReadBuffer* buffer, void* context) {
38     DvrBufferQueueTest* thiz = static_cast<DvrBufferQueueTest*>(context);
39     thiz->HandleBufferRemoved(buffer);
40   }
41 
42  protected:
TearDown()43   void TearDown() override {
44     if (write_queue_ != nullptr) {
45       dvrWriteBufferQueueDestroy(write_queue_);
46       write_queue_ = nullptr;
47     }
48   }
49 
HandleBufferAvailable()50   void HandleBufferAvailable() {
51     buffer_available_count_ += 1;
52     ALOGD_IF(TRACE, "Buffer avaiable, count=%d", buffer_available_count_);
53   }
54 
HandleBufferRemoved(DvrReadBuffer * buffer)55   void HandleBufferRemoved(DvrReadBuffer* buffer) {
56     buffer_removed_count_ += 1;
57     ALOGD_IF(TRACE, "Buffer removed, buffer=%p, count=%d", buffer,
58              buffer_removed_count_);
59   }
60 
61   DvrWriteBufferQueue* write_queue_{nullptr};
62   int buffer_available_count_{0};
63   int buffer_removed_count_{0};
64 };
65 
TEST_F(DvrBufferQueueTest,WriteQueueCreateDestroy)66 TEST_F(DvrBufferQueueTest, WriteQueueCreateDestroy) {
67   int ret = dvrWriteBufferQueueCreate(
68       kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
69       /*capacity=*/0, sizeof(DvrNativeBufferMetadata), &write_queue_);
70   ASSERT_EQ(0, ret);
71 
72   dvrWriteBufferQueueDestroy(write_queue_);
73   write_queue_ = nullptr;
74 }
75 
TEST_F(DvrBufferQueueTest,WriteQueueGetCapacity)76 TEST_F(DvrBufferQueueTest, WriteQueueGetCapacity) {
77   int ret = dvrWriteBufferQueueCreate(
78       kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
79       kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_);
80   ASSERT_EQ(0, ret);
81 
82   size_t capacity = dvrWriteBufferQueueGetCapacity(write_queue_);
83 
84   ALOGD_IF(TRACE, "TestWrite_QueueGetCapacity, capacity=%zu", capacity);
85   ASSERT_EQ(kQueueCapacity, capacity);
86 }
87 
TEST_F(DvrBufferQueueTest,CreateReadQueueFromWriteQueue)88 TEST_F(DvrBufferQueueTest, CreateReadQueueFromWriteQueue) {
89   int ret = dvrWriteBufferQueueCreate(
90       kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
91       /*capacity=*/0, sizeof(DvrNativeBufferMetadata), &write_queue_);
92   ASSERT_EQ(0, ret);
93 
94   DvrReadBufferQueue* read_queue = nullptr;
95   ret = dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue);
96 
97   ASSERT_EQ(0, ret);
98   ASSERT_NE(nullptr, read_queue);
99 
100   dvrReadBufferQueueDestroy(read_queue);
101 }
102 
TEST_F(DvrBufferQueueTest,CreateReadQueueFromReadQueue)103 TEST_F(DvrBufferQueueTest, CreateReadQueueFromReadQueue) {
104   int ret = dvrWriteBufferQueueCreate(
105       kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
106       /*capacity=*/0, sizeof(DvrNativeBufferMetadata), &write_queue_);
107   ASSERT_EQ(0, ret);
108 
109   DvrReadBufferQueue* read_queue1 = nullptr;
110   DvrReadBufferQueue* read_queue2 = nullptr;
111   ret = dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue1);
112 
113   ASSERT_EQ(0, ret);
114   ASSERT_NE(nullptr, read_queue1);
115 
116   ret = dvrReadBufferQueueCreateReadQueue(read_queue1, &read_queue2);
117   ASSERT_EQ(0, ret);
118   ASSERT_NE(nullptr, read_queue2);
119   ASSERT_NE(read_queue1, read_queue2);
120 
121   dvrReadBufferQueueDestroy(read_queue1);
122   dvrReadBufferQueueDestroy(read_queue2);
123 }
124 
TEST_F(DvrBufferQueueTest,GainBuffer)125 TEST_F(DvrBufferQueueTest, GainBuffer) {
126   int ret = dvrWriteBufferQueueCreate(
127       kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
128       kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_);
129   ASSERT_EQ(ret, 0);
130 
131   DvrWriteBuffer* wb = nullptr;
132   EXPECT_FALSE(dvrWriteBufferIsValid(wb));
133 
134   DvrNativeBufferMetadata meta;
135   int fence_fd = -1;
136   ret = dvrWriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb, &meta,
137                                       &fence_fd);
138   ASSERT_EQ(ret, 0);
139   EXPECT_EQ(fence_fd, -1);
140   EXPECT_NE(wb, nullptr);
141   EXPECT_TRUE(dvrWriteBufferIsValid(wb));
142 }
143 
TEST_F(DvrBufferQueueTest,AcquirePostGainRelease)144 TEST_F(DvrBufferQueueTest, AcquirePostGainRelease) {
145   int ret = dvrWriteBufferQueueCreate(
146       kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
147       kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_);
148   ASSERT_EQ(ret, 0);
149 
150   DvrReadBufferQueue* read_queue = nullptr;
151   DvrReadBuffer* rb = nullptr;
152   DvrWriteBuffer* wb = nullptr;
153   DvrNativeBufferMetadata meta1;
154   DvrNativeBufferMetadata meta2;
155   int fence_fd = -1;
156 
157   ret = dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue);
158 
159   ASSERT_EQ(ret, 0);
160   ASSERT_NE(read_queue, nullptr);
161 
162   dvrReadBufferQueueSetBufferAvailableCallback(read_queue,
163                                                &BufferAvailableCallback, this);
164 
165   // Gain buffer for writing.
166   ret = dvrWriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb, &meta1,
167                                       &fence_fd);
168   ASSERT_EQ(ret, 0);
169   ASSERT_NE(wb, nullptr);
170   ASSERT_TRUE(dvrWriteBufferIsValid(wb));
171   ALOGD_IF(TRACE, "TestDequeuePostDequeueRelease, gain buffer %p, fence_fd=%d",
172            wb, fence_fd);
173   android::base::unique_fd release_fence(fence_fd);
174 
175   // Post buffer to the read_queue.
176   meta1.timestamp = 42;
177   ret = dvrWriteBufferQueuePostBuffer(write_queue_, wb, &meta1, /*fence=*/-1);
178   ASSERT_EQ(ret, 0);
179   ASSERT_FALSE(dvrWriteBufferIsValid(wb));
180   wb = nullptr;
181 
182   // Acquire buffer for reading.
183   ret = dvrReadBufferQueueAcquireBuffer(read_queue, /*timeout=*/10, &rb, &meta2,
184                                         &fence_fd);
185   ASSERT_EQ(ret, 0);
186   ASSERT_NE(rb, nullptr);
187 
188   // Dequeue is successfully, BufferAvailableCallback should be fired once.
189   ASSERT_EQ(buffer_available_count_, 1);
190   ASSERT_TRUE(dvrReadBufferIsValid(rb));
191 
192   // Metadata should be passed along from producer to consumer properly.
193   ASSERT_EQ(meta1.timestamp, meta2.timestamp);
194 
195   ALOGD_IF(TRACE,
196            "TestDequeuePostDequeueRelease, acquire buffer %p, fence_fd=%d", rb,
197            fence_fd);
198   android::base::unique_fd acquire_fence(fence_fd);
199 
200   // Release buffer to the write_queue.
201   ret = dvrReadBufferQueueReleaseBuffer(read_queue, rb, &meta2,
202                                         /*release_fence_fd=*/-1);
203   ASSERT_EQ(ret, 0);
204   ASSERT_FALSE(dvrReadBufferIsValid(rb));
205   rb = nullptr;
206 
207   // TODO(b/34387835) Currently buffer allocation has to happen after all queues
208   // are initialized.
209   size_t capacity = dvrReadBufferQueueGetCapacity(read_queue);
210 
211   ALOGD_IF(TRACE, "TestDequeuePostDequeueRelease, capacity=%zu", capacity);
212   ASSERT_EQ(kQueueCapacity, capacity);
213 
214   dvrReadBufferQueueDestroy(read_queue);
215 }
216 
TEST_F(DvrBufferQueueTest,GetANativeWindow)217 TEST_F(DvrBufferQueueTest, GetANativeWindow) {
218   int ret = dvrWriteBufferQueueCreate(
219       kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
220       /*capacity=*/0, sizeof(DvrNativeBufferMetadata), &write_queue_);
221   ASSERT_EQ(0, ret);
222   ASSERT_NE(nullptr, write_queue_);
223 
224   ANativeWindow* window = nullptr;
225   ret = dvrWriteBufferQueueGetANativeWindow(write_queue_, &window);
226   ASSERT_EQ(0, ret);
227   ASSERT_NE(nullptr, window);
228 
229   uint32_t width = ANativeWindow_getWidth(window);
230   uint32_t height = ANativeWindow_getHeight(window);
231   uint32_t format = ANativeWindow_getFormat(window);
232   ASSERT_EQ(kBufferWidth, width);
233   ASSERT_EQ(kBufferHeight, height);
234   ASSERT_EQ(kBufferFormat, format);
235 }
236 
237 // Create buffer queue of three buffers and dequeue three buffers out of it.
238 // Before each dequeue operation, we resize the buffer queue and expect the
239 // queue always return buffer with desired dimension.
TEST_F(DvrBufferQueueTest,ResizeBuffer)240 TEST_F(DvrBufferQueueTest, ResizeBuffer) {
241   int ret = dvrWriteBufferQueueCreate(
242       kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
243       kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_);
244   ASSERT_EQ(0, ret);
245 
246   int fence_fd = -1;
247 
248   DvrNativeBufferMetadata meta;
249   DvrReadBufferQueue* read_queue = nullptr;
250   DvrWriteBuffer* wb1 = nullptr;
251   DvrWriteBuffer* wb2 = nullptr;
252   DvrWriteBuffer* wb3 = nullptr;
253   AHardwareBuffer* ahb1 = nullptr;
254   AHardwareBuffer* ahb2 = nullptr;
255   AHardwareBuffer* ahb3 = nullptr;
256   AHardwareBuffer_Desc buffer_desc;
257 
258   ret = dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue);
259 
260   ASSERT_EQ(0, ret);
261   ASSERT_NE(nullptr, read_queue);
262 
263   dvrReadBufferQueueSetBufferRemovedCallback(read_queue, &BufferRemovedCallback,
264                                              this);
265 
266   // Handle all pending events on the read queue.
267   ret = dvrReadBufferQueueHandleEvents(read_queue);
268   ASSERT_EQ(0, ret);
269 
270   size_t capacity = dvrReadBufferQueueGetCapacity(read_queue);
271   ALOGD_IF(TRACE, "TestResizeBuffer, capacity=%zu", capacity);
272   ASSERT_EQ(kQueueCapacity, capacity);
273 
274   // Resize before dequeuing.
275   constexpr uint32_t w1 = 10;
276   ret = dvrWriteBufferQueueResizeBuffer(write_queue_, w1, kBufferHeight);
277   ASSERT_EQ(0, ret);
278 
279   // Gain first buffer for writing. All buffers will be resized.
280   ret = dvrWriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb1, &meta,
281                                       &fence_fd);
282   ASSERT_EQ(0, ret);
283   ASSERT_TRUE(dvrWriteBufferIsValid(wb1));
284   ALOGD_IF(TRACE, "TestResizeBuffer, gain buffer %p", wb1);
285   android::base::unique_fd release_fence1(fence_fd);
286 
287   // Check the buffer dimension.
288   ret = dvrWriteBufferGetAHardwareBuffer(wb1, &ahb1);
289   ASSERT_EQ(0, ret);
290   AHardwareBuffer_describe(ahb1, &buffer_desc);
291   ASSERT_EQ(w1, buffer_desc.width);
292   ASSERT_EQ(kBufferHeight, buffer_desc.height);
293   AHardwareBuffer_release(ahb1);
294 
295   // For the first resize, all buffers are reallocated.
296   int expected_buffer_removed_count = kQueueCapacity;
297   ret = dvrReadBufferQueueHandleEvents(read_queue);
298   ASSERT_EQ(0, ret);
299   ASSERT_EQ(expected_buffer_removed_count, buffer_removed_count_);
300 
301   // Resize the queue. We are testing with blob format, keep height to be 1.
302   constexpr uint32_t w2 = 20;
303   ret = dvrWriteBufferQueueResizeBuffer(write_queue_, w2, kBufferHeight);
304   ASSERT_EQ(0, ret);
305 
306   // The next buffer we dequeued should have new width.
307   ret = dvrWriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb2, &meta,
308                                       &fence_fd);
309   ASSERT_EQ(0, ret);
310   ASSERT_TRUE(dvrWriteBufferIsValid(wb2));
311   ALOGD_IF(TRACE, "TestResizeBuffer, gain buffer %p, fence_fd=%d", wb2,
312            fence_fd);
313   android::base::unique_fd release_fence2(fence_fd);
314 
315   // Check the buffer dimension, should be new width
316   ret = dvrWriteBufferGetAHardwareBuffer(wb2, &ahb2);
317   ASSERT_EQ(0, ret);
318   AHardwareBuffer_describe(ahb2, &buffer_desc);
319   ASSERT_EQ(w2, buffer_desc.width);
320   AHardwareBuffer_release(ahb2);
321 
322   // For the second resize, all but one buffers are reallocated.
323   expected_buffer_removed_count += (kQueueCapacity - 1);
324   ret = dvrReadBufferQueueHandleEvents(read_queue);
325   ASSERT_EQ(0, ret);
326   ASSERT_EQ(expected_buffer_removed_count, buffer_removed_count_);
327 
328   // Resize the queue for the third time.
329   constexpr uint32_t w3 = 30;
330   ret = dvrWriteBufferQueueResizeBuffer(write_queue_, w3, kBufferHeight);
331   ASSERT_EQ(0, ret);
332 
333   // The next buffer we dequeued should have new width.
334   ret = dvrWriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb3, &meta,
335                                       &fence_fd);
336   ASSERT_EQ(0, ret);
337   ASSERT_TRUE(dvrWriteBufferIsValid(wb3));
338   ALOGD_IF(TRACE, "TestResizeBuffer, gain buffer %p, fence_fd=%d", wb3,
339            fence_fd);
340   android::base::unique_fd release_fence3(fence_fd);
341 
342   // Check the buffer dimension, should be new width
343   ret = dvrWriteBufferGetAHardwareBuffer(wb3, &ahb3);
344   ASSERT_EQ(0, ret);
345   AHardwareBuffer_describe(ahb3, &buffer_desc);
346   ASSERT_EQ(w3, buffer_desc.width);
347   AHardwareBuffer_release(ahb3);
348 
349   // For the third resize, all but two buffers are reallocated.
350   expected_buffer_removed_count += (kQueueCapacity - 2);
351   ret = dvrReadBufferQueueHandleEvents(read_queue);
352   ASSERT_EQ(0, ret);
353   ASSERT_EQ(expected_buffer_removed_count, buffer_removed_count_);
354 
355   dvrReadBufferQueueDestroy(read_queue);
356 }
357 
TEST_F(DvrBufferQueueTest,ReadQueueEventFd)358 TEST_F(DvrBufferQueueTest, ReadQueueEventFd) {
359   int ret = dvrWriteBufferQueueCreate(
360       kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
361       kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_);
362   ASSERT_EQ(0, ret);
363 
364   DvrReadBufferQueue* read_queue = nullptr;
365   ret = dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue);
366 
367   ASSERT_EQ(0, ret);
368   ASSERT_NE(nullptr, read_queue);
369 
370   int event_fd = dvrReadBufferQueueGetEventFd(read_queue);
371   ASSERT_GT(event_fd, 0);
372 }
373 
374 // Verifies a Dvr{Read,Write}BufferQueue contains the same set of
375 // Dvr{Read,Write}Buffer(s) during their lifecycles. And for the same buffer_id,
376 // the corresponding AHardwareBuffer handle stays the same.
TEST_F(DvrBufferQueueTest,StableBufferIdAndHardwareBuffer)377 TEST_F(DvrBufferQueueTest, StableBufferIdAndHardwareBuffer) {
378   int ret = dvrWriteBufferQueueCreate(
379       kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
380       kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_);
381   ASSERT_EQ(0, ret);
382 
383   int fence_fd = -1;
384   DvrReadBufferQueue* read_queue = nullptr;
385   EXPECT_EQ(0, dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue));
386 
387   // Read buffers.
388   std::array<DvrReadBuffer*, kQueueCapacity> rbs;
389   // Write buffers.
390   std::array<DvrWriteBuffer*, kQueueCapacity> wbs;
391   // Buffer metadata.
392   std::array<DvrNativeBufferMetadata, kQueueCapacity> metas;
393   // Hardware buffers for Read buffers.
394   std::unordered_map<int, AHardwareBuffer*> rhbs;
395   // Hardware buffers for Write buffers.
396   std::unordered_map<int, AHardwareBuffer*> whbs;
397 
398   constexpr int kNumTests = 100;
399 
400   // This test runs the following operations many many times. Thus we prefer to
401   // use ASSERT_XXX rather than EXPECT_XXX to avoid spamming the output.
402   std::function<void(size_t i)> Gain = [&](size_t i) {
403     int ret = dvrWriteBufferQueueGainBuffer(write_queue_, /*timeout=*/10,
404                                             &wbs[i], &metas[i], &fence_fd);
405     ASSERT_EQ(ret, 0);
406     ASSERT_LT(fence_fd, 0);  // expect invalid fence.
407     ASSERT_TRUE(dvrWriteBufferIsValid(wbs[i]));
408     int buffer_id = dvrWriteBufferGetId(wbs[i]);
409     ASSERT_GT(buffer_id, 0);
410 
411     AHardwareBuffer* hb = nullptr;
412     ASSERT_EQ(0, dvrWriteBufferGetAHardwareBuffer(wbs[i], &hb));
413 
414     auto whb_it = whbs.find(buffer_id);
415     if (whb_it == whbs.end()) {
416       // If this is a new buffer id, check that total number of unique
417       // hardware buffers won't exceed queue capacity.
418       ASSERT_LT(whbs.size(), kQueueCapacity);
419       whbs.emplace(buffer_id, hb);
420     } else {
421       // If this is a buffer id we have seen before, check that the
422       // buffer_id maps to the same AHardwareBuffer handle.
423       ASSERT_EQ(hb, whb_it->second);
424     }
425   };
426 
427   std::function<void(size_t i)> Post = [&](size_t i) {
428     ASSERT_TRUE(dvrWriteBufferIsValid(wbs[i]));
429 
430     metas[i].timestamp++;
431     int ret = dvrWriteBufferQueuePostBuffer(write_queue_, wbs[i], &metas[i],
432                                             /*fence=*/-1);
433     ASSERT_EQ(ret, 0);
434   };
435 
436   std::function<void(size_t i)> Acquire = [&](size_t i) {
437     int ret = dvrReadBufferQueueAcquireBuffer(read_queue, /*timeout=*/10,
438                                               &rbs[i], &metas[i], &fence_fd);
439     ASSERT_EQ(ret, 0);
440     ASSERT_LT(fence_fd, 0);  // expect invalid fence.
441     ASSERT_TRUE(dvrReadBufferIsValid(rbs[i]));
442 
443     int buffer_id = dvrReadBufferGetId(rbs[i]);
444     ASSERT_GT(buffer_id, 0);
445 
446     AHardwareBuffer* hb = nullptr;
447     ASSERT_EQ(0, dvrReadBufferGetAHardwareBuffer(rbs[i], &hb));
448 
449     auto rhb_it = rhbs.find(buffer_id);
450     if (rhb_it == rhbs.end()) {
451       // If this is a new buffer id, check that total number of unique hardware
452       // buffers won't exceed queue capacity.
453       ASSERT_LT(rhbs.size(), kQueueCapacity);
454       rhbs.emplace(buffer_id, hb);
455     } else {
456       // If this is a buffer id we have seen before, check that the buffer_id
457       // maps to the same AHardwareBuffer handle.
458       ASSERT_EQ(hb, rhb_it->second);
459     }
460   };
461 
462   std::function<void(size_t i)> Release = [&](size_t i) {
463     ASSERT_TRUE(dvrReadBufferIsValid(rbs[i]));
464 
465     int ret = dvrReadBufferQueueReleaseBuffer(read_queue, rbs[i], &metas[i],
466                                               /*release_fence_fd=*/-1);
467     ASSERT_EQ(ret, 0);
468   };
469 
470   // Scenario one:
471   for (int i = 0; i < kNumTests; i++) {
472     // Gain all write buffers.
473     for (size_t i = 0; i < kQueueCapacity; i++) {
474       ASSERT_NO_FATAL_FAILURE(Gain(i));
475     }
476     // Post all write buffers.
477     for (size_t i = 0; i < kQueueCapacity; i++) {
478       ASSERT_NO_FATAL_FAILURE(Post(i));
479     }
480     // Acquire all read buffers.
481     for (size_t i = 0; i < kQueueCapacity; i++) {
482       ASSERT_NO_FATAL_FAILURE(Acquire(i));
483     }
484     // Release all read buffers.
485     for (size_t i = 0; i < kQueueCapacity; i++) {
486       ASSERT_NO_FATAL_FAILURE(Release(i));
487     }
488   }
489 
490   // Scenario two:
491   for (int i = 0; i < kNumTests; i++) {
492     // Gain and post all write buffers.
493     for (size_t i = 0; i < kQueueCapacity; i++) {
494       ASSERT_NO_FATAL_FAILURE(Gain(i));
495       ASSERT_NO_FATAL_FAILURE(Post(i));
496     }
497     // Acquire and release all read buffers.
498     for (size_t i = 0; i < kQueueCapacity; i++) {
499       ASSERT_NO_FATAL_FAILURE(Acquire(i));
500       ASSERT_NO_FATAL_FAILURE(Release(i));
501     }
502   }
503 
504   // Scenario three:
505   for (int i = 0; i < kNumTests; i++) {
506     // Gain all write buffers then post them in reversed order.
507     for (size_t i = 0; i < kQueueCapacity; i++) {
508       ASSERT_NO_FATAL_FAILURE(Gain(i));
509     }
510     for (size_t i = 0; i < kQueueCapacity; i++) {
511       ASSERT_NO_FATAL_FAILURE(Post(kQueueCapacity - 1 - i));
512     }
513 
514     // Acquire all write buffers then release them in reversed order.
515     for (size_t i = 0; i < kQueueCapacity; i++) {
516       ASSERT_NO_FATAL_FAILURE(Acquire(i));
517     }
518     for (size_t i = 0; i < kQueueCapacity; i++) {
519       ASSERT_NO_FATAL_FAILURE(Release(kQueueCapacity - 1 - i));
520     }
521   }
522 }
523 
524 }  // namespace
525