From fe98a5d932c8935ef4b8d4fa9aa1926f61e31b20 Mon Sep 17 00:00:00 2001 From: "Dmitry.Yudin" Date: Tue, 20 May 2025 16:33:32 +0200 Subject: [PATCH] Add Maven repository path resolution tests Introduced unit tests for Maven repository path resolution logic GitOrigin-RevId: cd3b32529d8a0c49f708fcc56e5827d8576b7225 --- .../intellij/build/MavenRepositoryPathUtil.kt | 6 +- .../intellij.platform.buildScripts.tests.iml | 2 + .../build/MavenRepositoryPathUtilTest.kt | 189 ++++++++++++++++++ 3 files changed, 196 insertions(+), 1 deletion(-) create mode 100644 platform/build-scripts/tests/testSrc/org/jetbrains/intellij/build/MavenRepositoryPathUtilTest.kt diff --git a/platform/build-scripts/src/org/jetbrains/intellij/build/MavenRepositoryPathUtil.kt b/platform/build-scripts/src/org/jetbrains/intellij/build/MavenRepositoryPathUtil.kt index 63aadb2987c2..06b03c278550 100644 --- a/platform/build-scripts/src/org/jetbrains/intellij/build/MavenRepositoryPathUtil.kt +++ b/platform/build-scripts/src/org/jetbrains/intellij/build/MavenRepositoryPathUtil.kt @@ -8,6 +8,7 @@ import io.opentelemetry.api.common.AttributeKey import io.opentelemetry.api.common.Attributes import io.opentelemetry.api.trace.Span import org.jdom.Element +import org.jetbrains.annotations.TestOnly import org.jetbrains.jps.model.serialization.JpsMavenSettings import java.io.File import java.nio.file.Path @@ -66,4 +67,7 @@ private fun findMavenRepositoryProperty(mavenOpts: String?): String? { private fun File.getRepositoryFromSettings(): String? { val element = runCatching { JDOMUtil.load(this) }.getOrNull() return element?.content?.firstOrNull { (it as? Element)?.name == "localRepository" }?.value -} \ No newline at end of file +} + +@TestOnly +fun getMavenRepositoryPathTest(span: Span? = null): Path = getMavenRepositoryPath(span) \ No newline at end of file diff --git a/platform/build-scripts/tests/intellij.platform.buildScripts.tests.iml b/platform/build-scripts/tests/intellij.platform.buildScripts.tests.iml index 2006e98e7d09..abe7a890e34d 100644 --- a/platform/build-scripts/tests/intellij.platform.buildScripts.tests.iml +++ b/platform/build-scripts/tests/intellij.platform.buildScripts.tests.iml @@ -32,5 +32,7 @@ + + \ No newline at end of file diff --git a/platform/build-scripts/tests/testSrc/org/jetbrains/intellij/build/MavenRepositoryPathUtilTest.kt b/platform/build-scripts/tests/testSrc/org/jetbrains/intellij/build/MavenRepositoryPathUtilTest.kt new file mode 100644 index 000000000000..f89b0d78e7b0 --- /dev/null +++ b/platform/build-scripts/tests/testSrc/org/jetbrains/intellij/build/MavenRepositoryPathUtilTest.kt @@ -0,0 +1,189 @@ +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package org.jetbrains.intellij.build + +import com.intellij.util.EnvironmentUtil +import io.opentelemetry.api.common.AttributeKey +import io.opentelemetry.api.common.Attributes +import io.opentelemetry.api.trace.Span +import org.jetbrains.jps.model.serialization.JpsMavenSettings +import org.junit.jupiter.api.AfterEach +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.io.TempDir +import org.mockito.MockedStatic +import org.mockito.Mockito +import java.io.File +import java.nio.file.Path +import kotlin.io.path.Path + +class MavenRepositoryPathUtilTest { + + companion object { + private val mockEnv: MockedStatic = Mockito.mockStatic(EnvironmentUtil::class.java) + private val mockFile = Mockito.mock(File::class.java) + private val mockSpan = Mockito.mock(Span::class.java) + } + + private val defaultRepositoryPath = Path(System.getProperty("user.home"), ".m2/repository") + + @AfterEach + fun afterEach() { + mockEnv.reset() + Mockito.reset(mockFile, mockSpan) + } + + @Test + fun `test getMavenRepositoryPath returns default path when no settings exist`() { + mockEnv.`when` { EnvironmentUtil.getValue("MAVEN_OPTS") } + .thenReturn(null) + + Mockito.`when`(mockFile.exists()) + .thenReturn(false) + + val path = getMavenRepositoryPathTest(mockSpan) + Assertions.assertEquals(defaultRepositoryPath, path) + + Mockito.verify(mockSpan, Mockito.never()).addEvent( + Mockito.anyString(), + Mockito.any(Attributes::class.java), + ) + } + + @Test + fun `test getMavenRepositoryPath with MAVEN_OPTS env`(@TempDir tempDir: Path) { + val testPathMvn = "/custom/maven/re.po" + val testPathXml = "/fail/test/path" + val mavenOpts = "-Dmaven.repo.local=$testPathMvn" + + mockEnv.`when` { EnvironmentUtil.getValue("MAVEN_OPTS") } + .thenReturn(mavenOpts) + + val settingsContent = """ + + ${testPathXml} + + """.trimIndent() + val settingsFile = tempDir.resolve(".m2/settings.xml").toFile() + settingsFile.parentFile.mkdirs() + settingsFile.writeText(settingsContent) + + val mockSettingsXml = Mockito.mockStatic(JpsMavenSettings::class.java) + mockSettingsXml.`when` { JpsMavenSettings.getUserMavenSettingsXml() } + .thenReturn(settingsFile) + + val path = getMavenRepositoryPathTest(mockSpan) + Assertions.assertEquals(testPathMvn, path.toString()) + + Mockito.verify(mockSpan).addEvent( + "Found MAVEN_OPTS system env", + Attributes.of(AttributeKey.stringKey("local maven repository path"), testPathMvn), + ) + mockSettingsXml.close() + } + + @Test + fun `test getMavenRepositoryPath with no maven_repo_local in MAVEN_OPTS env`() { + mockEnv.`when` { EnvironmentUtil.getValue("MAVEN_OPTS") } + .thenReturn("-Xmx2g -Dother.property=value") + + Mockito.`when`(mockFile.exists()) + .thenReturn(false) + + val result = getMavenRepositoryPathTest(null) + Assertions.assertEquals(defaultRepositoryPath, result) + } + + @Test + fun `test getMavenRepositoryPath from settings xml`(@TempDir tempDir: Path) { + val settingsFile = tempDir.resolve(".m2/settings.xml").toFile() + val customRepoPath = tempDir.resolve("custom-repo") + + getMavenRepositoryPathFromSettings(settingsFile, customRepoPath) + } + + @Test + fun `test getMavenRepositoryPath from settings xml unix path`(@TempDir tempDir: Path) { + val settingsFile = tempDir.resolve(".m2/settings.xml").toFile() + val customRepoPath = Path("/usr/local/maven/repository") + + getMavenRepositoryPathFromSettings(settingsFile, customRepoPath) + } + + @Test + fun `test getMavenRepositoryPath from settings xml windows path`(@TempDir tempDir: Path) { + val settingsFile = tempDir.resolve(".m2/settings.xml").toFile() + val customRepoPath = Path("C:\\Users\\user name\\maven\\repository") + + getMavenRepositoryPathFromSettings(settingsFile, customRepoPath) + } + + @Test + fun `test getMavenRepositoryPath from settings xml empty file`(@TempDir tempDir: Path) { + mockEnv.`when` { EnvironmentUtil.getValue("MAVEN_OPTS") } + .thenReturn(null) + + val settingsFile = tempDir.resolve(".m2/settings.xml").toFile() + + settingsFile.parentFile.mkdirs() + settingsFile.writeText("") + + val mockSettingsXml = Mockito.mockStatic(JpsMavenSettings::class.java) + mockSettingsXml.`when` { JpsMavenSettings.getUserMavenSettingsXml() } + .thenReturn(settingsFile) + + val path = getMavenRepositoryPathTest(mockSpan) + Assertions.assertEquals(defaultRepositoryPath, path) + + mockSettingsXml.close() + } + + @Test + fun `test findMavenRepositoryProperty extracts repository path unix`() { + val testPath = "/test/repo/path" + val mavenOpts = "-Xmx2g -Dtest=1 -Dmaven.repo.local=$testPath -Dproperty=value -Dprop" + mockEnv.`when` { EnvironmentUtil.getValue("MAVEN_OPTS") } + .thenReturn(mavenOpts) + + val result = getMavenRepositoryPathTest().toString() + Assertions.assertEquals(testPath, result) + } + + @Test + fun `test findMavenRepositoryProperty extracts repository path windows`() { + val testPath = "C:\\user test\\repo\\path" + val mavenOpts = "-Xmx2g -Dprop -Dtest=1 -Dmaven.repo.local=\"$testPath\" -Dproperty=value" + mockEnv.`when` { EnvironmentUtil.getValue("MAVEN_OPTS") } + .thenReturn(mavenOpts) + + val result = getMavenRepositoryPathTest().toString() + Assertions.assertEquals(testPath, result) + } + + private fun getMavenRepositoryPathFromSettings(settingsFile: File, repositoryPath: Path) { + mockEnv.`when` { EnvironmentUtil.getValue("MAVEN_OPTS") } + .thenReturn(null) + + val settingsContent = """ + + ${repositoryPath} + + """.trimIndent() + + val settingsFile = settingsFile + settingsFile.parentFile.mkdirs() + settingsFile.writeText(settingsContent) + + val mockSettingsXml = Mockito.mockStatic(JpsMavenSettings::class.java) + mockSettingsXml.`when` { JpsMavenSettings.getUserMavenSettingsXml() } + .thenReturn(settingsFile) + + val path = getMavenRepositoryPathTest(mockSpan) + Assertions.assertEquals(repositoryPath, path) + + Mockito.verify(mockSpan).addEvent( + "Found localRepository param in .m2/settings.xml file", + Attributes.of(AttributeKey.stringKey("local maven repository path"), repositoryPath.toString()), + ) + mockSettingsXml.close() + } +} \ No newline at end of file