test/test_buffer.cpp

Sat, 30 Apr 2022 09:47:20 +0200

author
Mike Becker <universe@uap-core.de>
date
Sat, 30 Apr 2022 09:47:20 +0200
changeset 539
9cd98da9ee17
parent 538
2cfbcbe86a7c
child 541
67e078518935
permissions
-rw-r--r--

#184 start implementation of the flush feature

universe@530 1 /*
universe@530 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
universe@530 3 *
universe@530 4 * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved.
universe@530 5 *
universe@530 6 * Redistribution and use in source and binary forms, with or without
universe@530 7 * modification, are permitted provided that the following conditions are met:
universe@530 8 *
universe@530 9 * 1. Redistributions of source code must retain the above copyright
universe@530 10 * notice, this list of conditions and the following disclaimer.
universe@530 11 *
universe@530 12 * 2. Redistributions in binary form must reproduce the above copyright
universe@530 13 * notice, this list of conditions and the following disclaimer in the
universe@530 14 * documentation and/or other materials provided with the distribution.
universe@530 15 *
universe@530 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
universe@530 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
universe@530 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
universe@530 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
universe@530 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
universe@530 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
universe@530 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
universe@530 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
universe@530 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
universe@530 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
universe@530 26 * POSSIBILITY OF SUCH DAMAGE.
universe@530 27 */
universe@530 28
universe@530 29 #include "cx/buffer.h"
universe@530 30
universe@530 31 #include <gtest/gtest.h>
universe@530 32 #include "util_allocator.h"
universe@530 33
universe@539 34 static void expect_default_flush_config(CxBuffer *buf) {
universe@539 35 EXPECT_EQ(buf->flush_blkmax, 0);
universe@539 36 EXPECT_EQ(buf->flush_blksize, 4096);
universe@539 37 EXPECT_EQ(buf->flush_threshold, SIZE_MAX);
universe@539 38 EXPECT_EQ(buf->flush_func, nullptr);
universe@539 39 }
universe@539 40
universe@535 41 TEST(BufferInit, WrapSpace) {
universe@535 42 CxTestingAllocator alloc;
universe@530 43 CxBuffer buf;
universe@535 44 void *space = cxMalloc(&alloc, 16);
universe@535 45 cxBufferInit(&buf, space, 16, &alloc, CX_BUFFER_DEFAULT);
universe@539 46 expect_default_flush_config(&buf);
universe@530 47 EXPECT_EQ(buf.space, space);
universe@530 48 EXPECT_EQ(buf.flags & CX_BUFFER_AUTO_EXTEND, 0);
universe@530 49 EXPECT_EQ(buf.flags & CX_BUFFER_FREE_CONTENTS, 0);
universe@530 50 EXPECT_EQ(buf.pos, 0);
universe@530 51 EXPECT_EQ(buf.size, 0);
universe@530 52 EXPECT_EQ(buf.capacity, 16);
universe@535 53 EXPECT_EQ(buf.allocator, &alloc);
universe@530 54 cxBufferDestroy(&buf);
universe@535 55 EXPECT_FALSE(alloc.verify());
universe@535 56 cxFree(&alloc, space);
universe@535 57 EXPECT_TRUE(alloc.verify());
universe@530 58 }
universe@530 59
universe@539 60 TEST(BufferInit, WrapSpaceAutoExtend) {
universe@539 61 CxTestingAllocator alloc;
universe@539 62 CxBuffer buf;
universe@539 63 void *space = cxMalloc(&alloc, 16);
universe@539 64 cxBufferInit(&buf, space, 16, &alloc, CX_BUFFER_AUTO_EXTEND);
universe@539 65 expect_default_flush_config(&buf);
universe@539 66 EXPECT_EQ(buf.space, space);
universe@539 67 EXPECT_EQ(buf.flags & CX_BUFFER_AUTO_EXTEND, CX_BUFFER_AUTO_EXTEND);
universe@539 68 EXPECT_EQ(buf.flags & CX_BUFFER_FREE_CONTENTS, 0);
universe@539 69 EXPECT_EQ(buf.pos, 0);
universe@539 70 EXPECT_EQ(buf.size, 0);
universe@539 71 EXPECT_EQ(buf.capacity, 16);
universe@539 72 EXPECT_EQ(buf.allocator, &alloc);
universe@539 73 cxBufferDestroy(&buf);
universe@539 74 EXPECT_FALSE(alloc.verify());
universe@539 75 cxFree(&alloc, space);
universe@539 76 EXPECT_TRUE(alloc.verify());
universe@539 77 }
universe@539 78
universe@535 79 TEST(BufferInit, WrapSpaceAutoFree) {
universe@535 80 CxTestingAllocator alloc;
universe@530 81 CxBuffer buf;
universe@535 82 void *space = cxMalloc(&alloc, 16);
universe@535 83 cxBufferInit(&buf, space, 16, &alloc, CX_BUFFER_FREE_CONTENTS);
universe@539 84 expect_default_flush_config(&buf);
universe@530 85 EXPECT_EQ(buf.space, space);
universe@530 86 EXPECT_EQ(buf.flags & CX_BUFFER_AUTO_EXTEND, 0);
universe@530 87 EXPECT_EQ(buf.flags & CX_BUFFER_FREE_CONTENTS, CX_BUFFER_FREE_CONTENTS);
universe@530 88 EXPECT_EQ(buf.pos, 0);
universe@530 89 EXPECT_EQ(buf.size, 0);
universe@530 90 EXPECT_EQ(buf.capacity, 16);
universe@535 91 EXPECT_EQ(buf.allocator, &alloc);
universe@535 92 EXPECT_FALSE(alloc.verify());
universe@530 93 cxBufferDestroy(&buf);
universe@535 94 EXPECT_TRUE(alloc.verify());
universe@530 95 }
universe@535 96
universe@535 97 TEST(BufferInit, FreshSpace) {
universe@535 98 CxTestingAllocator alloc;
universe@535 99 CxBuffer buf;
universe@535 100 cxBufferInit(&buf, nullptr, 8, &alloc, CX_BUFFER_DEFAULT);
universe@539 101 expect_default_flush_config(&buf);
universe@535 102 EXPECT_NE(buf.space, nullptr);
universe@535 103 EXPECT_EQ(buf.flags & CX_BUFFER_AUTO_EXTEND, 0);
universe@535 104 EXPECT_EQ(buf.flags & CX_BUFFER_FREE_CONTENTS, CX_BUFFER_FREE_CONTENTS);
universe@535 105 EXPECT_EQ(buf.pos, 0);
universe@535 106 EXPECT_EQ(buf.size, 0);
universe@535 107 EXPECT_EQ(buf.capacity, 8);
universe@535 108 EXPECT_EQ(buf.allocator, &alloc);
universe@535 109 EXPECT_FALSE(alloc.verify()); // space is still allocated
universe@535 110 cxBufferDestroy(&buf);
universe@535 111 EXPECT_TRUE(alloc.verify());
universe@535 112 }
universe@535 113
universe@535 114 class BufferShiftFixture : public ::testing::Test {
universe@535 115 protected:
universe@535 116 void SetUp() override {
universe@535 117 ASSERT_TRUE(alloc.verify());
universe@535 118 cxBufferInit(&buf, nullptr, 16, &alloc, CX_BUFFER_DEFAULT);
universe@535 119 memcpy(buf.space, "test____________", 16);
universe@535 120 buf.capacity = 8; // purposely pretend that the buffer has less capacity s.t. we can test beyond the range
universe@535 121 buf.pos = 4;
universe@535 122 buf.size = 4;
universe@535 123 }
universe@535 124
universe@535 125 void TearDown() override {
universe@535 126 cxBufferDestroy(&buf);
universe@535 127 EXPECT_TRUE(alloc.verify());
universe@535 128 }
universe@535 129
universe@535 130 CxTestingAllocator alloc;
universe@535 131 CxBuffer buf{};
universe@535 132 };
universe@535 133
universe@535 134 class BufferShiftLeft : public BufferShiftFixture {
universe@535 135 };
universe@535 136
universe@535 137 TEST_F(BufferShiftLeft, Zero) {
universe@535 138 ASSERT_EQ(buf.pos, 4);
universe@535 139 ASSERT_EQ(buf.size, 4);
universe@535 140 int ret = cxBufferShiftLeft(&buf, 0);
universe@535 141 EXPECT_EQ(ret, 0);
universe@535 142 EXPECT_EQ(buf.pos, 4);
universe@535 143 EXPECT_EQ(buf.size, 4);
universe@535 144 EXPECT_TRUE(memcmp(buf.space, "test________", 8) == 0);
universe@535 145 }
universe@535 146
universe@535 147 TEST_F(BufferShiftLeft, Standard) {
universe@535 148 ASSERT_EQ(buf.pos, 4);
universe@535 149 ASSERT_EQ(buf.size, 4);
universe@535 150 int ret = cxBufferShiftLeft(&buf, 2);
universe@535 151 EXPECT_EQ(ret, 0);
universe@535 152 EXPECT_EQ(buf.pos, 2);
universe@535 153 EXPECT_EQ(buf.size, 2);
universe@535 154 EXPECT_TRUE(memcmp(buf.space, "stst________", 8) == 0);
universe@535 155 }
universe@535 156
universe@535 157 TEST_F(BufferShiftLeft, Overshift) {
universe@535 158 ASSERT_LT(buf.pos, 6);
universe@535 159 ASSERT_LT(buf.size, 6);
universe@535 160 int ret = cxBufferShiftLeft(&buf, 6);
universe@535 161 EXPECT_EQ(ret, 0);
universe@535 162 EXPECT_EQ(buf.pos, 0);
universe@535 163 EXPECT_EQ(buf.size, 0);
universe@535 164 EXPECT_TRUE(memcmp(buf.space, "test________", 8) == 0);
universe@535 165 }
universe@535 166
universe@535 167 TEST_F(BufferShiftLeft, OvershiftPosOnly) {
universe@535 168 buf.pos = 2;
universe@535 169 ASSERT_EQ(buf.size, 4);
universe@535 170 int ret = cxBufferShiftLeft(&buf, 3);
universe@535 171 EXPECT_EQ(ret, 0);
universe@535 172 EXPECT_EQ(buf.pos, 0);
universe@535 173 EXPECT_EQ(buf.size, 1);
universe@535 174 EXPECT_TRUE(memcmp(buf.space, "test________", 8) == 0);
universe@535 175 }
universe@535 176
universe@535 177 TEST_F(BufferShiftLeft, OffsetInterface) {
universe@535 178 buf.pos = 3;
universe@535 179 ASSERT_EQ(buf.size, 4);
universe@535 180 int ret = cxBufferShift(&buf, -2);
universe@535 181 EXPECT_EQ(ret, 0);
universe@535 182 EXPECT_EQ(buf.pos, 1);
universe@535 183 EXPECT_EQ(buf.size, 2);
universe@535 184 EXPECT_TRUE(memcmp(buf.space, "stst________", 8) == 0);
universe@535 185 }
universe@535 186
universe@535 187 class BufferShiftRight : public BufferShiftFixture {
universe@535 188 };
universe@535 189
universe@535 190 TEST_F(BufferShiftRight, Zero) {
universe@535 191 ASSERT_EQ(buf.pos, 4);
universe@535 192 ASSERT_EQ(buf.size, 4);
universe@535 193 int ret = cxBufferShiftRight(&buf, 0);
universe@535 194 EXPECT_EQ(ret, 0);
universe@535 195 EXPECT_EQ(buf.pos, 4);
universe@535 196 EXPECT_EQ(buf.size, 4);
universe@535 197 EXPECT_TRUE(memcmp(buf.space, "test________", 8) == 0);
universe@535 198 }
universe@535 199
universe@535 200 TEST_F(BufferShiftRight, Standard) {
universe@535 201 ASSERT_EQ(buf.pos, 4);
universe@535 202 ASSERT_EQ(buf.size, 4);
universe@535 203 int ret = cxBufferShiftRight(&buf, 3);
universe@535 204 EXPECT_EQ(ret, 0);
universe@535 205 EXPECT_EQ(buf.pos, 7);
universe@535 206 EXPECT_EQ(buf.size, 7);
universe@535 207 EXPECT_TRUE(memcmp(buf.space, "testest_____", 8) == 0);
universe@535 208 }
universe@535 209
universe@535 210 TEST_F(BufferShiftRight, OvershiftDiscard) {
universe@535 211 ASSERT_EQ(buf.pos, 4);
universe@535 212 ASSERT_EQ(buf.size, 4);
universe@535 213 ASSERT_EQ(buf.capacity, 8);
universe@535 214 int ret = cxBufferShiftRight(&buf, 6);
universe@535 215 EXPECT_EQ(ret, 0);
universe@535 216 EXPECT_EQ(buf.pos, 8);
universe@535 217 EXPECT_EQ(buf.size, 8);
universe@535 218 EXPECT_EQ(buf.capacity, 8);
universe@535 219 EXPECT_TRUE(memcmp(buf.space, "test__te____", 8) == 0);
universe@535 220 }
universe@535 221
universe@535 222 TEST_F(BufferShiftRight, OvershiftExtend) {
universe@535 223 ASSERT_EQ(buf.pos, 4);
universe@535 224 ASSERT_EQ(buf.size, 4);
universe@535 225 ASSERT_EQ(buf.capacity, 8);
universe@535 226 buf.flags |= CX_BUFFER_AUTO_EXTEND;
universe@535 227 int ret = cxBufferShiftRight(&buf, 6);
universe@535 228 EXPECT_EQ(ret, 0);
universe@535 229 EXPECT_EQ(buf.pos, 10);
universe@535 230 EXPECT_EQ(buf.size, 10);
universe@535 231 EXPECT_GE(buf.capacity, 10);
universe@535 232 EXPECT_TRUE(memcmp(buf.space, "test__test__", 8) == 0);
universe@535 233 }
universe@535 234
universe@535 235 TEST_F(BufferShiftRight, OffsetInterface) {
universe@535 236 buf.pos = 3;
universe@535 237 ASSERT_EQ(buf.size, 4);
universe@535 238 int ret = cxBufferShift(&buf, 2);
universe@535 239 EXPECT_EQ(ret, 0);
universe@535 240 EXPECT_EQ(buf.pos, 5);
universe@535 241 EXPECT_EQ(buf.size, 6);
universe@535 242 EXPECT_TRUE(memcmp(buf.space, "tetest______", 8) == 0);
universe@535 243 }
universe@535 244
universe@535 245 TEST(BufferMinimumCapacity, Sufficient) {
universe@535 246 CxTestingAllocator alloc;
universe@535 247 auto space = cxMalloc(&alloc, 8);
universe@535 248 CxBuffer buf;
universe@535 249 cxBufferInit(&buf, space, 8, &alloc, CX_BUFFER_FREE_CONTENTS);
universe@535 250 memcpy(space, "Testing", 8);
universe@535 251 buf.size = 8;
universe@535 252 cxBufferMinimumCapacity(&buf, 6);
universe@535 253 EXPECT_EQ(buf.capacity, 8);
universe@535 254 EXPECT_EQ(buf.size, 8);
universe@535 255 EXPECT_TRUE(memcmp(buf.space, "Testing", 8) == 0);
universe@535 256 cxBufferDestroy(&buf);
universe@535 257 EXPECT_TRUE(alloc.verify());
universe@535 258 }
universe@535 259
universe@535 260 TEST(BufferMinimumCapacity, Extend) {
universe@535 261 CxTestingAllocator alloc;
universe@535 262 auto space = cxMalloc(&alloc, 8);
universe@535 263 CxBuffer buf;
universe@535 264 cxBufferInit(&buf, space, 8, &alloc, CX_BUFFER_FREE_CONTENTS); // NO auto extend!
universe@535 265 memcpy(space, "Testing", 8);
universe@535 266 buf.size = 8;
universe@535 267 cxBufferMinimumCapacity(&buf, 16);
universe@535 268 EXPECT_EQ(buf.capacity, 16);
universe@535 269 EXPECT_EQ(buf.size, 8);
universe@535 270 EXPECT_TRUE(memcmp(buf.space, "Testing", 8) == 0);
universe@535 271 cxBufferDestroy(&buf);
universe@535 272 EXPECT_TRUE(alloc.verify());
universe@535 273 }
universe@536 274
universe@536 275 TEST(BufferClear, Test) {
universe@536 276 char space[16];
universe@536 277 strcpy(space, "clear test");
universe@536 278 CxBuffer buf;
universe@536 279 cxBufferInit(&buf, space, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
universe@536 280 ASSERT_EQ(buf.size, 0);
universe@536 281 // only clear the used part of the buffer
universe@536 282 cxBufferClear(&buf);
universe@536 283 EXPECT_EQ(memcmp(space, "clear test", 10), 0);
universe@536 284 buf.size = 5;
universe@536 285 buf.pos = 3;
universe@536 286 cxBufferClear(&buf);
universe@536 287 EXPECT_EQ(memcmp(space, "\0\0\0\0\0 test", 10), 0);
universe@536 288 EXPECT_EQ(buf.size, 0);
universe@536 289 EXPECT_EQ(buf.pos, 0);
universe@538 290 cxBufferDestroy(&buf);
universe@536 291 }
universe@538 292
universe@538 293 class BufferWrite : public ::testing::Test {
universe@538 294 protected:
universe@538 295 CxBuffer buf{};
universe@538 296
universe@538 297 void SetUp() override {
universe@538 298 cxBufferInit(&buf, nullptr, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
universe@538 299 buf.capacity = 8; // artificially reduce capacity to check OOB writes
universe@538 300 memset(buf.space, 0, 16);
universe@538 301 memcpy(buf.space, "prep", 4);
universe@538 302 buf.size = buf.pos = 4;
universe@538 303 }
universe@538 304
universe@538 305 void TearDown() override {
universe@538 306 cxBufferDestroy(&buf);
universe@538 307 }
universe@538 308 };
universe@538 309
universe@538 310 TEST_F(BufferWrite, SizeOneFit) {
universe@538 311 const char *data = "test";
universe@538 312 ASSERT_EQ(buf.capacity, 8);
universe@538 313 ASSERT_EQ(buf.pos, 4);
universe@538 314 size_t written = cxBufferWrite(data, 1, 4, &buf);
universe@538 315 EXPECT_EQ(written, 4);
universe@538 316 EXPECT_EQ(buf.size, 8);
universe@538 317 EXPECT_EQ(buf.pos, 8);
universe@538 318 EXPECT_EQ(buf.capacity, 8);
universe@538 319 EXPECT_EQ(memcmp(buf.space, "preptest", 8), 0);
universe@538 320 }
universe@538 321
universe@538 322 TEST_F(BufferWrite, SizeOneOverwrite) {
universe@538 323
universe@538 324 }
universe@538 325
universe@538 326 TEST_F(BufferWrite, SizeOnePartialOverwrite) {
universe@538 327
universe@538 328 }
universe@538 329
universe@538 330 TEST_F(BufferWrite, SizeOneDiscard) {
universe@538 331 const char *data = "testing";
universe@538 332 ASSERT_EQ(buf.capacity, 8);
universe@538 333 ASSERT_EQ(buf.pos, 4);
universe@538 334 size_t written = cxBufferWrite(data, 1, 7, &buf);
universe@538 335 EXPECT_EQ(written, 4);
universe@538 336 EXPECT_EQ(buf.size, 8);
universe@538 337 EXPECT_EQ(buf.pos, 8);
universe@538 338 EXPECT_EQ(buf.capacity, 8);
universe@538 339 EXPECT_EQ(memcmp(buf.space, "preptest\0", 9), 0);
universe@538 340 }
universe@538 341
universe@538 342 TEST_F(BufferWrite, SizeOneExtend) {
universe@538 343 buf.flags |= CX_BUFFER_AUTO_EXTEND;
universe@538 344 const char *data = "testing";
universe@538 345 ASSERT_EQ(buf.capacity, 8);
universe@538 346 ASSERT_EQ(buf.pos, 4);
universe@538 347 size_t written = cxBufferWrite(data, 1, 7, &buf);
universe@538 348 EXPECT_EQ(written, 7);
universe@538 349 EXPECT_EQ(buf.size, 11);
universe@538 350 EXPECT_EQ(buf.pos, 11);
universe@538 351 EXPECT_GE(buf.capacity, 11);
universe@538 352 EXPECT_EQ(memcmp(buf.space, "preptesting", 11), 0);
universe@538 353 }
universe@538 354
universe@538 355 TEST_F(BufferWrite, MultibyteOverwrite) {
universe@538 356
universe@538 357 }
universe@538 358
universe@538 359 TEST_F(BufferWrite, MultibytePartialOverwrite) {
universe@538 360
universe@538 361 }
universe@538 362
universe@538 363 TEST_F(BufferWrite, MultibyteFit) {
universe@538 364
universe@538 365 }
universe@538 366
universe@538 367 TEST_F(BufferWrite, MultibyteDiscard) {
universe@538 368 // remember: whole elements are discarded if they do not fit
universe@538 369 }
universe@538 370
universe@538 371 TEST_F(BufferWrite, MultibyteExtend) {
universe@538 372
universe@538 373 }
universe@538 374
universe@538 375 TEST_F(BufferWrite, PutcWrapperFit) {
universe@538 376
universe@538 377 }
universe@538 378
universe@538 379 TEST_F(BufferWrite, PutcWrapperOverwrite) {
universe@538 380
universe@538 381 }
universe@538 382
universe@538 383 TEST_F(BufferWrite, PutcWrapperPartialOverwrite) {
universe@538 384
universe@538 385 }
universe@538 386
universe@538 387 TEST_F(BufferWrite, PutcWrapperDiscard) {
universe@538 388
universe@538 389 }
universe@538 390
universe@538 391 TEST_F(BufferWrite, PutcWrapperExtend) {
universe@538 392
universe@538 393 }
universe@538 394
universe@538 395 TEST_F(BufferWrite, PutStringWrapperFit) {
universe@538 396
universe@538 397 }
universe@538 398
universe@538 399 TEST_F(BufferWrite, PutStringWrapperOverwrite) {
universe@538 400
universe@538 401 }
universe@538 402
universe@538 403 TEST_F(BufferWrite, PutStringWrapperPartialOverwrite) {
universe@538 404
universe@538 405 }
universe@538 406
universe@538 407 TEST_F(BufferWrite, PutStringWrapperDiscard) {
universe@538 408
universe@538 409 }
universe@538 410
universe@538 411 TEST_F(BufferWrite, PutStringWrapperExtend) {
universe@538 412
universe@538 413 }

mercurial