Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 32 additions & 3 deletions test/test_bson.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,25 @@
_NUMPY_AVAILABLE = importlib.util.find_spec("numpy") is not None


def _total_memory():
"""Return total physical memory in bytes, or None if it cannot be determined."""
try:
return os.sysconf("SC_PAGE_SIZE") * os.sysconf("SC_PHYS_PAGES")
except (ValueError, OSError, AttributeError):
return None


# PYTHON-6140: on Linux, skip if the host cannot allocate the ~4GiB this test
# needs. On other platforms, run the test and skip on MemoryError.
_TOTAL_MEMORY = _total_memory()
_ENCODE_SIZE_LIMIT_MIN_MEMORY = 6 << 30
_SKIP_ENCODE_SIZE_LIMIT = (
sys.platform == "linux"
and _TOTAL_MEMORY is not None
and _TOTAL_MEMORY < _ENCODE_SIZE_LIMIT_MIN_MEMORY
)


class NotADict(abc.MutableMapping):
"""Non-dict type that implements the mapping protocol."""

Expand Down Expand Up @@ -692,12 +711,22 @@ def test_overflow(self):
self.assertRaises(OverflowError, encode, {"x": -9223372036854775809})

@unittest.skipUnless(bson.has_c(), "This test requires the C extension")
@unittest.skipIf(
_SKIP_ENCODE_SIZE_LIMIT,
"Test requires at least 6GiB of memory (PYTHON-6140)",
)
def test_encode_size_limit(self):
# PYTHON-5996: encoding must raise when a document's encoded size
# exceeds the BSON size limit.
big_value = "a" * (1 << 30)
with self.assertRaises(ValueError):
encode({"a": big_value, "b": big_value, "c": big_value})
try:
big_value = "a" * (1 << 30)
with self.assertRaises(ValueError):
encode({"a": big_value, "b": big_value, "c": big_value})
except MemoryError:
# PYTHON-6140: some hosts report enough installed memory but
# cannot actually commit it (pagefile limits, mongod running on
# the same host). Skip rather than fail.
self.skipTest("Could not allocate enough memory (PYTHON-6140)")

def test_small_long_encode_decode(self):
encoded1 = encode({"x": 256})
Expand Down
Loading