extract some logic from intellij.tools.ide.starter to intellij.platform.testFramework.teamCity

GitOrigin-RevId: 1609f55e616c133a7fc1c16c4bf32bf5fe282ec9
This commit is contained in:
Daniil Ovchinnikov
2024-02-18 14:39:13 +01:00
committed by intellij-monorepo-bot
parent e3f16066a4
commit 45d1228fa8
6 changed files with 154 additions and 0 deletions

1
.idea/modules.xml generated
View File

@@ -1053,6 +1053,7 @@
<module fileurl="file://$PROJECT_DIR$/platform/testFramework/core/intellij.platform.testFramework.core.iml" filepath="$PROJECT_DIR$/platform/testFramework/core/intellij.platform.testFramework.core.iml" />
<module fileurl="file://$PROJECT_DIR$/platform/testFramework/impl/intellij.platform.testFramework.impl.iml" filepath="$PROJECT_DIR$/platform/testFramework/impl/intellij.platform.testFramework.impl.iml" />
<module fileurl="file://$PROJECT_DIR$/platform/testFramework/junit5/intellij.platform.testFramework.junit5.iml" filepath="$PROJECT_DIR$/platform/testFramework/junit5/intellij.platform.testFramework.junit5.iml" />
<module fileurl="file://$PROJECT_DIR$/platform/testFramework/teamCity/intellij.platform.testFramework.teamCity.iml" filepath="$PROJECT_DIR$/platform/testFramework/teamCity/intellij.platform.testFramework.teamCity.iml" />
<module fileurl="file://$PROJECT_DIR$/platform/testFramework/ui/intellij.platform.testFramework.ui.iml" filepath="$PROJECT_DIR$/platform/testFramework/ui/intellij.platform.testFramework.ui.iml" />
<module fileurl="file://$PROJECT_DIR$/platform/testRunner/intellij.platform.testRunner.iml" filepath="$PROJECT_DIR$/platform/testRunner/intellij.platform.testRunner.iml" />
<module fileurl="file://$PROJECT_DIR$/platform/platform-tests/intellij.platform.tests.iml" filepath="$PROJECT_DIR$/platform/platform-tests/intellij.platform.tests.iml" />

View File

@@ -0,0 +1,3 @@
This module is expected to be used in the test process, which loads the application (regular tests),
as well as in the test process, which starts the whole IDE in another process (integration tests).
`com.intellij.openapi.application.Application` must not be accessible in this module.

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" packagePrefix="com.intellij.platform.testFramework.teamCity" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="kotlin-stdlib" level="project" />
<orderEntry type="library" name="jetbrains-annotations" level="project" />
</component>
</module>

View File

@@ -0,0 +1,103 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.platform.testFramework.teamCity
private val OFFSET: Int = "AAAAAAA".hashCode()
/**
* 0340430340434 => XDMSLS
*/
fun convertToHashCodeWithOnlyLetters(hash: Int): String {
val offsettedHash = (hash - OFFSET).toLong()
var longHash: Long = offsettedHash and 0xFFFFFFFFL
val generatedChars = CharArray(7)
val aChar = 'A'
generatedChars.indices.forEach { index ->
generatedChars[6 - index] = (aChar + ((longHash % 31).toInt()))
longHash /= 31
}
return generatedChars.filter { it.isLetterOrDigit() }.joinToString(separator = "")
}
/**
* Simplifies test grouping by replacing numbers, hashes, hex numbers with predefined constant values <ID>, <HASH>, <HEX>
* Eg:
* text@3ba5aac, text => text<ID>, text
* some-text.db451f59 => some-text.<HASH>
* 0x01 => <HEX>
* text1234text => text<NUM>text
**/
fun generifyErrorMessage(originalMessage: String): String {
return originalMessage
.generifyID()
.generifyHash()
.generifyHexadecimal()
.generifyHexCode()
.generifyNumber()
}
/** text@3ba5aac, text => text<ID>, text */
fun String.generifyID(omitDollarSign: Boolean = false): String {
val regexpStr = if (omitDollarSign) "[@#][A-Za-z\\d-_]+"
else "[\$@#][A-Za-z\\d-_]+"
return this.replace(regexpStr.toRegex(), "<ID>")
}
/** some-text.db451f59 => some-text.<HASH> */
fun String.generifyHash(): String = this
.replace("[.]([A-Za-z]+\\d|\\d+[A-Za-z])[A-Za-z\\d]*".toRegex(), ".<HASH>")
/**
* Replaces hexadecimal numbers in a string with a generic placeholder <NUM>.
* The hexadecimal number should be either at the beginning/end of the string or surrounded by special characters.
* Examples:
* ```
* sometext-aed23 => sometext-<NUM>
* abc323#sometext => <NUM>#sometext
* sometext$ABCDE2323$sometext => sometext$<NUM>$sometext
* ```
*/
fun String.generifyHexadecimal(): String {
val hexNumber ="[a-fA-F0-9]{2,}"
val specialChars = "[\\W_]"
val regex = Regex("($specialChars)($hexNumber)$|^($hexNumber)($specialChars)|($specialChars)($hexNumber)($specialChars)")
return this.replace(regex) {
if (it.groupValues[2].isNotEmpty()) {
"${it.groupValues[1]}<NUM>"
} else if (it.groupValues[4].isNotEmpty()) {
"<NUM>${it.groupValues[4]}"
} else {
"${it.groupValues[5]}<NUM>${it.groupValues[7]}"
}
}
}
/** 0x01 => <HEX> */
fun String.generifyHexCode(): String = this.replace("0x[\\da-fA-F]+".toRegex(), "<HEX>")
/** text1234text => text<NUM>text */
fun String.generifyNumber(): String = this.replace("\\d+".toRegex(), "<NUM>")
fun String.generifyDollarSign(): String = this.replace("\\$<NUM>+".toRegex(), "")
/** Leave only numbers and characters */
fun String.replaceSpecialCharacters(newValue: String, vararg ignoreSymbols: String): String {
val regex = Regex("[^a-zA-Z0-9${ignoreSymbols.joinToString(separator = "")}]")
return this
.replace(regex, newValue)
}
/** Leave only numbers and characters.
* Replace everything else with hyphens.
*/
fun String.replaceSpecialCharactersWithHyphens(ignoreSymbols: List<String> = listOf(".", "/", """\\""")): String {
return this
.replaceSpecialCharacters(newValue = "-", *ignoreSymbols.toTypedArray())
.replace("[-]+".toRegex(), "-")
.removePrefix("-")
.removeSuffix("-")
}

View File

@@ -0,0 +1,5 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
@Internal
package com.intellij.platform.testFramework.teamCity;
import org.jetbrains.annotations.ApiStatus.Internal;

View File

@@ -0,0 +1,29 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.platform.testFramework.teamCity
import java.io.PrintStream
import java.util.*
// Functions in this file only handle TeamCity message formatting.
fun PrintStream.reportTestFailure(testName: String, message: String, details: String) {
val flowId = UUID.randomUUID().toString()
val escapedTestName = testName.escapeStringForTeamCity()
val escapedMessage = message.escapeStringForTeamCity()
val escapedDetails = details.escapeStringForTeamCity()
println("""
##teamcity[testStarted flowId='$flowId' name='$escapedTestName' nodeId='$escapedTestName' parentNodeId='0']
##teamcity[testFailed flowId='$flowId' name='$escapedTestName' nodeId='$escapedTestName' parentNodeId='0' message='$escapedMessage' details='$escapedDetails']
##teamcity[testFinished flowId='$flowId' name='$escapedTestName' nodeId='$escapedTestName' parentNodeId='0']
""".trimIndent())
}
fun String.escapeStringForTeamCity(): String {
return this.substring(0, kotlin.math.min(7000, this.length))
.replace("\\|", "||")
.replace("\\[", "|[")
.replace("]", "|]")
.replace("\n", "|n")
.replace("'", "|'")
.replace("\r", "|r")
}