diff options
Diffstat (limited to 'src/base/circular_queue.test.cc')
-rw-r--r-- | src/base/circular_queue.test.cc | 243 |
1 files changed, 243 insertions, 0 deletions
diff --git a/src/base/circular_queue.test.cc b/src/base/circular_queue.test.cc new file mode 100644 index 000000000..db59c3049 --- /dev/null +++ b/src/base/circular_queue.test.cc @@ -0,0 +1,243 @@ +/* + * Copyright (c) 2018 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Giacomo Travaglini + */ + +#include <gtest/gtest.h> + +#include "base/circular_queue.hh" + +/** Testing that once instantiated with a fixed size, + * the queue is still empty */ +TEST(CircularQueueTest, Empty) +{ + const auto cq_size = 8; + CircularQueue<uint32_t> cq(cq_size); + + ASSERT_EQ(cq.capacity(), cq_size); + ASSERT_EQ(cq.size(), 0); + ASSERT_TRUE(cq.empty()); +} + +/** Testing that once instantiated with a fixed size, + * the queue has Head = Tail + 1 */ +TEST(CircularQueueTest, HeadTailEmpty) +{ + const auto cq_size = 8; + CircularQueue<uint32_t> cq(cq_size); + ASSERT_EQ(cq.head(), cq.tail() + 1); +} + +/** Adding elements to the circular queue. + * Once an element has been added we test the new value + * of front() and back() (head an tail). Since we are just + * adding elements and not removing them, we expect the front + * value to be fixed and the back value to change, matching + * the latest pushed value.*/ +TEST(CircularQueueTest, AddingElements) +{ + const auto cq_size = 8; + CircularQueue<uint32_t> cq(cq_size); + + const auto first_element = 0xAAAAAAAA; + cq.push_back(first_element); + ASSERT_EQ(cq.front(), first_element); + ASSERT_EQ(cq.back(), first_element); + + const auto second_element = 0x55555555; + cq.push_back(second_element); + ASSERT_EQ(cq.front(), first_element); + ASSERT_EQ(cq.back(), second_element); + + ASSERT_EQ(cq.size(), 2); +} + +/** Removing elements from the circular queue. + * We add two elements and we consequently remove them. + * After removing them we check that the elements have been + * effectively removed, which means the circular queue is + * empty */ +TEST(CircularQueueTest, RemovingElements) +{ + const auto cq_size = 8; + CircularQueue<uint32_t> cq(cq_size); + + // Adding first element + const auto first_element = 0xAAAAAAAA; + cq.push_back(first_element); + + // Adding second element + const auto second_element = 0x55555555; + cq.push_back(second_element); + + auto initial_head = cq.head(); + auto initial_tail = cq.tail(); + + // Removing first and second element + cq.pop_front(); + ASSERT_EQ(cq.head(), initial_head + 1); + ASSERT_EQ(cq.tail(), initial_tail); + + cq.pop_front(); + ASSERT_EQ(cq.head(), initial_head + 2); + ASSERT_EQ(cq.tail(), initial_tail); + + ASSERT_EQ(cq.size(), 0); + ASSERT_TRUE(cq.empty()); +} + +/** Testing CircularQueue::full + * This tests adds elements to the queue and checks that it is full, + * which means: + * - CircularQueue::full == true + * - Head = Tail + 1 + */ +TEST(CircularQueueTest, Full) +{ + const auto cq_size = 8; + CircularQueue<uint32_t> cq(cq_size); + + const auto value = 0xAAAAAAAA; + for (auto idx = 0; idx < cq_size; idx++) { + cq.push_back(value); + } + + ASSERT_TRUE(cq.full()); + ASSERT_EQ(cq.head(), cq.tail() + 1); +} + +/** Testing CircularQueue::begin(), CircularQueue::end() + * This tests the following: + * - In an empty queue, begin() == end() + * - After pushing some elements in the queue, the begin() + * and end() iterators are correctly misaligned + */ +TEST(CircularQueueTest, BeginEnd) +{ + const auto cq_size = 8; + CircularQueue<uint32_t> cq(cq_size); + + // Begin/End are the same (empty) + ASSERT_EQ(cq.begin(), cq.end()); + + const auto first_value = 0xAAAAAAAA; + const auto second_value = 0x55555555; + + cq.push_back(first_value); + cq.push_back(second_value); + + // End = Begin + 2 + ASSERT_EQ(cq.begin() + 2, cq.end()); +} + +/** Testing that begin() and end() (-1) iterators + * actually point to the correct values + * so that dereferencing them leads to a match with the + * values of (front() and back()) + */ +TEST(CircularQueueTest, BeginFrontEndBack) +{ + const auto cq_size = 8; + CircularQueue<uint32_t> cq(cq_size); + + const auto front_value = 0xAAAAAAAA; + const auto back_value = 0x55555555; + + cq.push_back(front_value); + cq.push_back(back_value); + + ASSERT_EQ(*(cq.begin()), cq.front()); + ASSERT_EQ(*(cq.end() - 1), cq.back()); +} + +/** Testing circular queue iterators: + * By allocating two iterators to a queue we test several + * operators. + */ +TEST(CircularQueueTest, IteratorsOp) +{ + const auto cq_size = 8; + CircularQueue<uint32_t> cq(cq_size); + + const auto first_value = 0xAAAAAAAA; + const auto second_value = 0x55555555; + cq.push_back(first_value); + cq.push_back(second_value); + + auto it_1 = cq.begin(); + auto it_2 = cq.begin() + 1; + + // Operators test + ASSERT_TRUE(it_1 != it_2); + ASSERT_FALSE(it_1 == it_2); + ASSERT_FALSE(it_1 > it_2); + ASSERT_FALSE(it_1 >= it_2); + ASSERT_TRUE(it_1 < it_2); + ASSERT_TRUE(it_1 <= it_2); + ASSERT_EQ(*it_1, first_value); + ASSERT_EQ(it_1 + 1, it_2); + ASSERT_EQ(it_1, it_2 - 1); + ASSERT_EQ(it_2 - it_1, 1); + + auto temp_it = it_1; + ASSERT_EQ(++temp_it, it_2); + ASSERT_EQ(--temp_it, it_1); + ASSERT_EQ(temp_it++, it_1); + ASSERT_EQ(temp_it, it_2); + ASSERT_EQ(temp_it--, it_2); + ASSERT_EQ(temp_it, it_1); +} + +/** + * Testing a full loop, which is incrementing one iterator until + * it wraps and has the same index as the starting iterator. + * This test checks that even if they have the same index, they are + * not the same iterator since they have different round. + */ +TEST(CircularQueueTest, FullLoop) +{ + const auto cq_size = 8; + CircularQueue<uint32_t> cq(cq_size); + + // ending_it does a full loop and points at the same + // index as starting_it but with a different round + auto starting_it = cq.begin(); + auto ending_it = starting_it + cq_size; + + ASSERT_EQ(starting_it._idx, ending_it._idx); + ASSERT_TRUE(starting_it != ending_it); +} |