aboutsummaryrefslogtreecommitdiffstats
path: root/lib/src/test/test_slab.cc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/src/test/test_slab.cc')
-rw-r--r--lib/src/test/test_slab.cc148
1 files changed, 148 insertions, 0 deletions
diff --git a/lib/src/test/test_slab.cc b/lib/src/test/test_slab.cc
new file mode 100644
index 000000000..15deff3c1
--- /dev/null
+++ b/lib/src/test/test_slab.cc
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 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:
+ *
+ * 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/slab.h>
+}
+
+class SlabTest : public ::testing::Test
+{
+protected:
+ SlabTest () {}
+ virtual ~SlabTest () { slab_free (slab); }
+
+ slab_t *slab;
+};
+
+typedef struct
+{
+ int index;
+ int val;
+} element_t;
+
+TEST_F (SlabTest, SlabCreateAndGetSingleChunk)
+{
+ slab = slab_create (element_t, 16);
+ ASSERT_NE (slab, nullptr);
+
+ element_t *e = slab_get (element_t, slab);
+ ASSERT_NE (e, nullptr);
+ slab_put (slab, e);
+}
+
+TEST_F (SlabTest, SlabGetChunks)
+{
+ slab = slab_create (element_t, 2);
+
+ // Force creation of multiple blocks (since initial size is only 2)
+ for (int i = 0; i < 100; i++)
+ {
+ element_t *e = slab_get (element_t, slab);
+ EXPECT_NE (e, nullptr);
+ }
+}
+
+TEST_F (SlabTest, SlabGetAndPutChunksNoResize)
+{
+ constexpr int NUM_ELEMENTS = 64;
+ element_t *elements[NUM_ELEMENTS];
+ for (int i = 0; i < NUM_ELEMENTS; i++)
+ elements[i] = NULL;
+
+ // Initial size=NUM_ELEMENTS, only one block will be created
+ slab = slab_create (element_t, NUM_ELEMENTS);
+
+ for (int i = 0; i < NUM_ELEMENTS; i++)
+ {
+ elements[i] = slab_get (element_t, slab);
+ EXPECT_NE (elements[i], nullptr);
+ }
+
+ // Release all chunks
+ for (int i = 0; i < NUM_ELEMENTS; i++)
+ slab_put (slab, elements[i]);
+}
+
+TEST_F (SlabTest, SlabGetAndPutChunks)
+{
+ constexpr int NUM_ELEMENTS = 100;
+ element_t *elements[NUM_ELEMENTS];
+ for (int i = 0; i < NUM_ELEMENTS; i++)
+ elements[i] = NULL;
+
+ // Initial size=2 while NUM_ELEMENTS=100, to force creation of multiple
+ // blocks
+ slab = slab_create (sizeof (element_t), 2);
+
+ for (int i = 0; i < NUM_ELEMENTS; i++)
+ {
+ elements[i] = slab_get (element_t, slab);
+ EXPECT_NE (elements[i], nullptr);
+ }
+
+ // Release all chunks
+ for (int i = 0; i < NUM_ELEMENTS; i++)
+ slab_put (slab, elements[i]);
+}
+
+TEST_F (SlabTest, SlabGetAndPutSomeChunks)
+{
+ slab = slab_create (element_t, 2);
+
+ constexpr int NUM_ELEMENTS = 100;
+ element_t *elements[NUM_ELEMENTS];
+ for (int i = 0; i < NUM_ELEMENTS; i++)
+ elements[i] = NULL;
+
+ // Get chunks...
+ for (int i = 0; i < NUM_ELEMENTS; i++)
+ {
+ elements[i] = slab_get (element_t, slab);
+ EXPECT_NE (elements[i], nullptr);
+
+ // ...and return only some of them
+ if (i % 5 == 0)
+ slab_put (slab, elements[i]);
+ }
+}
+
+TEST_F (SlabTest, SlabGetSameChunkTwice)
+{
+ slab = slab_create (element_t, 1);
+
+ // Get chunk and update it before returning it
+ element_t *e = slab_get (element_t, slab);
+ ASSERT_NE (e, nullptr);
+ element_t *prev = e;
+ e->index = 2;
+ e->val = 3;
+ slab_put (slab, e);
+
+ // Get a chunk again: it should return the previous one
+ // without wiping its memory
+ e = slab_get (element_t, slab);
+ ASSERT_NE (e, nullptr);
+ EXPECT_EQ (e, prev);
+ EXPECT_EQ (e->index, 2);
+ EXPECT_EQ (e->val, 3);
+
+ // Try to get an additional chunk: it should return a new chunk
+ // (different from previous one)
+ e = slab_get (element_t, slab);
+ EXPECT_NE (e, prev);
+} \ No newline at end of file