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

add new step karmaExecuteTests #351

Merged
merged 21 commits into from
Nov 8, 2018
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
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
98 changes: 98 additions & 0 deletions documentation/docs/steps/karmaExecuteTests.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# karmaExecuteTests

## Description

In this step the ([Karma test runner](http://karma-runner.github.io)) is executed.

The step is using the `seleniumExecuteTest` step to spins up two containers in a Docker network:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line length


- a Selenium/Chrome container (`selenium/standalone-chrome`)
- a NodeJS container (`node:8-stretch`)

In the Docker network, the containers can be referenced by the values provided in `dockerName` and `sidecarName`, the default values are `karma` and `selenium`. These values must be used in the `hostname` properties of the test configuration ([Karma](https://karma-runner.github.io/1.0/config/configuration-file.html) and [WebDriver](https://github.com/karma-runner/karma-webdriver-launcher#usage)).
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line length


!!! note
In a Kubernetes environment, the containers both need to be referenced with `localhost`.

## Prerequisites

- **running Karma tests** - have a NPM module with running tests executed with Karma
- **configured WebDriver** - have the [`karma-webdriver-launcher`](https://github.com/karma-runner/karma-webdriver-launcher) package installed and a custom, WebDriver-based browser configured in Karma
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line length


## Parameters

| parameter | mandatory | default | possible values |
| ----------|-----------|---------|-----------------|
|script|yes|||
|containerPortMappings|no|`[node:8-stretch: [[containerPort: 9876, hostPort: 9876]]]`||
|dockerEnvVars|no|||
|dockerImage|no|`node:8-stretch`||
|dockerName|no|`karma`||
|dockerWorkspace|no|`/home/node`||
|failOnError|no|||
|installCommand|no|`npm install --quiet`||
|modules|no|`['.']`||
|runCommand|no|`npm run karma`||
|sidecarEnvVars|no|||
|sidecarImage|no|||
|sidecarName|no|||
|sidecarVolumeBind|no|||
|stashContent|no|||

- `script` - defines the global script environment of the Jenkinsfile run. Typically `this` is passed to this parameter. This allows the function to access the [`commonPipelineEnvironment`](commonPipelineEnvironment.md) for storing the measured duration.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line length

- `containerPortMappings` - see step [dockerExecute](dockerExecute.md)
- `dockerEnvVars` - see step [dockerExecute](dockerExecute.md)
- `dockerImage` - see step [dockerExecute](dockerExecute.md)
- `dockerName` - see step [dockerExecute](dockerExecute.md)
- `dockerWorkspace` - see step [dockerExecute](dockerExecute.md)
- `failOnError` - see step [seleniumExecuteTests](seleniumExecuteTests.md)
- `installCommand` - the command that is executed to install dependencies
- `modules` - define the paths of the modules to execute tests on
- `runCommand` - the command that is executed to start the tests
- `sidecarEnvVars` - see step [dockerExecute](dockerExecute.md)
- `sidecarImage` - see step [dockerExecute](dockerExecute.md)
- `sidecarName` - see step [dockerExecute](dockerExecute.md)
- `sidecarVolumeBind` - see step [dockerExecute](dockerExecute.md)
- `stashContent` - pass specific stashed that should be considered for the tests

## Step configuration

We recommend to define values of step parameters via [config.yml file](../configuration.md).

In following sections the configuration is possible:

| parameter | general | step | stage |
| ----------|---------|------|-------|
|script||||
|containerPortMappings|X|X|X|
|dockerEnvVars|X|X|X|
|dockerImage|X|X|X|
|dockerName|X|X|X|
|dockerWorkspace|X|X|X|
|failOnError|X|X|X|
|installCommand|X|X|X|
|modules|X|X|X|
|runCommand|X|X|X|
|sidecarEnvVars|X|X|X|
|sidecarImage|X|X|X|
|sidecarName|X|X|X|
|sidecarVolumeBind|X|X|X|
|stashContent|X|X|X|

## Return value

none

## Side effects

Step uses `seleniumExecuteTest` & `dockerExecute` inside.

## Exceptions

none

## Example

```groovy
karmaExecuteTests script: this, modules: ['./shoppinglist', './catalog']
```
1 change: 1 addition & 0 deletions documentation/mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ nav:
- handlePipelineStepErrors: steps/handlePipelineStepErrors.md
- healthExecuteCheck: steps/healthExecuteCheck.md
- influxWriteData: steps/influxWriteData.md
- karmaExecuteTests: steps/karmaExecuteTests.md
- mailSendNotification: steps/mailSendNotification.md
- mavenExecute: steps/mavenExecute.md
- mtaBuild: steps/mtaBuild.md
Expand Down
12 changes: 12 additions & 0 deletions resources/default_pipeline_environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,18 @@ steps:
healthEndpoint: ''
influxWriteData:
influxServer: 'jenkins'
karmaExecuteTests:
containerPortMappings:
'node:8-stretch':
- containerPort: 9876
hostPort: 9876
dockerImage: 'node:8-stretch'
dockerName: 'karma'
dockerWorkspace: '/home/node'
installCommand: 'npm install --quiet'
modules:
- '.'
runCommand: 'npm run karma'
mailSendNotification:
notificationAttachment: true
notifyCulprits: true
Expand Down
56 changes: 56 additions & 0 deletions test/groovy/KarmaExecuteTestsTest.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#!groovy
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.rules.ExpectedException
import org.junit.rules.RuleChain
import util.*

import static org.hamcrest.Matchers.*
import static org.junit.Assert.assertThat

class KarmaExecuteTestsTest extends BasePiperTest {
private JenkinsStepRule jsr = new JenkinsStepRule(this)
private JenkinsLoggingRule jlr = new JenkinsLoggingRule(this)
private JenkinsShellCallRule jscr = new JenkinsShellCallRule(this)
private JenkinsEnvironmentRule jer = new JenkinsEnvironmentRule(this)
private ExpectedException thrown = ExpectedException.none()

@Rule
public RuleChain rules = Rules
.getCommonRules(this)
.around(new JenkinsReadYamlRule(this))
.around(jscr)
.around(jlr)
.around(jer)
.around(jsr)
.around(thrown)

def seleniumParams = [:]

@Before
void init() throws Exception {
helper.registerAllowedMethod("unstash", [String.class], { s -> return [s]})

helper.registerAllowedMethod('seleniumExecuteTests', [Map.class, Closure.class], {map, body ->
seleniumParams = map
return body()
})
}

@Test
void testDefaults() throws Exception {
jsr.step.karmaExecuteTests(
script: nullScript,
juStabUtils: utils
)
assertThat(jscr.shell, hasItems(
containsString("cd '.' && npm install --quiet"),
containsString("cd '.' && npm run karma")
))
assertThat(seleniumParams.dockerImage, is('node:8-stretch'))
assertThat(seleniumParams.dockerName, is('karma'))
assertThat(seleniumParams.dockerWorkspace, is('/home/node'))
assertJobStatusSuccess()
}
}
73 changes: 73 additions & 0 deletions vars/karmaExecuteTests.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import com.sap.piper.ConfigurationHelper
import com.sap.piper.GitUtils
import com.sap.piper.Utils

import groovy.text.SimpleTemplateEngine
import groovy.transform.Field

@Field String STEP_NAME = 'karmaExecuteTests'
@Field Set GENERAL_CONFIG_KEYS = [
'containerPortMappings', //port mappings required for containers. This will only take effect inside a Kubernetes pod, format [[containerPort: 1111, hostPort: 1111]]
CCFenner marked this conversation as resolved.
Show resolved Hide resolved
'dockerEnvVars', //envVars to be set in the execution container if required
'dockerImage', //Docker image for code execution
'dockerName', //name of the Docker container. If not on Kubernetes pod, this will define the network-alias to the NPM container and is thus required for accessing the server, example http://karma:9876 (default).
'dockerWorkspace', //user home directory for Docker execution. This will only take effect inside a Kubernetes pod.
'failOnError',
'installCommand',
'modules',
'runCommand',
'sidecarEnvVars', //envVars to be set in Selenium container if required
'sidecarImage', //image for Selenium execution which runs as sidecar to dockerImage
'sidecarName', //name of the Selenium container. If not on Kubernetes pod, this will define the network-alias to the Selenium container and is thus required for accessing the server, example http://selenium:4444 (default)
'sidecarVolumeBind', //volume bind. This will not take effect in Kubernetes pod.
'stashContent' //list of stash names which are required to be unstashed before test run
]
@Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS
@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS

void call(Map parameters = [:]) {
handlePipelineStepErrors(stepName: STEP_NAME, stepParameters: parameters) {
def script = parameters?.script ?: [commonPipelineEnvironment: commonPipelineEnvironment]
CCFenner marked this conversation as resolved.
Show resolved Hide resolved
def utils = parameters?.juStabUtils ?: new Utils()

// load default & individual configuration
Map config = ConfigurationHelper.newInstance(this)
.loadStepDefaults()
.mixinGeneralConfig(script.commonPipelineEnvironment, GENERAL_CONFIG_KEYS)
.mixinStepConfig(script.commonPipelineEnvironment, STEP_CONFIG_KEYS)
.mixinStageConfig(script.commonPipelineEnvironment, parameters.stageName?:env.STAGE_NAME, STEP_CONFIG_KEYS)
.mixin(parameters, PARAMETER_KEYS)
.use()

utils.pushToSWA([step: STEP_NAME], config)

def testJobs = [:]
def options = [
containerPortMappings: config.containerPortMappings,
dockerEnvVars: config.dockerEnvVars,
dockerImage: config.dockerImage,
dockerName: config.dockerName,
dockerWorkspace: config.dockerWorkspace,
failOnError: config.failOnError,
sidecarEnvVars: config.sidecarEnvVars,
sidecarImage: config.sidecarImage,
sidecarName: config.sidecarName,
sidecarVolumeBind: config.sidecarVolumeBind,
stashContent: config.stashContent
]
for(String path : config.modules){
testJobs["Karma - ${path}"] = {
seleniumExecuteTests(options){
sh "cd '${path}' && ${config.installCommand}"
marcusholl marked this conversation as resolved.
Show resolved Hide resolved
sh "cd '${path}' && ${config.runCommand}"
}
}
}

if(testJobs.size() == 1){
testJobs.each({ key, value -> value() })
}else{
parallel testJobs.plus([failFast: false])
}
}
}