Commit: 8a7d1f3b3cadfbd3a62fee66480d568d5e024d2e
Author: Campbell Barton
Date:   Mon May 30 15:27:10 2016 +1000
Branches: master
https://developer.blender.org/rB8a7d1f3b3cadfbd3a62fee66480d568d5e024d2e

BLI_array_store tests

Ensure the data is valid once expanded,
and that de-duplication is working as expected.

===================================================================

A       tests/gtests/blenlib/BLI_array_store_test.cc
M       tests/gtests/blenlib/CMakeLists.txt

===================================================================

diff --git a/tests/gtests/blenlib/BLI_array_store_test.cc 
b/tests/gtests/blenlib/BLI_array_store_test.cc
new file mode 100644
index 0000000..33fb454
--- /dev/null
+++ b/tests/gtests/blenlib/BLI_array_store_test.cc
@@ -0,0 +1,815 @@
+/* Apache License, Version 2.0 */
+
+#include "testing/testing.h"
+
+extern "C" {
+#include "BLI_array_store.h"
+
+#include "MEM_guardedalloc.h"
+#include "BLI_sys_types.h"
+#include "BLI_utildefines.h"
+#include "BLI_listbase.h"
+#include "BLI_array_utils.h"
+#include "BLI_string.h"
+#include "BLI_rand.h"
+#include "BLI_ressource_strings.h"
+}
+
+/* print memory savings */
+// #define DEBUG_PRINT
+
+
+/* -------------------------------------------------------------------- */
+/* Helper functions */
+
+#ifdef DEBUG_PRINT
+static void print_mem_saved(const char *id, const BArrayStore *bs)
+{
+       const double size_real   = BLI_array_store_calc_size_compacted_get(bs);
+       const double size_expand = BLI_array_store_calc_size_expanded_get(bs);
+       const double percent = size_expand ? ((size_real / size_expand) * 
100.0) : -1.0;
+       printf("%s: %.8f%%\n", id, percent);
+}
+#endif
+
+
+/* -------------------------------------------------------------------- */
+/* Test Chunks (building data from list of chunks) */
+
+typedef struct TestChunnk {
+       struct TestChunnk *next, *prev;
+       const void *data;
+       size_t data_len;
+} TestChunnk;
+
+static TestChunnk *testchunk_list_add(ListBase *lb, const void *data, size_t 
data_len)
+{
+       TestChunnk *tc = (TestChunnk *)MEM_mallocN(sizeof(*tc), __func__);
+       tc->data = data;
+       tc->data_len = data_len;
+       BLI_addtail(lb, tc);
+
+       return tc;
+}
+
+#if 0
+static TestChunnk *testchunk_list_add_copydata(ListBase *lb, const void *data, 
size_t data_len)
+{
+       void *data_copy = MEM_mallocN(data_len, __func__);
+       memcpy(data_copy, data, data_len);
+       return testchunk_list_add(lb, data_copy, data_len);
+}
+#endif
+
+static void testchunk_list_free(ListBase *lb)
+{
+       for (TestChunnk *tc = (TestChunnk *)lb->first, *tb_next; tc; tc = 
tb_next) {
+               tb_next = tc->next;
+               MEM_freeN((void *)tc->data);
+               MEM_freeN(tc);
+       }
+       BLI_listbase_clear(lb);
+}
+
+#if 0
+static char *testchunk_as_data(
+        ListBase *lb,
+        size_t *r_data_len)
+{
+       size_t data_len = 0;
+       for (TestChunnk *tc = (TestChunnk *)lb->first; tc; tc = tc->next) {
+               data_len += tc->data_len;
+       }
+       char *data = (char *)MEM_mallocN(data_len, __func__);
+       size_t i = 0;
+       for (TestChunnk *tc = (TestChunnk *)lb->first; tc; tc = tc->next) {
+               memcpy(&data[i], tc->data, tc->data_len);
+               data_len += tc->data_len;
+               i += tc->data_len;
+       }
+       if (r_data_len) {
+               *r_data_len = i;
+       }
+       return data;
+}
+#endif
+
+static char *testchunk_as_data_array(
+        TestChunnk **tc_array, int tc_array_len,
+        size_t *r_data_len)
+{
+       size_t data_len = 0;
+       for (int tc_index = 0; tc_index < tc_array_len; tc_index++) {
+               data_len += tc_array[tc_index]->data_len;
+       }
+       char *data = (char *)MEM_mallocN(data_len, __func__);
+       size_t i = 0;
+       for (int tc_index = 0; tc_index < tc_array_len; tc_index++) {
+               TestChunnk *tc = tc_array[tc_index];
+               memcpy(&data[i], tc->data, tc->data_len);
+               i += tc->data_len;
+       }
+       if (r_data_len) {
+               *r_data_len = i;
+       }
+       return data;
+}
+
+
+/* -------------------------------------------------------------------- */
+/* Test Buffer */
+
+/* API to handle local allocation of data so we can compare it with the data 
in the array_store */
+typedef struct TestBuffer {
+       struct TestBuffer *next, *prev;
+       const void *data;
+       size_t data_len;
+
+       /* for reference */
+       BArrayState *state;
+} TestBuffer;
+
+static TestBuffer *testbuffer_list_add(ListBase *lb, const void *data, size_t 
data_len)
+{
+       TestBuffer *tb = (TestBuffer *)MEM_mallocN(sizeof(*tb), __func__);
+       tb->data = data;
+       tb->data_len = data_len;
+       tb->state = NULL;
+       BLI_addtail(lb, tb);
+       return tb;
+}
+
+static TestBuffer *testbuffer_list_add_copydata(ListBase *lb, const void 
*data, size_t data_len)
+{
+       void *data_copy = MEM_mallocN(data_len, __func__);
+       memcpy(data_copy, data, data_len);
+       return testbuffer_list_add(lb, data_copy, data_len);
+}
+
+static void testbuffer_list_state_from_data(
+        ListBase *lb,
+        const char *data, const size_t data_len)
+{
+       testbuffer_list_add_copydata(lb, (const void *)data, data_len);
+}
+
+/**
+ * A version of testbuffer_list_state_from_data that expand data by stride,
+ * handy so we can test data at different strides.
+ */
+static void testbuffer_list_state_from_data__stride_expand(
+        ListBase *lb,
+        const char *data, const size_t data_len,
+        const size_t stride)
+{
+       if (stride == 1) {
+               testbuffer_list_state_from_data(lb, data, data_len);
+       }
+       else {
+               const size_t data_stride_len = data_len  * stride;
+               char *data_stride = (char *)MEM_mallocN(data_stride_len, 
__func__);
+
+               for (size_t i = 0, i_stride = 0; i < data_len; i += 1, i_stride 
+= stride) {
+                       memset(&data_stride[i_stride], data[i], stride);
+               }
+
+               testbuffer_list_add(lb, (const void *)data_stride, 
data_stride_len);
+       }
+}
+
+#define testbuffer_list_state_from_string_array(lb, data_array) \
+{ \
+       unsigned int i_ = 0; \
+       const char *data; \
+       while ((data = data_array[i_++])) { \
+               testbuffer_list_state_from_data(lb, data, strlen(data)); \
+       } \
+} ((void)0)
+
+//
+
+#define TESTBUFFER_STRINGS_CREATE(lb, ...) \
+{ \
+       BLI_listbase_clear(lb); \
+       const char *data_array[] = {__VA_ARGS__ NULL}; \
+       testbuffer_list_state_from_string_array((lb), data_array); \
+} ((void)0)
+
+/* test in both directions */
+#define TESTBUFFER_STRINGS_EX(bs, ...) \
+{ \
+       ListBase lb; \
+       TESTBUFFER_STRINGS_CREATE(&lb, __VA_ARGS__); \
+       \
+       testbuffer_run_tests(bs, &lb); \
+       \
+       testbuffer_list_free(&lb); \
+} ((void)0)
+
+#define TESTBUFFER_STRINGS(stride, chunk_count, ...) \
+{ \
+       ListBase lb; \
+       TESTBUFFER_STRINGS_CREATE(&lb, __VA_ARGS__); \
+       \
+       testbuffer_run_tests_simple(&lb, stride, chunk_count); \
+       \
+       testbuffer_list_free(&lb); \
+} ((void)0)
+
+static bool testbuffer_item_validate(TestBuffer *tb)
+{
+       size_t data_state_len;
+       bool ok = true;
+       void *data_state = BLI_array_store_state_data_get_alloc(tb->state, 
&data_state_len);
+       if (tb->data_len != data_state_len) {
+               ok = false;
+       }
+       else if (memcmp(data_state, tb->data, data_state_len) != 0) {
+               ok = false;
+       }
+       MEM_freeN(data_state);
+       return ok;
+}
+
+static bool testbuffer_list_validate(const ListBase *lb)
+{
+       for (TestBuffer *tb = (TestBuffer *)lb->first; tb; tb = tb->next) {
+               if (!testbuffer_item_validate(tb)) {
+                       return false;
+               }
+       }
+
+       return true;
+}
+
+static void testbuffer_list_data_randomize(ListBase *lb, unsigned int 
random_seed)
+{
+       for (TestBuffer *tb = (TestBuffer *)lb->first; tb; tb = tb->next) {
+               BLI_array_randomize((void *)tb->data, 1, tb->data_len, 
random_seed++);
+       }
+}
+
+static void testbuffer_list_store_populate(
+        BArrayStore *bs, ListBase *lb)
+{
+       for (TestBuffer *tb = (TestBuffer *)lb->first, *tb_prev = NULL; tb; 
tb_prev = tb, tb = tb->next) {
+               tb->state = BLI_array_store_state_add(bs, tb->data, 
tb->data_len, (tb_prev ? tb_prev->state : NULL));
+       }
+}
+
+static void testbuffer_list_store_clear(
+        BArrayStore *bs, ListBase *lb)
+{
+       for (TestBuffer *tb = (TestBuffer *)lb->first; tb; tb = tb->next) {
+               BLI_array_store_state_remove(bs, tb->state);
+               tb->state = NULL;
+       }
+}
+
+static void testbuffer_list_free(ListBase *lb)
+{
+       for (TestBuffer *tb = (TestBuffer *)lb->first, *tb_next; tb; tb = 
tb_next) {
+               tb_next = tb->next;
+               MEM_freeN((void *)tb->data);
+               MEM_freeN(tb);
+       }
+       BLI_listbase_clear(lb);
+}
+
+static void testbuffer_run_tests_single(
+        BArrayStore *bs, ListBase *lb)
+{
+       testbuffer_list_store_populate(bs, lb);
+       EXPECT_EQ(true, testbuffer_list_validate(lb));
+       EXPECT_EQ(true, BLI_array_store_is_valid(bs));
+#ifdef DEBUG_PRINT
+       print_mem_saved("data", bs);
+#endif
+}
+
+/* avoid copy-paste code to run tests */
+static void testbuffer_run_tests(
+        BArrayStore *bs, ListBase *lb)
+{
+       /* forwards */
+       testbuffer_run_tests_single(bs, lb);
+       testbuffer_list_store_clear(bs, lb);
+
+       BLI_listbase_reverse(lb);
+
+       /* backwards */
+       testbuffer_run_tests_single(bs, lb);
+       testbuffer_list_store_clear(bs, lb);
+}
+
+static void testbuffer_run_tests_simple(
+        ListBase *lb,
+        const int stride, const int chunk_count)
+{
+       BArrayStore *bs = BLI_array_store_create(stride, chunk_count);
+       testbuffer_run_tests(bs, lb);
+       BLI_array_store_destroy(bs);
+}
+
+
+/* -------------------------------------------------------------------- */
+/* Basic Tests */
+
+TEST(array_store, Nop)
+{
+       BArrayStore *bs = BLI_array_store_create(1, 32);
+       BLI_array_store_destroy(bs);
+}
+
+TEST(array_store, NopState)
+{
+       BArrayStore *bs = BLI_array_store_create(1, 32);
+       const unsigned char data[] = "test";
+       BArrayState *state = BLI_array_store_state_add(bs, data, sizeof(data) - 
1, NULL);
+       EXPECT_EQ(sizeof(data) - 1, BLI_array_store_state_size_get(state));
+       BLI_array_store_state_remove(bs, state);
+       BLI_array_store_destroy(bs);
+}
+
+TEST(array_store, Single)
+{
+       BArrayStore *bs = BLI_array_store_create(1, 32);
+       const char data_src[] = "test";
+       const char *data_dst;
+       BArrayState *state = BLI_array_store_state_add(bs, data_src, 
sizeof(data_src), NULL);
+       size_t data_dst_len;
+       data_dst = (char *)BLI_array_store_state_data_get_alloc(state, 
&data_dst_len);
+       EXPECT_STREQ(data_src, data_dst);
+       EXPECT_EQ(sizeof(data_src), data_dst_len);
+       BLI_array_store_destroy(bs);
+       MEM_freeN((void *)data_dst);
+}
+
+TEST(array_store, DoubleNop)
+{
+       BArrayStore *bs = BLI_array_store_create(1, 32);
+       const char data_src[] = "test";
+       const char *data_dst;
+
+       BArrayState *state_a = BLI_array_store_state_add(bs, data_src, 
sizeof(data_src), NULL);
+       BArrayState *state_b = BLI_array_store_state_add(bs, data_src, 
sizeof(data_src), state_a);
+
+       EXPECT_EQ(sizeof(data_src),     
BLI_array_store_calc_size_compacted_get(bs));
+       EXPECT_EQ(sizeof(data_src) * 2, 
BLI_array_store_calc_size_expanded_get(bs));
+
+       size_t data_dst_len;
+
+       data_dst = (char *)BLI_array_store_state_data_get_alloc(state_a, 
&data_dst_len);
+       EXPECT_STREQ(data_src, data_dst);
+       MEM_freeN((void *)data_dst);
+
+       data_dst = (char *)BLI_array_store_state_data_get_alloc(state

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to