1f00567ecSGuillaume Chatelet //===-- Unittests for BlockStore ------------------------------------------===// 2f00567ecSGuillaume Chatelet // 3f00567ecSGuillaume Chatelet // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4f00567ecSGuillaume Chatelet // See https://llvm.org/LICENSE.txt for license information. 5f00567ecSGuillaume Chatelet // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6f00567ecSGuillaume Chatelet // 7f00567ecSGuillaume Chatelet //===----------------------------------------------------------------------===// 8f00567ecSGuillaume Chatelet 9f00567ecSGuillaume Chatelet #include "src/__support/blockstore.h" 10af1315c2SSiva Chandra Reddy #include "test/UnitTest/Test.h" 11f00567ecSGuillaume Chatelet 12f00567ecSGuillaume Chatelet struct Element { 13f00567ecSGuillaume Chatelet int a; 14f00567ecSGuillaume Chatelet long b; 15f00567ecSGuillaume Chatelet unsigned c; 16f00567ecSGuillaume Chatelet }; 17f00567ecSGuillaume Chatelet 18b6bc9d72SGuillaume Chatelet class LlvmLibcBlockStoreTest : public LIBC_NAMESPACE::testing::Test { 19f00567ecSGuillaume Chatelet public: 20f00567ecSGuillaume Chatelet template <size_t BLOCK_SIZE, size_t ELEMENT_COUNT, bool REVERSE> 21f00567ecSGuillaume Chatelet void populate_and_iterate() { 226503eff6SNick Desaulniers LIBC_NAMESPACE::BlockStore<Element, BLOCK_SIZE, REVERSE> block_store; 23f00567ecSGuillaume Chatelet for (int i = 0; i < int(ELEMENT_COUNT); ++i) 24eb9cc253SSiva Chandra Reddy ASSERT_TRUE(block_store.push_back({i, 2 * i, 3 * unsigned(i)})); 25f00567ecSGuillaume Chatelet auto end = block_store.end(); 26f00567ecSGuillaume Chatelet int i = 0; 27f00567ecSGuillaume Chatelet for (auto iter = block_store.begin(); iter != end; ++iter, ++i) { 28f00567ecSGuillaume Chatelet Element &e = *iter; 29f00567ecSGuillaume Chatelet if (REVERSE) { 30f00567ecSGuillaume Chatelet int j = ELEMENT_COUNT - 1 - i; 31f00567ecSGuillaume Chatelet ASSERT_EQ(e.a, j); 32f00567ecSGuillaume Chatelet ASSERT_EQ(e.b, long(j * 2)); 33f00567ecSGuillaume Chatelet ASSERT_EQ(e.c, unsigned(j * 3)); 34f00567ecSGuillaume Chatelet } else { 35f00567ecSGuillaume Chatelet ASSERT_EQ(e.a, i); 36f00567ecSGuillaume Chatelet ASSERT_EQ(e.b, long(i * 2)); 37f00567ecSGuillaume Chatelet ASSERT_EQ(e.c, unsigned(i * 3)); 38f00567ecSGuillaume Chatelet } 39f00567ecSGuillaume Chatelet } 40f00567ecSGuillaume Chatelet ASSERT_EQ(i, int(ELEMENT_COUNT)); 416503eff6SNick Desaulniers LIBC_NAMESPACE::BlockStore<Element, BLOCK_SIZE, REVERSE>::destroy( 42f00567ecSGuillaume Chatelet &block_store); 43f00567ecSGuillaume Chatelet } 44f00567ecSGuillaume Chatelet 45f00567ecSGuillaume Chatelet template <bool REVERSE> void back_test() { 466503eff6SNick Desaulniers using LIBC_NAMESPACE::BlockStore; 47f00567ecSGuillaume Chatelet BlockStore<int, 4, REVERSE> block_store; 48f00567ecSGuillaume Chatelet for (int i = 0; i < 20; i++) 49eb9cc253SSiva Chandra Reddy ASSERT_TRUE(block_store.push_back(i)); 50f00567ecSGuillaume Chatelet for (int i = 19; i >= 0; i--, block_store.pop_back()) 51f00567ecSGuillaume Chatelet ASSERT_EQ(block_store.back(), i); 52f00567ecSGuillaume Chatelet block_store.destroy(&block_store); 53f00567ecSGuillaume Chatelet } 54f00567ecSGuillaume Chatelet 55f00567ecSGuillaume Chatelet template <bool REVERSE> void empty_test() { 566503eff6SNick Desaulniers using LIBC_NAMESPACE::BlockStore; 57f00567ecSGuillaume Chatelet BlockStore<int, 2, REVERSE> block_store; 58f00567ecSGuillaume Chatelet 59f00567ecSGuillaume Chatelet ASSERT_TRUE(block_store.empty()); 60eb9cc253SSiva Chandra Reddy ASSERT_TRUE(block_store.push_back(1)); 61eb9cc253SSiva Chandra Reddy for (int i = 0; i < 10; i++) { 62f00567ecSGuillaume Chatelet ASSERT_FALSE(block_store.empty()); 63eb9cc253SSiva Chandra Reddy ASSERT_TRUE(block_store.push_back(1)); 64eb9cc253SSiva Chandra Reddy } 65f00567ecSGuillaume Chatelet block_store.destroy(&block_store); 66f00567ecSGuillaume Chatelet } 67eb272568SMichael Jones 68eb272568SMichael Jones template <bool REVERSE> void erase_test() { 69eb272568SMichael Jones using LIBC_NAMESPACE::BlockStore; 70eb272568SMichael Jones BlockStore<int, 2, REVERSE> block_store; 71eb272568SMichael Jones int i; 72eb272568SMichael Jones 73eb272568SMichael Jones constexpr int ARR_SIZE = 6; 74eb272568SMichael Jones 75eb272568SMichael Jones ASSERT_TRUE(block_store.empty()); 76eb272568SMichael Jones for (int i = 0; i < ARR_SIZE; i++) { 77eb272568SMichael Jones ASSERT_TRUE(block_store.push_back(i + 1)); 78eb272568SMichael Jones } 79eb272568SMichael Jones 80eb272568SMichael Jones // block_store state should be {1,2,3,4,5,6} 81eb272568SMichael Jones 82eb272568SMichael Jones block_store.erase(block_store.begin()); 83eb272568SMichael Jones 84eb272568SMichael Jones // FORWARD: block_store state should be {2,3,4,5,6} 85eb272568SMichael Jones // REVERSE: block_store state should be {1,2,3,4,5} 86eb272568SMichael Jones 87eb272568SMichael Jones auto iter = block_store.begin(); 88eb272568SMichael Jones for (i = 0; iter != block_store.end(); ++i, ++iter) { 89eb272568SMichael Jones if (!REVERSE) { 90eb272568SMichael Jones ASSERT_EQ(*iter, i + 2); 91eb272568SMichael Jones } else { 92eb272568SMichael Jones ASSERT_EQ(*iter, (ARR_SIZE - 1) - i); 93eb272568SMichael Jones } 94eb272568SMichael Jones } 95eb272568SMichael Jones 96eb272568SMichael Jones // Assert that there were the correct number of elements 97eb272568SMichael Jones ASSERT_EQ(i, ARR_SIZE - 1); 98eb272568SMichael Jones 99eb272568SMichael Jones block_store.erase(block_store.end()); 100eb272568SMichael Jones 101eb272568SMichael Jones // BOTH: block_store state should be {2,3,4,5} 102eb272568SMichael Jones 103eb272568SMichael Jones iter = block_store.begin(); 104eb272568SMichael Jones for (i = 0; iter != block_store.end(); ++i, ++iter) { 105eb272568SMichael Jones if (!REVERSE) { 106eb272568SMichael Jones ASSERT_EQ(*iter, i + 2); 107eb272568SMichael Jones } else { 108eb272568SMichael Jones ASSERT_EQ(*iter, (ARR_SIZE - 1) - i); 109eb272568SMichael Jones } 110eb272568SMichael Jones } 111eb272568SMichael Jones 112eb272568SMichael Jones ASSERT_EQ(i, ARR_SIZE - 2); 113eb272568SMichael Jones 114eb272568SMichael Jones block_store.erase(block_store.begin() + 1); 115eb272568SMichael Jones 116eb272568SMichael Jones // FORWARD: block_store state should be {2,4,5} 117eb272568SMichael Jones // REVERSE: block_store state should be {2,3,5} 118eb272568SMichael Jones 119eb272568SMichael Jones const int FORWARD_RESULTS[] = {2, 4, 5}; 120eb272568SMichael Jones const int REVERSE_RESULTS[] = {2, 3, 5}; 121eb272568SMichael Jones 122eb272568SMichael Jones iter = block_store.begin(); 123eb272568SMichael Jones for (i = 0; iter != block_store.end(); ++i, ++iter) { 124eb272568SMichael Jones if (!REVERSE) { 125eb272568SMichael Jones ASSERT_EQ(*iter, FORWARD_RESULTS[i]); 126eb272568SMichael Jones } else { 127eb272568SMichael Jones ASSERT_EQ(*iter, REVERSE_RESULTS[ARR_SIZE - 4 - i]); // reversed 128eb272568SMichael Jones } 129eb272568SMichael Jones } 130eb272568SMichael Jones 131eb272568SMichael Jones ASSERT_EQ(i, ARR_SIZE - 3); 132eb272568SMichael Jones 133eb272568SMichael Jones block_store.erase(block_store.begin() + 1); 134eb272568SMichael Jones // BOTH: block_store state should be {2,5} 135eb272568SMichael Jones 136eb272568SMichael Jones iter = block_store.begin(); 137eb272568SMichael Jones if (!REVERSE) { 138eb272568SMichael Jones ASSERT_EQ(*iter, 2); 139eb272568SMichael Jones ASSERT_EQ(*(iter + 1), 5); 140eb272568SMichael Jones } else { 141eb272568SMichael Jones ASSERT_EQ(*iter, 5); 142eb272568SMichael Jones ASSERT_EQ(*(iter + 1), 2); 143eb272568SMichael Jones } 144eb272568SMichael Jones 145eb272568SMichael Jones block_store.erase(block_store.begin()); 146eb272568SMichael Jones // FORWARD: block_store state should be {5} 147eb272568SMichael Jones // REVERSE: block_store state should be {2} 148eb272568SMichael Jones iter = block_store.begin(); 149eb272568SMichael Jones if (!REVERSE) { 150eb272568SMichael Jones ASSERT_EQ(*iter, 5); 151eb272568SMichael Jones } else { 152eb272568SMichael Jones ASSERT_EQ(*iter, 2); 153eb272568SMichael Jones } 154eb272568SMichael Jones 155eb272568SMichael Jones block_store.erase(block_store.begin()); 156eb272568SMichael Jones // BOTH: block_store state should be {} 157eb272568SMichael Jones 158eb272568SMichael Jones block_store.destroy(&block_store); 159eb272568SMichael Jones } 160f00567ecSGuillaume Chatelet }; 161f00567ecSGuillaume Chatelet 162f00567ecSGuillaume Chatelet TEST_F(LlvmLibcBlockStoreTest, PopulateAndIterate4) { 163f00567ecSGuillaume Chatelet populate_and_iterate<4, 4, false>(); 164f00567ecSGuillaume Chatelet } 165f00567ecSGuillaume Chatelet 166f00567ecSGuillaume Chatelet TEST_F(LlvmLibcBlockStoreTest, PopulateAndIterate8) { 167f00567ecSGuillaume Chatelet populate_and_iterate<4, 8, false>(); 168f00567ecSGuillaume Chatelet } 169f00567ecSGuillaume Chatelet 170f00567ecSGuillaume Chatelet TEST_F(LlvmLibcBlockStoreTest, PopulateAndIterate10) { 171f00567ecSGuillaume Chatelet populate_and_iterate<4, 10, false>(); 172f00567ecSGuillaume Chatelet } 173f00567ecSGuillaume Chatelet 174f00567ecSGuillaume Chatelet TEST_F(LlvmLibcBlockStoreTest, PopulateAndIterateReverse4) { 175f00567ecSGuillaume Chatelet populate_and_iterate<4, 4, true>(); 176f00567ecSGuillaume Chatelet } 177f00567ecSGuillaume Chatelet 178f00567ecSGuillaume Chatelet TEST_F(LlvmLibcBlockStoreTest, PopulateAndIterateReverse8) { 179f00567ecSGuillaume Chatelet populate_and_iterate<4, 8, true>(); 180f00567ecSGuillaume Chatelet } 181f00567ecSGuillaume Chatelet 182f00567ecSGuillaume Chatelet TEST_F(LlvmLibcBlockStoreTest, PopulateAndIterateReverse10) { 183f00567ecSGuillaume Chatelet populate_and_iterate<4, 10, true>(); 184f00567ecSGuillaume Chatelet } 185f00567ecSGuillaume Chatelet 186*bc4c3bf1SJoseph Huber TEST_F(LlvmLibcBlockStoreTest, Back) { 187*bc4c3bf1SJoseph Huber back_test<false>(); 188*bc4c3bf1SJoseph Huber back_test<true>(); 189*bc4c3bf1SJoseph Huber } 190f00567ecSGuillaume Chatelet 191f00567ecSGuillaume Chatelet TEST_F(LlvmLibcBlockStoreTest, Empty) { 192f00567ecSGuillaume Chatelet empty_test<false>(); 193f00567ecSGuillaume Chatelet empty_test<true>(); 194f00567ecSGuillaume Chatelet } 195eb272568SMichael Jones 196eb272568SMichael Jones TEST_F(LlvmLibcBlockStoreTest, Erase) { 197eb272568SMichael Jones erase_test<false>(); 198eb272568SMichael Jones erase_test<true>(); 199eb272568SMichael Jones } 200