test-buffer.c revision dd8a8566def603776cc102ec86906556b8bd5b0a
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen/* Copyright (c) 2007-2014 Dovecot authors, see the included COPYING file */
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen#include "test-lib.h"
2423da95ee20fd4b3c260c1389cf2952d25f099cTimo Sirainen#include "buffer.h"
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#include <stdlib.h>
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenvoid test_buffer(void)
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen{
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen#define BUF_TEST_SIZE (1024*2)
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen#define BUF_TEST_COUNT 1000
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen buffer_t *buf;
ef50336eefcb9ba99f73c6af37420eaf8857a39bTimo Sirainen unsigned char *p, testdata[BUF_TEST_SIZE], shadowbuf[BUF_TEST_SIZE];
ef50336eefcb9ba99f73c6af37420eaf8857a39bTimo Sirainen unsigned int i, shadowbuf_size;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen size_t pos, pos2, size;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen int test = -1;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen bool zero;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen buf = buffer_create_dynamic(default_pool, 1);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen for (i = 0; i < BUF_TEST_SIZE; i++)
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen testdata[i] = rand();
533bfba437e4120aa29dd45bca2aa87e30ee28a2Timo Sirainen memset(shadowbuf, 0, sizeof(shadowbuf));
533bfba437e4120aa29dd45bca2aa87e30ee28a2Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen shadowbuf_size = 0;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen for (i = 0; i < BUF_TEST_COUNT; i++) {
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen if (buf->used == BUF_TEST_SIZE) {
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen size = shadowbuf_size = rand() % (buf->used - 1);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen buffer_set_used_size(buf, size);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen memset(shadowbuf + shadowbuf_size, 0,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen BUF_TEST_SIZE - shadowbuf_size);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen i_assert(buf->used < BUF_TEST_SIZE);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen }
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen test = rand() % 6;
c040ee67d0ac0fb7375bb543965bf67dcae6affaTimo Sirainen zero = rand() % 10 == 0;
533bfba437e4120aa29dd45bca2aa87e30ee28a2Timo Sirainen switch (test) {
533bfba437e4120aa29dd45bca2aa87e30ee28a2Timo Sirainen case 0:
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen pos = rand() % (BUF_TEST_SIZE-1);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen size = rand() % (BUF_TEST_SIZE - pos);
d92f33f13830ba23d814342bf3ea8db721a15bb1Timo Sirainen if (!zero) {
d92f33f13830ba23d814342bf3ea8db721a15bb1Timo Sirainen buffer_write(buf, pos, testdata, size);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen memcpy(shadowbuf + pos, testdata, size);
61e84692827b6a64912343f515c984853021483aTimo Sirainen } else {
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen buffer_write_zero(buf, pos, size);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen memset(shadowbuf + pos, 0, size);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen }
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen if (pos + size > shadowbuf_size)
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen shadowbuf_size = pos + size;
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen break;
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen case 1:
7230352f1177a8ed2b924c6992e751fd2ab9bc27Timo Sirainen size = rand() % (BUF_TEST_SIZE - buf->used);
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen if (!zero) {
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen buffer_append(buf, testdata, size);
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen memcpy(shadowbuf + shadowbuf_size,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen testdata, size);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen } else {
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen buffer_append_zero(buf, size);
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainen memset(shadowbuf + shadowbuf_size, 0, size);
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainen }
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainen shadowbuf_size += size;
0e5f8c4589cfeccb752307c8ac35a2f1633e4ecaTimo Sirainen break;
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainen case 2:
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainen pos = rand() % (BUF_TEST_SIZE-1);
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainen size = rand() % (BUF_TEST_SIZE - I_MAX(buf->used, pos));
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainen if (!zero) {
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen buffer_insert(buf, pos, testdata, size);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen memmove(shadowbuf + pos + size,
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen shadowbuf + pos,
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen BUF_TEST_SIZE - (pos + size));
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen memcpy(shadowbuf + pos, testdata, size);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen } else {
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen buffer_insert_zero(buf, pos, size);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen memmove(shadowbuf + pos + size,
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen shadowbuf + pos,
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen BUF_TEST_SIZE - (pos + size));
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen memset(shadowbuf + pos, 0, size);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen }
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen if (pos < shadowbuf_size)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen shadowbuf_size += size;
bbd0a870f8639767e4e4011d2aedadac08d5c66fTimo Sirainen else
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen shadowbuf_size = pos + size;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen break;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen case 3:
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen pos = rand() % (BUF_TEST_SIZE-1);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen size = rand() % (BUF_TEST_SIZE - pos);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen buffer_delete(buf, pos, size);
c58906589cafc32df4c04ffbef933baadd3f2276Timo Sirainen if (pos < shadowbuf_size) {
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen if (pos + size > shadowbuf_size)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen size = shadowbuf_size - pos;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen memmove(shadowbuf + pos,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen shadowbuf + pos + size,
d02d34e138e32b4266f5a403d6c51d7803bf322fTimo Sirainen BUF_TEST_SIZE - (pos + size));
106b804c819443791f1324f8bbe34429eeea6a13Timo Sirainen
d02d34e138e32b4266f5a403d6c51d7803bf322fTimo Sirainen shadowbuf_size -= size;
5694eeb99b69dea8033ca77ad69743c6b4871370Timo Sirainen memset(shadowbuf + shadowbuf_size, 0,
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen BUF_TEST_SIZE - shadowbuf_size);
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen }
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen break;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen case 4:
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen if (shadowbuf_size == 0)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen break;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen pos = rand() % (shadowbuf_size-1); /* dest */
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen pos2 = rand() % (shadowbuf_size-1); /* source */
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen size = rand() % (shadowbuf_size - I_MAX(pos, pos2));
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen buffer_copy(buf, pos, buf, pos2, size);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen memmove(shadowbuf + pos,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen shadowbuf + pos2, size);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen if (pos > pos2 && pos + size > shadowbuf_size)
4366a21968093172d9b757fe6894b1ee8916434eTimo Sirainen shadowbuf_size = pos + size;
4366a21968093172d9b757fe6894b1ee8916434eTimo Sirainen break;
4366a21968093172d9b757fe6894b1ee8916434eTimo Sirainen case 5:
4366a21968093172d9b757fe6894b1ee8916434eTimo Sirainen pos = rand() % (BUF_TEST_SIZE-1);
4366a21968093172d9b757fe6894b1ee8916434eTimo Sirainen size = rand() % (BUF_TEST_SIZE - pos);
4366a21968093172d9b757fe6894b1ee8916434eTimo Sirainen p = buffer_get_space_unsafe(buf, pos, size);
4366a21968093172d9b757fe6894b1ee8916434eTimo Sirainen memcpy(p, testdata, size);
4366a21968093172d9b757fe6894b1ee8916434eTimo Sirainen memcpy(shadowbuf + pos, testdata, size);
4366a21968093172d9b757fe6894b1ee8916434eTimo Sirainen if (pos + size > shadowbuf_size)
4366a21968093172d9b757fe6894b1ee8916434eTimo Sirainen shadowbuf_size = pos + size;
4366a21968093172d9b757fe6894b1ee8916434eTimo Sirainen break;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen }
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen i_assert(shadowbuf_size <= BUF_TEST_SIZE);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen if (buf->used != shadowbuf_size ||
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen memcmp(buf->data, shadowbuf, buf->used) != 0)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen break;
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen }
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen if (i == BUF_TEST_COUNT)
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen test_out("buffer", TRUE);
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen else {
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen test_out_reason("buffer", FALSE,
96f2533c48ce5def0004931606a2fdf275578880Timo Sirainen t_strdup_printf("round %u test %d failed", i, test));
4645cc6c911a95991d7af43b40f88e99506ea5e9Timo Sirainen }
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen buffer_free(&buf);
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen}
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen