mirror of
https://github.com/microsoft/mimalloc.git
synced 2025-07-06 19:38:41 +03:00
merge from dev-trace
This commit is contained in:
commit
99c113d573
142 changed files with 3301 additions and 1807 deletions
|
@ -216,7 +216,7 @@ int main() {
|
|||
free(p1);
|
||||
free(p2);
|
||||
free(s);
|
||||
|
||||
|
||||
/* now test if override worked by allocating/freeing across the api's*/
|
||||
//p1 = mi_malloc(32);
|
||||
//free(p1);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <mimalloc.h>
|
||||
#include <mimalloc-override.h>
|
||||
|
||||
int main() {
|
||||
mi_version(); // ensure mimalloc library is linked
|
||||
|
@ -25,6 +25,12 @@ int main() {
|
|||
//free(p1);
|
||||
//p2 = malloc(32);
|
||||
//mi_free(p2);
|
||||
p1 = malloc(24);
|
||||
p2 = reallocarray(p1, 16, 16);
|
||||
free(p2);
|
||||
p1 = malloc(24);
|
||||
assert(reallocarr(&p1, 16, 16) == 0);
|
||||
free(p1);
|
||||
mi_stats_print(NULL);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ int main() {
|
|||
strdup_test();
|
||||
// corrupt_free();
|
||||
|
||||
//test_mt_shutdown();
|
||||
test_mt_shutdown();
|
||||
//fail_aslr();
|
||||
bench_alloc_large();
|
||||
mi_stats_print(NULL);
|
||||
|
@ -78,7 +78,7 @@ public:
|
|||
static void various_tests() {
|
||||
atexit(free_p);
|
||||
void* p1 = malloc(78);
|
||||
void* p2 = mi_malloc_aligned(16, 24);
|
||||
void* p2 = mi_malloc_aligned(24, 16);
|
||||
free(p1);
|
||||
p1 = malloc(8);
|
||||
char* s = mi_strdup("hello\n");
|
||||
|
|
332
test/test-api-fill.c
Normal file
332
test/test-api-fill.c
Normal file
|
@ -0,0 +1,332 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
Copyright (c) 2018-2020, Microsoft Research, Daan Leijen
|
||||
This is free software; you can redistribute it and/or modify it under the
|
||||
terms of the MIT license. A copy of the license can be found in the file
|
||||
"LICENSE" at the root of this distribution.
|
||||
-----------------------------------------------------------------------------*/
|
||||
#include "mimalloc.h"
|
||||
#include "mimalloc-types.h"
|
||||
|
||||
#include "testhelper.h"
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Helper functions
|
||||
// ---------------------------------------------------------------------------
|
||||
bool check_zero_init(uint8_t* p, size_t size);
|
||||
#if MI_DEBUG >= 2
|
||||
bool check_debug_fill_uninit(uint8_t* p, size_t size);
|
||||
bool check_debug_fill_freed(uint8_t* p, size_t size);
|
||||
#endif
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Main testing
|
||||
// ---------------------------------------------------------------------------
|
||||
int main(void) {
|
||||
mi_option_disable(mi_option_verbose);
|
||||
|
||||
// ---------------------------------------------------
|
||||
// Zeroing allocation
|
||||
// ---------------------------------------------------
|
||||
CHECK_BODY("zeroinit-zalloc-small", {
|
||||
size_t zalloc_size = MI_SMALL_SIZE_MAX / 2;
|
||||
uint8_t* p = (uint8_t*)mi_zalloc(zalloc_size);
|
||||
result = check_zero_init(p, zalloc_size);
|
||||
mi_free(p);
|
||||
});
|
||||
CHECK_BODY("zeroinit-zalloc-large", {
|
||||
size_t zalloc_size = MI_SMALL_SIZE_MAX * 2;
|
||||
uint8_t* p = (uint8_t*)mi_zalloc(zalloc_size);
|
||||
result = check_zero_init(p, zalloc_size);
|
||||
mi_free(p);
|
||||
});
|
||||
CHECK_BODY("zeroinit-zalloc_small", {
|
||||
size_t zalloc_size = MI_SMALL_SIZE_MAX / 2;
|
||||
uint8_t* p = (uint8_t*)mi_zalloc_small(zalloc_size);
|
||||
result = check_zero_init(p, zalloc_size);
|
||||
mi_free(p);
|
||||
});
|
||||
|
||||
CHECK_BODY("zeroinit-calloc-small", {
|
||||
size_t calloc_size = MI_SMALL_SIZE_MAX / 2;
|
||||
uint8_t* p = (uint8_t*)mi_calloc(calloc_size, 1);
|
||||
result = check_zero_init(p, calloc_size);
|
||||
mi_free(p);
|
||||
});
|
||||
CHECK_BODY("zeroinit-calloc-large", {
|
||||
size_t calloc_size = MI_SMALL_SIZE_MAX * 2;
|
||||
uint8_t* p = (uint8_t*)mi_calloc(calloc_size, 1);
|
||||
result = check_zero_init(p, calloc_size);
|
||||
mi_free(p);
|
||||
});
|
||||
|
||||
CHECK_BODY("zeroinit-rezalloc-small", {
|
||||
size_t zalloc_size = MI_SMALL_SIZE_MAX / 2;
|
||||
uint8_t* p = (uint8_t*)mi_zalloc(zalloc_size);
|
||||
result = check_zero_init(p, zalloc_size);
|
||||
zalloc_size *= 3;
|
||||
p = (uint8_t*)mi_rezalloc(p, zalloc_size);
|
||||
result &= check_zero_init(p, zalloc_size);
|
||||
mi_free(p);
|
||||
});
|
||||
CHECK_BODY("zeroinit-rezalloc-large", {
|
||||
size_t zalloc_size = MI_SMALL_SIZE_MAX * 2;
|
||||
uint8_t* p = (uint8_t*)mi_zalloc(zalloc_size);
|
||||
result = check_zero_init(p, zalloc_size);
|
||||
zalloc_size *= 3;
|
||||
p = (uint8_t*)mi_rezalloc(p, zalloc_size);
|
||||
result &= check_zero_init(p, zalloc_size);
|
||||
mi_free(p);
|
||||
});
|
||||
|
||||
CHECK_BODY("zeroinit-recalloc-small", {
|
||||
size_t calloc_size = MI_SMALL_SIZE_MAX / 2;
|
||||
uint8_t* p = (uint8_t*)mi_calloc(calloc_size, 1);
|
||||
result = check_zero_init(p, calloc_size);
|
||||
calloc_size *= 3;
|
||||
p = (uint8_t*)mi_recalloc(p, calloc_size, 1);
|
||||
result &= check_zero_init(p, calloc_size);
|
||||
mi_free(p);
|
||||
});
|
||||
CHECK_BODY("zeroinit-recalloc-large", {
|
||||
size_t calloc_size = MI_SMALL_SIZE_MAX * 2;
|
||||
uint8_t* p = (uint8_t*)mi_calloc(calloc_size, 1);
|
||||
result = check_zero_init(p, calloc_size);
|
||||
calloc_size *= 3;
|
||||
p = (uint8_t*)mi_recalloc(p, calloc_size, 1);
|
||||
result &= check_zero_init(p, calloc_size);
|
||||
mi_free(p);
|
||||
});
|
||||
|
||||
// ---------------------------------------------------
|
||||
// Zeroing in aligned API
|
||||
// ---------------------------------------------------
|
||||
CHECK_BODY("zeroinit-zalloc_aligned-small", {
|
||||
size_t zalloc_size = MI_SMALL_SIZE_MAX / 2;
|
||||
uint8_t* p = (uint8_t*)mi_zalloc_aligned(zalloc_size, MI_MAX_ALIGN_SIZE * 2);
|
||||
result = check_zero_init(p, zalloc_size);
|
||||
mi_free(p);
|
||||
});
|
||||
CHECK_BODY("zeroinit-zalloc_aligned-large", {
|
||||
size_t zalloc_size = MI_SMALL_SIZE_MAX * 2;
|
||||
uint8_t* p = (uint8_t*)mi_zalloc_aligned(zalloc_size, MI_MAX_ALIGN_SIZE * 2);
|
||||
result = check_zero_init(p, zalloc_size);
|
||||
mi_free(p);
|
||||
});
|
||||
|
||||
CHECK_BODY("zeroinit-calloc_aligned-small", {
|
||||
size_t calloc_size = MI_SMALL_SIZE_MAX / 2;
|
||||
uint8_t* p = (uint8_t*)mi_calloc_aligned(calloc_size, 1, MI_MAX_ALIGN_SIZE * 2);
|
||||
result = check_zero_init(p, calloc_size);
|
||||
mi_free(p);
|
||||
});
|
||||
CHECK_BODY("zeroinit-calloc_aligned-large", {
|
||||
size_t calloc_size = MI_SMALL_SIZE_MAX * 2;
|
||||
uint8_t* p = (uint8_t*)mi_calloc_aligned(calloc_size, 1, MI_MAX_ALIGN_SIZE * 2);
|
||||
result = check_zero_init(p, calloc_size);
|
||||
mi_free(p);
|
||||
});
|
||||
|
||||
CHECK_BODY("zeroinit-rezalloc_aligned-small", {
|
||||
size_t zalloc_size = MI_SMALL_SIZE_MAX / 2;
|
||||
uint8_t* p = (uint8_t*)mi_zalloc_aligned(zalloc_size, MI_MAX_ALIGN_SIZE * 2);
|
||||
result = check_zero_init(p, zalloc_size);
|
||||
zalloc_size *= 3;
|
||||
p = (uint8_t*)mi_rezalloc_aligned(p, zalloc_size, MI_MAX_ALIGN_SIZE * 2);
|
||||
result &= check_zero_init(p, zalloc_size);
|
||||
mi_free(p);
|
||||
});
|
||||
CHECK_BODY("zeroinit-rezalloc_aligned-large", {
|
||||
size_t zalloc_size = MI_SMALL_SIZE_MAX * 2;
|
||||
uint8_t* p = (uint8_t*)mi_zalloc_aligned(zalloc_size, MI_MAX_ALIGN_SIZE * 2);
|
||||
result = check_zero_init(p, zalloc_size);
|
||||
zalloc_size *= 3;
|
||||
p = (uint8_t*)mi_rezalloc_aligned(p, zalloc_size, MI_MAX_ALIGN_SIZE * 2);
|
||||
result &= check_zero_init(p, zalloc_size);
|
||||
mi_free(p);
|
||||
});
|
||||
|
||||
CHECK_BODY("zeroinit-recalloc_aligned-small", {
|
||||
size_t calloc_size = MI_SMALL_SIZE_MAX / 2;
|
||||
uint8_t* p = (uint8_t*)mi_calloc_aligned(calloc_size, 1, MI_MAX_ALIGN_SIZE * 2);
|
||||
result = check_zero_init(p, calloc_size);
|
||||
calloc_size *= 3;
|
||||
p = (uint8_t*)mi_recalloc_aligned(p, calloc_size, 1, MI_MAX_ALIGN_SIZE * 2);
|
||||
result &= check_zero_init(p, calloc_size);
|
||||
mi_free(p);
|
||||
});
|
||||
CHECK_BODY("zeroinit-recalloc_aligned-large", {
|
||||
size_t calloc_size = MI_SMALL_SIZE_MAX * 2;
|
||||
uint8_t* p = (uint8_t*)mi_calloc_aligned(calloc_size, 1, MI_MAX_ALIGN_SIZE * 2);
|
||||
result = check_zero_init(p, calloc_size);
|
||||
calloc_size *= 3;
|
||||
p = (uint8_t*)mi_recalloc_aligned(p, calloc_size, 1, MI_MAX_ALIGN_SIZE * 2);
|
||||
result &= check_zero_init(p, calloc_size);
|
||||
mi_free(p);
|
||||
});
|
||||
|
||||
#if MI_DEBUG >= 2
|
||||
// ---------------------------------------------------
|
||||
// Debug filling
|
||||
// ---------------------------------------------------
|
||||
CHECK_BODY("uninit-malloc-small", {
|
||||
size_t malloc_size = MI_SMALL_SIZE_MAX / 2;
|
||||
uint8_t* p = (uint8_t*)mi_malloc(malloc_size);
|
||||
result = check_debug_fill_uninit(p, malloc_size);
|
||||
mi_free(p);
|
||||
});
|
||||
CHECK_BODY("uninit-malloc-large", {
|
||||
size_t malloc_size = MI_SMALL_SIZE_MAX * 2;
|
||||
uint8_t* p = (uint8_t*)mi_malloc(malloc_size);
|
||||
result = check_debug_fill_uninit(p, malloc_size);
|
||||
mi_free(p);
|
||||
});
|
||||
|
||||
CHECK_BODY("uninit-malloc_small", {
|
||||
size_t malloc_size = MI_SMALL_SIZE_MAX / 2;
|
||||
uint8_t* p = (uint8_t*)mi_malloc_small(malloc_size);
|
||||
result = check_debug_fill_uninit(p, malloc_size);
|
||||
mi_free(p);
|
||||
});
|
||||
|
||||
CHECK_BODY("uninit-realloc-small", {
|
||||
size_t malloc_size = MI_SMALL_SIZE_MAX / 2;
|
||||
uint8_t* p = (uint8_t*)mi_malloc(malloc_size);
|
||||
result = check_debug_fill_uninit(p, malloc_size);
|
||||
malloc_size *= 3;
|
||||
p = (uint8_t*)mi_realloc(p, malloc_size);
|
||||
result &= check_debug_fill_uninit(p, malloc_size);
|
||||
mi_free(p);
|
||||
});
|
||||
CHECK_BODY("uninit-realloc-large", {
|
||||
size_t malloc_size = MI_SMALL_SIZE_MAX * 2;
|
||||
uint8_t* p = (uint8_t*)mi_malloc(malloc_size);
|
||||
result = check_debug_fill_uninit(p, malloc_size);
|
||||
malloc_size *= 3;
|
||||
p = (uint8_t*)mi_realloc(p, malloc_size);
|
||||
result &= check_debug_fill_uninit(p, malloc_size);
|
||||
mi_free(p);
|
||||
});
|
||||
|
||||
CHECK_BODY("uninit-mallocn-small", {
|
||||
size_t malloc_size = MI_SMALL_SIZE_MAX / 2;
|
||||
uint8_t* p = (uint8_t*)mi_mallocn(malloc_size, 1);
|
||||
result = check_debug_fill_uninit(p, malloc_size);
|
||||
mi_free(p);
|
||||
});
|
||||
CHECK_BODY("uninit-mallocn-large", {
|
||||
size_t malloc_size = MI_SMALL_SIZE_MAX * 2;
|
||||
uint8_t* p = (uint8_t*)mi_mallocn(malloc_size, 1);
|
||||
result = check_debug_fill_uninit(p, malloc_size);
|
||||
mi_free(p);
|
||||
});
|
||||
|
||||
CHECK_BODY("uninit-reallocn-small", {
|
||||
size_t malloc_size = MI_SMALL_SIZE_MAX / 2;
|
||||
uint8_t* p = (uint8_t*)mi_mallocn(malloc_size, 1);
|
||||
result = check_debug_fill_uninit(p, malloc_size);
|
||||
malloc_size *= 3;
|
||||
p = (uint8_t*)mi_reallocn(p, malloc_size, 1);
|
||||
result &= check_debug_fill_uninit(p, malloc_size);
|
||||
mi_free(p);
|
||||
});
|
||||
CHECK_BODY("uninit-reallocn-large", {
|
||||
size_t malloc_size = MI_SMALL_SIZE_MAX * 2;
|
||||
uint8_t* p = (uint8_t*)mi_mallocn(malloc_size, 1);
|
||||
result = check_debug_fill_uninit(p, malloc_size);
|
||||
malloc_size *= 3;
|
||||
p = (uint8_t*)mi_reallocn(p, malloc_size, 1);
|
||||
result &= check_debug_fill_uninit(p, malloc_size);
|
||||
mi_free(p);
|
||||
});
|
||||
|
||||
CHECK_BODY("uninit-malloc_aligned-small", {
|
||||
size_t malloc_size = MI_SMALL_SIZE_MAX / 2;
|
||||
uint8_t* p = (uint8_t*)mi_malloc_aligned(malloc_size, MI_MAX_ALIGN_SIZE * 2);
|
||||
result = check_debug_fill_uninit(p, malloc_size);
|
||||
mi_free(p);
|
||||
});
|
||||
CHECK_BODY("uninit-malloc_aligned-large", {
|
||||
size_t malloc_size = MI_SMALL_SIZE_MAX * 2;
|
||||
uint8_t* p = (uint8_t*)mi_malloc_aligned(malloc_size, MI_MAX_ALIGN_SIZE * 2);
|
||||
result = check_debug_fill_uninit(p, malloc_size);
|
||||
mi_free(p);
|
||||
});
|
||||
|
||||
CHECK_BODY("uninit-realloc_aligned-small", {
|
||||
size_t malloc_size = MI_SMALL_SIZE_MAX / 2;
|
||||
uint8_t* p = (uint8_t*)mi_malloc_aligned(malloc_size, MI_MAX_ALIGN_SIZE * 2);
|
||||
result = check_debug_fill_uninit(p, malloc_size);
|
||||
malloc_size *= 3;
|
||||
p = (uint8_t*)mi_realloc_aligned(p, malloc_size, MI_MAX_ALIGN_SIZE * 2);
|
||||
result &= check_debug_fill_uninit(p, malloc_size);
|
||||
mi_free(p);
|
||||
});
|
||||
CHECK_BODY("uninit-realloc_aligned-large", {
|
||||
size_t malloc_size = MI_SMALL_SIZE_MAX * 2;
|
||||
uint8_t* p = (uint8_t*)mi_malloc_aligned(malloc_size, MI_MAX_ALIGN_SIZE * 2);
|
||||
result = check_debug_fill_uninit(p, malloc_size);
|
||||
malloc_size *= 3;
|
||||
p = (uint8_t*)mi_realloc_aligned(p, malloc_size, MI_MAX_ALIGN_SIZE * 2);
|
||||
result &= check_debug_fill_uninit(p, malloc_size);
|
||||
mi_free(p);
|
||||
});
|
||||
|
||||
|
||||
CHECK_BODY("fill-freed-small", {
|
||||
size_t malloc_size = MI_SMALL_SIZE_MAX / 2;
|
||||
uint8_t* p = (uint8_t*)mi_malloc(malloc_size);
|
||||
mi_free(p);
|
||||
// First sizeof(void*) bytes will contain housekeeping data, skip these
|
||||
result = check_debug_fill_freed(p + sizeof(void*), malloc_size - sizeof(void*));
|
||||
});
|
||||
CHECK_BODY("fill-freed-large", {
|
||||
size_t malloc_size = MI_SMALL_SIZE_MAX * 2;
|
||||
uint8_t* p = (uint8_t*)mi_malloc(malloc_size);
|
||||
mi_free(p);
|
||||
// First sizeof(void*) bytes will contain housekeeping data, skip these
|
||||
result = check_debug_fill_freed(p + sizeof(void*), malloc_size - sizeof(void*));
|
||||
});
|
||||
#endif
|
||||
|
||||
// ---------------------------------------------------
|
||||
// Done
|
||||
// ---------------------------------------------------[]
|
||||
return print_test_summary();
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Helper functions
|
||||
// ---------------------------------------------------------------------------
|
||||
bool check_zero_init(uint8_t* p, size_t size) {
|
||||
if(!p)
|
||||
return false;
|
||||
bool result = true;
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
result &= p[i] == 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#if MI_DEBUG >= 2
|
||||
bool check_debug_fill_uninit(uint8_t* p, size_t size) {
|
||||
if(!p)
|
||||
return false;
|
||||
|
||||
bool result = true;
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
result &= p[i] == MI_DEBUG_UNINIT;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool check_debug_fill_freed(uint8_t* p, size_t size) {
|
||||
if(!p)
|
||||
return false;
|
||||
|
||||
bool result = true;
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
result &= p[i] == MI_DEBUG_FREED;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#endif
|
|
@ -23,7 +23,6 @@ we therefore test the API over various inputs. Please add more tests :-)
|
|||
[1] https://github.com/daanx/mimalloc-bench
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
@ -35,34 +34,9 @@ we therefore test the API over various inputs. Please add more tests :-)
|
|||
|
||||
#include "mimalloc.h"
|
||||
// #include "mimalloc-internal.h"
|
||||
#include "mimalloc-types.h" // for MI_DEBUG
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Test macros: CHECK(name,predicate) and CHECK_BODY(name,body)
|
||||
// ---------------------------------------------------------------------------
|
||||
static int ok = 0;
|
||||
static int failed = 0;
|
||||
|
||||
#define CHECK_BODY(name,body) \
|
||||
do { \
|
||||
fprintf(stderr,"test: %s... ", name ); \
|
||||
bool result = true; \
|
||||
do { body } while(false); \
|
||||
if (!(result)) { \
|
||||
failed++; \
|
||||
fprintf(stderr, \
|
||||
"\n FAILED: %s:%d:\n %s\n", \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
#body); \
|
||||
/* exit(1); */ \
|
||||
} \
|
||||
else { \
|
||||
ok++; \
|
||||
fprintf(stderr,"ok.\n"); \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#define CHECK(name,expr) CHECK_BODY(name,{ result = (expr); })
|
||||
#include "testhelper.h"
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Test functions
|
||||
|
@ -158,6 +132,28 @@ int main(void) {
|
|||
CHECK_BODY("malloc-aligned5", {
|
||||
void* p = mi_malloc_aligned(4097,4096); size_t usable = mi_usable_size(p); result = usable >= 4097 && usable < 10000; mi_free(p);
|
||||
});
|
||||
CHECK_BODY("malloc-aligned6", {
|
||||
bool ok = true;
|
||||
for (size_t align = 1; align <= MI_ALIGNMENT_MAX && ok; align *= 2) {
|
||||
void* ps[8];
|
||||
for (int i = 0; i < 8 && ok; i++) {
|
||||
ps[i] = mi_malloc_aligned(align*13 /*size*/, align);
|
||||
if (ps[i] == NULL || (uintptr_t)(ps[i]) % align != 0) {
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 8 && ok; i++) {
|
||||
mi_free(ps[i]);
|
||||
}
|
||||
}
|
||||
result = ok;
|
||||
});
|
||||
CHECK_BODY("malloc-aligned7", {
|
||||
void* p = mi_malloc_aligned(1024,MI_ALIGNMENT_MAX); mi_free(p);
|
||||
});
|
||||
CHECK_BODY("malloc-aligned8", {
|
||||
void* p = mi_malloc_aligned(1024,2*MI_ALIGNMENT_MAX); mi_free(p);
|
||||
});
|
||||
CHECK_BODY("malloc-aligned-at1", {
|
||||
void* p = mi_malloc_aligned_at(48,32,0); result = (p != NULL && ((uintptr_t)(p) + 0) % 32 == 0); mi_free(p);
|
||||
});
|
||||
|
@ -172,8 +168,8 @@ int main(void) {
|
|||
ok = (p != NULL && (uintptr_t)(p) % 16 == 0); mi_free(p);
|
||||
}
|
||||
result = ok;
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
// ---------------------------------------------------
|
||||
// Heaps
|
||||
// ---------------------------------------------------
|
||||
|
@ -197,10 +193,7 @@ int main(void) {
|
|||
// ---------------------------------------------------
|
||||
// Done
|
||||
// ---------------------------------------------------[]
|
||||
fprintf(stderr,"\n\n---------------------------------------------\n"
|
||||
"succeeded: %i\n"
|
||||
"failed : %i\n\n", ok, failed);
|
||||
return failed;
|
||||
return print_test_summary();
|
||||
}
|
||||
|
||||
// ---------------------------------------------------
|
||||
|
|
49
test/testhelper.h
Normal file
49
test/testhelper.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
Copyright (c) 2018-2020, Microsoft Research, Daan Leijen
|
||||
This is free software; you can redistribute it and/or modify it under the
|
||||
terms of the MIT license. A copy of the license can be found in the file
|
||||
"LICENSE" at the root of this distribution.
|
||||
-----------------------------------------------------------------------------*/
|
||||
#ifndef TESTHELPER_H_
|
||||
#define TESTHELPER_H_
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Test macros: CHECK(name,predicate) and CHECK_BODY(name,body)
|
||||
// ---------------------------------------------------------------------------
|
||||
static int ok = 0;
|
||||
static int failed = 0;
|
||||
|
||||
#define CHECK_BODY(name,body) \
|
||||
do { \
|
||||
fprintf(stderr,"test: %s... ", name ); \
|
||||
bool result = true; \
|
||||
do { body } while(false); \
|
||||
if (!(result)) { \
|
||||
failed++; \
|
||||
fprintf(stderr, \
|
||||
"\n FAILED: %s:%d:\n %s\n", \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
#body); \
|
||||
/* exit(1); */ \
|
||||
} \
|
||||
else { \
|
||||
ok++; \
|
||||
fprintf(stderr,"ok.\n"); \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#define CHECK(name,expr) CHECK_BODY(name,{ result = (expr); })
|
||||
|
||||
// Print summary of test. Return value can be directly use as a return value for main().
|
||||
static inline int print_test_summary(void)
|
||||
{
|
||||
fprintf(stderr,"\n\n---------------------------------------------\n"
|
||||
"succeeded: %i\n"
|
||||
"failed : %i\n\n", ok, failed);
|
||||
return failed;
|
||||
}
|
||||
|
||||
#endif // TESTHELPER_H_
|
Loading…
Add table
Add a link
Reference in a new issue