246 lines
10 KiB
Python
246 lines
10 KiB
Python
from __future__ import annotations
|
|
|
|
import unittest
|
|
from unittest.mock import patch
|
|
|
|
from core.config import HARBOR_PROJECT, HARBOR_REGISTRY
|
|
from monitors.yumi.service_release import build_update_targets_payload, deploy_updated_services_payload
|
|
|
|
|
|
class ServiceReleaseTargetsTests(unittest.TestCase):
|
|
@patch("monitors.yumi.service_release.gateway_clb_configuration_error", return_value="gateway CLB protection requires .env")
|
|
@patch("monitors.yumi.service_release.frontend_release_enabled", return_value=False)
|
|
@patch("monitors.yumi.service_release.service_repository_ref", side_effect=lambda service: f"repo/{service}")
|
|
@patch("monitors.yumi.service_release.buildable_service_names", return_value=["gateway"])
|
|
@patch("monitors.yumi.service_release.service_records_by_name")
|
|
@patch("monitors.yumi.service_release.load_local_host_compose_model")
|
|
def test_build_update_targets_payload_adds_gateway_clb_warning(
|
|
self,
|
|
load_local_host_compose_model_mock,
|
|
service_records_by_name_mock,
|
|
buildable_service_names_mock,
|
|
service_repository_ref_mock,
|
|
frontend_release_enabled_mock,
|
|
gateway_clb_configuration_error_mock,
|
|
) -> None:
|
|
del buildable_service_names_mock
|
|
del service_repository_ref_mock
|
|
del frontend_release_enabled_mock
|
|
del gateway_clb_configuration_error_mock
|
|
service_records_by_name_mock.return_value = {
|
|
"gateway": [
|
|
{
|
|
"host": "gateway-1",
|
|
"ip": "10.0.0.1",
|
|
"instanceId": "ins-gateway-1",
|
|
"port": 8080,
|
|
"path": "/health",
|
|
}
|
|
]
|
|
}
|
|
load_local_host_compose_model_mock.return_value = {
|
|
"services": {
|
|
"gateway": {"image": "registry/gateway:main"},
|
|
}
|
|
}
|
|
|
|
payload = build_update_targets_payload()
|
|
|
|
self.assertTrue(payload["ok"])
|
|
self.assertEqual(payload["items"][0]["warnings"], ["gateway CLB protection requires .env"])
|
|
|
|
@patch("monitors.yumi.service_release.frontend_release_enabled", return_value=False)
|
|
@patch("monitors.yumi.service_release.service_repository_ref", side_effect=lambda service: f"repo/{service}")
|
|
@patch("monitors.yumi.service_release.buildable_service_names", return_value=["auth", "gateway"])
|
|
@patch("monitors.yumi.service_release.service_records_by_name")
|
|
@patch("monitors.yumi.service_release.load_local_host_compose_model")
|
|
def test_build_update_targets_payload_reuses_host_compose_model(
|
|
self,
|
|
load_local_host_compose_model_mock,
|
|
service_records_by_name_mock,
|
|
buildable_service_names_mock,
|
|
service_repository_ref_mock,
|
|
frontend_release_enabled_mock,
|
|
) -> None:
|
|
del buildable_service_names_mock, service_repository_ref_mock, frontend_release_enabled_mock
|
|
service_records_by_name_mock.return_value = {
|
|
"auth": [
|
|
{
|
|
"host": "app-1",
|
|
"ip": "10.0.0.1",
|
|
"instanceId": "ins-app-1",
|
|
"port": 8080,
|
|
"path": "/auth",
|
|
}
|
|
],
|
|
"gateway": [
|
|
{
|
|
"host": "app-1",
|
|
"ip": "10.0.0.1",
|
|
"instanceId": "ins-app-1",
|
|
"port": 9000,
|
|
"path": "/gateway",
|
|
}
|
|
],
|
|
}
|
|
load_local_host_compose_model_mock.return_value = {
|
|
"services": {
|
|
"auth": {"image": "registry/auth:main"},
|
|
"gateway": {"image": "registry/gateway:main"},
|
|
}
|
|
}
|
|
|
|
payload = build_update_targets_payload()
|
|
|
|
self.assertTrue(payload["ok"])
|
|
self.assertEqual(load_local_host_compose_model_mock.call_count, 1)
|
|
self.assertEqual([item["service"] for item in payload["items"]], ["auth", "gateway"])
|
|
self.assertEqual(payload["items"][0]["currentImages"], ["registry/auth:main"])
|
|
self.assertEqual(payload["items"][1]["currentImages"], ["registry/gateway:main"])
|
|
|
|
@patch("monitors.yumi.service_release.frontend_release_enabled", return_value=False)
|
|
@patch("monitors.yumi.service_release.service_repository_ref", side_effect=lambda service: f"repo/{service}")
|
|
@patch("monitors.yumi.service_release.buildable_service_names", return_value=["auth"])
|
|
@patch("monitors.yumi.service_release.service_records_by_name")
|
|
@patch("monitors.yumi.service_release.load_local_host_compose_model", side_effect=RuntimeError("broken compose"))
|
|
def test_build_update_targets_payload_keeps_items_when_compose_unavailable(
|
|
self,
|
|
load_local_host_compose_model_mock,
|
|
service_records_by_name_mock,
|
|
buildable_service_names_mock,
|
|
service_repository_ref_mock,
|
|
frontend_release_enabled_mock,
|
|
) -> None:
|
|
del load_local_host_compose_model_mock
|
|
del buildable_service_names_mock, service_repository_ref_mock, frontend_release_enabled_mock
|
|
service_records_by_name_mock.return_value = {
|
|
"auth": [
|
|
{
|
|
"host": "app-1",
|
|
"ip": "10.0.0.1",
|
|
"instanceId": "ins-app-1",
|
|
"port": 8080,
|
|
"path": "/auth",
|
|
}
|
|
]
|
|
}
|
|
|
|
payload = build_update_targets_payload()
|
|
|
|
self.assertTrue(payload["ok"])
|
|
self.assertEqual(len(payload["items"]), 1)
|
|
self.assertEqual(payload["items"][0]["currentImages"], [])
|
|
self.assertEqual(payload["items"][0]["warnings"], ["app-1: broken compose"])
|
|
|
|
@patch("monitors.yumi.service_release.frontend_release_enabled", return_value=False)
|
|
@patch("monitors.yumi.service_release.buildable_service_names", return_value=["auth"])
|
|
@patch("monitors.yumi.service_release.service_records_by_name")
|
|
@patch("monitors.yumi.service_release.load_local_host_compose_model", side_effect=RuntimeError("broken compose"))
|
|
def test_build_update_targets_payload_falls_back_repository_when_compose_unavailable(
|
|
self,
|
|
load_local_host_compose_model_mock,
|
|
service_records_by_name_mock,
|
|
buildable_service_names_mock,
|
|
frontend_release_enabled_mock,
|
|
) -> None:
|
|
del load_local_host_compose_model_mock
|
|
del buildable_service_names_mock, frontend_release_enabled_mock
|
|
service_records_by_name_mock.return_value = {
|
|
"auth": [
|
|
{
|
|
"host": "app-1",
|
|
"ip": "10.0.0.1",
|
|
"instanceId": "ins-app-1",
|
|
"port": 8080,
|
|
"path": "/auth",
|
|
}
|
|
]
|
|
}
|
|
|
|
payload = build_update_targets_payload()
|
|
|
|
self.assertTrue(payload["ok"])
|
|
self.assertEqual(len(payload["items"]), 1)
|
|
self.assertEqual(payload["items"][0]["repository"], f"{HARBOR_REGISTRY}/{HARBOR_PROJECT}/java/chatapp3-auth")
|
|
|
|
@patch("monitors.yumi.service_release.ADMIN_FRONTEND_INSTANCE_ID", "ins-admin")
|
|
@patch("monitors.yumi.service_release.ADMIN_FRONTEND_IP", "10.2.1.2")
|
|
@patch("monitors.yumi.service_release.ADMIN_FRONTEND_HOST", "admin-platform")
|
|
@patch("monitors.yumi.service_release.ADMIN_FRONTEND_REPO_URL", "git@example.com:hy/chatapp3-admin.git")
|
|
@patch("monitors.yumi.service_release.ADMIN_FRONTEND_SITE_DIR", "/opt/yumi-admin/frontend-admin/site")
|
|
@patch("monitors.yumi.service_release.frontend_release_enabled", return_value=True)
|
|
@patch(
|
|
"monitors.yumi.service_release.frontend_release_display",
|
|
return_value={
|
|
"currentLabel": "main@abc123",
|
|
"currentTitle": "abc123",
|
|
"detailLabel": "abc123",
|
|
"detailTitle": "abc123",
|
|
"copyValue": "abc123",
|
|
},
|
|
)
|
|
@patch("monitors.yumi.service_release.buildable_service_names", return_value=["admin"])
|
|
@patch("monitors.yumi.service_release.service_records_by_name", return_value={})
|
|
def test_build_update_targets_payload_adds_admin_frontend_target(
|
|
self,
|
|
service_records_by_name_mock,
|
|
buildable_service_names_mock,
|
|
frontend_release_display_mock,
|
|
frontend_release_enabled_mock,
|
|
) -> None:
|
|
del service_records_by_name_mock, buildable_service_names_mock
|
|
del frontend_release_display_mock, frontend_release_enabled_mock
|
|
|
|
payload = build_update_targets_payload()
|
|
|
|
self.assertTrue(payload["ok"])
|
|
self.assertEqual(len(payload["items"]), 1)
|
|
admin = payload["items"][0]
|
|
self.assertEqual(admin["service"], "admin")
|
|
self.assertEqual(admin["kind"], "frontend")
|
|
self.assertEqual(admin["repository"], "git@example.com:hy/chatapp3-admin.git")
|
|
self.assertEqual(admin["hosts"][0]["host"], "admin-platform")
|
|
self.assertEqual(admin["hosts"][0]["ip"], "10.2.1.2")
|
|
|
|
@patch("monitors.yumi.service_release.frontend_release_enabled", return_value=True)
|
|
@patch("monitors.yumi.service_release.service_records_by_name", return_value={})
|
|
@patch(
|
|
"monitors.yumi.service_release.deploy_frontend_site",
|
|
return_value={
|
|
"ok": True,
|
|
"updatedAt": "2026-04-24T00:00:00+00:00",
|
|
"services": ["admin"],
|
|
"build": [{"kind": "frontend", "gitRef": "release/admin", "commit": "abc123"}],
|
|
"templates": [],
|
|
"preparedHosts": [],
|
|
"steps": [{"service": "admin", "host": "admin-platform", "status": "success"}],
|
|
"message": "service update complete",
|
|
},
|
|
)
|
|
def test_deploy_updated_services_payload_dispatches_admin_frontend(
|
|
self,
|
|
deploy_frontend_site_mock,
|
|
service_records_by_name_mock,
|
|
frontend_release_enabled_mock,
|
|
) -> None:
|
|
del service_records_by_name_mock, frontend_release_enabled_mock
|
|
|
|
payload = deploy_updated_services_payload(
|
|
["admin"],
|
|
java_git_ref="main",
|
|
go_git_ref="main",
|
|
admin_git_ref="release/admin",
|
|
image_tag="",
|
|
skip_maven_build=False,
|
|
)
|
|
|
|
deploy_frontend_site_mock.assert_called_once_with("admin", git_ref="release/admin", progress=None)
|
|
self.assertTrue(payload["ok"])
|
|
self.assertEqual(payload["services"], ["admin"])
|
|
self.assertEqual(payload["build"][0]["kind"], "frontend")
|
|
self.assertEqual(payload["steps"][0]["service"], "admin")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|