Skip to content
This repository has been archived by the owner on Feb 20, 2025. It is now read-only.

Commit

Permalink
Add a virtual method for customizing the exception message for unity …
Browse files Browse the repository at this point in the history
  • Loading branch information
Azurelol authored Dec 18, 2024
1 parent 2e803b3 commit d3f830d
Show file tree
Hide file tree
Showing 7 changed files with 116 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class DefaultUnityPluginTestOptions implements UnityPluginTestOptions {
Boolean addMockTask = true
Boolean forceMockTaskRun = true
Boolean clearMockTaskActions = false
Boolean writeMockExecutable = true

boolean applyPlugin() {
applyPlugin
Expand All @@ -36,6 +37,11 @@ class DefaultUnityPluginTestOptions implements UnityPluginTestOptions {
unityPath
}

@Override
boolean writeMockExecutable() {
writeMockExecutable
}

boolean addPluginTestDefaults() {
addPluginTestDefaults
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ import java.lang.annotation.Target

UnityPathResolution unityPath() default UnityPathResolution.Mock

boolean writeMockExecutable() default true

boolean addPluginTestDefaults() default true

boolean disableAutoActivateAndLicense() default true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@ package wooga.gradle.unity

import com.wooga.gradle.PlatformUtils
import com.wooga.gradle.test.IntegrationSpec
import com.wooga.gradle.test.executable.FakeExecutables
import com.wooga.gradle.test.mock.MockExecutable
import com.wooga.spock.extensions.unity.DefaultUnityPluginTestOptions
import com.wooga.spock.extensions.unity.UnityPathResolution
import com.wooga.spock.extensions.unity.UnityPluginTestOptions
import groovy.transform.stc.ClosureParams
import groovy.transform.stc.FromString
import wooga.gradle.unity.tasks.Unity
import wooga.gradle.unity.utils.ProjectSettingsFile

Expand Down Expand Up @@ -100,8 +102,9 @@ abstract class UnityIntegrationSpec extends IntegrationSpec {

switch (options.unityPath()) {
case UnityPathResolution.Mock:
mockUnityFile = createMockUnity()
addUnityPathToExtension(mockUnityFile.path)
if (options.writeMockExecutable()) {
writeMockExecutable()
}
break

case UnityPathResolution.Default:
Expand Down Expand Up @@ -132,6 +135,24 @@ abstract class UnityIntegrationSpec extends IntegrationSpec {
projectSettingsFile
}

/**
* Writes the mock executable with a predetermined location
*/
protected void writeMockExecutable(@ClosureParams(value = FromString, options = "com.wooga.gradle.test.mock.MockExecutable")
Closure<MockExecutable> configure = null) {
// Create and configure the file to be written
def mockUnity = new MockExecutable("fakeUnity.bat")
mockUnity.withText(mockUnityStartupMessage)
if (configure != null) {
configure(mockUnity)
}
// Write the file
mockUnityFile = mockUnity.toDirectory(unityMainDirectory)
// Write its location onto the unity extension
addUnityPathToExtension(mockUnityFile.path)
}

// TODO: Refactor away
protected File createMockUnity(String extraLog = null, int exitValue=0) {
def mockUnityFile = createFile("fakeUnity.bat", unityMainDirectory).with {
delete()
Expand Down Expand Up @@ -165,7 +186,6 @@ abstract class UnityIntegrationSpec extends IntegrationSpec {
""".readLines().collect{it.stripIndent().trim() }.findAll {!it.empty}.join("\n")
}
return mockUnityFile

}

void setLicenseDirectory() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,11 @@ import com.wooga.gradle.PlatformUtils
import com.wooga.gradle.test.PropertyQueryTaskWriter
import com.wooga.gradle.test.TaskIntegrationSpec
import com.wooga.gradle.test.writers.PropertyGetterTaskWriter
import com.wooga.gradle.test.writers.PropertySetterWriter
import org.gradle.api.logging.LogLevel
import spock.lang.Unroll
import wooga.gradle.unity.testutils.GradleRunResult
import wooga.gradle.unity.models.UnityCommandLineOption
import wooga.gradle.unity.tasks.Unity

import java.lang.reflect.ParameterizedType
import java.nio.file.Files
import java.nio.file.StandardCopyOption
import java.time.Duration
Expand Down Expand Up @@ -352,8 +349,10 @@ abstract class UnityTaskIntegrationSpec<T extends UnityTask> extends UnityIntegr
@Unroll
def "unity #message #maxRetries times with #retryWait wait times when line in log matches #retryRegexes"() {
given:

def fakeUnity = createMockUnity(unityLog, 1)
addUnityPathToExtension(fakeUnity.absolutePath)

buildFile << """
$subjectUnderTestName {
maxRetries = ${wrapValue(maxRetries, Integer)}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package wooga.gradle.unity.tasks


import com.wooga.spock.extensions.unity.UnityPluginTestOptions
import groovy.json.StringEscapeUtils
import wooga.gradle.unity.UnityTaskIntegrationSpec

import java.util.regex.Matcher
import java.util.regex.Pattern

class FailingTask extends Unity {

static Pattern pattern = Pattern.compile("<BUILD ERRORS>(?<summary>(.*\\s*)*)</BUILD ERRORS>")

// Escape for ^<, ^>
public static String expectedErrorMessage = """[BuildEngine] Collected errors during build process:
<BUILD ERRORS>
[Error] FOO Wooga.UnifiedBuildSystem.Tests.Editor.BuildEngineTest+FailingBuildSteps:FailInElaborateWays (at Packages/com.wooga.unified-build-system/Tests/Editor/BuildEngine/BuildRequestOutputTest.cs:32)
[Error] BAR Wooga.UnifiedBuildSystem.Tests.Editor.BuildEngineTest+FailingBuildSteps:FailInElaborateWays (at Packages/com.wooga.unified-build-system/Tests/Editor/BuildEngine/BuildRequestOutputTest.cs:32)
[Exception] Exception: Boom! Wooga.UnifiedBuildSystem.Editor.BuildTask`1[[Wooga.UnifiedBuildSystem.Editor.BuildTaskArguments, Wooga.Build.Editor, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]:Execute (at Packages/com.wooga.build/Editor/Tasks/BuildTask.cs:73)
[Error] Failed to execute task 'FailInElaborateWays' Wooga.UnifiedBuildSystem.Editor.BuildEngine+State:SetBuildFailure (at Packages/com.wooga.unified-build-system/Editor/BuildEngine/BuildEngine.cs:89)
</BUILD ERRORS>""".stripIndent()

static String buildErrorStartMarker = "<BUILD ERRORS>"
static String buildErrorEndMarker = "</BUILD ERRORS>"

@Override
protected String composeExceptionMessage(String stdout, String stderr) {
Matcher matcher = pattern.matcher(stderr)
if (matcher.find()){
var summary = matcher.group(0)
return summary
}
return ""
}
}

class FailTaskIntegrationSpec extends UnityTaskIntegrationSpec<FailingTask>{

static String echoError(String message) {
"""echo "${StringEscapeUtils.escapeJava(message).replace("`", "\\`") }" 1>&2 """
}

@UnityPluginTestOptions(writeMockExecutable = false)
def "throws composited exception message"() {

given:
writeMockExecutable({
it.text += "\n${FailingTask.expectedErrorMessage.readLines().collect{echoError(it) }.join("\n")}"
it.printEnvironment = false
it.exitValue = 666
})

when:
def result = runTasksWithFailure(subjectUnderTestName)

then:
result.wasExecuted(subjectUnderTestName)
result.standardError.contains(FailingTask.buildErrorStartMarker)
result.standardError.contains(FailingTask.buildErrorEndMarker)
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package wooga.gradle.unity.testutils

import com.wooga.gradle.test.mock.MockExecutable
import org.gradle.internal.impldep.org.apache.commons.lang.StringUtils

class GradleRunResult {
Expand Down Expand Up @@ -46,23 +47,23 @@ class GradleRunResult {
}

private static ArrayList<String> loadArgs(String stdOutput) {
def argumentsStartToken = "[ARGUMENTS]:"
def argumentsStartToken = MockExecutable.ARGUMENTS_START_MARKER
def lastExecutionOffset = stdOutput.lastIndexOf(argumentsStartToken)
if(lastExecutionOffset < 0) {
System.out.println(stdOutput)
throw new IllegalArgumentException("couldn't find arguments list in stdout")
}
def lastExecTailString = stdOutput.substring(lastExecutionOffset)
def argsString = substringBetween(lastExecTailString, argumentsStartToken, "[LOG]").
def argsString = substringBetween(lastExecTailString, argumentsStartToken, MockExecutable.ARGUMENTS_END_MARKER).
replace(argumentsStartToken, "")
def parts = argsString.split(" ").
findAll {!StringUtils.isEmpty(it) }.collect{ it.trim() }
return parts
}

private static Map<String, String> loadEnvs(String stdOutput) {
String environmentStartToken = "[ENVIRONMENT]:"
def argsString = substringBetween(stdOutput, environmentStartToken, "[ARGUMENTS]").
String environmentStartToken = MockExecutable.ENVIRONMENT_START_MARKER
def argsString = substringBetween(stdOutput, environmentStartToken, MockExecutable.ENVIRONMENT_END_MARKER).
replace(environmentStartToken, "")
def parts = argsString.split(System.lineSeparator()).
findAll {!StringUtils.isEmpty(it) }.collect{ it.trim() }
Expand Down
22 changes: 15 additions & 7 deletions src/main/groovy/wooga/gradle/unity/UnityTask.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -98,19 +98,27 @@ abstract class UnityTask extends DefaultTask
})

if (execResult.exitValue != 0) {
String message = ""
// Only write out the message if not already set to --info
if (!logger.infoEnabled) {
def stdout = logFile.text
def stderr = lastStderrStream? new String(lastStderrStream.toByteArray()) : ""
message = stderr ? stderr : stdout
}
def stdout = logFile.text
def stderr = lastStderrStream ? new String(lastStderrStream.toByteArray()) : ""
String message = composeExceptionMessage(stdout, stderr)
throw new UnityExecutionException("Failed during execution of the Unity process with arguments:\n${_arguments}\n${message}")
}

postExecute(execResult)
}

/**
* Composes the message to be included in an exception thrown when the task fails
* Override this in your custom task in order to improve reporting.
*/
protected String composeExceptionMessage(String stdout, String stderr) {
String message = ""
if (!logger.infoEnabled) {
message = stderr ? stderr : stdout
}
return message
}

/**
* Invoked before the task executes the Unity process
*/
Expand Down

0 comments on commit d3f830d

Please sign in to comment.