/* * 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 #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 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 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 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 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 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 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 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 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 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); }