1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2024-12-14 11:03:09 +02:00
sap-jenkins-library/consumer-test/TestRunnerThread.groovy

136 lines
4.8 KiB
Groovy
Raw Normal View History

2019-05-09 10:28:54 +02:00
@Grab('org.yaml:snakeyaml:1.17')
import org.yaml.snakeyaml.Yaml
class TestRunnerThread extends Thread {
static def workspacesRootDir
static def libraryVersionUnderTest
static def repositoryUnderTest
Process currentProcess
final StringBuilder stdOut = new StringBuilder()
final StringBuilder stdErr = new StringBuilder()
int lastPrintedStdOutLine = -1
public def returnCode = -1
public def lastCommand
def area
def testCase
def uniqueName
def testCaseRootDir
def testCaseWorkspace
def testCaseConfig
TestRunnerThread(File testCaseFile) {
// Regex pattern expects a folder structure such as '/rootDir/areaDir/testCase.extension'
def testCaseMatches = (testCaseFile.toString() =~
/^[\w\-]+\\/([\w\-]+)\\/([\w\-]+)\..*\u0024/)
this.area = testCaseMatches[0][1]
this.testCase = testCaseMatches[0][2]
if (!area || !testCase) {
throw new RuntimeException("Expecting file structure '/rootDir/areaDir/testCase.yml' " +
"but got '${testCaseFile}'.")
}
this.uniqueName = "${area}|${testCase}"
this.testCaseRootDir = new File("${workspacesRootDir}/${area}/${testCase}")
this.testCaseWorkspace = "${testCaseRootDir}/workspace"
this.testCaseConfig = new Yaml().load(testCaseFile.text)
}
void run() {
println "[INFO] Test case '${uniqueName}' launched."
if (testCaseRootDir.exists() || !testCaseRootDir.mkdirs()) {
throw new RuntimeException("Creation of dir '${testCaseRootDir}' failed.")
}
executeShell("git clone -b ${testCase} ${testCaseConfig.referenceAppRepoUrl} " +
"${testCaseWorkspace}")
addJenkinsYmlToWorkspace()
setLibraryVersionInJenkinsfile()
//Commit the changed version because artifactSetVersion expects the git repo not to be dirty
executeShell(["git", "-C", "${testCaseWorkspace}", "commit", "--all",
'--author="piper-testing-bot <piper-testing-bot@example.com>"',
'--message="Set piper lib version for test"'])
executeShell("docker run -v /var/run/docker.sock:/var/run/docker.sock " +
"-v ${System.getenv('PWD')}/${testCaseWorkspace}:/workspace -v /tmp " +
"-e CASC_JENKINS_CONFIG=/workspace/jenkins.yml -e CX_INFRA_IT_CF_USERNAME " +
"-e CX_INFRA_IT_CF_PASSWORD -e BRANCH_NAME=${testCase} ppiper/jenkinsfile-runner")
println "*****[INFO] Test case '${uniqueName}' finished successfully.*****"
printOutput()
}
// Configure path to library-repository under test in Jenkins config
private void addJenkinsYmlToWorkspace() {
def sourceFile = 'jenkins.yml'
def sourceText = new File(sourceFile).text.replaceAll(
'__REPO_SLUG__', repositoryUnderTest)
def target = new File("${testCaseWorkspace}/${sourceFile}")
target.write(sourceText)
}
// Force usage of library version under test by setting it in the Jenkinsfile,
// which is then the first definition and thus has the highest precedence.
private void setLibraryVersionInJenkinsfile() {
def jenkinsfile = new File("${testCaseWorkspace}/Jenkinsfile")
def manipulatedText =
"@Library(\"piper-library-os@${libraryVersionUnderTest}\") _\n" +
jenkinsfile.text
jenkinsfile.write(manipulatedText)
}
private void executeShell(command) {
lastCommand = command
def startOfCommandString = "Shell command: '${command}'\n"
stdOut << startOfCommandString
stdErr << startOfCommandString
currentProcess = command.execute()
currentProcess.waitForProcessOutput(stdOut, stdErr)
returnCode = currentProcess.exitValue()
currentProcess = null
if (returnCode > 0) {
throw new ReturnCodeNotZeroException("Test case: [${uniqueName}]; " +
"shell command '${command} exited with return code '${returnCode}")
}
}
void printOutput() {
println "\n[INFO] stdout output from test case ${uniqueName}:"
stdOut.eachLine { line, i ->
println "${i} [${uniqueName}] ${line}"
lastPrintedStdOutLine = i
}
println "\n[INFO] stderr output from test case ${uniqueName}:"
stdErr.eachLine { line, i ->
println "${i} [${uniqueName}] ${line}"
}
}
public void printRunningStdOut() {
stdOut.eachLine { line, i ->
if (i > lastPrintedStdOutLine) {
println "${i} [${uniqueName}] ${line}"
lastPrintedStdOutLine = i
}
}
}
@Override
public String toString() {
return uniqueName
}
}
class ReturnCodeNotZeroException extends Exception {
ReturnCodeNotZeroException(message) {
super(message)
}
}