test_buffer.py
Overview
`test_buffer.py` is a test module designed to validate the behavior of the `orjson` JSON parsing library under constrained memory conditions. Specifically, it verifies that `orjson.loads()` correctly raises a `JSONDecodeError` when attempting to parse a very large JSON string that exceeds available memory limits. The test is conditionally executed based on an environment variable that specifies the memory available for the test, ensuring it only runs in appropriate environments.
This file uses the `pytest` testing framework and relies on an environment variable `ORJSON_RUNNER_MEMORY_GIB` to determine the memory setting in GiB (gibibytes). It constructs a large JSON string and checks that parsing fails gracefully with the expected error message when memory is insufficient.
Detailed Explanation
Imports and Constants
import os
import pytest
import orjson
ORJSON_RUNNER_MEMORY_GIB = os.getenv("ORJSON_RUNNER_MEMORY_GIB", "")
os: Used to access environment variables.
pytest: The testing framework used to define and run the test.
orjson: The JSON parsing library being tested.
ORJSON_RUNNER_MEMORY_GIB: Environment variable that determines the memory size (in GiB) available for running this test. Defaults to an empty string if unset.
Function: test_memory_loads
@pytest.mark.skipif(
not ORJSON_RUNNER_MEMORY_GIB,
reason="ORJSON_RUNNER_MEMORY_GIB not defined",
)
def test_memory_loads():
buffer_factor = 12
segment = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
size = (
(int(ORJSON_RUNNER_MEMORY_GIB) * 1024 * 1024 * 1024)
// buffer_factor
// len(segment)
)
doc = "".join(segment for _ in range(size))
with pytest.raises(orjson.JSONDecodeError) as exc_info:
_ = orjson.loads(doc)
assert (
str(exc_info.value)
== "Not enough memory to allocate buffer for parsing: line 1 column 1 (char 0)"
)
Purpose
This test verifies that `orjson.loads()` raises a `JSONDecodeError` with a specific error message when attempting to parse a large JSON string that exceeds the available memory buffer.
Parameters
None (pytest test function)
Behavior and Workflow
Conditional Execution:
The test is skipped ifORJSON_RUNNER_MEMORY_GIBis not defined in the environment.Setup Large Input:
buffer_factoris set to 12, a divisor used to calculate the size of the JSON string relative to available memory.segmentis a fixed 64-character string of repeated 'a' characters.sizeis calculated as the number of repeated segments to create a JSON string that will roughly consume available memory divided bybuffer_factorand the length of the segment.
Create Large Document:
Joins the
segmentstringsizetimes to create a very large stringdoc.
Test for Exception:
Attempts to parse
docusingorjson.loads().Expects a
JSONDecodeErrorto be raised due to insufficient memory to allocate the parsing buffer.
Assertion:
Confirms that the exception message matches the expected error message:
Not enough memory to allocate buffer for parsing: line 1 column 1 (char 0)
Return Value
None. This is a test function that asserts behavior via exceptions.
Usage Example
This test is meant to be run in an environment where `ORJSON_RUNNER_MEMORY_GIB` is defined. Example:
export ORJSON_RUNNER_MEMORY_GIB=2
pytest test_buffer.py
This will run the test with 2 GiB memory considered for buffer allocation.
Important Implementation Details
Memory Calculation:
The test dynamically calculates the size of the input string based on the memory available (ORJSON_RUNNER_MEMORY_GIB) multiplied by 1024³ to convert GiB to bytes. Then it divides by a buffer factor and the length of the repeated segment to produce a sufficiently large string to trigger the memory allocation failure inorjson.Error Detection:
Instead of just checking that an error occurs, the test verifies the exact error message to ensure that the failure is due to memory allocation issues and not some other parsing error.Environment Dependency:
The test is designed to be skipped if theORJSON_RUNNER_MEMORY_GIBenvironment variable is not set, preventing false negatives in environments where memory size is unknown or irrelevant.
Interaction with Other Parts of the System
orjsonLibrary:
This test depends on theorjsonlibrary's internal memory management and error reporting. It validates thatorjsonproperly handles large input sizes and reports memory allocation failures gracefully.Test Framework (
pytest):
Usespytestdecorators and context managers for conditional skipping and exception assertion.Environment Configuration:
Relies on an external environment variable to parameterize test conditions, enabling flexible test runs across multiple environments or CI pipelines with different memory constraints.
Visual Diagram: Class and Function Structure
This file contains a single test function and no classes, so a flowchart representing the test function workflow is most appropriate.
flowchart TD
Start["Start test_memory_loads()"]
CheckEnv["Check ORJSON_RUNNER_MEMORY_GIB\n(environment variable)"]
SkipTest["Skip test if variable not set"]
CalculateSize["Calculate size of large string:\nsize = (memory in bytes) // buffer_factor // len(segment)"]
CreateDoc["Create large string 'doc' by repeating segment 'size' times"]
CallOrjson["Call orjson.loads(doc)"]
ExpectError["Expect orjson.JSONDecodeError exception"]
AssertMsg["Assert exception message matches\n\"Not enough memory to allocate buffer...\""]
End["Test passes if assertion succeeds"]
Start --> CheckEnv
CheckEnv -- Not Set --> SkipTest
CheckEnv -- Set --> CalculateSize
SkipTest --> End
CalculateSize --> CreateDoc
CreateDoc --> CallOrjson
CallOrjson --> ExpectError
ExpectError --> AssertMsg
AssertMsg --> End
Summary
File Name:
test_buffer.pyPurpose: Tests
orjsonJSON parsing under constrained memory conditions by attempting to parse a huge string and verifying appropriate exception handling.Key Function:
test_memory_loads()— conditionally runs based on environment variable, creates a large input, and asserts thatorjson.loads()raises a memory-related exception.Integration: Works closely with
orjsoninternals, depends on environment setup, and is executed viapytest.Use Case: Ensures robustness of
orjsonin low-memory environments or when parsing very large JSON inputs.
This test helps maintain the reliability and stability of the JSON parsing library in extreme memory usage scenarios, providing confidence that memory allocation failures are handled predictably.