diff options
Diffstat (limited to 'lib/src/test')
-rw-r--r-- | lib/src/test/CMakeLists.txt | 6 | ||||
-rw-r--r-- | lib/src/test/test_bitmap.cc | 261 | ||||
-rw-r--r-- | lib/src/test/test_interest_manifest.cc | 203 | ||||
-rw-r--r-- | lib/src/test/test_khash.cc | 179 | ||||
-rw-r--r-- | lib/src/test/test_name.cc | 82 | ||||
-rw-r--r-- | lib/src/test/test_new_header.cc | 42 | ||||
-rw-r--r-- | lib/src/test/test_pool.cc | 209 | ||||
-rw-r--r-- | lib/src/test/test_ring.cc | 104 | ||||
-rw-r--r-- | lib/src/test/test_udp_header.cc | 65 | ||||
-rw-r--r-- | lib/src/test/test_vector.cc | 254 |
10 files changed, 1314 insertions, 91 deletions
diff --git a/lib/src/test/CMakeLists.txt b/lib/src/test/CMakeLists.txt index 3e3c025c7..17cf835d2 100644 --- a/lib/src/test/CMakeLists.txt +++ b/lib/src/test/CMakeLists.txt @@ -22,6 +22,12 @@ list(APPEND TESTS_SRC test_new_header.cc test_udp_header.cc test_validation.cc + test_bitmap.cc + test_interest_manifest.cc + test_khash.cc + test_pool.cc + test_ring.cc + test_vector.cc ) ############################################################## diff --git a/lib/src/test/test_bitmap.cc b/lib/src/test/test_bitmap.cc new file mode 100644 index 000000000..7fc8eef71 --- /dev/null +++ b/lib/src/test/test_bitmap.cc @@ -0,0 +1,261 @@ +/* + * Copyright (c) 2021 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <gtest/gtest.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <unistd.h> +#include <netinet/in.h> + +extern "C" +{ +#define WITH_TESTS +#include <hicn/util/bitmap.h> +} + +#define DEFAULT_SIZE 10 + +class BitmapTest : public ::testing::Test +{ +protected: + BitmapTest () {} + + virtual ~BitmapTest () {} + + bitmap_t *bitmap; +}; + +/* + * TEST: bitmap allocation + */ +TEST_F (BitmapTest, BitmapAllocation) +{ + int rc; + + /* + * We take a value < 32 on purpose to avoid confusion on the choice of a 32 + * or 64 bit integer for storage + */ + size_t size_not_pow2 = DEFAULT_SIZE; + bitmap_init (bitmap, size_not_pow2, 0); + + /* + * Bitmap should have been allocated with a size rounded to the next power + * of 2 + */ + EXPECT_EQ (bitmap_get_alloc_size (bitmap), 1UL); + + /* By default, no element should be set */ + EXPECT_FALSE (bitmap_is_set (bitmap, 0)); + EXPECT_TRUE (bitmap_is_unset (bitmap, 0)); + + EXPECT_EQ (bitmap_get_alloc_size (bitmap), 1UL); + + EXPECT_FALSE (bitmap_is_set (bitmap, size_not_pow2 - 1)); + EXPECT_TRUE (bitmap_is_unset (bitmap, size_not_pow2 - 1)); + + /* Bitmap should not have been reallocated */ + EXPECT_EQ (bitmap_get_alloc_size (bitmap), 1UL); + + /* After setting a bit after the end, bitmap should have been reallocated */ + bitmap_set (bitmap, sizeof (bitmap[0]) * 8 - 1); + EXPECT_EQ (bitmap_get_alloc_size (bitmap), 1UL); + + /* After setting a bit after the end, bitmap should have been reallocated */ + rc = bitmap_set (bitmap, sizeof (bitmap[0]) * 8); + EXPECT_GE (rc, 0); + EXPECT_EQ (bitmap_get_alloc_size (bitmap), 2UL); + + rc = bitmap_set (bitmap, sizeof (bitmap[0]) * 8 + 1); + EXPECT_GE (rc, 0); + EXPECT_EQ (bitmap_get_alloc_size (bitmap), 2UL); + + bitmap_free (bitmap); + + size_t size_pow2 = 16; + + /* Limiting test for allocation size */ + bitmap_init (bitmap, size_pow2, 0); + EXPECT_EQ (bitmap_get_alloc_size (bitmap), 1UL); + + bitmap_free (bitmap); +} + +TEST_F (BitmapTest, BitmapSet) +{ + bitmap_init (bitmap, DEFAULT_SIZE, 0); + + bitmap_set (bitmap, 20); + EXPECT_TRUE (bitmap_is_set (bitmap, 20)); + EXPECT_FALSE (bitmap_is_unset (bitmap, 20)); + EXPECT_FALSE (bitmap_is_set (bitmap, 19)); + EXPECT_TRUE (bitmap_is_unset (bitmap, 19)); + + // Test edge cases (i.e. start and end of block) + off_t start_position = 0; + bitmap_set (bitmap, start_position); + EXPECT_TRUE (bitmap_is_set (bitmap, start_position)); + EXPECT_FALSE (bitmap_is_unset (bitmap, start_position)); + + off_t end_position = BITMAP_WIDTH (bitmap) - 1; + bitmap_set (bitmap, end_position); + EXPECT_TRUE (bitmap_is_set (bitmap, end_position)); + EXPECT_FALSE (bitmap_is_unset (bitmap, end_position)); + + bitmap_free (bitmap); +} + +TEST_F (BitmapTest, BitmapUnSet) +{ + bitmap_init (bitmap, DEFAULT_SIZE, 0); + + bitmap_set (bitmap, 20); + bitmap_set (bitmap, 19); + bitmap_unset (bitmap, 20); + EXPECT_FALSE (bitmap_is_set (bitmap, 20)); + EXPECT_TRUE (bitmap_is_unset (bitmap, 20)); + EXPECT_TRUE (bitmap_is_set (bitmap, 19)); + EXPECT_FALSE (bitmap_is_unset (bitmap, 19)); + + bitmap_free (bitmap); +} + +TEST_F (BitmapTest, BitmapSetTo) +{ + bitmap_init (bitmap, DEFAULT_SIZE, 0); + + bitmap_set_to (bitmap, 40); + EXPECT_TRUE (bitmap_is_set (bitmap, 20)); + EXPECT_TRUE (bitmap_is_set (bitmap, 21)); + EXPECT_TRUE (bitmap_is_unset (bitmap, 41)); + EXPECT_TRUE (bitmap_is_unset (bitmap, 42)); + + bitmap_free (bitmap); +} + +TEST_F (BitmapTest, BitmapFirstSet) +{ + bitmap_init (bitmap, DEFAULT_SIZE, 0); + + // Get first set bit. It should be INVALID_INDEX + EXPECT_EQ (bitmap_first_set (bitmap), BITMAP_INVALID_INDEX); + + // set bit 40 + bitmap_set (bitmap, 40); + EXPECT_TRUE (bitmap_is_set (bitmap, 40)); + + // Get first set bit. It should be bit 40 (surprise):) + EXPECT_EQ (bitmap_first_set (bitmap), hicn_uword (40)); + + // set bit 3 + bitmap_set (bitmap, 3); + EXPECT_TRUE (bitmap_is_set (bitmap, 3)); + + // The first set bit now should be bit #3 + EXPECT_EQ (bitmap_first_set (bitmap), hicn_uword (3)); + + bitmap_free (bitmap); +} + +TEST_F (BitmapTest, BitmapFirstUnSet) +{ + bitmap_init (bitmap, DEFAULT_SIZE, 0); + + // Get first unset bit. It should be 0 + EXPECT_EQ (bitmap_first_unset (bitmap), hicn_uword (0)); + + // set bit 0 + bitmap_set (bitmap, 0); + EXPECT_TRUE (bitmap_is_set (bitmap, 0)); + + // Get first unset bit. It should be bit 1 + EXPECT_EQ (bitmap_first_unset (bitmap), hicn_uword (1)); + + // set bit 3 + bitmap_set (bitmap, 3); + EXPECT_TRUE (bitmap_is_set (bitmap, 3)); + + // The first set bit now should be still 1 + EXPECT_EQ (bitmap_first_unset (bitmap), hicn_uword (1)); + + bitmap_free (bitmap); +} + +TEST_F (BitmapTest, BitmapNextSet) +{ + bitmap_init (bitmap, DEFAULT_SIZE, 0); + + // Get next unset bit >= 0. It should be INVALID + EXPECT_EQ (bitmap_next_set (bitmap, 0), BITMAP_INVALID_INDEX); + + // set bit 0 + bitmap_set (bitmap, 0); + EXPECT_TRUE (bitmap_is_set (bitmap, 0)); + + // Get next set bit >= 0. It should be bit 0 + EXPECT_EQ (bitmap_next_set (bitmap, 0), hicn_uword (0)); + + // set bit 3 + bitmap_set (bitmap, 3); + EXPECT_TRUE (bitmap_is_set (bitmap, 3)); + + // Get next set bit >= 1. It should be 3 + EXPECT_EQ (bitmap_next_set (bitmap, 1), hicn_uword (3)); + + // set (N-2)th bit + bitmap_set (bitmap, DEFAULT_SIZE * WORD_WIDTH - 2); + EXPECT_TRUE (bitmap_is_set (bitmap, DEFAULT_SIZE * WORD_WIDTH - 2)); + EXPECT_EQ (bitmap_next_set (bitmap, DEFAULT_SIZE * WORD_WIDTH - 3), + DEFAULT_SIZE * WORD_WIDTH - 2); + + // set (N-1)th bit + bitmap_unset (bitmap, DEFAULT_SIZE * WORD_WIDTH - 2); + bitmap_set (bitmap, DEFAULT_SIZE * WORD_WIDTH - 1); + EXPECT_TRUE (bitmap_is_set (bitmap, DEFAULT_SIZE * WORD_WIDTH - 1)); + EXPECT_EQ (bitmap_next_set (bitmap, DEFAULT_SIZE * WORD_WIDTH - 2), + DEFAULT_SIZE * WORD_WIDTH - 1); + EXPECT_EQ (bitmap_next_set (bitmap, DEFAULT_SIZE * WORD_WIDTH - 1), + DEFAULT_SIZE * WORD_WIDTH - 1); + + bitmap_free (bitmap); +} + +TEST_F (BitmapTest, BitmapNextUnSet) +{ + bitmap_init (bitmap, DEFAULT_SIZE, 0); + + // Get next unset bit >= 0. It should be 0 + EXPECT_EQ (bitmap_next_unset (bitmap, 0), hicn_uword (0)); + + // set bit 0 + bitmap_set (bitmap, 0); + EXPECT_TRUE (bitmap_is_set (bitmap, 0)); + + // Get next set bit >= 0. It should be bit 1 + EXPECT_EQ (bitmap_next_unset (bitmap, 0), hicn_uword (1)); + + // set bit 3 + bitmap_set (bitmap, 3); + EXPECT_TRUE (bitmap_is_set (bitmap, 3)); + + // Get next unset bit after 3. It should be 4 + EXPECT_EQ (bitmap_next_unset (bitmap, 3), hicn_uword (4)); + + bitmap_free (bitmap); +} diff --git a/lib/src/test/test_interest_manifest.cc b/lib/src/test/test_interest_manifest.cc new file mode 100644 index 000000000..5df06d6bd --- /dev/null +++ b/lib/src/test/test_interest_manifest.cc @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2021 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <gtest/gtest.h> +#include <gmock/gmock.h> + +extern "C" +{ +#include <hicn/interest_manifest.h> +} + +static constexpr hicn_uword WORD_SIZE = WORD_WIDTH; + +class InterestManifestTest : public ::testing::Test +{ +protected: + static constexpr u32 n_suffixes = 0x00000014; + static constexpr u32 padding = 0x21232425; + static constexpr hicn_uword bitmap_word = ~0ULL; + static inline std::vector<uint32_t> values = { 10, 22, 23, 43, 54, 65, 66, + 4, 33, 2, 44, 99, 87, 67, + 78, 98, 76, 1, 7, 123 }; + InterestManifestTest () {} + virtual ~InterestManifestTest () {} + + uint8_t buffer[512]; + hicn_uword bitmap_saved[BITMAP_SIZE]; +}; + +TEST_F (InterestManifestTest, OneWordBitmapUpdate) +{ + hicn_uword initial_bitmap[1]; + hicn_uword curr_bitmap[1] = { 0 }; + initial_bitmap[0] = + 0x0000000000000b07; // ...000000000000000000000101100000111 + + // Consume first 4 'one' bits (i.e. suffixes), reaching position 9 + size_t pos = 0, max_suffixes = 4; + pos = interest_manifest_update_bitmap (initial_bitmap, curr_bitmap, pos, + WORD_SIZE, max_suffixes); + EXPECT_EQ (pos, std::size_t (9)); + EXPECT_EQ (curr_bitmap[0], hicn_uword (0x0000000000000107)); + + // Consume the remaining 2 'one' bits, reaching end of bitmap + hicn_uword curr_bitmap2[1] = { 0 }; + pos = interest_manifest_update_bitmap (initial_bitmap, curr_bitmap2, pos, + WORD_SIZE, max_suffixes); + EXPECT_EQ (pos, WORD_SIZE); + EXPECT_EQ (curr_bitmap2[0], hicn_uword (0x00000a00)); + + // Consume all suffixes at once + hicn_uword curr_bitmap3[1] = { 0 }; + max_suffixes = 16; + pos = interest_manifest_update_bitmap (initial_bitmap, curr_bitmap3, 0, + WORD_SIZE, max_suffixes); + EXPECT_EQ (pos, WORD_SIZE); + EXPECT_EQ (curr_bitmap3[0], initial_bitmap[0]); +} + +TEST_F (InterestManifestTest, TwoWordBitmapUpdate) +{ + hicn_uword initial_bitmap[2]; + initial_bitmap[0] = 0x0000000000000b07; + initial_bitmap[1] = 0x0000000000000b07; + // -> 0000000000000000000010110000011100000000000000000000101100000111 + + int expected_pos[] = { WORD_SIZE + 2, 2 * WORD_SIZE }; + u32 expected_bitmap[][2] = { { 0x00000b07, 0x00000003 }, + { 0x0, 0x00000b04 } }; + + // Loop to consume all suffixes + int pos = 0, max_suffixes = 8, i = 0, len = WORD_SIZE * 2; + while (pos != len) + { + hicn_uword curr_bitmap[2] = { 0 }; + pos = interest_manifest_update_bitmap (initial_bitmap, curr_bitmap, pos, + len, max_suffixes); + + EXPECT_EQ (pos, expected_pos[i]); + EXPECT_EQ (curr_bitmap[0], expected_bitmap[i][0]); + EXPECT_EQ (curr_bitmap[1], expected_bitmap[i][1]); + i++; + } +} + +TEST_F (InterestManifestTest, SerializeDeserialize) +{ +#if hicn_uword_bits == 64 +#define F(x) hicn_host_to_net_64 (x) +#elif hicn_uword_bits == 32 +#define F(x) hicn_host_to_net_32 (x) +#else +#error "Unrecognized architecture" +#endif + + auto header = reinterpret_cast<interest_manifest_header_t *> (buffer); + interest_manifest_init (header); + + for (const auto &v : values) + { + interest_manifest_add_suffix (header, v); + } + + EXPECT_EQ (header->n_suffixes, n_suffixes); + + // Save bitmap + memcpy (bitmap_saved, header->request_bitmap, sizeof (bitmap_saved)); + + // Serialize manifest + interest_manifest_serialize (header); + + // If architecture is little endian, bytes should be now swapped + EXPECT_THAT (header->n_suffixes, ::testing::Eq (hicn_host_to_net_32 ( + n_suffixes) /* 0x14000000 */)); + + for (unsigned i = 0; i < BITMAP_SIZE; i++) + { + EXPECT_THAT (header->request_bitmap[i], + ::testing::Eq (F (bitmap_saved[i]))); + } + + hicn_name_suffix_t *suffix = (hicn_name_suffix_t *) (header + 1); + for (unsigned i = 0; i < n_suffixes; i++) + { + EXPECT_THAT (*(suffix + i), + ::testing::Eq (hicn_host_to_net_32 (values[i]))); + } + + // Deserialize manifest + interest_manifest_deserialize (header); + + // Bytes should now be as before + EXPECT_THAT (header->n_suffixes, ::testing::Eq (n_suffixes)); + + int i = 0; + interest_manifest_foreach_suffix (header, suffix) + { + EXPECT_THAT (*suffix, ::testing::Eq (values[i])); + i++; + } +} + +TEST_F (InterestManifestTest, ForEach) +{ + auto header = reinterpret_cast<interest_manifest_header_t *> (buffer); + header->n_suffixes = n_suffixes; + header->padding = padding; + memset (header->request_bitmap, 0xff, BITMAP_SIZE * sizeof (hicn_uword)); + + hicn_name_suffix_t *suffix = (hicn_name_suffix_t *) (header + 1); + for (uint32_t i = 0; i < n_suffixes; i++) + { + *(suffix + i) = values[i]; + } + + // Iterate over interest manifest. As bitmap is all 1, we should be able to + // iterate over all suffixes. + unsigned i = 0; + interest_manifest_foreach_suffix (header, suffix) + { + EXPECT_EQ (*suffix, values[i]); + i++; + } + + std::set<uint32_t> set_values (values.begin (), values.end ()); + + // Unset few bitmap positions + interest_manifest_del_suffix (header, 5); + set_values.erase (values[5]); + + interest_manifest_del_suffix (header, 6); + set_values.erase (values[6]); + + interest_manifest_del_suffix (header, 12); + set_values.erase (values[12]); + + interest_manifest_del_suffix (header, 17); + set_values.erase (values[17]); + + // Iterate over interest manifest and remove elements in manifest from set. + // The set should be empty at the end. + interest_manifest_foreach_suffix (header, suffix) + { + std::cout << suffix - _FIRST (header) << std::endl; + EXPECT_TRUE (set_values.find (*suffix) != set_values.end ()) + << "The value was " << *suffix; + set_values.erase (*suffix); + } + + EXPECT_TRUE (set_values.empty ()); +}
\ No newline at end of file diff --git a/lib/src/test/test_khash.cc b/lib/src/test/test_khash.cc new file mode 100644 index 000000000..b0423ab5d --- /dev/null +++ b/lib/src/test/test_khash.cc @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2021 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <gtest/gtest.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <unistd.h> +#include <netinet/in.h> + +extern "C" +{ +#include <hicn/util/khash.h> +} + +KHASH_MAP_INIT_INT (int, unsigned char) + +typedef struct +{ + unsigned key; + unsigned char val; +} int_unpack_t; + +typedef struct +{ + unsigned key; + unsigned char val; +} __attribute__ ((__packed__)) int_packed_t; + +#define hash_eq(a, b) ((a).key == (b).key) +#define hash_func(a) ((a).key) + +KHASH_INIT (iun, int_unpack_t, char, 0, hash_func, hash_eq) +KHASH_INIT (ipk, int_packed_t, char, 0, hash_func, hash_eq) + +class KHashTest : public ::testing::Test +{ +protected: + KHashTest () {} + + virtual ~KHashTest () + { + // You can do clean-up work that doesn't throw exceptions here. + } + + // If the constructor and destructor are not enough for setting up + // and cleaning up each test, you can define the following methods: + + virtual void + SetUp () + { + khash = kh_init (int); + } + + virtual void + TearDown () + { + kh_destroy (int, khash); + } + khash_t (int) * khash; +}; + +TEST_F (KHashTest, KhashIntSize) +{ + int ret; + int k; + int size = kh_size (khash); + + EXPECT_EQ (size, 0); + k = kh_put (int, khash, 10, &ret); + if (ret == 1) + { + kh_val (khash, k) = 10; + } + size = kh_size (khash); + EXPECT_EQ (size, 1); +} + +TEST_F (KHashTest, KhashIntPut) +{ + int ret; + int k; + k = kh_put (int, khash, 10, &ret); + if (ret == 1) + { + kh_val (khash, k) = 10; + } + int size = kh_size (khash); + EXPECT_EQ (size, 1); + k = kh_put (int, khash, 20, &ret); + if (ret == 1) + { + kh_val (khash, k) = 20; + } + size = kh_size (khash); + EXPECT_EQ (size, 2); +} + +TEST_F (KHashTest, KhashCheckValue) +{ + int ret; + int k; + k = kh_put (int, khash, 10, &ret); + if (ret == 1) + { + kh_val (khash, k) = 100; + } + k = kh_put (int, khash, 20, &ret); + if (ret == 1) + { + kh_val (khash, k) = 200; + } + + k = kh_put (int, khash, 10, &ret); + int val = -1; + if (!ret) + val = kh_val (khash, k); + EXPECT_EQ (val, 100); + + k = kh_put (int, khash, 20, &ret); + val = -1; + if (!ret) + val = kh_val (khash, k); + EXPECT_EQ (val, 200); +} + +// Check that there are no collisions in case of same key hash +typedef struct +{ + int x; +} Key; +#define hash_key(key) 1 // Hash is always 1 to simulate collisions +#define key_hash_eq(a, b) (a->x == b->x) // Function used in case of collisions +KHASH_INIT (test_map, const Key *, unsigned, 1, hash_key, key_hash_eq); + +TEST_F (KHashTest, Collisions) +{ + int ret; + khiter_t k; + + kh_test_map_t *map = kh_init (test_map); + Key key1 = { .x = 10 }; + Key key2 = { .x = 11 }; + + k = kh_put_test_map (map, &key1, &ret); + EXPECT_EQ (ret, 1); + kh_val (map, k) = 15; + + k = kh_put_test_map (map, &key2, &ret); + EXPECT_EQ (ret, 1); + kh_val (map, k) = 27; + + k = kh_get_test_map (map, &key1); + ASSERT_NE (k, kh_end (map)); + unsigned val = kh_val (map, k); + EXPECT_EQ (val, 15u); + + k = kh_get_test_map (map, &key2); + ASSERT_NE (k, kh_end (map)); + val = kh_val (map, k); + EXPECT_EQ (val, 27u); + + kh_destroy_test_map (map); +} diff --git a/lib/src/test/test_name.cc b/lib/src/test/test_name.cc index 207725adb..35e636b63 100644 --- a/lib/src/test/test_name.cc +++ b/lib/src/test/test_name.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Cisco and/or its affiliates. + * Copyright (c) 2021-2022 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -58,32 +58,24 @@ protected: // The hash should be equal, with and without considering the suffix uint32_t hash_a, hash_b; - rc = hicn_name_hash (&name_a, &hash_a, 1); - EXPECT_EQ (rc, 0); - rc = hicn_name_hash (&name_b, &hash_b, 1); - EXPECT_EQ (rc, 0); + hash_a = hicn_name_get_hash (&name_a); + hash_b = hicn_name_get_hash (&name_b); EXPECT_EQ (hash_a, hash_b); - rc = hicn_name_hash (&name_a, &hash_a, 0); - EXPECT_EQ (rc, 0); - rc = hicn_name_hash (&name_b, &hash_b, 0); - EXPECT_EQ (rc, 0); + hash_a = hicn_name_get_prefix_hash (&name_a); + hash_b = hicn_name_get_prefix_hash (&name_b); EXPECT_EQ (hash_a, hash_b); // Now let's change the suffix - rc = hicn_name_set_seq_number (&name_a, 97531); + rc = hicn_name_set_suffix (&name_a, 97531); // They should result equal if we do not consider the suffix - rc = hicn_name_hash (&name_a, &hash_a, 0); - EXPECT_EQ (rc, 0); - rc = hicn_name_hash (&name_b, &hash_b, 0); - EXPECT_EQ (rc, 0); + hash_a = hicn_name_get_prefix_hash (&name_a); + hash_b = hicn_name_get_prefix_hash (&name_b); EXPECT_EQ (hash_a, hash_b); // And different if we consider it - rc = hicn_name_hash (&name_a, &hash_a, 1); - EXPECT_EQ (rc, 0); - rc = hicn_name_hash (&name_b, &hash_b, 1); - EXPECT_EQ (rc, 0); + hash_a = hicn_name_get_hash (&name_a); + hash_b = hicn_name_get_hash (&name_b); EXPECT_NE (hash_a, hash_b); } @@ -120,7 +112,7 @@ protected: EXPECT_EQ (rc, 0); // Now let's change the suffix - rc = hicn_name_set_seq_number (&name_a, 97531); + rc = hicn_name_set_suffix (&name_a, 97531); // They should result equal if we do not consider the suffix rc = hicn_name_compare (&name_a, &name_b, 0); EXPECT_EQ (rc, 0); @@ -130,13 +122,13 @@ protected: } void - nameFromIpPrefixTest (const ip_prefix_t &ip_prefix) + nameFromIpPrefixTest (const hicn_ip_prefix_t &hicn_ip_prefix) { uint32_t suffix = 54321; hicn_name_t name; - int rc = hicn_name_create_from_ip_prefix (&ip_prefix, suffix, &name); + int rc = hicn_name_create_from_ip_prefix (&hicn_ip_prefix, suffix, &name); EXPECT_EQ (rc, HICN_LIB_ERROR_NONE); - rc = memcmp (ip_prefix.address.v6.as_u8, name.prefix.v6.as_u8, + rc = memcmp (hicn_ip_prefix.address.v6.as_u8, name.prefix.v6.as_u8, sizeof (name.prefix.v6)); EXPECT_EQ (rc, 0); EXPECT_EQ (suffix, name.suffix); @@ -154,16 +146,16 @@ protected: int family; rc = hicn_name_get_family (&name, &family); - ip_prefix_t ip_prefix; - rc = hicn_name_to_ip_prefix (&name, &ip_prefix); + hicn_ip_prefix_t hicn_ip_prefix; + rc = hicn_name_to_hicn_ip_prefix (&name, &hicn_ip_prefix); EXPECT_EQ (rc, HICN_LIB_ERROR_NONE); - EXPECT_EQ (ip_prefix.family, family); - rc = ip_address_cmp (&ip_prefix.address, &name.prefix, AF_INET6); + EXPECT_EQ (hicn_ip_prefix.family, family); + rc = hicn_ip_address_cmp (&hicn_ip_prefix.address, &name.prefix); EXPECT_EQ (rc, 0); } hicn_name_t name_, name4_, name6_; - ip_address_t ipv6_prefix_bytes, ipv4_prefix_bytes; + hicn_ip_address_t ipv6_prefix_bytes, ipv4_prefix_bytes; }; /** @@ -180,7 +172,7 @@ TEST_F (NameTest, NameInitialization) EXPECT_EQ (rc, HICN_LIB_ERROR_NONE); // Check name is correctly created - rc = ip_address_cmp (&name6.prefix, &ipv6_prefix_bytes, AF_INET6); + rc = hicn_ip_address_cmp (&name6.prefix, &ipv6_prefix_bytes); EXPECT_EQ (rc, 0); EXPECT_EQ (name6.suffix, suffix); @@ -190,7 +182,7 @@ TEST_F (NameTest, NameInitialization) EXPECT_EQ (rc, HICN_LIB_ERROR_NONE); // Check name is correctly created - rc = ip_address_cmp (&name4.prefix, &ipv4_prefix_bytes, AF_INET); + rc = hicn_ip_address_cmp (&name4.prefix, &ipv4_prefix_bytes); EXPECT_EQ (name4.prefix.pad[0], 0UL); EXPECT_EQ (name4.prefix.pad[1], 0UL); EXPECT_EQ (name4.prefix.pad[2], 0UL); @@ -202,7 +194,7 @@ TEST_F (NameTest, NameInitialization) EXPECT_EQ (rc, HICN_LIB_ERROR_NONE); // Check name is correctly created - rc = ip_address_cmp (&name6.prefix, &ipv4_prefix_bytes, AF_INET); + rc = hicn_ip_address_cmp (&name6.prefix, &ipv4_prefix_bytes); EXPECT_EQ (name6.prefix.pad[0], 0UL); EXPECT_EQ (name6.prefix.pad[1], 0UL); EXPECT_EQ (name6.prefix.pad[2], 0UL); @@ -215,22 +207,26 @@ TEST_F (NameTest, NameInitialization) */ TEST_F (NameTest, NameFromIpPrefix6) { - ip_prefix_t ip_prefix = { .family = AF_INET6, .address = {}, .len = 64 }; + hicn_ip_prefix_t hicn_ip_prefix = { .family = AF_INET6, + .address = {}, + .len = 64 }; - ip_prefix.address.v6.as_u64[0] = ipv6_prefix_bytes.v6.as_u64[0]; - ip_prefix.address.v6.as_u64[1] = ipv6_prefix_bytes.v6.as_u64[1]; + hicn_ip_prefix.address.v6.as_u64[0] = ipv6_prefix_bytes.v6.as_u64[0]; + hicn_ip_prefix.address.v6.as_u64[1] = ipv6_prefix_bytes.v6.as_u64[1]; - nameFromIpPrefixTest (ip_prefix); + nameFromIpPrefixTest (hicn_ip_prefix); } TEST_F (NameTest, NameFromIpPrefix4) { - ip_prefix_t ip_prefix = { .family = AF_INET, .address = {}, .len = 64 }; - ip_prefix.address.v4.as_u32 = ipv4_prefix_bytes.v4.as_u32; - ip_prefix.address.pad[0] = 0; - ip_prefix.address.pad[1] = 0; - ip_prefix.address.pad[2] = 0; - nameFromIpPrefixTest (ip_prefix); + hicn_ip_prefix_t hicn_ip_prefix = { .family = AF_INET, + .address = {}, + .len = 64 }; + hicn_ip_prefix.address.v4.as_u32 = ipv4_prefix_bytes.v4.as_u32; + hicn_ip_prefix.address.pad[0] = 0; + hicn_ip_prefix.address.pad[1] = 0; + hicn_ip_prefix.address.pad[2] = 0; + nameFromIpPrefixTest (hicn_ip_prefix); } TEST_F (NameTest, NameCompare6) { nameCompareTest (ipv6_prefix); } @@ -257,8 +253,8 @@ TEST_F (NameTest, NameCopy4) { nameCopyTest (ipv4_prefix); } TEST_F (NameTest, NameCopyToDestination) { - ip4_address_t dst4; - ip6_address_t dst6; + ipv4_address_t dst4; + ipv6_address_t dst6; // Copy names to destination int rc = hicn_name_copy_prefix_to_destination (dst4.as_u8, &name4_); @@ -282,7 +278,7 @@ TEST_F (NameTest, SetGetSuffix) EXPECT_EQ (suffix, suffix_ret); // Set new suffix - rc = hicn_name_set_seq_number (&name6_, suffix2); + rc = hicn_name_set_suffix (&name6_, suffix2); EXPECT_EQ (rc, HICN_LIB_ERROR_NONE); // Check suffix was set diff --git a/lib/src/test/test_new_header.cc b/lib/src/test/test_new_header.cc index 33c9e13c9..c936b6910 100644 --- a/lib/src/test/test_new_header.cc +++ b/lib/src/test/test_new_header.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Cisco and/or its affiliates. + * Copyright (c) 2021-2022 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -20,10 +20,10 @@ extern "C" #include <hicn/name.h> #include <hicn/common.h> #include <hicn/error.h> -#include <hicn/protocol/new.h> -#include <hicn/protocol/ah.h> -#include <hicn/header.h> -#include <hicn/compat.h> +#include <hicn/packet.h> + +#include "../protocol/ah.h" +#include "../protocol/new.h" } class NewHeaderTest : public ::testing::Test @@ -33,10 +33,11 @@ protected: const char *ipv4_prefix = "12.13.14.15"; const uint32_t suffix = 12345; - NewHeaderTest (size_t hdr_size, hicn_format_t format) - : buffer_ (new uint8_t[hdr_size]), header_ ((hicn_header_t *) (buffer_)), + NewHeaderTest (hicn_packet_format_t format) + : buffer_ (new uint8_t[NEW_HDRLEN]), format_ (format), name_{}, name4_{}, name6_{} { + int rc = inet_pton (AF_INET6, ipv6_prefix, &ipv6_prefix_bytes.v6); EXPECT_EQ (rc, 1); @@ -49,42 +50,46 @@ protected: EXPECT_EQ (rc, HICN_LIB_ERROR_NONE); } - NewHeaderTest () : NewHeaderTest (NEW_HDRLEN, HF_NEW) {} + NewHeaderTest () : NewHeaderTest (HICN_PACKET_FORMAT_NEW) {} virtual ~NewHeaderTest () { delete[] buffer_; } void - checkCommon (const _new_header_t *new_hdr) + checkCommon () { // Initialize header - int rc = hicn_packet_init_header (format_, header_); + hicn_packet_set_format (&pkbuf_, format_); + // pkbuf_set_type (&pkbuf_, HICN_PACKET_TYPE_UNDEFINED); + int rc = hicn_packet_init_header (&pkbuf_, 0); EXPECT_EQ (rc, HICN_LIB_ERROR_NONE); + auto new_hdr = (_new_header_t *) buffer_; + // Check fields EXPECT_EQ (new_hdr->prefix.v6.as_u64[0], 0UL); EXPECT_EQ (new_hdr->prefix.v6.as_u64[1], 0UL); EXPECT_EQ (new_hdr->suffix, 0UL); EXPECT_EQ (new_hdr->lifetime, 0UL); EXPECT_EQ (new_hdr->path_label, 0UL); - EXPECT_EQ (new_hdr->payload_length, 0UL); + EXPECT_EQ (new_hdr->payload_len, 0UL); EXPECT_EQ (_get_new_header_version (new_hdr), 0x9); + EXPECT_EQ (new_hdr->flags, 0); } virtual void SetUp () override { - auto new_hdr = &header_->protocol.newhdr; - checkCommon (new_hdr); - EXPECT_EQ (new_hdr->flags, 0); + checkCommon (); } uint8_t *buffer_; - hicn_header_t *header_; - hicn_format_t format_; + hicn_packet_buffer_t pkbuf_; + hicn_packet_format_t format_; hicn_name_t name_, name4_, name6_; - ip_address_t ipv6_prefix_bytes, ipv4_prefix_bytes; + hicn_ip_address_t ipv6_prefix_bytes, ipv4_prefix_bytes; }; +#if 0 class NewHeaderAHTest : public NewHeaderTest { protected: @@ -229,7 +234,7 @@ TEST_F (NewHeaderTest, SetGetName) TEST_F (NewHeaderTest, SetGetLocator) { // This function does nothing but it is set for compatibility - ip_address_t locator; + hicn_ip_address_t locator; memset (&locator, 0, sizeof (locator)); locator.v6.as_u8[15] = 1; int rc = hicn_packet_set_interest (format_, header_); @@ -338,3 +343,4 @@ TEST_F (NewHeaderTest, SetGetPayloadType) EXPECT_EQ (payload_type, payload_type_ret); } +#endif diff --git a/lib/src/test/test_pool.cc b/lib/src/test/test_pool.cc new file mode 100644 index 000000000..cbb5ce068 --- /dev/null +++ b/lib/src/test/test_pool.cc @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2021 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <gtest/gtest.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <unistd.h> +#include <netinet/in.h> + +extern "C" +{ +#define WITH_TESTS +#include <hicn/util/pool.h> +} + +/* + * TODO + * - test max_size + */ + +#define DEFAULT_SIZE 10 + +class PoolTest : public ::testing::Test +{ +protected: + PoolTest () {} + virtual ~PoolTest () {} + + int *pool; +}; + +TEST_F (PoolTest, PoolAllocation) +{ + int rc; + + pool_init (pool, DEFAULT_SIZE, 0); + + size_t pool_size = next_pow2 (DEFAULT_SIZE); + + EXPECT_EQ (pool_get_alloc_size (pool), pool_size); + + /* Check that free indices and bitmaps are correctly initialize */ + off_t *fi = pool_get_free_indices (pool); + EXPECT_EQ (vector_len (fi), pool_size); + EXPECT_EQ (fi[0], (long) (pool_size - 1)); + EXPECT_EQ (fi[pool_size - 1], 0); + + /* The allocated size of the underlying vector should be the next power of + * two + */ + EXPECT_EQ (vector_get_alloc_size (fi), pool_size); + + bitmap_t *fb = pool_get_free_bitmap (pool); + EXPECT_TRUE (bitmap_is_set (fb, 0)); + EXPECT_TRUE (bitmap_is_set (fb, pool_size - 2)); + EXPECT_TRUE (bitmap_is_set (fb, pool_size - 1)); + EXPECT_TRUE (bitmap_is_unset (fb, pool_size)); + + /* Getting elements from the pool should correctly update the free indices + * and bitmap */ + int *elt; + + rc = pool_get (pool, elt); + EXPECT_GE (rc, 0); + EXPECT_EQ (vector_len (fi), pool_size - 1); + EXPECT_TRUE (bitmap_is_unset (fb, 0)); + + rc = pool_get (pool, elt); + EXPECT_GE (rc, 0); + EXPECT_EQ (vector_len (fi), pool_size - 2); + EXPECT_TRUE (bitmap_is_unset (fb, 1)); + + for (unsigned i = 0; i < pool_size - 4; i++) + { + rc = pool_get (pool, elt); + EXPECT_GE (rc, 0); + } + + rc = pool_get (pool, elt); + EXPECT_GE (rc, 0); + EXPECT_EQ (vector_len (fi), 1UL); + EXPECT_TRUE (bitmap_is_unset (fb, pool_size - 2)); + + rc = pool_get (pool, elt); + EXPECT_GE (rc, 0); + EXPECT_EQ (vector_len (fi), 0UL); + EXPECT_TRUE (bitmap_is_unset (fb, pool_size - 1)); + + /* + * Getting elements within the allocated range should not have triggered a + * resize + */ + EXPECT_EQ (pool_len (pool), pool_size); + + /* + * Getting elements once the allocated range has been exceeded should + * trigger a resize + */ + rc = pool_get (pool, elt); + EXPECT_GE (rc, 0); + + EXPECT_EQ (pool_get_alloc_size (pool), pool_size * 2); + + EXPECT_EQ (pool_len (pool), pool_size + 1); + + /* + * Doubling the size, we should have again pool_size elements free, minus 1 + */ + EXPECT_EQ (pool_get_free_indices_size (pool), pool_size - 1); + + /* + * NOTE: this is wrong as there has been a realloc and the old fi + * pointer is now invalid + */ + // EXPECT_EQ(vector_len(fi), pool_size - 1); + + /* And the bitmap should also be correctly modified */ + fb = pool_get_free_bitmap (pool); + EXPECT_TRUE (bitmap_is_unset (fb, pool_size)); + + /* Check that surrounding values are also correct */ + EXPECT_TRUE (bitmap_is_unset (fb, pool_size - 1)); + EXPECT_TRUE (bitmap_is_set (fb, pool_size + 1)); + + /* Setting elements after should through */ + + /* Check that free indices and bitmaps are correctly updated */ + + pool_free (pool); +} + +TEST_F (PoolTest, PoolPut) +{ + pool_init (pool, DEFAULT_SIZE, 0); + + int *elt; + pool_get (pool, elt); + *elt = 10; + pool_put (pool, elt); + + pool_free (pool); +} + +TEST_F (PoolTest, PoolGetForceBitmapRealloc) +{ + const int N = 64; + int *elts[N]; + int *elt = NULL; + pool_init (pool, N, 0); + + for (int i = 0; i < N; i++) + pool_get (pool, elts[i]); + pool_get (pool, elt); + + pool_free (pool); +} + +TEST_F (PoolTest, PoolGetAfterReleasing) +{ + int *elt1 = NULL, *elt2 = NULL, *tmp = NULL; + pool_init (pool, DEFAULT_SIZE, 0); + + // If two elements are requested... + off_t id1 = pool_get (pool, elt1); + pool_get (pool, tmp); + + // ...and the first one is released... + pool_put (pool, elt1); + + // ...requesting a new one should return + // the first one (that was freed) + off_t id2 = pool_get (pool, elt2); + EXPECT_EQ (id1, id2); + EXPECT_EQ (elt1, elt2); + + pool_free (pool); +} + +TEST_F (PoolTest, PoolGetMultipleElementsAfterReleasing) +{ + const int N = 2; + int *elts[N]; + pool_init (pool, N, 0); + + for (int i = 0; i < N; i++) + pool_get (pool, elts[i]); + for (int i = 0; i < N; i++) + pool_put (pool, elts[i]); + for (int i = 0; i < N; i++) + pool_get (pool, elts[i]); + + pool_free (pool); +} diff --git a/lib/src/test/test_ring.cc b/lib/src/test/test_ring.cc new file mode 100644 index 000000000..f0b0371e8 --- /dev/null +++ b/lib/src/test/test_ring.cc @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2021 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <gtest/gtest.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <unistd.h> +#include <netinet/in.h> + +extern "C" +{ +#define WITH_TESTS +#include <hicn/util/ring.h> +} + +#define DEFAULT_SIZE 10UL + +class RingTest : public ::testing::Test +{ +protected: + RingTest () { ring_init (ring, DEFAULT_SIZE); } + virtual ~RingTest () { ring_free (ring); } + + int *ring = NULL; +}; + +/* TEST: Ring allocation and initialization */ +TEST_F (RingTest, RingAddOne) +{ + int val = -1; + /* Allocated size should be the next power of two */ + EXPECT_EQ (ring_get_size (ring), 0UL); + ring_add_value (ring, 1); + EXPECT_EQ (ring_get_size (ring), 1UL); + ring_get (ring, 0, &val); + EXPECT_EQ (val, 1); + EXPECT_EQ (ring_get_size (ring), 1UL); + ring_advance (ring, 1); + EXPECT_EQ (ring_get_size (ring), 0UL); +} + +TEST_F (RingTest, RingAddMany) +{ + size_t i = 0; + int val = -1; + size_t count = 0; + + /* Allocated size should be the next power of two */ + EXPECT_EQ (ring_get_size (ring), 0UL); + for (unsigned i = 0; i < DEFAULT_SIZE; i++) + ring_add_value (ring, i); + EXPECT_EQ (ring_get_size (ring), DEFAULT_SIZE); + + count = 0; + ring_enumerate_n (ring, i, &val, 1, { + EXPECT_EQ (val, (int) (i)); + count++; + }); + EXPECT_EQ (count, 1UL); + + count = 0; + ring_enumerate_n (ring, i, &val, DEFAULT_SIZE, { + EXPECT_EQ (val, (int) (i)); + count++; + }); + EXPECT_EQ (count, DEFAULT_SIZE); + + count = 0; + ring_enumerate_n (ring, i, &val, DEFAULT_SIZE + 1, { + EXPECT_EQ (val, (int) (i)); + count++; + }); + EXPECT_EQ (count, DEFAULT_SIZE); + + // Drop one + ring_add_value (ring, DEFAULT_SIZE); + EXPECT_EQ (ring_get_size (ring), DEFAULT_SIZE); + + count = 0; + ring_enumerate_n (ring, i, &val, DEFAULT_SIZE, { + EXPECT_EQ (val, (int) (i + 1)); // all values shoud be shifted + count++; + }); + EXPECT_EQ (count, DEFAULT_SIZE); + + ring_advance (ring, DEFAULT_SIZE); + EXPECT_EQ (ring_get_size (ring), 0UL); +} diff --git a/lib/src/test/test_udp_header.cc b/lib/src/test/test_udp_header.cc index 5d9f4d1eb..2853ee31b 100644 --- a/lib/src/test/test_udp_header.cc +++ b/lib/src/test/test_udp_header.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Cisco and/or its affiliates. + * Copyright (c) 2021-2022 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -20,10 +20,12 @@ extern "C" #include <hicn/name.h> #include <hicn/common.h> #include <hicn/error.h> -#include <hicn/protocol/new.h> -#include <hicn/protocol/ah.h> -#include <hicn/header.h> -#include <hicn/compat.h> +#include <hicn/packet.h> + +#include "../protocol/ah.h" +#include "../protocol/ipv6.h" +#include "../protocol/udp.h" +#include "../protocol/new.h" } class UdpHeaderTest : public ::testing::Test @@ -33,8 +35,8 @@ protected: const char *ipv4_prefix = "12.13.14.15"; const uint32_t suffix = 12345; - UdpHeaderTest (size_t hdr_size, hicn_format_t format) - : buffer_ (new uint8_t[hdr_size]), header_ ((hicn_header_t *) (buffer_)), + UdpHeaderTest (size_t hdr_size, hicn_packet_format_t format) + : buffer_ (new uint8_t[hdr_size]), hdr_size_ (hdr_size), format_ (format), name_{}, name4_{}, name6_{} { int rc = inet_pton (AF_INET6, ipv6_prefix, &ipv6_prefix_bytes.v6); @@ -50,19 +52,26 @@ protected: } UdpHeaderTest () - : UdpHeaderTest (NEW_HDRLEN + UDP_HDRLEN + IPV6_HDRLEN, HF_INET6_UDP) + : UdpHeaderTest (NEW_HDRLEN + UDP_HDRLEN + IPV6_HDRLEN, + HICN_PACKET_FORMAT_IPV6_UDP) { } virtual ~UdpHeaderTest () { delete[] buffer_; } + // checked everytime we build the packet... void - checkCommon (const _ipv6_header_t *ip6_hdr) + checkCommon () { - // Initialize header - int rc = hicn_packet_init_header (format_, header_); + /* Initialize packet buffer headers */ + hicn_packet_set_format (&pkbuf_, format_); + hicn_packet_set_type (&pkbuf_, HICN_PACKET_TYPE_INTEREST); + hicn_packet_set_buffer (&pkbuf_, buffer_, hdr_size_, 0); + int rc = hicn_packet_init_header (&pkbuf_, 0); EXPECT_EQ (rc, HICN_LIB_ERROR_NONE); + auto ip6_hdr = (_ipv6_header_t *) buffer_; + // Check fields EXPECT_EQ (ip6_hdr->saddr.as_u64[0], 0UL); EXPECT_EQ (ip6_hdr->saddr.as_u64[1], 0UL); @@ -82,22 +91,22 @@ protected: EXPECT_EQ (new_hdr->suffix, 0UL); EXPECT_EQ (new_hdr->lifetime, 0UL); EXPECT_EQ (new_hdr->path_label, 0UL); - EXPECT_EQ (new_hdr->payload_length, 0UL); + EXPECT_EQ (new_hdr->payload_len, 0UL); EXPECT_EQ (_get_new_header_version (new_hdr), 0x9); } virtual void SetUp () override { - auto ip6_hdr = &header_->protocol.ipv6; - checkCommon (ip6_hdr); + checkCommon (); } uint8_t *buffer_; - hicn_header_t *header_; - hicn_format_t format_; + size_t hdr_size_; + hicn_packet_buffer_t pkbuf_; + hicn_packet_format_t format_; hicn_name_t name_, name4_, name6_; - ip_address_t ipv6_prefix_bytes, ipv4_prefix_bytes; + hicn_ip_address_t ipv6_prefix_bytes, ipv4_prefix_bytes; }; class UdpHeaderAHTest : public UdpHeaderTest @@ -105,7 +114,7 @@ class UdpHeaderAHTest : public UdpHeaderTest protected: UdpHeaderAHTest () : UdpHeaderTest (AH_HDRLEN + NEW_HDRLEN + UDP_HDRLEN + IPV6_HDRLEN, - HF_INET6_UDP_AH) + HICN_PACKET_FORMAT_IPV6_UDP_AH) { } }; @@ -115,26 +124,21 @@ protected: */ TEST_F (UdpHeaderTest, GetFormat) { - // Get format from existing packet - hicn_format_t format; - int rc = hicn_packet_get_format (header_, &format); - EXPECT_EQ (rc, HICN_LIB_ERROR_NONE); - - // Check it corresponds to the new header format - EXPECT_EQ (format, HF_INET6_UDP); + hicn_packet_format_t format = hicn_packet_get_format (&pkbuf_); + EXPECT_EQ (format.as_u32, HICN_PACKET_FORMAT_IPV6_UDP.as_u32); } TEST_F (UdpHeaderAHTest, GetFormat) { // Get format from existing packet - hicn_format_t format; - int rc = hicn_packet_get_format (header_, &format); - EXPECT_EQ (rc, HICN_LIB_ERROR_NONE); + hicn_packet_format_t format = hicn_packet_get_format (&pkbuf_); // Check it corresponds to the new header format - EXPECT_EQ (format, HF_INET6_UDP_AH); + EXPECT_EQ (format.as_u32, HICN_PACKET_FORMAT_IPV6_UDP_AH.as_u32); } +#if 0 + // /** // * @brief Checksum functions are not required, but we keep them for // * compatibility. @@ -244,7 +248,7 @@ TEST_F (UdpHeaderTest, SetGetName) TEST_F (UdpHeaderTest, SetGetLocator) { // This function does nothing but it is set for compatibility - ip_address_t locator; + hicn_ip_address_t locator; memset (&locator, 0, sizeof (locator)); locator.v6.as_u8[15] = 1; int rc = hicn_packet_set_interest (format_, header_); @@ -353,3 +357,4 @@ TEST_F (UdpHeaderTest, SetGetPayloadType) EXPECT_EQ (payload_type, payload_type_ret); } +#endif diff --git a/lib/src/test/test_vector.cc b/lib/src/test/test_vector.cc new file mode 100644 index 000000000..88b0bb7cf --- /dev/null +++ b/lib/src/test/test_vector.cc @@ -0,0 +1,254 @@ +/* + * Copyright (c) 2021 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <gtest/gtest.h> + +extern "C" +{ +#include <hicn/util/vector.h> +} + +static constexpr size_t DEFAULT_SIZE = 10; +static constexpr size_t N_ELEMENTS = 5; + +class VectorTest : public ::testing::Test +{ +protected: + VectorTest () { vector_init (vector, DEFAULT_SIZE, 0); } + virtual ~VectorTest () { vector_free (vector); } + + int *vector = NULL; +}; + +TEST_F (VectorTest, VectorAllocateAndResize) +{ + // Allocated size should be the next power of two + EXPECT_EQ (vector_get_alloc_size (vector), 16UL); + + // Setting elements within the allocated size should not trigger a resize + vector_ensure_pos (vector, 15); + EXPECT_EQ (vector_get_alloc_size (vector), 16UL); + + // Setting elements after should through + vector_ensure_pos (vector, 16); + EXPECT_EQ (vector_get_alloc_size (vector), 32UL); +} + +TEST_F (VectorTest, VectorSize) +{ + EXPECT_EQ (vector_len (vector), size_t (0)); + + // Check size after pushing one element + vector_push (vector, 1); + EXPECT_EQ (vector_len (vector), size_t (1)); + + // Check size after pushing additional elements + vector_push (vector, 2); + vector_push (vector, 3); + EXPECT_EQ (vector_len (vector), size_t (3)); + + // Try adding multiple elements + const int n_elements_to_add = 5; + size_t expected_new_len = vector_len (vector) + n_elements_to_add; + for (int i = 0; i < n_elements_to_add; i++) + vector_push (vector, i); + EXPECT_EQ (vector_len (vector), expected_new_len); +} + +TEST_F (VectorTest, VectorCheckValue) +{ + // Add elements + vector_push (vector, 109); + vector_push (vector, 200); + EXPECT_EQ (vector_at (vector, 0), 109); + EXPECT_EQ (vector_at (vector, 1), 200); + + // Update element + vector_set (vector, 1, 400); + EXPECT_EQ (vector_at (vector, 1), 400); + + // Add at last available position + size_t prev_size = vector_len (vector); + vector_set (vector, vector_len (vector) - 1, 123); + EXPECT_EQ (vector_at (vector, vector_len (vector) - 1), 123); + EXPECT_EQ (prev_size, vector_len (vector)) << "Size should not have changed"; +} + +TEST_F (VectorTest, RemoveElement) +{ + // Populate vector + for (size_t i = 0; i < N_ELEMENTS; i++) + vector_push (vector, i); + EXPECT_EQ (vector_len (vector), N_ELEMENTS); + for (size_t i = 0; i < vector_len (vector); i++) + EXPECT_EQ (vector_at (vector, i), (int) i); + + // Remove element + int value_to_remove = 3; + int num_removed = vector_remove_unordered (vector, value_to_remove); + + EXPECT_EQ (vector_len (vector), N_ELEMENTS - 1); + EXPECT_EQ (num_removed, 1); + for (size_t i = 0; i < vector_len (vector); i++) + EXPECT_NE (vector_at (vector, i), value_to_remove); +} + +TEST_F (VectorTest, RemoveNonExistingElement) +{ + // Push some initial values + vector_push (vector, 1); + vector_push (vector, 2); + vector_push (vector, 3); + EXPECT_EQ (vector_len (vector), size_t (3)); + + // Remove non-existing element + int num_removed = vector_remove_unordered (vector, 5); + EXPECT_EQ (num_removed, 0); + size_t prev_size = vector_len (vector); + EXPECT_EQ (prev_size, vector_len (vector)) << "Size should not have changed"; +} + +TEST_F (VectorTest, RemoveDuplicatedElement) +{ + // Populate vector + for (size_t i = 0; i < N_ELEMENTS; i++) + vector_push (vector, i); + EXPECT_EQ (vector_len (vector), N_ELEMENTS); + for (size_t i = 0; i < vector_len (vector); i++) + EXPECT_EQ (vector_at (vector, i), (int) i); + vector_set (vector, 0, 3); // Duplicate element + + // Remove (duplicated) elements + int value_to_remove = 3; + int num_removed = vector_remove_unordered (vector, value_to_remove); + + EXPECT_EQ (vector_len (vector), N_ELEMENTS - 2); + EXPECT_EQ (num_removed, 2); + for (size_t i = 0; i < vector_len (vector); i++) + EXPECT_NE (vector_at (vector, i), value_to_remove); +} + +TEST_F (VectorTest, Iterate) +{ + for (size_t i = 0; i < N_ELEMENTS; i++) + vector_push (vector, i); + + int count = 0; + int *elem; + vector_foreach (vector, elem, { EXPECT_EQ (*elem, count++); }); +} + +TEST_F (VectorTest, MultipleResize) +{ + // Use small vector (size=1) to force multiple realloc operations + int *small_vector; + vector_init (small_vector, 1, 0); + + for (size_t i = 0; i < N_ELEMENTS; i++) + vector_push (small_vector, i); + + for (size_t i = 0; i < N_ELEMENTS; i++) + EXPECT_EQ (vector_at (small_vector, i), (int) i); + + EXPECT_EQ (vector_len (small_vector), 5UL); + EXPECT_EQ (vector_get_alloc_size (small_vector), 8UL); + + vector_free (small_vector); +} + +TEST_F (VectorTest, MaxSize) +{ + const int max_size = 4; + + // Fill the vector until max size is reached + int *small_vector; + vector_init (small_vector, 2, max_size); + for (int i = 0; i < max_size; i++) + vector_push (small_vector, i); + + // Try expanding or appending elements should fail + int rc = vector_ensure_pos (small_vector, max_size); + EXPECT_EQ (rc, -1); + rc = vector_push (small_vector, 123); + EXPECT_EQ (rc, -1); + + vector_free (small_vector); +} + +TEST_F (VectorTest, Contains) +{ + // No elements + EXPECT_EQ (vector_contains (vector, 1), false); + + // Push one element + vector_push (vector, 1); + EXPECT_EQ (vector_contains (vector, 1), true); + + // Update element + vector_set (vector, 0, 2); + EXPECT_EQ (vector_contains (vector, 1), false); + EXPECT_EQ (vector_contains (vector, 2), true); +} + +TEST_F (VectorTest, Remove) +{ + // Remove element at invalid position + int rc = vector_remove_at (vector, 2); + EXPECT_EQ (rc, -1); // Failure + + // Push two elements and remove the second one + vector_push (vector, 1); + vector_push (vector, 2); + rc = vector_remove_at (vector, 1); + EXPECT_EQ (rc, 0); // Success + EXPECT_EQ (vector_len (vector), size_t (1)); + + // Push another element: it should replace the previous one + vector_push (vector, 3); + EXPECT_EQ (vector_len (vector), size_t (2)); + EXPECT_EQ (vector_at (vector, 1), 3); +} + +TEST_F (VectorTest, RemoveInTheMiddle) +{ + for (size_t i = 0; i < N_ELEMENTS; i++) + vector_push (vector, i); + + // Remove element in central position + int rc = vector_remove_at (vector, 2); + EXPECT_EQ (rc, 0); // Success + EXPECT_EQ (vector_contains (vector, 2), false); + EXPECT_EQ (vector_len (vector), N_ELEMENTS - 1); + + // Check if elements have been shifted (preserving the order) + int expected[] = { 0, 1, 3, 4 }; + for (size_t i = 0; i < vector_len (vector); i++) + EXPECT_EQ (vector_at (vector, i), expected[i]); +} + +TEST_F (VectorTest, Reset) +{ + vector_push (vector, 1); + vector_push (vector, 2); + EXPECT_EQ (vector_len (vector), size_t (2)); + + vector_reset (vector); + EXPECT_EQ (vector_len (vector), size_t (0)); + + vector_push (vector, 5); + EXPECT_EQ (vector_len (vector), size_t (1)); + EXPECT_EQ (vector_contains (vector, 5), true); + EXPECT_EQ (vector_at (vector, 0), 5); +}
\ No newline at end of file |