Skip to content

Commit 3969826

Browse files
author
Micah Scott
committed
Edge case tests for sizing, allocation, and accessors
1 parent 6f732fc commit 3969826

File tree

1 file changed

+211
-0
lines changed

1 file changed

+211
-0
lines changed

src/libbson/tests/test-bson-vector.c

Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1384,6 +1384,213 @@ test_bson_vector_example_packed_bit_view (void)
13841384
bson_destroy (&doc);
13851385
}
13861386

1387+
static void
1388+
test_bson_vector_edge_cases_int8 (void)
1389+
{
1390+
size_t max_representable_elements = (size_t) UINT32_MAX - BSON_VECTOR_HEADER_LEN;
1391+
1392+
// Test binary_data_length (uint32_t) edge cases, without any allocation.
1393+
{
1394+
ASSERT_CMPUINT32 (bson_vector_int8_binary_data_length (max_representable_elements - 1u), ==, UINT32_MAX - 1u);
1395+
ASSERT_CMPUINT32 (bson_vector_int8_binary_data_length (max_representable_elements), ==, UINT32_MAX);
1396+
ASSERT_CMPUINT32 (bson_vector_int8_binary_data_length (max_representable_elements + 1u), ==, 0);
1397+
}
1398+
1399+
// Needs little real memory because most bytes are never accessed,
1400+
// but we do need a virtual address space larger than 32 bits.
1401+
#if BSON_WORD_SIZE > 32
1402+
1403+
size_t expected_bson_overhead =
1404+
5 /* empty bson document */ + 3 /* "v" element header */ + 5 /* binary item header */;
1405+
size_t max_alloc_elements = (size_t) BSON_MAX_SIZE - expected_bson_overhead - BSON_VECTOR_HEADER_LEN;
1406+
1407+
bson_t doc = BSON_INITIALIZER;
1408+
bson_vector_int8_view_t view;
1409+
1410+
// Test allocation (BSON_MAX_SIZE + uint32_t) edge cases.
1411+
{
1412+
ASSERT (!BSON_APPEND_VECTOR_INT8_UNINIT (&doc, "v", max_representable_elements, &view));
1413+
ASSERT (!BSON_APPEND_VECTOR_INT8_UNINIT (&doc, "v", max_representable_elements + 1u, &view));
1414+
ASSERT (!BSON_APPEND_VECTOR_INT8_UNINIT (&doc, "v", max_alloc_elements + 1u, &view));
1415+
ASSERT (BSON_APPEND_VECTOR_INT8_UNINIT (&doc, "v", max_alloc_elements, &view));
1416+
}
1417+
1418+
// Test some read and write boundaries.
1419+
{
1420+
int8_t values[] = {1, 2, 3, 4, 5};
1421+
size_t values_size = sizeof values / sizeof values[0];
1422+
ASSERT (bson_vector_int8_view_write (view, values, values_size, 0));
1423+
ASSERT (bson_vector_int8_view_read (view, values, values_size, 0));
1424+
ASSERT (!bson_vector_int8_view_write (view, values, max_alloc_elements + 1u, 0));
1425+
ASSERT (!bson_vector_int8_view_read (view, values, max_alloc_elements + 1u, 0));
1426+
ASSERT (bson_vector_int8_view_write (view, values, values_size, max_alloc_elements - values_size));
1427+
ASSERT (bson_vector_int8_view_read (view, values, values_size, max_alloc_elements - values_size));
1428+
ASSERT (!bson_vector_int8_view_write (view, values, values_size, max_alloc_elements - values_size + 1u));
1429+
ASSERT (!bson_vector_int8_view_read (view, values, values_size, max_alloc_elements - values_size + 1u));
1430+
ASSERT (!bson_vector_int8_view_write (view, values, values_size + 1u, max_alloc_elements - values_size));
1431+
ASSERT (!bson_vector_int8_view_read (view, values, values_size + 1u, max_alloc_elements - values_size));
1432+
ASSERT (!bson_vector_int8_view_write (view, values, SIZE_MAX, max_alloc_elements - values_size));
1433+
ASSERT (!bson_vector_int8_view_read (view, values, SIZE_MAX, max_alloc_elements - values_size));
1434+
ASSERT (!bson_vector_int8_view_write (view, values, SIZE_MAX, max_alloc_elements - values_size + 1u));
1435+
ASSERT (!bson_vector_int8_view_read (view, values, SIZE_MAX, max_alloc_elements - values_size + 1u));
1436+
}
1437+
1438+
bson_destroy (&doc);
1439+
#endif // BSON_WORD_SIZE > 32
1440+
}
1441+
1442+
static void
1443+
test_bson_vector_edge_cases_float32 (void)
1444+
{
1445+
size_t max_representable_elements = ((size_t) UINT32_MAX - BSON_VECTOR_HEADER_LEN) / sizeof (float);
1446+
1447+
// Test binary_data_length (uint32_t) edge cases, without any allocation.
1448+
// Note that the longest possible multiple of a complete element is 1 byte short of UINT32_MAX.
1449+
{
1450+
ASSERT_CMPUINT32 (
1451+
bson_vector_float32_binary_data_length (max_representable_elements - 1u), ==, UINT32_MAX - 1u - 4u);
1452+
ASSERT_CMPUINT32 (bson_vector_float32_binary_data_length (max_representable_elements), ==, UINT32_MAX - 1u);
1453+
ASSERT_CMPUINT32 (bson_vector_float32_binary_data_length (max_representable_elements + 1u), ==, 0);
1454+
}
1455+
1456+
// Needs little real memory because most bytes are never accessed,
1457+
// but we do need a virtual address space larger than 32 bits.
1458+
#if BSON_WORD_SIZE > 32
1459+
1460+
size_t expected_bson_overhead =
1461+
5 /* empty bson document */ + 3 /* "v" element header */ + 5 /* binary item header */;
1462+
size_t max_alloc_elements =
1463+
((size_t) BSON_MAX_SIZE - expected_bson_overhead - BSON_VECTOR_HEADER_LEN) / sizeof (float);
1464+
1465+
bson_t doc = BSON_INITIALIZER;
1466+
bson_vector_float32_view_t view;
1467+
1468+
// Test allocation (BSON_MAX_SIZE + uint32_t) edge cases.
1469+
{
1470+
ASSERT (!BSON_APPEND_VECTOR_FLOAT32_UNINIT (&doc, "v", max_representable_elements, &view));
1471+
ASSERT (!BSON_APPEND_VECTOR_FLOAT32_UNINIT (&doc, "v", max_representable_elements + 1u, &view));
1472+
ASSERT (!BSON_APPEND_VECTOR_FLOAT32_UNINIT (&doc, "v", max_alloc_elements + 1u, &view));
1473+
ASSERT (BSON_APPEND_VECTOR_FLOAT32_UNINIT (&doc, "v", max_alloc_elements, &view));
1474+
}
1475+
1476+
// Test some read and write boundaries.
1477+
{
1478+
float values[] = {1.f, 2.f, 3.f, 4.f, 5.f};
1479+
size_t values_size = sizeof values / sizeof values[0];
1480+
ASSERT (bson_vector_float32_view_write (view, values, values_size, 0));
1481+
ASSERT (bson_vector_float32_view_read (view, values, values_size, 0));
1482+
ASSERT (!bson_vector_float32_view_write (view, values, max_alloc_elements + 1u, 0));
1483+
ASSERT (!bson_vector_float32_view_read (view, values, max_alloc_elements + 1u, 0));
1484+
ASSERT (bson_vector_float32_view_write (view, values, values_size, max_alloc_elements - values_size));
1485+
ASSERT (bson_vector_float32_view_read (view, values, values_size, max_alloc_elements - values_size));
1486+
ASSERT (!bson_vector_float32_view_write (view, values, values_size, max_alloc_elements - values_size + 1u));
1487+
ASSERT (!bson_vector_float32_view_read (view, values, values_size, max_alloc_elements - values_size + 1u));
1488+
ASSERT (!bson_vector_float32_view_write (view, values, values_size + 1u, max_alloc_elements - values_size));
1489+
ASSERT (!bson_vector_float32_view_read (view, values, values_size + 1u, max_alloc_elements - values_size));
1490+
ASSERT (!bson_vector_float32_view_write (view, values, SIZE_MAX, max_alloc_elements - values_size));
1491+
ASSERT (!bson_vector_float32_view_read (view, values, SIZE_MAX, max_alloc_elements - values_size));
1492+
ASSERT (!bson_vector_float32_view_write (view, values, SIZE_MAX, max_alloc_elements - values_size + 1u));
1493+
ASSERT (!bson_vector_float32_view_read (view, values, SIZE_MAX, max_alloc_elements - values_size + 1u));
1494+
}
1495+
1496+
bson_destroy (&doc);
1497+
#endif // BSON_WORD_SIZE > 32
1498+
}
1499+
1500+
static void
1501+
test_bson_vector_edge_cases_packed_bit (void)
1502+
{
1503+
size_t max_representable_elements = ((size_t) UINT32_MAX - BSON_VECTOR_HEADER_LEN) * 8u;
1504+
1505+
// Test binary_data_length (uint32_t) edge cases, without any allocation.
1506+
{
1507+
ASSERT_CMPUINT32 (
1508+
bson_vector_packed_bit_binary_data_length (max_representable_elements - 8u), ==, UINT32_MAX - 1u);
1509+
ASSERT_CMPUINT32 (bson_vector_packed_bit_binary_data_length (max_representable_elements - 7u), ==, UINT32_MAX);
1510+
ASSERT_CMPUINT32 (bson_vector_packed_bit_binary_data_length (max_representable_elements), ==, UINT32_MAX);
1511+
ASSERT_CMPUINT32 (bson_vector_packed_bit_binary_data_length (max_representable_elements + 1u), ==, 0);
1512+
}
1513+
1514+
// Needs little real memory because most bytes are never accessed,
1515+
// but we do need a virtual address space larger than 32 bits.
1516+
#if BSON_WORD_SIZE > 32
1517+
1518+
size_t expected_bson_overhead =
1519+
5 /* empty bson document */ + 3 /* "v" element header */ + 5 /* binary item header */;
1520+
size_t max_alloc_bytes = (size_t) BSON_MAX_SIZE - expected_bson_overhead - BSON_VECTOR_HEADER_LEN;
1521+
size_t max_alloc_elements = max_alloc_bytes * 8u;
1522+
1523+
bson_t doc = BSON_INITIALIZER;
1524+
bson_vector_packed_bit_view_t view;
1525+
1526+
// Test allocation (BSON_MAX_SIZE + uint32_t) edge cases.
1527+
{
1528+
ASSERT (!BSON_APPEND_VECTOR_PACKED_BIT_UNINIT (&doc, "v", max_representable_elements, &view));
1529+
ASSERT (!BSON_APPEND_VECTOR_PACKED_BIT_UNINIT (&doc, "v", max_representable_elements + 1u, &view));
1530+
ASSERT (!BSON_APPEND_VECTOR_PACKED_BIT_UNINIT (&doc, "v", max_alloc_elements + 1u, &view));
1531+
ASSERT (BSON_APPEND_VECTOR_PACKED_BIT_UNINIT (&doc, "v", max_alloc_elements, &view));
1532+
}
1533+
1534+
// Test some pack and unpack boundaries, similar to the read/write tests for non-packed element types.
1535+
// Only tests one length, but it's chosen to be greater than 8 and not a multiple of 8.
1536+
{
1537+
bool values[190];
1538+
size_t values_size = sizeof values / sizeof values[0];
1539+
for (size_t i = 0; i < values_size; i++) {
1540+
values[i] = (i & 3) == 3;
1541+
}
1542+
ASSERT (bson_vector_packed_bit_view_pack_bool (view, values, values_size, 0));
1543+
ASSERT (bson_vector_packed_bit_view_unpack_bool (view, values, values_size, 0));
1544+
ASSERT (!bson_vector_packed_bit_view_pack_bool (view, values, max_alloc_elements + 1u, 0));
1545+
ASSERT (!bson_vector_packed_bit_view_unpack_bool (view, values, max_alloc_elements + 1u, 0));
1546+
ASSERT (bson_vector_packed_bit_view_pack_bool (view, values, values_size, max_alloc_elements - values_size));
1547+
ASSERT (bson_vector_packed_bit_view_unpack_bool (view, values, values_size, max_alloc_elements - values_size));
1548+
ASSERT (
1549+
!bson_vector_packed_bit_view_pack_bool (view, values, values_size, max_alloc_elements - values_size + 1u));
1550+
ASSERT (
1551+
!bson_vector_packed_bit_view_unpack_bool (view, values, values_size, max_alloc_elements - values_size + 1u));
1552+
ASSERT (
1553+
!bson_vector_packed_bit_view_pack_bool (view, values, values_size + 1u, max_alloc_elements - values_size));
1554+
ASSERT (
1555+
!bson_vector_packed_bit_view_unpack_bool (view, values, values_size + 1u, max_alloc_elements - values_size));
1556+
ASSERT (!bson_vector_packed_bit_view_pack_bool (view, values, SIZE_MAX, max_alloc_elements - values_size));
1557+
ASSERT (!bson_vector_packed_bit_view_unpack_bool (view, values, SIZE_MAX, max_alloc_elements - values_size));
1558+
ASSERT (!bson_vector_packed_bit_view_pack_bool (view, values, SIZE_MAX, max_alloc_elements - values_size + 1u));
1559+
ASSERT (!bson_vector_packed_bit_view_unpack_bool (view, values, SIZE_MAX, max_alloc_elements - values_size + 1u));
1560+
}
1561+
1562+
// Test some read and write boundaries on packed bytes.
1563+
{
1564+
uint8_t packed[] = {0x12, 0x34, 0x56, 0x78, 0x9A};
1565+
ASSERT (bson_vector_packed_bit_view_write_packed (view, packed, sizeof packed, 0));
1566+
ASSERT (bson_vector_packed_bit_view_read_packed (view, packed, sizeof packed, 0));
1567+
ASSERT (!bson_vector_packed_bit_view_write_packed (view, packed, max_alloc_bytes + 1u, 0));
1568+
ASSERT (!bson_vector_packed_bit_view_read_packed (view, packed, max_alloc_bytes + 1u, 0));
1569+
ASSERT (
1570+
bson_vector_packed_bit_view_write_packed (view, packed, sizeof packed, max_alloc_bytes - sizeof packed));
1571+
ASSERT (
1572+
bson_vector_packed_bit_view_read_packed (view, packed, sizeof packed, max_alloc_bytes - sizeof packed));
1573+
ASSERT (!bson_vector_packed_bit_view_write_packed (
1574+
view, packed, sizeof packed, max_alloc_bytes - sizeof packed + 1u));
1575+
ASSERT (!bson_vector_packed_bit_view_read_packed (
1576+
view, packed, sizeof packed, max_alloc_bytes - sizeof packed + 1u));
1577+
ASSERT (!bson_vector_packed_bit_view_write_packed (
1578+
view, packed, sizeof packed + 1u, max_alloc_bytes - sizeof packed));
1579+
ASSERT (!bson_vector_packed_bit_view_read_packed (
1580+
view, packed, sizeof packed + 1u, max_alloc_bytes - sizeof packed));
1581+
ASSERT (
1582+
!bson_vector_packed_bit_view_write_packed (view, packed, SIZE_MAX, max_alloc_bytes - sizeof packed));
1583+
ASSERT (!bson_vector_packed_bit_view_read_packed (view, packed, SIZE_MAX, max_alloc_bytes - sizeof packed));
1584+
ASSERT (!bson_vector_packed_bit_view_write_packed (
1585+
view, packed, SIZE_MAX, max_alloc_bytes - sizeof packed + 1u));
1586+
ASSERT (
1587+
!bson_vector_packed_bit_view_read_packed (view, packed, SIZE_MAX, max_alloc_bytes - sizeof packed + 1u));
1588+
}
1589+
1590+
bson_destroy (&doc);
1591+
#endif // BSON_WORD_SIZE > 32
1592+
}
1593+
13871594
void
13881595
test_bson_vector_install (TestSuite *suite)
13891596
{
@@ -1404,4 +1611,8 @@ test_bson_vector_install (TestSuite *suite)
14041611
TestSuite_Add (
14051612
suite, "/bson_binary_vector/example/packed_bit_const_view", test_bson_vector_example_packed_bit_const_view);
14061613
TestSuite_Add (suite, "/bson_binary_vector/example/packed_bit_view", test_bson_vector_example_packed_bit_view);
1614+
1615+
TestSuite_Add (suite, "/bson_binary_vector/edge_cases/int8", test_bson_vector_edge_cases_int8);
1616+
TestSuite_Add (suite, "/bson_binary_vector/edge_cases/float32", test_bson_vector_edge_cases_float32);
1617+
TestSuite_Add (suite, "/bson_binary_vector/edge_cases/packed_bit", test_bson_vector_edge_cases_packed_bit);
14071618
}

0 commit comments

Comments
 (0)