1
mirror of https://github.com/jedisct1/libsodium.git synced 2024-12-20 10:37:24 -07:00
libsodium/test/default/cmptest.h
Frank Denis 9567bbe65f Limit resources when running tests
The default memory limit matches the limit already used when running
the javascript and webassembly tests.

Original diff by @pilou-

Fixes #837
2019-05-21 10:52:01 +02:00

264 lines
5.2 KiB
C

#ifndef __CMPTEST_H__
#define __CMPTEST_H__
#ifdef NDEBUG
#/**/undef/**/ NDEBUG
#endif
#include <assert.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#if defined(HAVE_SYS_RESOURCE_H) && defined(HAVE_SETRLIMIT)
# include <sys/types.h>
# include <sys/time.h>
# include <sys/resource.h>
#endif
#include "sodium.h"
#include "quirks.h"
#ifndef TOTAL_MEMORY_TESTS
# define TOTAL_MEMORY_TESTS 16777216
#endif
#ifdef __EMSCRIPTEN__
# undef TEST_SRCDIR
# define TEST_SRCDIR "/test-data"
#endif
#ifndef TEST_SRCDIR
# define TEST_SRCDIR "."
#endif
#define TEST_NAME_RES TEST_NAME ".res"
#define TEST_NAME_OUT TEST_SRCDIR "/" TEST_NAME ".exp"
#ifdef HAVE_ARC4RANDOM
# undef rand
# define rand(X) arc4random(X)
#endif
int xmain(void);
static unsigned char *guard_page;
static int set_resource_limits(void)
{
int res = 0;
#if defined(RLIM_INFINITY) && defined(HAVE_SETRLIMIT)
struct rlimit limits;
limits.rlim_cur = limits.rlim_max = TOTAL_MEMORY_TESTS;
# ifdef RLIMIT_AS
res |= setrlimit(RLIMIT_AS, &limits);
# endif
# ifdef RLIMIT_DATA
res |= setrlimit(RLIMIT_DATA, &limits);
# endif
#endif
return res;
}
#ifdef BENCHMARKS
# include <sys/time.h>
# ifndef ITERATIONS
# define ITERATIONS 128
# endif
struct {
void *pnt;
size_t size;
} mempool[1024];
static size_t mempool_idx;
static __attribute__((malloc)) void *mempool_alloc(size_t size)
{
size_t i;
if (size >= (size_t) 0x80000000 - (size_t) 0x00000fff) {
return NULL;
}
size = (size + (size_t) 0x00000fff) & ~ (size_t) 0x00000fff;
for (i = 0U; i < mempool_idx; i++) {
if (mempool[i].size >= (size | (size_t) 0x80000000)) {
mempool[i].size &= ~ (size_t) 0x80000000;
return mempool[i].pnt;
}
}
if (mempool_idx >= sizeof mempool / sizeof mempool[0]) {
return NULL;
}
mempool[mempool_idx].size = size;
return (mempool[mempool_idx++].pnt = (void *) malloc(size));
}
static void mempool_free(void *pnt)
{
size_t i;
for (i = 0U; i < mempool_idx; i++) {
if (mempool[i].pnt == pnt) {
if ((mempool[i].size & (size_t) 0x80000000) != (size_t) 0x0) {
break;
}
mempool[i].size |= (size_t) 0x80000000;
return;
}
}
abort();
}
static __attribute__((malloc)) void *mempool_allocarray(size_t count, size_t size)
{
if (count > (size_t) 0U && size >= (size_t) SIZE_MAX / count) {
return NULL;
}
return mempool_alloc(count * size);
}
static int mempool_free_all(void)
{
size_t i;
int ret = 0;
for (i = 0U; i < mempool_idx; i++) {
if ((mempool[i].size & (size_t) 0x80000000) == (size_t) 0x0) {
ret = -1;
}
free(mempool[i].pnt);
mempool[i].pnt = NULL;
}
mempool_idx = (size_t) 0U;
return ret;
}
#define sodium_malloc(X) mempool_alloc(X)
#define sodium_free(X) mempool_free(X)
#define sodium_allocarray(X, Y) mempool_allocarray((X), (Y))
static unsigned long long now(void)
{
struct timeval tp;
unsigned long long now;
if (gettimeofday(&tp, NULL) != 0) {
abort();
}
now = ((unsigned long long) tp.tv_sec * 1000000ULL) +
(unsigned long long) tp.tv_usec;
return now;
}
int main(void)
{
unsigned long long ts_start;
unsigned long long ts_end;
unsigned int i;
(void) set_resource_limits();
if (sodium_init() != 0) {
return 99;
}
#ifndef __EMSCRIPTEN__
randombytes_set_implementation(&randombytes_salsa20_implementation);
#endif
ts_start = now();
for (i = 0; i < ITERATIONS; i++) {
if (xmain() != 0) {
abort();
}
}
ts_end = now();
printf("%llu\n", 1000000ULL * (ts_end - ts_start) / ITERATIONS);
if (mempool_free_all() != 0) {
fprintf(stderr, "** memory leaks detected **\n");
return 99;
}
return 0;
}
#undef printf
#define printf(...) do { } while(0)
#elif !defined(BROWSER_TESTS)
static FILE *fp_res;
int main(void)
{
FILE *fp_out;
unsigned char *_guard_page;
int c;
(void) set_resource_limits();
if ((fp_res = fopen(TEST_NAME_RES, "w+")) == NULL) {
perror("fopen(" TEST_NAME_RES ")");
return 99;
}
if (sodium_init() != 0) {
return 99;
}
# if defined(__EMSCRIPTEN__) || defined(__SANITIZE_ADDRESS__)
guard_page = _guard_page = NULL;
#else
if ((_guard_page = (unsigned char *) sodium_malloc(0)) == NULL) {
perror("sodium_malloc()");
return 99;
}
guard_page = _guard_page + 1;
#endif
if (xmain() != 0) {
return 99;
}
rewind(fp_res);
if ((fp_out = fopen(TEST_NAME_OUT, "r")) == NULL) {
perror("fopen(" TEST_NAME_OUT ")");
return 99;
}
do {
if ((c = fgetc(fp_res)) != fgetc(fp_out)) {
return 99;
}
} while (c != EOF);
sodium_free(_guard_page);
return 0;
}
#undef printf
#define printf(...) fprintf(fp_res, __VA_ARGS__)
#else
int main(void)
{
if (sodium_init() != 0) {
return 99;
}
if (xmain() != 0) {
return 99;
}
printf("--- SUCCESS ---\n");
return 0;
}
#endif
#define main xmain
#endif