Files
scylladb/test/cluster/test_rest_api_on_startup.py
Andrzej Jackowski 1ff7f5941b test: add test_rest_api_on_startup
This test verifies that REST API requests are handled properly
when a server is started or restarted. It is used to verify
the fix for scylladb/scylladb#27130, where a server failed with a
segmentation fault when `storage_service/raft_topology/reload` was
called too early.

Refs: scylladb/scylladb#27130
2025-12-03 15:35:59 +01:00

64 lines
2.1 KiB
Python

# Copyright (C) 2025-present ScyllaDB
#
# SPDX-License-Identifier: LicenseRef-ScyllaDB-Source-Available-1.0
from test.pylib.manager_client import ManagerClient
import asyncio
from datetime import datetime, timedelta
import pytest
import logging
import time
from test.pylib.rest_client import HTTPError
logger = logging.getLogger(__name__)
@pytest.mark.asyncio
async def test_rest_api_on_startup(request, manager: ManagerClient):
host = None
stop_loop = False
# Asynchronously keep sending a REST API request in a loop.
# This lets us verify that the server doesn't crash when it is
# started or restarted while requests are ongoing.
async def test_rest_api():
timeout = 60 # seconds
start_time = time.time()
while True:
if time.time() - start_time > timeout:
raise TimeoutError
try:
logger.info(f"Sending raft_topology/reload request")
result = await manager.api.client.post("/storage_service/raft_topology/reload", host=host)
logger.info(f"Received result {result}")
if stop_loop:
return
except Exception as ex:
# Some errors are expected, for example:
# - Initially, `host=None`, so `manager.api.client.post` fails
# - Scylla returns 404 until the `/storage_service/raft_topology/reload` endpoint exists
# - aiohttp raises ClientConnectorError when it cannot connect
# This is okay. The important point is that ScyllaDB does not crash,
# so the final request should succeed.
pass
# Avoid spamming requests to prevent log flooding.
# One request per millisecond should be sufficient to expose issues.
await asyncio.sleep(0.001)
fut = asyncio.create_task(test_rest_api())
logger.info("Starting server")
server = await manager.server_add()
host = server.ip_addr
logger.info("Restarting server")
await manager.server_restart(server.server_id)
logger.info("Stopping the loop")
stop_loop = True
await fut