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/modules/audio_device/android/single_rw_fifo.h"
12
13#include <list>
14
15#include "testing/gtest/include/gtest/gtest.h"
16#include "webrtc/system_wrappers/interface/scoped_ptr.h"
17
18namespace webrtc {
19
20class SingleRwFifoTest : public testing::Test {
21 public:
22  enum {
23    // Uninteresting as it does not affect test
24    kBufferSize = 8,
25    kCapacity = 6,
26  };
27
28  SingleRwFifoTest() : fifo_(kCapacity), pushed_(0), available_(0) {
29  }
30  virtual ~SingleRwFifoTest() {}
31
32  void SetUp() {
33    for (int8_t i = 0; i < kCapacity; ++i) {
34      // Create memory area.
35      buffer_[i].reset(new int8_t[kBufferSize]);
36      // Set the first byte in the buffer to the order in which it was created
37      // this allows us to e.g. check that the buffers don't re-arrange.
38      buffer_[i][0] = i;
39      // Queue used by test.
40      memory_queue_.push_back(buffer_[i].get());
41    }
42    available_ = kCapacity;
43    VerifySizes();
44  }
45
46  void Push(int number_of_buffers) {
47    for (int8_t i = 0; i < number_of_buffers; ++i) {
48      int8_t* data = memory_queue_.front();
49      memory_queue_.pop_front();
50      fifo_.Push(data);
51      --available_;
52      ++pushed_;
53    }
54    VerifySizes();
55    VerifyOrdering();
56  }
57  void Pop(int number_of_buffers) {
58    for (int8_t i = 0; i < number_of_buffers; ++i) {
59      int8_t* data = fifo_.Pop();
60      memory_queue_.push_back(data);
61      ++available_;
62      --pushed_;
63    }
64    VerifySizes();
65    VerifyOrdering();
66  }
67
68  void VerifyOrdering() const {
69    std::list<int8_t*>::const_iterator iter = memory_queue_.begin();
70    if (iter == memory_queue_.end()) {
71      return;
72    }
73    int8_t previous_index = DataToElementIndex(*iter);
74    ++iter;
75    for (; iter != memory_queue_.end(); ++iter) {
76      int8_t current_index = DataToElementIndex(*iter);
77      EXPECT_EQ(current_index, ++previous_index % kCapacity);
78    }
79  }
80
81  void VerifySizes() {
82    EXPECT_EQ(available_, static_cast<int>(memory_queue_.size()));
83    EXPECT_EQ(pushed_, fifo_.size());
84  }
85
86  int8_t DataToElementIndex(int8_t* data) const {
87    return data[0];
88  }
89
90 protected:
91  SingleRwFifo fifo_;
92  // Memory area for proper de-allocation.
93  scoped_ptr<int8_t[]> buffer_[kCapacity];
94  std::list<int8_t*> memory_queue_;
95
96  int pushed_;
97  int available_;
98
99 private:
100  DISALLOW_COPY_AND_ASSIGN(SingleRwFifoTest);
101};
102
103TEST_F(SingleRwFifoTest, Construct) {
104  // All verifications are done in SetUp.
105}
106
107TEST_F(SingleRwFifoTest, Push) {
108  Push(kCapacity);
109}
110
111TEST_F(SingleRwFifoTest, Pop) {
112  // Push all available.
113  Push(available_);
114
115  // Test border cases:
116  // At capacity
117  Pop(1);
118  Push(1);
119
120  // At minimal capacity
121  Pop(pushed_);
122  Push(1);
123  Pop(1);
124}
125
126}  // namespace webrtc
127