Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

inital package check implementation (#53) #54

Merged
merged 67 commits into from
Sep 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
9a9332d
add new step ttCheckPackage (#53)
MxEh-TT Aug 3, 2023
43a24f6
throw exception on checkfindings, add logger (#53)
MxEh-TT Aug 3, 2023
aa62691
add tests (#53)
MxEh-TT Aug 3, 2023
f72d04e
adjust line length (#53)
MxEh-TT Aug 3, 2023
9fe2364
rm test package with check errors for now (#53)
MxEh-TT Aug 3, 2023
c5ed2a1
adjust logging, add no existing file container test (#53)
MxEh-TT Aug 7, 2023
778b14d
fix non-existing test package (#53)
MxEh-TT Aug 7, 2023
48339fc
adjust not existing file handling (#53)
MxEh-TT Aug 7, 2023
2e563ce
adjust check file exists (#53)
MxEh-TT Aug 7, 2023
4e4afac
rename path variable (#53)
MxEh-TT Aug 7, 2023
cd568c4
adjust logs (#53)
MxEh-TT Aug 8, 2023
386d60f
adjust container test (#53)
MxEh-TT Aug 8, 2023
a60bfab
fix test checkpackge step (#53)
MxEh-TT Aug 8, 2023
06df790
add setInstallations to non existing package check, formatting (#53)
MxEh-TT Aug 17, 2023
abf049e
prepare check for invalid package test (#53)
MxEh-TT Aug 17, 2023
f854bb6
try with Result.Failure (#53)
MxEh-TT Aug 17, 2023
acc937e
adjust non existing package test (#53)
MxEh-TT Aug 18, 2023
66f2f44
adjust logs (#53)
MxEh-TT Aug 18, 2023
9bfd8b6
try print container test logs (#53)
MxEh-TT Aug 18, 2023
d409b4f
let api handle missing file,adjust missing package test (#53)
MxEh-TT Aug 18, 2023
201123b
remove exception, print errors instead (#53)
MxEh-TT Aug 21, 2023
bd4aa14
add package without desc to container tests (#53)
MxEh-TT Aug 21, 2023
78e2dde
add exec setting - do packageCheck before execution of pkg,prj (#53)
MxEh-TT Aug 21, 2023
b6e3d57
fix expected string typo (#53)
MxEh-TT Aug 21, 2023
9cae5b1
move new check into old check method (#53)
MxEh-TT Aug 22, 2023
8d72399
add executePackageCheck flag to roundtrip tests (#53)
MxEh-TT Aug 22, 2023
a9c5df8
adjust container test until workspace adjustment is live (#53)
MxEh-TT Aug 22, 2023
203b184
fix variable name (#53)
MxEh-TT Aug 24, 2023
5edcf07
rm unnecessary size variable (#53)
MxEh-TT Aug 24, 2023
65f8985
rm unused variables (#53)
MxEh-TT Aug 24, 2023
55023a4
add docstrings (#53)
MxEh-TT Aug 24, 2023
b4eaed3
new line eof (#53)
MxEh-TT Aug 24, 2023
c00dc11
add package check to features (#53)
MxEh-TT Aug 24, 2023
480bffc
make checkfinding serializable (#53)
MxEh-TT Aug 29, 2023
4083acb
format code (#53)
MxEh-TT Aug 29, 2023
1c451fa
add missing param in docs (#53)
MxEh-TT Sep 1, 2023
10d1e96
add execution config to PackageCheckStep (#53)
MxEh-TT Sep 1, 2023
c79c410
add PackageCheck test to run package, project; adjust container test …
MxEh-TT Sep 1, 2023
4233843
add PackageCheck example to README (#53)
MxEh-TT Sep 1, 2023
630211d
add explaination (#53)
MxEh-TT Sep 4, 2023
ebb7e96
catch api exception, print error (#53)
MxEh-TT Sep 4, 2023
816bd17
adjust container test to new apiexception handling (#53)
MxEh-TT Sep 4, 2023
4820052
hide executePackageCheck checkbox if current step is CackageCheckStep…
MxEh-TT Sep 7, 2023
b96e70f
add invalid project container test (#53)
MxEh-TT Sep 7, 2023
fe8f9d2
add ToolInstallation model, implement executionconfig options for Pac…
MxEh-TT Sep 7, 2023
85623a9
fix variable type constructor (#53)
MxEh-TT Sep 7, 2023
17ce705
adjust var name to match other steps (#53)
MxEh-TT Sep 8, 2023
176745e
adjust tests to new var name, fix timeout stepIT (#53)
MxEh-TT Sep 8, 2023
dc4a341
adjust examples in README (#53)
MxEh-TT Sep 8, 2023
766548a
fix var name, adjust step to spotbugs fix (#53)
MxEh-TT Sep 8, 2023
2f0eb76
getter returns new object containing issues (#53)
MxEh-TT Sep 8, 2023
5b5f5dd
move optional package check for runPackage runProject (#53)
MxEh-TT Sep 14, 2023
2b544d7
move result setting to CheckPackageResult, adjust docs, throw Connect…
MxEh-TT Sep 14, 2023
76099ee
adjust jelly, add additinal information on behaviour (#53)
MxEh-TT Sep 14, 2023
61fb2c0
adjust and add further tests (#53)
MxEh-TT Sep 14, 2023
23e6106
adjust docs (#53)
MxEh-TT Sep 14, 2023
c07f7d8
fix typos in container tests (#53)
MxEh-TT Sep 14, 2023
13dc11b
fix typo in Perform check on project test (#53)
MxEh-TT Sep 14, 2023
f998179
adjust set result CheckPackageResult (#53)
MxEh-TT Sep 14, 2023
a984eaf
adjust expected logs formatting (#53)
MxEh-TT Sep 14, 2023
98f2b18
add userpymodules to resourcemapping (#53)
MxEh-TT Sep 19, 2023
7a6c411
fix typos, formatting (#53)
MxEh-TT Sep 21, 2023
958025e
rm rethrow of Exception (#53)
MxEh-TT Sep 21, 2023
c616b4a
only catch/handle missing file api_execption (#53)
MxEh-TT Sep 21, 2023
d28b52c
remove timeout setting from integration tests (#53)
MxEh-TT Sep 21, 2023
5e3fd18
fix typo (#53)
MxEh-TT Sep 21, 2023
749614c
add declaration of exception to call (#53)
MxEh-TT Sep 22, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,10 @@ and [CX Templates](https://github.com/tracetronic/cx-templates).
## Features

- Provides an easy integration and control of ECU-TEST and TRACE-CHECK with Jenkins
- Enables perfoming package and project checks with rules defined in ECU-TEST.
- [Custom-Checks](https://github.com/tracetronic/ecu-test_custom-checks) provides an easy way to configure and import these checks.
- Enables the execution of ECU-TEST packages and projects with their respective configurations
- Enable the upload of generated test reports to [TEST-GUIDE](https://www.tracetronic.com/products/test-guide/)
- Enables the upload of generated test reports to [TEST-GUIDE](https://www.tracetronic.com/products/test-guide/)
- Using "pipelines first" approach to improve the automated process and traceability

## Configuration
Expand All @@ -71,6 +73,10 @@ node('windows') {
stage('Start Tools') {
ttStartTool toolName: 'ECU-TEST', workspaceDir: './workspace', settingsDir: './settings'
}
stage('Package Checks') {
ttCheckPackage testCasePath: 'sample.pkg'
ttCheckPackage testCasePath: 'sample.prj'
}
stage('Test Execution') {
ttRunProject testCasePath: 'sample.prj', testConfig: [tbcPath: 'sample.tbc', tcfPath: 'sample.tcf', constants: [[label: 'sample', value: '123']]]
ttRunPackage testCasePath: 'sample.pkg', testConfig: [tbcPath: '', tcfPath: '', forceConfigurationReload: true, constants: [[label: 'sample', value: '\'sampleValue\'']]]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,23 @@ import de.tracetronic.cxs.generated.et.client.ApiClient
import de.tracetronic.cxs.generated.et.client.ApiException
import de.tracetronic.cxs.generated.et.client.Configuration
import de.tracetronic.cxs.generated.et.client.api.ApiStatusApi
import de.tracetronic.cxs.generated.et.client.api.ChecksApi
import de.tracetronic.cxs.generated.et.client.api.ExecutionApi
import de.tracetronic.cxs.generated.et.client.api.ReportApi
import de.tracetronic.cxs.generated.et.client.model.CheckFinding
import de.tracetronic.cxs.generated.et.client.model.CheckReport
import de.tracetronic.cxs.generated.et.client.model.CheckExecutionOrder
import de.tracetronic.cxs.generated.et.client.model.CheckExecutionStatus
import de.tracetronic.cxs.generated.et.client.model.Execution
import de.tracetronic.cxs.generated.et.client.model.ExecutionOrder
import de.tracetronic.cxs.generated.et.client.model.ExecutionStatus
import de.tracetronic.cxs.generated.et.client.model.ReportGeneration
import de.tracetronic.cxs.generated.et.client.model.ReportGenerationOrder
import de.tracetronic.cxs.generated.et.client.model.ReportGenerationStatus
import de.tracetronic.cxs.generated.et.client.model.ReportInfo
import de.tracetronic.cxs.generated.et.client.model.SimpleMessage
import de.tracetronic.cxs.generated.et.client.model.TGUpload
import de.tracetronic.cxs.generated.et.client.model.TGUploadOrder
import de.tracetronic.cxs.generated.et.client.model.TGUploadStatus
import hudson.model.TaskListener
import org.apache.commons.lang.StringUtils

class RestApiClient {
Expand Down Expand Up @@ -61,6 +64,27 @@ class RestApiClient {
return alive
}

/**
* This method performs the package check via the ChecksApi and returns the CheckResult.
* Throws ApiExceptions on error status codes.
* @param filepath the path to the package or project to be checked
* @return the check report
*/
CheckReport runPackageCheck(String filepath) throws ApiException {
ChecksApi apiInstance = new ChecksApi(apiClient)
CheckExecutionOrder order = new CheckExecutionOrder().filePath(filepath)
String checkExecutionId = apiInstance.createCheckExecutionOrder(order).getCheckExecutionId()
Closure<Boolean> checkStatus = { CheckExecutionStatus response ->
response?.status in [null, 'WAITING', 'RUNNING']
}

while (checkStatus(apiInstance.getCheckExecutionStatus(checkExecutionId))) {
sleep(1000)
}
CheckReport checkReport = apiInstance.getCheckResult(checkExecutionId)
return checkReport
}

Execution runTest(ExecutionOrder executionOrder, int timeout) {
ExecutionApi apiInstance = new ExecutionApi(apiClient)
apiInstance.createExecution(executionOrder)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,21 @@ package de.tracetronic.jenkins.plugins.ecutestexecution.builder
import de.tracetronic.cxs.generated.et.client.model.Execution
import de.tracetronic.cxs.generated.et.client.model.ExecutionOrder
import de.tracetronic.cxs.generated.et.client.model.ReportInfo
import de.tracetronic.jenkins.plugins.ecutestexecution.ETInstallation
import de.tracetronic.jenkins.plugins.ecutestexecution.RestApiClient
import de.tracetronic.jenkins.plugins.ecutestexecution.configs.ExecutionConfig
import de.tracetronic.jenkins.plugins.ecutestexecution.configs.TestConfig
import de.tracetronic.jenkins.plugins.ecutestexecution.model.CheckPackageResult
import de.tracetronic.jenkins.plugins.ecutestexecution.model.TestResult
import de.tracetronic.jenkins.plugins.ecutestexecution.model.ToolInstallations
import de.tracetronic.jenkins.plugins.ecutestexecution.steps.CheckPackageStep
import de.tracetronic.jenkins.plugins.ecutestexecution.util.LogConfigUtil
import de.tracetronic.jenkins.plugins.ecutestexecution.util.ProcessUtil
import hudson.EnvVars
import hudson.Launcher
import hudson.model.Computer
import hudson.model.Node
import hudson.model.TaskListener
import jenkins.security.MasterToSlaveCallable
import org.apache.commons.lang.StringUtils
import org.jenkinsci.plugins.workflow.steps.StepContext

import java.util.concurrent.TimeoutException

/**
* Common base class for all test related steps implemented in this plugin.
*/
Expand Down Expand Up @@ -51,35 +48,33 @@ abstract class AbstractTestBuilder implements Serializable {
return testConfig ? new TestConfig(testConfig) : null
}

/**
* Performs CheckPackageStep if executePackageCheck option was set in the execution config and calls the execution
* of the package.
* @return TestResult
* results of the test execution
*/
TestResult runTest() {

def toolInstallations = getToolInstallationsOnNode()
TaskListener listener = context.get(TaskListener.class)
ToolInstallations toolInstallations = new ToolInstallations(context)

if (executionConfig.executePackageCheck){
CheckPackageStep step = new CheckPackageStep(testCasePath)
step.setExecutionConfig(executionConfig)
CheckPackageResult check_result = step.start(context).run()
if (executionConfig.stopOnError && check_result.result == "ERROR") {
listener.logger.println(
"Skipping execution of ${testArtifactName} ${testCasePath} due to failed package checks"
)
return new TestResult(null, "ERROR",null)
}
}

return context.get(Launcher.class).getChannel().call(new RunTestCallable(testCasePath,
context.get(EnvVars.class), context.get(TaskListener.class), executionConfig,
context.get(EnvVars.class), listener, executionConfig,
getTestArtifactName(), getLogConfig(), getExecutionOrderBuilder(), toolInstallations))
}

private ArrayList<String> getToolInstallationsOnNode() {
/**
* This method gets the executable names of the tool installations on the node given by the context. Context is
* not reasonably available in the MasterToSlaveCallable, so all info which needs a context must be fetched
* outside.
*
* @return list of the executable names of the ECU-TEST installations on the respective node (can also be
* TRACE-CHECK executables)
*/
Computer computer = context.get(Launcher).getComputer()
Node node = computer?.getNode()
EnvVars envVars = context.get(EnvVars)
TaskListener listener = context.get(TaskListener)
if(node) {
return ETInstallation.getAllExecutableNames(envVars, node, listener)
} else {
return null
}
}

private static final class RunTestCallable extends MasterToSlaveCallable<TestResult, IOException> {

private static final long serialVersionUID = 1L
Expand All @@ -91,11 +86,11 @@ abstract class AbstractTestBuilder implements Serializable {
private final ExecutionConfig executionConfig
private final String testArtifactName
private final LogConfigUtil configUtil
private final ArrayList<String> toolInstallations
private final ToolInstallations toolInstallations

RunTestCallable(final String testCasePath, EnvVars envVars, TaskListener listener,
ExecutionConfig executionConfig, String testArtifactName, LogConfigUtil configUtil,
ExecutionOrderBuilder executionOrderBuilder, ArrayList<String> toolInstallations) {
ExecutionOrderBuilder executionOrderBuilder, ToolInstallations toolInstallations) {
this.testCasePath = testCasePath
this.envVars = envVars
this.listener = listener
Expand Down Expand Up @@ -126,39 +121,14 @@ abstract class AbstractTestBuilder implements Serializable {
result = new TestResult(null, 'ERROR', null)
listener.logger.println("Executing ${testArtifactName} failed!")
if (executionConfig.stopOnError) {
stopToolInstances()
toolInstallations.stopToolInstances(executionConfig.timeout)
if (executionConfig.stopUndefinedTools) {
stopTTInstances()
toolInstallations.stopTTInstances(executionConfig.timeout)
}
}
}
listener.logger.println(result.toString())

return result
}

private stopToolInstances() {
int timeout = executionConfig.timeout
if (toolInstallations) {
if (ProcessUtil.killProcesses(toolInstallations, timeout)) {
listener.logger.println('-> Tools stopped successfully.')
}
else {
throw new TimeoutException("Timeout of ${timeout} seconds exceeded for stopping tool!")
}
} else {
listener.logger.println("No Tool Installations to stop were found. No processes killed.")
}
}

private stopTTInstances() {
int timeout = executionConfig.timeout
listener.logger.println("Stop TraceTronic tool instances.")
if (ProcessUtil.killTTProcesses(timeout)) {
listener.logger.println("Stopped TraceTronic tools successfully.")
} else {
throw new TimeoutException("Timeout of ${timeout} seconds exceeded for stopping TraceTronic tools!")
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,22 @@ class ExecutionConfig extends AbstractDescribableImpl<ExecutionConfig> implement
private int timeout
private boolean stopOnError
private boolean stopUndefinedTools
private boolean executePackageCheck


@DataBoundConstructor
ExecutionConfig() {
this.timeout = DEFAULT_TIMEOUT
this.stopOnError = true
this.stopUndefinedTools = true
this.executePackageCheck = false
}

ExecutionConfig(ExecutionConfig config) {
this.timeout = config.getTimeout()
this.stopOnError = config.isStopOnError()
this.stopUndefinedTools = config.getStopUndefinedTools()
this.executePackageCheck = config.getExecutePackageCheck()
}

int getTimeout() {
Expand All @@ -56,6 +59,15 @@ class ExecutionConfig extends AbstractDescribableImpl<ExecutionConfig> implement
this.stopOnError = stopOnError
}

boolean getExecutePackageCheck() {
return executePackageCheck
}

@DataBoundSetter
void setExecutePackageCheck(boolean executePackageCheck) {
this.executePackageCheck = executePackageCheck
}

boolean getStopUndefinedTools() {
return stopUndefinedTools
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package de.tracetronic.jenkins.plugins.ecutestexecution.model

import org.jenkinsci.plugins.scriptsecurity.sandbox.whitelists.Whitelisted

/**
* Class holding the result of a package check.
*/
class CheckPackageResult implements Serializable {

private static final long serialVersionUID = 1L

private final String result
private final String testCasePath
private final List<HashMap<String, String>> issues

/**
* Instantiates a new [CheckPackageResult].
* @param testCasePath
* the path to the file (package or project) where CheckPackageStep was executed on
* @param issues
* the issues contain hashmaps with filename as key and issue message as value
*/
CheckPackageResult(String testCasePath, List<HashMap<String, String>> issues) {
this.result = (issues == null || issues.size()) ? "ERROR" : "SUCCESS"
this.testCasePath = testCasePath
this.issues = issues
}

/**
* @return result
*/
@Whitelisted
String getResult() {
return result
}

/**
* @return the testCasePath
*/
@Whitelisted
String getTestCasePath() {
return testCasePath
}

/**
* @return the issues
*/
@Whitelisted
List<HashMap<String, String>> getIssues() {
return new ArrayList<HashMap<String, String>>(issues)
}

/**
* Returns a string representation of the object.
* @return package check result as string
*/
@Override
String toString() {
String str = "-> result: ${result} \n"
if (issues && issues.size() != 0) {
str += "-> ${issues.size()} issues in ${testCasePath} \n"
}
for (issue in issues) {
str += "--> ${issue.filename}: ${issue.message}\n"
}
return str.stripIndent().trim()
}
}
Loading