mirror of
https://github.com/SAP/jenkins-library.git
synced 2024-12-12 10:55:20 +02:00
feat(karma): migrate karmaExecuteTests to go implementation (#2695)
* convert karmaExecuteTests to go implementation * removed KarmaExecuteTestsTest.groovy * added KarmaExecuteTests to fieldRelatedWhiteList * Update vars/karmaExecuteTests.groovy Co-authored-by: Christopher Fenner <26137398+CCFenner@users.noreply.github.com> * Update resources/metadata/karmaExecuteTests.yaml Co-authored-by: Christopher Fenner <26137398+CCFenner@users.noreply.github.com> * Update resources/metadata/karmaExecuteTests.yaml Co-authored-by: Christopher Fenner <26137398+CCFenner@users.noreply.github.com> * added reference seleniumHubCredentialsId to yaml file, fixed modules code * karmaExecuteTests.yaml renamed to karma.yaml Co-authored-by: lndrschlz <leander.schulz01@sap.com> Co-authored-by: Christopher Fenner <26137398+CCFenner@users.noreply.github.com>
This commit is contained in:
parent
d04a7c2eb3
commit
61f4c5245a
@ -19,23 +19,27 @@ func karmaExecuteTests(config karmaExecuteTestsOptions, telemetryData *telemetry
|
||||
|
||||
func runKarma(config karmaExecuteTestsOptions, command command.ExecRunner) {
|
||||
installCommandTokens := tokenize(config.InstallCommand)
|
||||
command.SetDir(config.ModulePath)
|
||||
err := command.RunExecutable(installCommandTokens[0], installCommandTokens[1:]...)
|
||||
if err != nil {
|
||||
log.Entry().
|
||||
WithError(err).
|
||||
WithField("command", config.InstallCommand).
|
||||
Fatal("failed to execute install command")
|
||||
}
|
||||
|
||||
runCommandTokens := tokenize(config.RunCommand)
|
||||
command.SetDir(config.ModulePath)
|
||||
err = command.RunExecutable(runCommandTokens[0], runCommandTokens[1:]...)
|
||||
if err != nil {
|
||||
log.Entry().
|
||||
WithError(err).
|
||||
WithField("command", config.RunCommand).
|
||||
Fatal("failed to execute run command")
|
||||
modulePaths := config.Modules
|
||||
|
||||
for _, module := range modulePaths {
|
||||
command.SetDir(module)
|
||||
err := command.RunExecutable(installCommandTokens[0], installCommandTokens[1:]...)
|
||||
if err != nil {
|
||||
log.Entry().
|
||||
WithError(err).
|
||||
WithField("command", config.InstallCommand).
|
||||
Fatal("failed to execute install command")
|
||||
}
|
||||
|
||||
command.SetDir(module)
|
||||
err = command.RunExecutable(runCommandTokens[0], runCommandTokens[1:]...)
|
||||
if err != nil {
|
||||
log.Entry().
|
||||
WithError(err).
|
||||
WithField("command", config.RunCommand).
|
||||
Fatal("failed to execute run command")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,9 +14,9 @@ import (
|
||||
)
|
||||
|
||||
type karmaExecuteTestsOptions struct {
|
||||
InstallCommand string `json:"installCommand,omitempty"`
|
||||
ModulePath string `json:"modulePath,omitempty"`
|
||||
RunCommand string `json:"runCommand,omitempty"`
|
||||
InstallCommand string `json:"installCommand,omitempty"`
|
||||
Modules []string `json:"modules,omitempty"`
|
||||
RunCommand string `json:"runCommand,omitempty"`
|
||||
}
|
||||
|
||||
// KarmaExecuteTestsCommand Executes the Karma test runner
|
||||
@ -87,11 +87,11 @@ In the Docker network, the containers can be referenced by the values provided i
|
||||
|
||||
func addKarmaExecuteTestsFlags(cmd *cobra.Command, stepConfig *karmaExecuteTestsOptions) {
|
||||
cmd.Flags().StringVar(&stepConfig.InstallCommand, "installCommand", `npm install --quiet`, "The command that is executed to install the test tool.")
|
||||
cmd.Flags().StringVar(&stepConfig.ModulePath, "modulePath", `.`, "Define the path of the module to execute tests on.")
|
||||
cmd.Flags().StringSliceVar(&stepConfig.Modules, "modules", []string{`.`}, "Define the paths of the modules to execute tests on.")
|
||||
cmd.Flags().StringVar(&stepConfig.RunCommand, "runCommand", `npm run karma`, "The command that is executed to start the tests.")
|
||||
|
||||
cmd.MarkFlagRequired("installCommand")
|
||||
cmd.MarkFlagRequired("modulePath")
|
||||
cmd.MarkFlagRequired("modules")
|
||||
cmd.MarkFlagRequired("runCommand")
|
||||
}
|
||||
|
||||
@ -119,10 +119,10 @@ func karmaExecuteTestsMetadata() config.StepData {
|
||||
Aliases: []config.Alias{},
|
||||
},
|
||||
{
|
||||
Name: "modulePath",
|
||||
Name: "modules",
|
||||
ResourceRef: []config.ResourceReference{},
|
||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||
Type: "string",
|
||||
Type: "[]string",
|
||||
Mandatory: true,
|
||||
Aliases: []config.Alias{},
|
||||
},
|
||||
|
@ -2,16 +2,17 @@ package cmd
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/SAP/jenkins-library/pkg/mock"
|
||||
"testing"
|
||||
|
||||
"github.com/SAP/jenkins-library/pkg/mock"
|
||||
|
||||
"github.com/SAP/jenkins-library/pkg/log"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestRunKarma(t *testing.T) {
|
||||
t.Run("success case", func(t *testing.T) {
|
||||
opts := karmaExecuteTestsOptions{ModulePath: "./test", InstallCommand: "npm install test", RunCommand: "npm run test"}
|
||||
opts := karmaExecuteTestsOptions{Modules: []string{"./test"}, InstallCommand: "npm install test", RunCommand: "npm run test"}
|
||||
|
||||
e := mock.ExecMockRunner{}
|
||||
runKarma(opts, &e)
|
||||
@ -28,7 +29,7 @@ func TestRunKarma(t *testing.T) {
|
||||
var hasFailed bool
|
||||
log.Entry().Logger.ExitFunc = func(int) { hasFailed = true }
|
||||
|
||||
opts := karmaExecuteTestsOptions{ModulePath: "./test", InstallCommand: "fail install test", RunCommand: "npm run test"}
|
||||
opts := karmaExecuteTestsOptions{Modules: []string{"./test"}, InstallCommand: "fail install test", RunCommand: "npm run test"}
|
||||
|
||||
e := mock.ExecMockRunner{ShouldFailOnCommand: map[string]error{"fail install test": errors.New("error case")}}
|
||||
runKarma(opts, &e)
|
||||
@ -39,7 +40,7 @@ func TestRunKarma(t *testing.T) {
|
||||
var hasFailed bool
|
||||
log.Entry().Logger.ExitFunc = func(int) { hasFailed = true }
|
||||
|
||||
opts := karmaExecuteTestsOptions{ModulePath: "./test", InstallCommand: "npm install test", RunCommand: "npm run test"}
|
||||
opts := karmaExecuteTestsOptions{Modules: []string{"./test"}, InstallCommand: "npm install test", RunCommand: "npm run test"}
|
||||
|
||||
e := mock.ExecMockRunner{ShouldFailOnCommand: map[string]error{"npm install test": errors.New("error case")}}
|
||||
runKarma(opts, &e)
|
||||
|
@ -15,6 +15,10 @@ metadata:
|
||||
In a Kubernetes environment, the containers both need to be referenced with `localhost`.
|
||||
spec:
|
||||
inputs:
|
||||
secrets:
|
||||
- name: seleniumHubCredentialsId
|
||||
type: jenkins
|
||||
description: "Defines the id of the user/password credentials to be used to connect to a Selenium Hub. The credentials are provided in the environment variables `PIPER_SELENIUM_HUB_USER` and `PIPER_SELENIUM_HUB_PASSWORD`."
|
||||
resources:
|
||||
- name: buildDescriptor
|
||||
type: stash
|
||||
@ -31,10 +35,10 @@ spec:
|
||||
- STAGES
|
||||
- STEPS
|
||||
mandatory: true
|
||||
- name: modulePath
|
||||
type: string
|
||||
description: Define the path of the module to execute tests on.
|
||||
default: "."
|
||||
- name: modules
|
||||
type: "[]string"
|
||||
description: Define the paths of the modules to execute tests on.
|
||||
default: ["."]
|
||||
scope:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
|
@ -170,6 +170,7 @@ public class CommonStepsTest extends BasePiperTest{
|
||||
'containerSaveImage', //implementing new golang pattern without fields
|
||||
'detectExecuteScan', //implementing new golang pattern without fields
|
||||
'kanikoExecute', //implementing new golang pattern without fields
|
||||
'karmaExecuteTests', //implementing new golang pattern without fields
|
||||
'gitopsUpdateDeployment', //implementing new golang pattern without fields
|
||||
'vaultRotateSecretId', //implementing new golang pattern without fields
|
||||
'deployIntegrationArtifact', //implementing new golang pattern without fields
|
||||
|
@ -1,101 +0,0 @@
|
||||
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 stepRule = new JenkinsStepRule(this)
|
||||
private JenkinsLoggingRule loggingRule = new JenkinsLoggingRule(this)
|
||||
private JenkinsShellCallRule shellRule = new JenkinsShellCallRule(this)
|
||||
private JenkinsEnvironmentRule environmentRule = new JenkinsEnvironmentRule(this)
|
||||
private ExpectedException thrown = ExpectedException.none()
|
||||
|
||||
@Rule
|
||||
public RuleChain rules = Rules
|
||||
.getCommonRules(this)
|
||||
.around(new JenkinsReadYamlRule(this))
|
||||
.around(shellRule)
|
||||
.around(loggingRule)
|
||||
.around(environmentRule)
|
||||
.around(stepRule)
|
||||
.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 {
|
||||
stepRule.step.karmaExecuteTests(
|
||||
script: nullScript,
|
||||
juStabUtils: utils
|
||||
)
|
||||
assertThat(shellRule.shell, hasItems(
|
||||
containsString("cd '.' && npm install --quiet"),
|
||||
containsString("cd '.' && npm run karma")
|
||||
))
|
||||
assertThat(seleniumParams.dockerImage, is('node:lts-stretch'))
|
||||
assertThat(seleniumParams.dockerName, is('karma'))
|
||||
assertThat(seleniumParams.dockerWorkspace, is('/home/node'))
|
||||
assertJobStatusSuccess()
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDockerFromCustomStepConfiguration() {
|
||||
|
||||
def expectedImage = 'image:test'
|
||||
def expectedEnvVars = ['NO_PROXY':'', 'no_proxy':'', 'env1': 'value1', 'env2': 'value2']
|
||||
def expectedOptions = '--opt1=val1 --opt2=val2 --opt3'
|
||||
def expectedWorkspace = '/path/to/workspace'
|
||||
|
||||
nullScript.commonPipelineEnvironment.configuration = [steps:[karmaExecuteTests:[
|
||||
dockerImage: expectedImage,
|
||||
dockerOptions: expectedOptions,
|
||||
dockerEnvVars: expectedEnvVars,
|
||||
dockerWorkspace: expectedWorkspace
|
||||
]]]
|
||||
|
||||
stepRule.step.karmaExecuteTests(
|
||||
script: nullScript,
|
||||
juStabUtils: utils
|
||||
)
|
||||
|
||||
assert expectedImage == seleniumParams.dockerImage
|
||||
assert expectedOptions == seleniumParams.dockerOptions
|
||||
assert expectedWorkspace == seleniumParams.dockerWorkspace
|
||||
expectedEnvVars.each { key, value ->
|
||||
assert seleniumParams.dockerEnvVars[key] == value
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMultiModules() throws Exception {
|
||||
stepRule.step.karmaExecuteTests(
|
||||
script: nullScript,
|
||||
juStabUtils: utils,
|
||||
modules: ['./ui-trade', './ui-traderequest']
|
||||
)
|
||||
assertThat(shellRule.shell, hasItems(
|
||||
containsString("cd './ui-trade' && npm run karma"),
|
||||
containsString("cd './ui-trade' && npm install --quiet")
|
||||
))
|
||||
assertThat(shellRule.shell, hasItems(
|
||||
containsString("cd './ui-traderequest' && npm run karma"),
|
||||
containsString("cd './ui-traderequest' && npm install --quiet")
|
||||
))
|
||||
assertJobStatusSuccess()
|
||||
}
|
||||
}
|
@ -9,124 +9,12 @@ import groovy.text.GStringTemplateEngine
|
||||
import groovy.transform.Field
|
||||
|
||||
@Field String STEP_NAME = getClass().getName()
|
||||
@Field Set GENERAL_CONFIG_KEYS = [
|
||||
/**
|
||||
* Map which defines per docker image the port mappings, e.g. `containerPortMappings: ['selenium/standalone-chrome': [[name: 'selPort', containerPort: 4444, hostPort: 4444]]]`.
|
||||
*/
|
||||
'containerPortMappings',
|
||||
/** A map of environment variables to set in the container, e.g. [http_proxy:'proxy:8080']. */
|
||||
'dockerEnvVars',
|
||||
/** The name of the docker image that should be used. If empty, Docker is not used and the command is executed directly on the Jenkins system. */
|
||||
'dockerImage',
|
||||
/**
|
||||
* Kubernetes only:
|
||||
* Name of the container launching `dockerImage`.
|
||||
* SideCar only:
|
||||
* Name of the container in local network.
|
||||
*/
|
||||
'dockerName',
|
||||
/**
|
||||
* Kubernetes only:
|
||||
* Specifies a dedicated user home directory for the container which will be passed as value for environment variable `HOME`.
|
||||
*/
|
||||
'dockerWorkspace',
|
||||
/** @see dockerExecute */
|
||||
'dockerOptions',
|
||||
/**
|
||||
* With `failOnError` the behavior in case tests fail can be defined.
|
||||
* @possibleValues `true`, `false`
|
||||
*/
|
||||
'failOnError',
|
||||
/** The command that is executed to install the test tool. */
|
||||
'installCommand',
|
||||
/** Define the paths of the modules to execute tests on. */
|
||||
'modules',
|
||||
/** The command that is executed to start the tests. */
|
||||
'runCommand',
|
||||
/** @see seleniumExecuteTests */
|
||||
'seleniumHubCredentialsId',
|
||||
/** A map of environment variables to set in the sidecar container, similar to `dockerEnvVars`. */
|
||||
'sidecarEnvVars',
|
||||
/** The name of the docker image of the sidecar container. If empty, no sidecar container is started. */
|
||||
'sidecarImage',
|
||||
/**
|
||||
* as `dockerName` for the sidecar container
|
||||
*/
|
||||
'sidecarName',
|
||||
/** Volumes that should be mounted into the sidecar container. */
|
||||
'sidecarVolumeBind',
|
||||
/** If specific stashes should be considered for the tests, their names need to be passed via the parameter `stashContent`. */
|
||||
'stashContent'
|
||||
]
|
||||
@Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS
|
||||
@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS
|
||||
@Field String METADATA_FILE = 'metadata/karma.yaml'
|
||||
|
||||
/**
|
||||
* In this step the ([Karma test runner](http://karma-runner.github.io)) is executed.
|
||||
*
|
||||
* The step is using the `seleniumExecuteTest` step to spin up two containers in a Docker network:
|
||||
*
|
||||
* * a Selenium/Chrome container (`selenium/standalone-chrome`)
|
||||
* * a NodeJS container (`node:lts-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)).
|
||||
*
|
||||
* !!! note
|
||||
* In a Kubernetes environment, the containers both need to be referenced with `localhost`.
|
||||
*/
|
||||
@GenerateDocumentation
|
||||
void call(Map parameters = [:]) {
|
||||
handlePipelineStepErrors(stepName: STEP_NAME, stepParameters: parameters) {
|
||||
final script = checkScript(this, parameters) ?: this
|
||||
def utils = parameters?.juStabUtils ?: new Utils()
|
||||
String stageName = parameters.stageName ?: env.STAGE_NAME
|
||||
|
||||
// load default & individual configuration
|
||||
Map config = ConfigurationHelper.newInstance(this)
|
||||
.loadStepDefaults([:], stageName)
|
||||
.mixinGeneralConfig(script.commonPipelineEnvironment, GENERAL_CONFIG_KEYS)
|
||||
.mixinStepConfig(script.commonPipelineEnvironment, STEP_CONFIG_KEYS)
|
||||
.mixinStageConfig(script.commonPipelineEnvironment, stageName, STEP_CONFIG_KEYS)
|
||||
.mixin(parameters, PARAMETER_KEYS)
|
||||
.use()
|
||||
|
||||
utils.pushToSWA([step: STEP_NAME], config)
|
||||
|
||||
def testJobs = [:]
|
||||
def options = [
|
||||
script: script,
|
||||
containerPortMappings: config.containerPortMappings,
|
||||
dockerEnvVars: config.dockerEnvVars,
|
||||
dockerImage: config.dockerImage,
|
||||
dockerName: config.dockerName,
|
||||
dockerWorkspace: config.dockerWorkspace,
|
||||
dockerOptions: config.dockerOptions,
|
||||
failOnError: config.failOnError,
|
||||
seleniumHubCredentialsId: config.seleniumHubCredentialsId,
|
||||
sidecarEnvVars: config.sidecarEnvVars,
|
||||
sidecarImage: config.sidecarImage,
|
||||
sidecarName: config.sidecarName,
|
||||
sidecarVolumeBind: config.sidecarVolumeBind,
|
||||
stashContent: config.stashContent
|
||||
]
|
||||
for(String path : config.modules){
|
||||
String modulePath = path
|
||||
testJobs["Karma - ${modulePath}"] = {
|
||||
seleniumExecuteTests(options){
|
||||
try {
|
||||
sh "cd '${modulePath}' && ${config.installCommand}"
|
||||
sh "cd '${modulePath}' && ${config.runCommand}"
|
||||
} catch (e) {
|
||||
error "[${STEP_NAME}] ERROR: The execution of the karma tests failed, see the log for details."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(testJobs.size() == 1){
|
||||
testJobs.each({ key, value -> value() })
|
||||
}else{
|
||||
parallel testJobs.plus([failFast: false])
|
||||
}
|
||||
}
|
||||
List credentials = [
|
||||
[type: 'usernamePassword', id: 'seleniumHubCredentialsId', env: ['PIPER_SELENIUM_HUB_USER', 'PIPER_SELENIUM_HUB_PASSWORD']],
|
||||
]
|
||||
final script = checkScript(this, parameters) ?: this
|
||||
piperExecuteBin(parameters, STEP_NAME, METADATA_FILE, credentials)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user