test/test_buffer.cpp

Mon, 25 Jul 2022 15:29:56 +0200

author
Mike Becker <universe@uap-core.de>
date
Mon, 25 Jul 2022 15:29:56 +0200
changeset 567
f90a7cfe2480
parent 566
d3100c987a39
child 568
8eda32d09e3d
permissions
-rw-r--r--

#184 #170 more thorough flush testing

Also adds proper doc for write function.

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@548 34 class BufferFixture : public ::testing::Test {
universe@548 35 protected:
universe@548 36 void SetUp() override {
universe@548 37 cxBufferInit(&buf, nullptr, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
universe@548 38 buf.size = 6;
universe@548 39 buf.pos = 3;
universe@548 40 }
universe@548 41
universe@548 42 void TearDown() override {
universe@548 43 cxBufferDestroy(&buf);
universe@548 44 }
universe@548 45
universe@548 46 CxBuffer buf{};
universe@548 47 };
universe@548 48
universe@539 49 static void expect_default_flush_config(CxBuffer *buf) {
universe@539 50 EXPECT_EQ(buf->flush_blkmax, 0);
universe@539 51 EXPECT_EQ(buf->flush_blksize, 4096);
universe@539 52 EXPECT_EQ(buf->flush_threshold, SIZE_MAX);
universe@539 53 EXPECT_EQ(buf->flush_func, nullptr);
universe@541 54 EXPECT_EQ(buf->flush_target, nullptr);
universe@539 55 }
universe@539 56
universe@535 57 TEST(BufferInit, WrapSpace) {
universe@535 58 CxTestingAllocator alloc;
universe@530 59 CxBuffer buf;
universe@535 60 void *space = cxMalloc(&alloc, 16);
universe@535 61 cxBufferInit(&buf, space, 16, &alloc, CX_BUFFER_DEFAULT);
universe@539 62 expect_default_flush_config(&buf);
universe@530 63 EXPECT_EQ(buf.space, space);
universe@530 64 EXPECT_EQ(buf.flags & CX_BUFFER_AUTO_EXTEND, 0);
universe@530 65 EXPECT_EQ(buf.flags & CX_BUFFER_FREE_CONTENTS, 0);
universe@530 66 EXPECT_EQ(buf.pos, 0);
universe@530 67 EXPECT_EQ(buf.size, 0);
universe@530 68 EXPECT_EQ(buf.capacity, 16);
universe@535 69 EXPECT_EQ(buf.allocator, &alloc);
universe@530 70 cxBufferDestroy(&buf);
universe@535 71 EXPECT_FALSE(alloc.verify());
universe@535 72 cxFree(&alloc, space);
universe@535 73 EXPECT_TRUE(alloc.verify());
universe@530 74 }
universe@530 75
universe@539 76 TEST(BufferInit, WrapSpaceAutoExtend) {
universe@539 77 CxTestingAllocator alloc;
universe@539 78 CxBuffer buf;
universe@539 79 void *space = cxMalloc(&alloc, 16);
universe@539 80 cxBufferInit(&buf, space, 16, &alloc, CX_BUFFER_AUTO_EXTEND);
universe@539 81 expect_default_flush_config(&buf);
universe@539 82 EXPECT_EQ(buf.space, space);
universe@539 83 EXPECT_EQ(buf.flags & CX_BUFFER_AUTO_EXTEND, CX_BUFFER_AUTO_EXTEND);
universe@539 84 EXPECT_EQ(buf.flags & CX_BUFFER_FREE_CONTENTS, 0);
universe@539 85 EXPECT_EQ(buf.pos, 0);
universe@539 86 EXPECT_EQ(buf.size, 0);
universe@539 87 EXPECT_EQ(buf.capacity, 16);
universe@539 88 EXPECT_EQ(buf.allocator, &alloc);
universe@539 89 cxBufferDestroy(&buf);
universe@539 90 EXPECT_FALSE(alloc.verify());
universe@539 91 cxFree(&alloc, space);
universe@539 92 EXPECT_TRUE(alloc.verify());
universe@539 93 }
universe@539 94
universe@535 95 TEST(BufferInit, WrapSpaceAutoFree) {
universe@535 96 CxTestingAllocator alloc;
universe@530 97 CxBuffer buf;
universe@535 98 void *space = cxMalloc(&alloc, 16);
universe@535 99 cxBufferInit(&buf, space, 16, &alloc, CX_BUFFER_FREE_CONTENTS);
universe@539 100 expect_default_flush_config(&buf);
universe@530 101 EXPECT_EQ(buf.space, space);
universe@530 102 EXPECT_EQ(buf.flags & CX_BUFFER_AUTO_EXTEND, 0);
universe@530 103 EXPECT_EQ(buf.flags & CX_BUFFER_FREE_CONTENTS, CX_BUFFER_FREE_CONTENTS);
universe@530 104 EXPECT_EQ(buf.pos, 0);
universe@530 105 EXPECT_EQ(buf.size, 0);
universe@530 106 EXPECT_EQ(buf.capacity, 16);
universe@535 107 EXPECT_EQ(buf.allocator, &alloc);
universe@535 108 EXPECT_FALSE(alloc.verify());
universe@530 109 cxBufferDestroy(&buf);
universe@535 110 EXPECT_TRUE(alloc.verify());
universe@530 111 }
universe@535 112
universe@535 113 TEST(BufferInit, FreshSpace) {
universe@535 114 CxTestingAllocator alloc;
universe@535 115 CxBuffer buf;
universe@535 116 cxBufferInit(&buf, nullptr, 8, &alloc, CX_BUFFER_DEFAULT);
universe@539 117 expect_default_flush_config(&buf);
universe@535 118 EXPECT_NE(buf.space, nullptr);
universe@535 119 EXPECT_EQ(buf.flags & CX_BUFFER_AUTO_EXTEND, 0);
universe@535 120 EXPECT_EQ(buf.flags & CX_BUFFER_FREE_CONTENTS, CX_BUFFER_FREE_CONTENTS);
universe@535 121 EXPECT_EQ(buf.pos, 0);
universe@535 122 EXPECT_EQ(buf.size, 0);
universe@535 123 EXPECT_EQ(buf.capacity, 8);
universe@535 124 EXPECT_EQ(buf.allocator, &alloc);
universe@535 125 EXPECT_FALSE(alloc.verify()); // space is still allocated
universe@535 126 cxBufferDestroy(&buf);
universe@535 127 EXPECT_TRUE(alloc.verify());
universe@535 128 }
universe@535 129
universe@535 130 class BufferShiftFixture : public ::testing::Test {
universe@535 131 protected:
universe@535 132 void SetUp() override {
universe@535 133 ASSERT_TRUE(alloc.verify());
universe@535 134 cxBufferInit(&buf, nullptr, 16, &alloc, CX_BUFFER_DEFAULT);
universe@535 135 memcpy(buf.space, "test____________", 16);
universe@535 136 buf.capacity = 8; // purposely pretend that the buffer has less capacity s.t. we can test beyond the range
universe@535 137 buf.pos = 4;
universe@535 138 buf.size = 4;
universe@535 139 }
universe@535 140
universe@535 141 void TearDown() override {
universe@535 142 cxBufferDestroy(&buf);
universe@535 143 EXPECT_TRUE(alloc.verify());
universe@535 144 }
universe@535 145
universe@535 146 CxTestingAllocator alloc;
universe@535 147 CxBuffer buf{};
universe@535 148 };
universe@535 149
universe@535 150 class BufferShiftLeft : public BufferShiftFixture {
universe@535 151 };
universe@535 152
universe@535 153 TEST_F(BufferShiftLeft, Zero) {
universe@535 154 ASSERT_EQ(buf.pos, 4);
universe@535 155 ASSERT_EQ(buf.size, 4);
universe@535 156 int ret = cxBufferShiftLeft(&buf, 0);
universe@535 157 EXPECT_EQ(ret, 0);
universe@535 158 EXPECT_EQ(buf.pos, 4);
universe@535 159 EXPECT_EQ(buf.size, 4);
universe@535 160 EXPECT_TRUE(memcmp(buf.space, "test________", 8) == 0);
universe@535 161 }
universe@535 162
universe@547 163 TEST_F(BufferShiftLeft, ZeroOffsetInterface) {
universe@547 164 ASSERT_EQ(buf.pos, 4);
universe@547 165 ASSERT_EQ(buf.size, 4);
universe@547 166 int ret = cxBufferShift(&buf, -0);
universe@547 167 EXPECT_EQ(ret, 0);
universe@547 168 EXPECT_EQ(buf.pos, 4);
universe@547 169 EXPECT_EQ(buf.size, 4);
universe@547 170 EXPECT_TRUE(memcmp(buf.space, "test________", 8) == 0);
universe@547 171 }
universe@547 172
universe@535 173 TEST_F(BufferShiftLeft, Standard) {
universe@535 174 ASSERT_EQ(buf.pos, 4);
universe@535 175 ASSERT_EQ(buf.size, 4);
universe@535 176 int ret = cxBufferShiftLeft(&buf, 2);
universe@535 177 EXPECT_EQ(ret, 0);
universe@535 178 EXPECT_EQ(buf.pos, 2);
universe@535 179 EXPECT_EQ(buf.size, 2);
universe@535 180 EXPECT_TRUE(memcmp(buf.space, "stst________", 8) == 0);
universe@535 181 }
universe@535 182
universe@535 183 TEST_F(BufferShiftLeft, Overshift) {
universe@535 184 ASSERT_LT(buf.pos, 6);
universe@535 185 ASSERT_LT(buf.size, 6);
universe@535 186 int ret = cxBufferShiftLeft(&buf, 6);
universe@535 187 EXPECT_EQ(ret, 0);
universe@535 188 EXPECT_EQ(buf.pos, 0);
universe@535 189 EXPECT_EQ(buf.size, 0);
universe@535 190 EXPECT_TRUE(memcmp(buf.space, "test________", 8) == 0);
universe@535 191 }
universe@535 192
universe@535 193 TEST_F(BufferShiftLeft, OvershiftPosOnly) {
universe@535 194 buf.pos = 2;
universe@535 195 ASSERT_EQ(buf.size, 4);
universe@535 196 int ret = cxBufferShiftLeft(&buf, 3);
universe@535 197 EXPECT_EQ(ret, 0);
universe@535 198 EXPECT_EQ(buf.pos, 0);
universe@535 199 EXPECT_EQ(buf.size, 1);
universe@535 200 EXPECT_TRUE(memcmp(buf.space, "test________", 8) == 0);
universe@535 201 }
universe@535 202
universe@535 203 TEST_F(BufferShiftLeft, OffsetInterface) {
universe@535 204 buf.pos = 3;
universe@535 205 ASSERT_EQ(buf.size, 4);
universe@535 206 int ret = cxBufferShift(&buf, -2);
universe@535 207 EXPECT_EQ(ret, 0);
universe@535 208 EXPECT_EQ(buf.pos, 1);
universe@535 209 EXPECT_EQ(buf.size, 2);
universe@535 210 EXPECT_TRUE(memcmp(buf.space, "stst________", 8) == 0);
universe@535 211 }
universe@535 212
universe@535 213 class BufferShiftRight : public BufferShiftFixture {
universe@535 214 };
universe@535 215
universe@535 216 TEST_F(BufferShiftRight, Zero) {
universe@535 217 ASSERT_EQ(buf.pos, 4);
universe@535 218 ASSERT_EQ(buf.size, 4);
universe@535 219 int ret = cxBufferShiftRight(&buf, 0);
universe@535 220 EXPECT_EQ(ret, 0);
universe@535 221 EXPECT_EQ(buf.pos, 4);
universe@535 222 EXPECT_EQ(buf.size, 4);
universe@535 223 EXPECT_TRUE(memcmp(buf.space, "test________", 8) == 0);
universe@535 224 }
universe@535 225
universe@547 226 TEST_F(BufferShiftRight, ZeroOffsetInterface) {
universe@547 227 ASSERT_EQ(buf.pos, 4);
universe@547 228 ASSERT_EQ(buf.size, 4);
universe@547 229 int ret = cxBufferShift(&buf, +0);
universe@547 230 EXPECT_EQ(ret, 0);
universe@547 231 EXPECT_EQ(buf.pos, 4);
universe@547 232 EXPECT_EQ(buf.size, 4);
universe@547 233 EXPECT_TRUE(memcmp(buf.space, "test________", 8) == 0);
universe@547 234 }
universe@547 235
universe@535 236 TEST_F(BufferShiftRight, Standard) {
universe@535 237 ASSERT_EQ(buf.pos, 4);
universe@535 238 ASSERT_EQ(buf.size, 4);
universe@535 239 int ret = cxBufferShiftRight(&buf, 3);
universe@535 240 EXPECT_EQ(ret, 0);
universe@535 241 EXPECT_EQ(buf.pos, 7);
universe@535 242 EXPECT_EQ(buf.size, 7);
universe@535 243 EXPECT_TRUE(memcmp(buf.space, "testest_____", 8) == 0);
universe@535 244 }
universe@535 245
universe@535 246 TEST_F(BufferShiftRight, OvershiftDiscard) {
universe@535 247 ASSERT_EQ(buf.pos, 4);
universe@535 248 ASSERT_EQ(buf.size, 4);
universe@535 249 ASSERT_EQ(buf.capacity, 8);
universe@535 250 int ret = cxBufferShiftRight(&buf, 6);
universe@535 251 EXPECT_EQ(ret, 0);
universe@535 252 EXPECT_EQ(buf.pos, 8);
universe@535 253 EXPECT_EQ(buf.size, 8);
universe@535 254 EXPECT_EQ(buf.capacity, 8);
universe@535 255 EXPECT_TRUE(memcmp(buf.space, "test__te____", 8) == 0);
universe@535 256 }
universe@535 257
universe@535 258 TEST_F(BufferShiftRight, OvershiftExtend) {
universe@535 259 ASSERT_EQ(buf.pos, 4);
universe@535 260 ASSERT_EQ(buf.size, 4);
universe@535 261 ASSERT_EQ(buf.capacity, 8);
universe@535 262 buf.flags |= CX_BUFFER_AUTO_EXTEND;
universe@535 263 int ret = cxBufferShiftRight(&buf, 6);
universe@535 264 EXPECT_EQ(ret, 0);
universe@535 265 EXPECT_EQ(buf.pos, 10);
universe@535 266 EXPECT_EQ(buf.size, 10);
universe@535 267 EXPECT_GE(buf.capacity, 10);
universe@535 268 EXPECT_TRUE(memcmp(buf.space, "test__test__", 8) == 0);
universe@535 269 }
universe@535 270
universe@535 271 TEST_F(BufferShiftRight, OffsetInterface) {
universe@535 272 buf.pos = 3;
universe@535 273 ASSERT_EQ(buf.size, 4);
universe@535 274 int ret = cxBufferShift(&buf, 2);
universe@535 275 EXPECT_EQ(ret, 0);
universe@535 276 EXPECT_EQ(buf.pos, 5);
universe@535 277 EXPECT_EQ(buf.size, 6);
universe@535 278 EXPECT_TRUE(memcmp(buf.space, "tetest______", 8) == 0);
universe@535 279 }
universe@535 280
universe@535 281 TEST(BufferMinimumCapacity, Sufficient) {
universe@535 282 CxTestingAllocator alloc;
universe@535 283 auto space = cxMalloc(&alloc, 8);
universe@535 284 CxBuffer buf;
universe@535 285 cxBufferInit(&buf, space, 8, &alloc, CX_BUFFER_FREE_CONTENTS);
universe@535 286 memcpy(space, "Testing", 8);
universe@535 287 buf.size = 8;
universe@535 288 cxBufferMinimumCapacity(&buf, 6);
universe@535 289 EXPECT_EQ(buf.capacity, 8);
universe@535 290 EXPECT_EQ(buf.size, 8);
universe@535 291 EXPECT_TRUE(memcmp(buf.space, "Testing", 8) == 0);
universe@535 292 cxBufferDestroy(&buf);
universe@535 293 EXPECT_TRUE(alloc.verify());
universe@535 294 }
universe@535 295
universe@535 296 TEST(BufferMinimumCapacity, Extend) {
universe@535 297 CxTestingAllocator alloc;
universe@535 298 auto space = cxMalloc(&alloc, 8);
universe@535 299 CxBuffer buf;
universe@535 300 cxBufferInit(&buf, space, 8, &alloc, CX_BUFFER_FREE_CONTENTS); // NO auto extend!
universe@535 301 memcpy(space, "Testing", 8);
universe@535 302 buf.size = 8;
universe@535 303 cxBufferMinimumCapacity(&buf, 16);
universe@535 304 EXPECT_EQ(buf.capacity, 16);
universe@535 305 EXPECT_EQ(buf.size, 8);
universe@535 306 EXPECT_TRUE(memcmp(buf.space, "Testing", 8) == 0);
universe@535 307 cxBufferDestroy(&buf);
universe@535 308 EXPECT_TRUE(alloc.verify());
universe@535 309 }
universe@536 310
universe@536 311 TEST(BufferClear, Test) {
universe@536 312 char space[16];
universe@536 313 strcpy(space, "clear test");
universe@536 314 CxBuffer buf;
universe@536 315 cxBufferInit(&buf, space, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
universe@536 316 ASSERT_EQ(buf.size, 0);
universe@536 317 // only clear the used part of the buffer
universe@536 318 cxBufferClear(&buf);
universe@536 319 EXPECT_EQ(memcmp(space, "clear test", 10), 0);
universe@536 320 buf.size = 5;
universe@536 321 buf.pos = 3;
universe@536 322 cxBufferClear(&buf);
universe@536 323 EXPECT_EQ(memcmp(space, "\0\0\0\0\0 test", 10), 0);
universe@536 324 EXPECT_EQ(buf.size, 0);
universe@536 325 EXPECT_EQ(buf.pos, 0);
universe@538 326 cxBufferDestroy(&buf);
universe@536 327 }
universe@538 328
universe@538 329 class BufferWrite : public ::testing::Test {
universe@538 330 protected:
universe@545 331 CxBuffer buf{}, target{};
universe@538 332
universe@538 333 void SetUp() override {
universe@545 334 cxBufferInit(&target, nullptr, 16, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND);
universe@538 335 cxBufferInit(&buf, nullptr, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
universe@538 336 buf.capacity = 8; // artificially reduce capacity to check OOB writes
universe@538 337 memset(buf.space, 0, 16);
universe@538 338 memcpy(buf.space, "prep", 4);
universe@538 339 buf.size = buf.pos = 4;
universe@538 340 }
universe@538 341
universe@538 342 void TearDown() override {
universe@538 343 cxBufferDestroy(&buf);
universe@545 344 cxBufferDestroy(&target);
universe@545 345 }
universe@545 346
universe@545 347 void enableFlushing() {
universe@545 348 buf.flush_target = &target;
universe@545 349 buf.flush_func = reinterpret_cast<cx_write_func>(cxBufferWrite);
universe@545 350 buf.flush_blkmax = 1;
universe@538 351 }
universe@538 352 };
universe@538 353
universe@567 354 static size_t mock_write_limited_rate(
universe@567 355 void const *ptr,
universe@567 356 size_t size,
universe@567 357 __attribute__((unused)) size_t nitems,
universe@567 358 CxBuffer *buffer
universe@567 359 ) {
universe@567 360 // simulate limited target drain capacity
universe@567 361 static bool full = false;
universe@567 362 if (full) {
universe@567 363 full = false;
universe@567 364 return 0;
universe@567 365 } else {
universe@567 366 full = true;
universe@567 367 return cxBufferWrite(ptr, size, nitems > 2 ? 2 : nitems, buffer);
universe@567 368 }
universe@567 369 }
universe@567 370
universe@538 371 TEST_F(BufferWrite, SizeOneFit) {
universe@538 372 const char *data = "test";
universe@538 373 ASSERT_EQ(buf.capacity, 8);
universe@538 374 ASSERT_EQ(buf.pos, 4);
universe@541 375 ASSERT_EQ(buf.size, 4);
universe@538 376 size_t written = cxBufferWrite(data, 1, 4, &buf);
universe@538 377 EXPECT_EQ(written, 4);
universe@538 378 EXPECT_EQ(buf.size, 8);
universe@538 379 EXPECT_EQ(buf.pos, 8);
universe@538 380 EXPECT_EQ(buf.capacity, 8);
universe@538 381 EXPECT_EQ(memcmp(buf.space, "preptest", 8), 0);
universe@538 382 }
universe@538 383
universe@538 384 TEST_F(BufferWrite, SizeOneDiscard) {
universe@538 385 const char *data = "testing";
universe@538 386 ASSERT_EQ(buf.capacity, 8);
universe@538 387 ASSERT_EQ(buf.pos, 4);
universe@541 388 ASSERT_EQ(buf.size, 4);
universe@538 389 size_t written = cxBufferWrite(data, 1, 7, &buf);
universe@538 390 EXPECT_EQ(written, 4);
universe@538 391 EXPECT_EQ(buf.size, 8);
universe@538 392 EXPECT_EQ(buf.pos, 8);
universe@538 393 EXPECT_EQ(buf.capacity, 8);
universe@538 394 EXPECT_EQ(memcmp(buf.space, "preptest\0", 9), 0);
universe@538 395 }
universe@538 396
universe@538 397 TEST_F(BufferWrite, SizeOneExtend) {
universe@538 398 buf.flags |= CX_BUFFER_AUTO_EXTEND;
universe@538 399 const char *data = "testing";
universe@538 400 ASSERT_EQ(buf.capacity, 8);
universe@538 401 ASSERT_EQ(buf.pos, 4);
universe@541 402 ASSERT_EQ(buf.size, 4);
universe@538 403 size_t written = cxBufferWrite(data, 1, 7, &buf);
universe@538 404 EXPECT_EQ(written, 7);
universe@538 405 EXPECT_EQ(buf.size, 11);
universe@538 406 EXPECT_EQ(buf.pos, 11);
universe@538 407 EXPECT_GE(buf.capacity, 11);
universe@538 408 EXPECT_EQ(memcmp(buf.space, "preptesting", 11), 0);
universe@538 409 }
universe@538 410
universe@538 411 TEST_F(BufferWrite, MultibyteFit) {
universe@541 412 const char *data = "test";
universe@541 413 ASSERT_EQ(buf.capacity, 8);
universe@541 414 ASSERT_EQ(buf.pos, 4);
universe@541 415 ASSERT_EQ(buf.size, 4);
universe@541 416 size_t written = cxBufferWrite(data, 2, 2, &buf);
universe@541 417 EXPECT_EQ(written, 2);
universe@541 418 EXPECT_EQ(buf.size, 8);
universe@541 419 EXPECT_EQ(buf.pos, 8);
universe@541 420 EXPECT_EQ(buf.capacity, 8);
universe@541 421 EXPECT_EQ(memcmp(buf.space, "preptest", 8), 0);
universe@538 422 }
universe@538 423
universe@538 424 TEST_F(BufferWrite, MultibyteDiscard) {
universe@542 425 const char *data = "testing";
universe@541 426 ASSERT_EQ(buf.capacity, 8);
universe@541 427 ASSERT_EQ(buf.size, 4);
universe@541 428 buf.pos = 3;
universe@542 429 size_t written = cxBufferWrite(data, 2, 4, &buf);
universe@538 430 // remember: whole elements are discarded if they do not fit
universe@541 431 EXPECT_EQ(written, 2);
universe@541 432 EXPECT_EQ(buf.size, 7);
universe@541 433 EXPECT_EQ(buf.pos, 7);
universe@541 434 EXPECT_EQ(buf.capacity, 8);
universe@541 435 EXPECT_EQ(memcmp(buf.space, "pretest\0", 8), 0);
universe@538 436 }
universe@538 437
universe@538 438 TEST_F(BufferWrite, MultibyteExtend) {
universe@541 439 buf.flags |= CX_BUFFER_AUTO_EXTEND;
universe@541 440 const char *data = "tester";
universe@541 441 ASSERT_EQ(buf.capacity, 8);
universe@541 442 ASSERT_EQ(buf.size, 4);
universe@541 443 buf.pos = 3;
universe@541 444 size_t written = cxBufferWrite(data, 2, 3, &buf);
universe@541 445 // remember: whole elements are discarded if they do not fit
universe@541 446 EXPECT_EQ(written, 3);
universe@541 447 EXPECT_EQ(buf.size, 9);
universe@541 448 EXPECT_EQ(buf.pos, 9);
universe@541 449 EXPECT_GE(buf.capacity, 9);
universe@566 450 EXPECT_EQ(memcmp(buf.space, "pretester", 9), 0);
universe@538 451 }
universe@538 452
universe@538 453 TEST_F(BufferWrite, PutcWrapperFit) {
universe@541 454 ASSERT_EQ(buf.capacity, 8);
universe@541 455 ASSERT_EQ(buf.pos, 4);
universe@541 456 ASSERT_EQ(buf.size, 4);
universe@565 457 int c = cxBufferPut(&buf, 0x200 | 'a');
universe@541 458 EXPECT_EQ(c, 'a');
universe@541 459 EXPECT_EQ(buf.size, 5);
universe@541 460 EXPECT_EQ(buf.pos, 5);
universe@541 461 EXPECT_EQ(buf.capacity, 8);
universe@541 462 EXPECT_EQ(memcmp(buf.space, "prepa\0", 6), 0);
universe@538 463 }
universe@538 464
universe@538 465 TEST_F(BufferWrite, PutcWrapperDiscard) {
universe@541 466 ASSERT_EQ(buf.capacity, 8);
universe@541 467 ASSERT_EQ(buf.size, 4);
universe@541 468 buf.pos = 8;
universe@565 469 int c = cxBufferPut(&buf, 0x200 | 'a');
universe@541 470 EXPECT_EQ(c, EOF);
universe@541 471 EXPECT_EQ(buf.size, 4);
universe@541 472 EXPECT_EQ(buf.pos, 8);
universe@541 473 EXPECT_EQ(buf.capacity, 8);
universe@541 474 EXPECT_EQ(memcmp(buf.space, "prep\0\0\0\0\0", 9), 0);
universe@538 475 }
universe@538 476
universe@538 477 TEST_F(BufferWrite, PutcWrapperExtend) {
universe@541 478 buf.flags |= CX_BUFFER_AUTO_EXTEND;
universe@541 479 ASSERT_EQ(buf.capacity, 8);
universe@541 480 ASSERT_EQ(buf.size, 4);
universe@541 481 buf.pos = 8;
universe@565 482 int c = cxBufferPut(&buf, 0x200 | 'a');
universe@541 483 EXPECT_EQ(c, 'a');
universe@541 484 EXPECT_EQ(buf.size, 9);
universe@541 485 EXPECT_EQ(buf.pos, 9);
universe@541 486 EXPECT_GE(buf.capacity, 9);
universe@566 487 EXPECT_EQ(memcmp(buf.space, "prep\0\0\0\0a", 9), 0);
universe@538 488 }
universe@538 489
universe@538 490 TEST_F(BufferWrite, PutStringWrapperFit) {
universe@541 491 const char *data = "test";
universe@541 492 ASSERT_EQ(buf.capacity, 8);
universe@541 493 ASSERT_EQ(buf.pos, 4);
universe@541 494 ASSERT_EQ(buf.size, 4);
universe@541 495 size_t written = cxBufferPutString(&buf, data);
universe@541 496 EXPECT_EQ(written, 4);
universe@541 497 EXPECT_EQ(buf.size, 8);
universe@541 498 EXPECT_EQ(buf.pos, 8);
universe@541 499 EXPECT_EQ(buf.capacity, 8);
universe@541 500 EXPECT_EQ(memcmp(buf.space, "preptest", 8), 0);
universe@538 501 }
universe@538 502
universe@538 503 TEST_F(BufferWrite, PutStringWrapperDiscard) {
universe@541 504 const char *data = "testing";
universe@541 505 ASSERT_EQ(buf.capacity, 8);
universe@541 506 ASSERT_EQ(buf.pos, 4);
universe@541 507 ASSERT_EQ(buf.size, 4);
universe@541 508 size_t written = cxBufferPutString(&buf, data);
universe@541 509 EXPECT_EQ(written, 4);
universe@541 510 EXPECT_EQ(buf.size, 8);
universe@541 511 EXPECT_EQ(buf.pos, 8);
universe@541 512 EXPECT_EQ(buf.capacity, 8);
universe@541 513 EXPECT_EQ(memcmp(buf.space, "preptest\0", 9), 0);
universe@538 514 }
universe@538 515
universe@538 516 TEST_F(BufferWrite, PutStringWrapperExtend) {
universe@541 517 buf.flags |= CX_BUFFER_AUTO_EXTEND;
universe@541 518 const char *data = "testing";
universe@541 519 ASSERT_EQ(buf.capacity, 8);
universe@541 520 ASSERT_EQ(buf.pos, 4);
universe@541 521 ASSERT_EQ(buf.size, 4);
universe@541 522 size_t written = cxBufferPutString(&buf, data);
universe@541 523 EXPECT_EQ(written, 7);
universe@541 524 EXPECT_EQ(buf.size, 11);
universe@541 525 EXPECT_EQ(buf.pos, 11);
universe@541 526 EXPECT_GE(buf.capacity, 11);
universe@541 527 EXPECT_EQ(memcmp(buf.space, "preptesting", 11), 0);
universe@541 528 }
universe@538 529
universe@541 530 TEST_F(BufferWrite, MultOverflow) {
universe@541 531 const char *data = "testing";
universe@541 532 ASSERT_EQ(buf.capacity, 8);
universe@541 533 ASSERT_EQ(buf.pos, 4);
universe@541 534 ASSERT_EQ(buf.size, 4);
universe@541 535 size_t written = cxBufferWrite(data, 8, SIZE_MAX / 4, &buf);
universe@541 536 EXPECT_EQ(written, 0);
universe@541 537 EXPECT_EQ(buf.capacity, 8);
universe@541 538 EXPECT_EQ(buf.pos, 4);
universe@541 539 EXPECT_EQ(buf.size, 4);
universe@541 540 EXPECT_EQ(memcmp(buf.space, "prep\0", 5), 0);
universe@538 541 }
universe@541 542
universe@541 543 TEST_F(BufferWrite, MaxCapaOverflow) {
universe@541 544 buf.flags |= CX_BUFFER_AUTO_EXTEND;
universe@541 545 const char *data = "testing";
universe@541 546 ASSERT_EQ(buf.capacity, 8);
universe@541 547 ASSERT_EQ(buf.pos, 4);
universe@541 548 ASSERT_EQ(buf.size, 4);
universe@541 549 size_t written = cxBufferWrite(data, 1, SIZE_MAX - 2, &buf);
universe@541 550 EXPECT_EQ(written, 0);
universe@541 551 EXPECT_EQ(buf.capacity, 8);
universe@541 552 EXPECT_EQ(buf.pos, 4);
universe@541 553 EXPECT_EQ(buf.size, 4);
universe@541 554 EXPECT_EQ(memcmp(buf.space, "prep\0", 5), 0);
universe@541 555 }
universe@541 556
universe@541 557 TEST_F(BufferWrite, OnlyOverwrite) {
universe@541 558 buf.flags |= CX_BUFFER_AUTO_EXTEND;
universe@541 559 ASSERT_EQ(buf.capacity, 8);
universe@541 560 memcpy(buf.space, "preptest", 8);
universe@541 561 buf.pos = 3;
universe@541 562 buf.size = 8;
universe@541 563 size_t written = cxBufferWrite("XXX", 2, 2, &buf);
universe@541 564 EXPECT_EQ(written, 2);
universe@541 565 EXPECT_EQ(buf.capacity, 8);
universe@541 566 EXPECT_EQ(buf.size, 8);
universe@541 567 EXPECT_EQ(buf.pos, 7);
universe@541 568 EXPECT_EQ(memcmp(buf.space, "preXXX\0t", 8), 0);
universe@541 569 }
universe@545 570
universe@545 571 TEST_F(BufferWrite, FlushAtCapacity) {
universe@545 572 enableFlushing();
universe@545 573 ASSERT_EQ(buf.capacity, 8);
universe@545 574 ASSERT_EQ(buf.pos, 4);
universe@545 575 size_t written = cxBufferWrite("foo", 1, 3, &buf);
universe@545 576 EXPECT_EQ(written, 3);
universe@545 577 ASSERT_EQ(buf.pos, 7);
universe@545 578 ASSERT_EQ(buf.size, 7);
universe@545 579 ASSERT_EQ(target.pos, 0);
universe@545 580 ASSERT_EQ(target.size, 0);
universe@545 581 written = cxBufferWrite("hello", 1, 5, &buf);
universe@545 582 EXPECT_EQ(written, 5);
universe@545 583 EXPECT_EQ(buf.pos, 0);
universe@545 584 EXPECT_EQ(buf.size, 0);
universe@545 585 EXPECT_EQ(buf.capacity, 8);
universe@545 586 EXPECT_EQ(target.pos, 12);
universe@545 587 ASSERT_EQ(target.size, 12);
universe@545 588 EXPECT_EQ(memcmp(target.space, "prepfoohello", 12), 0);
universe@545 589 }
universe@546 590
universe@546 591 TEST_F(BufferWrite, FlushAtThreshold) {
universe@546 592 enableFlushing();
universe@546 593 buf.flush_threshold = 12;
universe@546 594 buf.flags |= CX_BUFFER_AUTO_EXTEND;
universe@546 595 ASSERT_EQ(buf.capacity, 8);
universe@546 596 ASSERT_EQ(buf.pos, 4);
universe@546 597 size_t written = cxBufferWrite("foobar", 1, 6, &buf);
universe@546 598 EXPECT_EQ(written, 6);
universe@546 599 ASSERT_EQ(buf.pos, 10);
universe@546 600 ASSERT_EQ(buf.size, 10);
universe@546 601 ASSERT_GE(buf.capacity, 10);
universe@546 602 ASSERT_LE(buf.capacity, 12);
universe@546 603 ASSERT_EQ(target.pos, 0);
universe@546 604 ASSERT_EQ(target.size, 0);
universe@546 605 written = cxBufferWrite("hello", 1, 5, &buf);
universe@546 606 EXPECT_EQ(written, 5);
universe@546 607 EXPECT_EQ(buf.pos, 0);
universe@546 608 EXPECT_EQ(buf.size, 0);
universe@546 609 EXPECT_LE(buf.capacity, 12);
universe@546 610 EXPECT_EQ(target.pos, 15);
universe@546 611 ASSERT_EQ(target.size, 15);
universe@546 612 EXPECT_EQ(memcmp(target.space, "prepfoobarhello", 15), 0);
universe@546 613 }
universe@547 614
universe@567 615 TEST_F(BufferWrite, FlushRateLimited) {
universe@567 616 enableFlushing();
universe@567 617 // limit the rate of the flush function and the capacity of the target
universe@567 618 target.capacity = 16;
universe@567 619 target.flags &= ~CX_BUFFER_AUTO_EXTEND;
universe@567 620 buf.flush_func = (cx_write_func) mock_write_limited_rate;
universe@567 621 ASSERT_EQ(buf.capacity, 8);
universe@567 622 ASSERT_EQ(buf.pos, 4);
universe@567 623 size_t written = cxBufferWrite("foo", 1, 3, &buf);
universe@567 624 EXPECT_EQ(written, 3);
universe@567 625 ASSERT_EQ(buf.pos, 7);
universe@567 626 ASSERT_EQ(buf.size, 7);
universe@567 627 ASSERT_EQ(target.pos, 0);
universe@567 628 ASSERT_EQ(target.size, 0);
universe@567 629 written = cxBufferWrite("hello, world!", 1, 13, &buf);
universe@567 630 // " world!" fits into this buffer, the remaining stuff is flushed out
universe@567 631 EXPECT_EQ(written, 13);
universe@567 632 EXPECT_EQ(buf.pos, 7);
universe@567 633 EXPECT_EQ(buf.size, 7);
universe@567 634 EXPECT_EQ(buf.capacity, 8);
universe@567 635 EXPECT_EQ(memcmp(buf.space, " world!", 7), 0);
universe@567 636 EXPECT_EQ(target.pos, 13);
universe@567 637 ASSERT_EQ(target.size, 13);
universe@567 638 EXPECT_EQ(target.capacity, 16);
universe@567 639 EXPECT_EQ(memcmp(target.space, "prepfoohello,", 13), 0);
universe@567 640 }
universe@567 641
universe@548 642 class BufferSeek : public BufferFixture {
universe@547 643 };
universe@547 644
universe@547 645 TEST_F(BufferSeek, SetZero) {
universe@547 646 int result = cxBufferSeek(&buf, 0, SEEK_SET);
universe@547 647 EXPECT_EQ(result, 0);
universe@547 648 EXPECT_EQ(buf.pos, 0);
universe@547 649 }
universe@547 650
universe@547 651 TEST_F(BufferSeek, SetValid) {
universe@547 652 int result = cxBufferSeek(&buf, 5, SEEK_SET);
universe@547 653 EXPECT_EQ(result, 0);
universe@547 654 EXPECT_EQ(buf.pos, 5);
universe@547 655 }
universe@547 656
universe@547 657 TEST_F(BufferSeek, SetInvalid) {
universe@547 658 ASSERT_EQ(buf.pos, 3);
universe@547 659 int result = cxBufferSeek(&buf, 6, SEEK_SET);
universe@547 660 EXPECT_NE(result, 0);
universe@547 661 EXPECT_EQ(buf.pos, 3);
universe@547 662 }
universe@547 663
universe@547 664 TEST_F(BufferSeek, CurZero) {
universe@547 665 ASSERT_EQ(buf.pos, 3);
universe@547 666 int result = cxBufferSeek(&buf, 0, SEEK_CUR);
universe@547 667 EXPECT_EQ(result, 0);
universe@547 668 EXPECT_EQ(buf.pos, 3);
universe@547 669 }
universe@547 670
universe@547 671 TEST_F(BufferSeek, CurValidPositive) {
universe@547 672 ASSERT_EQ(buf.pos, 3);
universe@547 673 int result = cxBufferSeek(&buf, 2, SEEK_CUR);
universe@547 674 EXPECT_EQ(result, 0);
universe@547 675 EXPECT_EQ(buf.pos, 5);
universe@547 676 }
universe@547 677
universe@547 678 TEST_F(BufferSeek, CurValidNegative) {
universe@547 679 ASSERT_EQ(buf.pos, 3);
universe@547 680 int result = cxBufferSeek(&buf, -3, SEEK_CUR);
universe@547 681 EXPECT_EQ(result, 0);
universe@547 682 EXPECT_EQ(buf.pos, 0);
universe@547 683 }
universe@547 684
universe@547 685 TEST_F(BufferSeek, CurInvalidPositive) {
universe@547 686 ASSERT_EQ(buf.pos, 3);
universe@547 687 int result = cxBufferSeek(&buf, 3, SEEK_CUR);
universe@547 688 EXPECT_NE(result, 0);
universe@547 689 EXPECT_EQ(buf.pos, 3);
universe@547 690 }
universe@547 691
universe@547 692 TEST_F(BufferSeek, CurInvalidNegative) {
universe@547 693 ASSERT_EQ(buf.pos, 3);
universe@547 694 int result = cxBufferSeek(&buf, -4, SEEK_CUR);
universe@547 695 EXPECT_NE(result, 0);
universe@547 696 EXPECT_EQ(buf.pos, 3);
universe@547 697 }
universe@547 698
universe@547 699 TEST_F(BufferSeek, EndZero) {
universe@547 700 ASSERT_EQ(buf.size, 6);
universe@547 701 int result = cxBufferSeek(&buf, 0, SEEK_END);
universe@547 702 // the (past-the-)end position is always invalid
universe@547 703 EXPECT_NE(result, 0);
universe@547 704 EXPECT_EQ(buf.pos, 3);
universe@547 705 }
universe@547 706
universe@547 707 TEST_F(BufferSeek, EndValid) {
universe@547 708 ASSERT_EQ(buf.size, 6);
universe@547 709 int result = cxBufferSeek(&buf, -6, SEEK_END);
universe@547 710 EXPECT_EQ(result, 0);
universe@547 711 EXPECT_EQ(buf.pos, 0);
universe@547 712 }
universe@547 713
universe@547 714 TEST_F(BufferSeek, EndInvalid) {
universe@547 715 ASSERT_EQ(buf.size, 6);
universe@547 716 int result = cxBufferSeek(&buf, 1, SEEK_END);
universe@547 717 EXPECT_NE(result, 0);
universe@547 718 EXPECT_EQ(buf.pos, 3);
universe@547 719 }
universe@547 720
universe@547 721 TEST_F(BufferSeek, WhenceInvalid) {
universe@547 722 ASSERT_EQ(buf.size, 6);
universe@547 723 ASSERT_EQ(buf.pos, 3);
universe@547 724 int result = cxBufferSeek(&buf, 2, 9000);
universe@547 725 EXPECT_NE(result, 0);
universe@547 726 EXPECT_EQ(buf.size, 6);
universe@547 727 EXPECT_EQ(buf.pos, 3);
universe@548 728 }
universe@548 729
universe@548 730 class BufferEof : public BufferFixture {
universe@548 731 };
universe@548 732
universe@548 733 TEST_F(BufferEof, Reached) {
universe@548 734 buf.pos = buf.size;
universe@548 735 EXPECT_TRUE(cxBufferEof(&buf));
universe@548 736 buf.pos = buf.size - 1;
universe@548 737 ASSERT_FALSE(cxBufferEof(&buf));
universe@548 738 cxBufferPut(&buf, 'a');
universe@548 739 EXPECT_TRUE(cxBufferEof(&buf));
universe@548 740 }
universe@548 741
universe@548 742 TEST_F(BufferEof, NotReached) {
universe@548 743 buf.pos = buf.size - 1;
universe@548 744 EXPECT_FALSE(cxBufferEof(&buf));
universe@548 745 buf.pos = 0;
universe@548 746 cxBufferWrite("test", 1, 5, &buf);
universe@548 747 EXPECT_FALSE(cxBufferEof(&buf));
universe@548 748 }

mercurial