mirror of
https://github.com/hansjone/netx.git
synced 2026-10-09 02:00:46 +08:00
fix(UME): 兼容首批无marker场景并补充回归测试
告警分页在响应头缺失 marker 时直接结束迭代,避免首批已全量却重复翻页;同时补充对应单测并保持 HTTPTransport 传输方式与现网一致。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
2c0b52d972
commit
00afaaae3d
3 changed files with 35 additions and 4 deletions
|
|
@ -177,8 +177,9 @@ class UMEClient:
|
|||
def _client(self) -> httpx.Client:
|
||||
# Use explicit HTTPTransport to keep behavior consistent with onsite validation.
|
||||
# In this mode, requests run over HTTP/1.1 and avoid HTTP/2 negotiation issues.
|
||||
transport = httpx.HTTPTransport()
|
||||
return httpx.Client(verify=self.verify_tls, timeout=self.timeout_s, transport=transport)
|
||||
transport = httpx.HTTPTransport(verify=self.verify_tls, http2=False)
|
||||
return httpx.Client(transport=transport, timeout=self.timeout_s)
|
||||
|
||||
|
||||
def _extract_token_and_ttl(self, payload: dict[str, Any]) -> tuple[str, int | None]:
|
||||
token = ""
|
||||
|
|
|
|||
|
|
@ -282,8 +282,12 @@ def _sync_alarms_common(
|
|||
next_marker = str(diag.marker or "").strip()
|
||||
if is_end_of_reply:
|
||||
break
|
||||
# marker paging: no marker and empty data means no next page.
|
||||
if not next_marker and not rows:
|
||||
# marker paging: if response header has no marker, treat as end of iteration.
|
||||
# Some UME deployments omit marker when the first page already contains all rows.
|
||||
if not next_marker:
|
||||
if rows:
|
||||
warnings.append("marker_missing_stop")
|
||||
paging_note = "marker_missing_stop"
|
||||
break
|
||||
|
||||
if not is_uncleared:
|
||||
|
|
|
|||
|
|
@ -281,6 +281,32 @@ class UmeSyncServiceTests(unittest.TestCase):
|
|||
self.assertEqual(job.pulled_count, 1)
|
||||
self.assertIsNotNone(self.db.get(UmeAlarmCurrent, "AK-1"))
|
||||
|
||||
def test_sync_current_alarms_stop_when_marker_missing(self):
|
||||
class _C:
|
||||
def __init__(self):
|
||||
self.calls = 0
|
||||
|
||||
def get_alarms(self, *, is_uncleared: bool, limit=None, marker=None):
|
||||
self.calls += 1
|
||||
|
||||
class _D:
|
||||
marker = ""
|
||||
is_end_of_reply = None
|
||||
|
||||
return (
|
||||
[
|
||||
{"alarmKey": "AK-1", "ne-id": "NE-1", "perceivedSeverity": "major", "isCleared": "false"},
|
||||
],
|
||||
_D(),
|
||||
)
|
||||
|
||||
c = _C()
|
||||
job, _ = sync_alarms_current(self.db, c, trigger_mode="manual")
|
||||
self.assertEqual(job.status, "done")
|
||||
self.assertEqual(job.pulled_count, 1)
|
||||
self.assertEqual(c.calls, 1)
|
||||
self.assertIsNotNone(self.db.get(UmeAlarmCurrent, "AK-1"))
|
||||
|
||||
def test_derive_ne_id_from_alarmkey_formats(self):
|
||||
alarm_hash = {"alarmkey": "00ceb960-1b62-478e-8303-0935ffea1d28#99010"}
|
||||
alarm_csv = {"alarmkey": "00ceb960-1b62-478e-8303-0935ffea1d28, 4237, 79"}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue