test: verify go services are enabled
This commit is contained in:
@@ -167,7 +167,7 @@ python3 tools/go_systemd_prod_smoke.py --host 115.29.187.205 --user root
|
|||||||
python3 tools/go_native_prod_smoke.py --date 2026-07-02 --timeout 8
|
python3 tools/go_native_prod_smoke.py --date 2026-07-02 --timeout 8
|
||||||
```
|
```
|
||||||
|
|
||||||
`go_systemd_prod_smoke.py` 通过 SSH 检查四个 Go systemd 服务是否 `active`,并确认 `808`、`32960` 由 `gateway` 监听、`20210` 由 `realtime-api` 监听,避免旧 Java/Docker 进程占用生产端口。运行环境需要已配置 SSH 免密或已建立可用的 SSH 认证方式。
|
`go_systemd_prod_smoke.py` 通过 SSH 检查四个 Go systemd 服务是否 `active` 且 `enabled`,并确认 `808`、`32960` 由 `gateway` 监听、`20210` 由 `realtime-api` 监听,避免旧 Java/Docker 进程占用生产端口。运行环境需要已配置 SSH 免密或已建立可用的 SSH 认证方式。
|
||||||
|
|
||||||
`go_native_prod_smoke.py` 通过 `20210` HTTP API 验证 GB32960、JT808、宇通 MQTT 的 RAW 查询,三类协议的位置和里程点查询,GB32960/JT808 的 `daily_mileage_km`、`daily_total_mileage_km` 统计,以及三类协议的 Redis realtime snapshot、online、protocol 查询。默认检查今天东八区数据时,还会要求三类 RAW 最新样本不超过 15 分钟,避免旧数据误判为接收正常;任一检查不达标时退出码为非 0。
|
`go_native_prod_smoke.py` 通过 `20210` HTTP API 验证 GB32960、JT808、宇通 MQTT 的 RAW 查询,三类协议的位置和里程点查询,GB32960/JT808 的 `daily_mileage_km`、`daily_total_mileage_km` 统计,以及三类协议的 Redis realtime snapshot、online、protocol 查询。默认检查今天东八区数据时,还会要求三类 RAW 最新样本不超过 15 分钟,避免旧数据误判为接收正常;任一检查不达标时退出码为非 0。
|
||||||
|
|
||||||
@@ -212,7 +212,7 @@ journalctl -u lingniu-go-realtime-api --since '5 minutes ago' --no-pager
|
|||||||
|
|
||||||
2026-07-02 01:30 CST 已验证:
|
2026-07-02 01:30 CST 已验证:
|
||||||
|
|
||||||
- 四个 Go systemd 服务均为 `active`。
|
- 四个 Go systemd 服务均为 `active` 且 `enabled`。
|
||||||
- `gateway` 正在监听 `32960` 和 `808`。
|
- `gateway` 正在监听 `32960` 和 `808`。
|
||||||
- `realtime-api` 正在监听 `20210`。
|
- `realtime-api` 正在监听 `20210`。
|
||||||
- GB32960、JT808、YUTONG_MQTT 的东八区 RAW 查询均可命中生产数据。
|
- GB32960、JT808、YUTONG_MQTT 的东八区 RAW 查询均可命中生产数据。
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ python3 tools/go_prod_acceptance.py --date 2026-07-02
|
|||||||
|
|
||||||
该命令会聚合执行:
|
该命令会聚合执行:
|
||||||
|
|
||||||
- `go_systemd_prod_smoke.py`:应用 ECS systemd 服务和端口归属
|
- `go_systemd_prod_smoke.py`:应用 ECS systemd 服务 active/enabled 和端口归属
|
||||||
- `go_kafka_prod_smoke.py`:Kafka topic 和消费组 lag
|
- `go_kafka_prod_smoke.py`:Kafka topic 和消费组 lag
|
||||||
- `go_native_prod_smoke.py`:HTTP API、TDengine/MySQL/Redis 数据链路
|
- `go_native_prod_smoke.py`:HTTP API、TDengine/MySQL/Redis 数据链路
|
||||||
|
|
||||||
@@ -42,6 +42,7 @@ python3 tools/go_systemd_prod_smoke.py --host 115.29.187.205 --user root
|
|||||||
- `lingniu-go-history-writer.service`
|
- `lingniu-go-history-writer.service`
|
||||||
- `lingniu-go-stat-writer.service`
|
- `lingniu-go-stat-writer.service`
|
||||||
- `lingniu-go-realtime-api.service`
|
- `lingniu-go-realtime-api.service`
|
||||||
|
- 上述服务均为 `active` 且 `enabled`
|
||||||
- `808`、`32960` 由 `gateway` 监听
|
- `808`、`32960` 由 `gateway` 监听
|
||||||
- `20210` 由 `realtime-api` 监听
|
- `20210` 由 `realtime-api` 监听
|
||||||
|
|
||||||
|
|||||||
@@ -32,12 +32,19 @@ class Check:
|
|||||||
message: str
|
message: str
|
||||||
|
|
||||||
|
|
||||||
def parse_service_states(output: str) -> dict[str, str]:
|
@dataclass(frozen=True)
|
||||||
states: dict[str, str] = {}
|
class ServiceState:
|
||||||
|
active: str
|
||||||
|
enabled: str
|
||||||
|
|
||||||
|
|
||||||
|
def parse_service_states(output: str) -> dict[str, ServiceState]:
|
||||||
|
states: dict[str, ServiceState] = {}
|
||||||
for line in output.splitlines():
|
for line in output.splitlines():
|
||||||
parts = line.split()
|
parts = line.split()
|
||||||
if len(parts) >= 2:
|
if len(parts) >= 2:
|
||||||
states[parts[0]] = parts[1]
|
enabled = parts[2] if len(parts) >= 3 else "enabled"
|
||||||
|
states[parts[0]] = ServiceState(parts[1], enabled)
|
||||||
return states
|
return states
|
||||||
|
|
||||||
|
|
||||||
@@ -45,9 +52,13 @@ def service_checks(output: str, services: list[str]) -> list[Check]:
|
|||||||
states = parse_service_states(output)
|
states = parse_service_states(output)
|
||||||
checks: list[Check] = []
|
checks: list[Check] = []
|
||||||
for service in services:
|
for service in services:
|
||||||
state = states.get(service, "missing")
|
state = states.get(service, ServiceState("missing", "missing"))
|
||||||
status = "pass" if state == "active" else "fail"
|
status = "pass" if state.active == "active" and state.enabled == "enabled" else "fail"
|
||||||
checks.append(Check("service." + service, status, "state=" + state))
|
checks.append(Check(
|
||||||
|
"service." + service,
|
||||||
|
status,
|
||||||
|
"state=" + state.active + "; enabled=" + state.enabled,
|
||||||
|
))
|
||||||
return checks
|
return checks
|
||||||
|
|
||||||
|
|
||||||
@@ -89,7 +100,9 @@ def remote_command(services: list[str]) -> str:
|
|||||||
quoted = " ".join(services)
|
quoted = " ".join(services)
|
||||||
return (
|
return (
|
||||||
"for svc in " + quoted + "; do "
|
"for svc in " + quoted + "; do "
|
||||||
"printf '%s ' \"$svc\"; systemctl is-active \"$svc\" || true; "
|
"printf '%s ' \"$svc\"; "
|
||||||
|
"printf '%s ' \"$(systemctl is-active \"$svc\" 2>/dev/null || true)\"; "
|
||||||
|
"systemctl is-enabled \"$svc\" 2>/dev/null || true; "
|
||||||
"done; "
|
"done; "
|
||||||
"printf '\\n--PORTS--\\n'; "
|
"printf '\\n--PORTS--\\n'; "
|
||||||
"ss -lntp"
|
"ss -lntp"
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ from tools import go_systemd_prod_smoke as smoke
|
|||||||
class GoSystemdProdSmokeTest(unittest.TestCase):
|
class GoSystemdProdSmokeTest(unittest.TestCase):
|
||||||
def test_service_checks_require_all_go_units_active(self):
|
def test_service_checks_require_all_go_units_active(self):
|
||||||
output = """
|
output = """
|
||||||
lingniu-go-gateway.service active
|
lingniu-go-gateway.service active enabled
|
||||||
lingniu-go-history-writer.service active
|
lingniu-go-history-writer.service active enabled
|
||||||
lingniu-go-stat-writer.service active
|
lingniu-go-stat-writer.service active enabled
|
||||||
lingniu-go-realtime-api.service active
|
lingniu-go-realtime-api.service active enabled
|
||||||
"""
|
"""
|
||||||
|
|
||||||
checks = smoke.service_checks(output, smoke.DEFAULT_SERVICES)
|
checks = smoke.service_checks(output, smoke.DEFAULT_SERVICES)
|
||||||
@@ -18,8 +18,8 @@ lingniu-go-realtime-api.service active
|
|||||||
|
|
||||||
def test_service_checks_fail_when_unit_is_missing_or_inactive(self):
|
def test_service_checks_fail_when_unit_is_missing_or_inactive(self):
|
||||||
output = """
|
output = """
|
||||||
lingniu-go-gateway.service active
|
lingniu-go-gateway.service active enabled
|
||||||
lingniu-go-history-writer.service failed
|
lingniu-go-history-writer.service failed enabled
|
||||||
"""
|
"""
|
||||||
|
|
||||||
checks = smoke.service_checks(output, smoke.DEFAULT_SERVICES)
|
checks = smoke.service_checks(output, smoke.DEFAULT_SERVICES)
|
||||||
@@ -28,6 +28,20 @@ lingniu-go-history-writer.service failed
|
|||||||
self.assertEqual(by_name["service.lingniu-go-history-writer.service"].status, "fail")
|
self.assertEqual(by_name["service.lingniu-go-history-writer.service"].status, "fail")
|
||||||
self.assertEqual(by_name["service.lingniu-go-stat-writer.service"].status, "fail")
|
self.assertEqual(by_name["service.lingniu-go-stat-writer.service"].status, "fail")
|
||||||
|
|
||||||
|
def test_service_checks_fail_when_unit_is_not_enabled(self):
|
||||||
|
output = """
|
||||||
|
lingniu-go-gateway.service active disabled
|
||||||
|
lingniu-go-history-writer.service active enabled
|
||||||
|
lingniu-go-stat-writer.service active enabled
|
||||||
|
lingniu-go-realtime-api.service active enabled
|
||||||
|
"""
|
||||||
|
|
||||||
|
checks = smoke.service_checks(output, smoke.DEFAULT_SERVICES)
|
||||||
|
by_name = {check.name: check for check in checks}
|
||||||
|
|
||||||
|
self.assertEqual(by_name["service.lingniu-go-gateway.service"].status, "fail")
|
||||||
|
self.assertIn("enabled=disabled", by_name["service.lingniu-go-gateway.service"].message)
|
||||||
|
|
||||||
def test_port_checks_require_expected_go_processes(self):
|
def test_port_checks_require_expected_go_processes(self):
|
||||||
output = """
|
output = """
|
||||||
LISTEN 0 4096 *:32960 *:* users:(("gateway",pid=10,fd=3))
|
LISTEN 0 4096 *:32960 *:* users:(("gateway",pid=10,fd=3))
|
||||||
|
|||||||
Reference in New Issue
Block a user