161 lines
6.0 KiB
Python
161 lines
6.0 KiB
Python
import hashlib
|
|
import io
|
|
import tempfile
|
|
import unittest
|
|
import zipfile
|
|
from pathlib import Path
|
|
|
|
from deploy_tool.installer import (
|
|
MAVEN_ARCHIVE_NAME,
|
|
TOMCAT_VERSION,
|
|
install_maven,
|
|
install_tomcat,
|
|
build_install_command,
|
|
explain_install_failure,
|
|
format_install_output,
|
|
recommend_jdk_version,
|
|
)
|
|
from deploy_tool.scanner import scan_project
|
|
|
|
|
|
class InstallerTests(unittest.TestCase):
|
|
def test_recommends_jdk_8_from_maven_source_property(self):
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
root = Path(tmp)
|
|
backend = root / "server"
|
|
(backend / "src" / "main" / "java").mkdir(parents=True)
|
|
(backend / "pom.xml").write_text(
|
|
"""
|
|
<project>
|
|
<properties>
|
|
<maven.compiler.source>1.8</maven.compiler.source>
|
|
<maven.compiler.target>1.8</maven.compiler.target>
|
|
</properties>
|
|
<dependencies>
|
|
<dependency>spring-boot-starter-web</dependency>
|
|
</dependencies>
|
|
</project>
|
|
""",
|
|
encoding="utf-8",
|
|
)
|
|
|
|
scan = scan_project(root)
|
|
|
|
recommendation = recommend_jdk_version(scan)
|
|
self.assertEqual(recommendation.version, "8")
|
|
self.assertIn("maven.compiler.source", recommendation.reason)
|
|
|
|
def test_recommends_jdk_17_for_spring_boot_3(self):
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
root = Path(tmp)
|
|
backend = root / "server"
|
|
(backend / "src" / "main" / "java").mkdir(parents=True)
|
|
(backend / "pom.xml").write_text(
|
|
"""
|
|
<project>
|
|
<parent>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-starter-parent</artifactId>
|
|
<version>3.2.5</version>
|
|
</parent>
|
|
</project>
|
|
""",
|
|
encoding="utf-8",
|
|
)
|
|
|
|
scan = scan_project(root)
|
|
|
|
recommendation = recommend_jdk_version(scan)
|
|
self.assertEqual(recommendation.version, "17")
|
|
self.assertIn("Spring Boot 3", recommendation.reason)
|
|
|
|
def test_defaults_to_jdk_8_without_project_signal(self):
|
|
recommendation = recommend_jdk_version(None)
|
|
|
|
self.assertEqual(recommendation.version, "8")
|
|
self.assertIn("默认", recommendation.reason)
|
|
|
|
def test_builds_jdk_winget_install_command(self):
|
|
command = build_install_command("JDK", version="8")
|
|
|
|
self.assertEqual(command, ["winget", "install", "-e", "--id", "EclipseAdoptium.Temurin.8.JDK"])
|
|
|
|
def test_builds_node_winget_install_command(self):
|
|
command = build_install_command("Node.js")
|
|
|
|
self.assertEqual(command, ["winget", "install", "-e", "--id", "OpenJS.NodeJS.LTS"])
|
|
|
|
def test_maven_is_not_offered_as_an_invalid_winget_package(self):
|
|
with self.assertRaises(ValueError):
|
|
build_install_command("Maven")
|
|
|
|
def test_installs_maven_from_verified_apache_archive(self):
|
|
archive_buffer = io.BytesIO()
|
|
with zipfile.ZipFile(archive_buffer, "w") as archive:
|
|
archive.writestr("apache-maven-3.10.0/bin/mvn.cmd", "@echo off")
|
|
archive_bytes = archive_buffer.getvalue()
|
|
checksum = hashlib.sha512(archive_bytes).hexdigest().encode("ascii")
|
|
|
|
def opener(url, timeout):
|
|
return io.BytesIO(checksum if url.endswith(".sha512") else archive_bytes)
|
|
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
messages = []
|
|
executable = install_maven(messages.append, Path(tmp), opener)
|
|
|
|
self.assertTrue(executable.exists())
|
|
self.assertEqual(executable.read_text(), "@echo off")
|
|
self.assertTrue(any("校验通过" in message for message in messages))
|
|
|
|
def test_rejects_maven_archive_with_wrong_checksum(self):
|
|
def opener(url, timeout):
|
|
payload = ("0" * 128).encode("ascii") if url.endswith(".sha512") else b"not-a-zip"
|
|
return io.BytesIO(payload)
|
|
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
with self.assertRaisesRegex(RuntimeError, "SHA-512"):
|
|
install_maven(lambda _message: None, Path(tmp), opener)
|
|
self.assertFalse((Path(tmp) / MAVEN_ARCHIVE_NAME.removesuffix("-bin.zip")).exists())
|
|
|
|
def test_installs_tomcat_from_verified_apache_archive(self):
|
|
archive_buffer = io.BytesIO()
|
|
with zipfile.ZipFile(archive_buffer, "w") as archive:
|
|
archive.writestr(f"apache-tomcat-{TOMCAT_VERSION}/bin/catalina.bat", "@echo off")
|
|
archive_bytes = archive_buffer.getvalue()
|
|
checksum = hashlib.sha512(archive_bytes).hexdigest().encode("ascii")
|
|
|
|
def opener(url, timeout):
|
|
return io.BytesIO(checksum if url.endswith(".sha512") else archive_bytes)
|
|
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
executable = install_tomcat(lambda _message: None, Path(tmp), opener)
|
|
|
|
self.assertTrue(executable.exists())
|
|
self.assertEqual(executable.name, "catalina.bat")
|
|
|
|
def test_formats_winget_progress_without_garbled_bar(self):
|
|
raw = "████████████▒▒▒▒▒▒ 63%\r".encode("utf-8")
|
|
|
|
self.assertEqual(format_install_output(raw), ["安装进度: 63%"])
|
|
|
|
def test_keeps_readable_winget_text(self):
|
|
raw = "已找到 Eclipse Temurin JDK [EclipseAdoptium.Temurin.8.JDK]\n".encode("utf-8")
|
|
|
|
self.assertEqual(format_install_output(raw), ["已找到 Eclipse Temurin JDK [EclipseAdoptium.Temurin.8.JDK]"])
|
|
|
|
|
|
def test_explains_missing_maven_winget_package(self):
|
|
message = explain_install_failure(
|
|
"Maven",
|
|
2316632084,
|
|
["找不到与输入条件匹配的程序包。"],
|
|
)
|
|
|
|
self.assertIn("winget 当前源找不到 Maven 包", message)
|
|
self.assertIn("手动下载 Apache Maven", message)
|
|
self.assertIn("mvn.cmd", message)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|