Skip to content
Merged
Show file tree
Hide file tree
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
15 changes: 12 additions & 3 deletions airflow/api_connexion/schemas/pool_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,18 @@ def get_deferred_slots(obj: Pool) -> int:
return obj.deferred_slots()

@staticmethod
def get_open_slots(obj: Pool) -> float:
"""Return the open slots of the pool."""
return obj.open_slots()
def get_open_slots(obj: Pool) -> int:
"""
Return the open slots of the pool.

Unlimited pools (``slots == -1``) use ``float('inf')`` internally; the REST API
schema requires an integer, so we serialize that as ``-1`` (same convention as
``slots`` for unlimited).
"""
open_slots = obj.open_slots()
if isinstance(open_slots, float) and open_slots == float("inf"):
return -1
return int(open_slots)


class PoolCollection(NamedTuple):
Expand Down
22 changes: 17 additions & 5 deletions tests/api_connexion/schemas/test_pool_schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,22 +33,34 @@ def setup_method(self) -> None:
def teardown_method(self) -> None:
clear_db_pools()

@pytest.mark.parametrize(
("pool_name", "slots", "expected_open_slots"),
[
pytest.param("test_pool", 2, 2, id="finite_slots"),
pytest.param("unlimited_pool", -1, -1, id="unlimited_slots_serialized_as_minus_one"),
],
)
@provide_session
def test_serialize(self, session):
pool_model = Pool(pool="test_pool", slots=2, include_deferred=False)
def test_serialize(self, pool_name, slots, expected_open_slots, session):
"""Pools must serialize open_slots as an integer.

Unlimited pools (``slots == -1``) must not leak ``inf`` into the JSON
response since the OpenAPI schema declares ``open_slots`` as an integer.
"""
pool_model = Pool(pool=pool_name, slots=slots, include_deferred=False)
session.add(pool_model)
session.commit()
pool_instance = session.query(Pool).filter(Pool.pool == pool_model.pool).first()
serialized_pool = pool_schema.dump(pool_instance)
assert serialized_pool == {
"name": "test_pool",
"slots": 2,
"name": pool_name,
"slots": slots,
"occupied_slots": 0,
"running_slots": 0,
"queued_slots": 0,
"scheduled_slots": 0,
"deferred_slots": 0,
"open_slots": 2,
"open_slots": expected_open_slots,
"description": None,
"include_deferred": False,
}
Expand Down
Loading