glusterfs
489 строк · 12.9 Кб
1/*
2Copyright (c) 2014 Red Hat, Inc. <http://www.redhat.com>
3This file is part of GlusterFS.
4
5This file is licensed to you under your choice of the GNU Lesser
6General Public License, version 3 or any later version (LGPLv3 or
7later), or the GNU General Public License, version 2 (GPLv2), in all
8cases as published by the Free Software Foundation.
9*/
10
11#include "glusterfs/mem-pool.h"12#include "glusterfs/logging.h"13#include "glusterfs/xlator.h"14
15#include <stdarg.h>16#include <stddef.h>17#include <setjmp.h>18#include <inttypes.h>19#include <string.h>20#include <cmocka_pbc.h>21#include <cmocka.h>22
23#ifndef assert_ptr_equal24#define assert_ptr_equal(a, b) \25_assert_int_equal(cast_ptr_to_largest_integral_type(a), \26cast_ptr_to_largest_integral_type(b), __FILE__, \27__LINE__)28#endif29
30/*
31* memory header for gf_mem_set_acct_info
32*/
33typedef struct {34uint32_t type;35size_t size;36xlator_t *xl;37gf_mem_magic_t header_magic;38void *data[];39} mem_header_t;40
41/*
42* Prototypes to private functions
43*/
44int
45gf_mem_set_acct_info(xlator_t *xl, char **alloc_ptr, size_t size, uint32_t type,46const char *typestr);47size_t
48__gf_total_alloc_size(size_t req_size);49void
50__gf_mem_trailer_write(uint8_t *trailer);51gf_mem_magic_t
52__gf_mem_trailer_read(uint8_t *trailer);53
54/*
55* Helper functions
56*/
57static xlator_t *58helper_xlator_init(uint32_t num_types)59{
60xlator_t *xl;61int i, ret;62
63REQUIRE(num_types > 0);64
65xl = test_calloc(1, sizeof(xlator_t));66assert_non_null(xl);67xl->mem_acct->num_types = num_types;68xl->mem_acct = test_calloc(sizeof(struct mem_acct) +69sizeof(struct mem_acct_rec) * num_types);70assert_non_null(xl->mem_acct);71
72xl->ctx = test_calloc(1, sizeof(glusterfs_ctx_t));73assert_non_null(xl->ctx);74
75for (i = 0; i < num_types; i++) {76ret = LOCK_INIT(&(xl->mem_acct->rec[i].lock));77assert_int_equal(ret, 0);78}79
80ENSURE(num_types == xl->mem_acct->num_types);81ENSURE(NULL != xl);82
83return xl;84}
85
86static int87helper_xlator_destroy(xlator_t *xl)88{
89int i, ret;90
91for (i = 0; i < xl->mem_acct->num_types; i++) {92ret = LOCK_DESTROY(&(xl->mem_acct->rec[i].lock));93assert_int_equal(ret, 0);94}95
96free(xl->mem_acct->rec);97free(xl->ctx);98free(xl);99return 0;100}
101
102static void103helper_check_memory_headers(char *mem, xlator_t *xl, size_t size, uint32_t type)104{
105mem_header_t *p;106
107p = (mem_header_t *)mem, assert_int_equal(p->type, type);108assert_int_equal(p->size, size);109assert_true(p->xl == xl);110assert_int_equal(p->header_magic, GF_MEM_HEADER_MAGIC);111assert_true(__gf_mem_trailer_read((uint8_t *)mem + sizeof(mem_header_t) +112size) == GF_MEM_TRAILER_MAGIC);113}
114
115/*
116* Tests
117*/
118static void119test_gf_mem_acct_enable_set(void **state)120{
121(void)state;122glusterfs_ctx_t test_ctx;123
124expect_assert_failure(gf_mem_acct_enable_set(NULL));125
126memset(&test_ctx, 0, sizeof(test_ctx));127assert_true(NULL == test_ctx.process_uuid);128gf_mem_acct_enable_set((void *)&test_ctx);129assert_true(1 == test_ctx.mem_acct_enable);130assert_true(NULL == test_ctx.process_uuid);131}
132
133static void134test_gf_mem_set_acct_info_asserts(void **state)135{
136xlator_t *xl;137xlator_t xltest;138char *alloc_ptr;139size_t size;140uint32_t type;141
142memset(&xltest, 0, sizeof(xlator_t));143xl = (xlator_t *)0xBADD;144alloc_ptr = (char *)0xBADD;145size = 8196;146type = 0;147
148// Check xl is NULL149expect_assert_failure(150gf_mem_set_acct_info(NULL, &alloc_ptr, size, type, ""));151// Check xl->mem_acct = NULL152expect_assert_failure(153gf_mem_set_acct_info(&xltest, &alloc_ptr, 0, type, ""));154// Check type <= xl->mem_acct->num_types155type = 100;156expect_assert_failure(157gf_mem_set_acct_info(&xltest, &alloc_ptr, 0, type, ""));158// Check alloc is NULL159assert_int_equal(-1, gf_mem_set_acct_info(&xltest, NULL, size, type, ""));160
161// Initialize xl162xl = helper_xlator_init(10);163
164// Test number of types165type = 100;166assert_true(NULL != xl->mem_acct);167assert_true(type > xl->mem_acct->num_types);168expect_assert_failure(gf_mem_set_acct_info(xl, &alloc_ptr, size, type, ""));169
170helper_xlator_destroy(xl);171}
172
173static void174test_gf_mem_set_acct_info_memory(void **state)175{
176xlator_t *xl;177char *alloc_ptr;178char *temp_ptr;179size_t size;180uint32_t type;181const char *typestr = "TEST";182
183size = 8196;184type = 9;185
186// Initialize xl187xl = helper_xlator_init(10);188assert_null(xl->mem_acct->rec[type].typestr);189
190// Test allocation191temp_ptr = test_calloc(1, size + GF_MEM_HEADER_SIZE + GF_MEM_TRAILER_SIZE);192assert_non_null(temp_ptr);193alloc_ptr = temp_ptr;194gf_mem_set_acct_info(xl, &alloc_ptr, size, type, typestr);195
196// Check values197assert_ptr_equal(typestr, xl->mem_acct->rec[type].typestr);198assert_int_equal(xl->mem_acct->rec[type].size, size);199assert_int_equal(xl->mem_acct->rec[type].num_allocs, 1);200assert_int_equal(xl->mem_acct->rec[type].total_allocs, 1);201assert_int_equal(xl->mem_acct->rec[type].max_size, size);202assert_int_equal(xl->mem_acct->rec[type].max_num_allocs, 1);203
204// Check memory205helper_check_memory_headers(temp_ptr, xl, size, type);206
207// Check that alloc_ptr has been moved correctly208// by gf_mem_set_acct_info209{210mem_header_t *p;211
212p = (mem_header_t *)temp_ptr;213p++;214p->type = 1234;215assert_int_equal(*(uint32_t *)alloc_ptr, p->type);216}217
218free(temp_ptr);219helper_xlator_destroy(xl);220}
221
222static void223test_gf_calloc_default_calloc(void **state)224{
225xlator_t *xl;226void *mem;227size_t size;228uint32_t type;229
230// Initialize xl231xl = helper_xlator_init(10);232assert_int_equal(xl->ctx->mem_acct_enable, 0);233will_return(__glusterfs_this_location, &xl);234
235// Call __gf_calloc236size = 1024;237type = 3;238mem = __gf_calloc(1, size, type, "3");239assert_non_null(mem);240memset(mem, 0x5A, size);241
242// Check xl did not change243assert_int_equal(xl->mem_acct->rec[type].size, 0);244assert_int_equal(xl->mem_acct->rec[type].num_allocs, 0);245assert_int_equal(xl->mem_acct->rec[type].total_allocs, 0);246assert_int_equal(xl->mem_acct->rec[type].max_size, 0);247assert_int_equal(xl->mem_acct->rec[type].max_num_allocs, 0);248
249free(mem);250helper_xlator_destroy(xl);251}
252
253static void254test_gf_calloc_mem_acct_enabled(void **state)255{
256xlator_t *xl;257void *mem;258size_t size;259uint32_t type;260
261// Initialize xl262xl = helper_xlator_init(10);263assert_int_equal(xl->ctx->mem_acct_enable, 0);264xl->ctx->mem_acct_enable = 1;265
266// For line mem-pool.c:115 and mem-pool:118267will_return_always(__glusterfs_this_location, &xl);268
269// Call __gf_calloc270size = 1024;271type = 3;272mem = __gf_calloc(1, size, type, "3");273assert_non_null(mem);274memset(mem, 0x5A, size);275
276// Check xl values277assert_int_equal(xl->mem_acct->rec[type].size, size);278assert_int_equal(xl->mem_acct->rec[type].num_allocs, 1);279assert_int_equal(xl->mem_acct->rec[type].total_allocs, 1);280assert_int_equal(xl->mem_acct->rec[type].max_size, size);281assert_int_equal(xl->mem_acct->rec[type].max_num_allocs, 1);282
283// Check memory284helper_check_memory_headers(mem - sizeof(mem_header_t), xl, size, type);285free(mem - sizeof(mem_header_t));286helper_xlator_destroy(xl);287}
288
289static void290test_gf_malloc_default_malloc(void **state)291{
292xlator_t *xl;293void *mem;294size_t size;295uint32_t type;296
297// Initialize xl298xl = helper_xlator_init(10);299assert_int_equal(xl->ctx->mem_acct_enable, 0);300will_return(__glusterfs_this_location, &xl);301
302// Call __gf_malloc303size = 1024;304type = 3;305mem = __gf_malloc(size, type, "3");306assert_non_null(mem);307memset(mem, 0x5A, size);308
309// Check xl did not change310assert_int_equal(xl->mem_acct->rec[type].size, 0);311assert_int_equal(xl->mem_acct->rec[type].num_allocs, 0);312assert_int_equal(xl->mem_acct->rec[type].total_allocs, 0);313assert_int_equal(xl->mem_acct->rec[type].max_size, 0);314assert_int_equal(xl->mem_acct->rec[type].max_num_allocs, 0);315
316free(mem);317helper_xlator_destroy(xl);318}
319
320static void321test_gf_malloc_mem_acct_enabled(void **state)322{
323xlator_t *xl;324void *mem;325size_t size;326uint32_t type;327
328// Initialize xl329xl = helper_xlator_init(10);330assert_int_equal(xl->ctx->mem_acct_enable, 0);331xl->ctx->mem_acct_enable = 1;332
333// For line mem-pool.c:115 and mem-pool:118334will_return_always(__glusterfs_this_location, &xl);335
336// Call __gf_malloc337size = 1024;338type = 3;339mem = __gf_malloc(size, type, "3");340assert_non_null(mem);341memset(mem, 0x5A, size);342
343// Check xl values344assert_int_equal(xl->mem_acct->rec[type].size, size);345assert_int_equal(xl->mem_acct->rec[type].num_allocs, 1);346assert_int_equal(xl->mem_acct->rec[type].total_allocs, 1);347assert_int_equal(xl->mem_acct->rec[type].max_size, size);348assert_int_equal(xl->mem_acct->rec[type].max_num_allocs, 1);349
350// Check memory351helper_check_memory_headers(mem - sizeof(mem_header_t), xl, size, type);352free(mem - sizeof(mem_header_t));353helper_xlator_destroy(xl);354}
355
356static void357test_gf_realloc_default_realloc(void **state)358{
359xlator_t *xl;360void *mem;361size_t size;362uint32_t type;363
364// Initialize xl365xl = helper_xlator_init(10);366assert_int_equal(xl->ctx->mem_acct_enable, 0);367will_return_always(__glusterfs_this_location, &xl);368
369// Call __gf_malloc then realloc370size = 10;371type = 3;372mem = __gf_malloc(size, type, "3");373assert_non_null(mem);374memset(mem, 0xA5, size);375
376size = 1024;377mem = __gf_realloc(mem, size);378assert_non_null(mem);379memset(mem, 0x5A, size);380
381// Check xl did not change382assert_int_equal(xl->mem_acct->rec[type].size, 0);383assert_int_equal(xl->mem_acct->rec[type].num_allocs, 0);384assert_int_equal(xl->mem_acct->rec[type].total_allocs, 0);385assert_int_equal(xl->mem_acct->rec[type].max_size, 0);386assert_int_equal(xl->mem_acct->rec[type].max_num_allocs, 0);387
388free(mem);389helper_xlator_destroy(xl);390}
391
392static void393test_gf_realloc_mem_acct_enabled(void **state)394{
395xlator_t *xl;396void *mem;397size_t size;398uint32_t type;399
400// Initialize xl401xl = helper_xlator_init(10);402assert_int_equal(xl->ctx->mem_acct_enable, 0);403xl->ctx->mem_acct_enable = 1;404
405// For line mem-pool.c:115 and mem-pool:118406will_return_always(__glusterfs_this_location, &xl);407
408// Call __gf_malloc then realloc409size = 1024;410type = 3;411mem = __gf_malloc(size, type, "3");412assert_non_null(mem);413memset(mem, 0xA5, size);414
415size = 2048;416mem = __gf_realloc(mem, size);417assert_non_null(mem);418memset(mem, 0x5A, size);419
420// Check xl values421//422// :TODO: This is really weird. I would have expected423// xl to only have a size equal to that of the realloc424// not to the realloc + the malloc.425// Is this a bug?426//427assert_int_equal(xl->mem_acct->rec[type].size, size + 1024);428assert_int_equal(xl->mem_acct->rec[type].num_allocs, 2);429assert_int_equal(xl->mem_acct->rec[type].total_allocs, 2);430assert_int_equal(xl->mem_acct->rec[type].max_size, size + 1024);431assert_int_equal(xl->mem_acct->rec[type].max_num_allocs, 2);432
433// Check memory434helper_check_memory_headers(mem - sizeof(mem_header_t), xl, size, type);435free(mem - sizeof(mem_header_t));436helper_xlator_destroy(xl);437}
438
439static void440test_gf_realloc_ptr(void **state)441{
442xlator_t *xl;443void *mem;444size_t size;445
446// Initialize xl447xl = helper_xlator_init(10);448assert_int_equal(xl->ctx->mem_acct_enable, 0);449
450// For line mem-pool.c:115 and mem-pool:118451will_return_always(__glusterfs_this_location, &xl);452
453// Tests according to the manpage for realloc454
455// Like a malloc456size = 1024;457mem = __gf_realloc(NULL, size);458assert_non_null(mem);459memset(mem, 0xA5, size);460
461// Like a free462mem = __gf_realloc(mem, 0);463assert_null(mem);464
465// Now enable xl context466xl->ctx->mem_acct_enable = 1;467expect_assert_failure(__gf_realloc(NULL, size));468
469helper_xlator_destroy(xl);470}
471
472int
473main(void)474{
475const struct CMUnitTest libglusterfs_mem_pool_tests[] = {476cmocka_unit_test(test_gf_mem_acct_enable_set),477cmocka_unit_test(test_gf_mem_set_acct_info_asserts),478cmocka_unit_test(test_gf_mem_set_acct_info_memory),479cmocka_unit_test(test_gf_calloc_default_calloc),480cmocka_unit_test(test_gf_calloc_mem_acct_enabled),481cmocka_unit_test(test_gf_malloc_default_malloc),482cmocka_unit_test(test_gf_malloc_mem_acct_enabled),483cmocka_unit_test(test_gf_realloc_default_realloc),484cmocka_unit_test(test_gf_realloc_mem_acct_enabled),485cmocka_unit_test(test_gf_realloc_ptr),486};487
488return cmocka_run_group_tests(libglusterfs_mem_pool_tests, NULL, NULL);489}
490