diff --git a/src/ploigos_step_runner/step_implementers/package/maven.py b/src/ploigos_step_runner/step_implementers/package/maven.py
index 1a0ac90b..4e7c4fd5 100644
--- a/src/ploigos_step_runner/step_implementers/package/maven.py
+++ b/src/ploigos_step_runner/step_implementers/package/maven.py
@@ -3,12 +3,6 @@
Notes
-----
-.. WARNING::
-
- This can currently only handle POMs that generate a single artifact.
- See https://github.com/ploigos/ploigos-step-runner/issues/99 for RFE
- to handle multiple artifacts.
-
.. Important::
If package not specified in pom will default to jar in result.
@@ -22,17 +16,31 @@
* runtime configuration
* previous step results
-Configuration Key | Required? | Default | Description
-----------------------|-----------|-------------------------|-----------
-`pom-file` | True | `'pom.xml'` | Maven pom file to build
-`artifact-extensions` | True | `["jar", "war", "ear"]` | Extensions to look for in the \
- `artifact-parent-dir` for built \
- artifacts.
-`artifact-parent-dir` | True | `'target'` | Parent directory to look for built \
- artifacts in ending in \
- `artifact-extensions`.
-`tls-verify` | No | True | Disables TLS Verification if set to \
- False
+Configuration Key | Required? | Default | Description
+-----------------------------|-----------|---------|-----------
+`pom-file` | Yes | `'pom.xml'` | pom used when executing maven.
+`tls-verify` | No | `True` | Disables TLS Verification if set to False
+`maven-profiles` | No | `[]` | List of maven profiles to use.
+`maven-no-transfer-progress` | No | `True` | \
+ `True` to suppress the transfer progress of packages maven downloads.
+ `False` to have the transfer progress printed.\
+ See https://maven.apache.org/ref/current/maven-embedder/cli.html
+`maven-additional-arguments` | No | `['-Dmaven.test.skip=true']` \
+ | List of additional arguments to use. \
+ Skipping tests by default because assuming \
+ a previous step already ran them.
+`maven-servers` | No | | Dictionary of dictionaries of \
+ id, username, password
+`maven-repositories` | No | | Dictionary of dictionaries of \
+ id, url, snapshots, releases
+`maven-mirrors` | No | | Dictionary of dictionaries of \
+ id, url, mirror_of
+`artifact-extensions` | Yes | `["jar", "war", "ear"]` \
+ | Extensions to look for in the `artifact-parent-dir` \
+ for built artifacts.
+`artifact-parent-dir` | Yes | `'target'` \
+ | Parent directory to look for built artifacts in \
+ ending in `artifact-extensions`.
Result Artifacts
----------------
@@ -40,7 +48,8 @@
Result Artifact Key | Description
--------------------|------------
-`package-artifacts` | An array of dictionaries with information on the built artifacts.
+`maven-output` | Path to Stdout and Stderr from invoking Maven.
+`packages` | An array of dictionaries with information on the built artifacts.
## package-artifacts
@@ -49,58 +58,18 @@
| Key | Description
|-----------------|------------
| `path` | Absolute path to the built artifact.
-| `artifact-id` | Maven artifact ID.
-| `group-id` | Maven group ID.
-| `package-type` | Package type.
-| `pom-path` | Absolute path to the pom that built the artifact.
-
-Examples
---------
-
-**Example 1**
-
-*Given POM*
-
-
- 4.0.0
- com.mycompany.app
- my-app
- 1.0-SNAPSHOT
-
- 1.8
- 1.8
-
-
-
-**Example 2**
-
-*Given POM*
-
-
- 4.0.0
- com.mycompany.app
- my-app
- 1.0-SNAPSHOT
- war
-
- 1.8
- 1.8
-
-
"""
import os
-import sys
-import sh
-from ploigos_step_runner import StepResult
-from ploigos_step_runner.step_implementers.shared.maven_generic import MavenGeneric
-from ploigos_step_runner.utils.io import create_sh_redirect_to_multiple_streams_fn_callback
-from ploigos_step_runner.utils.xml import get_xml_element
+from ploigos_step_runner import StepResult, StepRunnerException
+from ploigos_step_runner.step_implementers.shared.maven_generic import \
+ MavenGeneric
DEFAULT_CONFIG = {
- 'tls-verify': True,
- 'pom-file': 'pom.xml',
+ 'maven-additional-arguments': [
+ '-Dmaven.test.skip=true'
+ ],
'artifact-extensions': ["jar", "war", "ear"],
'artifact-parent-dir': 'target'
}
@@ -109,10 +78,23 @@
'pom-file'
]
-
class Maven(MavenGeneric):
"""`StepImplementer` for the `package` step using Maven.
"""
+ def __init__( # pylint: disable=too-many-arguments
+ self,
+ workflow_result,
+ parent_work_dir_path,
+ config,
+ environment=None
+ ):
+ super().__init__(
+ workflow_result=workflow_result,
+ parent_work_dir_path=parent_work_dir_path,
+ config=config,
+ environment=environment,
+ maven_phases_and_goals=['package']
+ )
@staticmethod
def step_implementer_config_defaults():
@@ -126,9 +108,8 @@ def step_implementer_config_defaults():
Notes
-----
These are the lowest precedence configuration values.
-
"""
- return DEFAULT_CONFIG
+ return {**MavenGeneric.step_implementer_config_defaults(), **DEFAULT_CONFIG}
@staticmethod
def _required_config_or_result_keys():
@@ -157,106 +138,48 @@ def _run_step(self): # pylint: disable=too-many-locals
"""
step_result = StepResult.from_step_implementer(self)
- tls_verify = self.get_value('tls-verify')
pom_file = self.get_value('pom-file')
artifact_extensions = self.get_value('artifact-extensions')
artifact_parent_dir = self.get_value('artifact-parent-dir')
- if not os.path.exists(pom_file):
- step_result.success = False
- step_result.message = f'Given pom file does not exist: {pom_file}'
- return step_result
-
- mvn_additional_options = []
- if not tls_verify:
- mvn_additional_options += [
- '-Dmaven.wagon.http.ssl.insecure=true',
- '-Dmaven.wagon.http.ssl.allowall=true',
- '-Dmaven.wagon.http.ssl.ignore.validity.dates=true',
- ]
-
- settings_file = self._generate_maven_settings()
- mvn_output_file_path = self.write_working_file('mvn_test_output.txt')
+ # package the artifacts
+ mvn_output_file_path = self.write_working_file('mvn_output.txt')
try:
- with open(mvn_output_file_path, 'w') as mvn_output_file:
- out_callback = create_sh_redirect_to_multiple_streams_fn_callback([
- sys.stdout,
- mvn_output_file
- ])
- err_callback = create_sh_redirect_to_multiple_streams_fn_callback([
- sys.stderr,
- mvn_output_file
- ])
+ # execute maven step (params come from config)
+ self._run_maven_step(
+ mvn_output_file_path=mvn_output_file_path
+ )
+
+ # find the artifacts
+ packages = []
+ pom_file_dir_name = os.path.dirname(os.path.abspath(pom_file))
+ artifact_parent_dir_full_path = \
+ os.listdir(os.path.join(
+ pom_file_dir_name,
+ artifact_parent_dir))
+ for filename in artifact_parent_dir_full_path:
+ if any(filename.endswith(ext) for ext in artifact_extensions):
+ packages += [{
+ 'path': os.path.join(
+ pom_file_dir_name,
+ artifact_parent_dir,
+ filename
+ )
+ }]
- sh.mvn( # pylint: disable=no-member
- 'clean',
- 'install',
- '-f', pom_file,
- '-s', settings_file,
- *mvn_additional_options,
- _out=out_callback,
- _err=err_callback
- )
- except sh.ErrorReturnCode as error:
+ step_result.add_artifact(
+ name='packages',
+ value=packages
+ )
+ except StepRunnerException as error:
step_result.success = False
- step_result.message = "Package failures. See 'maven-output' report artifacts " \
- f"for details: {error}"
- return step_result
+ step_result.message = "Error running 'maven package' to package artifacts. " \
+ f"More details maybe found in 'maven-output' report artifact: {error}"
finally:
step_result.add_artifact(
- description="Standard out and standard error from 'mvn install'.",
+ description="Standard out and standard error from maven.",
name='maven-output',
value=mvn_output_file_path
)
- # find the artifacts
- artifact_file_names = []
- artifact_parent_dir_full_path = \
- os.listdir(os.path.join(
- os.path.dirname(os.path.abspath(pom_file)),
- artifact_parent_dir))
- for filename in artifact_parent_dir_full_path:
- if any(filename.endswith(ext) for ext in artifact_extensions):
- artifact_file_names.append(filename)
-
- # error if we find more then one artifact
- # see https://projects.engineering.redhat.com/browse/NAPSSPO-546
- if len(artifact_file_names) > 1:
- step_result.success = False
- step_result.message = 'pom resulted in multiple artifacts with expected artifact ' \
- f'extensions ({artifact_extensions}), this is unsupported'
- return step_result
-
- if len(artifact_file_names) < 1:
- step_result.success = False
- step_result.message = 'pom resulted in 0 with expected artifact extensions ' \
- f'({artifact_extensions}), this is unsupported'
- return step_result
-
- artifact_id = get_xml_element(pom_file, 'artifactId').text
- group_id = get_xml_element(pom_file, 'groupId').text
- try:
- package_type = get_xml_element(pom_file, 'package').text
- except ValueError:
- package_type = 'jar'
-
- package_artifacts = {
- 'path': os.path.join(
- os.path.dirname(os.path.abspath(pom_file)),
- artifact_parent_dir,
- artifact_file_names[0]
- ),
- 'artifact-id': artifact_id,
- 'group-id': group_id,
- 'package-type': package_type,
- 'pom-path': pom_file
- }
-
- # Currently, package returns ONE 'artifact', eg: one war file
- # However, in the future, an ARRAY could be returned, eg: several jar files
- step_result.add_artifact(
- name='package-artifacts',
- value=[package_artifacts]
- )
-
return step_result
diff --git a/src/ploigos_step_runner/step_implementers/push_artifacts/maven.py b/src/ploigos_step_runner/step_implementers/push_artifacts/maven.py
index bdfebc8a..3061f3e7 100644
--- a/src/ploigos_step_runner/step_implementers/push_artifacts/maven.py
+++ b/src/ploigos_step_runner/step_implementers/push_artifacts/maven.py
@@ -9,19 +9,34 @@
* runtime configuration
* previous step results
-Configuration Key | Required | Default | Description
--------------------------------|----------|---------|------------------------------------------
-`maven-push-artifact-repo-url` | yes | | id for the maven servers and mirrors
-`maven-push-artifact-repo-id` | Yes | | url for the maven servers and mirrors
-`version` | Yes | | version to push
-`package-artifacts` | Yes | | Artifacts is dictionary \
- Each element of an `artifact` will be used \
- as a parameter to deploy to repository:
\
- * artifact.group-id
\
- * artifact.artifact-id
\
- * artifact.path
\
- * artifact.package-type
-`tls-verify` | No | True | Disables TLS Verification if set to False
+Configuration Key | Required? | Default | Description
+-----------------------------|-----------|---------|-----------
+`pom-file` | Yes | `'pom.xml'` | pom used when executing maven.
+`tls-verify` | No | `True` | Disables TLS Verification if set to False
+`maven-profiles` | No | `[]` | List of maven profiles to use.
+`maven-no-transfer-progress` | No | `True` | \
+ `True` to suppress the transfer progress of packages maven downloads.
+ `False` to have the transfer progress printed.\
+ See https://maven.apache.org/ref/current/maven-embedder/cli.html
+`maven-additional-arguments` | No | `['-Dmaven.test.skip=true', \
+ '-Dmaven.install.skip=true']` \
+ | List of additional arguments to use. \
+ Skipping tests by default because assuming \
+ a previous step already ran them. \
+ Skipping install backs assuming this is \
+ running in an ephermal environment where \
+ that would be a waist of time, and also \
+ that a previous step ran `package` \
+ and `push-artifacts` steps.
+`maven-servers` | No | | Dictionary of dictionaries of \
+ id, username, password
+`maven-repositories` | No | | Dictionary of dictionaries of \
+ id, url, snapshots, releases
+`maven-mirrors` | No | | Dictionary of dictionaries of \
+ id, url, mirror_of
+`version` | Yes | | version to push
+`maven-push-artifact-repo-url` | yes | | id for the maven servers and mirrors
+`maven-push-artifact-repo-id` | Yes | | url for the maven servers and mirrors
Result Artifacts
----------------
@@ -29,68 +44,49 @@
Result Artifact Key | Description
--------------------|------------
-`push-artifacts` | An array of dictionaries with information on the built artifacts.
-
-## push-artifacts
-Keys in the dictionary elements in the `push-artifacts` array in the step results.
-
-| Key | Description
-|-----------------|------------
-| `path` | Absolute path to the artifact pushed to the artifact repository
-| `artifact-id` | Maven artifact ID pushed to the artifact repository
-| `group-id` | Maven group ID pushed to the artifact repository
-| `version` | Version pushed to the artifact repository
-| `packaging` | Type of package (eg: jar, war)
-
-Examples
---------
-
-**Example: Step Configuration (minimal)**
-
- push-artifacts:
- - implementer: Maven
- config:
- maven-push-artifact-repo-id: internal-id-name
- maven-push-artifact-repo-url: url-to server
-
-**Example: Generated Maven Deploy (uses both step configuration and previous results)**
-
- mvn
- deploy:deploy-file'
- -Durl=maven-push-artifact-repo-url
- -Dversion=package.artifact.version
- -DgroupId=package.artifact.group-id
- -DartifactId=package.artifact.artifact-id
- -Dfile=package.artifact.path
- -Dpackaging=package.artifact.package-type
- -DrepositoryId=maven-push-artifact-repo-id
- -s settings.xml
+`push-artifacts` | An array of dictionaries with information on the pushed artifacts
"""
-import sys
-import sh
-from ploigos_step_runner import StepResult
-from ploigos_step_runner.step_implementers.shared.maven_generic import MavenGeneric
-from ploigos_step_runner.utils.io import create_sh_redirect_to_multiple_streams_fn_callback
+from ploigos_step_runner import StepResult, StepRunnerException
+from ploigos_step_runner.step_implementers.shared.maven_generic import \
+ MavenGeneric
+from ploigos_step_runner.utils.maven import run_maven
DEFAULT_CONFIG = {
- 'tls-verify': True
+ 'maven-additional-arguments': [
+ '-Dmaven.install.skip=true',
+ '-Dmaven.test.skip=true'
+ ]
}
+
REQUIRED_CONFIG_OR_PREVIOUS_STEP_RESULT_ARTIFACT_KEYS = [
+ 'pom-file',
'maven-push-artifact-repo-url',
'maven-push-artifact-repo-id',
- 'version',
- 'package-artifacts'
+ 'version'
]
class Maven(MavenGeneric):
- """`StepImplementer` for the `package` step using Maven.
+ """`StepImplementer` for the `push-artifacts` step using Maven.
"""
+ def __init__( # pylint: disable=too-many-arguments
+ self,
+ workflow_result,
+ parent_work_dir_path,
+ config,
+ environment=None
+ ):
+ super().__init__(
+ workflow_result=workflow_result,
+ parent_work_dir_path=parent_work_dir_path,
+ config=config,
+ environment=environment,
+ maven_phases_and_goals=['deploy']
+ )
@staticmethod
def step_implementer_config_defaults():
- """
- Getter for the StepImplementer's configuration defaults.
+ """Getter for the StepImplementer's configuration defaults.
Returns
-------
@@ -101,7 +97,7 @@ def step_implementer_config_defaults():
-----
These are the lowest precedence configuration values.
"""
- return DEFAULT_CONFIG
+ return {**MavenGeneric.step_implementer_config_defaults(), **DEFAULT_CONFIG}
@staticmethod
def _required_config_or_result_keys():
@@ -134,76 +130,56 @@ def _run_step(self): # pylint: disable=too-many-locals
maven_push_artifact_repo_id = self.get_value('maven-push-artifact-repo-id')
maven_push_artifact_repo_url = self.get_value('maven-push-artifact-repo-url')
version = self.get_value('version')
- package_artifacts = self.get_value('package-artifacts')
- tls_verify = self.get_value('tls-verify')
-
- # disable tls verification
- mvn_additional_options = []
- if not tls_verify:
- mvn_additional_options += [
- '-Dmaven.wagon.http.ssl.insecure=true',
- '-Dmaven.wagon.http.ssl.allowall=true',
- '-Dmaven.wagon.http.ssl.ignore.validity.dates=true',
- ]
-
- # Create settings.xml
- settings_file = self._generate_maven_settings()
# push the artifacts
- push_artifacts = []
- mvn_output_file_path = self.write_working_file('mvn_test_output.txt')
+ mvn_update_version_output_file_path = self.write_working_file('mvn_versions_set_output.txt')
+ mvn_push_artifacts_output_file_path = self.write_working_file('mvn_deploy_output.txt')
try:
- for package in package_artifacts:
- artifact_path = package['path']
- group_id = package['group-id']
- artifact_id = package['artifact-id']
- package_type = package['package-type']
-
- # push the artifact
- with open(mvn_output_file_path, 'a') as mvn_output_file:
- out_callback = create_sh_redirect_to_multiple_streams_fn_callback([
- sys.stdout,
- mvn_output_file
- ])
- err_callback = create_sh_redirect_to_multiple_streams_fn_callback([
- sys.stderr,
- mvn_output_file
- ])
- sh.mvn( # pylint: disable=no-member
- 'deploy:deploy-file',
- '-Dversion=' + version,
- '-Dfile=' + artifact_path,
- '-DgroupId=' + group_id,
- '-DartifactId=' + artifact_id,
- '-Dpackaging=' + package_type,
- '-Durl=' + maven_push_artifact_repo_url,
- '-DrepositoryId=' + maven_push_artifact_repo_id,
- '-s' + settings_file,
- *mvn_additional_options,
- _out=out_callback,
- _err=err_callback
- )
-
- # record the pushed artifact
- push_artifacts.append({
- 'artifact-id': artifact_id,
- 'group-id': group_id,
- 'version': version,
- 'path': artifact_path,
- 'packaging': package_type,
- })
- except sh.ErrorReturnCode as error:
+ # update the version before pushing
+ # NOTE 1: we know this is weird. But the version in the pom isn't necessarily
+ # the version that was calculated as part of the release and so we need
+ # to update that before doing the maven deploy so the maven deploy will
+ # use the new version.
+ #
+ # NOTE 2: we tried doing this in the same command as the deploy,
+ # but the pom was already loaded so even though the xml was updated
+ # the deploy still used the old version, hence having to run this
+ # first and independently.
+ print("Update maven package version")
+ run_maven(
+ mvn_output_file_path=mvn_update_version_output_file_path,
+ settings_file=self.maven_settings_file,
+ pom_file=self.get_value('pom-file'),
+ phases_and_goals=['versions:set'],
+ additional_arguments=[
+ f'-DnewVersion={version}'
+ ]
+ )
+
+ # execute maven step (params come from config)
+ print("Push packaged maven artifacts")
+ self._run_maven_step(
+ mvn_output_file_path=mvn_push_artifacts_output_file_path,
+ step_implementer_additional_arguments=[
+ '-DaltDeploymentRepository=' \
+ f'{maven_push_artifact_repo_id}::default::{maven_push_artifact_repo_url}'
+ ]
+ )
+ except StepRunnerException as error:
step_result.success = False
- step_result.message = "Push artifacts failures. See 'maven-output' report artifacts " \
- f"for details: {error}"
+ step_result.message = "Error running 'maven deploy' to push artifacts. " \
+ f"More details maybe found in 'maven-output' report artifact: {error}"
+ finally:
+ step_result.add_artifact(
+ description="Standard out and standard error from running maven to update version.",
+ name='maven-update-version-output',
+ value=mvn_update_version_output_file_path
+ )
+ step_result.add_artifact(
+ description="Standard out and standard error from running maven to " \
+ "push artifacts to repository.",
+ name='maven-push-artifacts-output',
+ value=mvn_push_artifacts_output_file_path
+ )
- step_result.add_artifact(
- description="Standard out and standard error from 'mvn install'.",
- name='maven-output',
- value=mvn_output_file_path
- )
- step_result.add_artifact(
- name='push-artifacts',
- value=push_artifacts
- )
return step_result
diff --git a/src/ploigos_step_runner/step_implementers/shared/maven_generic.py b/src/ploigos_step_runner/step_implementers/shared/maven_generic.py
index 3d02c393..f493f075 100644
--- a/src/ploigos_step_runner/step_implementers/shared/maven_generic.py
+++ b/src/ploigos_step_runner/step_implementers/shared/maven_generic.py
@@ -1,13 +1,53 @@
"""Abstract parent class for StepImplementers that use Maven.
+
+Step Configuration
+------------------
+Step configuration expected as input to this step.
+Could come from:
+* static configuration
+* runtime configuration
+* previous step results
+
+Configuration Key | Required? | Default | Description
+-----------------------------|-----------|---------|-----------
+`pom-file` | Yes | `'pom.xml'` | pom used when executing maven.
+`tls-verify` | No | `True` | Disables TLS Verification if set to False
+`maven-phases-and-goals` | Yes | | List of maven phases and/or goals to execute.
+`maven-profiles` | No | `[]` | List of maven profiles to use.
+`maven-no-transfer-progress` | No | `True` | \
+ `True` to suppress the transfer progress of packages maven downloads.
+ `False` to have the transfer progress printed.\
+ See https://maven.apache.org/ref/current/maven-embedder/cli.html
+`maven-additional-arguments` | No | `[]` | List of additional arguments to use.
+`maven-servers` | No | | Dictionary of dictionaries of \
+ id, username, password
+`maven-repositories` | No | | Dictionary of dictionaries of \
+ id, url, snapshots, releases
+`maven-mirrors` | No | | Dictionary of dictionaries of \
+ id, url, mirror_of
"""
import os
+from ploigos_step_runner import StepResult, StepRunnerException
from ploigos_step_runner.config.config_value import ConfigValue
from ploigos_step_runner.step_implementer import StepImplementer
-from ploigos_step_runner.utils.maven import generate_maven_settings, write_effective_pom
+from ploigos_step_runner.utils.maven import (generate_maven_settings,
+ run_maven, write_effective_pom)
from ploigos_step_runner.utils.xml import get_xml_element_by_path
+DEFAULT_CONFIG = {
+ 'pom-file': 'pom.xml',
+ 'tls-verify': True,
+ 'maven-profiles': [],
+ 'maven-additional-arguments': [],
+ 'maven-no-transfer-progress': True
+}
+
+REQUIRED_CONFIG_OR_PREVIOUS_STEP_RESULT_ARTIFACT_KEYS = [
+ 'pom-file',
+ 'maven-phases-and-goals'
+]
class MavenGeneric(StepImplementer):
"""Abstract parent class for StepImplementers that use Maven.
@@ -19,6 +59,56 @@ class MavenGeneric(StepImplementer):
f'{SUREFIRE_PLUGIN_XML_ELEMENT_PATH}/mvn:configuration/mvn:reportsDirectory'
DEFAULT_SUREFIRE_PLUGIN_REPORTS_DIR = 'target/surefire-reports'
+ def __init__( # pylint: disable=too-many-arguments
+ self,
+ workflow_result,
+ parent_work_dir_path,
+ config,
+ environment=None,
+ maven_phases_and_goals=None
+ ):
+ self.__maven_settings_file = None
+ self.__maven_phases_and_goals = maven_phases_and_goals
+
+ super().__init__(
+ workflow_result=workflow_result,
+ parent_work_dir_path=parent_work_dir_path,
+ config=config,
+ environment=environment
+ )
+
+ @staticmethod
+ def step_implementer_config_defaults():
+ """Getter for the StepImplementer's configuration defaults.
+
+ Returns
+ -------
+ dict
+ Default values to use for step configuration values.
+
+ Notes
+ -----
+ These are the lowest precedence configuration values.
+ """
+ return DEFAULT_CONFIG
+
+ @staticmethod
+ def _required_config_or_result_keys():
+ """Getter for step configuration or previous step result artifacts that are required before
+ running this step.
+
+ See Also
+ --------
+ _validate_required_config_or_previous_step_result_artifact_keys
+
+ Returns
+ -------
+ array_list
+ Array of configuration keys or previous step result artifacts
+ that are required before running the step.
+ """
+ return REQUIRED_CONFIG_OR_PREVIOUS_STEP_RESULT_ARTIFACT_KEYS
+
def _validate_required_config_or_previous_step_result_artifact_keys(self):
"""Validates that the required configuration keys or previous step result artifacts
are set and have valid values.
@@ -41,23 +131,50 @@ def _validate_required_config_or_previous_step_result_artifact_keys(self):
assert os.path.exists(pom_file), \
f'Given maven pom file (pom-file) does not exist: {pom_file}'
- def _generate_maven_settings(self):
- maven_servers = ConfigValue.convert_leaves_to_values(
- self.get_value('maven-servers')
- )
- maven_repositories = ConfigValue.convert_leaves_to_values(
- self.get_value('maven-repositories')
- )
- maven_mirrors = ConfigValue.convert_leaves_to_values(
- self.get_value('maven-mirrors')
- )
+ @property
+ def maven_phases_and_goals(self):
+ """Property for getting the maven phases and goals to execute which can either come
+ from field set on this class via constructor, intended for use by sub classes that want
+ to hard code the phases and goals for convenience, or comes from config value
+ `maven-phases-and-goals` set by the user.
- return generate_maven_settings(
- working_dir=self.work_dir_path,
- maven_servers=maven_servers,
- maven_repositories=maven_repositories,
- maven_mirrors=maven_mirrors
- )
+ Returns
+ -------
+ str
+ Maven phases and/or goals to execute.
+ """
+ maven_phases_and_goals = None
+ if self.__maven_phases_and_goals:
+ maven_phases_and_goals = self.__maven_phases_and_goals
+ else:
+ maven_phases_and_goals = self.get_value('maven-phases-and-goals')
+
+ return maven_phases_and_goals
+
+ @property
+ def maven_settings_file(self):
+ """Gets the maven settings file for this step.
+ """
+
+ if not self.__maven_settings_file:
+ maven_servers = ConfigValue.convert_leaves_to_values(
+ self.get_value('maven-servers')
+ )
+ maven_repositories = ConfigValue.convert_leaves_to_values(
+ self.get_value('maven-repositories')
+ )
+ maven_mirrors = ConfigValue.convert_leaves_to_values(
+ self.get_value('maven-mirrors')
+ )
+
+ self.__maven_settings_file = generate_maven_settings(
+ working_dir=self.work_dir_path,
+ maven_servers=maven_servers,
+ maven_repositories=maven_repositories,
+ maven_mirrors=maven_mirrors
+ )
+
+ return self.__maven_settings_file
def _get_effective_pom(self):
"""Writes the effective pom to a file and returns the path.
@@ -78,8 +195,94 @@ def _get_effective_pom(self):
return effective_pom_path
def _get_effective_pom_element(self, element_path):
+ """Get an XML element from the effective pom.
+
+ Parameters
+ ----------
+ element_path : str
+ XML path of element to to get from effective pom.
+
+ Returns
+ -------
+ str
+ Value of the element from the effective pom.
+ """
return get_xml_element_by_path(
self._get_effective_pom(),
element_path,
default_namespace='mvn'
)
+
+ def _run_maven_step(
+ self,
+ mvn_output_file_path,
+ step_implementer_additional_arguments=None
+ ):
+ """Runs maven using the configuration given to this step runner.
+
+ Parameters
+ ----------
+ mvn_output_file_path : str
+ Path to file containing the maven stdout and stderr output.
+ step_implementer_additional_arguments : []
+ Additional arguments hard coded by the step implementer.
+
+ Raises
+ ------
+ StepRunnerException
+ If maven returns a none 0 exit code.
+ """
+
+ phases_and_goals = self.maven_phases_and_goals
+ pom_file = self.get_value('pom-file')
+ tls_verify = self.get_value('tls-verify')
+ profiles = self.get_value('maven-profiles')
+ no_transfer_progress = self.get_value('maven-no-transfer-progress')
+
+ additional_arguments = []
+ if step_implementer_additional_arguments:
+ additional_arguments = \
+ step_implementer_additional_arguments + self.get_value('maven-additional-arguments')
+ else:
+ additional_arguments = self.get_value('maven-additional-arguments')
+
+ run_maven(
+ mvn_output_file_path=mvn_output_file_path,
+ phases_and_goals=phases_and_goals,
+ additional_arguments=additional_arguments,
+ pom_file=pom_file,
+ tls_verify=tls_verify,
+ profiles=profiles,
+ no_transfer_progress=no_transfer_progress,
+ settings_file=self.maven_settings_file
+ )
+
+ def _run_step(self): # pylint: disable=too-many-locals
+ """Runs the step implemented by this StepImplementer.
+
+ Returns
+ -------
+ StepResult
+ Object containing the dictionary results of this step.
+ """
+ step_result = StepResult.from_step_implementer(self)
+
+ # package the artifacts
+ mvn_output_file_path = self.write_working_file('mvn_output.txt')
+ try:
+ # execute maven step (params come from config)
+ self._run_maven_step(
+ mvn_output_file_path=mvn_output_file_path
+ )
+ except StepRunnerException as error:
+ step_result.success = False
+ step_result.message = "Error running maven. " \
+ f"More details maybe found in 'maven-output' report artifact: {error}"
+ finally:
+ step_result.add_artifact(
+ description="Standard out and standard error from maven.",
+ name='maven-output',
+ value=mvn_output_file_path
+ )
+
+ return step_result
diff --git a/src/ploigos_step_runner/step_implementers/uat/maven_selenium_cucumber.py b/src/ploigos_step_runner/step_implementers/uat/maven_selenium_cucumber.py
index 1f8c97dc..36f44272 100644
--- a/src/ploigos_step_runner/step_implementers/uat/maven_selenium_cucumber.py
+++ b/src/ploigos_step_runner/step_implementers/uat/maven_selenium_cucumber.py
@@ -8,24 +8,41 @@
* runtime configuration
* previous step results
-Configuration Key | Required? | Default | Description
----------------------|-----------|--------------------|------------
-`fail-on-no-tests` | Yes | True | Value to specify whether unit-test \
- step can succeed when no tests are defined
-`pom-file` | Yes | `pom.xml` | pom used to run tests and check \
- for existence of custom reportsDirectory
-`selenium-hub-url` | Yes | | URL where the Selenium Hub is running
-`target-host-url` | Maybe | | Target host URL for UAT. \
-
\
- If not given then use first host url from \
- `deployed-host-urls`.
-`deployed-host-urls` | Maybe | | Deployed host URLs. If `target-host-url` \
- is not given then use first URL from this \
- list. If `target-host-url` is given then \
- ignore this value.
-`uat-maven-profile` | Yes | `integration-test` | Maven profile to use to invoke \
- Selenium tests.
-`tls-verify` | No | True | Disables TLS Verification if set to False
+Configuration Key | Required? | Default | Description
+-----------------------------|-----------|---------|------------
+`pom-file` | Yes | `'pom.xml'` | pom used when executing maven.
+`tls-verify` | No | `True` | Disables TLS Verification if set to False
+`maven-profiles` | No | `['integration-test']` \
+ | \
+ List of maven profiles to use. \
+ Typically user acceptance tests are executed \
+ using a specific profile using `maven test`. \
+ If your user acceptance tests are run \
+ differently look to use \
+ `ploigos_step_runner.step_implementers.shared.MavenGeneric` \
+ instead.
+`maven-no-transfer-progress` | No | `True` | \
+ `True` to suppress the transfer progress of packages maven downloads.
+ `False` to have the transfer progress printed.\
+ See https://maven.apache.org/ref/current/maven-embedder/cli.html
+`maven-additional-arguments` | No | `[]` | List of additional arguments to use.
+`maven-servers` | No | | Dictionary of dictionaries of \
+ id, username, password
+`maven-repositories` | No | | Dictionary of dictionaries of \
+ id, url, snapshots, releases
+`maven-mirrors` | No | | Dictionary of dictionaries of \
+ id, url, mirror_of
+`fail-on-no-tests` | Yes | `True ` | `True` to fail if there are not tests to run. \
+ `False` to ignore if there are no tests to run.
+`selenium-hub-url` | Yes | | URL where the Selenium Hub is running
+`target-host-url` | Maybe | | Target host URL for UAT. \
+
\
+ If not given then use first host url from \
+ `deployed-host-urls`.
+`deployed-host-urls` | Maybe | | Deployed host URLs. If `target-host-url` \
+ is not given then use first URL from this \
+ list. If `target-host-url` is given then \
+ ignore this value.
Result Artifacts
----------------
@@ -40,35 +57,43 @@
"""
import os
-import sys
-import sh
-from ploigos_step_runner.config.config_value import ConfigValue
-from ploigos_step_runner.exceptions import StepRunnerException
-from ploigos_step_runner.step_implementers.shared.maven_generic import MavenGeneric
from ploigos_step_runner import StepResult
-from ploigos_step_runner.utils.io import create_sh_redirect_to_multiple_streams_fn_callback
-from ploigos_step_runner.utils.xml import aggregate_xml_element_attribute_values
+from ploigos_step_runner.exceptions import StepRunnerException
+from ploigos_step_runner.step_implementers.shared.maven_generic import \
+ MavenGeneric
+from ploigos_step_runner.utils.xml import \
+ aggregate_xml_element_attribute_values
DEFAULT_CONFIG = {
- 'tls-verify': True,
- 'fail-on-no-tests': True,
- 'pom-file': 'pom.xml',
- 'uat-maven-profile': 'integration-test'
+ 'maven-profiles': ['integration-test'],
+ 'fail-on-no-tests': True
}
REQUIRED_CONFIG_OR_PREVIOUS_STEP_RESULT_ARTIFACT_KEYS = [
- 'fail-on-no-tests',
'pom-file',
+ 'fail-on-no-tests',
'selenium-hub-url',
- 'uat-maven-profile'
]
-
class MavenSeleniumCucumber(MavenGeneric):
"""`StepImplementer` for the `uat` step using Maven driving Selenium generating
Cucumber reports.
"""
+ def __init__( # pylint: disable=too-many-arguments
+ self,
+ workflow_result,
+ parent_work_dir_path,
+ config,
+ environment=None
+ ):
+ super().__init__(
+ workflow_result=workflow_result,
+ parent_work_dir_path=parent_work_dir_path,
+ config=config,
+ environment=environment,
+ maven_phases_and_goals=['test']
+ )
@staticmethod
def step_implementer_config_defaults():
@@ -83,7 +108,7 @@ def step_implementer_config_defaults():
-----
These are the lowest precedence configuration values.
"""
- return DEFAULT_CONFIG
+ return {**MavenGeneric.step_implementer_config_defaults(), **DEFAULT_CONFIG}
@staticmethod
def _required_config_or_result_keys():
@@ -136,15 +161,11 @@ def _run_step(self): # pylint: disable=too-many-locals,too-many-statements,too-m
"""
step_result = StepResult.from_step_implementer(self)
- settings_file = self._generate_maven_settings()
pom_file = self.get_value('pom-file')
fail_on_no_tests = self.get_value('fail-on-no-tests')
selenium_hub_url = self.get_value('selenium-hub-url')
- deployed_host_urls = ConfigValue.convert_leaves_to_values(
- self.get_value('deployed-host-urls')
- )
- uat_maven_profile = self.get_value('uat-maven-profile')
- tls_verify = self.get_value('tls-verify')
+ deployed_host_urls = self.get_value('deployed-host-urls')
+ maven_profiles = self.get_value('maven-profiles')
# NOTE:
# at some point may need to do smarter logic if a deployable has more then one deployed
@@ -161,7 +182,6 @@ def _run_step(self): # pylint: disable=too-many-locals,too-many-statements,too-m
else:
target_base_url = self.get_value('target-host-url')
-
# ensure surefire plugin enabled
maven_surefire_plugin = self._get_effective_pom_element(
element_path=MavenGeneric.SUREFIRE_PLUGIN_XML_ELEMENT_PATH
@@ -177,60 +197,45 @@ def _run_step(self): # pylint: disable=too-many-locals,too-many-statements,too-m
element_path=MavenGeneric.SUREFIRE_PLUGIN_REPORTS_DIR_XML_ELEMENT_PATH
)
if reports_dir is not None:
- test_results_dir = reports_dir.text
+ if os.path.isabs(reports_dir.text):
+ test_results_dir = reports_dir.text
+ else:
+ test_results_dir = os.path.join(
+ os.path.dirname(os.path.abspath(pom_file)),
+ reports_dir.text
+ )
else:
test_results_dir = os.path.join(
os.path.dirname(os.path.abspath(pom_file)),
MavenGeneric.DEFAULT_SUREFIRE_PLUGIN_REPORTS_DIR
)
- mvn_additional_options = []
- if not tls_verify:
- mvn_additional_options += [
- '-Dmaven.wagon.http.ssl.insecure=true',
- '-Dmaven.wagon.http.ssl.allowall=true',
- '-Dmaven.wagon.http.ssl.ignore.validity.dates=true',
- ]
-
cucumber_html_report_path = os.path.join(self.work_dir_path, 'cucumber.html')
cucumber_json_report_path = os.path.join(self.work_dir_path, 'cucumber.json')
mvn_output_file_path = self.write_working_file('mvn_test_output.txt')
try:
- with open(mvn_output_file_path, 'w') as mvn_output_file:
- out_callback = create_sh_redirect_to_multiple_streams_fn_callback([
- sys.stdout,
- mvn_output_file
- ])
- err_callback = create_sh_redirect_to_multiple_streams_fn_callback([
- sys.stderr,
- mvn_output_file
- ])
- sh.mvn( # pylint: disable=no-member
- 'clean',
- 'test',
- f'-P{uat_maven_profile}',
+ # execute maven step (params come from config)
+ self._run_maven_step(
+ mvn_output_file_path=mvn_output_file_path,
+ step_implementer_additional_arguments=[
f'-Dselenium.hub.url={selenium_hub_url}',
f'-Dtarget.base.url={target_base_url}',
f'-Dcucumber.plugin=' \
f'html:{cucumber_html_report_path},' \
f'json:{cucumber_json_report_path}',
- '-f', pom_file,
- '-s', settings_file,
- *mvn_additional_options,
- _out=out_callback,
- _err=err_callback
- )
+ ]
+ )
# if not results
# else add evidence of results
if not os.path.isdir(test_results_dir) or len(os.listdir(test_results_dir)) == 0:
if fail_on_no_tests:
step_result.message = "No user acceptance tests defined" \
- f" using maven profile ({uat_maven_profile})."
+ f" using maven profile ({maven_profiles})."
step_result.success = False
else:
step_result.message = "No user acceptance tests defined" \
- f" using maven profile ({uat_maven_profile})," \
+ f" using maven profile ({maven_profiles})," \
" but 'fail-on-no-tests' is False."
else:
attribs = ["time", "tests", "errors", "skipped", "failures"]
@@ -239,48 +244,57 @@ def _run_step(self): # pylint: disable=too-many-locals,too-many-statements,too-m
report_results = aggregate_xml_element_attribute_values(
test_results_dir,
xml_element,
- attribs)
+ attribs
+ )
+ not_found_attribs = []
for attrib in attribs:
if attrib in report_results:
step_result.add_evidence(
- description="Surefire report value for " + attrib,
- name="uat-evidence-" + attrib,
- value=report_results[attrib]
- )
+ description="Surefire report value for " + attrib,
+ name="uat-evidence-" + attrib,
+ value=report_results[attrib]
+ )
else:
- raise ValueError("Error gathering evidence from "\
- "surefire report, expected attribute " + attrib +" "\
- "not found in report " + test_results_dir)
-
- except sh.ErrorReturnCode:
- step_result.message = "User acceptance test failures. See 'maven-output'" \
- ", 'surefire-reports', 'cucumber-report-html', and 'cucumber-report-json'" \
- " report artifacts for details."
+ not_found_attribs.append(attrib)
+
+ if not_found_attribs:
+ #NOTE: not sure if this should be a failure or just a warning...
+ raise ValueError(
+ "Error gathering evidence from "\
+ f"surefire report, expected attribute(s) ({not_found_attribs}) "\
+ f"not found in report ({test_results_dir})"
+ )
+
+ except StepRunnerException as error:
step_result.success = False
+ step_result.message = "Error running 'maven test' to run user acceptance tests. " \
+ "More details maybe found in 'maven-output', `surefire-reports`, " \
+ "`cucumber-report-html`, and `cucumber-report-json` " \
+ f"report artifact: {error}"
except ValueError as error:
step_result.message = str(error)
step_result.success = False
-
- step_result.add_artifact(
- description=f"Standard out and standard error by 'mvn -P{uat_maven_profile} test'.",
- name='maven-output',
- value=mvn_output_file_path
- )
- step_result.add_artifact(
- description=f"Surefire reports generated by 'mvn -P{uat_maven_profile} test'.",
- name='surefire-reports',
- value=test_results_dir
- )
- step_result.add_artifact(
- description=f"Cucumber (HTML) report generated by 'mvn -P{uat_maven_profile} test'.",
- name='cucumber-report-html',
- value=cucumber_html_report_path
- )
- step_result.add_artifact(
- description=f"Cucumber (JSON) report generated by 'mvn -P{uat_maven_profile} test'.",
- name='cucumber-report-json',
- value=cucumber_json_report_path
- )
+ finally:
+ step_result.add_artifact(
+ description="Standard out and standard error from maven.",
+ name='maven-output',
+ value=mvn_output_file_path
+ )
+ step_result.add_artifact(
+ description="Surefire reports generated by maven.",
+ name='surefire-reports',
+ value=test_results_dir
+ )
+ step_result.add_artifact(
+ description="Cucumber (HTML) report generated by maven.",
+ name='cucumber-report-html',
+ value=cucumber_html_report_path
+ )
+ step_result.add_artifact(
+ description="Cucumber (JSON) report generated by maven.",
+ name='cucumber-report-json',
+ value=cucumber_json_report_path
+ )
return step_result
diff --git a/src/ploigos_step_runner/step_implementers/unit_test/maven.py b/src/ploigos_step_runner/step_implementers/unit_test/maven.py
index c829abee..f5f5879b 100644
--- a/src/ploigos_step_runner/step_implementers/unit_test/maven.py
+++ b/src/ploigos_step_runner/step_implementers/unit_test/maven.py
@@ -8,13 +8,24 @@
* runtime configuration
* previous step results
-Configuration Key | Required? | Default | Description
--------------------|-----------|-------------|-----------
-`fail-on-no-tests` | True | True | Value to specify whether unit-test \
- step can succeed when no tests are defined
-`pom-file` | True | `'pom.xml'` | pom used to run tests and check \
- for existence of custom reportsDirectory
-`tls-verify` | No | True | Disables TLS Verification if set to False
+Configuration Key | Required? | Default | Description
+-----------------------------|-----------|---------|-----------
+`pom-file` | Yes | `'pom.xml'` | pom used when executing maven.
+`tls-verify` | No | `True` | Disables TLS Verification if set to False
+`maven-profiles` | No | `[]` | List of maven profiles to use.
+`maven-no-transfer-progress` | No | `True` | \
+ `True` to suppress the transfer progress of packages maven downloads.
+ `False` to have the transfer progress printed.\
+ See https://maven.apache.org/ref/current/maven-embedder/cli.html
+`maven-additional-arguments` | No | `[]` | List of additional arguments to use.
+`maven-servers` | No | | Dictionary of dictionaries of \
+ id, username, password
+`maven-repositories` | No | | Dictionary of dictionaries of \
+ id, url, snapshots, releases
+`maven-mirrors` | No | | Dictionary of dictionaries of \
+ id, url, mirror_of
+`fail-on-no-tests` | Yes | `True ` | `True` to fail if there are not tests to run. \
+ `False` to ignore if there are no tests to run.
Result Artifacts
----------------
@@ -26,28 +37,37 @@
`surefile-reports` | Path to Surefire reports generated from invoking Maven.
"""
import os
-import sys
-import sh
-from ploigos_step_runner import StepResult
-from ploigos_step_runner.step_implementers.shared.maven_generic import MavenGeneric
-from ploigos_step_runner.utils.io import create_sh_redirect_to_multiple_streams_fn_callback
+from ploigos_step_runner import StepResult, StepRunnerException
+from ploigos_step_runner.step_implementers.shared.maven_generic import \
+ MavenGeneric
DEFAULT_CONFIG = {
- 'tls-verify': True,
- 'fail-on-no-tests': True,
- 'pom-file': 'pom.xml'
+ 'fail-on-no-tests': True
}
REQUIRED_CONFIG_OR_PREVIOUS_STEP_RESULT_ARTIFACT_KEYS = [
- 'fail-on-no-tests',
- 'pom-file'
+ 'pom-file',
+ 'fail-on-no-tests'
]
-
class Maven(MavenGeneric):
"""`StepImplementer` for the `unit-test` step using Maven with Surefire plugin.
"""
+ def __init__( # pylint: disable=too-many-arguments
+ self,
+ workflow_result,
+ parent_work_dir_path,
+ config,
+ environment=None
+ ):
+ super().__init__(
+ workflow_result=workflow_result,
+ parent_work_dir_path=parent_work_dir_path,
+ config=config,
+ environment=environment,
+ maven_phases_and_goals=['test']
+ )
@staticmethod
def step_implementer_config_defaults():
@@ -61,9 +81,8 @@ def step_implementer_config_defaults():
Notes
-----
These are the lowest precedence configuration values.
-
"""
- return DEFAULT_CONFIG
+ return {**MavenGeneric.step_implementer_config_defaults(), **DEFAULT_CONFIG}
@staticmethod
def _required_config_or_result_keys():
@@ -92,11 +111,11 @@ def _run_step(self):
"""
step_result = StepResult.from_step_implementer(self)
- tls_verify = self.get_value('tls-verify')
pom_file = self.get_value('pom-file')
fail_on_no_tests = self.get_value('fail-on-no-tests')
# ensure surefire plugin enabled
+ # NOTE: should this really be hard requirement?
maven_surefire_plugin = self._get_effective_pom_element(
element_path=MavenGeneric.SUREFIRE_PLUGIN_XML_ELEMENT_PATH
)
@@ -111,62 +130,47 @@ def _run_step(self):
element_path=MavenGeneric.SUREFIRE_PLUGIN_REPORTS_DIR_XML_ELEMENT_PATH
)
if reports_dir is not None:
- test_results_dir = reports_dir.text
+ if os.path.isabs(reports_dir.text):
+ test_results_dir = reports_dir.text
+ else:
+ test_results_dir = os.path.join(
+ os.path.dirname(os.path.abspath(pom_file)),
+ reports_dir.text
+ )
else:
test_results_dir = os.path.join(
os.path.dirname(os.path.abspath(pom_file)),
MavenGeneric.DEFAULT_SUREFIRE_PLUGIN_REPORTS_DIR
)
- mvn_additional_options = []
- if not tls_verify:
- mvn_additional_options += [
- '-Dmaven.wagon.http.ssl.insecure=true',
- '-Dmaven.wagon.http.ssl.allowall=true',
- '-Dmaven.wagon.http.ssl.ignore.validity.dates=true',
- ]
-
- settings_file = self._generate_maven_settings()
- mvn_output_file_path = self.write_working_file('mvn_test_output.txt')
+ # run the tests
+ mvn_output_file_path = self.write_working_file('mvn_output.txt')
try:
- with open(mvn_output_file_path, 'w') as mvn_output_file:
- out_callback = create_sh_redirect_to_multiple_streams_fn_callback([
- sys.stdout,
- mvn_output_file
- ])
- err_callback = create_sh_redirect_to_multiple_streams_fn_callback([
- sys.stderr,
- mvn_output_file
- ])
-
- sh.mvn( # pylint: disable=no-member
- 'clean',
- 'test',
- '-f', pom_file,
- '-s', settings_file,
- *mvn_additional_options,
- _out=out_callback,
- _err=err_callback
- )
+ # execute maven step (params come from config)
+ self._run_maven_step(
+ mvn_output_file_path=mvn_output_file_path
+ )
+ # check if any tests were run
if not os.path.isdir(test_results_dir) or len(os.listdir(test_results_dir)) == 0:
if fail_on_no_tests:
step_result.message = 'No unit tests defined.'
step_result.success = False
else:
step_result.message = "No unit tests defined, but 'fail-on-no-tests' is False."
- except sh.ErrorReturnCode as error:
- step_result.message = "Unit test failures. See 'maven-output'" \
- f" and 'surefire-reports' report artifacts for details: {error}"
+ except StepRunnerException as error:
step_result.success = False
+ step_result.message = "Error running 'maven test' to run unit tests. " \
+ "More details maybe found in 'maven-output' and `surefire-reports` " \
+ f"report artifact: {error}"
finally:
step_result.add_artifact(
- description="Standard out and standard error from 'mvn test'.",
+ description="Standard out and standard error from maven.",
name='maven-output',
value=mvn_output_file_path
)
step_result.add_artifact(
- description="Surefire reports generated from 'mvn test'.",
+ description="Surefire reports generated by maven.",
name='surefire-reports',
value=test_results_dir
)
diff --git a/src/ploigos_step_runner/utils/maven.py b/src/ploigos_step_runner/utils/maven.py
index 490c338d..390e776b 100644
--- a/src/ploigos_step_runner/utils/maven.py
+++ b/src/ploigos_step_runner/utils/maven.py
@@ -1,11 +1,13 @@
"""Shared utils for maven operations.
"""
-
import os
+import sys
import xml.etree.ElementTree as ET
import sh
from ploigos_step_runner.exceptions import StepRunnerException
+from ploigos_step_runner.utils.io import \
+ create_sh_redirect_to_multiple_streams_fn_callback
def generate_maven_settings(working_dir, maven_servers, maven_repositories, maven_mirrors):
@@ -442,3 +444,95 @@ def write_effective_pom(
) from error
return output_path
+
+def run_maven( #pylint: disable=too-many-arguments
+ mvn_output_file_path,
+ settings_file,
+ pom_file,
+ phases_and_goals,
+ tls_verify=True,
+ additional_arguments=None,
+ profiles=None,
+ no_transfer_progress=True
+):
+ """Runs maven using the given configuration.
+
+ Parameters
+ ----------
+ mvn_output_file_path : str
+ Path to file containing the maven stdout and stderr output.
+ phases_and_goals : [str]
+ List of maven phases and/or goals to execute.
+ additional_arguments : [str]
+ List of additional arguments to use.
+ pom_file : str (path)
+ pom used when executing maven.
+ tls_verify : boolean
+ Disables TLS Verification if set to False
+ profiles : [str]
+ List of maven profiles to use.
+ no_transfer_progress : boolean
+ `True` to suppress the transfer progress of packages maven downloads.
+ `False` to have the transfer progress printed.\
+ See https://maven.apache.org/ref/current/maven-embedder/cli.html
+ settings_file : str (path)
+ Maven settings file to use.
+
+ Raises
+ ------
+ StepRunnerException
+ If maven returns a none 0 exit code.
+ """
+
+ if not isinstance(phases_and_goals, list):
+ phases_and_goals = [phases_and_goals]
+
+ # create profile argument
+ profiles_arguments = ""
+ if profiles:
+ profiles_arguments = ['-P', f"{','.join(profiles)}"]
+
+ # create no transfer progress argument
+ no_transfer_progress_argument = None
+ if no_transfer_progress:
+ no_transfer_progress_argument = '--no-transfer-progress'
+
+ # create tls arguments
+ tls_arguments = []
+ if not tls_verify:
+ tls_arguments += [
+ '-Dmaven.wagon.http.ssl.insecure=true',
+ '-Dmaven.wagon.http.ssl.allowall=true',
+ '-Dmaven.wagon.http.ssl.ignore.validity.dates=true',
+ ]
+
+ if not additional_arguments:
+ additional_arguments = []
+
+ # run maven
+ try:
+ with open(mvn_output_file_path, 'w') as mvn_output_file:
+ out_callback = create_sh_redirect_to_multiple_streams_fn_callback([
+ sys.stdout,
+ mvn_output_file
+ ])
+ err_callback = create_sh_redirect_to_multiple_streams_fn_callback([
+ sys.stderr,
+ mvn_output_file
+ ])
+
+ sh.mvn( # pylint: disable=no-member
+ *phases_and_goals,
+ '-f', pom_file,
+ '-s', settings_file,
+ *profiles_arguments,
+ no_transfer_progress_argument,
+ *tls_arguments,
+ *additional_arguments,
+ _out=out_callback,
+ _err=err_callback
+ )
+ except sh.ErrorReturnCode as error:
+ raise StepRunnerException(
+ f"Error running maven. {error}"
+ ) from error
diff --git a/tests/config/test_config_value.py b/tests/config/test_config_value.py
index 93cc6551..ee819b3e 100644
--- a/tests/config/test_config_value.py
+++ b/tests/config/test_config_value.py
@@ -1,8 +1,6 @@
from io import StringIO
import os.path
-import unittest
-from testfixtures import TempDirectory
from unittest.mock import patch
from tests.helpers.base_test_case import BaseTestCase
diff --git a/tests/helpers/maven_step_implementer_test_case.py b/tests/helpers/maven_step_implementer_test_case.py
deleted file mode 100644
index 97b8e3a5..00000000
--- a/tests/helpers/maven_step_implementer_test_case.py
+++ /dev/null
@@ -1,58 +0,0 @@
-import os
-from pathlib import Path
-
-import sh
-from tests.helpers.base_step_implementer_test_case import \
- BaseStepImplementerTestCase
-
-
-class MaveStepImplementerTestCase(BaseStepImplementerTestCase):
- @staticmethod
- def create_mvn_side_effect(
- pom_file,
- artifact_parent_dir,
- artifact_names,
- raise_error_on_tests=False
- ):
- """simulates what mvn does by touching files.
-
- Notes
- -----
- Supports
- - mvn clean
- - mvn install
- - mvn test
- """
- target_dir_path = os.path.join(
- os.path.dirname(os.path.abspath(pom_file)),
- artifact_parent_dir)
-
- def mvn_side_effect(*args, **kwargs):
- if 'clean' in args:
- if os.path.exists(target_dir_path):
- os.rmdir(target_dir_path)
-
- if 'install' in args:
- os.mkdir(target_dir_path)
-
- for artifact_name in artifact_names:
- artifact_path = os.path.join(
- target_dir_path,
- artifact_name
- )
- Path(artifact_path).touch()
-
- if 'test' in args:
- if raise_error_on_tests:
- raise sh.ErrorReturnCode('mvn', b'mock out', b'mock error')
-
- os.makedirs(target_dir_path, exist_ok=True)
-
- for artifact_name in artifact_names:
- artifact_path = os.path.join(
- target_dir_path,
- artifact_name
- )
- Path(artifact_path).touch()
-
- return mvn_side_effect
diff --git a/tests/step_implementers/package/test_maven_package.py b/tests/step_implementers/package/test_maven_package.py
index 73ebea2a..02058a9d 100644
--- a/tests/step_implementers/package/test_maven_package.py
+++ b/tests/step_implementers/package/test_maven_package.py
@@ -1,432 +1,287 @@
-# pylint: disable=missing-module-docstring
-# pylint: disable=missing-class-docstring
-# pylint: disable=missing-function-docstring
import os
-import re
from pathlib import Path
from unittest.mock import patch
-import sh
-from ploigos_step_runner import StepResult
+from ploigos_step_runner import StepResult, StepRunnerException, WorkflowResult
from ploigos_step_runner.step_implementers.package import Maven
from testfixtures import TempDirectory
from tests.helpers.base_step_implementer_test_case import \
BaseStepImplementerTestCase
-class TestStepImplementerMavenPackageBase(BaseStepImplementerTestCase):
+@patch("ploigos_step_runner.step_implementers.shared.MavenGeneric.__init__")
+class TestStepImplementerMavenPackage___init__(BaseStepImplementerTestCase):
+ def test_defaults(self, mock_super_init):
+ workflow_result = WorkflowResult()
+ parent_work_dir_path = '/fake/path'
+ config = {}
+
+ Maven(
+ workflow_result=workflow_result,
+ parent_work_dir_path=parent_work_dir_path,
+ config=config
+ )
+
+ mock_super_init.assert_called_once_with(
+ workflow_result=workflow_result,
+ parent_work_dir_path=parent_work_dir_path,
+ config=config,
+ environment=None,
+ maven_phases_and_goals=['package']
+ )
+
+ def test_given_environment(self, mock_super_init):
+ workflow_result = WorkflowResult()
+ parent_work_dir_path = '/fake/path'
+ config = {}
+
+ Maven(
+ workflow_result=workflow_result,
+ parent_work_dir_path=parent_work_dir_path,
+ config=config,
+ environment='mock-env'
+ )
+
+ mock_super_init.assert_called_once_with(
+ workflow_result=workflow_result,
+ parent_work_dir_path=parent_work_dir_path,
+ config=config,
+ environment='mock-env',
+ maven_phases_and_goals=['package']
+ )
+
+class TestStepImplementerMavenPackage_step_implementer_config_defaults(
+ BaseStepImplementerTestCase
+):
+ def test_result(self):
+ self.assertEqual(
+ Maven.step_implementer_config_defaults(),
+ {
+ 'pom-file': 'pom.xml',
+ 'tls-verify': True,
+ 'maven-profiles': [],
+ 'maven-additional-arguments': [],
+ 'maven-no-transfer-progress': True,
+ 'maven-additional-arguments': [
+ '-Dmaven.test.skip=true'
+ ],
+ 'artifact-extensions': ["jar", "war", "ear"],
+ 'artifact-parent-dir': 'target'
+ }
+ )
+
+class TestStepImplementerMavenPackage__required_config_or_result_keys(
+ BaseStepImplementerTestCase
+):
+ def test_result(self):
+ self.assertEqual(
+ Maven._required_config_or_result_keys(),
+ [
+ 'pom-file'
+ ]
+ )
+
+@patch.object(Maven, '_run_maven_step')
+@patch.object(Maven, 'write_working_file', return_value='/mock/mvn_output.txt')
+class TestStepImplementerMavenPackage__run_step(
+ BaseStepImplementerTestCase
+):
def create_step_implementer(
self,
step_config={},
- step_name='',
- implementer='',
workflow_result=None,
parent_work_dir_path=''
):
return self.create_given_step_implementer(
step_implementer=Maven,
step_config=step_config,
- step_name=step_name,
- implementer=implementer,
+ step_name='package',
+ implementer='Maven',
workflow_result=workflow_result,
parent_work_dir_path=parent_work_dir_path
)
- # TESTS FOR configuration checks
- def test_step_implementer_config_defaults(self):
- defaults = Maven.step_implementer_config_defaults()
- expected_defaults = {
- 'tls-verify': True,
- 'pom-file': 'pom.xml',
- 'artifact-extensions': ["jar", "war", "ear"],
- 'artifact-parent-dir': 'target'
- }
- self.assertEqual(defaults, expected_defaults)
-
- def test__required_config_or_result_keys(self):
- required_keys = Maven._required_config_or_result_keys()
- expected_required_keys = [
- 'pom-file'
- ]
- self.assertEqual(required_keys, expected_required_keys)
-
- def create_mvn_side_effect(pom_file, artifact_parent_dir, artifact_names):
- """simulates what mvn does by touching files.
- Notes
- -----
- Supports
- - mvn clean
- - mvn install
- """
- target_dir_path = os.path.join(
- os.path.dirname(os.path.abspath(pom_file)),
- artifact_parent_dir)
-
- def mvn_side_effect(*args, **kwargs):
- if 'clean' in args:
- if os.path.exists(target_dir_path):
- os.rmdir(target_dir_path)
-
- if 'install' in args:
- os.mkdir(target_dir_path)
-
- for artifact_name in artifact_names:
- artifact_path = os.path.join(
- target_dir_path,
- artifact_name
- )
- Path(artifact_path).touch()
-
- return mvn_side_effect
-
- @patch('sh.mvn', create=True)
- def test_run_step_pass(self, mvn_mock):
- with TempDirectory() as temp_dir:
- artifact_id = 'my-app'
- version = '1.0'
- package = 'war'
- parent_work_dir_path = os.path.join(temp_dir.path, 'working')
- temp_dir.write('pom.xml', b'''
- 4.0.0
- com.mycompany.app
- my-app
- 1.0
- war
- ''')
- pom_file_path = os.path.join(temp_dir.path, 'pom.xml')
-
- step_config = {'pom-file': pom_file_path}
-
- artifact_file_name = f'{artifact_id}-{version}.{package}'
+ def test_success_single_packaged_artifact(
+ self,
+ mock_write_working_file,
+ mock_run_maven_step
+ ):
+ with TempDirectory() as test_dir:
+ parent_work_dir_path = os.path.join(test_dir.path, 'working')
+ pom_file = os.path.join(test_dir.path, 'mock-pom.xml')
+ step_config = {
+ 'pom-file': pom_file
+ }
step_implementer = self.create_step_implementer(
step_config=step_config,
- step_name='package',
- implementer='Maven',
parent_work_dir_path=parent_work_dir_path,
)
- mvn_mock.side_effect = TestStepImplementerMavenPackageBase.create_mvn_side_effect(
- pom_file_path,
- 'target',
- [artifact_file_name])
+ # setup sideeffects
+ artifact_parent_dir = os.path.join(test_dir.path, 'target')
+ package_artifact_names = [
+ f'my-app.jar'
+ ]
+ def run_maven_side_effect(mvn_output_file_path):
+ os.makedirs(artifact_parent_dir, exist_ok=True)
+ for artifact_name in package_artifact_names:
+ artifact_path = os.path.join(
+ artifact_parent_dir,
+ artifact_name
+ )
+ Path(artifact_path).touch()
- result = step_implementer._run_step()
+ mock_run_maven_step.side_effect = run_maven_side_effect
- package_artifacts = {
- 'path': temp_dir.path + '/target/my-app-1.0.war',
- 'artifact-id': 'my-app',
- 'group-id': 'com.mycompany.app',
- 'package-type': 'war',
- 'pom-path': pom_file_path
- }
+ # run step
+ actual_step_result = step_implementer._run_step()
+
+ # create expected step result
expected_step_result = StepResult(
step_name='package',
sub_step_name='Maven',
sub_step_implementer_name='Maven'
)
- expected_step_result.add_artifact(name='package-artifacts', value=[package_artifacts])
- mvn_output_file_path = os.path.join(
- step_implementer.work_dir_path,
- 'mvn_test_output.txt'
- )
expected_step_result.add_artifact(
- description="Standard out and standard error from 'mvn install'.",
+ description="Standard out and standard error from maven.",
name='maven-output',
- value=mvn_output_file_path
- )
-
- self.assertEqual(expected_step_result, result)
-
- @patch('sh.mvn', create=True)
- def test_run_step_pass_no_package_in_pom(self, mvn_mock):
- with TempDirectory() as temp_dir:
- artifact_id = 'my-app'
- version = '1.0'
- package = 'jar'
- parent_work_dir_path = os.path.join(temp_dir.path, 'working')
- temp_dir.write('pom.xml',b'''
- 4.0.0
- com.mycompany.app
- my-app
- 1.0
- ''')
- pom_file_path = os.path.join(temp_dir.path, 'pom.xml')
-
- step_config = {'pom-file': pom_file_path}
-
- artifact_file_name = f'{artifact_id}-{version}.{package}'
-
- step_implementer = self.create_step_implementer(
- step_config=step_config,
- step_name='package',
- implementer='Maven',
- parent_work_dir_path=parent_work_dir_path,
- )
-
- mvn_mock.side_effect = TestStepImplementerMavenPackageBase.create_mvn_side_effect(
- pom_file_path,
- 'target',
- [artifact_file_name])
-
- result = step_implementer._run_step()
-
- package_artifacts = {
- 'path': temp_dir.path + '/target/my-app-1.0.jar',
- 'artifact-id': 'my-app',
- 'group-id': 'com.mycompany.app',
- 'package-type': 'jar',
- 'pom-path': pom_file_path
- }
- expected_step_result = StepResult(step_name='package', sub_step_name='Maven', sub_step_implementer_name='Maven')
- expected_step_result.add_artifact(name='package-artifacts', value=[package_artifacts])
- mvn_output_file_path = os.path.join(
- step_implementer.work_dir_path,
- 'mvn_test_output.txt'
+ value='/mock/mvn_output.txt'
)
expected_step_result.add_artifact(
- description="Standard out and standard error from 'mvn install'.",
- name='maven-output',
- value=mvn_output_file_path
+ name='packages',
+ value=[{
+ 'path': os.path.join(artifact_parent_dir, 'my-app.jar')
+ }]
)
- self.assertEqual(result, expected_step_result)
-
-
- @patch('sh.mvn', create=True)
- def test_run_step_fail_no_pom(self, mvn_mock):
- with TempDirectory() as temp_dir:
- parent_work_dir_path = os.path.join(temp_dir.path, 'working')
-
- step_config = {}
-
- step_implementer = self.create_step_implementer(
- step_config=step_config,
- step_name='package',
- implementer='Maven',
- parent_work_dir_path=parent_work_dir_path,
+ # verify step result
+ self.assertEqual(
+ actual_step_result,
+ expected_step_result
)
- result = step_implementer._run_step()
-
- expected_step_result = StepResult(step_name='package', sub_step_name='Maven', sub_step_implementer_name='Maven')
- expected_step_result.success = False
- expected_step_result.message = 'Given pom file does not exist: pom.xml'
-
- self.assertEqual(result, expected_step_result)
-
- @patch('sh.mvn', create=True)
- def test_run_step_fail_mvn_error(self, mvn_mock):
- with TempDirectory() as temp_dir:
- parent_work_dir_path = os.path.join(temp_dir.path, 'working')
- temp_dir.write('pom.xml',b'''
- 4.0.0
- com.mycompany.app
- my-app
- 1.0
- ''')
- pom_file_path = os.path.join(temp_dir.path, 'pom.xml')
+ mock_write_working_file.assert_called_once()
+ mock_run_maven_step.assert_called_with(
+ mvn_output_file_path='/mock/mvn_output.txt'
+ )
- step_config = {'pom-file': pom_file_path}
+ def test_success_multiple_packaged_artifact(
+ self,
+ mock_write_working_file,
+ mock_run_maven_step
+ ):
+ with TempDirectory() as test_dir:
+ parent_work_dir_path = os.path.join(test_dir.path, 'working')
+ pom_file = os.path.join(test_dir.path, 'mock-pom.xml')
+ step_config = {
+ 'pom-file': pom_file
+ }
step_implementer = self.create_step_implementer(
step_config=step_config,
- step_name='package',
- implementer='Maven',
parent_work_dir_path=parent_work_dir_path,
)
- mvn_mock.side_effect = sh.ErrorReturnCode('mvn', b'mock out', b'mock error')
+ # setup sideeffects
+ artifact_parent_dir = os.path.join(test_dir.path, 'target')
+ package_artifact_names = [
+ f'my-app.jar',
+ f'my-app.war'
+ ]
+ def run_maven_side_effect(mvn_output_file_path):
+ os.makedirs(artifact_parent_dir, exist_ok=True)
+ for artifact_name in package_artifact_names:
+ artifact_path = os.path.join(
+ artifact_parent_dir,
+ artifact_name
+ )
+ Path(artifact_path).touch()
+ mock_run_maven_step.side_effect = run_maven_side_effect
- result = step_implementer._run_step()
+ # run step
+ actual_step_result = step_implementer._run_step()
+ # create expected step result
expected_step_result = StepResult(
step_name='package',
sub_step_name='Maven',
sub_step_implementer_name='Maven'
)
- mvn_output_file_path = os.path.join(
- step_implementer.work_dir_path,
- 'mvn_test_output.txt'
- )
expected_step_result.add_artifact(
- description="Standard out and standard error from 'mvn install'.",
+ description="Standard out and standard error from maven.",
name='maven-output',
- value=mvn_output_file_path
- )
- expected_step_result.success = False
-
- self.assertEqual(result.success, expected_step_result.success)
- self.assertRegex(result.message, re.compile(
- r"Package failures. See 'maven-output' report artifacts for details:"
- r".*RAN: mvn"
- r".*STDOUT:"
- r".*mock out"
- r".*STDERR:"
- r".*mock error",
- re.DOTALL
- ))
- self.assertEqual(result.artifacts, expected_step_result.artifacts)
-
- @patch('sh.mvn', create=True)
- def test_run_step_fail_multiple_artifacts(self, mvn_mock):
- with TempDirectory() as temp_dir:
- artifact_id = 'my-app'
- version = '1.0'
- package = 'jar'
- parent_work_dir_path = os.path.join(temp_dir.path, 'working')
- temp_dir.write('pom.xml',b'''
- 4.0.0
- com.mycompany.app
- my-app
- 1.0
- ''')
- pom_file_path = os.path.join(temp_dir.path, 'pom.xml')
-
- step_config = {'pom-file': pom_file_path}
-
- artifact_file_name = f'{artifact_id}-{version}.{package}'
-
- step_implementer = self.create_step_implementer(
- step_config=step_config,
- step_name='package',
- implementer='Maven',
- parent_work_dir_path=parent_work_dir_path,
- )
-
- mvn_mock.side_effect = TestStepImplementerMavenPackageBase.create_mvn_side_effect(
- pom_file_path,
- 'target',
- [
- f'{artifact_id}-{version}.war',
- artifact_file_name
- ]
- )
-
- result = step_implementer._run_step()
-
- expected_step_result = StepResult(step_name='package', sub_step_name='Maven', sub_step_implementer_name='Maven')
- expected_step_result.success = False
- expected_step_result.message = "pom resulted in multiple artifacts with expected artifact extensions (['jar', 'war', 'ear']), this is unsupported"
- mvn_output_file_path = os.path.join(
- step_implementer.work_dir_path,
- 'mvn_test_output.txt'
+ value='/mock/mvn_output.txt'
)
expected_step_result.add_artifact(
- description="Standard out and standard error from 'mvn install'.",
- name='maven-output',
- value=mvn_output_file_path
+ name='packages',
+ value=[
+ {
+ 'path': os.path.join(artifact_parent_dir, 'my-app.jar')
+ },
+ {
+ 'path': os.path.join(artifact_parent_dir, 'my-app.war')
+ }
+ ]
)
- self.assertEqual(result, expected_step_result)
-
- @patch('sh.mvn', create=True)
- def test_run_step_fail_no_artifacts(self, mvn_mock):
- with TempDirectory() as temp_dir:
- artifact_id = ''
- version = ''
- package = ''
- parent_work_dir_path = os.path.join(temp_dir.path, 'working')
- temp_dir.write('pom.xml',b'''
- 4.0.0
- com.mycompany.app
- my-app
- 1.0
- ''')
- pom_file_path = os.path.join(temp_dir.path, 'pom.xml')
-
- step_config = {'pom-file': pom_file_path}
-
- artifact_file_name = f'{artifact_id}-{version}.{package}'
- step_implementer = self.create_step_implementer(
- step_config=step_config,
- step_name='package',
- implementer='Maven',
- parent_work_dir_path=parent_work_dir_path,
+ # verify step result
+ self.assertEqual(
+ actual_step_result,
+ expected_step_result
)
- mvn_mock.side_effect = TestStepImplementerMavenPackageBase.create_mvn_side_effect(
- pom_file_path,
- 'target',
- [artifact_file_name]
+ mock_write_working_file.assert_called_once()
+ mock_run_maven_step.assert_called_with(
+ mvn_output_file_path='/mock/mvn_output.txt'
)
- result = step_implementer._run_step()
-
- expected_step_result = StepResult(step_name='package', sub_step_name='Maven', sub_step_implementer_name='Maven')
- expected_step_result.success = False
- expected_step_result.message = "pom resulted in 0 with expected artifact extensions (['jar', 'war', 'ear']), this is unsupported"
- mvn_output_file_path = os.path.join(
- step_implementer.work_dir_path,
- 'mvn_test_output.txt'
- )
- expected_step_result.add_artifact(
- description="Standard out and standard error from 'mvn install'.",
- name='maven-output',
- value=mvn_output_file_path
- )
-
- self.assertEqual(result, expected_step_result)
-
- @patch('sh.mvn', create=True)
- def test_run_step_tls_verify_false(self, mvn_mock):
- with TempDirectory() as temp_dir:
- artifact_id = 'my-app'
- version = '1.0'
- package = 'war'
- parent_work_dir_path = os.path.join(temp_dir.path, 'working')
- temp_dir.write('pom.xml', b'''
- 4.0.0
- com.mycompany.app
- my-app
- 1.0
- war
- ''')
- pom_file_path = os.path.join(temp_dir.path, 'pom.xml')
+ def test_fail_maven_run(
+ self,
+ mock_write_working_file,
+ mock_run_maven_step
+ ):
+ with TempDirectory() as test_dir:
+ parent_work_dir_path = os.path.join(test_dir.path, 'working')
+ pom_file = os.path.join(test_dir.path, 'mock-pom.xml')
step_config = {
- 'pom-file': pom_file_path,
- 'tls-verify': False
+ 'pom-file': pom_file
}
-
- artifact_file_name = f'{artifact_id}-{version}.{package}'
-
step_implementer = self.create_step_implementer(
step_config=step_config,
- step_name='package',
- implementer='Maven',
parent_work_dir_path=parent_work_dir_path,
)
- mvn_mock.side_effect = TestStepImplementerMavenPackageBase.create_mvn_side_effect(
- pom_file_path,
- 'target',
- [artifact_file_name])
+ # run step with mock failure
+ mock_run_maven_step.side_effect = StepRunnerException('Mock error running maven')
+ actual_step_result = step_implementer._run_step()
- result = step_implementer._run_step()
-
- package_artifacts = {
- 'path': temp_dir.path + '/target/my-app-1.0.war',
- 'artifact-id': 'my-app',
- 'group-id': 'com.mycompany.app',
- 'package-type': 'war',
- 'pom-path': pom_file_path
- }
+ # create expected step result
+ surefire_reports_dir = os.path.join(test_dir.path, 'target/surefire-reports')
expected_step_result = StepResult(
step_name='package',
sub_step_name='Maven',
sub_step_implementer_name='Maven'
)
- expected_step_result.add_artifact(name='package-artifacts', value=[package_artifacts])
- mvn_output_file_path = os.path.join(
- step_implementer.work_dir_path,
- 'mvn_test_output.txt'
- )
+ expected_step_result.success = False
+ expected_step_result.message = "Error running 'maven package' to package artifacts. " \
+ "More details maybe found in 'maven-output' report artifact: " \
+ "Mock error running maven"
expected_step_result.add_artifact(
- description="Standard out and standard error from 'mvn install'.",
+ description="Standard out and standard error from maven.",
name='maven-output',
- value=mvn_output_file_path
+ value='/mock/mvn_output.txt'
)
- self.assertEqual(expected_step_result, result)
+ # verify step result
+ self.assertEqual(
+ actual_step_result,
+ expected_step_result
+ )
+
+ mock_write_working_file.assert_called_once()
+ mock_run_maven_step.assert_called_with(
+ mvn_output_file_path='/mock/mvn_output.txt'
+ )
diff --git a/tests/step_implementers/push_artifacts/test_maven_push_artifacts.py b/tests/step_implementers/push_artifacts/test_maven_push_artifacts.py
index 3768d03e..54fe1896 100644
--- a/tests/step_implementers/push_artifacts/test_maven_push_artifacts.py
+++ b/tests/step_implementers/push_artifacts/test_maven_push_artifacts.py
@@ -1,235 +1,329 @@
-# pylint: disable=missing-module-docstring
-# pylint: disable=missing-class-docstring
-# pylint: disable=missing-function-docstring
+
import os
-import re
-from unittest.mock import patch
+from unittest.mock import PropertyMock, patch
-import sh
+from ploigos_step_runner import StepResult, WorkflowResult, StepRunnerException
+from ploigos_step_runner.step_implementers.push_artifacts import Maven
from testfixtures import TempDirectory
from tests.helpers.base_step_implementer_test_case import \
BaseStepImplementerTestCase
-from ploigos_step_runner import StepResult
-from ploigos_step_runner.step_implementers.push_artifacts import Maven
-class TestStepImplementerMavenPushArtifacts(BaseStepImplementerTestCase):
+@patch("ploigos_step_runner.step_implementers.shared.MavenGeneric.__init__")
+class TestStepImplementerMavenDeploy___init__(BaseStepImplementerTestCase):
+ def test_defaults(self, mock_super_init):
+ workflow_result = WorkflowResult()
+ parent_work_dir_path = '/fake/path'
+ config = {}
+
+ Maven(
+ workflow_result=workflow_result,
+ parent_work_dir_path=parent_work_dir_path,
+ config=config
+ )
+
+ mock_super_init.assert_called_once_with(
+ workflow_result=workflow_result,
+ parent_work_dir_path=parent_work_dir_path,
+ config=config,
+ environment=None,
+ maven_phases_and_goals=['deploy']
+ )
+
+ def test_given_environment(self, mock_super_init):
+ workflow_result = WorkflowResult()
+ parent_work_dir_path = '/fake/path'
+ config = {}
+
+ Maven(
+ workflow_result=workflow_result,
+ parent_work_dir_path=parent_work_dir_path,
+ config=config,
+ environment='mock-env'
+ )
+
+ mock_super_init.assert_called_once_with(
+ workflow_result=workflow_result,
+ parent_work_dir_path=parent_work_dir_path,
+ config=config,
+ environment='mock-env',
+ maven_phases_and_goals=['deploy']
+ )
+
+class TestStepImplementerMavenDeploy_step_implementer_config_defaults(
+ BaseStepImplementerTestCase
+):
+ def test_result(self):
+ self.assertEqual(
+ Maven.step_implementer_config_defaults(),
+ {
+ 'pom-file': 'pom.xml',
+ 'tls-verify': True,
+ 'maven-profiles': [],
+ 'maven-additional-arguments': [],
+ 'maven-no-transfer-progress': True,
+ 'maven-additional-arguments': [
+ '-Dmaven.install.skip=true',
+ '-Dmaven.test.skip=true'
+ ]
+ }
+ )
+
+class TestStepImplementerMavenDeploy__required_config_or_result_keys(
+ BaseStepImplementerTestCase
+):
+ def test_result(self):
+ self.assertEqual(
+ Maven._required_config_or_result_keys(),
+ [
+ 'pom-file',
+ 'maven-push-artifact-repo-url',
+ 'maven-push-artifact-repo-id',
+ 'version'
+ ]
+ )
+
+@patch('ploigos_step_runner.step_implementers.push_artifacts.maven.run_maven')
+@patch.object(Maven, '_run_maven_step')
+@patch.object(
+ Maven,
+ 'write_working_file',
+ side_effect=['/mock/mvn_versions_set_output.txt', '/mock/mvn_deploy_output.txt']
+)
+@patch.object(
+ Maven,
+ 'maven_settings_file',
+ new_callable=PropertyMock,
+ return_value='/fake/settings.xml'
+)
+class TestStepImplementerMavenDeploy__run_step(
+ BaseStepImplementerTestCase
+):
def create_step_implementer(
self,
step_config={},
- step_name='',
- implementer='',
workflow_result=None,
parent_work_dir_path=''
):
return self.create_given_step_implementer(
step_implementer=Maven,
step_config=step_config,
- step_name=step_name,
- implementer=implementer,
+ step_name='deploy',
+ implementer='Maven',
workflow_result=workflow_result,
parent_work_dir_path=parent_work_dir_path
)
- def test_step_implementer_config_defaults(self):
- actual_defaults = Maven.step_implementer_config_defaults()
- expected_defaults = {
- 'tls-verify': True
- }
- self.assertEqual(expected_defaults, actual_defaults)
-
- def test__required_config_or_result_keys(self):
- actual_required_keys = Maven._required_config_or_result_keys()
- expected_required_keys = [
- 'maven-push-artifact-repo-url',
- 'maven-push-artifact-repo-id',
- 'version',
- 'package-artifacts'
- ]
- self.assertEqual(expected_required_keys, actual_required_keys)
-
- @patch('sh.mvn', create=True)
- def test_run_step_pass(self, mvn_mock):
- with TempDirectory() as temp_dir:
- parent_work_dir_path = os.path.join(temp_dir.path, 'working')
+ def test_success(
+ self,
+ mock_settings_file,
+ mock_write_working_file,
+ mock_run_maven_step,
+ mock_run_maven
+ ):
+ with TempDirectory() as test_dir:
+ parent_work_dir_path = os.path.join(test_dir.path, 'working')
+ pom_file = os.path.join(test_dir.path, 'mock-pom.xml')
+ maven_push_artifact_repo_id = 'mock-repo-id'
+ maven_push_artifact_repo_url = 'https://mock-repo.ploigos.com'
+ version = '0.42.0-mock'
step_config = {
- 'maven-push-artifact-repo-url': 'pass',
- 'maven-push-artifact-repo-id': 'pass'
- }
-
- # Previous (fake) results
- package_artifacts = [{
- 'path': 'test-path',
- 'group-id': 'test-group-id',
- 'artifact-id': 'test-artifact-id',
- 'package-type': 'test-package-type'
- }]
- artifact_config = {
- 'package-artifacts': {'value': package_artifacts},
- 'version': {'value': 'test-version'}
+ 'pom-file': pom_file,
+ 'maven-push-artifact-repo-id': maven_push_artifact_repo_id,
+ 'maven-push-artifact-repo-url': maven_push_artifact_repo_url,
+ 'version': version
}
- workflow_result = self.setup_previous_result(parent_work_dir_path, artifact_config)
-
- # Actual results
step_implementer = self.create_step_implementer(
step_config=step_config,
- step_name='push-artifacts',
- implementer='Maven',
- workflow_result=workflow_result,
- parent_work_dir_path=parent_work_dir_path
- )
- result = step_implementer._run_step()
-
- # Expected results
- push_artifacts = [{
- 'artifact-id': 'test-artifact-id',
- 'group-id': 'test-group-id',
- 'version': 'test-version',
- 'path': 'test-path',
- 'packaging': 'test-package-type',
- }]
+ parent_work_dir_path=parent_work_dir_path,
+ )
+
+ # run step
+ actual_step_result = step_implementer._run_step()
+
+ # create expected step result
expected_step_result = StepResult(
- step_name='push-artifacts',
+ step_name='deploy',
sub_step_name='Maven',
sub_step_implementer_name='Maven'
)
- expected_step_result.add_artifact(name='push-artifacts', value=push_artifacts)
- mvn_output_file_path = os.path.join(
- step_implementer.work_dir_path,
- 'mvn_test_output.txt'
+ expected_step_result.add_artifact(
+ description="Standard out and standard error from running maven to update version.",
+ name='maven-update-version-output',
+ value='/mock/mvn_versions_set_output.txt'
)
expected_step_result.add_artifact(
- description="Standard out and standard error from 'mvn install'.",
- name='maven-output',
- value=mvn_output_file_path
+ description="Standard out and standard error from running maven to " \
+ "push artifacts to repository.",
+ name='maven-push-artifacts-output',
+ value='/mock/mvn_deploy_output.txt'
)
- self.assertEqual(expected_step_result, result)
- @patch('sh.mvn', create=True)
- def test_run_step_fail(self, mvn_mock):
- with TempDirectory() as temp_dir:
- parent_work_dir_path = os.path.join(temp_dir.path, 'working')
+ # verify step result
+ self.assertEqual(
+ actual_step_result,
+ expected_step_result
+ )
- # config
- step_config = {
- 'maven-push-artifact-repo-url': 'pass',
- 'maven-push-artifact-repo-id': 'pass'
- }
+ mock_write_working_file.assert_called()
+ mock_run_maven.assert_called_with(
+ mvn_output_file_path='/mock/mvn_versions_set_output.txt',
+ settings_file='/fake/settings.xml',
+ pom_file=pom_file,
+ phases_and_goals=['versions:set'],
+ additional_arguments=[
+ f'-DnewVersion={version}'
+ ]
+ )
+ mock_run_maven_step.assert_called_with(
+ mvn_output_file_path='/mock/mvn_deploy_output.txt',
+ step_implementer_additional_arguments=[
+ '-DaltDeploymentRepository=' \
+ f'{maven_push_artifact_repo_id}::default::{maven_push_artifact_repo_url}'
+ ]
+ )
- # Previous (fake) results
- package_artifacts = [{
- 'path': 'test-path',
- 'group-id': 'test-group-id',
- 'artifact-id': 'test-artifact-id',
- 'package-type': 'test-package-type'
- }]
- artifact_config = {
- 'package-artifacts': {'value': package_artifacts},
- 'version': {'value': 'test-version'}
- }
- workflow_result = self.setup_previous_result(parent_work_dir_path, artifact_config)
+ def test_fail_set_version(
+ self,
+ mock_settings_file,
+ mock_write_working_file,
+ mock_run_maven_step,
+ mock_run_maven
+ ):
+ with TempDirectory() as test_dir:
+ parent_work_dir_path = os.path.join(test_dir.path, 'working')
- # Actual results
+ pom_file = os.path.join(test_dir.path, 'mock-pom.xml')
+ maven_push_artifact_repo_id = 'mock-repo-id'
+ maven_push_artifact_repo_url = 'https://mock-repo.ploigos.com'
+ version = '0.42.0-mock'
+ step_config = {
+ 'pom-file': pom_file,
+ 'maven-push-artifact-repo-id': maven_push_artifact_repo_id,
+ 'maven-push-artifact-repo-url': maven_push_artifact_repo_url,
+ 'version': version
+ }
step_implementer = self.create_step_implementer(
step_config=step_config,
- step_name='push-artifacts',
- implementer='Maven',
- workflow_result=workflow_result,
- parent_work_dir_path=parent_work_dir_path
+ parent_work_dir_path=parent_work_dir_path,
)
- sh.mvn.side_effect = sh.ErrorReturnCode('mvn', b'mock out', b'mock error')
- result = step_implementer._run_step()
+ # run step with mvn version:set failure
+ mock_run_maven.side_effect = StepRunnerException('mock error setting new pom version')
+ actual_step_result = step_implementer._run_step()
+ # create expected step result
expected_step_result = StepResult(
- step_name='push-artifacts',
+ step_name='deploy',
sub_step_name='Maven',
sub_step_implementer_name='Maven'
)
+ expected_step_result.success = False
+ expected_step_result.message = "Error running 'maven deploy' to push artifacts. " \
+ "More details maybe found in 'maven-output' report artifact: " \
+ "mock error setting new pom version"
expected_step_result.add_artifact(
- name='push-artifacts',
- value=[]
- )
- mvn_output_file_path = os.path.join(
- step_implementer.work_dir_path,
- 'mvn_test_output.txt'
+ description="Standard out and standard error from running maven to update version.",
+ name='maven-update-version-output',
+ value='/mock/mvn_versions_set_output.txt'
)
expected_step_result.add_artifact(
- description="Standard out and standard error from 'mvn install'.",
- name='maven-output',
- value=mvn_output_file_path
+ description="Standard out and standard error from running maven to " \
+ "push artifacts to repository.",
+ name='maven-push-artifacts-output',
+ value='/mock/mvn_deploy_output.txt'
)
- expected_step_result.success = False
- self.assertEqual(result.success, expected_step_result.success)
- self.assertRegex(result.message, re.compile(
- r"Push artifacts failures. See 'maven-output' report artifacts for details:"
- r".*RAN: mvn"
- r".*STDOUT:"
- r".*mock out"
- r".*STDERR:"
- r".*mock error",
- re.DOTALL
- ))
- self.assertEqual(result.artifacts, expected_step_result.artifacts)
-
- @patch('sh.mvn', create=True)
- def test_run_step_tls_verify_false(self, mvn_mock):
- with TempDirectory() as temp_dir:
- parent_work_dir_path = os.path.join(temp_dir.path, 'working')
+ # verify step result
+ self.assertEqual(
+ actual_step_result,
+ expected_step_result
+ )
- step_config = {
- 'maven-push-artifact-repo-url': 'pass',
- 'maven-push-artifact-repo-id': 'pass',
- 'tls-verify': False
- }
+ mock_write_working_file.assert_called()
+ mock_run_maven.assert_called_with(
+ mvn_output_file_path='/mock/mvn_versions_set_output.txt',
+ settings_file='/fake/settings.xml',
+ pom_file=pom_file,
+ phases_and_goals=['versions:set'],
+ additional_arguments=[
+ f'-DnewVersion={version}'
+ ]
+ )
+ mock_run_maven_step.assert_not_called()
- # Previous (fake) results
- package_artifacts = [{
- 'path': 'test-path',
- 'group-id': 'test-group-id',
- 'artifact-id': 'test-artifact-id',
- 'package-type': 'test-package-type'
- }]
- artifact_config = {
- 'package-artifacts': {'value': package_artifacts},
- 'version': {'value': 'test-version'}
- }
- workflow_result = self.setup_previous_result(parent_work_dir_path, artifact_config)
+ def test_fail_mvn_depoy(
+ self,
+ mock_settings_file,
+ mock_write_working_file,
+ mock_run_maven_step,
+ mock_run_maven
+ ):
+ with TempDirectory() as test_dir:
+ parent_work_dir_path = os.path.join(test_dir.path, 'working')
- # Actual results
+ pom_file = os.path.join(test_dir.path, 'mock-pom.xml')
+ maven_push_artifact_repo_id = 'mock-repo-id'
+ maven_push_artifact_repo_url = 'https://mock-repo.ploigos.com'
+ version = '0.42.0-mock'
+ step_config = {
+ 'pom-file': pom_file,
+ 'maven-push-artifact-repo-id': maven_push_artifact_repo_id,
+ 'maven-push-artifact-repo-url': maven_push_artifact_repo_url,
+ 'version': version
+ }
step_implementer = self.create_step_implementer(
step_config=step_config,
- step_name='push-artifacts',
- implementer='Maven',
- workflow_result=workflow_result,
- parent_work_dir_path=parent_work_dir_path
- )
- result = step_implementer._run_step()
-
- # Expected results
- push_artifacts = [{
- 'artifact-id': 'test-artifact-id',
- 'group-id': 'test-group-id',
- 'version': 'test-version',
- 'path': 'test-path',
- 'packaging': 'test-package-type',
- }]
+ parent_work_dir_path=parent_work_dir_path,
+ )
+
+ # run step with mvn deploy failure
+ mock_run_maven_step.side_effect = StepRunnerException('mock error running mvn deploy')
+ actual_step_result = step_implementer._run_step()
+
+ # create expected step result
expected_step_result = StepResult(
- step_name='push-artifacts',
+ step_name='deploy',
sub_step_name='Maven',
sub_step_implementer_name='Maven'
)
- expected_step_result.add_artifact(name='push-artifacts', value=push_artifacts)
- mvn_output_file_path = os.path.join(
- step_implementer.work_dir_path,
- 'mvn_test_output.txt'
+ expected_step_result.success = False
+ expected_step_result.message = "Error running 'maven deploy' to push artifacts. " \
+ "More details maybe found in 'maven-output' report artifact: " \
+ "mock error running mvn deploy"
+ expected_step_result.add_artifact(
+ description="Standard out and standard error from running maven to update version.",
+ name='maven-update-version-output',
+ value='/mock/mvn_versions_set_output.txt'
)
expected_step_result.add_artifact(
- description="Standard out and standard error from 'mvn install'.",
- name='maven-output',
- value=mvn_output_file_path
+ description="Standard out and standard error from running maven to " \
+ "push artifacts to repository.",
+ name='maven-push-artifacts-output',
+ value='/mock/mvn_deploy_output.txt'
)
- self.assertEqual(expected_step_result, result)
+ # verify step result
+ self.assertEqual(
+ actual_step_result,
+ expected_step_result
+ )
+
+ mock_write_working_file.assert_called()
+ mock_run_maven.assert_called_with(
+ mvn_output_file_path='/mock/mvn_versions_set_output.txt',
+ settings_file='/fake/settings.xml',
+ pom_file=pom_file,
+ phases_and_goals=['versions:set'],
+ additional_arguments=[
+ f'-DnewVersion={version}'
+ ]
+ )
+ mock_run_maven_step.assert_called_with(
+ mvn_output_file_path='/mock/mvn_deploy_output.txt',
+ step_implementer_additional_arguments=[
+ '-DaltDeploymentRepository=' \
+ f'{maven_push_artifact_repo_id}::default::{maven_push_artifact_repo_url}'
+ ]
+ )
diff --git a/tests/step_implementers/shared/test_maven_generic.py b/tests/step_implementers/shared/test_maven_generic.py
index 7970ad49..59e5ea3d 100644
--- a/tests/step_implementers/shared/test_maven_generic.py
+++ b/tests/step_implementers/shared/test_maven_generic.py
@@ -1,30 +1,114 @@
import os
from pathlib import Path
from shutil import copyfile
-from unittest.mock import patch
+from unittest.mock import PropertyMock, patch
+from ploigos_step_runner import StepResult, StepRunnerException, WorkflowResult
+from ploigos_step_runner.config.config import Config
+from ploigos_step_runner.step_implementers.shared.maven_generic import \
+ MavenGeneric
+from ploigos_step_runner.utils.file import create_parent_dir
from testfixtures import TempDirectory
from tests.helpers.base_step_implementer_test_case import \
BaseStepImplementerTestCase
-from ploigos_step_runner.step_implementers.shared.maven_generic import MavenGeneric
-from ploigos_step_runner import StepResult
-from ploigos_step_runner.utils.file import create_parent_dir
-class SampleMavenStepImplementer(MavenGeneric):
- @staticmethod
- def step_implementer_config_defaults():
- return {}
+@patch("ploigos_step_runner.StepImplementer.__init__")
+class TestStepImplementerSharedMavenGeneric___init__(BaseStepImplementerTestCase):
+
+ def test_no_environment_no_maven_phases_and_goals(self, mock_super_init):
+ workflow_result = WorkflowResult()
+ parent_work_dir_path = '/fake/path'
+ config = {}
+
+ step_implementer = MavenGeneric(
+ workflow_result=workflow_result,
+ parent_work_dir_path=parent_work_dir_path,
+ config=config
+ )
+
+ self.assertIsNone(step_implementer._MavenGeneric__maven_settings_file)
+ self.assertIsNone(step_implementer._MavenGeneric__maven_phases_and_goals)
+ mock_super_init.assert_called_once_with(
+ workflow_result=workflow_result,
+ parent_work_dir_path=parent_work_dir_path,
+ config=config,
+ environment=None
+ )
+
+ def test_with_environment_no_maven_phases_and_goals(self, mock_super_init):
+ workflow_result = WorkflowResult()
+ parent_work_dir_path = '/fake/path'
+ config = {}
+
+ step_implementer = MavenGeneric(
+ workflow_result=workflow_result,
+ parent_work_dir_path=parent_work_dir_path,
+ config=config,
+ environment='test-env'
+ )
- @staticmethod
- def _required_config_or_result_keys():
- return []
+ self.assertIsNone(step_implementer._MavenGeneric__maven_settings_file)
+ self.assertIsNone(step_implementer._MavenGeneric__maven_phases_and_goals)
+ mock_super_init.assert_called_once_with(
+ workflow_result=workflow_result,
+ parent_work_dir_path=parent_work_dir_path,
+ config=config,
+ environment='test-env'
+ )
+
+ def test_no_environment_with_maven_phases_and_goals(self, mock_super_init):
+ workflow_result = WorkflowResult()
+ parent_work_dir_path = '/fake/path'
+ config = {}
- def _run_step(self):
- step_result = StepResult.from_step_implementer(self)
- return step_result
+ step_implementer = MavenGeneric(
+ workflow_result=workflow_result,
+ parent_work_dir_path=parent_work_dir_path,
+ config=config,
+ maven_phases_and_goals=['fake-phase']
+ )
-class TestStepImplementerSharedMavenGeneric(BaseStepImplementerTestCase):
+ self.assertIsNone(step_implementer._MavenGeneric__maven_settings_file)
+ self.assertEqual(
+ step_implementer._MavenGeneric__maven_phases_and_goals,
+ ['fake-phase']
+ )
+ mock_super_init.assert_called_once_with(
+ workflow_result=workflow_result,
+ parent_work_dir_path=parent_work_dir_path,
+ config=config,
+ environment=None
+ )
+
+class TestStepImplementerSharedMavenGeneric_step_implementer_config_defaults(
+ BaseStepImplementerTestCase
+):
+ def test_result(self):
+ self.assertEqual(
+ MavenGeneric.step_implementer_config_defaults(),
+ {
+ 'pom-file': 'pom.xml',
+ 'tls-verify': True,
+ 'maven-profiles': [],
+ 'maven-additional-arguments': [],
+ 'maven-no-transfer-progress': True
+ }
+ )
+
+class TestStepImplementerSharedMavenGeneric__required_config_or_result_keys(
+ BaseStepImplementerTestCase
+):
+ def test_result(self):
+ self.assertEqual(
+ MavenGeneric._required_config_or_result_keys(),
+ [
+ 'pom-file',
+ 'maven-phases-and-goals'
+ ]
+ )
+
+class BaseTestStepImplementerSharedMavenGeneric(BaseStepImplementerTestCase):
def create_step_implementer(
self,
step_config={},
@@ -32,80 +116,141 @@ def create_step_implementer(
parent_work_dir_path=''
):
return self.create_given_step_implementer(
- step_implementer=SampleMavenStepImplementer,
+ step_implementer=MavenGeneric,
step_config=step_config,
step_name='foo',
- implementer='SampleMavenStepImplementer',
+ implementer='MavenGeneric',
workflow_result=workflow_result,
parent_work_dir_path=parent_work_dir_path
)
- @patch('ploigos_step_runner.step_implementers.shared.maven_generic.generate_maven_settings')
- def test__generate_maven_settings(self, utils_generate_maven_settings_mock):
+@patch("ploigos_step_runner.StepImplementer._validate_required_config_or_previous_step_result_artifact_keys")
+class TestStepImplementerSharedMavenGeneric__validate_required_config_or_previous_step_result_artifact_keys(
+ BaseTestStepImplementerSharedMavenGeneric
+):
+ def test_valid(self, mock_super_validate):
with TempDirectory() as test_dir:
parent_work_dir_path = os.path.join(test_dir.path, 'working')
- maven_servers = {
- "internal-mirror": {
- "id": "internal-server",
- "username": "ploigos"
- }
- }
- maven_repositories = {
- 'internal-mirror-1': {
- 'id': 'internal-server',
- 'url': 'https://foo.example.xyz',
- 'snapshots': 'true',
- 'releases': 'false'
- }
- }
- maven_mirrors = {
- "internal-mirror": {
- "id": "internal-mirror",
- "url": "https://artifacts.example.xyz/artifactory/release/",
- "mirror-of": "*"
- }
+
+ pom_file_path = os.path.join(test_dir.path, 'pom.xml')
+ step_config = {
+ 'pom-file': pom_file_path,
+ 'maven-phases-and-goals': 'fake-phase'
}
+
+ step_implementer = self.create_step_implementer(
+ step_config=step_config,
+ parent_work_dir_path=parent_work_dir_path,
+ )
+
+ Path(pom_file_path).touch()
+ step_implementer._validate_required_config_or_previous_step_result_artifact_keys()
+
+ mock_super_validate.assert_called_once_with()
+
+ def test_pom_file_does_not_exist(self, mock_super_validate):
+ with TempDirectory() as test_dir:
+ parent_work_dir_path = os.path.join(test_dir.path, 'working')
+
+ pom_file_path = '/does/not/exist/pom.xml'
step_config = {
- 'maven-servers' : maven_servers,
- 'maven-repositories' : maven_repositories,
- 'maven-mirrors': maven_mirrors
+ 'pom-file': pom_file_path,
+ 'maven-phases-and-goals': 'fake-phase'
}
+
step_implementer = self.create_step_implementer(
step_config=step_config,
parent_work_dir_path=parent_work_dir_path,
)
- expected_settings_xml_path = '/does/not/matter/settings.xml'
- def utils_generate_maven_settings_mock_side_effect(
- working_dir,
- maven_servers,
- maven_repositories,
- maven_mirrors
+ with self.assertRaisesRegex(
+ AssertionError,
+ rf'Given maven pom file \(pom-file\) does not exist: {pom_file_path}'
):
- return expected_settings_xml_path
- utils_generate_maven_settings_mock.side_effect = \
- utils_generate_maven_settings_mock_side_effect
+ step_implementer._validate_required_config_or_previous_step_result_artifact_keys()
+ mock_super_validate.assert_called_once_with()
- actual_settings_xml_path = step_implementer._generate_maven_settings()
- self.assertEqual(expected_settings_xml_path, actual_settings_xml_path)
+class TestStepImplementerSharedMavenGeneric_maven_phases_and_goals(
+ BaseTestStepImplementerSharedMavenGeneric
+):
+ def test_use_object_property_no_config_value(self):
+ workflow_result = WorkflowResult()
+ parent_work_dir_path = '/fake/path'
+ config = None
- utils_generate_maven_settings_mock.assert_called_once_with(
- working_dir=step_implementer.work_dir_path,
- maven_servers=maven_servers,
- maven_repositories=maven_repositories,
- maven_mirrors=maven_mirrors
- )
+ step_implementer = MavenGeneric(
+ workflow_result=workflow_result,
+ parent_work_dir_path=parent_work_dir_path,
+ config=config,
+ maven_phases_and_goals=['fake-phase']
+ )
- def test__validate_required_config_or_previous_step_result_artifact_keys_valid(self):
+ self.assertEqual(
+ step_implementer.maven_phases_and_goals,
+ ['fake-phase']
+ )
+
+ def test_use_object_property_with_config_value(self):
+ workflow_result = WorkflowResult()
+ parent_work_dir_path = '/fake/path'
+ step_config = {
+ 'maven-phases-and-goals': ['config-value-fake-phase']
+ }
+ config = Config({
+ Config.CONFIG_KEY: {
+ 'foo': [
+ {
+ 'implementer': 'MavenGeneric',
+ 'config': step_config
+ }
+ ]
+
+ }
+ })
+
+ step_implementer = MavenGeneric(
+ workflow_result=workflow_result,
+ parent_work_dir_path=parent_work_dir_path,
+ config=config,
+ maven_phases_and_goals=['object-property-fake-phase']
+ )
+
+ self.assertEqual(
+ step_implementer.maven_phases_and_goals,
+ ['object-property-fake-phase']
+ )
+
+ def test_use_config_value(self):
+ parent_work_dir_path = '/fake/path'
+ step_config = {
+ 'maven-phases-and-goals': ['config-value-fake-phase']
+ }
+
+ step_implementer = self.create_step_implementer(
+ step_config=step_config,
+ parent_work_dir_path=parent_work_dir_path,
+ )
+
+ self.assertEqual(
+ step_implementer.maven_phases_and_goals,
+ ['config-value-fake-phase']
+ )
+
+@patch(
+ "ploigos_step_runner.step_implementers.shared.maven_generic.generate_maven_settings",
+ return_value='/mock/settings.xml'
+)
+class TestStepImplementerSharedMavenGeneric_maven_settings_file(
+ BaseTestStepImplementerSharedMavenGeneric
+):
+ def test_no_config(self, mock_gen_mvn_settings):
with TempDirectory() as test_dir:
- results_dir_path = os.path.join(test_dir.path, 'step-runner-results')
- results_file_name = 'step-runner-results.yml'
parent_work_dir_path = os.path.join(test_dir.path, 'working')
pom_file_path = os.path.join(test_dir.path, 'pom.xml')
step_config = {
- 'fail-on-no-tests': True,
- 'pom-file': pom_file_path
+ 'pom-file': pom_file_path,
+ 'maven-phases-and-goals': 'fake-phase'
}
step_implementer = self.create_step_implementer(
@@ -113,19 +258,62 @@ def test__validate_required_config_or_previous_step_result_artifact_keys_valid(s
parent_work_dir_path=parent_work_dir_path,
)
- Path(pom_file_path).touch()
- step_implementer._validate_required_config_or_previous_step_result_artifact_keys()
+ # call first time
+ maven_settings_file = step_implementer.maven_settings_file
+ self.assertEqual(
+ maven_settings_file,
+ '/mock/settings.xml'
+ )
+ mock_gen_mvn_settings.assert_called_once_with(
+ working_dir=step_implementer.work_dir_path,
+ maven_servers=None,
+ maven_repositories=None,
+ maven_mirrors=None
+ )
- def test__validate_required_config_or_previous_step_result_artifact_keys_pom_file_does_not_exist(self):
+ # call second time
+ mock_gen_mvn_settings.reset_mock()
+ maven_settings_file = step_implementer.maven_settings_file
+ self.assertEqual(
+ maven_settings_file,
+ '/mock/settings.xml'
+ )
+ mock_gen_mvn_settings.assert_not_called()
+
+ def test_given_config_maven_servers_maven_repos_and_maven_mirrors(self, mock_gen_mvn_settings):
with TempDirectory() as test_dir:
- results_dir_path = os.path.join(test_dir.path, 'step-runner-results')
- results_file_name = 'step-runner-results.yml'
parent_work_dir_path = os.path.join(test_dir.path, 'working')
pom_file_path = os.path.join(test_dir.path, 'pom.xml')
+ maven_servers = {
+ 'internal-mirror-1': {
+ 'id': 'internal-server',
+ 'password': 'you-wish',
+ 'username': 'team-a'
+ }
+ }
+ maven_repositories = {
+ 'internal-mirror-1': {
+ 'id': 'internal-mirror-1',
+ 'url': 'https://nexus.apps.ploigos.com/repository/maven-public/',
+ 'snapshots': 'true',
+ 'releases': 'true'
+ }
+ }
+ maven_mirrors = {
+ 'internal-mirror-1': {
+ 'id': 'internal-mirror',
+ 'mirror-of': '*',
+ 'url': 'https://nexus.apps.ploigos.com/repository/maven-public/'
+ }
+ }
+
step_config = {
- 'fail-on-no-tests': True,
- 'pom-file': pom_file_path
+ 'pom-file': pom_file_path,
+ 'maven-phases-and-goals': 'fake-phase',
+ 'maven-servers': maven_servers,
+ 'maven-repositories': maven_repositories,
+ 'maven-mirrors': maven_mirrors
}
step_implementer = self.create_step_implementer(
@@ -133,14 +321,33 @@ def test__validate_required_config_or_previous_step_result_artifact_keys_pom_fil
parent_work_dir_path=parent_work_dir_path,
)
- with self.assertRaisesRegex(
- AssertionError,
- rf'Given maven pom file \(pom-file\) does not exist: {pom_file_path}'
- ):
- step_implementer._validate_required_config_or_previous_step_result_artifact_keys()
+ # call first time
+ maven_settings_file = step_implementer.maven_settings_file
+ self.assertEqual(
+ maven_settings_file,
+ '/mock/settings.xml'
+ )
+ mock_gen_mvn_settings.assert_called_once_with(
+ working_dir=step_implementer.work_dir_path,
+ maven_servers=maven_servers,
+ maven_repositories=maven_repositories,
+ maven_mirrors=maven_mirrors
+ )
- @patch('ploigos_step_runner.step_implementers.shared.maven_generic.write_effective_pom')
- def test__get_effective_pom_call_once(self, write_effective_pom_mock):
+ # call second time
+ mock_gen_mvn_settings.reset_mock()
+ maven_settings_file = step_implementer.maven_settings_file
+ self.assertEqual(
+ maven_settings_file,
+ '/mock/settings.xml'
+ )
+ mock_gen_mvn_settings.assert_not_called()
+
+@patch('ploigos_step_runner.step_implementers.shared.maven_generic.write_effective_pom')
+class TestStepImplementerSharedMavenGeneric__get_effective_pom(
+ BaseTestStepImplementerSharedMavenGeneric
+):
+ def test_call_once(self, write_effective_pom_mock):
with TempDirectory() as test_dir:
parent_work_dir_path = os.path.join(test_dir.path, 'working')
@@ -162,7 +369,10 @@ def write_effective_pom_mock_side_effect(pom_file_path, output_path):
write_effective_pom_mock.side_effect = write_effective_pom_mock_side_effect
# first call
- expected_effective_pom_path = os.path.join(step_implementer.work_dir_path, 'effective-pom.xml')
+ expected_effective_pom_path = os.path.join(
+ step_implementer.work_dir_path,
+ 'effective-pom.xml'
+ )
actual_effective_pom_path = step_implementer._get_effective_pom()
self.assertEqual(actual_effective_pom_path, expected_effective_pom_path)
write_effective_pom_mock.assert_called_once_with(
@@ -170,7 +380,6 @@ def write_effective_pom_mock_side_effect(pom_file_path, output_path):
output_path=expected_effective_pom_path
)
- @patch('ploigos_step_runner.step_implementers.shared.maven_generic.write_effective_pom')
def test__get_effective_pom_call_twice(self, write_effective_pom_mock):
with TempDirectory() as test_dir:
parent_work_dir_path = os.path.join(test_dir.path, 'working')
@@ -193,7 +402,10 @@ def write_effective_pom_mock_side_effect(pom_file_path, output_path):
write_effective_pom_mock.side_effect = write_effective_pom_mock_side_effect
# first call
- expected_effective_pom_path = os.path.join(step_implementer.work_dir_path, 'effective-pom.xml')
+ expected_effective_pom_path = os.path.join(
+ step_implementer.work_dir_path,
+ 'effective-pom.xml'
+ )
actual_effective_pom_path = step_implementer._get_effective_pom()
self.assertEqual(actual_effective_pom_path, expected_effective_pom_path)
write_effective_pom_mock.assert_called_once_with(
@@ -203,17 +415,21 @@ def write_effective_pom_mock_side_effect(pom_file_path, output_path):
# second call
write_effective_pom_mock.reset_mock()
- expected_effective_pom_path = os.path.join(step_implementer.work_dir_path, 'effective-pom.xml')
+ expected_effective_pom_path = os.path.join(
+ step_implementer.work_dir_path,
+ 'effective-pom.xml'
+ )
actual_effective_pom_path = step_implementer._get_effective_pom()
self.assertEqual(actual_effective_pom_path, expected_effective_pom_path)
write_effective_pom_mock.assert_not_called()
- @patch('ploigos_step_runner.step_implementers.shared.maven_generic.get_xml_element_by_path')
- @patch.object(MavenGeneric, '_get_effective_pom')
- def test__get_effective_pom_element(self, get_effective_pom_mock, get_xml_element_by_path_mock):
+@patch('ploigos_step_runner.step_implementers.shared.maven_generic.get_xml_element_by_path')
+@patch.object(MavenGeneric, '_get_effective_pom')
+class TestStepImplementerSharedMavenGeneric__get_effective_pom_element(
+ BaseTestStepImplementerSharedMavenGeneric
+):
+ def test_result(self, get_effective_pom_mock, get_xml_element_by_path_mock):
with TempDirectory() as test_dir:
- results_dir_path = os.path.join(test_dir.path, 'step-runner-results')
- results_file_name = 'step-runner-results.yml'
parent_work_dir_path = os.path.join(test_dir.path, 'working')
pom_file_path = os.path.join(test_dir.path, 'pom.xml')
@@ -237,3 +453,334 @@ def get_effective_pom_side_effect():
'foo',
default_namespace='mvn'
)
+
+@patch('ploigos_step_runner.step_implementers.shared.maven_generic.run_maven')
+@patch.object(
+ MavenGeneric,
+ 'maven_phases_and_goals',
+ new_callable=PropertyMock,
+ return_value=['fake-phase']
+)
+@patch.object(
+ MavenGeneric,
+ 'maven_settings_file',
+ new_callable=PropertyMock,
+ return_value='/fake/settings.xml'
+)
+class TestStepImplementerSharedMavenGeneric__run_maven_step(
+ BaseTestStepImplementerSharedMavenGeneric
+):
+ def test_defaults(self, mock_settings_file, mock_phases_and_goals, mock_run_maven):
+ with TempDirectory() as test_dir:
+ parent_work_dir_path = os.path.join(test_dir.path, 'working')
+
+ pom_file_path = os.path.join(test_dir.path, 'pom.xml')
+ step_config = {
+ 'pom-file': pom_file_path
+ }
+
+ step_implementer = self.create_step_implementer(
+ step_config=step_config,
+ parent_work_dir_path=parent_work_dir_path,
+ )
+
+ mvn_output_file_path = os.path.join(test_dir.path, 'maven-output.txt')
+ step_implementer._run_maven_step(
+ mvn_output_file_path=mvn_output_file_path
+ )
+
+ mock_run_maven.assert_called_with(
+ mvn_output_file_path=mvn_output_file_path,
+ phases_and_goals=['fake-phase'],
+ additional_arguments=[],
+ pom_file=pom_file_path,
+ tls_verify=True,
+ profiles=[],
+ no_transfer_progress=True,
+ settings_file='/fake/settings.xml'
+ )
+
+
+ def test_custom_profile(self, mock_settings_file, mock_phases_and_goals, mock_run_maven):
+ with TempDirectory() as test_dir:
+ parent_work_dir_path = os.path.join(test_dir.path, 'working')
+
+ pom_file_path = os.path.join(test_dir.path, 'pom.xml')
+ step_config = {
+ 'pom-file': pom_file_path,
+ 'maven-profiles': ['fake-profile-1', 'fakse-profile-2']
+ }
+
+ step_implementer = self.create_step_implementer(
+ step_config=step_config,
+ parent_work_dir_path=parent_work_dir_path,
+ )
+
+ mvn_output_file_path = os.path.join(test_dir.path, 'maven-output.txt')
+ step_implementer._run_maven_step(
+ mvn_output_file_path=mvn_output_file_path
+ )
+
+ mock_run_maven.assert_called_with(
+ mvn_output_file_path=mvn_output_file_path,
+ phases_and_goals=['fake-phase'],
+ additional_arguments=[],
+ pom_file=pom_file_path,
+ tls_verify=True,
+ profiles=['fake-profile-1', 'fakse-profile-2'],
+ no_transfer_progress=True,
+ settings_file='/fake/settings.xml'
+ )
+
+ def test_no_tls_verify(self, mock_settings_file, mock_phases_and_goals, mock_run_maven):
+ with TempDirectory() as test_dir:
+ parent_work_dir_path = os.path.join(test_dir.path, 'working')
+
+ pom_file_path = os.path.join(test_dir.path, 'pom.xml')
+ step_config = {
+ 'pom-file': pom_file_path,
+ 'tls-verify': False
+ }
+
+ step_implementer = self.create_step_implementer(
+ step_config=step_config,
+ parent_work_dir_path=parent_work_dir_path,
+ )
+
+ mvn_output_file_path = os.path.join(test_dir.path, 'maven-output.txt')
+ step_implementer._run_maven_step(
+ mvn_output_file_path=mvn_output_file_path
+ )
+
+ mock_run_maven.assert_called_with(
+ mvn_output_file_path=mvn_output_file_path,
+ phases_and_goals=['fake-phase'],
+ additional_arguments=[],
+ pom_file=pom_file_path,
+ tls_verify=False,
+ profiles=[],
+ no_transfer_progress=True,
+ settings_file='/fake/settings.xml'
+ )
+
+ def test_yes_transfer_progress(self, mock_settings_file, mock_phases_and_goals, mock_run_maven):
+ with TempDirectory() as test_dir:
+ parent_work_dir_path = os.path.join(test_dir.path, 'working')
+
+ pom_file_path = os.path.join(test_dir.path, 'pom.xml')
+ step_config = {
+ 'pom-file': pom_file_path,
+ 'maven-no-transfer-progress': False
+ }
+
+ step_implementer = self.create_step_implementer(
+ step_config=step_config,
+ parent_work_dir_path=parent_work_dir_path,
+ )
+
+ mvn_output_file_path = os.path.join(test_dir.path, 'maven-output.txt')
+ step_implementer._run_maven_step(
+ mvn_output_file_path=mvn_output_file_path
+ )
+
+ mock_run_maven.assert_called_with(
+ mvn_output_file_path=mvn_output_file_path,
+ phases_and_goals=['fake-phase'],
+ additional_arguments=[],
+ pom_file=pom_file_path,
+ tls_verify=True,
+ profiles=[],
+ no_transfer_progress=False,
+ settings_file='/fake/settings.xml'
+ )
+
+ def test_config_additional_arguments(
+ self,
+ mock_settings_file,
+ mock_phases_and_goals,
+ mock_run_maven
+ ):
+ with TempDirectory() as test_dir:
+ parent_work_dir_path = os.path.join(test_dir.path, 'working')
+
+ pom_file_path = os.path.join(test_dir.path, 'pom.xml')
+ step_config = {
+ 'pom-file': pom_file_path,
+ 'maven-additional-arguments': ['-Dfake.config.arg=True']
+ }
+
+ step_implementer = self.create_step_implementer(
+ step_config=step_config,
+ parent_work_dir_path=parent_work_dir_path,
+ )
+
+ mvn_output_file_path = os.path.join(test_dir.path, 'maven-output.txt')
+ step_implementer._run_maven_step(
+ mvn_output_file_path=mvn_output_file_path
+ )
+
+ mock_run_maven.assert_called_with(
+ mvn_output_file_path=mvn_output_file_path,
+ phases_and_goals=['fake-phase'],
+ additional_arguments=['-Dfake.config.arg=True'],
+ pom_file=pom_file_path,
+ tls_verify=True,
+ profiles=[],
+ no_transfer_progress=True,
+ settings_file='/fake/settings.xml'
+ )
+
+ def test_step_implementer_additional_arguments(
+ self,
+ mock_settings_file,
+ mock_phases_and_goals,
+ mock_run_maven
+ ):
+ with TempDirectory() as test_dir:
+ parent_work_dir_path = os.path.join(test_dir.path, 'working')
+
+ pom_file_path = os.path.join(test_dir.path, 'pom.xml')
+ step_config = {
+ 'pom-file': pom_file_path
+ }
+
+ step_implementer = self.create_step_implementer(
+ step_config=step_config,
+ parent_work_dir_path=parent_work_dir_path,
+ )
+
+ mvn_output_file_path = os.path.join(test_dir.path, 'maven-output.txt')
+ step_implementer._run_maven_step(
+ mvn_output_file_path=mvn_output_file_path,
+ step_implementer_additional_arguments=['-Dfake.step_implementer.arg=True']
+ )
+
+ mock_run_maven.assert_called_with(
+ mvn_output_file_path=mvn_output_file_path,
+ phases_and_goals=['fake-phase'],
+ additional_arguments=['-Dfake.step_implementer.arg=True'],
+ pom_file=pom_file_path,
+ tls_verify=True,
+ profiles=[],
+ no_transfer_progress=True,
+ settings_file='/fake/settings.xml'
+ )
+
+ def test_step_implementer_additional_arguments_and_config_additional_arguments(
+ self,
+ mock_settings_file,
+ mock_phases_and_goals,
+ mock_run_maven
+ ):
+ with TempDirectory() as test_dir:
+ parent_work_dir_path = os.path.join(test_dir.path, 'working')
+
+ pom_file_path = os.path.join(test_dir.path, 'pom.xml')
+ step_config = {
+ 'pom-file': pom_file_path,
+ 'maven-additional-arguments': ['-Dfake.config.arg=True']
+ }
+
+ step_implementer = self.create_step_implementer(
+ step_config=step_config,
+ parent_work_dir_path=parent_work_dir_path,
+ )
+
+ mvn_output_file_path = os.path.join(test_dir.path, 'maven-output.txt')
+ step_implementer._run_maven_step(
+ mvn_output_file_path=mvn_output_file_path,
+ step_implementer_additional_arguments=['-Dfake.step_implementer.arg=True']
+ )
+
+ mock_run_maven.assert_called_with(
+ mvn_output_file_path=mvn_output_file_path,
+ phases_and_goals=['fake-phase'],
+ additional_arguments=['-Dfake.step_implementer.arg=True', '-Dfake.config.arg=True'],
+ pom_file=pom_file_path,
+ tls_verify=True,
+ profiles=[],
+ no_transfer_progress=True,
+ settings_file='/fake/settings.xml'
+ )
+
+@patch.object(MavenGeneric, '_run_maven_step')
+@patch.object(MavenGeneric, 'write_working_file', return_value='/mock/mvn_output.txt')
+class TestStepImplementerSharedMavenGeneric__run_step(
+ BaseTestStepImplementerSharedMavenGeneric
+):
+ def test_success(self, mock_write_working_file, mock_run_maven_step):
+ with TempDirectory() as test_dir:
+ parent_work_dir_path = os.path.join(test_dir.path, 'working')
+
+ step_config = {}
+ step_implementer = self.create_step_implementer(
+ step_config=step_config,
+ parent_work_dir_path=parent_work_dir_path,
+ )
+
+ # run step
+ actual_step_result = step_implementer._run_step()
+
+ # create expected step result
+ expected_step_result = StepResult(
+ step_name='foo',
+ sub_step_name='MavenGeneric',
+ sub_step_implementer_name='MavenGeneric'
+ )
+ expected_step_result.add_artifact(
+ description="Standard out and standard error from maven.",
+ name='maven-output',
+ value='/mock/mvn_output.txt'
+ )
+
+ # verify step result
+ self.assertEqual(
+ actual_step_result,
+ expected_step_result
+ )
+
+ mock_write_working_file.assert_called_once()
+ mock_run_maven_step.assert_called_with(
+ mvn_output_file_path='/mock/mvn_output.txt'
+ )
+
+ def test_fail(self, mock_write_working_file, mock_run_maven_step):
+ with TempDirectory() as test_dir:
+ parent_work_dir_path = os.path.join(test_dir.path, 'working')
+
+ step_config = {}
+ step_implementer = self.create_step_implementer(
+ step_config=step_config,
+ parent_work_dir_path=parent_work_dir_path,
+ )
+
+ # run step with mock failure
+ mock_run_maven_step.side_effect = StepRunnerException('Mock error running maven')
+ actual_step_result = step_implementer._run_step()
+
+ # create expected step result
+ expected_step_result = StepResult(
+ step_name='foo',
+ sub_step_name='MavenGeneric',
+ sub_step_implementer_name='MavenGeneric'
+ )
+ expected_step_result.add_artifact(
+ description="Standard out and standard error from maven.",
+ name='maven-output',
+ value='/mock/mvn_output.txt'
+ )
+ expected_step_result.message = "Error running maven. " \
+ "More details maybe found in 'maven-output' report artifact: "\
+ "Mock error running maven"
+ expected_step_result.success = False
+
+ # verify step result
+ self.assertEqual(
+ actual_step_result,
+ expected_step_result
+ )
+
+ mock_write_working_file.assert_called_once()
+ mock_run_maven_step.assert_called_with(
+ mvn_output_file_path='/mock/mvn_output.txt'
+ )
diff --git a/tests/step_implementers/uat/test_maven_selenium_cucumber.py b/tests/step_implementers/uat/test_maven_selenium_cucumber.py
index 997128be..241b8c73 100644
--- a/tests/step_implementers/uat/test_maven_selenium_cucumber.py
+++ b/tests/step_implementers/uat/test_maven_selenium_cucumber.py
@@ -1,24 +1,20 @@
import os
-from io import IOBase
from pathlib import Path
-from shutil import copyfile
-from unittest.mock import patch
+from unittest.mock import Mock, patch
-import sh
-from testfixtures import TempDirectory
-from tests.helpers.maven_step_implementer_test_case import \
- MaveStepImplementerTestCase
-from tests.helpers.test_utils import Any
+from ploigos_step_runner import StepResult, StepRunnerException, WorkflowResult
from ploigos_step_runner.exceptions import StepRunnerException
from ploigos_step_runner.step_implementers.uat import MavenSeleniumCucumber
-from ploigos_step_runner import StepResult
-from ploigos_step_runner.utils.file import create_parent_dir
+from testfixtures import TempDirectory
+from tests.helpers.base_step_implementer_test_case import \
+ BaseStepImplementerTestCase
-class TestStepImplementerMavenSeleniumCucumberBase(MaveStepImplementerTestCase):
+class BaseTestStepImplementerSharedMavenSeleniumCucumber(BaseStepImplementerTestCase):
def create_step_implementer(
self,
step_config={},
+ workflow_result=None,
parent_work_dir_path=''
):
return self.create_given_step_implementer(
@@ -26,40 +22,91 @@ def create_step_implementer(
step_config=step_config,
step_name='uat',
implementer='MavenSeleniumCucumber',
+ workflow_result=workflow_result,
parent_work_dir_path=parent_work_dir_path
)
-class TestStepImplementerDeployMavenSeleniumCucumber_validate_required_config_or_previous_step_result_artifact_keys(
- TestStepImplementerMavenSeleniumCucumberBase
-):
- def test_MavenSeleniumCucumber_validate_required_config_or_previous_step_result_artifact_keys_success_target_host_url(self):
- with TempDirectory() as temp_dir:
- parent_work_dir_path = os.path.join(temp_dir.path, 'working')
+@patch("ploigos_step_runner.step_implementers.shared.MavenGeneric.__init__")
+class TestStepImplementerMavenTestMavenSeleniumCucumber___init__(BaseStepImplementerTestCase):
+ def test_defaults(self, mock_super_init):
+ workflow_result = WorkflowResult()
+ parent_work_dir_path = '/fake/path'
+ config = {}
- pom_file_path = os.path.join(temp_dir.path, 'pom.xml')
- Path(pom_file_path).touch()
- step_config = {
- 'selenium-hub-url': 'https://selenium.ploigos.xyz',
- 'pom-file': pom_file_path,
- 'target-host-url': 'https://foo.test.ploigos.xyz'
+ MavenSeleniumCucumber(
+ workflow_result=workflow_result,
+ parent_work_dir_path=parent_work_dir_path,
+ config=config
+ )
+
+ mock_super_init.assert_called_once_with(
+ workflow_result=workflow_result,
+ parent_work_dir_path=parent_work_dir_path,
+ config=config,
+ environment=None,
+ maven_phases_and_goals=['test']
+ )
+
+ def test_given_environment(self, mock_super_init):
+ workflow_result = WorkflowResult()
+ parent_work_dir_path = '/fake/path'
+ config = {}
+
+ MavenSeleniumCucumber(
+ workflow_result=workflow_result,
+ parent_work_dir_path=parent_work_dir_path,
+ config=config,
+ environment='mock-env'
+ )
+
+ mock_super_init.assert_called_once_with(
+ workflow_result=workflow_result,
+ parent_work_dir_path=parent_work_dir_path,
+ config=config,
+ environment='mock-env',
+ maven_phases_and_goals=['test']
+ )
+
+class TestStepImplementerMavenTestMavenSeleniumCucumber_step_implementer_config_defaults(
+ BaseStepImplementerTestCase
+):
+ def test_result(self):
+ self.assertEqual(
+ MavenSeleniumCucumber.step_implementer_config_defaults(),
+ {
+ 'pom-file': 'pom.xml',
+ 'tls-verify': True,
+ 'maven-profiles': [],
+ 'maven-additional-arguments': [],
+ 'maven-no-transfer-progress': True,
+ 'maven-profiles': ['integration-test'],
+ 'fail-on-no-tests': True
}
- step_implementer = self.create_step_implementer(
- step_config=step_config,
- parent_work_dir_path=parent_work_dir_path,
- )
+ )
- step_implementer._validate_required_config_or_previous_step_result_artifact_keys()
+class TestStepImplementerMavenTestMavenSeleniumCucumber__required_config_or_result_keys(
+ BaseStepImplementerTestCase
+):
+ def test_result(self):
+ self.assertEqual(
+ MavenSeleniumCucumber._required_config_or_result_keys(),
+ [
+ 'pom-file',
+ 'fail-on-no-tests',
+ 'selenium-hub-url',
+ ]
+ )
- def test_MavenSeleniumCucumber_validate_required_config_or_previous_step_result_artifact_keys_success_deployed_host_urls_1(self):
- with TempDirectory() as temp_dir:
- parent_work_dir_path = os.path.join(temp_dir.path, 'working')
+@patch("ploigos_step_runner.step_implementers.shared.MavenGeneric._validate_required_config_or_previous_step_result_artifact_keys")
+class TestStepImplementerSharedMavenGeneric__validate_required_config_or_previous_step_result_artifact_keys(
+ BaseTestStepImplementerSharedMavenSeleniumCucumber
+):
+ def test_valid_target_host_url(self, mock_super_validate):
+ with TempDirectory() as test_dir:
+ parent_work_dir_path = os.path.join(test_dir.path, 'working')
- pom_file_path = os.path.join(temp_dir.path, 'pom.xml')
- Path(pom_file_path).touch()
step_config = {
- 'selenium-hub-url': 'https://selenium.ploigos.xyz',
- 'pom-file': pom_file_path,
- 'deployed-host-urls': ['https://foo.test.ploigos.xyz']
+ 'target-host-url': 'https://mock-target-host-url.ploigos.com'
}
step_implementer = self.create_step_implementer(
step_config=step_config,
@@ -67,17 +114,14 @@ def test_MavenSeleniumCucumber_validate_required_config_or_previous_step_result_
)
step_implementer._validate_required_config_or_previous_step_result_artifact_keys()
+ mock_super_validate.assert_called_once_with()
- def test_MavenSeleniumCucumber_validate_required_config_or_previous_step_result_artifact_keys_success_deployed_host_urls_2(self):
- with TempDirectory() as temp_dir:
- parent_work_dir_path = os.path.join(temp_dir.path, 'working')
+ def test_valid_deployed_host_urls(self, mock_super_validate):
+ with TempDirectory() as test_dir:
+ parent_work_dir_path = os.path.join(test_dir.path, 'working')
- pom_file_path = os.path.join(temp_dir.path, 'pom.xml')
- Path(pom_file_path).touch()
step_config = {
- 'selenium-hub-url': 'https://selenium.ploigos.xyz',
- 'pom-file': pom_file_path,
- 'deployed-host-urls': ['https://foo.test.ploigos.xyz', 'https://bar.test.ploigos.xyz']
+ 'deployed-host-urls': ['https://mock-deployed-host-url1.ploigos.com']
}
step_implementer = self.create_step_implementer(
step_config=step_config,
@@ -85,17 +129,13 @@ def test_MavenSeleniumCucumber_validate_required_config_or_previous_step_result_
)
step_implementer._validate_required_config_or_previous_step_result_artifact_keys()
+ mock_super_validate.assert_called_once_with()
- def test_MavenSeleniumCucumber_validate_required_config_or_previous_step_result_artifact_keys_fail_no_target_urls(self):
- with TempDirectory() as temp_dir:
- parent_work_dir_path = os.path.join(temp_dir.path, 'working')
+ def test_fail_no_target_host_url_or_deployed_host_urls(self, mock_super_validate):
+ with TempDirectory() as test_dir:
+ parent_work_dir_path = os.path.join(test_dir.path, 'working')
- pom_file_path = os.path.join(temp_dir.path, 'pom.xml')
- Path(pom_file_path).touch()
- step_config = {
- 'selenium-hub-url': 'https://selenium.ploigos.xyz',
- 'pom-file': pom_file_path
- }
+ step_config = {}
step_implementer = self.create_step_implementer(
step_config=step_config,
parent_work_dir_path=parent_work_dir_path,
@@ -103,1074 +143,1902 @@ def test_MavenSeleniumCucumber_validate_required_config_or_previous_step_result_
with self.assertRaisesRegex(
StepRunnerException,
- rf"Either 'target-host-url' or 'deployed-host-urls' needs to be supplied but"
- " neither were."
+ "Either 'target-host-url' or 'deployed-host-urls' needs " \
+ "to be supplied but neither were."
):
step_implementer._validate_required_config_or_previous_step_result_artifact_keys()
-class TestStepImplementerMavenSeleniumCucumber_Other(TestStepImplementerMavenSeleniumCucumberBase):
- def test_step_implementer_config_defaults(self):
- actual_defaults = MavenSeleniumCucumber.step_implementer_config_defaults()
- expected_defaults = {
- 'fail-on-no-tests': True,
- 'pom-file': 'pom.xml',
- 'tls-verify': True,
- 'uat-maven-profile': 'integration-test'
- }
- self.assertEqual(expected_defaults, actual_defaults)
-
- def test__required_config_or_result_keys(self):
- actual_required_keys = MavenSeleniumCucumber._required_config_or_result_keys()
- expected_required_keys = [
- 'fail-on-no-tests',
- 'pom-file',
- 'selenium-hub-url',
- 'uat-maven-profile'
- ]
- self.assertEqual(expected_required_keys, actual_required_keys)
+ mock_super_validate.assert_called_once_with()
- def __run__run_step_test(
- self,
- test_dir,
- mvn_mock,
- write_effective_pom_mock,
- generate_maven_settings_mock,
- pom_content,
- group_id,
- artifact_id,
- surefire_reports_dir,
- selenium_hub_url,
- target_host_url=None,
- deployed_host_urls=None,
- write_mock_test_results=True,
- assert_mvn_called=True,
- assert_report_artifact=True,
- assert_evidence=True,
- expected_result_success=True,
- expected_result_message='',
- fail_on_no_tests=None,
- uat_maven_profile=None,
- pom_file_name='pom.xml',
- raise_error_on_tests=False,
- set_tls_verify_false=False,
- aggregate_xml_element_attribute_values_mock=False,
- aggregate_xml_element_attribute_values_mock_fail=False
- ):
- parent_work_dir_path = os.path.join(test_dir.path, 'working')
+@patch.object(MavenSeleniumCucumber, '_run_maven_step')
+@patch.object(MavenSeleniumCucumber, 'write_working_file', return_value='/mock/mvn_output.txt')
+@patch(
+ 'ploigos_step_runner.step_implementers.uat.maven_selenium_cucumber.aggregate_xml_element_attribute_values',
+ return_value={
+ 'time': '42',
+ 'tests': '42',
+ 'errors': '0',
+ 'skipped': '0',
+ 'failures': '0'
+ })
+class TestStepImplementerMavenTestMavenSeleniumCucumber__run_step(
+ BaseTestStepImplementerSharedMavenSeleniumCucumber
+):
+ def __expected_step_result_base(self):
+ expected_step_result = StepResult(
+ step_name='uat',
+ sub_step_name='MavenSeleniumCucumber',
+ sub_step_implementer_name='MavenSeleniumCucumber'
+ )
+
+ return expected_step_result
+ def __expected_step_result_with_artifacts(self, parent_work_dir_path, surefire_reports_dir):
cucumber_html_report_path = os.path.join(parent_work_dir_path, 'uat', 'cucumber.html')
cucumber_json_report_path = os.path.join(parent_work_dir_path, 'uat', 'cucumber.json')
+ expected_step_result = self.__expected_step_result_base()
+ expected_step_result.add_artifact(
+ description="Standard out and standard error from maven.",
+ name='maven-output',
+ value='/mock/mvn_output.txt'
+ )
+ expected_step_result.add_artifact(
+ description="Surefire reports generated by maven.",
+ name='surefire-reports',
+ value=surefire_reports_dir
+ )
+ expected_step_result.add_artifact(
+ description="Cucumber (HTML) report generated by maven.",
+ name='cucumber-report-html',
+ value=cucumber_html_report_path
+ )
+ expected_step_result.add_artifact(
+ description="Cucumber (JSON) report generated by maven.",
+ name='cucumber-report-json',
+ value=cucumber_json_report_path
+ )
- test_dir.write(pom_file_name, pom_content)
-
- pom_file_path = os.path.join(test_dir.path, pom_file_name)
- step_config = {
- 'pom-file': pom_file_path,
- 'selenium-hub-url': selenium_hub_url,
- 'tls-verify': True
- }
-
- if set_tls_verify_false:
- step_config['tls-verify'] = False
-
- target_base_url = None
- if deployed_host_urls:
- step_config['deployed-host-urls'] = deployed_host_urls
- if isinstance(deployed_host_urls, list):
- target_base_url = deployed_host_urls[0]
- else:
- target_base_url = deployed_host_urls
- if target_host_url:
- step_config['target-host-url'] = target_host_url
- target_base_url = target_host_url
-
- if fail_on_no_tests is not None:
- step_config['fail-on-no-tests'] = fail_on_no_tests
- if uat_maven_profile is not None:
- step_config['uat-maven-profile'] = uat_maven_profile
- else:
- uat_maven_profile = 'integration-test'
- step_implementer = self.create_step_implementer(
- step_config=step_config,
+ return expected_step_result
+
+ def __expected_step_result_with_artifacts_and_evidence(
+ self,
+ parent_work_dir_path,
+ surefire_reports_dir
+ ):
+ expected_step_result = self.__expected_step_result_with_artifacts(
parent_work_dir_path=parent_work_dir_path,
+ surefire_reports_dir=surefire_reports_dir
+ )
+ expected_step_result.add_evidence(
+ name='uat-evidence-time',
+ description='Surefire report value for time',
+ value='42'
+ )
+ expected_step_result.add_evidence(
+ name='uat-evidence-tests',
+ description='Surefire report value for tests',
+ value='42'
+ )
+ expected_step_result.add_evidence(
+ name='uat-evidence-errors',
+ description='Surefire report value for errors',
+ value='0'
+ )
+ expected_step_result.add_evidence(
+ name='uat-evidence-skipped',
+ description='Surefire report value for skipped',
+ value='0'
+ )
+ expected_step_result.add_evidence(
+ name='uat-evidence-failures',
+ description='Surefire report value for failures',
+ value='0'
)
- # mock generating settings
- settings_file_path = "/does/not/matter/settings.xml"
- def generate_maven_settings_side_effect():
- return settings_file_path
- generate_maven_settings_mock.side_effect = generate_maven_settings_side_effect
-
- # mock effective pom
- def write_effective_pom_mock_side_effect(pom_file_path, output_path):
- create_parent_dir(pom_file_path)
- copyfile(pom_file_path, output_path)
- write_effective_pom_mock.side_effect = write_effective_pom_mock_side_effect
-
- # mock test results
- if write_mock_test_results:
- mvn_mock.side_effect = MaveStepImplementerTestCase.create_mvn_side_effect(
- pom_file=pom_file_path,
- artifact_parent_dir=surefire_reports_dir,
- artifact_names=[
- f'{group_id}.{artifact_id}.CucumberTest.txt',
- f'TEST-{group_id}.{artifact_id}.CucumberTest.xml'
- ],
- raise_error_on_tests=raise_error_on_tests
- )
+ return expected_step_result
- # mock evidence
- if aggregate_xml_element_attribute_values_mock and not aggregate_xml_element_attribute_values_mock_fail:
- aggregate_xml_element_attribute_values_mock.return_value = {
- 'time': '42',
- 'tests': '42',
- 'errors': '0',
- 'skipped': '0',
- 'failures': '0'
- }
- elif aggregate_xml_element_attribute_values_mock_fail:
- aggregate_xml_element_attribute_values_mock.return_value = {
- 'time': '42'
- }
-
- result = step_implementer._run_step()
- if assert_mvn_called:
- if not set_tls_verify_false:
- mvn_mock.assert_called_once_with(
- 'clean',
- 'test',
- f'-P{uat_maven_profile}',
- f'-Dselenium.hub.url={selenium_hub_url}',
- f'-Dtarget.base.url={target_base_url}',
- f'-Dcucumber.plugin=' \
- f'html:{cucumber_html_report_path},' \
- f'json:{cucumber_json_report_path}',
- '-f', pom_file_path,
- '-s', settings_file_path,
- _out=Any(IOBase),
- _err=Any(IOBase)
- )
- else:
- mvn_mock.assert_called_once_with(
- 'clean',
- 'test',
- f'-P{uat_maven_profile}',
- f'-Dselenium.hub.url={selenium_hub_url}',
- f'-Dtarget.base.url={target_base_url}',
- f'-Dcucumber.plugin=' \
- f'html:{cucumber_html_report_path},' \
- f'json:{cucumber_json_report_path}',
- '-f', pom_file_path,
- '-s', settings_file_path,
- '-Dmaven.wagon.http.ssl.insecure=true',
- '-Dmaven.wagon.http.ssl.allowall=true',
- '-Dmaven.wagon.http.ssl.ignore.validity.dates=true',
- _out=Any(IOBase),
- _err=Any(IOBase)
+
+ def __create_run_maven_side_effect(self, surefire_reports_dir):
+ group_id = 'com.ploigos.app'
+ artifact_id = 'my-app'
+ surefire_artifact_names = [
+ f'{group_id}.{artifact_id}.ClassNameTest.txt',
+ f'TEST-{group_id}.{artifact_id}.ClassNameTest.xml'
+ ]
+ def run_maven_side_effect(**kargs):
+ os.makedirs(surefire_reports_dir, exist_ok=True)
+
+ for artifact_name in surefire_artifact_names:
+ artifact_path = os.path.join(
+ surefire_reports_dir,
+ artifact_name
)
+ Path(artifact_path).touch()
- expected_step_result = StepResult(
- step_name='uat',
- sub_step_name='MavenSeleniumCucumber',
- sub_step_implementer_name='MavenSeleniumCucumber'
- )
- expected_step_result.success = expected_result_success
- expected_step_result.message = expected_result_message
+ return run_maven_side_effect
- if assert_report_artifact:
- mvn_test_output_file_path = os.path.join(
- step_implementer.work_dir_path,
- 'mvn_test_output.txt'
- )
- expected_step_result.add_artifact(
- description=f"Standard out and standard error by 'mvn -P{uat_maven_profile} test'.",
- name='maven-output',
- value=mvn_test_output_file_path
- )
- expected_step_result.add_artifact(
- description=f"Surefire reports generated by 'mvn -P{uat_maven_profile} test'.",
- name='surefire-reports',
- value=surefire_reports_dir
- )
- expected_step_result.add_artifact(
- description=f"Cucumber (HTML) report generated by 'mvn -P{uat_maven_profile} test'.",
- name='cucumber-report-html',
- value=cucumber_html_report_path
- )
- expected_step_result.add_artifact(
- description=f"Cucumber (JSON) report generated by 'mvn -P{uat_maven_profile} test'.",
- name='cucumber-report-json',
- value=cucumber_json_report_path
- )
-
- if assert_evidence and not aggregate_xml_element_attribute_values_mock_fail:
- expected_step_result.add_evidence(
- name='uat-evidence-time',
- description='Surefire report value for time',
- value='42'
- )
- expected_step_result.add_evidence(
- name='uat-evidence-tests',
- description='Surefire report value for tests',
- value='42'
- )
- expected_step_result.add_evidence(
- name='uat-evidence-errors',
- description='Surefire report value for errors',
- value='0'
+ @patch.object(
+ MavenSeleniumCucumber,
+ '_get_effective_pom_element',
+ side_effect=['mock surefire element', None]
+ )
+ def test_success_target_host_url_default_reports_dir(
+ self,
+ mock_effective_pom_element,
+ mock_aggregate_xml_element_attribute_values,
+ mock_write_working_file,
+ mock_run_maven_step
+ ):
+ with TempDirectory() as test_dir:
+ parent_work_dir_path = os.path.join(test_dir.path, 'working')
+
+ pom_file = os.path.join(test_dir.path, 'mock-pom.xml')
+ selenium_hub_url = 'https://mock-selenium-hub.ploigos.com'
+ target_base_url = 'https://mock-app.ploigos.com'
+ step_config = {
+ 'pom-file': pom_file,
+ 'selenium-hub-url': selenium_hub_url,
+ 'target-host-url': target_base_url
+ }
+ step_implementer = self.create_step_implementer(
+ step_config=step_config,
+ parent_work_dir_path=parent_work_dir_path,
)
- expected_step_result.add_evidence(
- name='uat-evidence-skipped',
- description='Surefire report value for skipped',
- value='0'
+
+ # setup sideeffects
+ surefire_reports_dir = os.path.join(test_dir.path, 'target/surefire-reports')
+ mock_run_maven_step.side_effect = self.__create_run_maven_side_effect(
+ surefire_reports_dir=surefire_reports_dir
)
- expected_step_result.add_evidence(
- name='uat-evidence-failures',
- description='Surefire report value for failures',
- value='0'
+
+ # run step
+ actual_step_result = step_implementer._run_step()
+
+ # create expected step result
+ cucumber_html_report_path = os.path.join(parent_work_dir_path, 'uat', 'cucumber.html')
+ cucumber_json_report_path = os.path.join(parent_work_dir_path, 'uat', 'cucumber.json')
+ expected_step_result = self.__expected_step_result_with_artifacts_and_evidence(
+ parent_work_dir_path=parent_work_dir_path,
+ surefire_reports_dir=surefire_reports_dir
)
- elif assert_evidence and aggregate_xml_element_attribute_values_mock_fail:
- expected_step_result.add_evidence(
- name='uat-evidence-time',
- description='Surefire report value for time',
- value='42'
+
+ # verify step result
+ self.assertEqual(
+ actual_step_result,
+ expected_step_result
)
- print(result)
- self.assertEqual(expected_step_result, result)
+ mock_write_working_file.assert_called_once()
+ mock_run_maven_step.assert_called_with(
+ mvn_output_file_path='/mock/mvn_output.txt',
+ step_implementer_additional_arguments=[
+ f'-Dselenium.hub.url={selenium_hub_url}',
+ f'-Dtarget.base.url={target_base_url}',
+ f'-Dcucumber.plugin=' \
+ f'html:{cucumber_html_report_path},' \
+ f'json:{cucumber_json_report_path}',
+ ]
+ )
- @patch('ploigos_step_runner.step_implementers.uat.maven_selenium_cucumber.aggregate_xml_element_attribute_values')
- @patch.object(MavenSeleniumCucumber, '_generate_maven_settings')
- @patch('sh.mvn', create=True)
- @patch('ploigos_step_runner.step_implementers.shared.maven_generic.write_effective_pom')
- def test__run_step_success_defaults(
+ @patch.object(
+ MavenSeleniumCucumber,
+ '_get_effective_pom_element',
+ side_effect=['mock surefire element', None]
+ )
+ def test_success_single_deployed_host_url_default_reports_dir(
self,
- write_effective_pom_mock,
- mvn_mock,
- generate_maven_settings_mock,
- aggregate_xml_element_attribute_values_mock
+ mock_effective_pom_element,
+ mock_aggregate_xml_element_attribute_values,
+ mock_write_working_file,
+ mock_run_maven_step
):
with TempDirectory() as test_dir:
- group_id = 'com.mycompany.app'
- artifact_id = 'my-app'
- version = '1.0'
+ parent_work_dir_path = os.path.join(test_dir.path, 'working')
+
+ pom_file = os.path.join(test_dir.path, 'mock-pom.xml')
+ selenium_hub_url = 'https://mock-selenium-hub.ploigos.com'
+ target_base_url = 'https://mock-app.ploigos.com'
+ step_config = {
+ 'pom-file': pom_file,
+ 'selenium-hub-url': selenium_hub_url,
+ 'deployed-host-urls': target_base_url
+ }
+ step_implementer = self.create_step_implementer(
+ step_config=step_config,
+ parent_work_dir_path=parent_work_dir_path,
+ )
+
+ # setup sideeffects
surefire_reports_dir = os.path.join(test_dir.path, 'target/surefire-reports')
- pom_content = bytes(
-'''
- 4.0.0
- {group_id}
- {artifact_id}
- {version}
-
- 1.8
- 1.8
-
-
-
-
- maven-surefire-plugin
- ${{surefire-plugin.version}}
-
-
-
-'''.format(
- group_id=group_id,
- artifact_id=artifact_id,
- version=version
- ), 'utf-8'
+ mock_run_maven_step.side_effect = self.__create_run_maven_side_effect(
+ surefire_reports_dir=surefire_reports_dir
)
- self.__run__run_step_test(
- test_dir=test_dir,
- mvn_mock=mvn_mock,
- selenium_hub_url='https://test.xyz:4444',
- write_effective_pom_mock=write_effective_pom_mock,
- generate_maven_settings_mock=generate_maven_settings_mock,
- aggregate_xml_element_attribute_values_mock=aggregate_xml_element_attribute_values_mock,
- pom_content=pom_content,
- group_id=group_id,
- artifact_id=artifact_id,
+ # run step
+ actual_step_result = step_implementer._run_step()
+
+ # create expected step result
+ cucumber_html_report_path = os.path.join(parent_work_dir_path, 'uat', 'cucumber.html')
+ cucumber_json_report_path = os.path.join(parent_work_dir_path, 'uat', 'cucumber.json')
+ expected_step_result = self.__expected_step_result_with_artifacts_and_evidence(
+ parent_work_dir_path=parent_work_dir_path,
surefire_reports_dir=surefire_reports_dir
)
- @patch('ploigos_step_runner.step_implementers.uat.maven_selenium_cucumber.aggregate_xml_element_attribute_values')
- @patch.object(MavenSeleniumCucumber, '_generate_maven_settings')
- @patch('sh.mvn', create=True)
- @patch('ploigos_step_runner.step_implementers.shared.maven_generic.write_effective_pom')
- def test__run_step_tls_verify_false(
- self,
- write_effective_pom_mock,
- mvn_mock,
- generate_maven_settings_mock,
- aggregate_xml_element_attribute_values_mock
- ):
- with TempDirectory() as test_dir:
- group_id = 'com.mycompany.app'
- artifact_id = 'my-app'
- version = '1.0'
- surefire_reports_dir = os.path.join(test_dir.path, 'target/surefire-reports')
- pom_content = bytes(
-'''
- 4.0.0
- {group_id}
- {artifact_id}
- {version}
-
- 1.8
- 1.8
-
-
-
-
- maven-surefire-plugin
- ${{surefire-plugin.version}}
-
-
-
-'''.format(
- group_id=group_id,
- artifact_id=artifact_id,
- version=version
- ), 'utf-8'
+ # verify step result
+ self.assertEqual(
+ actual_step_result,
+ expected_step_result
)
- self.__run__run_step_test(
- test_dir=test_dir,
- mvn_mock=mvn_mock,
- selenium_hub_url='https://test.xyz:4444',
- write_effective_pom_mock=write_effective_pom_mock,
- generate_maven_settings_mock=generate_maven_settings_mock,
- aggregate_xml_element_attribute_values_mock=aggregate_xml_element_attribute_values_mock,
- pom_content=pom_content,
- group_id=group_id,
- artifact_id=artifact_id,
- surefire_reports_dir=surefire_reports_dir,
- set_tls_verify_false=True
+ mock_write_working_file.assert_called_once()
+ mock_run_maven_step.assert_called_with(
+ mvn_output_file_path='/mock/mvn_output.txt',
+ step_implementer_additional_arguments=[
+ f'-Dselenium.hub.url={selenium_hub_url}',
+ f'-Dtarget.base.url={target_base_url}',
+ f'-Dcucumber.plugin=' \
+ f'html:{cucumber_html_report_path},' \
+ f'json:{cucumber_json_report_path}',
+ ]
)
- @patch('ploigos_step_runner.step_implementers.uat.maven_selenium_cucumber.aggregate_xml_element_attribute_values')
- @patch.object(MavenSeleniumCucumber, '_generate_maven_settings')
- @patch('sh.mvn', create=True)
- @patch('ploigos_step_runner.step_implementers.shared.maven_generic.write_effective_pom')
- def test__run_step_success__deployed_host_urls_str(
+ @patch.object(
+ MavenSeleniumCucumber,
+ '_get_effective_pom_element',
+ side_effect=['mock surefire element', None]
+ )
+ def test_success_multiple_deployed_host_url_default_reports_dir(
self,
- write_effective_pom_mock,
- mvn_mock,
- generate_maven_settings_mock,
- aggregate_xml_element_attribute_values_mock
+ mock_effective_pom_element,
+ mock_aggregate_xml_element_attribute_values,
+ mock_write_working_file,
+ mock_run_maven_step
):
with TempDirectory() as test_dir:
- group_id = 'com.mycompany.app'
- artifact_id = 'my-app'
- version = '1.0'
+ parent_work_dir_path = os.path.join(test_dir.path, 'working')
+
+ pom_file = os.path.join(test_dir.path, 'mock-pom.xml')
+ selenium_hub_url = 'https://mock-selenium-hub.ploigos.com'
+ target_base_url = 'https://mock-app.ploigos.com'
+ deployed_host_urls = [target_base_url, 'https://mock-app-ignored.ploigos.com']
+ step_config = {
+ 'pom-file': pom_file,
+ 'selenium-hub-url': selenium_hub_url,
+ 'deployed-host-urls': deployed_host_urls
+ }
+ step_implementer = self.create_step_implementer(
+ step_config=step_config,
+ parent_work_dir_path=parent_work_dir_path,
+ )
+
+ # setup sideeffects
surefire_reports_dir = os.path.join(test_dir.path, 'target/surefire-reports')
- pom_content = bytes(
-'''
- 4.0.0
- {group_id}
- {artifact_id}
- {version}
-
- 1.8
- 1.8
-
-
-
-
- maven-surefire-plugin
- ${{surefire-plugin.version}}
-
-
-
-'''.format(
- group_id=group_id,
- artifact_id=artifact_id,
- version=version
- ), 'utf-8'
+ mock_run_maven_step.side_effect = self.__create_run_maven_side_effect(
+ surefire_reports_dir=surefire_reports_dir
)
- deployed_host_urls = 'https://foo.ploigos.xyz'
- self.__run__run_step_test(
- test_dir=test_dir,
- mvn_mock=mvn_mock,
- selenium_hub_url='https://test.xyz:4444',
- write_effective_pom_mock=write_effective_pom_mock,
- generate_maven_settings_mock=generate_maven_settings_mock,
- aggregate_xml_element_attribute_values_mock=aggregate_xml_element_attribute_values_mock,
- pom_content=pom_content,
- group_id=group_id,
- artifact_id=artifact_id,
- surefire_reports_dir=surefire_reports_dir,
- deployed_host_urls=deployed_host_urls
+ # run step
+ actual_step_result = step_implementer._run_step()
+
+ # create expected step result
+ cucumber_html_report_path = os.path.join(parent_work_dir_path, 'uat', 'cucumber.html')
+ cucumber_json_report_path = os.path.join(parent_work_dir_path, 'uat', 'cucumber.json')
+ expected_step_result = self.__expected_step_result_with_artifacts_and_evidence(
+ parent_work_dir_path=parent_work_dir_path,
+ surefire_reports_dir=surefire_reports_dir
)
+ expected_step_result.message = \
+ f"Given more then one deployed host URL ({deployed_host_urls})," \
+ f" targeting first one ({target_base_url}) for user acceptance test (UAT)."
- @patch('ploigos_step_runner.step_implementers.uat.maven_selenium_cucumber.aggregate_xml_element_attribute_values')
- @patch.object(MavenSeleniumCucumber, '_generate_maven_settings')
- @patch('sh.mvn', create=True)
- @patch('ploigos_step_runner.step_implementers.shared.maven_generic.write_effective_pom')
- def test__run_step_success__deployed_host_urls_array_1(
- self,
- write_effective_pom_mock,
- mvn_mock,
- generate_maven_settings_mock,
- aggregate_xml_element_attribute_values_mock
- ):
- with TempDirectory() as test_dir:
- group_id = 'com.mycompany.app'
- artifact_id = 'my-app'
- version = '1.0'
- surefire_reports_dir = os.path.join(test_dir.path, 'target/surefire-reports')
- pom_content = bytes(
-'''
- 4.0.0
- {group_id}
- {artifact_id}
- {version}
-
- 1.8
- 1.8
-
-
-
-
- maven-surefire-plugin
- ${{surefire-plugin.version}}
-
-
-
-'''.format(
- group_id=group_id,
- artifact_id=artifact_id,
- version=version
- ), 'utf-8'
+ # verify step result
+ self.assertEqual(
+ actual_step_result,
+ expected_step_result
)
- deployed_host_urls = ['https://foo.ploigos.xyz']
- self.__run__run_step_test(
- test_dir=test_dir,
- mvn_mock=mvn_mock,
- selenium_hub_url='https://test.xyz:4444',
- write_effective_pom_mock=write_effective_pom_mock,
- generate_maven_settings_mock=generate_maven_settings_mock,
- aggregate_xml_element_attribute_values_mock=aggregate_xml_element_attribute_values_mock,
- pom_content=pom_content,
- group_id=group_id,
- artifact_id=artifact_id,
- surefire_reports_dir=surefire_reports_dir,
- deployed_host_urls=deployed_host_urls
+ mock_write_working_file.assert_called_once()
+ mock_run_maven_step.assert_called_with(
+ mvn_output_file_path='/mock/mvn_output.txt',
+ step_implementer_additional_arguments=[
+ f'-Dselenium.hub.url={selenium_hub_url}',
+ f'-Dtarget.base.url={target_base_url}',
+ f'-Dcucumber.plugin=' \
+ f'html:{cucumber_html_report_path},' \
+ f'json:{cucumber_json_report_path}',
+ ]
)
- @patch('ploigos_step_runner.step_implementers.uat.maven_selenium_cucumber.aggregate_xml_element_attribute_values')
- @patch.object(MavenSeleniumCucumber, '_generate_maven_settings')
- @patch('sh.mvn', create=True)
- @patch('ploigos_step_runner.step_implementers.shared.maven_generic.write_effective_pom')
- def test__run_step_success__deployed_host_urls_array_2(
+ @patch.object(
+ MavenSeleniumCucumber,
+ '_get_effective_pom_element',
+ side_effect=['mock surefire element', Mock(text='mock/fake/reports')]
+ )
+ def test_success_target_host_url_pom_specified_relative_reports_dir(
self,
- write_effective_pom_mock,
- mvn_mock,
- generate_maven_settings_mock,
- aggregate_xml_element_attribute_values_mock,
+ mock_effective_pom_element,
+ mock_aggregate_xml_element_attribute_values,
+ mock_write_working_file,
+ mock_run_maven_step
):
with TempDirectory() as test_dir:
- group_id = 'com.mycompany.app'
- artifact_id = 'my-app'
- version = '1.0'
- surefire_reports_dir = os.path.join(test_dir.path, 'target/surefire-reports')
- pom_content = bytes(
-'''
- 4.0.0
- {group_id}
- {artifact_id}
- {version}
-
- 1.8
- 1.8
-
-
-
-
- maven-surefire-plugin
- ${{surefire-plugin.version}}
-
-
-
-'''.format(
- group_id=group_id,
- artifact_id=artifact_id,
- version=version
- ), 'utf-8'
+ parent_work_dir_path = os.path.join(test_dir.path, 'working')
+
+ pom_file = os.path.join(test_dir.path, 'mock-pom.xml')
+ selenium_hub_url = 'https://mock-selenium-hub.ploigos.com'
+ target_base_url = 'https://mock-app.ploigos.com'
+ step_config = {
+ 'pom-file': pom_file,
+ 'selenium-hub-url': selenium_hub_url,
+ 'target-host-url': target_base_url
+ }
+ step_implementer = self.create_step_implementer(
+ step_config=step_config,
+ parent_work_dir_path=parent_work_dir_path,
)
- deployed_host_urls = ['https://foo.ploigos.xyz', 'https://foo.ploigos.xyz']
- self.__run__run_step_test(
- test_dir=test_dir,
- mvn_mock=mvn_mock,
- selenium_hub_url='https://test.xyz:4444',
- write_effective_pom_mock=write_effective_pom_mock,
- generate_maven_settings_mock=generate_maven_settings_mock,
- aggregate_xml_element_attribute_values_mock=aggregate_xml_element_attribute_values_mock,
- pom_content=pom_content,
- group_id=group_id,
- artifact_id=artifact_id,
- surefire_reports_dir=surefire_reports_dir,
- deployed_host_urls=deployed_host_urls,
- expected_result_message=\
- f"Given more then one deployed host URL ({deployed_host_urls})," \
- f" targeting first one (https://foo.ploigos.xyz) for user acceptance test (UAT)."
+ # setup sideeffects
+ surefire_reports_dir = os.path.join(test_dir.path, 'mock/fake/reports')
+ mock_run_maven_step.side_effect = self.__create_run_maven_side_effect(
+ surefire_reports_dir=surefire_reports_dir
)
- @patch('ploigos_step_runner.step_implementers.uat.maven_selenium_cucumber.aggregate_xml_element_attribute_values')
- @patch.object(MavenSeleniumCucumber, '_generate_maven_settings')
- @patch('sh.mvn', create=True)
- @patch('ploigos_step_runner.step_implementers.shared.maven_generic.write_effective_pom')
- def test__run_step_success_provided_profile_override(
- self,
- write_effective_pom_mock,
- mvn_mock,
- generate_maven_settings_mock,
- aggregate_xml_element_attribute_values_mock
- ):
- with TempDirectory() as test_dir:
- group_id = 'com.mycompany.app'
- artifact_id = 'my-app'
- version = '1.0'
- surefire_reports_dir = os.path.join(test_dir.path, 'target/surefire-reports')
- pom_content = bytes(
-'''
- 4.0.0
- {group_id}
- {artifact_id}
- {version}
-
- 1.8
- 1.8
-
-
-
-
- maven-surefire-plugin
- ${{surefire-plugin.version}}
-
-
-
-'''.format(
- group_id=group_id,
- artifact_id=artifact_id,
- version=version
- ), 'utf-8'
+ # run step
+ actual_step_result = step_implementer._run_step()
+
+ # create expected step result
+ cucumber_html_report_path = os.path.join(parent_work_dir_path, 'uat', 'cucumber.html')
+ cucumber_json_report_path = os.path.join(parent_work_dir_path, 'uat', 'cucumber.json')
+ expected_step_result = self.__expected_step_result_with_artifacts_and_evidence(
+ parent_work_dir_path=parent_work_dir_path,
+ surefire_reports_dir=surefire_reports_dir
+ )
+
+ # verify step result
+ self.assertEqual(
+ actual_step_result,
+ expected_step_result
)
- self.__run__run_step_test(
- test_dir=test_dir,
- mvn_mock=mvn_mock,
- selenium_hub_url='https://test.xyz:4444',
- write_effective_pom_mock=write_effective_pom_mock,
- generate_maven_settings_mock=generate_maven_settings_mock,
- aggregate_xml_element_attribute_values_mock=aggregate_xml_element_attribute_values_mock,
- pom_content=pom_content,
- group_id=group_id,
- artifact_id=artifact_id,
- surefire_reports_dir=surefire_reports_dir,
- uat_maven_profile='custom-uat-profile'
+ mock_write_working_file.assert_called_once()
+ mock_run_maven_step.assert_called_with(
+ mvn_output_file_path='/mock/mvn_output.txt',
+ step_implementer_additional_arguments=[
+ f'-Dselenium.hub.url={selenium_hub_url}',
+ f'-Dtarget.base.url={target_base_url}',
+ f'-Dcucumber.plugin=' \
+ f'html:{cucumber_html_report_path},' \
+ f'json:{cucumber_json_report_path}',
+ ]
)
- @patch('ploigos_step_runner.step_implementers.uat.maven_selenium_cucumber.aggregate_xml_element_attribute_values')
- @patch.object(MavenSeleniumCucumber, '_generate_maven_settings')
- @patch('sh.mvn', create=True)
- @patch('ploigos_step_runner.step_implementers.shared.maven_generic.write_effective_pom')
- def test__run_step_success_provided_pom_file_override(
+ @patch.object(MavenSeleniumCucumber, '_get_effective_pom_element')
+ def test_success_target_host_url_pom_specified_absolute_reports_dir(
self,
- write_effective_pom_mock,
- mvn_mock,
- generate_maven_settings_mock,
- aggregate_xml_element_attribute_values_mock
+ mock_effective_pom_element,
+ mock_aggregate_xml_element_attribute_values,
+ mock_write_working_file,
+ mock_run_maven_step
):
with TempDirectory() as test_dir:
- group_id = 'com.mycompany.app'
- artifact_id = 'my-app'
- version = '1.0'
- surefire_reports_dir = os.path.join(test_dir.path, 'target/surefire-reports')
- pom_content = bytes(
-'''
- 4.0.0
- {group_id}
- {artifact_id}
- {version}
-
- 1.8
- 1.8
-
-
-
-
- maven-surefire-plugin
- ${{surefire-plugin.version}}
-
-
-
-'''.format(
- group_id=group_id,
- artifact_id=artifact_id,
- version=version
- ), 'utf-8'
+ parent_work_dir_path = os.path.join(test_dir.path, 'working')
+
+ pom_file = os.path.join(test_dir.path, 'mock-pom.xml')
+ selenium_hub_url = 'https://mock-selenium-hub.ploigos.com'
+ target_base_url = 'https://mock-app.ploigos.com'
+ step_config = {
+ 'pom-file': pom_file,
+ 'selenium-hub-url': selenium_hub_url,
+ 'target-host-url': target_base_url
+ }
+ step_implementer = self.create_step_implementer(
+ step_config=step_config,
+ parent_work_dir_path=parent_work_dir_path,
)
- self.__run__run_step_test(
- test_dir=test_dir,
- mvn_mock=mvn_mock,
- selenium_hub_url='https://test.xyz:4444',
- write_effective_pom_mock=write_effective_pom_mock,
- generate_maven_settings_mock=generate_maven_settings_mock,
- aggregate_xml_element_attribute_values_mock=aggregate_xml_element_attribute_values_mock,
- pom_content=pom_content,
- group_id=group_id,
- artifact_id=artifact_id,
- surefire_reports_dir=surefire_reports_dir,
- pom_file_name='custom-pom.xml'
+ # setup sideeffects
+ surefire_reports_dir = os.path.join(test_dir.path, 'mock-abs/fake/reports')
+ mock_effective_pom_element.side_effect = [
+ 'mock surefire element',
+ Mock(text=surefire_reports_dir)
+ ]
+ mock_run_maven_step.side_effect = self.__create_run_maven_side_effect(
+ surefire_reports_dir=surefire_reports_dir
)
- @patch('ploigos_step_runner.step_implementers.uat.maven_selenium_cucumber.aggregate_xml_element_attribute_values')
- @patch.object(MavenSeleniumCucumber, '_generate_maven_settings')
- @patch('sh.mvn', create=True)
- @patch('ploigos_step_runner.step_implementers.shared.maven_generic.write_effective_pom')
- def test__run_step_success_provided_fail_on_no_tests_false_with_tests(
- self,
- write_effective_pom_mock,
- mvn_mock,
- generate_maven_settings_mock,
- aggregate_xml_element_attribute_values_mock
- ):
- with TempDirectory() as test_dir:
- group_id = 'com.mycompany.app'
- artifact_id = 'my-app'
- version = '1.0'
- surefire_reports_dir = os.path.join(test_dir.path, 'target/surefire-reports')
- pom_content = bytes(
-'''
- 4.0.0
- {group_id}
- {artifact_id}
- {version}
-
- 1.8
- 1.8
-
-
-
-
- maven-surefire-plugin
- ${{surefire-plugin.version}}
-
-
-
-'''.format(
- group_id=group_id,
- artifact_id=artifact_id,
- version=version
- ), 'utf-8'
+ # run step
+ actual_step_result = step_implementer._run_step()
+
+ # create expected step result
+ cucumber_html_report_path = os.path.join(parent_work_dir_path, 'uat', 'cucumber.html')
+ cucumber_json_report_path = os.path.join(parent_work_dir_path, 'uat', 'cucumber.json')
+ expected_step_result = self.__expected_step_result_with_artifacts_and_evidence(
+ parent_work_dir_path=parent_work_dir_path,
+ surefire_reports_dir=surefire_reports_dir
+ )
+
+ # verify step result
+ self.assertEqual(
+ actual_step_result,
+ expected_step_result
)
- self.__run__run_step_test(
- test_dir=test_dir,
- mvn_mock=mvn_mock,
- selenium_hub_url='https://test.xyz:4444',
- write_effective_pom_mock=write_effective_pom_mock,
- generate_maven_settings_mock=generate_maven_settings_mock,
- aggregate_xml_element_attribute_values_mock=aggregate_xml_element_attribute_values_mock,
- pom_content=pom_content,
- group_id=group_id,
- artifact_id=artifact_id,
- surefire_reports_dir=surefire_reports_dir,
- fail_on_no_tests=False,
- write_mock_test_results=True,
- expected_result_success=True
+ mock_write_working_file.assert_called_once()
+ mock_run_maven_step.assert_called_with(
+ mvn_output_file_path='/mock/mvn_output.txt',
+ step_implementer_additional_arguments=[
+ f'-Dselenium.hub.url={selenium_hub_url}',
+ f'-Dtarget.base.url={target_base_url}',
+ f'-Dcucumber.plugin=' \
+ f'html:{cucumber_html_report_path},' \
+ f'json:{cucumber_json_report_path}',
+ ]
)
- @patch('ploigos_step_runner.step_implementers.uat.maven_selenium_cucumber.aggregate_xml_element_attribute_values')
- @patch.object(MavenSeleniumCucumber, '_generate_maven_settings')
- @patch('sh.mvn', create=True)
- @patch('ploigos_step_runner.step_implementers.shared.maven_generic.write_effective_pom')
- def test__run_step_success_provided_fail_on_no_tests_false_with_no_tests(
+ @patch.object(MavenSeleniumCucumber, '_get_effective_pom_element', side_effect=[None, None])
+ @patch.object(MavenSeleniumCucumber, '_get_effective_pom', return_value='mock-effective-pom.xml')
+ def test_fail_no_surefire_plugin(
self,
- write_effective_pom_mock,
- mvn_mock,
- generate_maven_settings_mock,
- aggregate_xml_element_attribute_values_mock
+ mock_effective_pom,
+ mock_effective_pom_element,
+ mock_aggregate_xml_element_attribute_values,
+ mock_write_working_file,
+ mock_run_maven_step
):
with TempDirectory() as test_dir:
- group_id = 'com.mycompany.app'
- artifact_id = 'my-app'
- version = '1.0'
+ parent_work_dir_path = os.path.join(test_dir.path, 'working')
+
+ pom_file = os.path.join(test_dir.path, 'mock-pom.xml')
+ selenium_hub_url = 'https://mock-selenium-hub.ploigos.com'
+ target_base_url = 'https://mock-app.ploigos.com'
+ step_config = {
+ 'pom-file': pom_file,
+ 'selenium-hub-url': selenium_hub_url,
+ 'target-host-url': target_base_url
+ }
+ step_implementer = self.create_step_implementer(
+ step_config=step_config,
+ parent_work_dir_path=parent_work_dir_path,
+ )
+
+ # setup sideeffects
surefire_reports_dir = os.path.join(test_dir.path, 'target/surefire-reports')
- pom_content = bytes(
-'''
- 4.0.0
- {group_id}
- {artifact_id}
- {version}
-
- 1.8
- 1.8
-
-
-
-
- maven-surefire-plugin
- ${{surefire-plugin.version}}
-
-
-
-'''.format(
- group_id=group_id,
- artifact_id=artifact_id,
- version=version
- ), 'utf-8'
+ mock_run_maven_step.side_effect = self.__create_run_maven_side_effect(
+ surefire_reports_dir=surefire_reports_dir
)
- self.__run__run_step_test(
- test_dir=test_dir,
- mvn_mock=mvn_mock,
- selenium_hub_url='https://test.xyz:4444',
- write_effective_pom_mock=write_effective_pom_mock,
- generate_maven_settings_mock=generate_maven_settings_mock,
- aggregate_xml_element_attribute_values_mock=aggregate_xml_element_attribute_values_mock,
- assert_evidence=False,
- pom_content=pom_content,
- group_id=group_id,
- artifact_id=artifact_id,
- surefire_reports_dir=surefire_reports_dir,
- fail_on_no_tests=False,
- write_mock_test_results=False,
- expected_result_success=True,
- expected_result_message="No user acceptance tests defined" \
- " using maven profile (integration-test)," \
- " but 'fail-on-no-tests' is False."
+ # run step
+ actual_step_result = step_implementer._run_step()
+
+ # create expected step result
+ expected_step_result = self.__expected_step_result_base()
+ expected_step_result.success = False
+ expected_step_result.message = 'Unit test dependency "maven-surefire-plugin" ' \
+ 'missing from effective pom (mock-effective-pom.xml).'
+
+ # verify step result
+ self.assertEqual(
+ actual_step_result,
+ expected_step_result
)
- @patch('ploigos_step_runner.step_implementers.uat.maven_selenium_cucumber.aggregate_xml_element_attribute_values')
- @patch.object(MavenSeleniumCucumber, '_generate_maven_settings')
- @patch('sh.mvn', create=True)
- @patch('ploigos_step_runner.step_implementers.shared.maven_generic.write_effective_pom')
- def test__run_step_fail_provided_fail_on_no_tests_true_with_no_tests(
+ mock_run_maven_step.assert_not_called()
+
+ @patch.object(
+ MavenSeleniumCucumber,
+ '_get_effective_pom_element',
+ side_effect=['mock surefire element', None]
+ )
+ def test_fail_no_tests(
self,
- write_effective_pom_mock,
- mvn_mock,
- generate_maven_settings_mock,
- aggregate_xml_element_attribute_values_mock
+ mock_effective_pom_element,
+ mock_aggregate_xml_element_attribute_values,
+ mock_write_working_file,
+ mock_run_maven_step
):
with TempDirectory() as test_dir:
- group_id = 'com.mycompany.app'
- artifact_id = 'my-app'
- version = '1.0'
+ parent_work_dir_path = os.path.join(test_dir.path, 'working')
+
+ pom_file = os.path.join(test_dir.path, 'mock-pom.xml')
+ selenium_hub_url = 'https://mock-selenium-hub.ploigos.com'
+ target_base_url = 'https://mock-app.ploigos.com'
+ step_config = {
+ 'pom-file': pom_file,
+ 'selenium-hub-url': selenium_hub_url,
+ 'target-host-url': target_base_url
+ }
+ step_implementer = self.create_step_implementer(
+ step_config=step_config,
+ parent_work_dir_path=parent_work_dir_path,
+ )
+
+ # run step
+ actual_step_result = step_implementer._run_step()
+
+ # create expected step result
surefire_reports_dir = os.path.join(test_dir.path, 'target/surefire-reports')
- pom_content = bytes(
-'''
- 4.0.0
- {group_id}
- {artifact_id}
- {version}
-
- 1.8
- 1.8
-
-
-
-
- maven-surefire-plugin
- ${{surefire-plugin.version}}
-
-
-
-'''.format(
- group_id=group_id,
- artifact_id=artifact_id,
- version=version
- ), 'utf-8'
+ cucumber_html_report_path = os.path.join(parent_work_dir_path, 'uat', 'cucumber.html')
+ cucumber_json_report_path = os.path.join(parent_work_dir_path, 'uat', 'cucumber.json')
+ expected_step_result = self.__expected_step_result_with_artifacts(
+ parent_work_dir_path=parent_work_dir_path,
+ surefire_reports_dir=surefire_reports_dir
)
+ expected_step_result.success = False
+ expected_step_result.message = "No user acceptance tests defined" \
+ f" using maven profile (['integration-test'])."
- self.__run__run_step_test(
- test_dir=test_dir,
- mvn_mock=mvn_mock,
- selenium_hub_url='https://test.xyz:4444',
- write_effective_pom_mock=write_effective_pom_mock,
- generate_maven_settings_mock=generate_maven_settings_mock,
- aggregate_xml_element_attribute_values_mock=aggregate_xml_element_attribute_values_mock,
- assert_evidence=False,
- pom_content=pom_content,
- group_id=group_id,
- artifact_id=artifact_id,
- surefire_reports_dir=surefire_reports_dir,
- fail_on_no_tests=True,
- write_mock_test_results=False,
- expected_result_success=False,
- expected_result_message="No user acceptance tests defined" \
- " using maven profile (integration-test)."
+ # verify step result
+ self.assertEqual(
+ actual_step_result,
+ expected_step_result
)
- @patch('ploigos_step_runner.step_implementers.uat.maven_selenium_cucumber.aggregate_xml_element_attribute_values')
- @patch.object(MavenSeleniumCucumber, '_generate_maven_settings')
- @patch('sh.mvn', create=True)
- @patch('ploigos_step_runner.step_implementers.shared.maven_generic.write_effective_pom')
- def test__run_step_fail_no_surefire_plugin(
+ mock_write_working_file.assert_called_once()
+ mock_run_maven_step.assert_called_with(
+ mvn_output_file_path='/mock/mvn_output.txt',
+ step_implementer_additional_arguments=[
+ f'-Dselenium.hub.url={selenium_hub_url}',
+ f'-Dtarget.base.url={target_base_url}',
+ f'-Dcucumber.plugin=' \
+ f'html:{cucumber_html_report_path},' \
+ f'json:{cucumber_json_report_path}',
+ ]
+ )
+
+ @patch.object(
+ MavenSeleniumCucumber,
+ '_get_effective_pom_element',
+ side_effect=['mock surefire element', None]
+ )
+ def test_success_but_no_tests(
self,
- write_effective_pom_mock,
- mvn_mock,
- generate_maven_settings_mock,
- aggregate_xml_element_attribute_values_mock
+ mock_effective_pom_element,
+ mock_aggregate_xml_element_attribute_values,
+ mock_write_working_file,
+ mock_run_maven_step
):
with TempDirectory() as test_dir:
- group_id = 'com.mycompany.app'
- artifact_id = 'my-app'
- version = '1.0'
+ parent_work_dir_path = os.path.join(test_dir.path, 'working')
+
+ pom_file = os.path.join(test_dir.path, 'mock-pom.xml')
+ selenium_hub_url = 'https://mock-selenium-hub.ploigos.com'
+ target_base_url = 'https://mock-app.ploigos.com'
+ step_config = {
+ 'pom-file': pom_file,
+ 'selenium-hub-url': selenium_hub_url,
+ 'target-host-url': target_base_url,
+ 'fail-on-no-tests': False
+ }
+ step_implementer = self.create_step_implementer(
+ step_config=step_config,
+ parent_work_dir_path=parent_work_dir_path,
+ )
+
+ # run step
+ actual_step_result = step_implementer._run_step()
+
+ # create expected step result
surefire_reports_dir = os.path.join(test_dir.path, 'target/surefire-reports')
- pom_content = bytes(
-'''
- 4.0.0
- {group_id}
- {artifact_id}
- {version}
-
- 1.8
- 1.8
-
-
-
-
-
-'''.format(
- group_id=group_id,
- artifact_id=artifact_id,
- version=version
- ), 'utf-8'
+ cucumber_html_report_path = os.path.join(parent_work_dir_path, 'uat', 'cucumber.html')
+ cucumber_json_report_path = os.path.join(parent_work_dir_path, 'uat', 'cucumber.json')
+ expected_step_result = self.__expected_step_result_with_artifacts(
+ parent_work_dir_path=parent_work_dir_path,
+ surefire_reports_dir=surefire_reports_dir
)
+ expected_step_result.message = "No user acceptance tests defined" \
+ " using maven profile (['integration-test'])," \
+ " but 'fail-on-no-tests' is False."
- effective_pom_path = os.path.join(
- test_dir.path,
- 'working',
- 'uat',
- 'effective-pom.xml'
+ # verify step result
+ self.assertEqual(
+ actual_step_result,
+ expected_step_result
)
- self.__run__run_step_test(
- test_dir=test_dir,
- mvn_mock=mvn_mock,
- selenium_hub_url='https://test.xyz:4444',
- write_effective_pom_mock=write_effective_pom_mock,
- generate_maven_settings_mock=generate_maven_settings_mock,
- aggregate_xml_element_attribute_values_mock=aggregate_xml_element_attribute_values_mock,
- assert_evidence=False,
- pom_content=pom_content,
- group_id=group_id,
- artifact_id=artifact_id,
- surefire_reports_dir=surefire_reports_dir,
- expected_result_success=False,
- expected_result_message='Unit test dependency "maven-surefire-plugin" ' \
- f'missing from effective pom ({effective_pom_path}).',
- assert_mvn_called=False,
- assert_report_artifact=False
+
+ mock_write_working_file.assert_called_once()
+ mock_run_maven_step.assert_called_with(
+ mvn_output_file_path='/mock/mvn_output.txt',
+ step_implementer_additional_arguments=[
+ f'-Dselenium.hub.url={selenium_hub_url}',
+ f'-Dtarget.base.url={target_base_url}',
+ f'-Dcucumber.plugin=' \
+ f'html:{cucumber_html_report_path},' \
+ f'json:{cucumber_json_report_path}',
+ ]
)
- @patch('ploigos_step_runner.step_implementers.uat.maven_selenium_cucumber.aggregate_xml_element_attribute_values')
- @patch.object(MavenSeleniumCucumber, '_generate_maven_settings')
- @patch('sh.mvn', create=True)
- @patch('ploigos_step_runner.step_implementers.shared.maven_generic.write_effective_pom')
- def test__run_step_success_pom_specified_reports_dir(
+ @patch.object(
+ MavenSeleniumCucumber,
+ '_get_effective_pom_element',
+ side_effect=['mock surefire element', None]
+ )
+ def test_could_not_find_expected_evidence(
self,
- write_effective_pom_mock,
- mvn_mock,
- generate_maven_settings_mock,
- aggregate_xml_element_attribute_values_mock
+ mock_effective_pom_element,
+ mock_aggregate_xml_element_attribute_values,
+ mock_write_working_file,
+ mock_run_maven_step
):
with TempDirectory() as test_dir:
- group_id = 'com.mycompany.app'
- artifact_id = 'my-app'
- version = '1.0'
+ parent_work_dir_path = os.path.join(test_dir.path, 'working')
+
+ pom_file = os.path.join(test_dir.path, 'mock-pom.xml')
+ selenium_hub_url = 'https://mock-selenium-hub.ploigos.com'
+ target_base_url = 'https://mock-app.ploigos.com'
+ step_config = {
+ 'pom-file': pom_file,
+ 'selenium-hub-url': selenium_hub_url,
+ 'target-host-url': target_base_url
+ }
+ step_implementer = self.create_step_implementer(
+ step_config=step_config,
+ parent_work_dir_path=parent_work_dir_path,
+ )
+
+ # setup sideeffects
surefire_reports_dir = os.path.join(test_dir.path, 'target/surefire-reports')
- pom_content = bytes(
-'''
- 4.0.0
- {group_id}
- {artifact_id}
- {version}
-
- 1.8
- 1.8
-
-
-
-
- maven-surefire-plugin
- ${{surefire-plugin.version}}
-
- {surefire_reports_dir}
-
-
-
-
-'''.format(
- group_id=group_id,
- artifact_id=artifact_id,
- version=version,
- surefire_reports_dir=surefire_reports_dir
- ), 'utf-8'
+ mock_run_maven_step.side_effect = self.__create_run_maven_side_effect(
+ surefire_reports_dir=surefire_reports_dir
)
+ mock_aggregate_xml_element_attribute_values.return_value = {}
+
+ # run step
+ actual_step_result = step_implementer._run_step()
- self.__run__run_step_test(
- test_dir=test_dir,
- mvn_mock=mvn_mock,
- selenium_hub_url='https://test.xyz:4444',
- write_effective_pom_mock=write_effective_pom_mock,
- generate_maven_settings_mock=generate_maven_settings_mock,
- aggregate_xml_element_attribute_values_mock=aggregate_xml_element_attribute_values_mock,
- assert_evidence=True,
- pom_content=pom_content,
- group_id=group_id,
- artifact_id=artifact_id,
+ # create expected step result
+ cucumber_html_report_path = os.path.join(parent_work_dir_path, 'uat', 'cucumber.html')
+ cucumber_json_report_path = os.path.join(parent_work_dir_path, 'uat', 'cucumber.json')
+ expected_step_result = self.__expected_step_result_with_artifacts(
+ parent_work_dir_path=parent_work_dir_path,
surefire_reports_dir=surefire_reports_dir
)
+ expected_step_result.success = False
+ attribs = ["time", "tests", "errors", "skipped", "failures"]
+ expected_step_result.message = "Error gathering evidence from "\
+ f"surefire report, expected attribute(s) ({attribs}) "\
+ f"not found in report ({surefire_reports_dir})"
- @patch('ploigos_step_runner.step_implementers.uat.maven_selenium_cucumber.aggregate_xml_element_attribute_values')
- @patch.object(MavenSeleniumCucumber, '_generate_maven_settings')
- @patch('sh.mvn', create=True)
- @patch('ploigos_step_runner.step_implementers.shared.maven_generic.write_effective_pom')
- def test__run_step_fail_mvn_test_failure(
- self,
- write_effective_pom_mock,
- mvn_mock,
- generate_maven_settings_mock,
- aggregate_xml_element_attribute_values_mock
- ):
- with TempDirectory() as test_dir:
- group_id = 'com.mycompany.app'
- artifact_id = 'my-app'
- version = '1.0'
- surefire_reports_dir = os.path.join(test_dir.path, 'target/surefire-reports')
- pom_content = bytes(
-'''
- 4.0.0
- {group_id}
- {artifact_id}
- {version}
-
- 1.8
- 1.8
-
-
-
-
- maven-surefire-plugin
- ${{surefire-plugin.version}}
-
-
-
-'''.format(
- group_id=group_id,
- artifact_id=artifact_id,
- version=version
- ), 'utf-8'
+ # verify step result
+ self.assertEqual(
+ actual_step_result,
+ expected_step_result
)
- self.__run__run_step_test(
- test_dir=test_dir,
- mvn_mock=mvn_mock,
- selenium_hub_url='https://test.xyz:4444',
- write_effective_pom_mock=write_effective_pom_mock,
- generate_maven_settings_mock=generate_maven_settings_mock,
- aggregate_xml_element_attribute_values_mock=None,
- assert_evidence=False,
- pom_content=pom_content,
- group_id=group_id,
- artifact_id=artifact_id,
- surefire_reports_dir=surefire_reports_dir,
- raise_error_on_tests=True,
- expected_result_success=False,
- expected_result_message="User acceptance test failures. See 'maven-output'" \
- ", 'surefire-reports', 'cucumber-report-html', and 'cucumber-report-json'" \
- " report artifacts for details."
+ mock_write_working_file.assert_called_once()
+ mock_run_maven_step.assert_called_with(
+ mvn_output_file_path='/mock/mvn_output.txt',
+ step_implementer_additional_arguments=[
+ f'-Dselenium.hub.url={selenium_hub_url}',
+ f'-Dtarget.base.url={target_base_url}',
+ f'-Dcucumber.plugin=' \
+ f'html:{cucumber_html_report_path},' \
+ f'json:{cucumber_json_report_path}',
+ ]
)
- @patch('ploigos_step_runner.step_implementers.uat.maven_selenium_cucumber.aggregate_xml_element_attribute_values')
- @patch.object(MavenSeleniumCucumber, '_generate_maven_settings')
- @patch('sh.mvn', create=True)
- @patch('ploigos_step_runner.step_implementers.shared.maven_generic.write_effective_pom')
- def test__run_step_failure_missing_evidence_attribute(
+ @patch.object(
+ MavenSeleniumCucumber,
+ '_get_effective_pom_element',
+ side_effect=['mock surefire element', None]
+ )
+ def test_fail_maven_error(
self,
- write_effective_pom_mock,
- mvn_mock,
- generate_maven_settings_mock,
- aggregate_xml_element_attribute_values_mock
+ mock_effective_pom_element,
+ mock_aggregate_xml_element_attribute_values,
+ mock_write_working_file,
+ mock_run_maven_step
):
with TempDirectory() as test_dir:
- group_id = 'com.mycompany.app'
- artifact_id = 'my-app'
- version = '1.0'
+ parent_work_dir_path = os.path.join(test_dir.path, 'working')
+
+ pom_file = os.path.join(test_dir.path, 'mock-pom.xml')
+ selenium_hub_url = 'https://mock-selenium-hub.ploigos.com'
+ target_base_url = 'https://mock-app.ploigos.com'
+ step_config = {
+ 'pom-file': pom_file,
+ 'selenium-hub-url': selenium_hub_url,
+ 'target-host-url': target_base_url
+ }
+ step_implementer = self.create_step_implementer(
+ step_config=step_config,
+ parent_work_dir_path=parent_work_dir_path,
+ )
+
+ # setup sideeffects
surefire_reports_dir = os.path.join(test_dir.path, 'target/surefire-reports')
- pom_content = bytes(
-'''
- 4.0.0
- {group_id}
- {artifact_id}
- {version}
-
- 1.8
- 1.8
-
-
-
-
- maven-surefire-plugin
- ${{surefire-plugin.version}}
-
-
-
-'''.format(
- group_id=group_id,
- artifact_id=artifact_id,
- version=version
- ), 'utf-8'
+ mock_run_maven_step.side_effect = StepRunnerException('mock maven error')
+
+ # run step
+ actual_step_result = step_implementer._run_step()
+
+ # create expected step result
+ cucumber_html_report_path = os.path.join(parent_work_dir_path, 'uat', 'cucumber.html')
+ cucumber_json_report_path = os.path.join(parent_work_dir_path, 'uat', 'cucumber.json')
+ expected_step_result = self.__expected_step_result_with_artifacts(
+ parent_work_dir_path=parent_work_dir_path,
+ surefire_reports_dir=surefire_reports_dir
+ )
+ expected_step_result.success = False
+ expected_step_result.message = "Error running 'maven test' to run user acceptance tests. " \
+ "More details maybe found in 'maven-output', `surefire-reports`, " \
+ "`cucumber-report-html`, and `cucumber-report-json` " \
+ "report artifact: mock maven error"
+
+ # verify step result
+ self.assertEqual(
+ actual_step_result,
+ expected_step_result
+ )
+
+ mock_write_working_file.assert_called_once()
+ mock_run_maven_step.assert_called_with(
+ mvn_output_file_path='/mock/mvn_output.txt',
+ step_implementer_additional_arguments=[
+ f'-Dselenium.hub.url={selenium_hub_url}',
+ f'-Dtarget.base.url={target_base_url}',
+ f'-Dcucumber.plugin=' \
+ f'html:{cucumber_html_report_path},' \
+ f'json:{cucumber_json_report_path}',
+ ]
)
- self.__run__run_step_test(
- test_dir=test_dir,
- mvn_mock=mvn_mock,
- selenium_hub_url='https://test.xyz:4444',
- write_effective_pom_mock=write_effective_pom_mock,
- generate_maven_settings_mock=generate_maven_settings_mock,
- aggregate_xml_element_attribute_values_mock=aggregate_xml_element_attribute_values_mock,
- aggregate_xml_element_attribute_values_mock_fail=True,
- assert_evidence=True,
- pom_content=pom_content,
- group_id=group_id,
- artifact_id=artifact_id,
- surefire_reports_dir=surefire_reports_dir,
- expected_result_success=False,
- expected_result_message="Error gathering evidence from "\
- "surefire report, expected attribute tests "\
- "not found in report " + surefire_reports_dir)
+# class TestStepImplementerMavenSeleniumCucumberBase(MaveStepImplementerTestCase):
+# def create_step_implementer(
+# self,
+# step_config={},
+# parent_work_dir_path=''
+# ):
+# return self.create_given_step_implementer(
+# step_implementer=MavenSeleniumCucumber,
+# step_config=step_config,
+# step_name='uat',
+# implementer='MavenSeleniumCucumber',
+# parent_work_dir_path=parent_work_dir_path
+# )
+
+# class TestStepImplementerDeployMavenSeleniumCucumber_validate_required_config_or_previous_step_result_artifact_keys(
+# TestStepImplementerMavenSeleniumCucumberBase
+# ):
+# def test_MavenSeleniumCucumber_validate_required_config_or_previous_step_result_artifact_keys_success_target_host_url(self):
+# with TempDirectory() as temp_dir:
+# parent_work_dir_path = os.path.join(temp_dir.path, 'working')
+
+# pom_file_path = os.path.join(temp_dir.path, 'pom.xml')
+# Path(pom_file_path).touch()
+# step_config = {
+# 'selenium-hub-url': 'https://selenium.ploigos.xyz',
+# 'pom-file': pom_file_path,
+# 'target-host-url': 'https://foo.test.ploigos.xyz'
+# }
+# step_implementer = self.create_step_implementer(
+# step_config=step_config,
+# parent_work_dir_path=parent_work_dir_path,
+# )
+
+# step_implementer._validate_required_config_or_previous_step_result_artifact_keys()
+
+# def test_MavenSeleniumCucumber_validate_required_config_or_previous_step_result_artifact_keys_success_deployed_host_urls_1(self):
+# with TempDirectory() as temp_dir:
+# parent_work_dir_path = os.path.join(temp_dir.path, 'working')
+
+# pom_file_path = os.path.join(temp_dir.path, 'pom.xml')
+# Path(pom_file_path).touch()
+# step_config = {
+# 'selenium-hub-url': 'https://selenium.ploigos.xyz',
+# 'pom-file': pom_file_path,
+# 'deployed-host-urls': ['https://foo.test.ploigos.xyz']
+# }
+# step_implementer = self.create_step_implementer(
+# step_config=step_config,
+# parent_work_dir_path=parent_work_dir_path,
+# )
+
+# step_implementer._validate_required_config_or_previous_step_result_artifact_keys()
+
+# def test_MavenSeleniumCucumber_validate_required_config_or_previous_step_result_artifact_keys_success_deployed_host_urls_2(self):
+# with TempDirectory() as temp_dir:
+# parent_work_dir_path = os.path.join(temp_dir.path, 'working')
+
+# pom_file_path = os.path.join(temp_dir.path, 'pom.xml')
+# Path(pom_file_path).touch()
+# step_config = {
+# 'selenium-hub-url': 'https://selenium.ploigos.xyz',
+# 'pom-file': pom_file_path,
+# 'deployed-host-urls': ['https://foo.test.ploigos.xyz', 'https://bar.test.ploigos.xyz']
+# }
+# step_implementer = self.create_step_implementer(
+# step_config=step_config,
+# parent_work_dir_path=parent_work_dir_path,
+# )
+
+# step_implementer._validate_required_config_or_previous_step_result_artifact_keys()
+
+# def test_MavenSeleniumCucumber_validate_required_config_or_previous_step_result_artifact_keys_fail_no_target_urls(self):
+# with TempDirectory() as temp_dir:
+# parent_work_dir_path = os.path.join(temp_dir.path, 'working')
+
+# pom_file_path = os.path.join(temp_dir.path, 'pom.xml')
+# Path(pom_file_path).touch()
+# step_config = {
+# 'selenium-hub-url': 'https://selenium.ploigos.xyz',
+# 'pom-file': pom_file_path
+# }
+# step_implementer = self.create_step_implementer(
+# step_config=step_config,
+# parent_work_dir_path=parent_work_dir_path,
+# )
+
+# with self.assertRaisesRegex(
+# StepRunnerException,
+# rf"Either 'target-host-url' or 'deployed-host-urls' needs to be supplied but"
+# " neither were."
+# ):
+# step_implementer._validate_required_config_or_previous_step_result_artifact_keys()
+
+# class TestStepImplementerMavenSeleniumCucumber_Other(TestStepImplementerMavenSeleniumCucumberBase):
+# def test_step_implementer_config_defaults(self):
+# actual_defaults = MavenSeleniumCucumber.step_implementer_config_defaults()
+# expected_defaults = {
+# 'fail-on-no-tests': True,
+# 'pom-file': 'pom.xml',
+# 'tls-verify': True,
+# 'uat-maven-profile': 'integration-test'
+# }
+# self.assertEqual(expected_defaults, actual_defaults)
+
+# def test__required_config_or_result_keys(self):
+# actual_required_keys = MavenSeleniumCucumber._required_config_or_result_keys()
+# expected_required_keys = [
+# 'fail-on-no-tests',
+# 'pom-file',
+# 'selenium-hub-url',
+# 'uat-maven-profile'
+# ]
+# self.assertEqual(expected_required_keys, actual_required_keys)
+
+# def __run__run_step_test(
+# self,
+# test_dir,
+# mvn_mock,
+# write_effective_pom_mock,
+# generate_maven_settings_mock,
+# pom_content,
+# group_id,
+# artifact_id,
+# surefire_reports_dir,
+# selenium_hub_url,
+# target_host_url=None,
+# deployed_host_urls=None,
+# write_mock_test_results=True,
+# assert_mvn_called=True,
+# assert_report_artifact=True,
+# assert_evidence=True,
+# expected_result_success=True,
+# expected_result_message='',
+# fail_on_no_tests=None,
+# uat_maven_profile=None,
+# pom_file_name='pom.xml',
+# raise_error_on_tests=False,
+# set_tls_verify_false=False,
+# aggregate_xml_element_attribute_values_mock=False,
+# aggregate_xml_element_attribute_values_mock_fail=False
+# ):
+# parent_work_dir_path = os.path.join(test_dir.path, 'working')
+
+# cucumber_html_report_path = os.path.join(parent_work_dir_path, 'uat', 'cucumber.html')
+# cucumber_json_report_path = os.path.join(parent_work_dir_path, 'uat', 'cucumber.json')
+
+# test_dir.write(pom_file_name, pom_content)
+
+# pom_file_path = os.path.join(test_dir.path, pom_file_name)
+# step_config = {
+# 'pom-file': pom_file_path,
+# 'selenium-hub-url': selenium_hub_url,
+# 'tls-verify': True
+# }
+
+# if set_tls_verify_false:
+# step_config['tls-verify'] = False
+
+# target_base_url = None
+# if deployed_host_urls:
+# step_config['deployed-host-urls'] = deployed_host_urls
+# if isinstance(deployed_host_urls, list):
+# target_base_url = deployed_host_urls[0]
+# else:
+# target_base_url = deployed_host_urls
+# if target_host_url:
+# step_config['target-host-url'] = target_host_url
+# target_base_url = target_host_url
+
+# if fail_on_no_tests is not None:
+# step_config['fail-on-no-tests'] = fail_on_no_tests
+# if uat_maven_profile is not None:
+# step_config['uat-maven-profile'] = uat_maven_profile
+# else:
+# uat_maven_profile = 'integration-test'
+# step_implementer = self.create_step_implementer(
+# step_config=step_config,
+# parent_work_dir_path=parent_work_dir_path,
+# )
+
+# # mock generating settings
+# settings_file_path = "/does/not/matter/settings.xml"
+# def generate_maven_settings_side_effect():
+# return settings_file_path
+# generate_maven_settings_mock.side_effect = generate_maven_settings_side_effect
+
+# # mock effective pom
+# def write_effective_pom_mock_side_effect(pom_file_path, output_path):
+# create_parent_dir(pom_file_path)
+# copyfile(pom_file_path, output_path)
+# write_effective_pom_mock.side_effect = write_effective_pom_mock_side_effect
+
+# # mock test results
+# if write_mock_test_results:
+# mvn_mock.side_effect = MaveStepImplementerTestCase.create_mvn_side_effect(
+# pom_file=pom_file_path,
+# artifact_parent_dir=surefire_reports_dir,
+# artifact_names=[
+# f'{group_id}.{artifact_id}.CucumberTest.txt',
+# f'TEST-{group_id}.{artifact_id}.CucumberTest.xml'
+# ],
+# raise_error_on_tests=raise_error_on_tests
+# )
+
+# # mock evidence
+# if aggregate_xml_element_attribute_values_mock and not aggregate_xml_element_attribute_values_mock_fail:
+# aggregate_xml_element_attribute_values_mock.return_value = {
+# 'time': '42',
+# 'tests': '42',
+# 'errors': '0',
+# 'skipped': '0',
+# 'failures': '0'
+# }
+# elif aggregate_xml_element_attribute_values_mock_fail:
+# aggregate_xml_element_attribute_values_mock.return_value = {
+# 'time': '42'
+# }
+
+# result = step_implementer._run_step()
+# if assert_mvn_called:
+# if not set_tls_verify_false:
+# mvn_mock.assert_called_once_with(
+# 'clean',
+# 'test',
+# f'-P{uat_maven_profile}',
+# f'-Dselenium.hub.url={selenium_hub_url}',
+# f'-Dtarget.base.url={target_base_url}',
+# f'-Dcucumber.plugin=' \
+# f'html:{cucumber_html_report_path},' \
+# f'json:{cucumber_json_report_path}',
+# '-f', pom_file_path,
+# '-s', settings_file_path,
+# _out=Any(IOBase),
+# _err=Any(IOBase)
+# )
+# else:
+# mvn_mock.assert_called_once_with(
+# 'clean',
+# 'test',
+# f'-P{uat_maven_profile}',
+# f'-Dselenium.hub.url={selenium_hub_url}',
+# f'-Dtarget.base.url={target_base_url}',
+# f'-Dcucumber.plugin=' \
+# f'html:{cucumber_html_report_path},' \
+# f'json:{cucumber_json_report_path}',
+# '-f', pom_file_path,
+# '-s', settings_file_path,
+# '-Dmaven.wagon.http.ssl.insecure=true',
+# '-Dmaven.wagon.http.ssl.allowall=true',
+# '-Dmaven.wagon.http.ssl.ignore.validity.dates=true',
+# _out=Any(IOBase),
+# _err=Any(IOBase)
+# )
+
+# expected_step_result = StepResult(
+# step_name='uat',
+# sub_step_name='MavenSeleniumCucumber',
+# sub_step_implementer_name='MavenSeleniumCucumber'
+# )
+# expected_step_result.success = expected_result_success
+# expected_step_result.message = expected_result_message
+
+# if assert_report_artifact:
+# mvn_test_output_file_path = os.path.join(
+# step_implementer.work_dir_path,
+# 'mvn_test_output.txt'
+# )
+# expected_step_result.add_artifact(
+# description=f"Standard out and standard error by 'mvn -P{uat_maven_profile} test'.",
+# name='maven-output',
+# value=mvn_test_output_file_path
+# )
+# expected_step_result.add_artifact(
+# description=f"Surefire reports generated by 'mvn -P{uat_maven_profile} test'.",
+# name='surefire-reports',
+# value=surefire_reports_dir
+# )
+# expected_step_result.add_artifact(
+# description=f"Cucumber (HTML) report generated by 'mvn -P{uat_maven_profile} test'.",
+# name='cucumber-report-html',
+# value=cucumber_html_report_path
+# )
+# expected_step_result.add_artifact(
+# description=f"Cucumber (JSON) report generated by 'mvn -P{uat_maven_profile} test'.",
+# name='cucumber-report-json',
+# value=cucumber_json_report_path
+# )
+
+# if assert_evidence and not aggregate_xml_element_attribute_values_mock_fail:
+# expected_step_result.add_evidence(
+# name='uat-evidence-time',
+# description='Surefire report value for time',
+# value='42'
+# )
+# expected_step_result.add_evidence(
+# name='uat-evidence-tests',
+# description='Surefire report value for tests',
+# value='42'
+# )
+# expected_step_result.add_evidence(
+# name='uat-evidence-errors',
+# description='Surefire report value for errors',
+# value='0'
+# )
+# expected_step_result.add_evidence(
+# name='uat-evidence-skipped',
+# description='Surefire report value for skipped',
+# value='0'
+# )
+# expected_step_result.add_evidence(
+# name='uat-evidence-failures',
+# description='Surefire report value for failures',
+# value='0'
+# )
+# elif assert_evidence and aggregate_xml_element_attribute_values_mock_fail:
+# expected_step_result.add_evidence(
+# name='uat-evidence-time',
+# description='Surefire report value for time',
+# value='42'
+# )
+# print(result)
+# self.assertEqual(expected_step_result, result)
+
+
+# @patch('ploigos_step_runner.step_implementers.uat.maven_selenium_cucumber.aggregate_xml_element_attribute_values')
+# @patch.object(MavenSeleniumCucumber, '_generate_maven_settings')
+# @patch('sh.mvn', create=True)
+# @patch('ploigos_step_runner.step_implementers.shared.maven_generic.write_effective_pom')
+# def test__run_step_success_defaults(
+# self,
+# write_effective_pom_mock,
+# mvn_mock,
+# generate_maven_settings_mock,
+# aggregate_xml_element_attribute_values_mock
+# ):
+# with TempDirectory() as test_dir:
+# group_id = 'com.mycompany.app'
+# artifact_id = 'my-app'
+# version = '1.0'
+# surefire_reports_dir = os.path.join(test_dir.path, 'target/surefire-reports')
+# pom_content = bytes(
+# '''
+# 4.0.0
+# {group_id}
+# {artifact_id}
+# {version}
+#
+# 1.8
+# 1.8
+#
+#
+#
+#
+# maven-surefire-plugin
+# ${{surefire-plugin.version}}
+#
+#
+#
+# '''.format(
+# group_id=group_id,
+# artifact_id=artifact_id,
+# version=version
+# ), 'utf-8'
+# )
+
+# self.__run__run_step_test(
+# test_dir=test_dir,
+# mvn_mock=mvn_mock,
+# selenium_hub_url='https://test.xyz:4444',
+# write_effective_pom_mock=write_effective_pom_mock,
+# generate_maven_settings_mock=generate_maven_settings_mock,
+# aggregate_xml_element_attribute_values_mock=aggregate_xml_element_attribute_values_mock,
+# pom_content=pom_content,
+# group_id=group_id,
+# artifact_id=artifact_id,
+# surefire_reports_dir=surefire_reports_dir
+# )
+
+# @patch('ploigos_step_runner.step_implementers.uat.maven_selenium_cucumber.aggregate_xml_element_attribute_values')
+# @patch.object(MavenSeleniumCucumber, '_generate_maven_settings')
+# @patch('sh.mvn', create=True)
+# @patch('ploigos_step_runner.step_implementers.shared.maven_generic.write_effective_pom')
+# def test__run_step_tls_verify_false(
+# self,
+# write_effective_pom_mock,
+# mvn_mock,
+# generate_maven_settings_mock,
+# aggregate_xml_element_attribute_values_mock
+# ):
+# with TempDirectory() as test_dir:
+# group_id = 'com.mycompany.app'
+# artifact_id = 'my-app'
+# version = '1.0'
+# surefire_reports_dir = os.path.join(test_dir.path, 'target/surefire-reports')
+# pom_content = bytes(
+# '''
+# 4.0.0
+# {group_id}
+# {artifact_id}
+# {version}
+#
+# 1.8
+# 1.8
+#
+#
+#
+#
+# maven-surefire-plugin
+# ${{surefire-plugin.version}}
+#
+#
+#
+# '''.format(
+# group_id=group_id,
+# artifact_id=artifact_id,
+# version=version
+# ), 'utf-8'
+# )
+
+# self.__run__run_step_test(
+# test_dir=test_dir,
+# mvn_mock=mvn_mock,
+# selenium_hub_url='https://test.xyz:4444',
+# write_effective_pom_mock=write_effective_pom_mock,
+# generate_maven_settings_mock=generate_maven_settings_mock,
+# aggregate_xml_element_attribute_values_mock=aggregate_xml_element_attribute_values_mock,
+# pom_content=pom_content,
+# group_id=group_id,
+# artifact_id=artifact_id,
+# surefire_reports_dir=surefire_reports_dir,
+# set_tls_verify_false=True
+# )
+
+# @patch('ploigos_step_runner.step_implementers.uat.maven_selenium_cucumber.aggregate_xml_element_attribute_values')
+# @patch.object(MavenSeleniumCucumber, '_generate_maven_settings')
+# @patch('sh.mvn', create=True)
+# @patch('ploigos_step_runner.step_implementers.shared.maven_generic.write_effective_pom')
+# def test__run_step_success__deployed_host_urls_str(
+# self,
+# write_effective_pom_mock,
+# mvn_mock,
+# generate_maven_settings_mock,
+# aggregate_xml_element_attribute_values_mock
+# ):
+# with TempDirectory() as test_dir:
+# group_id = 'com.mycompany.app'
+# artifact_id = 'my-app'
+# version = '1.0'
+# surefire_reports_dir = os.path.join(test_dir.path, 'target/surefire-reports')
+# pom_content = bytes(
+# '''
+# 4.0.0
+# {group_id}
+# {artifact_id}
+# {version}
+#
+# 1.8
+# 1.8
+#
+#
+#
+#
+# maven-surefire-plugin
+# ${{surefire-plugin.version}}
+#
+#
+#
+# '''.format(
+# group_id=group_id,
+# artifact_id=artifact_id,
+# version=version
+# ), 'utf-8'
+# )
+
+# deployed_host_urls = 'https://foo.ploigos.xyz'
+# self.__run__run_step_test(
+# test_dir=test_dir,
+# mvn_mock=mvn_mock,
+# selenium_hub_url='https://test.xyz:4444',
+# write_effective_pom_mock=write_effective_pom_mock,
+# generate_maven_settings_mock=generate_maven_settings_mock,
+# aggregate_xml_element_attribute_values_mock=aggregate_xml_element_attribute_values_mock,
+# pom_content=pom_content,
+# group_id=group_id,
+# artifact_id=artifact_id,
+# surefire_reports_dir=surefire_reports_dir,
+# deployed_host_urls=deployed_host_urls
+# )
+
+# @patch('ploigos_step_runner.step_implementers.uat.maven_selenium_cucumber.aggregate_xml_element_attribute_values')
+# @patch.object(MavenSeleniumCucumber, '_generate_maven_settings')
+# @patch('sh.mvn', create=True)
+# @patch('ploigos_step_runner.step_implementers.shared.maven_generic.write_effective_pom')
+# def test__run_step_success__deployed_host_urls_array_1(
+# self,
+# write_effective_pom_mock,
+# mvn_mock,
+# generate_maven_settings_mock,
+# aggregate_xml_element_attribute_values_mock
+# ):
+# with TempDirectory() as test_dir:
+# group_id = 'com.mycompany.app'
+# artifact_id = 'my-app'
+# version = '1.0'
+# surefire_reports_dir = os.path.join(test_dir.path, 'target/surefire-reports')
+# pom_content = bytes(
+# '''
+# 4.0.0
+# {group_id}
+# {artifact_id}
+# {version}
+#
+# 1.8
+# 1.8
+#
+#
+#
+#
+# maven-surefire-plugin
+# ${{surefire-plugin.version}}
+#
+#
+#
+# '''.format(
+# group_id=group_id,
+# artifact_id=artifact_id,
+# version=version
+# ), 'utf-8'
+# )
+
+# deployed_host_urls = ['https://foo.ploigos.xyz']
+# self.__run__run_step_test(
+# test_dir=test_dir,
+# mvn_mock=mvn_mock,
+# selenium_hub_url='https://test.xyz:4444',
+# write_effective_pom_mock=write_effective_pom_mock,
+# generate_maven_settings_mock=generate_maven_settings_mock,
+# aggregate_xml_element_attribute_values_mock=aggregate_xml_element_attribute_values_mock,
+# pom_content=pom_content,
+# group_id=group_id,
+# artifact_id=artifact_id,
+# surefire_reports_dir=surefire_reports_dir,
+# deployed_host_urls=deployed_host_urls
+# )
+
+# @patch('ploigos_step_runner.step_implementers.uat.maven_selenium_cucumber.aggregate_xml_element_attribute_values')
+# @patch.object(MavenSeleniumCucumber, '_generate_maven_settings')
+# @patch('sh.mvn', create=True)
+# @patch('ploigos_step_runner.step_implementers.shared.maven_generic.write_effective_pom')
+# def test__run_step_success__deployed_host_urls_array_2(
+# self,
+# write_effective_pom_mock,
+# mvn_mock,
+# generate_maven_settings_mock,
+# aggregate_xml_element_attribute_values_mock,
+# ):
+# with TempDirectory() as test_dir:
+# group_id = 'com.mycompany.app'
+# artifact_id = 'my-app'
+# version = '1.0'
+# surefire_reports_dir = os.path.join(test_dir.path, 'target/surefire-reports')
+# pom_content = bytes(
+# '''
+# 4.0.0
+# {group_id}
+# {artifact_id}
+# {version}
+#
+# 1.8
+# 1.8
+#
+#
+#
+#
+# maven-surefire-plugin
+# ${{surefire-plugin.version}}
+#
+#
+#
+# '''.format(
+# group_id=group_id,
+# artifact_id=artifact_id,
+# version=version
+# ), 'utf-8'
+# )
+
+# deployed_host_urls = ['https://foo.ploigos.xyz', 'https://foo.ploigos.xyz']
+# self.__run__run_step_test(
+# test_dir=test_dir,
+# mvn_mock=mvn_mock,
+# selenium_hub_url='https://test.xyz:4444',
+# write_effective_pom_mock=write_effective_pom_mock,
+# generate_maven_settings_mock=generate_maven_settings_mock,
+# aggregate_xml_element_attribute_values_mock=aggregate_xml_element_attribute_values_mock,
+# pom_content=pom_content,
+# group_id=group_id,
+# artifact_id=artifact_id,
+# surefire_reports_dir=surefire_reports_dir,
+# deployed_host_urls=deployed_host_urls,
+# expected_result_message=\
+# f"Given more then one deployed host URL ({deployed_host_urls})," \
+# f" targeting first one (https://foo.ploigos.xyz) for user acceptance test (UAT)."
+# )
+
+# @patch('ploigos_step_runner.step_implementers.uat.maven_selenium_cucumber.aggregate_xml_element_attribute_values')
+# @patch.object(MavenSeleniumCucumber, '_generate_maven_settings')
+# @patch('sh.mvn', create=True)
+# @patch('ploigos_step_runner.step_implementers.shared.maven_generic.write_effective_pom')
+# def test__run_step_success_provided_profile_override(
+# self,
+# write_effective_pom_mock,
+# mvn_mock,
+# generate_maven_settings_mock,
+# aggregate_xml_element_attribute_values_mock
+# ):
+# with TempDirectory() as test_dir:
+# group_id = 'com.mycompany.app'
+# artifact_id = 'my-app'
+# version = '1.0'
+# surefire_reports_dir = os.path.join(test_dir.path, 'target/surefire-reports')
+# pom_content = bytes(
+# '''
+# 4.0.0
+# {group_id}
+# {artifact_id}
+# {version}
+#
+# 1.8
+# 1.8
+#
+#
+#
+#
+# maven-surefire-plugin
+# ${{surefire-plugin.version}}
+#
+#
+#
+# '''.format(
+# group_id=group_id,
+# artifact_id=artifact_id,
+# version=version
+# ), 'utf-8'
+# )
+
+# self.__run__run_step_test(
+# test_dir=test_dir,
+# mvn_mock=mvn_mock,
+# selenium_hub_url='https://test.xyz:4444',
+# write_effective_pom_mock=write_effective_pom_mock,
+# generate_maven_settings_mock=generate_maven_settings_mock,
+# aggregate_xml_element_attribute_values_mock=aggregate_xml_element_attribute_values_mock,
+# pom_content=pom_content,
+# group_id=group_id,
+# artifact_id=artifact_id,
+# surefire_reports_dir=surefire_reports_dir,
+# uat_maven_profile='custom-uat-profile'
+# )
+
+# @patch('ploigos_step_runner.step_implementers.uat.maven_selenium_cucumber.aggregate_xml_element_attribute_values')
+# @patch.object(MavenSeleniumCucumber, '_generate_maven_settings')
+# @patch('sh.mvn', create=True)
+# @patch('ploigos_step_runner.step_implementers.shared.maven_generic.write_effective_pom')
+# def test__run_step_success_provided_pom_file_override(
+# self,
+# write_effective_pom_mock,
+# mvn_mock,
+# generate_maven_settings_mock,
+# aggregate_xml_element_attribute_values_mock
+# ):
+# with TempDirectory() as test_dir:
+# group_id = 'com.mycompany.app'
+# artifact_id = 'my-app'
+# version = '1.0'
+# surefire_reports_dir = os.path.join(test_dir.path, 'target/surefire-reports')
+# pom_content = bytes(
+# '''
+# 4.0.0
+# {group_id}
+# {artifact_id}
+# {version}
+#
+# 1.8
+# 1.8
+#
+#
+#
+#
+# maven-surefire-plugin
+# ${{surefire-plugin.version}}
+#
+#
+#
+# '''.format(
+# group_id=group_id,
+# artifact_id=artifact_id,
+# version=version
+# ), 'utf-8'
+# )
+
+# self.__run__run_step_test(
+# test_dir=test_dir,
+# mvn_mock=mvn_mock,
+# selenium_hub_url='https://test.xyz:4444',
+# write_effective_pom_mock=write_effective_pom_mock,
+# generate_maven_settings_mock=generate_maven_settings_mock,
+# aggregate_xml_element_attribute_values_mock=aggregate_xml_element_attribute_values_mock,
+# pom_content=pom_content,
+# group_id=group_id,
+# artifact_id=artifact_id,
+# surefire_reports_dir=surefire_reports_dir,
+# pom_file_name='custom-pom.xml'
+# )
+
+# @patch('ploigos_step_runner.step_implementers.uat.maven_selenium_cucumber.aggregate_xml_element_attribute_values')
+# @patch.object(MavenSeleniumCucumber, '_generate_maven_settings')
+# @patch('sh.mvn', create=True)
+# @patch('ploigos_step_runner.step_implementers.shared.maven_generic.write_effective_pom')
+# def test__run_step_success_provided_fail_on_no_tests_false_with_tests(
+# self,
+# write_effective_pom_mock,
+# mvn_mock,
+# generate_maven_settings_mock,
+# aggregate_xml_element_attribute_values_mock
+# ):
+# with TempDirectory() as test_dir:
+# group_id = 'com.mycompany.app'
+# artifact_id = 'my-app'
+# version = '1.0'
+# surefire_reports_dir = os.path.join(test_dir.path, 'target/surefire-reports')
+# pom_content = bytes(
+# '''
+# 4.0.0
+# {group_id}
+# {artifact_id}
+# {version}
+#
+# 1.8
+# 1.8
+#
+#
+#
+#
+# maven-surefire-plugin
+# ${{surefire-plugin.version}}
+#
+#
+#
+# '''.format(
+# group_id=group_id,
+# artifact_id=artifact_id,
+# version=version
+# ), 'utf-8'
+# )
+
+# self.__run__run_step_test(
+# test_dir=test_dir,
+# mvn_mock=mvn_mock,
+# selenium_hub_url='https://test.xyz:4444',
+# write_effective_pom_mock=write_effective_pom_mock,
+# generate_maven_settings_mock=generate_maven_settings_mock,
+# aggregate_xml_element_attribute_values_mock=aggregate_xml_element_attribute_values_mock,
+# pom_content=pom_content,
+# group_id=group_id,
+# artifact_id=artifact_id,
+# surefire_reports_dir=surefire_reports_dir,
+# fail_on_no_tests=False,
+# write_mock_test_results=True,
+# expected_result_success=True
+# )
+
+# @patch('ploigos_step_runner.step_implementers.uat.maven_selenium_cucumber.aggregate_xml_element_attribute_values')
+# @patch.object(MavenSeleniumCucumber, '_generate_maven_settings')
+# @patch('sh.mvn', create=True)
+# @patch('ploigos_step_runner.step_implementers.shared.maven_generic.write_effective_pom')
+# def test__run_step_success_provided_fail_on_no_tests_false_with_no_tests(
+# self,
+# write_effective_pom_mock,
+# mvn_mock,
+# generate_maven_settings_mock,
+# aggregate_xml_element_attribute_values_mock
+# ):
+# with TempDirectory() as test_dir:
+# group_id = 'com.mycompany.app'
+# artifact_id = 'my-app'
+# version = '1.0'
+# surefire_reports_dir = os.path.join(test_dir.path, 'target/surefire-reports')
+# pom_content = bytes(
+# '''
+# 4.0.0
+# {group_id}
+# {artifact_id}
+# {version}
+#
+# 1.8
+# 1.8
+#
+#
+#
+#
+# maven-surefire-plugin
+# ${{surefire-plugin.version}}
+#
+#
+#
+# '''.format(
+# group_id=group_id,
+# artifact_id=artifact_id,
+# version=version
+# ), 'utf-8'
+# )
+
+# self.__run__run_step_test(
+# test_dir=test_dir,
+# mvn_mock=mvn_mock,
+# selenium_hub_url='https://test.xyz:4444',
+# write_effective_pom_mock=write_effective_pom_mock,
+# generate_maven_settings_mock=generate_maven_settings_mock,
+# aggregate_xml_element_attribute_values_mock=aggregate_xml_element_attribute_values_mock,
+# assert_evidence=False,
+# pom_content=pom_content,
+# group_id=group_id,
+# artifact_id=artifact_id,
+# surefire_reports_dir=surefire_reports_dir,
+# fail_on_no_tests=False,
+# write_mock_test_results=False,
+# expected_result_success=True,
+# expected_result_message="No user acceptance tests defined" \
+# " using maven profile (integration-test)," \
+# " but 'fail-on-no-tests' is False."
+# )
+
+# @patch('ploigos_step_runner.step_implementers.uat.maven_selenium_cucumber.aggregate_xml_element_attribute_values')
+# @patch.object(MavenSeleniumCucumber, '_generate_maven_settings')
+# @patch('sh.mvn', create=True)
+# @patch('ploigos_step_runner.step_implementers.shared.maven_generic.write_effective_pom')
+# def test__run_step_fail_provided_fail_on_no_tests_true_with_no_tests(
+# self,
+# write_effective_pom_mock,
+# mvn_mock,
+# generate_maven_settings_mock,
+# aggregate_xml_element_attribute_values_mock
+# ):
+# with TempDirectory() as test_dir:
+# group_id = 'com.mycompany.app'
+# artifact_id = 'my-app'
+# version = '1.0'
+# surefire_reports_dir = os.path.join(test_dir.path, 'target/surefire-reports')
+# pom_content = bytes(
+# '''
+# 4.0.0
+# {group_id}
+# {artifact_id}
+# {version}
+#
+# 1.8
+# 1.8
+#
+#
+#
+#
+# maven-surefire-plugin
+# ${{surefire-plugin.version}}
+#
+#
+#
+# '''.format(
+# group_id=group_id,
+# artifact_id=artifact_id,
+# version=version
+# ), 'utf-8'
+# )
+
+# self.__run__run_step_test(
+# test_dir=test_dir,
+# mvn_mock=mvn_mock,
+# selenium_hub_url='https://test.xyz:4444',
+# write_effective_pom_mock=write_effective_pom_mock,
+# generate_maven_settings_mock=generate_maven_settings_mock,
+# aggregate_xml_element_attribute_values_mock=aggregate_xml_element_attribute_values_mock,
+# assert_evidence=False,
+# pom_content=pom_content,
+# group_id=group_id,
+# artifact_id=artifact_id,
+# surefire_reports_dir=surefire_reports_dir,
+# fail_on_no_tests=True,
+# write_mock_test_results=False,
+# expected_result_success=False,
+# expected_result_message="No user acceptance tests defined" \
+# " using maven profile (integration-test)."
+# )
+
+# @patch('ploigos_step_runner.step_implementers.uat.maven_selenium_cucumber.aggregate_xml_element_attribute_values')
+# @patch.object(MavenSeleniumCucumber, '_generate_maven_settings')
+# @patch('sh.mvn', create=True)
+# @patch('ploigos_step_runner.step_implementers.shared.maven_generic.write_effective_pom')
+# def test__run_step_fail_no_surefire_plugin(
+# self,
+# write_effective_pom_mock,
+# mvn_mock,
+# generate_maven_settings_mock,
+# aggregate_xml_element_attribute_values_mock
+# ):
+# with TempDirectory() as test_dir:
+# group_id = 'com.mycompany.app'
+# artifact_id = 'my-app'
+# version = '1.0'
+# surefire_reports_dir = os.path.join(test_dir.path, 'target/surefire-reports')
+# pom_content = bytes(
+# '''
+# 4.0.0
+# {group_id}
+# {artifact_id}
+# {version}
+#
+# 1.8
+# 1.8
+#
+#
+#
+#
+#
+# '''.format(
+# group_id=group_id,
+# artifact_id=artifact_id,
+# version=version
+# ), 'utf-8'
+# )
+
+# effective_pom_path = os.path.join(
+# test_dir.path,
+# 'working',
+# 'uat',
+# 'effective-pom.xml'
+# )
+# self.__run__run_step_test(
+# test_dir=test_dir,
+# mvn_mock=mvn_mock,
+# selenium_hub_url='https://test.xyz:4444',
+# write_effective_pom_mock=write_effective_pom_mock,
+# generate_maven_settings_mock=generate_maven_settings_mock,
+# aggregate_xml_element_attribute_values_mock=aggregate_xml_element_attribute_values_mock,
+# assert_evidence=False,
+# pom_content=pom_content,
+# group_id=group_id,
+# artifact_id=artifact_id,
+# surefire_reports_dir=surefire_reports_dir,
+# expected_result_success=False,
+# expected_result_message='Unit test dependency "maven-surefire-plugin" ' \
+# f'missing from effective pom ({effective_pom_path}).',
+# assert_mvn_called=False,
+# assert_report_artifact=False
+# )
+
+# @patch('ploigos_step_runner.step_implementers.uat.maven_selenium_cucumber.aggregate_xml_element_attribute_values')
+# @patch.object(MavenSeleniumCucumber, '_generate_maven_settings')
+# @patch('sh.mvn', create=True)
+# @patch('ploigos_step_runner.step_implementers.shared.maven_generic.write_effective_pom')
+# def test__run_step_success_pom_specified_reports_dir(
+# self,
+# write_effective_pom_mock,
+# mvn_mock,
+# generate_maven_settings_mock,
+# aggregate_xml_element_attribute_values_mock
+# ):
+# with TempDirectory() as test_dir:
+# group_id = 'com.mycompany.app'
+# artifact_id = 'my-app'
+# version = '1.0'
+# surefire_reports_dir = os.path.join(test_dir.path, 'target/surefire-reports')
+# pom_content = bytes(
+# '''
+# 4.0.0
+# {group_id}
+# {artifact_id}
+# {version}
+#
+# 1.8
+# 1.8
+#
+#
+#
+#
+# maven-surefire-plugin
+# ${{surefire-plugin.version}}
+#
+# {surefire_reports_dir}
+#
+#
+#
+#
+# '''.format(
+# group_id=group_id,
+# artifact_id=artifact_id,
+# version=version,
+# surefire_reports_dir=surefire_reports_dir
+# ), 'utf-8'
+# )
+
+# self.__run__run_step_test(
+# test_dir=test_dir,
+# mvn_mock=mvn_mock,
+# selenium_hub_url='https://test.xyz:4444',
+# write_effective_pom_mock=write_effective_pom_mock,
+# generate_maven_settings_mock=generate_maven_settings_mock,
+# aggregate_xml_element_attribute_values_mock=aggregate_xml_element_attribute_values_mock,
+# assert_evidence=True,
+# pom_content=pom_content,
+# group_id=group_id,
+# artifact_id=artifact_id,
+# surefire_reports_dir=surefire_reports_dir
+# )
+
+# @patch('ploigos_step_runner.step_implementers.uat.maven_selenium_cucumber.aggregate_xml_element_attribute_values')
+# @patch.object(MavenSeleniumCucumber, '_generate_maven_settings')
+# @patch('sh.mvn', create=True)
+# @patch('ploigos_step_runner.step_implementers.shared.maven_generic.write_effective_pom')
+# def test__run_step_fail_mvn_test_failure(
+# self,
+# write_effective_pom_mock,
+# mvn_mock,
+# generate_maven_settings_mock,
+# aggregate_xml_element_attribute_values_mock
+# ):
+# with TempDirectory() as test_dir:
+# group_id = 'com.mycompany.app'
+# artifact_id = 'my-app'
+# version = '1.0'
+# surefire_reports_dir = os.path.join(test_dir.path, 'target/surefire-reports')
+# pom_content = bytes(
+# '''
+# 4.0.0
+# {group_id}
+# {artifact_id}
+# {version}
+#
+# 1.8
+# 1.8
+#
+#
+#
+#
+# maven-surefire-plugin
+# ${{surefire-plugin.version}}
+#
+#
+#
+# '''.format(
+# group_id=group_id,
+# artifact_id=artifact_id,
+# version=version
+# ), 'utf-8'
+# )
+
+# self.__run__run_step_test(
+# test_dir=test_dir,
+# mvn_mock=mvn_mock,
+# selenium_hub_url='https://test.xyz:4444',
+# write_effective_pom_mock=write_effective_pom_mock,
+# generate_maven_settings_mock=generate_maven_settings_mock,
+# aggregate_xml_element_attribute_values_mock=None,
+# assert_evidence=False,
+# pom_content=pom_content,
+# group_id=group_id,
+# artifact_id=artifact_id,
+# surefire_reports_dir=surefire_reports_dir,
+# raise_error_on_tests=True,
+# expected_result_success=False,
+# expected_result_message="User acceptance test failures. See 'maven-output'" \
+# ", 'surefire-reports', 'cucumber-report-html', and 'cucumber-report-json'" \
+# " report artifacts for details."
+# )
+
+# @patch('ploigos_step_runner.step_implementers.uat.maven_selenium_cucumber.aggregate_xml_element_attribute_values')
+# @patch.object(MavenSeleniumCucumber, '_generate_maven_settings')
+# @patch('sh.mvn', create=True)
+# @patch('ploigos_step_runner.step_implementers.shared.maven_generic.write_effective_pom')
+# def test__run_step_failure_missing_evidence_attribute(
+# self,
+# write_effective_pom_mock,
+# mvn_mock,
+# generate_maven_settings_mock,
+# aggregate_xml_element_attribute_values_mock
+# ):
+# with TempDirectory() as test_dir:
+# group_id = 'com.mycompany.app'
+# artifact_id = 'my-app'
+# version = '1.0'
+# surefire_reports_dir = os.path.join(test_dir.path, 'target/surefire-reports')
+# pom_content = bytes(
+# '''
+# 4.0.0
+# {group_id}
+# {artifact_id}
+# {version}
+#
+# 1.8
+# 1.8
+#
+#
+#
+#
+# maven-surefire-plugin
+# ${{surefire-plugin.version}}
+#
+#
+#
+# '''.format(
+# group_id=group_id,
+# artifact_id=artifact_id,
+# version=version
+# ), 'utf-8'
+# )
+
+# self.__run__run_step_test(
+# test_dir=test_dir,
+# mvn_mock=mvn_mock,
+# selenium_hub_url='https://test.xyz:4444',
+# write_effective_pom_mock=write_effective_pom_mock,
+# generate_maven_settings_mock=generate_maven_settings_mock,
+# aggregate_xml_element_attribute_values_mock=aggregate_xml_element_attribute_values_mock,
+# aggregate_xml_element_attribute_values_mock_fail=True,
+# assert_evidence=True,
+# pom_content=pom_content,
+# group_id=group_id,
+# artifact_id=artifact_id,
+# surefire_reports_dir=surefire_reports_dir,
+# expected_result_success=False,
+# expected_result_message="Error gathering evidence from "\
+# "surefire report, expected attribute tests "\
+# "not found in report " + surefire_reports_dir)
diff --git a/tests/step_implementers/unit_test/test_maven_unit_test.py b/tests/step_implementers/unit_test/test_maven_unit_test.py
index ed2dafb0..a95c1325 100644
--- a/tests/step_implementers/unit_test/test_maven_unit_test.py
+++ b/tests/step_implementers/unit_test/test_maven_unit_test.py
@@ -1,23 +1,92 @@
import os
-import re
-from io import IOBase, StringIO
-from shutil import copyfile
-from unittest.mock import patch
+from pathlib import Path
+from unittest.mock import Mock, patch
-from ploigos_step_runner import StepResult, WorkflowResult
-from ploigos_step_runner.config.config import Config
+from ploigos_step_runner import StepResult, StepRunnerException, WorkflowResult
from ploigos_step_runner.step_implementers.unit_test import Maven
-from ploigos_step_runner.utils.file import create_parent_dir
from testfixtures import TempDirectory
-from tests.helpers.maven_step_implementer_test_case import \
- MaveStepImplementerTestCase
-from tests.helpers.test_utils import Any
+from tests.helpers.base_step_implementer_test_case import \
+ BaseStepImplementerTestCase
-class TestStepImplementerMavenUnitTest(MaveStepImplementerTestCase):
+@patch("ploigos_step_runner.step_implementers.shared.MavenGeneric.__init__")
+class TestStepImplementerMavenTest___init__(BaseStepImplementerTestCase):
+ def test_defaults(self, mock_super_init):
+ workflow_result = WorkflowResult()
+ parent_work_dir_path = '/fake/path'
+ config = {}
+
+ Maven(
+ workflow_result=workflow_result,
+ parent_work_dir_path=parent_work_dir_path,
+ config=config
+ )
+
+ mock_super_init.assert_called_once_with(
+ workflow_result=workflow_result,
+ parent_work_dir_path=parent_work_dir_path,
+ config=config,
+ environment=None,
+ maven_phases_and_goals=['test']
+ )
+
+ def test_given_environment(self, mock_super_init):
+ workflow_result = WorkflowResult()
+ parent_work_dir_path = '/fake/path'
+ config = {}
+
+ Maven(
+ workflow_result=workflow_result,
+ parent_work_dir_path=parent_work_dir_path,
+ config=config,
+ environment='mock-env'
+ )
+
+ mock_super_init.assert_called_once_with(
+ workflow_result=workflow_result,
+ parent_work_dir_path=parent_work_dir_path,
+ config=config,
+ environment='mock-env',
+ maven_phases_and_goals=['test']
+ )
+
+class TestStepImplementerMavenTest_step_implementer_config_defaults(
+ BaseStepImplementerTestCase
+):
+ def test_result(self):
+ self.assertEqual(
+ Maven.step_implementer_config_defaults(),
+ {
+ 'pom-file': 'pom.xml',
+ 'tls-verify': True,
+ 'maven-profiles': [],
+ 'maven-additional-arguments': [],
+ 'maven-no-transfer-progress': True,
+ 'fail-on-no-tests': True
+ }
+ )
+
+class TestStepImplementerMavenTest__required_config_or_result_keys(
+ BaseStepImplementerTestCase
+):
+ def test_result(self):
+ self.assertEqual(
+ Maven._required_config_or_result_keys(),
+ [
+ 'pom-file',
+ 'fail-on-no-tests'
+ ]
+ )
+
+@patch.object(Maven, '_run_maven_step')
+@patch.object(Maven, 'write_working_file', return_value='/mock/mvn_output.txt')
+class TestStepImplementerMavenTest__run_step(
+ BaseStepImplementerTestCase
+):
def create_step_implementer(
self,
step_config={},
+ workflow_result=None,
parent_work_dir_path=''
):
return self.create_given_step_implementer(
@@ -25,535 +94,448 @@ def create_step_implementer(
step_config=step_config,
step_name='unit-test',
implementer='Maven',
+ workflow_result=workflow_result,
parent_work_dir_path=parent_work_dir_path
)
- def test_step_implementer_config_defaults(self):
- defaults = Maven.step_implementer_config_defaults()
- expected_defaults = {
- 'fail-on-no-tests': True,
- 'pom-file': 'pom.xml',
- 'tls-verify': True
- }
- self.assertEqual(defaults, expected_defaults)
-
- def test__required_config_or_result_keys(self):
- required_keys = Maven._required_config_or_result_keys()
- expected_required_keys = [
- 'fail-on-no-tests',
- 'pom-file'
- ]
- self.assertEqual(required_keys, expected_required_keys)
-
- def __run__run_step_test(
+ @patch.object(Maven, '_get_effective_pom_element', side_effect=['mock surefire element', None])
+ def test_success_default_reports_dir(
self,
- test_dir,
- mvn_mock,
- write_effective_pom_mock,
- generate_maven_settings_mock,
- pom_content,
- group_id,
- artifact_id,
- surefire_reports_dir,
- write_mock_test_results=True,
- assert_mvn_called=True,
- assert_report_artifact=True,
- expected_result_success=True,
- expected_result_message='',
- expected_result_message_regex=None,
- fail_on_no_tests=None,
- raise_error_on_tests=False,
- set_tls_verify_false=False,
+ mock_effective_pom_element,
+ mock_write_working_file,
+ mock_run_maven_step
):
- parent_work_dir_path = os.path.join(test_dir.path, 'working')
+ with TempDirectory() as test_dir:
+ parent_work_dir_path = os.path.join(test_dir.path, 'working')
- test_dir.write('pom.xml', pom_content)
+ pom_file = os.path.join(test_dir.path, 'mock-pom.xml')
+ step_config = {
+ 'pom-file': pom_file
+ }
+ step_implementer = self.create_step_implementer(
+ step_config=step_config,
+ parent_work_dir_path=parent_work_dir_path,
+ )
- pom_file_path = os.path.join(test_dir.path, 'pom.xml')
- step_config = {
- 'pom-file': pom_file_path,
- 'tls-verify': True
- }
+ # setup sideeffects
+ surefire_reports_dir = os.path.join(test_dir.path, 'target/surefire-reports')
+ group_id = 'com.ploigos.app'
+ artifact_id = 'my-app'
+ surefire_artifact_names = [
+ f'{group_id}.{artifact_id}.ClassNameTest.txt',
+ f'TEST-{group_id}.{artifact_id}.ClassNameTest.xml'
+ ]
+ def run_maven_side_effect(mvn_output_file_path):
+ os.makedirs(surefire_reports_dir, exist_ok=True)
- if set_tls_verify_false:
- step_config['tls-verify'] = False
+ for artifact_name in surefire_artifact_names:
+ artifact_path = os.path.join(
+ surefire_reports_dir,
+ artifact_name
+ )
+ Path(artifact_path).touch()
- if fail_on_no_tests is not None:
- step_config['fail-on-no-tests'] = fail_on_no_tests
- step_implementer = self.create_step_implementer(
- step_config=step_config,
- parent_work_dir_path=parent_work_dir_path,
- )
+ mock_run_maven_step.side_effect = run_maven_side_effect
- # mock generating settings
- settings_file_path = "/does/not/matter/settings.xml"
- def generate_maven_settings_side_effect():
- return settings_file_path
- generate_maven_settings_mock.side_effect = generate_maven_settings_side_effect
-
- # mock effective pom
- def write_effective_pom_mock_side_effect(pom_file_path, output_path):
- create_parent_dir(pom_file_path)
- copyfile(pom_file_path, output_path)
- write_effective_pom_mock.side_effect = write_effective_pom_mock_side_effect
-
- # mock test results
- if write_mock_test_results:
- mvn_mock.side_effect = MaveStepImplementerTestCase.create_mvn_side_effect(
- pom_file=pom_file_path,
- artifact_parent_dir=surefire_reports_dir,
- artifact_names=[
- f'{group_id}.{artifact_id}.ClassNameTest.txt',
- f'TEST-{group_id}.{artifact_id}.ClassNameTest.xml'
- ],
- raise_error_on_tests=raise_error_on_tests
- )
-
- result = step_implementer._run_step()
- if assert_mvn_called:
- if not set_tls_verify_false:
- mvn_mock.assert_called_once_with(
- 'clean',
- 'test',
- '-f', pom_file_path,
- '-s', settings_file_path,
- _out=Any(IOBase),
- _err=Any(IOBase)
- )
- else:
- mvn_mock.assert_called_once_with(
- 'clean',
- 'test',
- '-f', pom_file_path,
- '-s', settings_file_path,
- '-Dmaven.wagon.http.ssl.insecure=true',
- '-Dmaven.wagon.http.ssl.allowall=true',
- '-Dmaven.wagon.http.ssl.ignore.validity.dates=true',
- _out=Any(IOBase),
- _err=Any(IOBase)
- )
-
- expected_step_result = StepResult(
- step_name='unit-test',
- sub_step_name='Maven',
- sub_step_implementer_name='Maven'
- )
- expected_step_result.success = expected_result_success
- expected_step_result.message = expected_result_message
+ # run step
+ actual_step_result = step_implementer._run_step()
- if assert_report_artifact:
- mvn_test_output_file_path = os.path.join(
- step_implementer.work_dir_path,
- 'mvn_test_output.txt'
+ # create expected step result
+ expected_step_result = StepResult(
+ step_name='unit-test',
+ sub_step_name='Maven',
+ sub_step_implementer_name='Maven'
)
expected_step_result.add_artifact(
- description="Standard out and standard error from 'mvn test'.",
+ description="Standard out and standard error from maven.",
name='maven-output',
- value=mvn_test_output_file_path
+ value='/mock/mvn_output.txt'
)
expected_step_result.add_artifact(
+ description="Surefire reports generated by maven.",
name='surefire-reports',
- description="Surefire reports generated from 'mvn test'.",
- value=surefire_reports_dir,
+ value=surefire_reports_dir
)
- if expected_result_message_regex:
- self.assertEqual(result.success, expected_step_result.success)
- self.assertRegex(result.message, expected_result_message_regex)
- self.assertEqual(result.artifacts, expected_step_result.artifacts)
- else:
- self.assertEqual(result, expected_step_result)
+ # verify step result
+ self.assertEqual(
+ actual_step_result,
+ expected_step_result
+ )
- @patch.object(Maven, '_generate_maven_settings')
- @patch('sh.mvn', create=True)
- @patch('ploigos_step_runner.step_implementers.shared.maven_generic.write_effective_pom')
- def test__run_step_success_default_reports_dir(
- self,
- write_effective_pom_mock,
- mvn_mock,
- generate_maven_settings_mock
- ):
- with TempDirectory() as test_dir:
- group_id = 'com.mycompany.app'
- artifact_id = 'my-app'
- version = '1.0'
- surefire_reports_dir = os.path.join(test_dir.path, 'target/surefire-reports')
- pom_content = bytes(
-'''
- 4.0.0
- {group_id}
- {artifact_id}
- {version}
-
- 1.8
- 1.8
-
-
-
-
- maven-surefire-plugin
- ${{surefire-plugin.version}}
-
-
-
-'''.format(
- group_id=group_id,
- artifact_id=artifact_id,
- version=version
- ), 'utf-8'
- )
-
- self.__run__run_step_test(
- test_dir=test_dir,
- mvn_mock=mvn_mock,
- write_effective_pom_mock=write_effective_pom_mock,
- generate_maven_settings_mock=generate_maven_settings_mock,
- pom_content=pom_content,
- group_id=group_id,
- artifact_id=artifact_id,
- surefire_reports_dir=surefire_reports_dir,
- )
-
- @patch.object(Maven, '_generate_maven_settings')
- @patch('sh.mvn', create=True)
- @patch('ploigos_step_runner.step_implementers.shared.maven_generic.write_effective_pom')
- def test__run_step_tls_verify_false(
+ mock_write_working_file.assert_called_once()
+ mock_run_maven_step.assert_called_with(
+ mvn_output_file_path='/mock/mvn_output.txt'
+ )
+
+ @patch.object(
+ Maven,
+ '_get_effective_pom_element',
+ side_effect=['mock surefire element', Mock(text='mock/fake/reports')]
+ )
+ def test_success_pom_specified_relative_reports_dir(
self,
- write_effective_pom_mock,
- mvn_mock,
- generate_maven_settings_mock
+ mock_effective_pom_element,
+ mock_write_working_file,
+ mock_run_maven_step
):
with TempDirectory() as test_dir:
- group_id = 'com.mycompany.app'
+ parent_work_dir_path = os.path.join(test_dir.path, 'working')
+
+ pom_file = os.path.join(test_dir.path, 'mock-pom.xml')
+ step_config = {
+ 'pom-file': pom_file
+ }
+ step_implementer = self.create_step_implementer(
+ step_config=step_config,
+ parent_work_dir_path=parent_work_dir_path,
+ )
+
+ # setup sideeffects
+ surefire_reports_dir = os.path.join(test_dir.path, 'mock/fake/reports')
+ group_id = 'com.ploigos.app'
artifact_id = 'my-app'
- version = '1.0'
- surefire_reports_dir = os.path.join(test_dir.path, 'target/surefire-reports')
- pom_content = bytes(
-'''
- 4.0.0
- {group_id}
- {artifact_id}
- {version}
-
- 1.8
- 1.8
-
-
-
-
- maven-surefire-plugin
- ${{surefire-plugin.version}}
-
-
-
-'''.format(
- group_id=group_id,
- artifact_id=artifact_id,
- version=version
- ), 'utf-8'
- )
-
- self.__run__run_step_test(
- test_dir=test_dir,
- mvn_mock=mvn_mock,
- write_effective_pom_mock=write_effective_pom_mock,
- generate_maven_settings_mock=generate_maven_settings_mock,
- pom_content=pom_content,
- group_id=group_id,
- artifact_id=artifact_id,
- surefire_reports_dir=surefire_reports_dir,
- set_tls_verify_false=True
- )
-
- @patch.object(Maven, '_generate_maven_settings')
- @patch('sh.mvn', create=True)
- @patch('ploigos_step_runner.step_implementers.shared.maven_generic.write_effective_pom')
- def test__run_step_success_pom_specified_reports_dir(
+ surefire_artifact_names = [
+ f'{group_id}.{artifact_id}.ClassNameTest.txt',
+ f'TEST-{group_id}.{artifact_id}.ClassNameTest.xml'
+ ]
+ def run_maven_side_effect(mvn_output_file_path):
+ os.makedirs(surefire_reports_dir, exist_ok=True)
+
+ for artifact_name in surefire_artifact_names:
+ artifact_path = os.path.join(
+ surefire_reports_dir,
+ artifact_name
+ )
+ Path(artifact_path).touch()
+
+ mock_run_maven_step.side_effect = run_maven_side_effect
+
+ # run step
+ actual_step_result = step_implementer._run_step()
+
+ # create expected step result
+ expected_step_result = StepResult(
+ step_name='unit-test',
+ sub_step_name='Maven',
+ sub_step_implementer_name='Maven'
+ )
+ expected_step_result.add_artifact(
+ description="Standard out and standard error from maven.",
+ name='maven-output',
+ value='/mock/mvn_output.txt'
+ )
+ expected_step_result.add_artifact(
+ description="Surefire reports generated by maven.",
+ name='surefire-reports',
+ value=surefire_reports_dir
+ )
+
+ # verify step result
+ self.assertEqual(
+ actual_step_result,
+ expected_step_result
+ )
+
+ mock_write_working_file.assert_called_once()
+ mock_run_maven_step.assert_called_with(
+ mvn_output_file_path='/mock/mvn_output.txt'
+ )
+
+ @patch.object(Maven, '_get_effective_pom_element')
+ def test_success_pom_specified_absolute_reports_dir(
self,
- write_effective_pom_mock,
- mvn_mock,
- generate_maven_settings_mock
+ mock_effective_pom_element,
+ mock_write_working_file,
+ mock_run_maven_step
):
with TempDirectory() as test_dir:
- group_id = 'com.mycompany.app'
+ parent_work_dir_path = os.path.join(test_dir.path, 'working')
+
+ pom_file = os.path.join(test_dir.path, 'mock-pom.xml')
+ step_config = {
+ 'pom-file': pom_file
+ }
+ step_implementer = self.create_step_implementer(
+ step_config=step_config,
+ parent_work_dir_path=parent_work_dir_path,
+ )
+
+ # setup sideeffects
+ surefire_reports_dir = os.path.join(test_dir.path, 'mock-abs/fake/reports')
+ mock_effective_pom_element.side_effect = [
+ 'mock surefire element',
+ Mock(text=surefire_reports_dir)
+ ]
+ group_id = 'com.ploigos.app'
artifact_id = 'my-app'
- version = '1.0'
- surefire_reports_dir = os.path.join(test_dir.path, 'target/custom-surefire-reports-dir')
- pom_content = bytes(
-'''
- 4.0.0
- {group_id}
- {artifact_id}
- {version}
-
- 1.8
- 1.8
-
-
-
-
- maven-surefire-plugin
- ${{surefire-plugin.version}}
-
- {surefire_reports_dir}
-
-
-
-
-'''.format(
- group_id=group_id,
- artifact_id=artifact_id,
- version=version,
- surefire_reports_dir=surefire_reports_dir
- ), 'utf-8'
- )
-
- self.__run__run_step_test(
- test_dir=test_dir,
- mvn_mock=mvn_mock,
- write_effective_pom_mock=write_effective_pom_mock,
- generate_maven_settings_mock=generate_maven_settings_mock,
- pom_content=pom_content,
- group_id=group_id,
- artifact_id=artifact_id,
- surefire_reports_dir=surefire_reports_dir
- )
-
- @patch.object(Maven, '_generate_maven_settings')
- @patch('sh.mvn', create=True)
- @patch('ploigos_step_runner.step_implementers.shared.maven_generic.write_effective_pom')
- def test__run_step_fail_missing_surefire_plugin(
+ surefire_artifact_names = [
+ f'{group_id}.{artifact_id}.ClassNameTest.txt',
+ f'TEST-{group_id}.{artifact_id}.ClassNameTest.xml'
+ ]
+ def run_maven_side_effect(mvn_output_file_path):
+ os.makedirs(surefire_reports_dir, exist_ok=True)
+
+ for artifact_name in surefire_artifact_names:
+ artifact_path = os.path.join(
+ surefire_reports_dir,
+ artifact_name
+ )
+ Path(artifact_path).touch()
+
+ mock_run_maven_step.side_effect = run_maven_side_effect
+
+ # run step
+ actual_step_result = step_implementer._run_step()
+
+ # create expected step result
+ expected_step_result = StepResult(
+ step_name='unit-test',
+ sub_step_name='Maven',
+ sub_step_implementer_name='Maven'
+ )
+ expected_step_result.add_artifact(
+ description="Standard out and standard error from maven.",
+ name='maven-output',
+ value='/mock/mvn_output.txt'
+ )
+ expected_step_result.add_artifact(
+ description="Surefire reports generated by maven.",
+ name='surefire-reports',
+ value=surefire_reports_dir
+ )
+
+ # verify step result
+ self.assertEqual(
+ actual_step_result,
+ expected_step_result
+ )
+
+ mock_write_working_file.assert_called_once()
+ mock_run_maven_step.assert_called_with(
+ mvn_output_file_path='/mock/mvn_output.txt'
+ )
+
+ @patch.object(Maven, '_get_effective_pom_element', side_effect=[None, None])
+ @patch.object(Maven, '_get_effective_pom', return_value='mock-effective-pom.xml')
+ def test_fail_no_surefire_plugin(
self,
- write_effective_pom_mock,
- mvn_mock,
- generate_maven_settings_mock
+ mock_effective_pom,
+ mock_effective_pom_element,
+ mock_write_working_file,
+ mock_run_maven_step
):
with TempDirectory() as test_dir:
- group_id = 'com.mycompany.app'
+ parent_work_dir_path = os.path.join(test_dir.path, 'working')
+
+ pom_file = os.path.join(test_dir.path, 'mock-pom.xml')
+ step_config = {
+ 'pom-file': pom_file
+ }
+ step_implementer = self.create_step_implementer(
+ step_config=step_config,
+ parent_work_dir_path=parent_work_dir_path,
+ )
+
+ # setup sideeffects
+ surefire_reports_dir = os.path.join(test_dir.path, 'target/surefire-reports')
+ group_id = 'com.ploigos.app'
artifact_id = 'my-app'
- version = '1.0'
- surefire_reports_dir = os.path.join(test_dir.path, 'target/custom-surefire-reports-dir')
- pom_content = bytes(
-'''
- 4.0.0
- {group_id}
- {artifact_id}
- {version}
-
- 1.8
- 1.8
-
-
-
-
-
-'''.format(
- group_id=group_id,
- artifact_id=artifact_id,
- version=version
- ), 'utf-8'
- )
-
- effective_pom_path = os.path.join(
- test_dir.path,
- 'working',
- 'unit-test',
- 'effective-pom.xml'
- )
- self.__run__run_step_test(
- test_dir=test_dir,
- mvn_mock=mvn_mock,
- write_effective_pom_mock=write_effective_pom_mock,
- generate_maven_settings_mock=generate_maven_settings_mock,
- pom_content=pom_content,
- group_id=group_id,
- artifact_id=artifact_id,
- surefire_reports_dir=surefire_reports_dir,
- expected_result_success=False,
- expected_result_message='Unit test dependency "maven-surefire-plugin" ' \
- f'missing from effective pom ({effective_pom_path}).',
- assert_mvn_called=False,
- assert_report_artifact=False
- )
-
- @patch.object(Maven, '_generate_maven_settings')
- @patch('sh.mvn', create=True)
- @patch('ploigos_step_runner.step_implementers.shared.maven_generic.write_effective_pom')
- def test__run_step_fail_no_unit_tests_defined(
+ surefire_artifact_names = [
+ f'{group_id}.{artifact_id}.ClassNameTest.txt',
+ f'TEST-{group_id}.{artifact_id}.ClassNameTest.xml'
+ ]
+ def run_maven_side_effect(mvn_output_file_path):
+ os.makedirs(surefire_reports_dir, exist_ok=True)
+
+ for artifact_name in surefire_artifact_names:
+ artifact_path = os.path.join(
+ surefire_reports_dir,
+ artifact_name
+ )
+ Path(artifact_path).touch()
+
+ mock_run_maven_step.side_effect = run_maven_side_effect
+
+ # run step
+ actual_step_result = step_implementer._run_step()
+
+ # create expected step result
+ expected_step_result = StepResult(
+ step_name='unit-test',
+ sub_step_name='Maven',
+ sub_step_implementer_name='Maven'
+ )
+ expected_step_result.success = False
+ expected_step_result.message = 'Unit test dependency "maven-surefire-plugin" ' \
+ f'missing from effective pom (mock-effective-pom.xml).'
+
+ # verify step result
+ self.assertEqual(
+ actual_step_result,
+ expected_step_result
+ )
+
+ mock_run_maven_step.assert_not_called()
+
+ @patch.object(Maven, '_get_effective_pom_element', side_effect=['mock surefire element', None])
+ def test_fail_no_tests(
self,
- write_effective_pom_mock,
- mvn_mock,
- generate_maven_settings_mock
+ mock_effective_pom_element,
+ mock_write_working_file,
+ mock_run_maven_step
):
with TempDirectory() as test_dir:
- group_id = 'com.mycompany.app'
- artifact_id = 'my-app'
- version = '1.0'
+ parent_work_dir_path = os.path.join(test_dir.path, 'working')
+
+ pom_file = os.path.join(test_dir.path, 'mock-pom.xml')
+ step_config = {
+ 'pom-file': pom_file
+ }
+ step_implementer = self.create_step_implementer(
+ step_config=step_config,
+ parent_work_dir_path=parent_work_dir_path,
+ )
+
+ # run step
+ actual_step_result = step_implementer._run_step()
+
+ # create expected step result
surefire_reports_dir = os.path.join(test_dir.path, 'target/surefire-reports')
- pom_content = bytes(
-'''
- 4.0.0
- {group_id}
- {artifact_id}
- {version}
-
- 1.8
- 1.8
-
-
-
-
- maven-surefire-plugin
- ${{surefire-plugin.version}}
-
-
-
-'''.format(
- group_id=group_id,
- artifact_id=artifact_id,
- version=version
- ), 'utf-8'
- )
-
- self.__run__run_step_test(
- test_dir=test_dir,
- mvn_mock=mvn_mock,
- write_effective_pom_mock=write_effective_pom_mock,
- generate_maven_settings_mock=generate_maven_settings_mock,
- pom_content=pom_content,
- group_id=group_id,
- artifact_id=artifact_id,
- surefire_reports_dir=surefire_reports_dir,
- write_mock_test_results=False,
- expected_result_success=False,
- expected_result_message='No unit tests defined.'
- )
-
- @patch.object(Maven, '_generate_maven_settings')
- @patch('sh.mvn', create=True)
- @patch('ploigos_step_runner.step_implementers.shared.maven_generic.write_effective_pom')
- def test__run_step_success_fail_on_no_tests_false_and_no_tests(
+ expected_step_result = StepResult(
+ step_name='unit-test',
+ sub_step_name='Maven',
+ sub_step_implementer_name='Maven'
+ )
+ expected_step_result.success = False
+ expected_step_result.message = 'No unit tests defined.'
+ expected_step_result.add_artifact(
+ description="Standard out and standard error from maven.",
+ name='maven-output',
+ value='/mock/mvn_output.txt'
+ )
+ expected_step_result.add_artifact(
+ description="Surefire reports generated by maven.",
+ name='surefire-reports',
+ value=surefire_reports_dir
+ )
+
+ # verify step result
+ self.assertEqual(
+ actual_step_result,
+ expected_step_result
+ )
+
+ mock_write_working_file.assert_called_once()
+ mock_run_maven_step.assert_called_with(
+ mvn_output_file_path='/mock/mvn_output.txt'
+ )
+
+ @patch.object(Maven, '_get_effective_pom_element', side_effect=['mock surefire element', None])
+ def test_success_but_no_tests(
self,
- write_effective_pom_mock,
- mvn_mock,
- generate_maven_settings_mock
+ mock_effective_pom_element,
+ mock_write_working_file,
+ mock_run_maven_step
):
with TempDirectory() as test_dir:
- group_id = 'com.mycompany.app'
- artifact_id = 'my-app'
- version = '1.0'
+ parent_work_dir_path = os.path.join(test_dir.path, 'working')
+
+ pom_file = os.path.join(test_dir.path, 'mock-pom.xml')
+ step_config = {
+ 'pom-file': pom_file,
+ 'fail-on-no-tests': False
+ }
+ step_implementer = self.create_step_implementer(
+ step_config=step_config,
+ parent_work_dir_path=parent_work_dir_path,
+ )
+
+ # run step
+ actual_step_result = step_implementer._run_step()
+
+ # create expected step result
surefire_reports_dir = os.path.join(test_dir.path, 'target/surefire-reports')
- pom_content = bytes(
-'''
- 4.0.0
- {group_id}
- {artifact_id}
- {version}
-
- 1.8
- 1.8
-
-
-
-
- maven-surefire-plugin
- ${{surefire-plugin.version}}
-
-
-
-'''.format(
- group_id=group_id,
- artifact_id=artifact_id,
- version=version
- ), 'utf-8'
- )
-
- self.__run__run_step_test(
- test_dir=test_dir,
- mvn_mock=mvn_mock,
- write_effective_pom_mock=write_effective_pom_mock,
- generate_maven_settings_mock=generate_maven_settings_mock,
- pom_content=pom_content,
- group_id=group_id,
- artifact_id=artifact_id,
- surefire_reports_dir=surefire_reports_dir,
- write_mock_test_results=False,
- fail_on_no_tests=False,
- expected_result_message="No unit tests defined, but 'fail-on-no-tests' is False."
- )
-
- @patch.object(Maven, '_generate_maven_settings')
- @patch('sh.mvn', create=True)
- @patch('ploigos_step_runner.step_implementers.shared.maven_generic.write_effective_pom')
- def test__run_step_fail_mvn_test_failure(
+ expected_step_result = StepResult(
+ step_name='unit-test',
+ sub_step_name='Maven',
+ sub_step_implementer_name='Maven'
+ )
+ expected_step_result.message = "No unit tests defined, but 'fail-on-no-tests' is False."
+ expected_step_result.add_artifact(
+ description="Standard out and standard error from maven.",
+ name='maven-output',
+ value='/mock/mvn_output.txt'
+ )
+ expected_step_result.add_artifact(
+ description="Surefire reports generated by maven.",
+ name='surefire-reports',
+ value=surefire_reports_dir
+ )
+
+ # verify step result
+ self.assertEqual(
+ actual_step_result,
+ expected_step_result
+ )
+
+ mock_write_working_file.assert_called_once()
+ mock_run_maven_step.assert_called_with(
+ mvn_output_file_path='/mock/mvn_output.txt'
+ )
+
+ @patch.object(Maven, '_get_effective_pom_element', side_effect=['mock surefire element', None])
+ def test_fail_maven_run(
self,
- write_effective_pom_mock,
- mvn_mock,
- generate_maven_settings_mock
+ mock_effective_pom_element,
+ mock_write_working_file,
+ mock_run_maven_step
):
with TempDirectory() as test_dir:
- group_id = 'com.mycompany.app'
- artifact_id = 'my-app'
- version = '1.0'
+ parent_work_dir_path = os.path.join(test_dir.path, 'working')
+
+ pom_file = os.path.join(test_dir.path, 'mock-pom.xml')
+ step_config = {
+ 'pom-file': pom_file
+ }
+ step_implementer = self.create_step_implementer(
+ step_config=step_config,
+ parent_work_dir_path=parent_work_dir_path,
+ )
+
+ # run step with mock failure
+ mock_run_maven_step.side_effect = StepRunnerException('Mock error running maven')
+ actual_step_result = step_implementer._run_step()
+
+ # create expected step result
surefire_reports_dir = os.path.join(test_dir.path, 'target/surefire-reports')
- pom_content = bytes(
-'''
- 4.0.0
- {group_id}
- {artifact_id}
- {version}
-
- 1.8
- 1.8
-
-
-
-
- maven-surefire-plugin
- ${{surefire-plugin.version}}
-
-
-
-'''.format(
- group_id=group_id,
- artifact_id=artifact_id,
- version=version
- ), 'utf-8'
- )
-
- self.__run__run_step_test(
- test_dir=test_dir,
- mvn_mock=mvn_mock,
- write_effective_pom_mock=write_effective_pom_mock,
- generate_maven_settings_mock=generate_maven_settings_mock,
- pom_content=pom_content,
- group_id=group_id,
- artifact_id=artifact_id,
- surefire_reports_dir=surefire_reports_dir,
- raise_error_on_tests=True,
- expected_result_success=False,
- expected_result_message_regex=re.compile(
- r"Unit test failures. See 'maven-output'" \
- r" and 'surefire-reports' report artifacts for details:"
- r".*RAN: mvn"
- r".*STDOUT:"
- r".*mock out"
- r".*STDERR:"
- r".*mock error",
- re.DOTALL
- )
+ expected_step_result = StepResult(
+ step_name='unit-test',
+ sub_step_name='Maven',
+ sub_step_implementer_name='Maven'
+ )
+ expected_step_result.success = False
+ expected_step_result.message = "Error running 'maven test' to run unit tests. " \
+ "More details maybe found in 'maven-output' and `surefire-reports` " \
+ f"report artifact: Mock error running maven"
+ expected_step_result.add_artifact(
+ description="Standard out and standard error from maven.",
+ name='maven-output',
+ value='/mock/mvn_output.txt'
+ )
+ expected_step_result.add_artifact(
+ description="Surefire reports generated by maven.",
+ name='surefire-reports',
+ value=surefire_reports_dir
+ )
+
+ # verify step result
+ self.assertEqual(
+ actual_step_result,
+ expected_step_result
+ )
+
+ mock_write_working_file.assert_called_once()
+ mock_run_maven_step.assert_called_with(
+ mvn_output_file_path='/mock/mvn_output.txt'
)
diff --git a/tests/utils/test_maven.py b/tests/utils/test_maven.py
index 4f031610..01935aae 100644
--- a/tests/utils/test_maven.py
+++ b/tests/utils/test_maven.py
@@ -4,14 +4,15 @@
"""
import re
import xml.etree.ElementTree as ET
-from io import BytesIO
-from unittest.mock import patch
+from io import BytesIO, StringIO, TextIOWrapper
+from unittest.mock import patch, call, mock_open
import sh
-from testfixtures import TempDirectory
-from tests.helpers.base_test_case import BaseTestCase
from ploigos_step_runner.exceptions import StepRunnerException
from ploigos_step_runner.utils.maven import *
+from testfixtures import TempDirectory
+from tests.helpers.base_test_case import BaseTestCase
+from tests.helpers.test_utils import Any
class TestMavenUtils(BaseTestCase):
@@ -1040,4 +1041,256 @@ def test_write_effective_pom_fail_not_absolute_path(self, mvn_mock):
'help:effective-pom',
f'-f={pom_file_path}',
f'-Doutput={effective_pom_path}'
- )
\ No newline at end of file
+ )
+
+class TestMavenUtils_run_maven(BaseTestCase):
+ @patch('sh.mvn', create=True)
+ @patch('ploigos_step_runner.utils.maven.create_sh_redirect_to_multiple_streams_fn_callback')
+ @patch("builtins.open", new_callable=mock_open)
+ def test_success_defaults(self, mock_open, redirect_mock, mvn_mock):
+ with TempDirectory() as temp_dir:
+ mvn_output_file_path = os.path.join(temp_dir.path, 'maven_output.txt')
+ settings_file = '/fake/settings.xml'
+ pom_file = '/fake/pom.xml'
+ phases_and_goals = 'fake'
+
+ run_maven(
+ mvn_output_file_path=mvn_output_file_path,
+ settings_file=settings_file,
+ pom_file=pom_file,
+ phases_and_goals=phases_and_goals,
+ )
+
+ mock_open.assert_called_with(mvn_output_file_path, 'w')
+ redirect_mock.assert_has_calls([
+ call([
+ sys.stdout,
+ mock_open.return_value
+ ]),
+ call([
+ sys.stderr,
+ mock_open.return_value
+ ])
+ ])
+
+ mvn_mock.assert_called_once_with(
+ 'fake',
+ '-f', '/fake/pom.xml',
+ '-s', '/fake/settings.xml',
+ '--no-transfer-progress',
+ _out=Any(StringIO),
+ _err=Any(StringIO)
+ )
+
+ @patch('sh.mvn', create=True)
+ @patch('ploigos_step_runner.utils.maven.create_sh_redirect_to_multiple_streams_fn_callback')
+ @patch("builtins.open", new_callable=mock_open)
+ def test_success_with_single_profile(self, mock_open, redirect_mock, mvn_mock):
+ with TempDirectory() as temp_dir:
+ mvn_output_file_path = os.path.join(temp_dir.path, 'maven_output.txt')
+ settings_file = '/fake/settings.xml'
+ pom_file = '/fake/pom.xml'
+ phases_and_goals = 'fake'
+
+ run_maven(
+ mvn_output_file_path=mvn_output_file_path,
+ settings_file=settings_file,
+ pom_file=pom_file,
+ phases_and_goals=phases_and_goals,
+ profiles=['fake-profile']
+ )
+
+ mock_open.assert_called_with(mvn_output_file_path, 'w')
+ redirect_mock.assert_has_calls([
+ call([
+ sys.stdout,
+ mock_open.return_value
+ ]),
+ call([
+ sys.stderr,
+ mock_open.return_value
+ ])
+ ])
+
+ mvn_mock.assert_called_once_with(
+ 'fake',
+ '-f', '/fake/pom.xml',
+ '-s', '/fake/settings.xml',
+ '-P', 'fake-profile',
+ '--no-transfer-progress',
+ _out=Any(StringIO),
+ _err=Any(StringIO)
+ )
+
+ @patch('sh.mvn', create=True)
+ @patch('ploigos_step_runner.utils.maven.create_sh_redirect_to_multiple_streams_fn_callback')
+ @patch("builtins.open", new_callable=mock_open)
+ def test_success_with_multiple_profile(self, mock_open, redirect_mock, mvn_mock):
+ with TempDirectory() as temp_dir:
+ mvn_output_file_path = os.path.join(temp_dir.path, 'maven_output.txt')
+ settings_file = '/fake/settings.xml'
+ pom_file = '/fake/pom.xml'
+ phases_and_goals = 'fake'
+
+ run_maven(
+ mvn_output_file_path=mvn_output_file_path,
+ settings_file=settings_file,
+ pom_file=pom_file,
+ phases_and_goals=phases_and_goals,
+ profiles=['fake-profile1', 'fake-profile2']
+ )
+
+ mock_open.assert_called_with(mvn_output_file_path, 'w')
+ redirect_mock.assert_has_calls([
+ call([
+ sys.stdout,
+ mock_open.return_value
+ ]),
+ call([
+ sys.stderr,
+ mock_open.return_value
+ ])
+ ])
+
+ mvn_mock.assert_called_once_with(
+ 'fake',
+ '-f', '/fake/pom.xml',
+ '-s', '/fake/settings.xml',
+ '-P', 'fake-profile1,fake-profile2',
+ '--no-transfer-progress',
+ _out=Any(StringIO),
+ _err=Any(StringIO)
+ )
+
+ @patch('sh.mvn', create=True)
+ @patch('ploigos_step_runner.utils.maven.create_sh_redirect_to_multiple_streams_fn_callback')
+ @patch("builtins.open", new_callable=mock_open)
+ def test_success_with_no_tls(self, mock_open, redirect_mock, mvn_mock):
+ with TempDirectory() as temp_dir:
+ mvn_output_file_path = os.path.join(temp_dir.path, 'maven_output.txt')
+ settings_file = '/fake/settings.xml'
+ pom_file = '/fake/pom.xml'
+ phases_and_goals = 'fake'
+
+ run_maven(
+ mvn_output_file_path=mvn_output_file_path,
+ settings_file=settings_file,
+ pom_file=pom_file,
+ phases_and_goals=phases_and_goals,
+ tls_verify=False
+ )
+
+ mock_open.assert_called_with(mvn_output_file_path, 'w')
+ redirect_mock.assert_has_calls([
+ call([
+ sys.stdout,
+ mock_open.return_value
+ ]),
+ call([
+ sys.stderr,
+ mock_open.return_value
+ ])
+ ])
+
+ mvn_mock.assert_called_once_with(
+ 'fake',
+ '-f', '/fake/pom.xml',
+ '-s', '/fake/settings.xml',
+ '--no-transfer-progress',
+ '-Dmaven.wagon.http.ssl.insecure=true',
+ '-Dmaven.wagon.http.ssl.allowall=true',
+ '-Dmaven.wagon.http.ssl.ignore.validity.dates=true',
+ _out=Any(StringIO),
+ _err=Any(StringIO)
+ )
+
+ @patch('sh.mvn', create=True)
+ @patch('ploigos_step_runner.utils.maven.create_sh_redirect_to_multiple_streams_fn_callback')
+ @patch("builtins.open", new_callable=mock_open)
+ def test_success_transfer_progress(self, mock_open, redirect_mock, mvn_mock):
+ with TempDirectory() as temp_dir:
+ mvn_output_file_path = os.path.join(temp_dir.path, 'maven_output.txt')
+ settings_file = '/fake/settings.xml'
+ pom_file = '/fake/pom.xml'
+ phases_and_goals = 'fake'
+
+ run_maven(
+ mvn_output_file_path=mvn_output_file_path,
+ settings_file=settings_file,
+ pom_file=pom_file,
+ phases_and_goals=phases_and_goals,
+ no_transfer_progress=False
+ )
+
+ mock_open.assert_called_with(mvn_output_file_path, 'w')
+ redirect_mock.assert_has_calls([
+ call([
+ sys.stdout,
+ mock_open.return_value
+ ]),
+ call([
+ sys.stderr,
+ mock_open.return_value
+ ])
+ ])
+
+ mvn_mock.assert_called_once_with(
+ 'fake',
+ '-f', '/fake/pom.xml',
+ '-s', '/fake/settings.xml',
+ None,
+ _out=Any(StringIO),
+ _err=Any(StringIO)
+ )
+
+ @patch('sh.mvn', create=True)
+ @patch('ploigos_step_runner.utils.maven.create_sh_redirect_to_multiple_streams_fn_callback')
+ @patch("builtins.open", new_callable=mock_open)
+ def test_success_failure(self, mock_open, redirect_mock, mvn_mock):
+ with TempDirectory() as temp_dir:
+ mvn_output_file_path = os.path.join(temp_dir.path, 'maven_output.txt')
+ settings_file = '/fake/settings.xml'
+ pom_file = '/fake/pom.xml'
+ phases_and_goals = 'fake'
+
+ mvn_mock.side_effect = sh.ErrorReturnCode('mvn', b'mock stdout', b'mock error')
+
+ with self.assertRaisesRegex(
+ StepRunnerException,
+ re.compile(
+ r"Error running maven."
+ r".*RAN: mvn"
+ r".*STDOUT:"
+ r".*mock stdout"
+ r".*STDERR:"
+ r".*mock error",
+ re.DOTALL
+ )
+ ):
+ run_maven(
+ mvn_output_file_path=mvn_output_file_path,
+ settings_file=settings_file,
+ pom_file=pom_file,
+ phases_and_goals=phases_and_goals,
+ )
+
+ mock_open.assert_called_with(mvn_output_file_path, 'w')
+ redirect_mock.assert_has_calls([
+ call([
+ sys.stdout,
+ mock_open.return_value
+ ]),
+ call([
+ sys.stderr,
+ mock_open.return_value
+ ])
+ ])
+
+ mvn_mock.assert_called_once_with(
+ 'fake',
+ '-f', '/fake/pom.xml',
+ '-s', '/fake/settings.xml',
+ '--no-transfer-progress',
+ _out=Any(StringIO),
+ _err=Any(StringIO)
+ )