Add SSM deployment and reliable Maven setup

This commit is contained in:
王鹏
2026-10-08 17:58:09 +08:00
parent 2d7b6216ba
commit d1695eba74
13 changed files with 626 additions and 46 deletions

View File

@@ -182,6 +182,30 @@ class DeployerTests(unittest.TestCase):
self.assertEqual(exit_code, 1)
self.assertEqual(terminated, [27544])
def test_tomcat_restart_accepts_port_owned_by_batch_child_process(self):
class RunningProcess:
pid = 27544
def poll(self):
return None
with (
TemporaryDirectory() as temp,
patch.object(deployer_module, "_is_port_open", return_value=True),
patch.object(deployer_module, "_find_listening_pids", return_value={31000}),
):
exit_code = deployer_module._restart_backend(
["catalina.bat", "run"],
Path(temp),
lambda _value: None,
port=8080,
require_service_pid=False,
replace_listeners=lambda _port, _output: True,
popen=lambda *args, **kwargs: RunningProcess(),
)
self.assertEqual(exit_code, 0)
def test_backend_restart_terminates_child_after_startup_timeout(self):
restart_backend = getattr(deployer_module, "_restart_backend", lambda *args, **kwargs: 0)
terminated = []
@@ -496,6 +520,64 @@ class DeployerTests(unittest.TestCase):
self.assertEqual(plan[0].command, [str(maven), "clean", "package", "-DskipTests"])
def test_deploys_ssm_war_to_configured_tomcat(self):
with TemporaryDirectory() as temp:
root = Path(temp)
backend = root / "ssm-server"
target = backend / "target"
tomcat = root / "apache-tomcat" / "bin" / "catalina.bat"
target.mkdir(parents=True)
tomcat.parent.mkdir(parents=True)
tomcat.write_text("@echo off", encoding="utf-8")
source_war = target / "movies.war"
source_war.write_text("war-content", encoding="utf-8")
scan = ScanResult(
root=root,
backend=ProjectComponent(
"SSM", backend, "Maven SSM WAR", {"backend_type": "ssm", "context_path": "/movies"}
),
frontend=None,
sql_files=[],
)
config = DeploymentConfig(
output_dir=root / "deploy",
tool_paths={"Tomcat": tomcat},
tool_search_roots=[root / "missing"],
)
plan = build_deployment_plan(scan, config)
self.assertEqual([step.kind for step in plan], ["backend_build_skip", "ssm_start", "deployment_summary"])
start_step = plan[1]
self.assertEqual(start_step.command, [str(tomcat.resolve()), "run"])
self.assertEqual(start_step.output_path, tomcat.parent.parent / "webapps" / "movies.war")
self.assertEqual(start_step.url, "http://localhost:8080/movies")
calls = []
def fake_runner(command, cwd, on_output, input_path=None, background=False):
calls.append((command, cwd, background))
return 0
self.assertEqual(run_steps(plan, lambda _line: None, process_runner=fake_runner), 0)
self.assertEqual((tomcat.parent.parent / "webapps" / "movies.war").read_text(), "war-content")
self.assertIn(([str(tomcat.resolve()), "run"], root / "deploy", True), calls)
def test_ssm_plan_requires_tomcat(self):
with TemporaryDirectory() as temp:
root = Path(temp)
backend = root / "ssm-server"
backend.mkdir()
scan = ScanResult(
root=root,
backend=ProjectComponent("SSM", backend, "SSM", {"backend_type": "ssm", "context_path": "/app"}),
frontend=None,
sql_files=[],
)
with self.assertRaisesRegex(FileNotFoundError, "需要 Tomcat"):
build_deployment_plan(scan, DeploymentConfig(tool_search_roots=[root / "missing"]))
def test_plan_uses_discovered_mysql_path_for_sql_import(self):
with TemporaryDirectory() as temp:
root = Path(temp)