From 1ef455a8dfb210fc05a80d9f306762205df8cc72 Mon Sep 17 00:00:00 2001 From: Dennis Behm Date: Thu, 1 Jun 2023 08:37:13 +0200 Subject: [PATCH 1/8] Strategy to record logical files but skip scanning them (#308) * Introduce a method to record files as logicalFiles but skip scanning * Use DBB DependencyScannerRegistry * Cleanup of languageHint settings Signed-off-by: Dennis Behm --- build-conf/Assembler.properties | 3 - build-conf/Cobol.properties | 4 - build-conf/DBDgen.properties | 3 - build-conf/PLI.properties | 4 - build-conf/PSBgen.properties | 3 - build-conf/README.md | 39 +++-- build-conf/REXX.properties | 4 - build-conf/build.properties | 114 ++++--------- build-conf/defaultzAppBuildConf.properties | 96 +++++++++++ build.groovy | 17 ++ .../application-conf/README.md | 2 +- samples/application-conf/README.md | 2 +- samples/application-conf/file.properties | 22 ++- .../application-conf/file.properties | 4 - utilities/BuildUtilities.groovy | 25 ++- utilities/DependencyScannerUtilities.groovy | 153 ++++++++++++++++++ utilities/ImpactUtilities.groovy | 42 +++-- utilities/README.md | 8 +- utilities/ScannerUtilities.groovy | 28 ---- 19 files changed, 382 insertions(+), 191 deletions(-) create mode 100644 build-conf/defaultzAppBuildConf.properties create mode 100644 utilities/DependencyScannerUtilities.groovy delete mode 100644 utilities/ScannerUtilities.groovy diff --git a/build-conf/Assembler.properties b/build-conf/Assembler.properties index 1d00addf..bbfc7521 100644 --- a/build-conf/Assembler.properties +++ b/build-conf/Assembler.properties @@ -59,9 +59,6 @@ assembler_eqalangx=EQALANGX assembler_pgm=ASMA90 assembler_linkEditor=IEWBLINK -# ASM scanner language hint -dbb.DependencyScanner.languageHint=ASM :: **/*.asm, **/*.mac - # # additional libraries for assembler SYSLIB concatenation, comma-separated, see definitions in application-conf # assembler_assemblySyslibConcatenation= diff --git a/build-conf/Cobol.properties b/build-conf/Cobol.properties index e96a5bda..1920e9ed 100644 --- a/build-conf/Cobol.properties +++ b/build-conf/Cobol.properties @@ -62,10 +62,6 @@ cobol_compileErrorFeedbackXmlOptions=tracks space(200,40) dsorg(PS) blksize(2799 # List of output datasets to document deletions cobol_outputDatasets=${cobol_loadPDS} -# -# COBOL scanner language hint -dbb.DependencyScanner.languageHint=COB :: **/*.cbl, **/*.cpy - # # Set filter used to exclude certain information from the link edit scanning. # The value contains a comma separated list of patterns. diff --git a/build-conf/DBDgen.properties b/build-conf/DBDgen.properties index 6169131d..d1dcbc7a 100644 --- a/build-conf/DBDgen.properties +++ b/build-conf/DBDgen.properties @@ -40,6 +40,3 @@ dbdgen_linkEditor=IEWBLINK # DBDlib Deploy Type # dbdgen_deployType=DBDLIB - -# dbdgen scanner language hint -dbb.DependencyScanner.languageHint=ASM :: **/*.asm, **/*.mac, **/*.psb diff --git a/build-conf/PLI.properties b/build-conf/PLI.properties index 1bec3161..3fe88ba0 100644 --- a/build-conf/PLI.properties +++ b/build-conf/PLI.properties @@ -59,10 +59,6 @@ pli_compileErrorFeedbackXmlOptions=tracks space(200,40) dsorg(PS) blksize(27998) # List of output datasets to document deletions pli_outputDatasets=${pli_loadPDS},${pli_dbrmPDS} -# -# PL/I scanner language hint -dbb.DependencyScanner.languageHint=PLI :: **/*.pli, **/*.inc, **/*.cpy - # # additional libraries for compile SYSLIB concatenation, comma-separated, see definitions in application-conf # pli_compileSyslibConcatenation= diff --git a/build-conf/PSBgen.properties b/build-conf/PSBgen.properties index e5b65ce5..7a75c436 100644 --- a/build-conf/PSBgen.properties +++ b/build-conf/PSBgen.properties @@ -40,6 +40,3 @@ psbgen_linkEditor=IEWBLINK # PSBlib Deploy Type # psbgen_deployType=PSBLIB - -# psbgen scanner language hint -dbb.DependencyScanner.languageHint=ASM :: **/*.asm, **/*.mac, **/*.psb diff --git a/build-conf/README.md b/build-conf/README.md index 345faf25..113532b5 100644 --- a/build-conf/README.md +++ b/build-conf/README.md @@ -37,24 +37,40 @@ General properties used mainly by `build.groovy` but can also be a place to decl Property | Description --- | --- buildPropFiles | Comma separated list of additional build property files to load. Supports both absolute and relative file paths. Relative paths assumed to be relative to `zAppBuild/build-conf/`. +applicationDefaultPropFiles | Comma separated list of default application configuration property files to load. Supports both absolute and relative file paths. Relative paths assumed to be relative to `zAppBuild/build-conf/`. buildListFileExt | File extension that indicates the build file is really a build list. -languagePropertyQualifiers | List of language script property qualifiers. Each language script property has a unique qualifier to avoid collision with other language script properties. applicationConfRootDir | Alternate root directory for application-conf location. Allows for the deployment of the application-conf directories to a static location. Defaults to ${workspace}/${application} +createBuildOutputSubfolder | Option to create a subfolder with the build label within the build output dir (outDir). Default: true. +buildOutputTSformat | Defines the build timestamp format for build output subfolder and build label. requiredDBBToolkitVersion | Minimum required DBB ToolkitVersion to run this version of zAppBuild. requiredBuildProperties | Comma separated list of required build properties for zAppBuild/build.groovy. Build and language scripts will validate that *required* build properties have been set before the script runs. If any are missing or empty, then a validation error will be thrown. -formatConsoleOutput | Flag to log output in table views instead of printing raw JSON data -impactBuildOnBuildPropertyChanges | Boolean property to activate impact builds on changes of build properties within the application repository -impactBuildOnBuildPropertyList | List of build property lists referencing which language properties should cause an impact build when the given property is changed -continueOnScanFailure | Determine the behavior when facing a scanner failure. true (default) to continue scanning. false will terminate the process. -createBuildOutputSubfolder | Option to create a subfolder with the build label within the build output dir (outDir). Default: true. -documentDeleteRecords | Option determine if the build framework should document deletions of outputs in DBB Build Report. Default: false. Requires DBB Toolkit 1.1.3 and higher. -generateDb2BindInfoRecord | Flag to control the generation of a generic DBB build record for a build file to document the configured db2 bind information (application-conf/bind.properties). Default: false ** Can be overridden by a file property. dbb.file.tagging | Controls compile log and build report file tagging. Default: true. -dbb.LinkEditScanner.excludeFilter | DBB configuration property used by the link edit scanner to exclude load module entries metadataStoreType | DBB MetadataStore Type configuration property. Valid options are 'file' or 'db2'. Default: file metadataStoreFileLocation | DBB File MetadataStore location. Default: $USER metadataStoreDb2Url | DBB configuration property for Db2 URL. ***Can be overridden by build.groovy option -url, --url*** metadataStoreDb2ConnectionConf | DBB configuration property for Db2 configuration properties file. +dbb.gateway.type | DBB configuration property to determine which gateway type is used for the build process +dbb.gateway.procedureName | Interactive gateway Procedure Name +dbb.gateway.accountNumber | Interactive gateway Account Number +dbb.gateway.groupId | Interactive gateway Group ID +dbb.gateway.regionSize | Interactive gateway Region Size +dbb.gateway.logLevel | Interactive gateway Log Level + +### defaultzAppBuildConf.properties +General application properties used by zAppBuild. + +Property | Description +--- | --- +dbb.scannerMapping | DBB PropertyMapping specifying the scanner implementation to be used +gitRepositoryCompareService | Service URL for the Git provider to record a link to the git provider for a visual comparison of two hashes +continueOnScanFailure | Determine the behavior when facing a scanner failure. true (default) to continue scanning. false will terminate the process. +formatConsoleOutput | Flag to log output in table views instead of printing raw JSON data on verbose output +generateDb2BindInfoRecord | Flag to control the generation of a generic DBB build record for a build file to document the configured db2 bind information (application-conf/bind.properties). Default: false ** Can be overridden by a file property. +generateDb2BindInfoRecordProperties | Comma-separated list of the bind parameters to be added to the DBB build record. +impactBuildOnBuildPropertyChanges | Boolean property to activate impact builds on changes of build properties within the application repository +impactBuildOnBuildPropertyList | List of build property lists referencing which language properties should cause an impact build when the given property is changed +documentDeleteRecords | Option determine if the build framework should document deletions of outputs in DBB Build Report. Default: false. +dbb.LinkEditScanner.excludeFilter | DBB configuration property used by the link edit scanner to exclude load module entries ### dependencyReport.properties Properties used by the impact utilities to generate a report of external impacted files @@ -90,7 +106,6 @@ assembler_compileErrorFeedbackXmlOptions | BPXWDYN creation options for SYSXMLSD assembler_outputDatasets | List of output datasets to document deletions ** Can be overridden by a file property. assembler_pgm | MVS program name of the high level assembler assembler_linkEditor | MVS program name of the link editor -dbb.DependencyScanner.languageHint | DBB configuration property used by the dependency scanner to disambiguate a source file's language assembler_dependenciesDatasetMapping | DBB property mapping to map dependencies to different target datasets ### BMS.properties @@ -140,7 +155,6 @@ cobol_linkEditor | MVS program name of the link editor cobol_dependenciesAlternativeLibraryNameMapping | a map to define target dataset definition for alternate include libraries cobol_dependenciesDatasetMapping | dbb property mapping to map dependencies to different target datasets -dbb.DependencyScanner.languageHint | DBB configuration property used by the dependency scanner to disambiguate a source file's language ### LinkEdit.properties Build properties used by zAppBuild/language/LinkEdit.groovy @@ -188,7 +202,6 @@ pli_outputDatasets | List of output datasets to document deletions ** Can be ov pli_listOptions | BPXWDYN creation options for LIST data sets pli_dependenciesAlternativeLibraryNameMapping | a map to define target dataset definition for alternate include libraries pli_dependenciesDatasetMapping | dbb property mapping to map dependencies to different target datasets -dbb.DependencyScanner.languageHint | DBB configuration property used by the dependency scanner to disambiguate a source file's language ### MFS.properties Build properties used by zAppBuild/language/MFS.groovy @@ -226,7 +239,6 @@ dbdgen_outputDatasets | List of output datasets to document deletions ** Can be dbdgen_pgm | MVS program name of the high level assembler dbdgen_linkEditor | MVS program name of the link editor dbdgen_deployType | Deploy Type of build outputs -dbb.DependencyScanner.languageHint | DBB configuration property used by the dependency scanner to disambiguate a source file's language ### PSBgen.properties Build properties used by zAppBuild/language/PSBgen.groovy @@ -247,7 +259,6 @@ psbgen_outputDatasets | List of output datasets to document deletions ** Can be psbgen_pgm | MVS program name of the high level assembler psbgen_linkEditor | MVS program name of the link editor psbgen_deployType | Deploy Type of build outputs -dbb.DependencyScanner.languageHint | DBB configuration property used by the dependency scanner to disambiguate a source file's language ### ACBgen.properties Build properties used by zAppBuild/language/PSBgen.groovy; ACBgen is part of the PSBgen process diff --git a/build-conf/REXX.properties b/build-conf/REXX.properties index 0e42a81a..e0dd7a52 100644 --- a/build-conf/REXX.properties +++ b/build-conf/REXX.properties @@ -44,10 +44,6 @@ rexx_printTempOptions=cyl space(5,5) unit(vio) blksize(133) lrecl(133) recfm(f,b # List of output datasets to document deletions rexx_outputDatasets=${rexx_cexecPDS},${rexx_loadPDS} -# -# rexx scanner language hint -dbb.DependencyScanner.languageHint=rexx :: **/*.rexx - # # Set filter used to exclude certain information from the link edit scanning. # The value contains a comma separated list of patterns. diff --git a/build-conf/build.properties b/build-conf/build.properties index 7633c347..eb0732b9 100644 --- a/build-conf/build.properties +++ b/build-conf/build.properties @@ -1,4 +1,13 @@ -# Build properties used by build.groovy +####################################################################### +# build.properties configuration to specify +# global build properties for zAppBuild +# +####################################################################### + + +####################################################################### +# Global build properties used by zappbuild +# # # Comma separated list of additional build property files to load @@ -6,14 +15,13 @@ buildPropFiles=datasets.properties,dependencyReport.properties,Assembler.properties,BMS.properties,MFS.properties,PSBgen.properties,DBDgen.properties,ACBgen.properties,Cobol.properties,LinkEdit.properties,PLI.properties,REXX.properties,ZunitConfig.properties,Transfer.properties # -# file extension that indicates the build file is really a build list or build list filter -buildListFileExt=txt +# Comma separated list of default application configuration property files to load +# Supports both relative path (to zAppBuild/build-conf/) and absolute path +applicationDefaultPropFiles=defaultzAppBuildConf.properties # -# Service URL for the Git provider to have a visual comparision of two hashes -# Leveraged as a build result property /compare/ -# samples: GitHub : /compare/ ; GitLab : /-/compare/ -gitRepositoryCompareService=/compare/ +# file extension that indicates the build file is really a build list or build list filter +buildListFileExt=txt # # Alternate root directory for application-conf locations. Allows for the deployment of @@ -42,74 +50,6 @@ gitRepositoryCompareService=/compare/ # Defaults to ${workspace} applicationConfRootDir= -# -# Minimum required DBB ToolkitVersion to run this version of zAppBuild -# Build initialization process validates the DBB Toolkit Version in use and matches that against this setting -requiredDBBToolkitVersion=2.0.0 - -# -# Comma separated list of required build properties for zAppBuild/build.groovy -requiredBuildProperties=buildOrder,buildListFileExt - -# -# Flag to log output in table views instead of printing raw JSON data -# default = false -formatConsoleOutput=false - -# -# impactBuildOnBuildPropertyChanges controls if impact calculation should analyze -# build property changes for COBOL, PLI, ASM. -# default = false -impactBuildOnBuildPropertyChanges=false - -# -# list of build property lists referencing which language properties should cause an impact build when the given property is changed -# properties need to be managed in property files within the application repository to detect the change; applies only to impact builds -# general pattern: langPrefix_impactPropertyList, optional: langPrefix_impactPropertyListCICS and langPrefix_impactPropertyListSQL -impactBuildOnBuildPropertyList=[${assembler_impactPropertyList},${assembler_impactPropertyListCICS},${assembler_impactPropertyListSQL},${bms_impactPropertyList},${cobol_impactPropertyList},${cobol_impactPropertyListCICS},${cobol_impactPropertyListSQL},${dbdgen_impactPropertyList},${linkedit_impactPropertyList},${mfs_impactPropertyList},${pli_impactPropertyList},${pli_impactPropertyListCICS},${pli_impactPropertyListSQL},${psbgen_impactPropertyList}] - -# createTestcaseDependency controls if a dependency should be set up between the testcase -# and the corresponding application program. If this property set to true, a dependency -# to the program is created for the testcase, which is then impacted by a change -# of the program. In this case, the testcase is recompiled everytime the program is modified. -# When set to false, the testcase is not impacted by the change of the program. -# Default: false -createTestcaseDependency=false - -# generateDb2BindInfoRecord controls if zAppBuild generates a generic DBB build record for a build file -# to document the configured db2 bind options (application-conf/bind.properties) . -# This allows to pass the information into the packaging step and on to your deployment manager, like UCD. -# Implemented in Assembler.groovy, Cobol.groovy and PLI.groovy -# See also generateDb2BindInfoRecordProperties for the list of properties which are documented -# Default: false -generateDb2BindInfoRecord=false - -# generateDb2BindInfoRecordProperties is a comma-separated list of existing bind parameters configured to zAppBuild. -# See application-conf/bind.properties for available properties. -generateDb2BindInfoRecordProperties=bind_collectionID,bind_packageOwner,bind_qualifier - -# dbb.file.tagging controls compile log and build report file tagging. If true, files -# written as UTF-8 or ASCII are tagged. -# If the environment variable _BPXK_AUTOCVT is set ALL, file tagging may have an -# adverse effect if viewing log files and build report via Jenkins. -# In this case, set dbb.file.tagging to false or comment out the line. Default: true -dbb.file.tagging=true - -# Set filter used to exclude certain information from the link edit scanning. -# The value contains a comma separated list of patterns. -# example: A filter of *.SUB1, *.SUB2 will exclude modules SUB1 and SUB2 -# from any dataset. To exclude member HELLO in PDS TEST.ASM will -# be matched by the pattern TEST.ASM.HELLO. The pattern TEST.ASM.* -# will match any member in the data set TEST.COBOL. -# The following filter excludes CICS and LE Library references. -dbb.LinkEditScanner.excludeFilter = ${SDFHLOAD}.*, ${SCEELKED}.* - -# -# Determine the behavior when facing a scanner failure -# 'true' proceeds with the build and report the a warning (default) -# 'false' will terminate the build process -continueOnScanFailure=true - # # Determine if a subfolder with a timestamp should be created in the buildOutDir location. # Applies to all build types except userBuild @@ -123,14 +63,20 @@ createBuildOutputSubfolder=true buildOutputTSformat=yyyyMMdd.HHmmss.mmm # -# Flag to determine if the build framework should document deletions of outputs in DBB Build Report -# for build files being mapped to language scripts -# -# Requires the DBB toolkit 1.1.3 or higher. Backward compatibility of zAppBuild is preserved, -# when feature is turned off +# Minimum required DBB ToolkitVersion to run this version of zAppBuild +# Build initialization process validates the DBB Toolkit Version in use and matches that against this setting +requiredDBBToolkitVersion=2.0.0 + # -# Default : false -documentDeleteRecords=false +# Comma separated list of required build properties for zAppBuild/build.groovy +requiredBuildProperties=buildOrder,buildListFileExt + +# dbb.file.tagging controls compile log and build report file tagging. If true, files +# written as UTF-8 or ASCII are tagged. +# If the environment variable _BPXK_AUTOCVT is set ALL, file tagging may have an +# adverse effect if viewing log files and build report via Jenkins. +# In this case, set dbb.file.tagging to false or comment out the line. Default: true +dbb.file.tagging=true # MetadataStore configuration properties: @@ -145,12 +91,12 @@ metadataStoreType=file #metadataStoreDb2Url=jdbc:db2: # Db2 connection configuration property file -# Sample is povided at $DBB_HOME/conf/db2Connection.conf +# Sample is povided at $DBB_HOME/conf/db2Connection.conf #metadataStoreDb2ConnectionConf= # The dbb.gateway.type property determines which gateway type is used for the entire build process -# Possible values are 'legacy' and 'interactive. Default if not indicated is 'legacy' +# Possible values are 'legacy' and 'interactive'. Default if not indicated is 'legacy' dbb.gateway.type=legacy # Procedure Name - specified with the procname parameter diff --git a/build-conf/defaultzAppBuildConf.properties b/build-conf/defaultzAppBuildConf.properties new file mode 100644 index 00000000..9b1b6cc9 --- /dev/null +++ b/build-conf/defaultzAppBuildConf.properties @@ -0,0 +1,96 @@ +####################################################################### +# Default application properties used by zappbuild +# +# treated as global defaults, if not overridden by +# settings in the /application-conf directory + +# +# dbb.scannerMapping to map file extensions to DBB dependency scanner configurations +# +# this maps file extensions to the scanner configuration for the DBB dependency scanners +# +# Schema +# "scannerClass":"ScannerImplementation" : "languageHint":"DBBScannerHint" :: comma separated list of file extensions +# +# Be aware, that the DependencyScannerRegistry comes with a set of default scanner configurations, +# which are documented at: +# https://www.ibm.com/docs/api/v1/content/SS6T76_2.0.0/javadoc/com/ibm/dbb/dependency/DependencyScannerRegistry.html +# +# If a file extension of a build file is not specified in the mapping, +# zAppBuild will skip scanning the file and only record a LogicalFile without capturing dependencies. +# +# Default mappings (always present based on DependencyScannerRegistry) +dbb.scannerMapping = "scannerClass":"DependencyScanner", "languageHint":"COB" :: cbl,cpy,cob +dbb.scannerMapping = "scannerClass":"DependencyScanner", "languageHint":"C" :: c, h +dbb.scannerMapping = "scannerClass":"DependencyScanner", "languageHint":"ASM" :: asm, mac +dbb.scannerMapping = "scannerClass":"DependencyScanner", "languageHint":"CPP" :: cpp, hpp +dbb.scannerMapping = "scannerClass":"DependencyScanner", "languageHint":"PLI" :: pli, inc +dbb.scannerMapping = "scannerClass":"ZUnitConfigScanner" :: bzucfg +# Custom mappings +dbb.scannerMapping = "scannerClass":"DependencyScanner", "languageHint":"REXX" :: rexx + +# +# Service URL for the Git provider to have a visual comparison of two hashes +# Leveraged as a build result property /compare/ +# samples: GitHub : /compare/ ; GitLab : /-/compare/ +gitRepositoryCompareService=/compare/ + +# +# Determine the behavior when facing a scanner failure +# 'true' proceeds with the build and reports a warning +# 'false' will terminate the build process (default) +continueOnScanFailure=false + +# +# Flag to log output in table views instead of printing raw JSON data +# default = false +formatConsoleOutput=false + +# createTestcaseDependency controls if a dependency should be set up between the testcase +# and the corresponding application program. If this property set to true, a dependency +# to the program is created for the testcase, which is then impacted by a change +# of the program. In this case, the testcase is recompiled everytime the program is modified. +# When set to false, the testcase is not impacted by the change of the program. +# Default: false +createTestcaseDependency=false + +# generateDb2BindInfoRecord controls if zAppBuild generates a generic DBB build record for a build file +# to document the configured db2 bind options (application-conf/bind.properties) . +# This allows to pass the information into the packaging step and on to your deployment manager, like UCD. +# Implemented in Assembler.groovy, Cobol.groovy and PLI.groovy +# See also generateDb2BindInfoRecordProperties for the list of properties which are documented +# Default: false +generateDb2BindInfoRecord=false + +# generateDb2BindInfoRecordProperties is a comma-separated list of existing bind parameters configured to zAppBuild. +# See application-conf/bind.properties for available properties. +generateDb2BindInfoRecordProperties=bind_collectionID,bind_packageOwner,bind_qualifier + +# +# impactBuildOnBuildPropertyChanges controls if impact calculation should analyze +# build property changes for COBOL, PLI, ASM. +# default = false +impactBuildOnBuildPropertyChanges=false + +# +# list of build property lists referencing which language properties should cause an impact build when the given property is changed +# properties need to be managed in property files within the application repository to detect the change; applies only to impact builds +# general pattern: langPrefix_impactPropertyList, optional: langPrefix_impactPropertyListCICS and langPrefix_impactPropertyListSQL +impactBuildOnBuildPropertyList=[${assembler_impactPropertyList},${assembler_impactPropertyListCICS},${assembler_impactPropertyListSQL},${bms_impactPropertyList},${cobol_impactPropertyList},${cobol_impactPropertyListCICS},${cobol_impactPropertyListSQL},${dbdgen_impactPropertyList},${linkedit_impactPropertyList},${mfs_impactPropertyList},${pli_impactPropertyList},${pli_impactPropertyListCICS},${pli_impactPropertyListSQL},${psbgen_impactPropertyList}] + + +# Set filter used to exclude certain information from the link edit scanning. +# The value contains a comma separated list of patterns. +# example: A filter of *.SUB1, *.SUB2 will exclude modules SUB1 and SUB2 +# from any dataset. To exclude member HELLO in PDS TEST.ASM will +# be matched by the pattern TEST.ASM.HELLO. The pattern TEST.ASM.* +# will match any member in the data set TEST.COBOL. +# The following filter excludes CICS and LE Library references. +dbb.LinkEditScanner.excludeFilter = ${SDFHLOAD}.*, ${SCEELKED}.* + +# +# Flag to determine if the build framework should document deletions of outputs in DBB Build Report +# for build files being mapped to language scripts +# +# Default : false +documentDeleteRecords=false diff --git a/build.groovy b/build.groovy index 609dcb90..ffae506b 100644 --- a/build.groovy +++ b/build.groovy @@ -19,6 +19,7 @@ import groovy.cli.commons.* @Field def impactUtils= loadScript(new File("utilities/ImpactUtilities.groovy")) @Field def reportingUtils= loadScript(new File("utilities/ReportingUtilities.groovy")) @Field def filePropUtils= loadScript(new File("utilities/FilePropUtilities.groovy")) +@Field def dependencyScannerUtils= loadScript(new File("utilities/DependencyScannerUtilities.groovy")) @Field String hashPrefix = ':githash:' @Field String giturlPrefix = ':giturl:' @Field String gitchangedfilesPrefix = ':gitchangedfiles:' @@ -214,6 +215,10 @@ def initializeBuildProcess(String[] args) { // verify/create/clone the collections for this build impactUtils.verifyCollections() + + // loading the scanner mapping to fill the DependencyScannerRegistry + dependencyScannerUtils.populateDependencyScannerRegistry() + } /* @@ -341,6 +346,18 @@ def populateBuildProperties(def opts) { props.load(new File(propFile)) } } + + // load additional build property files + if (props.applicationDefaultPropFiles) { + String[] applicationDefaultPropFiles = props.applicationDefaultPropFiles.split(',') + applicationDefaultPropFiles.each { propFile -> + if (!propFile.startsWith('/')) + propFile = "${buildConf}/${propFile}" + + if (opts.v) println "** Loading property file ${propFile}" + props.load(new File(propFile)) + } + } // load application.properties diff --git a/samples/MortgageApplication/application-conf/README.md b/samples/MortgageApplication/application-conf/README.md index 9475d1f1..ee334888 100644 --- a/samples/MortgageApplication/application-conf/README.md +++ b/samples/MortgageApplication/application-conf/README.md @@ -30,7 +30,7 @@ Location of file properties, script mappings and file level property overrides. Property | Description --- | --- dbb.scriptMapping | DBB configuration file properties association build files to language scripts -dbb.scannerMapping | DBB scanner mapping to overwrite the file scanner. File property +dbb.scannerMapping | zAppBuild configuration to map files extensions to DBB dependency scanner configurations cobol_testcase | File property to indicate a generated zUnit cobol test case to use a different set of source and output libraries ### BMS.properties diff --git a/samples/application-conf/README.md b/samples/application-conf/README.md index 1a4be3d3..02f049f9 100644 --- a/samples/application-conf/README.md +++ b/samples/application-conf/README.md @@ -39,7 +39,7 @@ Location of file properties, script mappings and file-level property overrides. Property | Description --- | --- dbb.scriptMapping | DBB configuration file properties association build files to language scripts -dbb.scannerMapping | DBB scanner mapping to overwrite the file scanner. File property +dbb.scannerMapping | zAppBuild configuration override/expansion to map files extensions to DBB dependency scanner configurations isSQL | File property overwrite to indicate that a file requires to include SQL parameters isCICS | File property overwrite to indicate that a file requires to include CICS parameters isMQ | File property overwrite to indicate that a file requires to include MQ parameters diff --git a/samples/application-conf/file.properties b/samples/application-conf/file.properties index 57018c23..9f8f39cc 100644 --- a/samples/application-conf/file.properties +++ b/samples/application-conf/file.properties @@ -14,8 +14,26 @@ dbb.scriptMapping = ZunitConfig.groovy :: **/*.bzucfg dbb.scriptMapping = Transfer.groovy :: **/*.jcl, **/*.xml # -# Scanner mappings for application programs that require a custom scanner -dbb.scannerMapping = ZUnitConfigScanner :: **/*.bzucfg +# dbb.scannerMapping to map files extensions to DBB dependency scanner configurations +# +# to override/expand the definitions from build-conf/defaultzAppBuildConf.properties +# +# this maps file extensions to scanner configuration for the DBB dependency scanners +# also see: +# https://www.ibm.com/docs/api/v1/content/SS6T76_2.0.0/javadoc/com/ibm/dbb/dependency/DependencyScannerRegistry.html +# +# Schema +# "scannerClass":"ScannerImplementation" : "languageHint":"DBBScannerHint" :: comma separated list of file extensions +# +# Note - if an extension of a build file is not specified in the mapping, +# zAppBuild will skip scanning the file and only record a LogicalFile without capturing dependencies. +# +# dbb.scannerMapping = "scannerClass":"DependencyScanner", "languageHint":"COB" :: cbl,cpy,cob +# dbb.scannerMapping = "scannerClass":"DependencyScanner", "languageHint":"C" :: c, h +# dbb.scannerMapping = "scannerClass":"DependencyScanner", "languageHint":"ASM" :: asm, mac +# dbb.scannerMapping = "scannerClass":"DependencyScanner", "languageHint":"CPP" :: cpp, hpp +# dbb.scannerMapping = "scannerClass":"DependencyScanner", "languageHint":"PLI" :: pli, inc +# dbb.scannerMapping = "scannerClass":"ZUnitConfigScanner" :: bzucfg # # General file level overwrites through DBB Build Properties diff --git a/test/applications/HelloWorld/application-conf/file.properties b/test/applications/HelloWorld/application-conf/file.properties index 7553c3e9..a2fc2cfa 100644 --- a/test/applications/HelloWorld/application-conf/file.properties +++ b/test/applications/HelloWorld/application-conf/file.properties @@ -13,10 +13,6 @@ dbb.scriptMapping = PLI.groovy :: **/*.pli dbb.scriptMapping = ZunitConfig.groovy :: **/*.bzucfg dbb.scriptMapping = Transfer.groovy :: **/*.jcl, **/*.xml -# -# Scanner mappings for application programs that require a custom scanner -dbb.scannerMapping = ZUnitConfigScanner :: **/*.bzucfg - # # General file level overwrites through DBB Build Properties # isCICS = true :: **/cobol/member.cbl diff --git a/utilities/BuildUtilities.groovy b/utilities/BuildUtilities.groovy index 6599bcd8..be366709 100644 --- a/utilities/BuildUtilities.groovy +++ b/utilities/BuildUtilities.groovy @@ -18,6 +18,8 @@ import groovy.ant.* @Field BuildProperties props = BuildProperties.getInstance() @Field HashSet copiedFileCache = new HashSet() @Field def gitUtils = loadScript(new File("GitUtilities.groovy")) +@Field def dependencyScannerUtils= loadScript(new File("DependencyScannerUtilities.groovy")) + /* * assertBuildProperties - verify that required build properties for a script exist @@ -116,7 +118,11 @@ def copySourceFiles(String buildFile, String srcPDS, String dependencyDatasetMap // Manually create logical file for the user build program String lname = CopyToPDS.createMemberName(buildFile) - String language = props.getFileProperty('dbb.DependencyScanner.languageHint', buildFile) ?: 'UNKN' + def scanner = dependencyScannerUtils.getScanner(buildFile) + String language = 'UNKN' + if (scanner instanceof com.ibm.dbb.dependency.DependencyScanner && ((DependencyScanner) scanner).getLanguageHint() != null) { + language = ((DependencyScanner) scanner).getLanguageHint() + } LogicalFile lfile = new LogicalFile(lname, buildFile, language, depFileData.isCICS, depFileData.isSQL, depFileData.isDLI) // get list of dependencies from userBuildDependencyFile @@ -468,19 +474,6 @@ def relativizeFolderPath(String folder, String path) { return path } -/* - * getScannerInstantiates - returns the mapped scanner or default scanner - */ -def getScanner(String buildFile){ - if (props.runzTests && props.runzTests.toBoolean()) { - scannerUtils= loadScript(new File("ScannerUtilities.groovy")) - scanner = scannerUtils.getScanner(buildFile) - } - else { - if (props.verbose) println("*** Scanning file with the default scanner") - scanner = new DependencyScanner() - } -} /* * createLanguageDatasets - gets the language used to create the datasets @@ -794,6 +787,7 @@ def getShortGitHash(String buildFile) { return null } + /** * createPathMatcherPattern * Generic method to build PathMatcher from a build property @@ -854,5 +848,4 @@ def printLogicalFileAttributes(LogicalFile logicalFile) { println "Program attributes: CICS=$cicsFlag, SQL=$sqlFlag, DLI=$dliFlag, MQ=$mqFlag" } - - \ No newline at end of file + diff --git a/utilities/DependencyScannerUtilities.groovy b/utilities/DependencyScannerUtilities.groovy new file mode 100644 index 00000000..357c2649 --- /dev/null +++ b/utilities/DependencyScannerUtilities.groovy @@ -0,0 +1,153 @@ +@groovy.transform.BaseScript com.ibm.dbb.groovy.ScriptLoader baseScript +import com.ibm.dbb.metadata.* +import com.ibm.dbb.dependency.* +import com.ibm.dbb.build.* +import groovy.transform.* +import groovy.xml.MarkupBuilder +import groovy.json.JsonParserType +import groovy.json.JsonBuilder +import groovy.json.JsonSlurper + +// define script properties +@Field BuildProperties props = BuildProperties.getInstance() + +/** + * DependencyScannerUtilties + * + * a collection of helper methods to + * + * * retrieve the scanner for a build file -getScanner() + * * populate the scanner registry from the configuration in + * build-conf or application-conf + * + */ + +/* + * getScanner() + * + * returns the mapped scanner or null if build file is not mapped + * + */ +def getScanner(String buildFile){ + + def scanner = null + + // check scannerMapping + scanner = DependencyScannerRegistry.getScanner(buildFile) + + if (scanner){ + if (scanner instanceof com.ibm.dbb.dependency.DependencyScanner) { + // Workaround - if no language hint exists the registry returned the default + // Scanner, and the file is not mapped + if (((DependencyScanner) scanner).getLanguageHint() == null) { + if (props.verbose) println("*** $buildFile is not mapped to a DBB Dependency scanner.") + scanner = null + } + } + } + else { + if (props.verbose) println("*** No scanner specified for $buildFile") + } + + return scanner +} + +/* + * populate DependencyScannerRegistry() + * + * this method is populating the DBB scanner registry based on the dbb.scannerMapping property + * + * also see application-conf/file.properties + * + */ + +def populateDependencyScannerRegistry() { + + println("** Loading DBB scanner mapping configuration dbb.scannerMapping") + + // loading scannerMappings + PropertyMappings scannerMapping = new PropertyMappings("dbb.scannerMapping") + + if (scannerMapping) { + // get all values + scannerMapping.getValues().each{ scannerConfig -> + + Map scannerConfigMap = parseConfigStringToMap(scannerConfig) + if (scannerConfigMap) { + scannerClass = scannerConfigMap.scannerClass + languageHint = scannerConfigMap.languageHint ? scannerConfigMap.languageHint : "none" + + // get file patterns / extensions + fileExtensionsPatterns = props.getFilePropertyPatterns("dbb.scannerMapping", scannerConfig) + if (fileExtensionsPatterns) { + fileExtensionsPatterns.each{ fileExt -> + + // define scanner + def scanner + + // evaluate configuration + if (scannerClass == "DependencyScanner") { + scanner = new DependencyScanner() + if (scannerConfigMap.languageHint) scanner.setLanguageHint(languageHint) + } else if (scannerClass == "ZUnitConfigScanner") { + scanner = new ZUnitConfigScanner() + } else { + errorMsg = "*! DependencyScannerUtilities.populateDependencyScannerRegistry() - Specified Dependency Scanner class $scannerClass does not exist. Process exiting." + println errorMsg + System.exit(3) + } + + // adding scanner mapping + // if (props.verbose) println("*** Adding scanner mapping for file extension $fileExt : (languageHint: $languageHint, Scanner Class: $scannerClass)") + DependencyScannerRegistry.addScanner(fileExt, scanner) + } + } + else { + println("**! Warning - No Patterns found for $scannerConfig for build property mapping dbb.scannerMapping.") + } + } + else { + println("**! The scanner configuration $scannerConfig could not successfully be parsed and is skipped.") + } + } + } + else { + println("**! Warning - Build configuration is not specifying the scanner mapping configuration - dbb.scannerMapping . Using default map of file extensions to IDependencyScanner instances. See DBB toolkit Javadoc.") + } +} + +/* + * Helper Method for populateDependencyScannerRegistry() to read through the string + * + * Decision was to not use JSON for this. + * + * Tests: + * + * "languageHint:COB,scannerClass:DependencyScanner" + * "languageHint:COB, scannerClass:DependencyScanner" + * "languageHint : COB, scannerClass : DependencyScanner" + * "languageHint : COB, scannerClass : DependencyScanner" + * "scannerClass : DependencyScanner ,languageHint : COB" + * "'scannerClass' : 'DependencyScanner' ,'languageHint' : 'COB'" + * '"scannerClass" : "DependencyScanner" ,"languageHint" : "COB"' + * '"scannerClass" : "DependencyScanner" ,"languageHint" : "COB"' + * '"scannerClass" : "DependencyScanner"' + * + */ +def parseConfigStringToMap(String configString) { + // map + Map scannerConfigMap = new HashMap() + + // string parsing + configString.replaceAll("'","").replaceAll('"','').split(',').each(){ entry -> + def pair = entry.split(':') + if(pair.size() == 2) { + scannerConfigMap.put(pair[0].trim(),pair[1].trim()) + } + } + + // validate existance of scannerClass definition + assert scannerConfigMap.scannerClass != null + + return scannerConfigMap +} \ No newline at end of file diff --git a/utilities/ImpactUtilities.groovy b/utilities/ImpactUtilities.groovy index b11783fd..fd59f861 100644 --- a/utilities/ImpactUtilities.groovy +++ b/utilities/ImpactUtilities.groovy @@ -13,6 +13,7 @@ import java.util.regex.* @Field BuildProperties props = BuildProperties.getInstance() @Field def gitUtils= loadScript(new File("GitUtilities.groovy")) @Field def buildUtils= loadScript(new File("BuildUtilities.groovy")) +@Field def dependencyScannerUtils= loadScript(new File("DependencyScannerUtilities.groovy")) @Field String hashPrefix = ':githash:' @Field def resolverUtils @@ -466,7 +467,7 @@ def scanOnlyStaticDependencies(List buildList){ if(langPrefix != null){ String isLinkEdited = props.getFileProperty("${langPrefix}_linkEdit", buildFile) - def scanner = buildUtils.getScanner(buildFile) + def scanner = dependencyScannerUtils.getScanner(buildFile) LogicalFile logicalFile = scanner.scan(buildFile, props.workspace) String member = CopyToPDS.createMemberName(buildFile) @@ -540,11 +541,18 @@ def updateCollection(changedFiles, deletedFiles, renamedFiles) { // make sure file is not an excluded file if ( new File("${props.workspace}/${file}").exists() && !buildUtils.matches(file, excludeMatchers)) { // files in a collection are stored as relative paths from a source directory - if (props.verbose) println "*** Scanning file $file (${props.workspace}/${file})" - def scanner = buildUtils.getScanner(file) + def scanner = dependencyScannerUtils.getScanner(file) try { - def logicalFile = scanner.scan(file, props.workspace) + def logicalFile + if (scanner != null) { + if (props.verbose) println "*** Scanning file $file (${props.workspace}/${file} with ${scanner.getClass()})" + logicalFile = scanner.scan(file, props.workspace) + } else { + if (props.verbose) println "*** Skipped scanning file $file (${props.workspace}/${file})" + // New logical file with Membername, buildfile, language set to file extension + logicalFile = new LogicalFile(CopyToPDS.createMemberName(file), file, file.substring(file.lastIndexOf(".") + 1).toUpperCase(), false, false, false) + } if (props.verbose) println "*** Logical file for $file =\n$logicalFile" // Update logical file with dependencies to build properties @@ -555,7 +563,7 @@ def updateCollection(changedFiles, deletedFiles, renamedFiles) { // If configured, update test case program dependencies if (props.createTestcaseDependency && props.createTestcaseDependency.toBoolean()) { // If the file is a zUnit configuration file (BZUCFG) - if (scanner.getClass() == com.ibm.dbb.dependency.ZUnitConfigScanner) { + if (scanner != null && scanner.getClass() == com.ibm.dbb.dependency.ZUnitConfigScanner) { def logicalDependencies = logicalFile.getLogicalDependencies() @@ -811,29 +819,23 @@ def addBuildPropertyDependencies(String buildProperties, LogicalFile logicalFile } } -/** - * isMappedAsZUnitConfigFile - * method to check if a file is mapped with the zUnitConfigScanner, indicating it's a zUnit CFG file - */ -def isMappedAsZUnitConfigFile(mapping, file) { - return (mapping.isMapped("ZUnitConfigScanner", file)) -} + /** * sortFileList * sort a list, putting the lines that defines files mapped as zUnit CFG files to the end */ def sortFileList(list) { - def mapping = new PropertyMappings("dbb.scannerMapping") + list.sort{s1, s2 -> - if (isMappedAsZUnitConfigFile(mapping, s1)) { - if (isMappedAsZUnitConfigFile(mapping, s2)) { + if (isMappedAsZUnitConfigFile(s1)) { + if (isMappedAsZUnitConfigFile(s2)) { return 0; } else { return 1; } } else { - if (isMappedAsZUnitConfigFile(mapping, s2)) { + if (isMappedAsZUnitConfigFile(s2)) { return -1; } else { return 0; @@ -841,3 +843,11 @@ def sortFileList(list) { } } } + +/** + * isMappedAsZUnitConfigFile + * method to check if a file is mapped with the zUnitConfigScanner, indicating it's a zUnit CFG file + */ +def isMappedAsZUnitConfigFile(String file) { + return (dependencyScannerUtils.getScanner(file).getClass() == com.ibm.dbb.dependency.ZUnitConfigScanner) +} \ No newline at end of file diff --git a/utilities/README.md b/utilities/README.md index 8466e2f6..254a1ea4 100644 --- a/utilities/README.md +++ b/utilities/README.md @@ -1,12 +1,12 @@ # Utility Files -This folder contains common utilty files used by the zAppBuild `build.groovy` script and language scripts. +This folder contains common utility and helper files used by the zAppBuild `build.groovy` script and language scripts. File | Description --- | --- -ADMIN.pw | Encrypted password file for password "ADMIN" which is the default ID and password for the DBB Web Application Liberty server. Convenient for initial set-up and testing of DBB functionality. For more information on creating password files see the documentation for the [Repository Client](https://www.ibm.com/support/knowledgecenter/SS6T76_1.0.4/buildresult.html#repository-client) in the DBB Knowledge Center. BindUtilities.groovy | Use for the DB2 binding. +BuildReportUtilities.groovy | Helper to populate additional build report entries. BuildUtilities.groovy | Common build utility methods. -FilePropUtilities.groovy | File property management utilities. +DependencyScannerUtilities.groovy | Populates the DependencyScannerRegistry and returns the mapped dependency scanner for a build file. +FilePropUtilities.groovy | Helper util to load and validate file level properties overrides. GitUtilities.groovy | Git command methods. ImpactUtilities.groovy | Methods used for ImpactBuilds. -ScannerUtilities.groovy | Returns custom scanners. diff --git a/utilities/ScannerUtilities.groovy b/utilities/ScannerUtilities.groovy deleted file mode 100644 index ef1af344..00000000 --- a/utilities/ScannerUtilities.groovy +++ /dev/null @@ -1,28 +0,0 @@ -@groovy.transform.BaseScript com.ibm.dbb.groovy.ScriptLoader baseScript -import com.ibm.dbb.metadata.* -import com.ibm.dbb.dependency.* -import com.ibm.dbb.build.* -import groovy.transform.* -import groovy.json.JsonSlurper -import com.ibm.dbb.scanner.zUnit.* - - -// define script properties -@Field BuildProperties props = BuildProperties.getInstance() - -/* - * getScanner - get the appropriate Scanner for a given file type (Defaults to DependencyScanner) - */ -def getScanner(String buildFile) { - def mapping = new PropertyMappings("dbb.scannerMapping") - if (mapping.isMapped("ZUnitConfigScanner", buildFile)) { - if (props.verbose) println("*** Scanning file with the ZUnitConfigScanner") - scanner = new ZUnitConfigScanner() - } - else { - if (props.verbose) println("*** Scanning file with the default scanner") - scanner = new DependencyScanner() - } - return scanner -} - From 5000f02e312e99a6488a2218a84d65d05bdd8180 Mon Sep 17 00:00:00 2001 From: Dennis Behm Date: Wed, 7 Jun 2023 12:13:10 +0200 Subject: [PATCH 2/8] Fix sorting of the list of changed programs to correctly insert test case dependency (#364) * Fix sorting of the list of changed programs to correctly insert test case dependency Signed-off-by: Dennis Behm --- utilities/ImpactUtilities.groovy | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utilities/ImpactUtilities.groovy b/utilities/ImpactUtilities.groovy index fd59f861..fb57a3b2 100644 --- a/utilities/ImpactUtilities.groovy +++ b/utilities/ImpactUtilities.groovy @@ -531,7 +531,7 @@ def updateCollection(changedFiles, deletedFiles, renamedFiles) { } if (props.createTestcaseDependency && props.createTestcaseDependency.toBoolean() && changedFiles && changedFiles.size() > 1) { - sortFileList(changedFiles); + changedFiles = sortFileList(changedFiles); if (props.verbose) println "*** Sorted list of changed files: $changedFiles" } @@ -827,7 +827,7 @@ def addBuildPropertyDependencies(String buildProperties, LogicalFile logicalFile */ def sortFileList(list) { - list.sort{s1, s2 -> + return list.sort{s1, s2 -> if (isMappedAsZUnitConfigFile(s1)) { if (isMappedAsZUnitConfigFile(s2)) { return 0; From 2bed12fc608ef7c7874ac3a8f66953dccd5c3adb Mon Sep 17 00:00:00 2001 From: Dennis Behm Date: Wed, 21 Jun 2023 10:37:34 +0200 Subject: [PATCH 3/8] Refactoring Test Framework (#363) * remove unnecessary templates * include git commit methods to testUtils * streamline the test scripts * reorganize output messages, fixing the passing properties * Update documentation of the testframework Signed-off-by: Dennis Behm --- test/README.md | 243 ++++++++---------- test/applications/HelloWorld/README.md | 20 ++ .../MortgageApplication/README.md | 28 +- .../application-conf/Cobol.properties | 20 +- .../MortgageApplication/bms/epsmlis.bms | 112 -------- .../MortgageApplication/bms/epsmort.bms | 42 --- .../MortgageApplication/cobol/epscsmrt.cbl | 61 ----- .../MortgageApplication/cobol/epsmlist.cbl | 196 -------------- .../MortgageApplication/copybook/epsmtout.cpy | 9 - .../MortgageApplication/link/epsmlist.lnk | 3 - .../MortgageApplication/test.properties | 4 +- test/test.groovy | 63 ++--- test/testScripts/README.md | 12 +- test/testScripts/fullBuild.groovy | 32 +-- test/testScripts/fullBuild_debug.groovy | 34 +-- .../fullBuild_languageConfigurations.groovy | 43 ++-- test/testScripts/impactBuild.groovy | 77 ++---- test/testScripts/impactBuild_deletion.groovy | 68 ++--- test/testScripts/impactBuild_preview.groovy | 83 ++---- .../testScripts/impactBuild_properties.groovy | 86 ++----- test/testScripts/impactBuild_renaming.groovy | 40 +-- test/testScripts/mergeBuild.groovy | 55 ++-- test/testScripts/resetBuild.groovy | 13 +- test/utils/testUtilities.groovy | 188 ++++++++++++++ 24 files changed, 552 insertions(+), 980 deletions(-) create mode 100644 test/applications/HelloWorld/README.md delete mode 100644 test/applications/MortgageApplication/bms/epsmlis.bms delete mode 100644 test/applications/MortgageApplication/bms/epsmort.bms delete mode 100644 test/applications/MortgageApplication/cobol/epscsmrt.cbl delete mode 100644 test/applications/MortgageApplication/cobol/epsmlist.cbl delete mode 100644 test/applications/MortgageApplication/copybook/epsmtout.cpy delete mode 100644 test/applications/MortgageApplication/link/epsmlist.lnk diff --git a/test/README.md b/test/README.md index a92d54b6..befef217 100644 --- a/test/README.md +++ b/test/README.md @@ -5,197 +5,173 @@ Test folder is designed to help test samples like the Mortgage Application again Folder/File | Description | Documentation Link --- | --- | --- applications/MortgageApplication | This folder contains modified language scripts used to execute impact build by replacing these modified files with the original language files | [MortgageApplication](applications/MortgageApplication/README.md) +applications/HelloWorld | This folder contains sample programs for Assembler | [HelloWorld](applications/HelloWorld/) test.groovy | This is the main build script that is called to start the test process | [test.groovy](/test/README.md#testing-applications-with-zappbuild) testScripts | This folder contains test scripts to execute full and impact builds | [testScripts](/test/testScripts/README.md) # Testing Applications with zAppBuild The main script for testing applications against zAppBuild is `test.groovy`. It takes most of its input from the command line to run full and impact builds. `test.groovy` once executed from the command line calls [fullBuild.groovy](/test/testScripts/fullBuild.groovy) and [impactBuild.groovy](/test/testScripts/impactBuild.groovy) scripts to perform an end to end test on the given feature branch with the program specified for impact build. -test.groovy script has five required arguments that must be present during each invocation: +test.groovy script has required arguments that must be present during each invocation: * --branch - zAppBuild branch to test * --app - Application that is being tested (example: MortgageApplication) -* --url - DBB Web Application server URL * --hlq - HLQ for dataset reation / deletion (example: USER.BUILD) -* --id - DBB Web Application user id -test.groovy script has three optional argument that can be present during each invocation -* --pw - DBB Web Application user password -* --pwFile - DBB Web Application user password file +test.groovy script has optional argument that can be present during each invocation +* --id - Db2 user id for the MetadataStore +* --url - Db2 JDBC URL for the MetadataStore. +* --pw - Db2 password (encrypted with DBB Password Utility) for the MetadataStore +* --pwFile - Absolute or relative (from workspace) path to file containing Db2 password * --verbose - Flag indicating to print trace statements -* --propFiles - Absolute path to the location of the datasets.properties +* --propFiles - Absolute path to the location of the datasets.properties and other configuration files. * --outDir - Absolute path to out directory # Examples of running an end to end test: -NOTE - For this invocation of the test framework, it is assumed to have the dataset.properties defined to the actual execution environment. +It is recommended to leverage the `--propFiles` to pass in any environment specific property files for your environment, such as the `dataset.properties`, the `build.properties` to configure the Metadatastore connection. +This avoids that you need to commit any environment specific configuration to the branch: ``` -$DBB_HOME/bin/groovyz ${repoPath}/test/test.groovy -b testBranch -a MortgageApplication -q USER.BUILD -u urlToDbbWebApp -i userID -p pwd -``` - -Note - With the invocation any kind of build properties, they are passed to zAppBuild. -``` -$DBB_HOME/bin/groovyz ${repoPath}/test/test.groovy -b testBranch -a MortgageApplication -q USER.BUILD -u urlToDbbWebApp -i userID -p pwd --propFiles /pathToDatasets/datasets.properties --outDir /pathToOutDir/out +$DBB_HOME/bin/groovyz ${repoPath}/test/test.groovy \ + --branch testBranch \ + --app MortgageApplication \ + --hlq USER.BUILD \ + --url jdbc:db2://system1.company.com:5040/DBB1 \ + --id JDBCID \ + --pwFile /var/dbb/pwdFile.txt \ + --propFiles /pathToDatasets/datasets.properties \ + --outDir /pathToOutDir/out ``` # Examples of outputs to be expected: Successful test run ``` -** Executing zAppBuild test framework test/test.groovy +.. ** Creating and checking out branch zAppBuildTesting -Your branch is up-to-date with 'origin/TestAutomation'. +Your branch is up to date with 'origin/testBranch'. On branch zAppBuildTesting nothing to commit, working tree clean -** Invoking test scripts according to test list order: fullBuild.groovy,impactBuild.groovy +** Invoking test scripts according to test list order: resetBuild.groovy,fullBuild.groovy,fullBuild_debug.groovy,resetBuild.groovy -** Executing test script fullBuild.groovy -** Executing /u/dbbAutomation/workspace/Automation_Jobs/DBB_All_BuildS/DBBZtoolkitTar/bin/groovyz /u/dbbAutomation/workspace/Automation_Jobs/ZAppBuildTest/ZAppBuild/dbb-zappbuild/build.groovy --workspace /u/dbbAutomation/workspace/Automation_Jobs/ZAppBuildTest/ZAppBuild/dbb-zappbuild/samples --application MortgageApplication --outDir /u/dbbAutomation/workspace/Automation_Jobs/ZAppBuildTest/ZAppBuild/dbb-zappbuild/out --hlq USER.BUILD --logEncoding UTF-8 --url urlToDbbWebApp --id userID --pw pwd --fullBuild -** Validating full build results +************************************************************** +** Executing test script resetBuild.groovy +************************************************************** +** DBB_HOME = /usr/lpp/dbb/v2r0 +** Executing /usr/lpp/dbb/v2r0/bin/groovyz /u/ibmuser/test-zapp/dbb-zappbuild/build.groovy --workspace /u/ibmuser/test-zapp/dbb-zappbuild/test/applications --application HelloWorld --outDir /u/ibmuser/test-zapp-app-out/testframework_out --hlq USER.DBB.TEST.BUILD --logEncoding UTF-8 --url jdbc:db2://10.3.20.201:4740/MOPDBC0 --id ibmuser --pwFile /var/dbb/config/db2-pwd-file.xml --verbose --propFiles /var/dbb/dbb-zappbuild-config/build.properties,/var/dbb/dbb-zappbuild-config/datasets.properties,/var/dbb/dbb-zappbuild-config/ibmuser.properties --reset +** Validating reset build ** -** FULL BUILD TEST : PASSED ** +** RESET OF THE BUILD : PASSED ** ** -Deleting full build PDSEs [BMS, COBOL, LINK] -** Executing test script impactBuild.groovy -** Processing changed files from impactBuild_changedFiles property : bms/epsmort.bms,cobol/epsmlist.cbl,copybook/epsmtout.cpy,link/epsmlist.lnk - -** Running impact build test for changed file bms/epsmort.bms -** Copying and committing /u/dbbAutomation/workspace/Automation_Jobs/ZAppBuildTest/ZAppBuild/dbb-zappbuild/test/applications/MortgageApplication/bms/epsmort.bms to /u/dbbAutomation/workspace/Automation_Jobs/ZAppBuildTest/ZAppBuild/dbb-zappbuild/samples/MortgageApplication/bms/epsmort.bms -** Executing /u/dbbAutomation/workspace/Automation_Jobs/DBB_All_BuildS/DBBZtoolkitTar/bin/groovyz /u/dbbAutomation/workspace/Automation_Jobs/ZAppBuildTest/ZAppBuild/dbb-zappbuild/build.groovy --workspace /u/dbbAutomation/workspace/Automation_Jobs/ZAppBuildTest/ZAppBuild/dbb-zappbuild/samples --application MortgageApplication --outDir /u/dbbAutomation/workspace/Automation_Jobs/ZAppBuildTest/ZAppBuild/dbb-zappbuild/out --hlq USER.BUILD --logEncoding UTF-8 --url urlToDbbWebApp --id userID --pw pwd --impactBuild -** Validating impact build results +************************************************************** +** Executing test script fullBuild.groovy +************************************************************** +** DBB_HOME = /usr/lpp/dbb/v2r0 +** Executing /usr/lpp/dbb/v2r0/bin/groovyz /u/ibmuser/test-zapp/dbb-zappbuild/build.groovy --workspace /u/ibmuser/test-zapp/dbb-zappbuild/test/applications --application HelloWorld --outDir /u/ibmuser/test-zapp-app-out/testframework_out --hlq USER.DBB.TEST.BUILD --logEncoding UTF-8 --url jdbc:db2://10.3.20.201:4740/MOPDBC0 --id ibmuser --pwFile /var/dbb/config/db2-pwd-file.xml --verbose --propFiles /var/dbb/dbb-zappbuild-config/build.properties,/var/dbb/dbb-zappbuild-config/datasets.properties,/var/dbb/dbb-zappbuild-config/ibmuser.properties --fullBuild +** Validating full build results ** -** IMPACT BUILD TEST : PASSED ** +** FULL BUILD TEST : PASSED ** ** -** Running impact build test for changed file cobol/epsmlist.cbl -** Copying and committing /u/dbbAutomation/workspace/Automation_Jobs/ZAppBuildTest/ZAppBuild/dbb-zappbuild/test/applications/MortgageApplication/cobol/epsmlist.cbl to /u/dbbAutomation/workspace/Automation_Jobs/ZAppBuildTest/ZAppBuild/dbb-zappbuild/samples/MortgageApplication/cobol/epsmlist.cbl -** Executing /u/dbbAutomation/workspace/Automation_Jobs/DBB_All_BuildS/DBBZtoolkitTar/bin/groovyz /u/dbbAutomation/workspace/Automation_Jobs/ZAppBuildTest/ZAppBuild/dbb-zappbuild/build.groovy --workspace /u/dbbAutomation/workspace/Automation_Jobs/ZAppBuildTest/ZAppBuild/dbb-zappbuild/samples --application MortgageApplication --outDir /u/dbbAutomation/workspace/Automation_Jobs/ZAppBuildTest/ZAppBuild/dbb-zappbuild/out --hlq USER.BUILD --logEncoding UTF-8 --url urlToDbbWebApp --id userID --pw pwd --impactBuild -** Validating impact build results +** Deleting build PDSEs [ASM, MACRO, DBRM, OBJ, LOAD] +** Deleting 'USER.DBB.TEST.BUILD.ASM' +** Deleting 'USER.DBB.TEST.BUILD.MACRO' +** Deleting 'USER.DBB.TEST.BUILD.DBRM' +** Deleting 'USER.DBB.TEST.BUILD.OBJ' +** Deleting 'USER.DBB.TEST.BUILD.LOAD' + +************************************************************** +** Executing test script fullBuild_debug.groovy +************************************************************** +** DBB_HOME = /usr/lpp/dbb/v2r0 +** Executing /usr/lpp/dbb/v2r0/bin/groovyz /u/ibmuser/test-zapp/dbb-zappbuild/build.groovy --workspace /u/ibmuser/test-zapp/dbb-zappbuild/test/applications --application HelloWorld --outDir /u/ibmuser/test-zapp-app-out/testframework_out --hlq USER.DBB.TEST.BUILD --logEncoding UTF-8 --url jdbc:db2://10.3.20.201:4740/MOPDBC0 --id ibmuser --pwFile /var/dbb/config/db2-pwd-file.xml --verbose --propFiles /var/dbb/dbb-zappbuild-config/build.properties,/var/dbb/dbb-zappbuild-config/datasets.properties,/var/dbb/dbb-zappbuild-config/ibmuser.properties --fullBuild --debug +** Validating full build results ** -** IMPACT BUILD TEST : PASSED ** +** FULL BUILD TEST : PASSED ** ** -** Running impact build test for changed file copybook/epsmtout.cpy -** Copying and committing /u/dbbAutomation/workspace/Automation_Jobs/ZAppBuildTest/ZAppBuild/dbb-zappbuild/test/applications/MortgageApplication/copybook/epsmtout.cpy to /u/dbbAutomation/workspace/Automation_Jobs/ZAppBuildTest/ZAppBuild/dbb-zappbuild/samples/MortgageApplication/copybook/epsmtout.cpy -** Executing /u/dbbAutomation/workspace/Automation_Jobs/DBB_All_BuildS/DBBZtoolkitTar/bin/groovyz /u/dbbAutomation/workspace/Automation_Jobs/ZAppBuildTest/ZAppBuild/dbb-zappbuild/build.groovy --workspace /u/dbbAutomation/workspace/Automation_Jobs/ZAppBuildTest/ZAppBuild/dbb-zappbuild/samples --application MortgageApplication --outDir /u/dbbAutomation/workspace/Automation_Jobs/ZAppBuildTest/ZAppBuild/dbb-zappbuild/out --hlq USER.BUILD --logEncoding UTF-8 --url urlToDbbWebApp --id userID --pw pwd --impactBuild -** Validating impact build results -** -** IMPACT BUILD TEST : PASSED ** -** - -** Running impact build test for changed file link/epsmlist.lnk -** Copying and committing /u/dbbAutomation/workspace/Automation_Jobs/ZAppBuildTest/ZAppBuild/dbb-zappbuild/test/applications/MortgageApplication/link/epsmlist.lnk to /u/dbbAutomation/workspace/Automation_Jobs/ZAppBuildTest/ZAppBuild/dbb-zappbuild/samples/MortgageApplication/link/epsmlist.lnk -** Executing /u/dbbAutomation/workspace/Automation_Jobs/DBB_All_BuildS/DBBZtoolkitTar/bin/groovyz /u/dbbAutomation/workspace/Automation_Jobs/ZAppBuildTest/ZAppBuild/dbb-zappbuild/build.groovy --workspace /u/dbbAutomation/workspace/Automation_Jobs/ZAppBuildTest/ZAppBuild/dbb-zappbuild/samples --application MortgageApplication --outDir /u/dbbAutomation/workspace/Automation_Jobs/ZAppBuildTest/ZAppBuild/dbb-zappbuild/out --hlq USER.BUILD --logEncoding UTF-8 --url urlToDbbWebApp --id userID --pw pwd --impactBuild -** Validating impact build results -** -** IMPACT BUILD TEST : PASSED ** -** -Deleting impact build PDSEs [BMS, COBOL, LINK, COPY, BMS.COPY, DBRM, LOAD, MFS, OBJ, TFORMAT] +** Deleting build PDSEs [ASM, MACRO, DBRM, OBJ, LOAD, SYSADATA, EQALANGX] +** Deleting 'USER.DBB.TEST.BUILD.ASM' +** Deleting 'USER.DBB.TEST.BUILD.MACRO' +** Deleting 'USER.DBB.TEST.BUILD.DBRM' +** Deleting 'USER.DBB.TEST.BUILD.OBJ' +** Deleting 'USER.DBB.TEST.BUILD.LOAD' +** Deleting 'USER.DBB.TEST.BUILD.SYSADATA' +** Deleting 'USER.DBB.TEST.BUILD.EQALANGX' +************************************************************** ** Executing test script resetBuild.groovy -** Executing /var/dbbreleng/workspace/Automation_Jobs/DBB_All_BuildS/DBBZtoolkitTar/bin/groovyz /u/dbbAutomation/workspace/Automation_Jobs/ZAppBuildTest/ZAppBuild/dbb-zappbuild/build.groovy --workspace /u/dbbAutomation/workspace/Automation_Jobs/ZAppBuildTest/ZAppBuild/dbb-zappbuild/samples --application MortgageApplication --outDir /u/builder/dbb/out --hlq USER.BUILD --logEncoding UTF-8 --url urlToDbbWebApp --id userID --pw pwd --reset - +************************************************************** +** DBB_HOME = /usr/lpp/dbb/v2r0 +** Executing /usr/lpp/dbb/v2r0/bin/groovyz /u/ibmuser/test-zapp/dbb-zappbuild/build.groovy --workspace /u/ibmuser/test-zapp/dbb-zappbuild/test/applications --application HelloWorld --outDir /u/ibmuser/test-zapp-app-out/testframework_out --hlq USER.DBB.TEST.BUILD --logEncoding UTF-8 --url jdbc:db2://10.3.20.201:4740/MOPDBC0 --id ibmuser --pwFile /var/dbb/config/db2-pwd-file.xml --verbose --propFiles /var/dbb/dbb-zappbuild-config/build.properties,/var/dbb/dbb-zappbuild-config/datasets.properties,/var/dbb/dbb-zappbuild-config/ibmuser.properties --reset ** Validating reset build ** ** RESET OF THE BUILD : PASSED ** ** ** Deleting test branch zAppBuildTesting -HEAD is now at 801c002 edited program file +HEAD is now at 68f9a2d make the credentials optional Your branch is up to date with 'origin/testBranch'. -Deleted branch zAppBuildTesting (was 801c002). +Deleted branch zAppBuildTesting (was 68f9a2d). On branch testBranch Your branch is up to date with 'origin/testBranch'. nothing to commit, working tree clean + +================================================================================================ +* ZAPPBUILD TESTFRAMEWORK COMPLETED. + All tests (resetBuild.groovy,fullBuild.groovy,fullBuild_debug.groovy,resetBuild.groovy) completed successfully. +================================================================================================ ** Build finished ``` -Build with errors +When an error is detected, the test framework will print the entire log of the failed test (failed assertion) for the analysis by the build script engineer: + ``` -** Executing test script impactBuild.groovy -** Processing changed files from impactBuild_changedFiles property : bms/epsmort.bms,cobol/epsmlist.cbl,copybook/epsmtout.cpy,link/epsmlist.lnk -** Running impact build test for changed file bms/epsmort.bms -** Copying and committing /u/dbbAutomation/workspace/Automation_Jobs/ZAppBuildTest/ZAppBuild/dbb-zappbuild/test/applications/MortgageApplication/bms/epsmort.bms to /u/dbbAutomation/workspace/Automation_Jobs/ZAppBuildTest/ZAppBuild/dbb-zappbuild/samples/MortgageApplication/bms/epsmort.bms -** Executing /u/dbbAutomation/workspace/Automation_Jobs/DBB_All_BuildS/DBBZtoolkitTar/bin/groovyz /u/dbbAutomation/workspace/Automation_Jobs/ZAppBuildTest/ZAppBuild/dbb-zappbuild/build.groovy --workspace /u/dbbAutomation/workspace/Automation_Jobs/ZAppBuildTest/ZAppBuild/dbb-zappbuild/samples --application MortgageApplication --outDir /u/dbbAutomation/workspace/Automation_Jobs/ZAppBuildTest/ZAppBuild/dbb-zappbuild/out --hlq USER.BUILD --logEncoding UTF-8 --url urlToDbbWebApp --id userID --pw pwd --impactBuild +... +** Executing test script impactBuild_renaming.groovy +** DBB_HOME = /usr/lpp/dbb/v2r0 +** Rename cobol/epscsmrt.cbl to cobol/epscsmr2.cbl + +** Running impact after renaming file cobol/epscsmrt.cbl to cobol/epscsmr2.cbl +** Executing /usr/lpp/dbb/v2r0/bin/groovyz /ZT01/var/jenkins/workspace/dbb-zappbuild-testframework-withParms/build.groovy --workspace /ZT01/var/jenkins/workspace/dbb-zappbuild-testframework-withParms/samples --application MortgageApplication --outDir /var/jenkins/workspace/dbb-zappbuild-testframework-withParms/logs_testframework_MortgageApp --hlq JENKINS.DBB.TEST.BUILD.T367ENHA --logEncoding UTF-8 --url jdbc:db2:somelocation --id DBEHM --pwFile /var/dbb/config/db2-pwd-file.xml --verbose --propFiles /var/dbb/dbb-zappbuild-config/build.properties,/var/dbb/dbb-zappbuild-config/datasets.properties,/var/dbb/dbb-zappbuild-config/dbb-db2-metadatastore-jenkins.properties --impactBuild ** Validating impact build results Deleting impact build PDSEs [BMS, COBOL, LINK, COPY, BMS.COPY, DBRM, LOAD, MFS, OBJ, TFORMAT] -** Deleting test branch zAppBuildTesting -HEAD is now at 1242001 edited program file -Your branch is up-to-date with 'origin/TestAutomation'. -Deleted branch zAppBuildTesting (was 1242001). -On branch TestAutomation -Your branch is up-to-date with 'origin/TestAutomation'. - -nothing to commit, working tree clean - -Caught: java.lang.AssertionError: *! IMPACT BUILD FAILED FOR bms/epsmort.bms -OUTPUT STREAM: - -** Build start at 20210310.120307.003 -** Repository client created for urlToDbbWebApp -** Build output located at /u/dbbAutomation/workspace/Automation_Jobs/ZAppBuildTest/ZAppBuild/dbb-zappbuild/out/build.20210310.120307.003 -** Build result created for BuildGroup:MortgageApplication-zAppBuildTesting BuildLabel:build.20210310.120307.003 at urlToDbbWebApp/rest/buildResult/733 -** --impactBuild option selected. Building impacted programs for application MortgageApplication -** Writing build list file to /u/dbbAutomation/workspace/Automation_Jobs/ZAppBuildTest/ZAppBuild/dbb-zappbuild/out/build.20210310.120307.003/buildList.txt -** Invoking build scripts according to build order: BMS.groovy,Cobol.groovy,LinkEdit.groovy -** Building files mapped to BMS.groovy script -*** Building file MortgageApplication/bms/epsmort.bms -** Building files mapped to Cobol.groovy script -*** Building file MortgageApplication/cobol/epscmort.cbl -*! The compile return code (12) for MortgageApplication/cobol/epscmort.cbl exceeded the maximum return code allowed (4) -** Writing build report data to /u/dbbAutomation/workspace/Automation_Jobs/ZAppBuildTest/ZAppBuild/dbb-zappbuild/out/build.20210310.120307.003/BuildReport.json -** Writing build report to /u/dbbAutomation/workspace/Automation_Jobs/ZAppBuildTest/ZAppBuild/dbb-zappbuild/out/build.20210310.120307.003/BuildReport.html -** Build ended at Wed Mar 10 12:03:27 EST 2021 -** Build State : ERROR -** Total files processed : 2 -** Total build time : 20.273 seconds - -** Build finished +*** +**START OF FAILED IMPACT BUILD TEST RESULTS** -. Expression: outputStream.contains(Build State : CLEAN) -java.lang.AssertionError: *! IMPACT BUILD FAILED FOR bms/epsmort.bms +*FAILED IMPACT BUILD TEST RESULTS* +[*! IMPACT BUILD FOR cobol/epscsmrt.cbl TOTAL FILES PROCESSED ARE NOT EQUAL TO 1 OUTPUT STREAM: -** Build start at 20210310.120307.003 -** Repository client created for urlToDbbWebApp -** Build output located at /u/dbbAutomation/workspace/Automation_Jobs/ZAppBuildTest/ZAppBuild/dbb-zappbuild/out/build.20210310.120307.003 -** Build result created for BuildGroup:MortgageApplication-zAppBuildTesting BuildLabel:build.20210310.120307.003 at urlToDbbWebApp/rest/buildResult/733 -** --impactBuild option selected. Building impacted programs for application MortgageApplication -** Writing build list file to /u/dbbAutomation/workspace/Automation_Jobs/ZAppBuildTest/ZAppBuild/dbb-zappbuild/out/build.20210310.120307.003/buildList.txt -** Invoking build scripts according to build order: BMS.groovy,Cobol.groovy,LinkEdit.groovy -** Building files mapped to BMS.groovy script -*** Building file MortgageApplication/bms/epsmort.bms -** Building files mapped to Cobol.groovy script -*** Building file MortgageApplication/cobol/epscmort.cbl -*! The compile return code (12) for MortgageApplication/cobol/epscmort.cbl exceeded the maximum return code allowed (4) -** Writing build report data to /u/dbbAutomation/workspace/Automation_Jobs/ZAppBuildTest/ZAppBuild/dbb-zappbuild/out/build.20210310.120307.003/BuildReport.json -** Writing build report to /u/dbbAutomation/workspace/Automation_Jobs/ZAppBuildTest/ZAppBuild/dbb-zappbuild/out/build.20210310.120307.003/BuildReport.html -** Build ended at Wed Mar 10 12:03:27 EST 2021 -** Build State : ERROR -** Total files processed : 2 -** Total build time : 20.273 seconds - -** Build finished - -. Expression: outputStream.contains(Build State : CLEAN) - at impactBuild.validateImpactBuild(impactBuild.groovy:81) - at impactBuild$_run_closure1.doCall(impactBuild.groovy:47) - at impactBuild.run(impactBuild.groovy:34) - at impactBuild$run.callCurrent(Unknown Source) - at fullBuild$run.callCurrent(Unknown Source) - at com.ibm.dbb.groovy.ScriptLoader._run(ScriptLoader.groovy:124) - at com.ibm.dbb.groovy.ScriptLoader$_run$1.call(Unknown Source) - at com.ibm.dbb.groovy.ScriptLoader$_run$1.call(Unknown Source) - at com.ibm.dbb.groovy.ScriptLoader.runScript(ScriptLoader.groovy:81) - at test$_run_closure1.doCall(test.groovy:22) - at test.run(test.groovy:20) -** Build finished +** Build start at 20230615.012609.026 +** Input args = /ZT01/var/jenkins/workspace/dbb-zappbuild-testframework-withParms/samples --application MortgageApplication --outDir /var/jenkins/workspace/dbb-zappbuild-testframework-withParms/logs_testframework_MortgageApp --hlq JENKINS.DBB.TEST.BUILD.T367ENHA --logEncoding UTF-8 --url jdbc:db2:somelocation --id DBEHM --pwFile /var/dbb/config/db2-pwd-file.xml --verbose --propFiles /var/dbb/dbb-zappbuild-config/build.properties,/var/dbb/dbb-zappbuild-config/datasets.properties,/var/dbb/dbb-zappbuild-config/dbb-db2-metadatastore-jenkins.properties --impactBuild +** Loading property file /ZT01/var/jenkins/workspace/dbb-zappbuild-testframework-withParms/build-conf/datasets.properties +** Loading property file /ZT01/var/jenkins/workspace/dbb-zappbuild-testframework-withParms/build-conf/dependencyReport.properties +** Loading property file /ZT01/var/jenkins/workspace/dbb-zappbuild-testframework-withParms/build-conf/Assembler.properties +** Loading property file /ZT01/var/jenkins/workspace/dbb-zappbuild-testframework-withParms/build-conf/BMS.properties +** Loading property file /ZT01/var/jenkins/workspace/dbb-zappbuild-testframework-withParms/build-conf/MFS.properties +** Loading property file /ZT01/var/jenkins/workspace/dbb-zappbuild-testframework-withParms/build-conf/PSBgen.properties +** Loading property file /ZT01/var/jenkins/workspace/dbb-zappbuild-testframework-withParms/build-conf/DBDgen.properties +** Loading property file /ZT01/var/jenkins/workspace/dbb-zappbuild-testframework-withParms/build-conf/ACBgen.properties +** Loading property file /ZT01/var/jenkins/workspace/dbb-zappbuild-testframework-withParms/build-conf/Cobol.properties +** Loading property file /ZT01/var/jenkins/workspace/dbb-zappbuild-testframework-withParms/build-conf/LinkEdit.properties +** Loading property file /ZT01/var/jenkins/workspace/dbb-zappbuild-testframework-withParms/build-conf/PLI.properties +** Loading property file /ZT01/var/jenkins/workspace/dbb-zappbuild-testframework-withParms/build-conf/REXX.properties +** Loading property file /ZT01/var/jenkins/workspace/dbb-zappbuild-testframework-withParms/build-conf/ZunitConfig.properties +** Loading property file /ZT01/var/jenkins/workspace/dbb-zappbuild-testframework-withParms/build-conf/Transfer.properties +** Loading property file /ZT01/var/jenkins/workspace/dbb-zappbuild-testframework-withParms/build-conf/defaultzAppBuildConf.properties +** appConf = /ZT01/var/jenkins/workspace/dbb-zappbuild-testframework-withParms/samples/MortgageApplication/application-conf +** Loading property file /ZT01/var/jenkins/workspace/dbb-zappbuild-testframework-withParms/samples/MortgageApplication/application-conf/file.properties +** Loading property file /ZT01/var/jenkins/workspace/dbb-zappbuild-testframework-withParms/samples/MortgageApplication/application-conf/BMS.properties +** Loading property file /ZT01/var/jenkins/workspace/dbb-zappbuild-testframework-withParms/samples/MortgageApplication/application-conf/Cobol.properties +** Loading property file /ZT01/var/jenkins/workspace/dbb-zappbuild-testframework-withParms/samples/MortgageApplication/application-conf/LinkEdit.properties +** Loading property file /ZT01/var/jenkins/workspace/dbb-zappbuild-testframework-withParms/samples/MortgageApplication/application-conf/languageConfigurationMapping.properties ``` ## Command Line Options Summary @@ -210,10 +186,11 @@ test framework arguments: zAppBuild arguments: -a, --app Application that is being tested (example: MortgageApplication), required -q, --hlq HLQ for dataset reation / deletion (example: USER.BUILD), required --u, --url DBB Web Application server URL, required --i, --id DBB Web Application user id, required --p, --pw DBB Web Application user password --P, --pwFile DBB Web Application user password file +-u, --url Db2 JDBC URL for the MetadataStore. + Example: jdbc:db2: +-i, --id Db2 user id for the MetadataStore +-p, --pw Db2 password (encrypted with DBB Password Utility) for the MetadataStore +-P, --pwFile Absolute or relative (from workspace) path to file containing Db2 password -f, --propFiles Absolute path to the location of the datasets.properties -o, --outDir Absolute path to out directory ``` diff --git a/test/applications/HelloWorld/README.md b/test/applications/HelloWorld/README.md new file mode 100644 index 00000000..6a112548 --- /dev/null +++ b/test/applications/HelloWorld/README.md @@ -0,0 +1,20 @@ +# HelloWorld +This contains program files and build configuration to execute the test scenarios with the HelloWorld appplication. + +Modified files of other supported languages for testing this application can be added. + +#### References for additional information about testing applications using zAppBuild +- [zAppBuild test framework documentation](/test/README.md) +- [Available test scenarios](/test/testScripts/README.md) that can be configured for a test application + +# test.properties +This application specify properties file is invoked by [test.groovy](/test/test.groovy) and it contains the below properties to configure the test scenarios for testing the HelloWorld application. + +Property | Description +--- | --- +test_testOrder | Comma separated list of the test script processing order +fullBuild_* | Test properties for `--fullBuild` build scenario +fullBuild_debug* | Test properties for `--fullBuild --debug` build scenario +reset_* | Properties for `--reset` option to cleanup DBB metadatastore + + diff --git a/test/applications/MortgageApplication/README.md b/test/applications/MortgageApplication/README.md index 614f624d..fc1d688f 100644 --- a/test/applications/MortgageApplication/README.md +++ b/test/applications/MortgageApplication/README.md @@ -1,18 +1,26 @@ # MortgageApplication -This contains the modified program files to execute an impact build of the MortgageApplication sample that's built by zAppBuild. The structure of this folder is the same the Mortagage Application in ZAppBuild. In addition to what provided here, modified files of other supported languages for testing this application can be added. +This contains the modified program files and build configuration to execute an impact build of the MortgageApplication sample that's built by zAppBuild. -#### Refers for additional information about testing applications using zAppBuild. -- [TestGroovy/README.md](/test/README.md) -- [Full-Impact-Reset/README.md](/test/testScripts/README.md) +The structure of this folder is the same the MortagageApplication in zAppBuild. Modified files of other supported languages for testing this application can be added. + +#### References for additional information about testing applications using zAppBuild +- [zAppBuild test framework documentation](/test/README.md) +- [Available test scenarios](/test/testScripts/README.md) that can be configured for a test application # test.properties -This application specify properties file is invoked by [test.groovy](/test/test.groovy) and it contains the properties below for testing mortgage application. +This application specify properties file is invoked by [test.groovy](/test/test.groovy) and it contains the below properties to configure the test scenarios for testing the mortgage application. Property | Description --- | --- test_testOrder | Comma separated list of the test script processing order -fullBuild_expectedFilesBuilt | List of programs should be built for a full build for this application -fullBuild_datasetsToCleanUp | List of source datasets (LLQ) that should be deleted during fullBuild.groovy cleanUp -impactBuild_changedFiles | List of changed source files to test impact builds for this application -impactBuild_datasetsToCleanUp | List of source datasets (LLQ) that should be deleted during impactBuild.groovy cleanUp -impactBuild_expectedFilesBuilt | Uses file properties to associate expected files built to changed files +fullBuild_* | Test properties for `--fullBuild` build scenario +fullBuild_languageConfigurations_* | Test properties for full build scenario with [language configuration settings](/docs/FilePropertyManagement.md) +mergeBuild_* | Test properties for `--mergeBuild` build scenario +impactBuild_* | Test properties for `--impactBuild` build scenario +impactBuild_rename* | Test properties for `--impactBuild` build scenario when renaming a file +impactBuild_properties* | Test properties for `--impactBuild` build scenario on property changes +impactBuild_deletion* | Test properties for `--impactBuild` build scenario on deleting files +impactBuild_preview* | Test properties for `--impactBuild --preview` build scenario +impactBuild_preview* | Test properties for `--impactBuild --preview` build scenario + + diff --git a/test/applications/MortgageApplication/application-conf/Cobol.properties b/test/applications/MortgageApplication/application-conf/Cobol.properties index 5681984b..7f1b5964 100644 --- a/test/applications/MortgageApplication/application-conf/Cobol.properties +++ b/test/applications/MortgageApplication/application-conf/Cobol.properties @@ -5,11 +5,6 @@ # leave empty - overridden by file properties if sorting needed cobol_fileBuildRank= -# -# COBOL dependency resolution rules -# Rules defined in application.properties -cobol_resolutionRules=[${copybookRule}] - # # COBOL dependencySearch configuration # searchPath defined in application.properties @@ -49,14 +44,13 @@ cobol_compileDebugParms=TEST # can be overridden by file properties cobol_linkEditParms=MAP,RENT,COMPAT(PM5) -# If you would like to have a physical link card, we generated it for you given the below pattern -# This property has priority over cobol_linkDebugExit -# cobol_linkEditStream= INCLUDE OBJECT(@{member}) +# Optional linkEditStream defining additional link instructions via SYSIN dd +# cobol_linkEditStream= INCLUDE SYSLIB(COBJT) \n cobol_linkEditStream= -# If using a debug exit, provide the SYSLIN instream DD -# Samp: cobol_linkDebugExit= INCLUDE OBJECT(@{member}) \n INCLUDE SYSLIB(EQAD3CXT) -cobol_linkDebugExit= INCLUDE OBJECT(@{member}) \n INCLUDE SYSLIB(EQAD3CXT) +# If using a debug exit for IBM Debug tool, provide the SYSIN instream DD which is appended to SYSIN +# Samp: cobol_linkDebugExit= INCLUDE SYSLIB(EQAD3CXT) \n +cobol_linkDebugExit= # @@ -75,11 +69,11 @@ cobol_storeSSI=true cobol_deployType=LOAD # -# default deployType +# deployType for build files with isCICS=true cobol_deployTypeCICS=CICSLOAD # -# default deployType +# deployType for build files with isDLI=true cobol_deployTypeDLI=IMSLOAD # diff --git a/test/applications/MortgageApplication/bms/epsmlis.bms b/test/applications/MortgageApplication/bms/epsmlis.bms deleted file mode 100644 index b409564a..00000000 --- a/test/applications/MortgageApplication/bms/epsmlis.bms +++ /dev/null @@ -1,112 +0,0 @@ -*********************************************************************** 00010000 -EPSMLIS DFHMSD TYPE=&SYSPARM,MODE=INOUT,LANG=COBOL, X - STORAGE=AUTO,TIOAPFX=YES,DSATTS=(COLOR,HILIGHT), X 0009000 - MAPATTS=(COLOR,HILIGHT) 0009100 -EPSMLIS DFHMDI SIZE=(24,80),CTRL=(PRINT,FREEKB) 0011000 - DFHMDF POS=(1,24),LENGTH=26,INITIAL='Better Mortgage Rates', * - ATTRB=(ASKIP,BRT) - DFHMDF POS=(24,58),LENGTH=0, * - ATTRB=ASKIP -* MENU MORTGAGE LIST MERGE BUILD TEST. - -LITCOMP DFHMDF POS=(3,1),LENGTH=24,INITIAL='Company', * - ATTRB=(ASKIP,NORM) -LITPHN DFHMDF POS=(3,26),LENGTH=13,INITIAL='Phone Number', * - ATTRB=(PROT,NORM) -EPDIFF1 DFHMDF POS=(3,40),LENGTH=13,INITIAL='Interest Rate', * - ATTRB=(PROT,NORM) -EPDIFF2 DFHMDF POS=(3,54),LENGTH=16,INITIAL='Monthly Payment', * - ATTRB=(PROT,NORM) -LITPHN1 DFHMDF POS=(3,71),LENGTH=7,INITIAL='# Years', * - ATTRB=(PROT,NORM) -EPCMP1 DFHMDF POS=(4,1),LENGTH=24, * - ATTRB=(PROT,NORM),HILIGHT=OFF,COLOR=GREEN -EPPHN1 DFHMDF POS=(4,26),LENGTH=13, * - ATTRB=(PROT,NORM),HILIGHT=OFF,COLOR=GREEN -EPRATE1 DFHMDF POS=(4,45),LENGTH=5, * - ATTRB=(NUM,NORM),COLOR=GREEN -EPLOAN1 DFHMDF POS=(4,56),LENGTH=12, * - ATTRB=(NUM,IC,NORM) -EPYEARS1 DFHMDF POS=(4,74),LENGTH=2, * - ATTRB=(NUM,NORM),COLOR=GREEN -EPCMP2 DFHMDF POS=(5,1),LENGTH=24, * - ATTRB=(PROT,NORM),HILIGHT=OFF,COLOR=GREEN -EPPHN2 DFHMDF POS=(5,26),LENGTH=13, * - ATTRB=(PROT,NORM),HILIGHT=OFF,COLOR=GREEN -EPRATE2 DFHMDF POS=(5,45),LENGTH=5, * - ATTRB=(NUM,NORM),COLOR=GREEN -EPLOAN2 DFHMDF POS=(5,56),LENGTH=12, * - ATTRB=(NUM,IC,NORM) -EPYEARS2 DFHMDF POS=(5,74),LENGTH=2, * - ATTRB=(NUM,NORM),COLOR=GREEN -EPCMP3 DFHMDF POS=(6,1),LENGTH=24, * - ATTRB=(PROT,NORM),HILIGHT=OFF,COLOR=GREEN -EPPHN3 DFHMDF POS=(6,26),LENGTH=13, * - ATTRB=(PROT,NORM),HILIGHT=OFF,COLOR=GREEN -EPRATE3 DFHMDF POS=(6,45),LENGTH=5, * - ATTRB=(NUM,NORM),COLOR=GREEN -EPLOAN3 DFHMDF POS=(6,56),LENGTH=12, * - ATTRB=(NUM,IC,NORM) -EPYEARS3 DFHMDF POS=(6,74),LENGTH=2, * - ATTRB=(NUM,NORM),COLOR=GREEN -EPCMP4 DFHMDF POS=(7,1),LENGTH=24, * - ATTRB=(PROT,NORM),HILIGHT=OFF,COLOR=GREEN -EPPHN4 DFHMDF POS=(7,26),LENGTH=13, * - ATTRB=(PROT,NORM),HILIGHT=OFF,COLOR=GREEN -EPRATE4 DFHMDF POS=(7,45),LENGTH=5, * - ATTRB=(NUM,NORM),COLOR=GREEN -EPLOAN4 DFHMDF POS=(7,56),LENGTH=12, * - ATTRB=(NUM,IC,NORM) -EPYEARS4 DFHMDF POS=(7,74),LENGTH=2, * - ATTRB=(NUM,NORM),COLOR=GREEN -EPCMP5 DFHMDF POS=(8,1),LENGTH=24, * - ATTRB=(PROT,NORM),HILIGHT=OFF,COLOR=GREEN -EPPHN5 DFHMDF POS=(8,26),LENGTH=13, * - ATTRB=(PROT,NORM),HILIGHT=OFF,COLOR=GREEN -EPRATE5 DFHMDF POS=(8,45),LENGTH=5, * - ATTRB=(NUM,NORM),COLOR=GREEN -EPLOAN5 DFHMDF POS=(8,56),LENGTH=12, * - ATTRB=(NUM,IC,NORM) -EPYEARS5 DFHMDF POS=(8,74),LENGTH=2, * - ATTRB=(NUM,NORM),COLOR=GREEN -EPCMP6 DFHMDF POS=(9,1),LENGTH=24, * - ATTRB=(PROT,NORM),HILIGHT=OFF,COLOR=GREEN -EPPHN6 DFHMDF POS=(9,26),LENGTH=13, * - ATTRB=(PROT,NORM),HILIGHT=OFF,COLOR=GREEN -EPRATE6 DFHMDF POS=(9,45),LENGTH=5, * - ATTRB=(NUM,NORM),COLOR=GREEN -EPLOAN6 DFHMDF POS=(9,56),LENGTH=12, * - ATTRB=(NUM,IC,NORM) -EPYEARS6 DFHMDF POS=(9,74),LENGTH=2, * - ATTRB=(NUM,NORM),COLOR=GREEN -EPCMP7 DFHMDF POS=(10,1),LENGTH=24, * - ATTRB=(PROT,NORM),HILIGHT=OFF,COLOR=GREEN -EPPHN7 DFHMDF POS=(10,26),LENGTH=13, * - ATTRB=(PROT,NORM),HILIGHT=OFF,COLOR=GREEN -EPRATE7 DFHMDF POS=(10,45),LENGTH=5, * - ATTRB=(NUM,NORM),COLOR=GREEN -EPLOAN7 DFHMDF POS=(10,56),LENGTH=12, * - ATTRB=(NUM,IC,NORM) -EPYEARS7 DFHMDF POS=(10,74),LENGTH=2, * - ATTRB=(NUM,NORM),COLOR=GREEN -EPCMP8 DFHMDF POS=(11,1),LENGTH=24, * - ATTRB=(PROT,NORM),HILIGHT=OFF,COLOR=GREEN -EPPHN8 DFHMDF POS=(11,26),LENGTH=13, * - ATTRB=(PROT,NORM),HILIGHT=OFF,COLOR=GREEN -EPRATE8 DFHMDF POS=(11,45),LENGTH=5, * - ATTRB=(NUM,NORM),COLOR=GREEN -EPLOAN8 DFHMDF POS=(11,56),LENGTH=12, * - ATTRB=(NUM,IC,NORM) - DFHMDF POS=(11,69), * - ATTRB=ASKIP -EPYEARS8 DFHMDF POS=(11,74),LENGTH=2, * - ATTRB=(NUM,NORM),COLOR=GREEN - DFHMDF POS=(11,77),LENGTH=0, * - ATTRB=ASKIP - DFHMDF POS=(23,17),LENGTH=43, * - INITIAL='Press F3 to quit or Enter to calculate loan', * - ATTRB=(ASKIP,NORM),HILIGHT=OFF,COLOR=BLUE -MSGERR DFHMDF POS=(24,17),LENGTH=40,INITIAL='INVALID KEY PRESSED', X - ATTRB=(PROT,DRK) -EPSMLIS DFHMSD TYPE=FINAL - END diff --git a/test/applications/MortgageApplication/bms/epsmort.bms b/test/applications/MortgageApplication/bms/epsmort.bms deleted file mode 100644 index d7505c58..00000000 --- a/test/applications/MortgageApplication/bms/epsmort.bms +++ /dev/null @@ -1,42 +0,0 @@ -*********************************************************************** 00010000 -EPSMORT DFHMSD TYPE=&SYSPARM,MODE=INOUT,LANG=COBOL, @P3CX0008000 - STORAGE=AUTO,TIOAPFX=YES,DSATTS=(COLOR,HILIGHT), X00090000 - MAPATTS=(COLOR,HILIGHT) 00091000 -* MENU MAPS.. -EPMENU DFHMDI SIZE=(24,80),CTRL=(PRINT,FREEKB) 00110000 -LITLOAN DFHMDF POS=(8,15),LENGTH=23,INITIAL='Amount of Loan:', * - ATTRB=(ASKIP,NORM) -EPLOAN DFHMDF POS=(8,42),LENGTH=12,INITIAL='999999999.99', * - ATTRB=(NUM,FSET,IC,NORM) - DFHMDF POS=(8,55), * - ATTRB=ASKIP -LITYEARS DFHMDF POS=(9,15),LENGTH=24, * - INITIAL='Length of Loan in Years:', * - ATTRB=(PROT,NORM) -EPYEARS DFHMDF POS=(9,42),LENGTH=2,INITIAL='99', * - ATTRB=(NUM,FSET,NORM),COLOR=GREEN - DFHMDF POS=(9,45),LENGTH=0, * - ATTRB=ASKIP -EPDIFF1 DFHMDF POS=(10,15),LENGTH=22,INITIAL='Interest Rate: ', * - ATTRB=(PROT,NORM) -EPRATE DFHMDF POS=(10,42),LENGTH=5,INITIAL='99.99', * - ATTRB=(NUM,FSET,NORM),COLOR=GREEN - DFHMDF POS=(15,7),LENGTH=60, * - INITIAL='Press PF9 to see companies that can match or be* - at this rate', * - ATTRB=(ASKIP,NORM),HILIGHT=OFF,COLOR=BLUE - DFHMDF POS=(14,15),LENGTH=43, * - INITIAL='Press F3 to quit or Enter to calculate loan', * - ATTRB=(ASKIP,NORM),HILIGHT=OFF,COLOR=BLUE -EPDIFF2 DFHMDF POS=(17,15),LENGTH=22,INITIAL='Monthly Payment: ', * - ATTRB=(PROT,NORM) -EPPAYMNT DFHMDF POS=(17,42),LENGTH=12, * - ATTRB=(PROT,NORM),HILIGHT=OFF,COLOR=YELLOW -MSGERR DFHMDF POS=(24,15),ATTRB=(PROT,DRK),LENGTH=40, X00340000 - INITIAL='INVALID KEY PRESSED' 00350000 - DFHMDF POS=(2,48),LENGTH=0, * - ATTRB=ASKIP - DFHMDF POS=(5,25),LENGTH=26,INITIAL='EPS MORTGAGE CALCULATOR',* - ATTRB=(ASKIP,BRT) -EPSMORT DFHMSD TYPE=FINAL 0036000 - END 00370000 diff --git a/test/applications/MortgageApplication/cobol/epscsmrt.cbl b/test/applications/MortgageApplication/cobol/epscsmrt.cbl deleted file mode 100644 index 9df63947..00000000 --- a/test/applications/MortgageApplication/cobol/epscsmrt.cbl +++ /dev/null @@ -1,61 +0,0 @@ - CBL NUMPROC(MIG),FLAG(I,W),RENT - ID DIVISION. - PROGRAM-ID. EPSCSMRT. - * THIS IS A CALLED PROGRAM EXAMPLE FOR DEMONSTRATION - * - * THIS PROGRAM IS INVOKED VIA A CICS LINK STATMENT - * AND DYNAMICALLY CALLS THE ACTUAL PROGRAM - * - * TEST CHANGE - * - * (C) 2017 IBM JIM HILDNER. - ENVIRONMENT DIVISION. - CONFIGURATION SECTION. - SOURCE-COMPUTER. FLEX-ES. - OBJECT-COMPUTER. FLEX-ES. - DATA DIVISION. - WORKING-STORAGE SECTION. - * - 01 WS-CALLED-PROGRAM PIC X(8). - - 01 STATIC-CALLED-PROGRAMS. - 03 STATIC-CALLED-PROGRAM-TABLE. - 05 FILLER PIC X(8) VALUE 'EPSMPMT'. - 05 FILLER PIC X(8) VALUE 'NOT VLD'. - 05 FILLER PIC X(8) VALUE ' '. - 03 CALLED-PROGRAM-TABLE - REDEFINES STATIC-CALLED-PROGRAM-TABLE - OCCURS 3 TIMES. - 05 CALLED-PROGRAM-NAME PIC X(8). - - COPY EPSPDATA. - - LINKAGE SECTION. - * - 01 DFHCOMMAREA. - COPY EPSMTCOM. - - PROCEDURE DIVISION USING DFHCOMMAREA. - * - A000-MAINLINE. - MOVE EPSPCOM-PRINCIPLE-DATA TO EPSPDATA-PRINCIPLE-DATA. - MOVE EPSPCOM-NUMBER-OF-YEARS TO EPSPDATA-NUMBER-OF-YEARS. - MOVE 'Y' TO EPSPDATA-YEAR-MONTH-IND. - MOVE EPSPCOM-QUOTED-INTEREST-RATE - TO - EPSPDATA-QUOTED-INTEREST-RATE. - MOVE CALLED-PROGRAM-NAME(1) TO WS-CALLED-PROGRAM. - MOVE SPACES TO EPSPDATA-RETURN-ERROR. - * CALL 'EPSMPMT' USING EPSPDATA. - CALL WS-CALLED-PROGRAM USING EPSPDATA. - MOVE EPSPDATA-RETURN-MONTH-PAYMENT - TO - EPSPCOM-RETURN-MONTH-PAYMENT. - MOVE EPSPDATA-RETURN-ERROR TO EPSPCOM-ERRMSG. - IF EPSPDATA-RETURN-ERROR = SPACES - MOVE ZERO TO EPSPCOM-PROGRAM-RETCODE - ELSE - MOVE 8 TO EPSPCOM-PROGRAM-RETCODE - END-IF. - GOBACK - . diff --git a/test/applications/MortgageApplication/cobol/epsmlist.cbl b/test/applications/MortgageApplication/cobol/epsmlist.cbl deleted file mode 100644 index 7ba8fd24..00000000 --- a/test/applications/MortgageApplication/cobol/epsmlist.cbl +++ /dev/null @@ -1,196 +0,0 @@ - ID DIVISION. - PROGRAM-ID. EPSMLIST. - * THI DEMONSTRATES CICS/DEBUG - EPSDEMOS 2008 - * - * THIS PROGRAM WILL RECEIVE A DATE AND COVERT THE DATE TO - * AN INTEGER IN A CALLED PROGRAM TO DETERMINE DAYS FROM - * CURRENT DATE. - * - * (C) 2008 IBM - JIM HILDNER RESERVED. - ENVIRONMENT DIVISION. - CONFIGURATION SECTION. - SOURCE-COMPUTER. IBM-FLEX-ES. - OBJECT-COMPUTER. IBM-FLEX-ES. - * - DATA DIVISION. - WORKING-STORAGE SECTION. - * - 01 W-FLAGS. - 10 W-SEND-FLAG PIC X. - 88 SEND-ERASE VALUE '1'. - 88 SEND-DATAONLY VALUE '2'. - 88 SEND-MAPONLY VALUE '3'. - 88 SEND-DATAONLY-ALARM VALUE '4'. - 01 W-CONVERSIONS. - 05 W-PMT-CNVRT PIC X(12). - 05 W-PMT-NUMBER - REDEFINES W-PMT-CNVRT - PIC 9(10)V99. - 05 WS-FORMAT-NUMBER PIC Z,ZZZ,ZZ9.99. - 05 W-PRINC-CNVRT PIC X(12). - 05 W-PRINC-NUMBER - REDEFINES W-PRINC-CNVRT - PIC 9(10)V99. - 01 W-CALL-PROGRAM PIC X(8). - 01 RESPONSE PIC S9(8) COMP. - 01 INTERNAL-PROGRAM-VARIABLES. - 05 RID-LENGTH PIC S9(9) COMP. - 05 DISP-COUNT PIC S9(4) COMP. - 05 MAX-LOOP PIC S9(4) COMP - VALUE IS 8. - 05 END-OF-FILE PIC X. - 05 CLOSE-FILE PIC X. - * - 01 W-RETIREMENT-WA PIC 9(4). - 01 W-COMAREA-LENGTH PIC 9(4) COMP. - 01 SAVE-COMM-AREA. - COPY EPSMTCOM. - 01 END-OF-TRANS-MSG PIC X(30) - VALUE 'END OF TRANSACTION - THANK YOU'. - COPY DFHAID. - * COPY DFHEIBLK. - COPY EPSMLIS. - 01 OUTMAP REDEFINES EPSMLISI. - 03 FILLER PIC X(110). - 03 OUTMAP-REPEATE OCCURS 8 TIMES. - 05 FILLER PIC X(5). - 05 OUTMAP-COMPANY PIC X(24). - 05 FILLER PIC X(5). - 05 OUTMAP-PHONE-NUM PIC X(13). - 05 FILLER PIC X(5). - 05 OUTMAP-RATE PIC X(5). - 05 FILLER PIC X(5). - 05 OUTMAP-LOAN PIC X(12). - 05 FILLER PIC X(5). - 05 OUTMAP-YEARS PIC X(2). - 03 FILLER PIC X(5). - 03 OUTMAP-MSG PIC X(40). - COPY EPSNBRPM. - COPY EPSMORTF. - 01 W-COMMUNICATION-AREA. - COPY EPSMTCOM. - LINKAGE SECTION. - 01 DFHCOMMAREA. - COPY EPSMTCOM. - PROCEDURE DIVISION USING DFHCOMMAREA. - * JPH - DO I need this for files - * EXEC CICS HANDLE CONDITION H900-NOT-FOUND - EPSCMORT-MAINLINE. - MOVE LENGTH OF DFHCOMMAREA to W-COMAREA-LENGTH. - MOVE DFHCOMMAREA TO SAVE-COMM-AREA. - EVALUATE TRUE - WHEN EIBCALEN = ZERO - * First time in - Show Screen - PERFORM A100-PROCESS-MAP - WHEN EIBAID = DFHCLEAR - * Process CLEAR key - EXEC CICS - RETURN - END-EXEC - WHEN EIBAID = DFHPF3 OR DFHPF12 - * Process END/RETURN keys - EXEC CICS - RETURN - END-EXEC - WHEN EIBAID = DFHENTER - * Process ENTER Key - PERFORM A100-PROCESS-MAP - WHEN OTHER - * Present Invalid Key - PERFORM A100-PROCESS-MAP - END-EVALUATE - . - MOVE SAVE-COMM-AREA TO DFHCOMMAREA. - EXEC CICS RETURN END-EXEC. - A100-PROCESS-MAP. - PERFORM A310-ERASE-MAP. - MOVE 0 TO RID-LENGTH. - MOVE 'N' TO CLOSE-FILE. - MOVE 'N' TO END-OF-FILE. - EXEC CICS STARTBR DATASET('EPSMORTF') - RIDFLD(RID-LENGTH) RBA - EQUAL - RESP(RESPONSE) END-EXEC. - IF (RESPONSE = DFHRESP(NORMAL)) - MOVE 'Y' TO CLOSE-FILE - MOVE 1 TO DISP-COUNT - PERFORM A150-PROCESS-FILE - UNTIL END-OF-FILE = 'Y' - OR DISP-COUNT > MAX-LOOP - ELSE - MOVE 'ERROR WITH START' TO EPCMP1O - MOVE RESPONSE TO EPLOAN1O - END-IF - . - IF CLOSE-FILE = 'Y' - EXEC CICS ENDBR FILE('EPSMORTF') END-EXEC - END-IF - . - PERFORM A300-SEND-MAP. - A150-PROCESS-FILE. - EXEC CICS READNEXT FILE('EPSMORTF') - INTO(MORTGAGE-COMPANY-INFO) - RIDFLD(RID-LENGTH) - RBA RESP(RESPONSE) - END-EXEC - . - IF (RESPONSE = DFHRESP(NORMAL)) - IF EPSPCOM-PRINCIPLE-DATA OF SAVE-COMM-AREA - < MORT-FILE-LOAN - AND EPSPCOM-QUOTED-INTEREST-RATE OF SAVE-COMM-AREA - > MORT-FILE-RATE - MOVE MORT-FILE-COMPANY - TO OUTMAP-COMPANY(DISP-COUNT) - MOVE MORT-FILE-PHONE-NUM - TO OUTMAP-PHONE-NUM(DISP-COUNT) - PERFORM A600-CALCULATE-MORTGAGE - MOVE MORT-FILE-RATE - TO WS-FORMAT-NUMBER - MOVE WS-FORMAT-NUMBER(7:5) - TO OUTMAP-RATE(DISP-COUNT) - MOVE EPSPCOM-RETURN-MONTH-PAYMENT OF DFHCOMMAREA - TO WS-FORMAT-NUMBER - MOVE WS-FORMAT-NUMBER TO OUTMAP-LOAN(DISP-COUNT) - MOVE MORT-FILE-YEARS - TO OUTMAP-YEARS(DISP-COUNT) - ADD 1 TO DISP-COUNT - END-IF - ELSE - IF (RESPONSE NOT = DFHRESP(ENDFILE)) - MOVE 'ERROR WITH READ NEXT' TO EPCMP1O - MOVE RESPONSE TO EPLOAN1O - ELSE - MOVE 'Y' TO END-OF-FILE - END-IF - END-IF - . - A300-SEND-MAP. - EXEC CICS - SEND MAP ('EPSMLIS') - MAPSET('EPSMLIS') - FROM(EPSMLISO) - END-EXEC. - A310-ERASE-MAP. - MOVE LOW-VALUES TO EPSMLISO. - EXEC CICS - SEND MAP ('EPSMLIS') - MAPSET('EPSMLIS') - FROM(EPSMLISO) - ERASE - END-EXEC. - A600-CALCULATE-MORTGAGE. - MOVE SAVE-COMM-AREA TO DFHCOMMAREA. - MOVE 'Y' TO EPSPCOM-YEAR-MONTH-IND - OF DFHCOMMAREA. - MOVE MORT-FILE-RATE TO EPSPCOM-QUOTED-INTEREST-RATE - OF DFHCOMMAREA. - MOVE MORT-FILE-YEARS TO EPSPCOM-NUMBER-OF-YEARS - OF DFHCOMMAREA. - MOVE 'EPSCSMRT' TO W-CALL-PROGRAM - EXEC CICS LINK PROGRAM( W-CALL-PROGRAM ) - COMMAREA( DFHCOMMAREA ) - END-EXEC - MOVE EPSPCOM-RETURN-MONTH-PAYMENT - OF DFHCOMMAREA - TO WS-FORMAT-NUMBER. - MOVE WS-FORMAT-NUMBER TO OUTMAP-LOAN(DISP-COUNT). diff --git a/test/applications/MortgageApplication/copybook/epsmtout.cpy b/test/applications/MortgageApplication/copybook/epsmtout.cpy deleted file mode 100644 index 59cee39c..00000000 --- a/test/applications/MortgageApplication/copybook/epsmtout.cpy +++ /dev/null @@ -1,9 +0,0 @@ - * OUTPUTS - 10 EPSPCOM-RETURN-MONTH-PAYMENT - PIC S9(7)V99 COMP. - 10 EPSPCOM-ERRMSG PIC X(80). - 10 EPSPCOM-PROGRAM-RETCODE PIC 9(4). - 88 EPS02-REQUEST-SUCCESS VALUE 0. - 10 EPSPCOM-PROGRAM-RETCODE-RDF - REDEFINES EPSPCOM-PROGRAM-RETCODE - PIC X(4). diff --git a/test/applications/MortgageApplication/link/epsmlist.lnk b/test/applications/MortgageApplication/link/epsmlist.lnk deleted file mode 100644 index 42b54e63..00000000 --- a/test/applications/MortgageApplication/link/epsmlist.lnk +++ /dev/null @@ -1,3 +0,0 @@ - INCLUDE SYSLMOD(EPSMPMT) - INCLUDE SYSLIB(EPSMLIST) - NAME EPSMLIST(R) ## test diff --git a/test/applications/MortgageApplication/test.properties b/test/applications/MortgageApplication/test.properties index a21531a2..a9c0a3a0 100644 --- a/test/applications/MortgageApplication/test.properties +++ b/test/applications/MortgageApplication/test.properties @@ -3,9 +3,7 @@ ######################## # # list of test scripts to run for this application -# the order of the list matters -# impactBuild_renaming + impactBuild_deletion impact name and the number of files -# impactBuild_properties changes the build property definitions +# each test scripts is expected to be independent of other scripts test_testOrder=resetBuild.groovy,\ mergeBuild.groovy,\ fullBuild.groovy,\ diff --git a/test/test.groovy b/test/test.groovy index 405d5617..6388700f 100644 --- a/test/test.groovy +++ b/test/test.groovy @@ -6,10 +6,14 @@ import groovy.cli.commons.* println "** Executing zAppBuild test framework test/test.groovy" // Parse test script arguments and load build properties -BuildProperties props = loadBuildProperties(args) +@Field BuildProperties props = BuildProperties.getInstance() +@Field def testUtils = loadScript(new File("utils/testUtilities.groovy")) + +// load test properties +props = loadBuildProperties(args) // create a test branch to run under -createTestBranch(props) +testUtils.createTestBranch() // flag to control test process props.testsSucceeded = 'true' @@ -32,14 +36,19 @@ try { } finally { // delete test branch - deleteTestBranch(props) + testUtils.deleteTestBranch() // if error occurred signal process error if (props.testsSucceeded.toBoolean() == false) { + println "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" println("*! Not all test scripts completed successfully. Please check console outputs. Send exit signal.") + println "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" System.exit(1) } else { - println("* ZAPPBUILD TESTFRAMEWORK COMPLETED. All tests (${props.test_testOrder}) completed successfully.") + println "\n================================================================================================" + println("* ZAPPBUILD TESTFRAMEWORK COMPLETED.\n All tests (${props.test_testOrder}) completed successfully.") + println "================================================================================================" + } } @@ -70,13 +79,13 @@ def loadBuildProperties(String [] args) { // zAppBuild options a(longOpt: 'app', 'Application that is being tested (example: MortgageApplication)', args: 1, required: true) q(longOpt: 'hlq', 'HLQ for dataset reation / deletion (example: USER.BUILD)', args: 1, required: true) - u(longOpt: 'url', 'DBB Web Application server URL', args: 1, required: true) - i(longOpt: 'id', 'DBB Web Application user id', args: 1, required: true) - p(longOpt: 'pw', 'DBB Web Application user password', args: 1) - P(longOpt: 'pwFile', 'DBB Web Application user password file', args: 1) + u(longOpt: 'url', 'Db2 JDBC URL for the MetadataStore. \n Example: jdbc:db2:', args: 1) + i(longOpt: 'id', 'Db2 user id for the MetadataStore', args: 1) + p(longOpt: 'pw', 'Db2 password (encrypted with DBB Password Utility) for the MetadataStore', args: 1) + P(longOpt: 'pwFile', 'Absolute or relative (from workspace) path to file containing Db2 password', args: 1) v(longOpt: 'verbose', 'Flag indicating to print trace statements') f(longOpt: 'propFiles', 'Commas spearated list of additional property files to load. Absolute paths or relative to workspace', args:1) - o(longOpt: 'outDir', 'Absolute path to the build output root directory', args:1) + o(longOpt: 'outDir', 'Absolute path to the build output root directory', args:1) } def options = cli.parse(args) @@ -135,39 +144,3 @@ def loadBuildProperties(String [] args) { return props } - -/* - * Create and checkout a local test branch for testing - */ -def createTestBranch(BuildProperties props) { - println "** Creating and checking out branch ${props.testBranch}" - def createTestBranch = """ - cd ${props.zAppBuildDir} - git checkout ${props.branch} - git checkout -b ${props.testBranch} ${props.branch} - git status -""" - def job = ['bash', '-c', createTestBranch].execute() - job.waitFor() - def createBranch = job.in.text - println "$createBranch" -} - -/* - * Deletes test branch - */ -def deleteTestBranch(BuildProperties props) { - println "\n** Deleting test branch ${props.testBranch}" - def deleteTestBranch = """ - cd ${props.zAppBuildDir} - rm -r out - git reset --hard ${props.testBranch} - git checkout ${props.branch} - git branch -D ${props.testBranch} - git status -""" - def job = ['bash', '-c', deleteTestBranch].execute() - job.waitFor() - def deleteBranch = job.in.text - println "$deleteBranch" -} diff --git a/test/testScripts/README.md b/test/testScripts/README.md index 7456b4bd..1aaee034 100644 --- a/test/testScripts/README.md +++ b/test/testScripts/README.md @@ -1,3 +1,7 @@ +# zAppBuild test scripts + +Each test script is expected to be able to run on its own without any dependency. It is expected, that a test script resets the environment during finalizing phase of the test. + ## fullBuild.groovy This script is called by test.groovy to run a full build by creating a new “automation” branch from the feature branch specified in the command line argument. It verifies the below requirements - Full build ran clean @@ -30,14 +34,12 @@ This script is called by test.groovy to run an impact build on an update of the This script is called by test.groovy to run an impact build on a renamed source file. It verifies - clean build - that the file with the new name is built -- that the logical file with the original name is deleted from the metadata store -Please note : This script is committing a potentially breaking change to any potential following test scripts. +- that the logical file with the original name is deleted from the metadata store and the test branch is reset ## impactBuild_deletion.groovy This script is called by test.groovy. It runs a fullbuild first to set the baseline and then to execute an impact build after a source file was deleted. It verifies - that the deleted file is correctly detected -- that the deleted output file is removed from the build library -Please note : This script is committing disrupting changes to the test branch and need to run at the end. - +- that the deleted output file is removed from the build library and the test branch is reset + ## resetBuild.groovy This is a maintenance script that runs at the end of this test pipeline to delete collections and build result groups. diff --git a/test/testScripts/fullBuild.groovy b/test/testScripts/fullBuild.groovy index b706b371..34a7f600 100644 --- a/test/testScripts/fullBuild.groovy +++ b/test/testScripts/fullBuild.groovy @@ -2,10 +2,13 @@ import groovy.transform.* import com.ibm.dbb.* import com.ibm.dbb.build.* -import com.ibm.jzos.ZFile @Field BuildProperties props = BuildProperties.getInstance() -println "\n** Executing test script fullBuild.groovy" +@Field def testUtils = loadScript(new File("../utils/testUtilities.groovy")) + +println "\n**************************************************************" +println "** Executing test script ${this.class.getName()}.groovy" +println "**************************************************************" // Get the DBB_HOME location def dbbHome = EnvVars.getHome() @@ -20,9 +23,10 @@ fullBuildCommand << "--application ${props.app}" fullBuildCommand << (props.outDir ? "--outDir ${props.outDir}" : "--outDir ${props.zAppBuildDir}/out") fullBuildCommand << "--hlq ${props.hlq}" fullBuildCommand << "--logEncoding UTF-8" -fullBuildCommand << "--url ${props.url}" -fullBuildCommand << "--id ${props.id}" -fullBuildCommand << (props.pw ? "--pw ${props.pw}" : "--pwFile ${props.pwFile}") +fullBuildCommand << (props.url ? "--url ${props.url}" : "") +fullBuildCommand << (props.id ? "--id ${props.id}" : "") +fullBuildCommand << (props.pw ? "--pw ${props.pw}" : "") +fullBuildCommand << (props.pwFile ? "--pwFile ${props.pwFile}" : "") fullBuildCommand << (props.verbose ? "--verbose" : "") fullBuildCommand << (props.propFiles ? "--propFiles ${props.propFiles}" : "") fullBuildCommand << "--fullBuild" @@ -60,7 +64,7 @@ catch(AssertionError e) { props.testsSucceeded = 'false' } finally { - cleanUpDatasets() + // report failures if (assertionList.size()>0) { println "\n***" println "**START OF FAILED FULL BUILD TEST RESULTS**\n" @@ -68,7 +72,8 @@ finally { println "\n**END OF FAILED FULL BUILD **" println "***" } - + + testUtils.cleanUpDatasets(props.fullBuild_datasetsToCleanUp) } // script end @@ -76,16 +81,3 @@ finally { //************************************************************* // Method Definitions //************************************************************* - -def cleanUpDatasets() { - def segments = props.fullBuild_datasetsToCleanUp.split(',') - - println "Deleting full build PDSEs ${segments}" - segments.each { segment -> - def pds = "'${props.hlq}.${segment}'" - if (ZFile.dsExists(pds)) { - if (props.verbose) println "** Deleting ${pds}" - ZFile.remove("//$pds") - } - } -} diff --git a/test/testScripts/fullBuild_debug.groovy b/test/testScripts/fullBuild_debug.groovy index 9fa7f5c7..562a2368 100644 --- a/test/testScripts/fullBuild_debug.groovy +++ b/test/testScripts/fullBuild_debug.groovy @@ -2,19 +2,19 @@ import groovy.transform.* import com.ibm.dbb.* import com.ibm.dbb.build.* -import com.ibm.jzos.ZFile @Field BuildProperties props = BuildProperties.getInstance() - @Field def testUtils = loadScript(new File("../utils/testUtilities.groovy")) -println "\n** Executing test script fullBuild_debug.groovy" +println "\n**************************************************************" +println "** Executing test script ${this.class.getName()}.groovy" +println "**************************************************************" // Get the DBB_HOME location def dbbHome = EnvVars.getHome() if (props.verbose) println "** DBB_HOME = ${dbbHome}" -// Create full build command +// Create full build command with debug option def fullBuildCommand = [] fullBuildCommand << "${dbbHome}/bin/groovyz" fullBuildCommand << "${props.zAppBuildDir}/build.groovy" @@ -23,9 +23,10 @@ fullBuildCommand << "--application ${props.app}" fullBuildCommand << (props.outDir ? "--outDir ${props.outDir}" : "--outDir ${props.zAppBuildDir}/out") fullBuildCommand << "--hlq ${props.hlq}" fullBuildCommand << "--logEncoding UTF-8" -fullBuildCommand << "--url ${props.url}" -fullBuildCommand << "--id ${props.id}" -fullBuildCommand << (props.pw ? "--pw ${props.pw}" : "--pwFile ${props.pwFile}") +fullBuildCommand << (props.url ? "--url ${props.url}" : "") +fullBuildCommand << (props.id ? "--id ${props.id}" : "") +fullBuildCommand << (props.pw ? "--pw ${props.pw}" : "") +fullBuildCommand << (props.pwFile ? "--pwFile ${props.pwFile}" : "") fullBuildCommand << "--verbose" fullBuildCommand << (props.propFiles ? "--propFiles ${props.propFiles}" : "") fullBuildCommand << "--fullBuild" @@ -81,7 +82,8 @@ catch(AssertionError e) { props.testsSucceeded = 'false' } finally { - cleanUpDatasets() + + // report failures if (assertionList.size()>0) { println "\n***" println "**START OF FAILED FULL BUILD WITH DEBUG TEST RESULTS**\n" @@ -89,6 +91,9 @@ finally { println "\n**END OF FAILED FULL BUILD WITH DEBUG**" println "***" } + + testUtils.cleanUpDatasets(props.fullBuild_debug_datasetsToCleanUp) + } @@ -97,16 +102,3 @@ finally { //************************************************************* // Method Definitions //************************************************************* - -def cleanUpDatasets() { - def segments = props.fullBuild_debug_datasetsToCleanUp.split(',') - - println "Deleting full build PDSEs ${segments}" - segments.each { segment -> - def pds = "'${props.hlq}.${segment}'" - if (ZFile.dsExists(pds)) { - if (props.verbose) println "** Deleting ${pds}" - ZFile.remove("//$pds") - } - } -} diff --git a/test/testScripts/fullBuild_languageConfigurations.groovy b/test/testScripts/fullBuild_languageConfigurations.groovy index f91a8755..31c01ffe 100644 --- a/test/testScripts/fullBuild_languageConfigurations.groovy +++ b/test/testScripts/fullBuild_languageConfigurations.groovy @@ -2,10 +2,13 @@ import groovy.transform.* import com.ibm.dbb.* import com.ibm.dbb.build.* -import com.ibm.jzos.ZFile @Field BuildProperties props = BuildProperties.getInstance() -println "\n** Executing test script fullBuild_languageConfigurations.groovy" +@Field def testUtils = loadScript(new File("../utils/testUtilities.groovy")) + +println "\n**************************************************************" +println "** Executing test script ${this.class.getName()}.groovy" +println "**************************************************************" // Get the DBB_HOME location def dbbHome = EnvVars.getHome() @@ -20,9 +23,10 @@ fullBuildCommand << "--application ${props.app}" fullBuildCommand << (props.outDir ? "--outDir ${props.outDir}" : "--outDir ${props.zAppBuildDir}/out") fullBuildCommand << "--hlq ${props.hlq}" fullBuildCommand << "--logEncoding UTF-8" -fullBuildCommand << "--url ${props.url}" -fullBuildCommand << "--id ${props.id}" -fullBuildCommand << (props.pw ? "--pw ${props.pw}" : "--pwFile ${props.pwFile}") +fullBuildCommand << (props.url ? "--url ${props.url}" : "") +fullBuildCommand << (props.id ? "--id ${props.id}" : "") +fullBuildCommand << (props.pw ? "--pw ${props.pw}" : "") +fullBuildCommand << (props.pwFile ? "--pwFile ${props.pwFile}" : "") fullBuildCommand << (props.verbose ? "--verbose" : "") fullBuildCommand << (props.propFiles ? "--propFiles ${props.propFiles}" : "") fullBuildCommand << "--fullBuild" @@ -36,9 +40,10 @@ userBuildCommand << "--application ${props.app}" userBuildCommand << (props.outDir ? "--outDir ${props.outDir}" : "--outDir ${props.zAppBuildDir}/out") userBuildCommand << "--hlq ${props.hlq}" userBuildCommand << "--logEncoding UTF-8" -userBuildCommand << "--url ${props.url}" -userBuildCommand << "--id ${props.id}" -userBuildCommand << (props.pw ? "--pw ${props.pw}" : "--pwFile ${props.pwFile}") +userBuildCommand << (props.url ? "--url ${props.url}" : "") +userBuildCommand << (props.id ? "--id ${props.id}" : "") +userBuildCommand << (props.pw ? "--pw ${props.pw}" : "") +userBuildCommand << (props.pwFile ? "--pwFile ${props.pwFile}" : "") userBuildCommand << (props.verbose ? "--verbose" : "") userBuildCommand << (props.propFiles ? "--propFiles ${props.propFiles}" : "") userBuildCommand << "--userBuild ${props.userBuild_languageConfigurations_buildFile}" @@ -157,10 +162,8 @@ catch(AssertionError e) { props.testsSucceeded = 'false' } finally { - cleanUpDatasets() - // reset language configuration changes - resetLanguageConfigurationChanges() - + + // report failures if (assertionList.size()>0) { println "\n***" println "**START OF FAILED TEST CASE for Language Configuration Overrides TEST RESULTS**\n" @@ -168,6 +171,10 @@ finally { println "\n**END OF FAILED TEST CASE for Language Configurations **" println "***" } + + testUtils.cleanUpDatasets(props.fullBuild_languageConfigurations_datasetsToCleanUp) + // reset language configuration changes + resetLanguageConfigurationChanges() } @@ -214,15 +221,3 @@ def resetLanguageConfigurationChanges() { task.waitForProcessOutput(outputStream, System.err) } -def cleanUpDatasets() { - def segments = props.fullBuild_languageConfigurations_datasetsToCleanUp.split(',') - - println "Deleting full build PDSEs ${segments}" - segments.each { segment -> - def pds = "'${props.hlq}.${segment}'" - if (ZFile.dsExists(pds)) { - if (props.verbose) println "** Deleting ${pds}" - ZFile.remove("//$pds") - } - } -} diff --git a/test/testScripts/impactBuild.groovy b/test/testScripts/impactBuild.groovy index 1c6fde56..9b0ad04b 100644 --- a/test/testScripts/impactBuild.groovy +++ b/test/testScripts/impactBuild.groovy @@ -3,31 +3,18 @@ import groovy.transform.* import com.ibm.dbb.* import com.ibm.dbb.build.* -import com.ibm.jzos.ZFile @Field BuildProperties props = BuildProperties.getInstance() -println "\n** Executing test script impactBuild.groovy" +@Field def testUtils = loadScript(new File("../utils/testUtilities.groovy")) + +println "\n**************************************************************" +println "** Executing test script ${this.class.getName()}.groovy" +println "**************************************************************" // Get the DBB_HOME location def dbbHome = EnvVars.getHome() if (props.verbose) println "** DBB_HOME = ${dbbHome}" -// Create full build command to set baseline -def fullBuildCommand = [] -fullBuildCommand << "${dbbHome}/bin/groovyz" -fullBuildCommand << "${props.zAppBuildDir}/build.groovy" -fullBuildCommand << "--workspace ${props.workspace}" -fullBuildCommand << "--application ${props.app}" -fullBuildCommand << (props.outDir ? "--outDir ${props.outDir}" : "--outDir ${props.zAppBuildDir}/out") -fullBuildCommand << "--hlq ${props.hlq}" -fullBuildCommand << "--logEncoding UTF-8" -fullBuildCommand << "--url ${props.url}" -fullBuildCommand << "--id ${props.id}" -fullBuildCommand << (props.pw ? "--pw ${props.pw}" : "--pwFile ${props.pwFile}") -fullBuildCommand << (props.verbose ? "--verbose" : "") -fullBuildCommand << (props.propFiles ? "--propFiles ${props.propFiles}" : "") -fullBuildCommand << "--fullBuild" - // create impact build command def impactBuildCommand = [] impactBuildCommand << "${dbbHome}/bin/groovyz" @@ -37,9 +24,10 @@ impactBuildCommand << "--application ${props.app}" impactBuildCommand << (props.outDir ? "--outDir ${props.outDir}" : "--outDir ${props.zAppBuildDir}/out") impactBuildCommand << "--hlq ${props.hlq}" impactBuildCommand << "--logEncoding UTF-8" -impactBuildCommand << "--url ${props.url}" -impactBuildCommand << "--id ${props.id}" -impactBuildCommand << (props.pw ? "--pw ${props.pw}" : "--pwFile ${props.pwFile}") +impactBuildCommand << (props.url ? "--url ${props.url}" : "") +impactBuildCommand << (props.id ? "--id ${props.id}" : "") +impactBuildCommand << (props.pw ? "--pw ${props.pw}" : "") +impactBuildCommand << (props.pwFile ? "--pwFile ${props.pwFile}" : "") impactBuildCommand << (props.verbose ? "--verbose" : "") impactBuildCommand << (props.propFiles ? "--propFiles ${props.propFiles}" : "") impactBuildCommand << "--impactBuild" @@ -51,23 +39,16 @@ def changedFiles = props.impactBuild_changedFiles.split(',') println("** Processing changed files from impactBuild_changedFiles property : ${props.impactBuild_changedFiles}") try { - println "\n** Running full build to set baseline" - - // run impact build - println "** Executing ${fullBuildCommand.join(" ")}" - def outputStream = new StringBuffer() - def process = [ - 'bash', - '-c', - fullBuildCommand.join(" ") - ].execute() - process.waitForProcessOutput(outputStream, System.err) + // Create full build command to set baseline + testUtils.runBaselineBuild() + // test setup changedFiles.each { changedFile -> println "\n** Running impact build test for changed file $changedFile" // update changed file in Git repo test branch - copyAndCommit(changedFile) + testUtils.updateFileAndCommit(props.appLocation, changedFile) + // run impact build println "** Executing ${impactBuildCommand.join(" ")}" @@ -80,7 +61,7 @@ try { } } finally { - cleanUpDatasets() + // report failures if (assertionList.size()>0) { println "\n***" println "**START OF FAILED IMPACT BUILD TEST RESULTS**\n" @@ -88,6 +69,9 @@ finally { println "\n**END OF FAILED IMPACT BUILD TEST RESULTS**" println "***" } + + // cleanup datasets + testUtils.cleanUpDatasets(props.impactBuild_datasetsToCleanUp) } // script end @@ -95,19 +79,6 @@ finally { // Method Definitions //************************************************************* -def copyAndCommit(String changedFile) { - println "** Copying and committing ${props.zAppBuildDir}/test/applications/${props.app}/${changedFile} to ${props.appLocation}/${changedFile}" - def commands = """ - cp ${props.zAppBuildDir}/test/applications/${props.app}/${changedFile} ${props.appLocation}/${changedFile} - cd ${props.appLocation}/ - git add . - git commit . -m "edited program file" -""" - def task = ['bash', '-c', commands].execute() - def outputStream = new StringBuffer(); - task.waitForProcessOutput(outputStream, System.err) -} - def validateImpactBuild(String changedFile, PropertyMappings filesBuiltMappings, StringBuffer outputStream) { println "** Validating impact build results" @@ -134,15 +105,3 @@ def validateImpactBuild(String changedFile, PropertyMappings filesBuiltMappings, props.testsSucceeded = 'false' } } -def cleanUpDatasets() { - def segments = props.impactBuild_datasetsToCleanUp.split(',') - - println "Deleting impact build PDSEs ${segments}" - segments.each { segment -> - def pds = "'${props.hlq}.${segment}'" - if (ZFile.dsExists(pds)) { - if (props.verbose) println "** Deleting ${pds}" - ZFile.remove("//$pds") - } - } -} diff --git a/test/testScripts/impactBuild_deletion.groovy b/test/testScripts/impactBuild_deletion.groovy index 34c10a56..7616ce9c 100644 --- a/test/testScripts/impactBuild_deletion.groovy +++ b/test/testScripts/impactBuild_deletion.groovy @@ -3,31 +3,18 @@ import groovy.transform.* import com.ibm.dbb.* import com.ibm.dbb.build.* -import com.ibm.jzos.ZFile @Field BuildProperties props = BuildProperties.getInstance() -println "\n** Executing test script impactBuild_deletion.groovy" +@Field def testUtils = loadScript(new File("../utils/testUtilities.groovy")) + +println "\n**************************************************************" +println "** Executing test script ${this.class.getName()}.groovy" +println "**************************************************************" // Get the DBB_HOME location def dbbHome = EnvVars.getHome() if (props.verbose) println "** DBB_HOME = ${dbbHome}" -// Create full build command to set baseline and populate output libraries -def fullBuildCommand = [] -fullBuildCommand << "${dbbHome}/bin/groovyz" -fullBuildCommand << "${props.zAppBuildDir}/build.groovy" -fullBuildCommand << "--workspace ${props.workspace}" -fullBuildCommand << "--application ${props.app}" -fullBuildCommand << (props.outDir ? "--outDir ${props.outDir}" : "--outDir ${props.zAppBuildDir}/out") -fullBuildCommand << "--hlq ${props.hlq}" -fullBuildCommand << "--logEncoding UTF-8" -fullBuildCommand << "--url ${props.url}" -fullBuildCommand << "--id ${props.id}" -fullBuildCommand << (props.pw ? "--pw ${props.pw}" : "--pwFile ${props.pwFile}") -fullBuildCommand << (props.verbose ? "--verbose" : "") -fullBuildCommand << (props.propFiles ? "--propFiles ${props.propFiles},${props.zAppBuildDir}/test/applications/${props.app}/${props.impactBuild_deletion_buildPropSetting}" : "--propFiles ${props.zAppBuildDir}/test/applications/${props.app}/${props.impactBuild_deletion_buildPropSetting}") -fullBuildCommand << "--fullBuild" - // create impact build command def impactBuildCommand = [] impactBuildCommand << "${dbbHome}/bin/groovyz" @@ -37,9 +24,10 @@ impactBuildCommand << "--application ${props.app}" impactBuildCommand << (props.outDir ? "--outDir ${props.outDir}" : "--outDir ${props.zAppBuildDir}/out") impactBuildCommand << "--hlq ${props.hlq}" impactBuildCommand << "--logEncoding UTF-8" -impactBuildCommand << "--url ${props.url}" -impactBuildCommand << "--id ${props.id}" -impactBuildCommand << (props.pw ? "--pw ${props.pw}" : "--pwFile ${props.pwFile}") +impactBuildCommand << (props.url ? "--url ${props.url}" : "") +impactBuildCommand << (props.id ? "--id ${props.id}" : "") +impactBuildCommand << (props.pw ? "--pw ${props.pw}" : "") +impactBuildCommand << (props.pwFile ? "--pwFile ${props.pwFile}" : "") impactBuildCommand << "--verbose" impactBuildCommand << (props.propFiles ? "--propFiles ${props.propFiles},${props.zAppBuildDir}/test/applications/${props.app}/${props.impactBuild_deletion_buildPropSetting}" : "--propFiles ${props.zAppBuildDir}/test/applications/${props.app}/${props.impactBuild_deletion_buildPropSetting}") impactBuildCommand << "--impactBuild" @@ -53,18 +41,10 @@ PropertyMappings outputsDeletedMappings = new PropertyMappings('impactBuild_dele def deleteFiles = props.impactBuild_deletion_deleteFiles.split(',') try { - println "\n** Running full build to set baseline" - - // run impact build - println "** Executing ${fullBuildCommand.join(" ")}" - def outputStream = new StringBuffer() - def process = [ - 'bash', - '-c', - fullBuildCommand.join(" ") - ].execute() - process.waitForProcessOutput(outputStream, System.err) - + // Create full build command to set baseline + testUtils.runBaselineBuild() + + // test setup deleteFiles.each{ deleteFile -> // delete file in Git repo test branch @@ -87,7 +67,8 @@ try { } } finally { - cleanUpDatasets() + + // report failures if (assertionList.size()>0) { println "\n***" println "**START OF FAILED IMPACT BUILD TEST RESULTS FOR FILE DELETION**\n" @@ -95,6 +76,12 @@ finally { println "\n**END OF FAILED IMPACT BUILD TEST RESULTS FOR FILE DELETION**" println "***" } + + // reset test branch + testUtils.resetTestBranch() + + // cleanup datasets + testUtils.cleanUpDatasets(props.impactBuild_deletion_datasetsToCleanUp) } // script end @@ -150,15 +137,4 @@ def validateImpactBuild(String deleteFile, PropertyMappings outputsDeletedMappin props.testsSucceeded = 'false' } } -def cleanUpDatasets() { - def segments = props.impactBuild_deletion_datasetsToCleanUp.split(',') - - println "Deleting impact build PDSEs ${segments}" - segments.each { segment -> - def pds = "'${props.hlq}.${segment}'" - if (ZFile.dsExists(pds)) { - if (props.verbose) println "** Deleting ${pds}" - ZFile.remove("//$pds") - } - } -} + diff --git a/test/testScripts/impactBuild_preview.groovy b/test/testScripts/impactBuild_preview.groovy index a65187f1..2c0fb83c 100644 --- a/test/testScripts/impactBuild_preview.groovy +++ b/test/testScripts/impactBuild_preview.groovy @@ -3,31 +3,18 @@ import groovy.transform.* import com.ibm.dbb.* import com.ibm.dbb.build.* -import com.ibm.jzos.ZFile @Field BuildProperties props = BuildProperties.getInstance() -println "\n** Executing test script impactBuild_preview.groovy" +@Field def testUtils = loadScript(new File("../utils/testUtilities.groovy")) + +println "\n**************************************************************" +println "** Executing test script ${this.class.getName()}.groovy" +println "**************************************************************" // Get the DBB_HOME location def dbbHome = EnvVars.getHome() if (props.verbose) println "** DBB_HOME = ${dbbHome}" -// Create full build command to set baseline -def fullBuildCommand = [] -fullBuildCommand << "${dbbHome}/bin/groovyz" -fullBuildCommand << "${props.zAppBuildDir}/build.groovy" -fullBuildCommand << "--workspace ${props.workspace}" -fullBuildCommand << "--application ${props.app}" -fullBuildCommand << (props.outDir ? "--outDir ${props.outDir}" : "--outDir ${props.zAppBuildDir}/out") -fullBuildCommand << "--hlq ${props.hlq}" -fullBuildCommand << "--logEncoding UTF-8" -fullBuildCommand << "--url ${props.url}" -fullBuildCommand << "--id ${props.id}" -fullBuildCommand << (props.pw ? "--pw ${props.pw}" : "--pwFile ${props.pwFile}") -fullBuildCommand << (props.verbose ? "--verbose" : "") -fullBuildCommand << (props.propFiles ? "--propFiles ${props.propFiles}" : "") -fullBuildCommand << "--fullBuild" - // create impact build command for preview def impactBuildPreviewCommand = [] impactBuildPreviewCommand << "${dbbHome}/bin/groovyz" @@ -37,9 +24,10 @@ impactBuildPreviewCommand << "--application ${props.app}" impactBuildPreviewCommand << (props.outDir ? "--outDir ${props.outDir}" : "--outDir ${props.zAppBuildDir}/out") impactBuildPreviewCommand << "--hlq ${props.hlq}" impactBuildPreviewCommand << "--logEncoding UTF-8" -impactBuildPreviewCommand << "--url ${props.url}" -impactBuildPreviewCommand << "--id ${props.id}" -impactBuildPreviewCommand << (props.pw ? "--pw ${props.pw}" : "--pwFile ${props.pwFile}") +impactBuildPreviewCommand << (props.url ? "--url ${props.url}" : "") +impactBuildPreviewCommand << (props.id ? "--id ${props.id}" : "") +impactBuildPreviewCommand << (props.pw ? "--pw ${props.pw}" : "") +impactBuildPreviewCommand << (props.pwFile ? "--pwFile ${props.pwFile}" : "") impactBuildPreviewCommand << (props.verbose ? "--verbose" : "") impactBuildPreviewCommand << (props.propFiles ? "--propFiles ${props.propFiles}" : "") impactBuildPreviewCommand << "--impactBuild --preview" // this will run zAppBuild only in preview mode. @@ -53,9 +41,10 @@ impactBuildCommand << "--application ${props.app}" impactBuildCommand << (props.outDir ? "--outDir ${props.outDir}" : "--outDir ${props.zAppBuildDir}/out") impactBuildCommand << "--hlq ${props.hlq}" impactBuildCommand << "--logEncoding UTF-8" -impactBuildCommand << "--url ${props.url}" -impactBuildCommand << "--id ${props.id}" -impactBuildCommand << (props.pw ? "--pw ${props.pw}" : "--pwFile ${props.pwFile}") +impactBuildCommand << (props.url ? "--url ${props.url}" : "") +impactBuildCommand << (props.id ? "--id ${props.id}" : "") +impactBuildCommand << (props.pw ? "--pw ${props.pw}" : "") +impactBuildCommand << (props.pwFile ? "--pwFile ${props.pwFile}" : "") impactBuildCommand << (props.verbose ? "--verbose" : "") impactBuildCommand << (props.propFiles ? "--propFiles ${props.propFiles}" : "") impactBuildCommand << "--impactBuild" @@ -67,23 +56,14 @@ def changedFiles = props.impactBuild_preview_changedFiles.split(',') println("** Processing changed files from impactBuild_preview_changedFiles property : ${props.impactBuild_preview_changedFiles}") try { - println "\n** Running full build to set baseline" - - // run impact build - println "** Executing ${fullBuildCommand.join(" ")}" - def outputStream = new StringBuffer() - def process = [ - 'bash', - '-c', - fullBuildCommand.join(" ") - ].execute() - process.waitForProcessOutput(outputStream, System.err) + // Create full build command to set baseline + testUtils.runBaselineBuild() changedFiles.each { changedFile -> println "\n** Running IMPACT BUILD WITH PREVIEW TEST for changed file $changedFile" // update changed file in Git repo test branch - copyAndCommit(changedFile) + testUtils.updateFileAndCommit(props.appLocation, changedFile) // run impact build with preview println "** Executing ${impactBuildPreviewCommand.join(" ")}" @@ -105,7 +85,7 @@ try { } } finally { - cleanUpDatasets() + // report failures if (assertionList.size()>0) { println "\n***" println "**START OF FAILED IMPACT BUILD WITH PREVIEW TEST RESULTS**\n" @@ -113,6 +93,10 @@ finally { println "\n**END OF FAILED IMPACT BUILD WITH PREVIEW TEST RESULTS**" println "***" } + + // cleanup datasets + testUtils.cleanUpDatasets(props.impactBuild_preview_datasetsToCleanUp) + } // script end @@ -120,19 +104,6 @@ finally { // Method Definitions //************************************************************* -def copyAndCommit(String changedFile) { - println "** Updating and committing ${props.appLocation}/${changedFile}" - def commands = """ - echo ' ' >> ${props.appLocation}/${changedFile} - cd ${props.appLocation}/ - git add . - git commit . -m "edited program file" -""" - def task = ['bash', '-c', commands].execute() - def outputStream = new StringBuffer(); - task.waitForProcessOutput(outputStream, System.err) -} - def validateImpactBuild(String changedFile, PropertyMappings filesBuiltMappings, StringBuffer outputStream) { println "** Validating impact build results" @@ -159,15 +130,3 @@ def validateImpactBuild(String changedFile, PropertyMappings filesBuiltMappings, props.testsSucceeded = 'false' } } -def cleanUpDatasets() { - def segments = props.impactBuild_preview_datasetsToCleanUp.split(',') - - println "Deleting impact build PDSEs ${segments}" - segments.each { segment -> - def pds = "'${props.hlq}.${segment}'" - if (ZFile.dsExists(pds)) { - if (props.verbose) println "** Deleting ${pds}" - ZFile.remove("//$pds") - } - } -} diff --git a/test/testScripts/impactBuild_properties.groovy b/test/testScripts/impactBuild_properties.groovy index 6bbea355..f783f72a 100644 --- a/test/testScripts/impactBuild_properties.groovy +++ b/test/testScripts/impactBuild_properties.groovy @@ -3,31 +3,18 @@ import groovy.transform.* import com.ibm.dbb.* import com.ibm.dbb.build.* -import com.ibm.jzos.ZFile @Field BuildProperties props = BuildProperties.getInstance() -println "\n### Executing test script impactBuild_properties.groovy" +@Field def testUtils = loadScript(new File("../utils/testUtilities.groovy")) + +println "\n**************************************************************" +println "** Executing test script ${this.class.getName()}.groovy" +println "**************************************************************" // Get the DBB_HOME location def dbbHome = EnvVars.getHome() if (props.verbose) println "** DBB_HOME = ${dbbHome}" -// Create full build command to initilize property dependencies -def fullBuildCommand = [] -fullBuildCommand << "${dbbHome}/bin/groovyz" -fullBuildCommand << "${props.zAppBuildDir}/build.groovy" -fullBuildCommand << "--workspace ${props.workspace}" -fullBuildCommand << "--application ${props.app}" -fullBuildCommand << (props.outDir ? "--outDir ${props.outDir}" : "--outDir ${props.zAppBuildDir}/out") -fullBuildCommand << "--hlq ${props.hlq}" -fullBuildCommand << "--logEncoding UTF-8" -fullBuildCommand << "--url ${props.url}" -fullBuildCommand << "--id ${props.id}" -fullBuildCommand << (props.pw ? "--pw ${props.pw}" : "--pwFile ${props.pwFile}") -fullBuildCommand << (props.verbose ? "--verbose" : "") -fullBuildCommand << (props.propFiles ? "--propFiles ${props.propFiles},${props.zAppBuildDir}/test/applications/${props.app}/${props.impactBuild_properties_buildPropSetting}" : "--propFiles ${props.zAppBuildDir}/test/applications/${props.app}/${props.impactBuild_properties_buildPropSetting}") -fullBuildCommand << "--fullBuild" - // create impact build command def impactBuildCommand = [] impactBuildCommand << "${dbbHome}/bin/groovyz" @@ -37,9 +24,10 @@ impactBuildCommand << "--application ${props.app}" impactBuildCommand << (props.outDir ? "--outDir ${props.outDir}" : "--outDir ${props.zAppBuildDir}/out") impactBuildCommand << "--hlq ${props.hlq}" impactBuildCommand << "--logEncoding UTF-8" -impactBuildCommand << "--url ${props.url}" -impactBuildCommand << "--id ${props.id}" -impactBuildCommand << (props.pw ? "--pw ${props.pw}" : "--pwFile ${props.pwFile}") +impactBuildCommand << (props.url ? "--url ${props.url}" : "") +impactBuildCommand << (props.id ? "--id ${props.id}" : "") +impactBuildCommand << (props.pw ? "--pw ${props.pw}" : "") +impactBuildCommand << (props.pwFile ? "--pwFile ${props.pwFile}" : "") impactBuildCommand << (props.verbose ? "--verbose" : "") impactBuildCommand << (props.propFiles ? "--propFiles ${props.propFiles},${props.zAppBuildDir}/test/applications/${props.app}/${props.impactBuild_properties_buildPropSetting}" : "--propFiles ${props.zAppBuildDir}/test/applications/${props.app}/${props.impactBuild_properties_buildPropSetting}") impactBuildCommand << "--impactBuild" @@ -48,24 +36,19 @@ impactBuildCommand << "--impactBuild" @Field def assertionList = [] PropertyMappings filesBuiltMappings = new PropertyMappings('impactBuild_properties_expectedFilesBuilt') def changedPropFile = props.impactBuild_properties_changedFile -println("** Processing changed files from impactBuild_properties_changedFiles property : ${changedPropFile}") try { - println "\n** Running build to set baseline" - - // run impact build - println "** Executing ${fullBuildCommand.join(" ")}" - def outputStream = new StringBuffer() - def process = ['bash', '-c', fullBuildCommand.join(" ")].execute() - process.waitForProcessOutput(outputStream, System.err) - - - println "\n** Running impact build test for changed file $changedPropFile" - + // Test process + + // Create full build command to set baseline + testUtils.runBaselineBuild("${props.zAppBuildDir}/test/applications/${props.app}/${props.impactBuild_properties_buildPropSetting}") + // update changed file in Git repo test branch - copyAndCommit(changedPropFile) + println("\n** Injecting property update impactBuild_properties_changedFiles property : ${changedPropFile}") + testUtils.copyAndCommit(changedPropFile) // run impact build + println "\n** Running impact build test for changed file $changedPropFile" println "** Executing ${impactBuildCommand.join(" ")}" outputStream = new StringBuffer() process = ['bash', '-c', impactBuildCommand.join(" ")].execute() @@ -75,14 +58,20 @@ try { validateImpactBuild(changedPropFile, filesBuiltMappings, outputStream) } finally { - cleanUpDatasets() - if (assertionList.size()>0) { + // report failures + if (assertionList.size()>0) { println "\n***" println "**START OF FAILED IMPACT BUILD ON PROPERTY CHANGE TEST RESULTS**\n" println "*FAILED IMPACT BUILD ON PROPERT CHANGE TEST RESULTS*\n" + assertionList println "\n**END OF FAILED IMPACT BUILD ON PROPERTY CHANGE TEST RESULTS**" println "***" } + + // reset test branch + testUtils.resetTestBranch() + + // cleanup datasets + testUtils.cleanUpDatasets(props.impactBuild_properties_datasetsToCleanUp) } // script end @@ -90,18 +79,7 @@ finally { // Method Definitions //************************************************************* -def copyAndCommit(String changedFile) { - println "** Copying and committing ${props.zAppBuildDir}/test/applications/${props.app}/${changedFile} to ${props.appLocation}/${changedFile}" - def commands = """ - cp ${props.zAppBuildDir}/test/applications/${props.app}/${changedFile} ${props.appLocation}/${changedFile} - cd ${props.appLocation}/ - git add . - git commit . -m "edited program file" -""" - def task = ['bash', '-c', commands].execute() - def outputStream = new StringBuffer(); - task.waitForProcessOutput(outputStream, System.err) -} + def validateImpactBuild(String changedFile, PropertyMappings filesBuiltMappings, StringBuffer outputStream) { @@ -129,15 +107,3 @@ def validateImpactBuild(String changedFile, PropertyMappings filesBuiltMappings, props.testsSucceeded = 'false' } } -def cleanUpDatasets() { - def segments = props.impactBuild_properties_datasetsToCleanUp.split(',') - - println "Deleting impact build PDSEs ${segments}" - segments.each { segment -> - def pds = "'${props.hlq}.${segment}'" - if (ZFile.dsExists(pds)) { - if (props.verbose) println "** Deleting ${pds}" - ZFile.remove("//$pds") - } - } -} diff --git a/test/testScripts/impactBuild_renaming.groovy b/test/testScripts/impactBuild_renaming.groovy index 8e7ed295..aa71f052 100644 --- a/test/testScripts/impactBuild_renaming.groovy +++ b/test/testScripts/impactBuild_renaming.groovy @@ -3,10 +3,13 @@ import groovy.transform.* import com.ibm.dbb.* import com.ibm.dbb.build.* -import com.ibm.jzos.ZFile @Field BuildProperties props = BuildProperties.getInstance() -println "\n** Executing test script impactBuild_renaming.groovy" +@Field def testUtils = loadScript(new File("../utils/testUtilities.groovy")) + +println "\n**************************************************************" +println "** Executing test script ${this.class.getName()}.groovy" +println "**************************************************************" // Get the DBB_HOME location def dbbHome = EnvVars.getHome() @@ -21,9 +24,10 @@ impactBuildCommand << "--application ${props.app}" impactBuildCommand << (props.outDir ? "--outDir ${props.outDir}" : "--outDir ${props.zAppBuildDir}/out") impactBuildCommand << "--hlq ${props.hlq}" impactBuildCommand << "--logEncoding UTF-8" -impactBuildCommand << "--url ${props.url}" -impactBuildCommand << "--id ${props.id}" -impactBuildCommand << (props.pw ? "--pw ${props.pw}" : "--pwFile ${props.pwFile}") +impactBuildCommand << (props.url ? "--url ${props.url}" : "") +impactBuildCommand << (props.id ? "--id ${props.id}" : "") +impactBuildCommand << (props.pw ? "--pw ${props.pw}" : "") +impactBuildCommand << (props.pwFile ? "--pwFile ${props.pwFile}" : "") impactBuildCommand << "--verbose" impactBuildCommand << (props.propFiles ? "--propFiles ${props.propFiles}" : "") impactBuildCommand << "--impactBuild" @@ -36,6 +40,11 @@ PropertyMappings renamedFilesMapping = new PropertyMappings('impactBuild_rename_ def renameFiles = props.impactBuild_rename_renameFiles.split(',') try { + + // Create full build command to set baseline + testUtils.runBaselineBuild() + + // run through tests renameFiles.each{ renameFile -> newFilename=renamedFilesMapping.getValue(renameFile) @@ -60,7 +69,7 @@ try { } } finally { - cleanUpDatasets() + // report failures if (assertionList.size()>0) { println "\n***" println "**START OF FAILED IMPACT BUILD TEST RESULTS**\n" @@ -68,6 +77,12 @@ finally { println "\n**END OF FAILED IMPACT BUILD TEST RESULTS**" println "***" } + + // reset test branch + testUtils.resetTestBranch() + + // cleanup datasets + testUtils.cleanUpDatasets(props.impactBuild_rename_datasetsToCleanUp) } // script end @@ -116,15 +131,4 @@ def validateImpactBuild(String renameFile, PropertyMappings filesBuiltMappings, props.testsSucceeded = 'false' } } -def cleanUpDatasets() { - def segments = props.impactBuild_rename_datasetsToCleanUp.split(',') - - println "Deleting impact build PDSEs ${segments}" - segments.each { segment -> - def pds = "'${props.hlq}.${segment}'" - if (ZFile.dsExists(pds)) { - if (props.verbose) println "** Deleting ${pds}" - ZFile.remove("//$pds") - } - } -} + diff --git a/test/testScripts/mergeBuild.groovy b/test/testScripts/mergeBuild.groovy index b384b19e..98ddf705 100644 --- a/test/testScripts/mergeBuild.groovy +++ b/test/testScripts/mergeBuild.groovy @@ -3,10 +3,13 @@ import groovy.transform.* import com.ibm.dbb.* import com.ibm.dbb.build.* -import com.ibm.jzos.ZFile @Field BuildProperties props = BuildProperties.getInstance() -println "\n** Executing test script mergeBuild.groovy" +@Field def testUtils = loadScript(new File("../utils/testUtilities.groovy")) + +println "\n**************************************************************" +println "** Executing test script ${this.class.getName()}.groovy" +println "**************************************************************" // Get the DBB_HOME location def dbbHome = EnvVars.getHome() @@ -24,9 +27,10 @@ mergeBuildCommand << "--application ${props.app}" mergeBuildCommand << (props.outDir ? "--outDir ${props.outDir}" : "--outDir ${props.zAppBuildDir}/out") mergeBuildCommand << "--hlq ${props.hlq}" mergeBuildCommand << "--logEncoding UTF-8" -mergeBuildCommand << "--url ${props.url}" -mergeBuildCommand << "--id ${props.id}" -mergeBuildCommand << (props.pw ? "--pw ${props.pw}" : "--pwFile ${props.pwFile}") +mergeBuildCommand << (props.url ? "--url ${props.url}" : "") +mergeBuildCommand << (props.id ? "--id ${props.id}" : "") +mergeBuildCommand << (props.pw ? "--pw ${props.pw}" : "") +mergeBuildCommand << (props.pwFile ? "--pwFile ${props.pwFile}" : "") mergeBuildCommand << (props.verbose ? "--verbose" : "") mergeBuildCommand << (props.propFiles ? "--propFiles ${props.zAppBuildDir}/test/applications/${props.app}/${props.mergeBuild_buildPropSetting},${props.propFiles}" : "") mergeBuildCommand << "--mergeBuild" @@ -35,13 +39,19 @@ mergeBuildCommand << "--mergeBuild" @Field def assertionList = [] PropertyMappings filesBuiltMappings = new PropertyMappings('mergeBuild_expectedFilesBuilt') def changedFiles = props.mergeBuild_changedFiles.split(',') -println("** Processing changed files from mergeBuild_changedFiles property : ${props.mergeBuild_changedFiles}") try { + + // Create full build command to set baseline + testUtils.runBaselineBuild() + + // test setup + println("** Processing changed files from mergeBuild_changedFiles property : ${props.mergeBuild_changedFiles}") + changedFiles.each { changedFile -> println "\n** Running merge build test for changed file $changedFile" // update changed file in Git repo test branch - copyAndCommit(changedFile) + testUtils.updateFileAndCommit(props.appLocation, changedFile) // run merge build println "** Executing ${mergeBuildCommand.join(" ")}" @@ -54,7 +64,7 @@ try { } } finally { - cleanUpDatasets() + // report failures if (assertionList.size()>0) { println "\n***" println "**START OF FAILED MERGED BUILD TEST RESULTS**\n" @@ -62,6 +72,9 @@ finally { println "\n**END OF FAILED MERGED BUILD TEST RESULTS**" println "***" } + // cleanup datasets + testUtils.cleanUpDatasets(props.mergeBuild_datasetsToCleanUp) + } // script end @@ -81,19 +94,6 @@ def writePropsFile() { } -def copyAndCommit(String changedFile) { - println "** Copying and committing ${props.zAppBuildDir}/test/applications/${props.app}/${changedFile} to ${props.appLocation}/${changedFile}" - def commands = """ - cp ${props.zAppBuildDir}/test/applications/${props.app}/${changedFile} ${props.appLocation}/${changedFile} - cd ${props.appLocation}/ - git add . - git commit . -m "edited program file" -""" - def task = ['bash', '-c', commands].execute() - def outputStream = new StringBuffer(); - task.waitForProcessOutput(outputStream, System.err) -} - def validateMergeBuild(String changedFile, PropertyMappings filesBuiltMappings, StringBuffer outputStream) { println "** Validating merge build results" @@ -120,15 +120,4 @@ def validateMergeBuild(String changedFile, PropertyMappings filesBuiltMappings, props.testsSucceeded = 'false' } } -def cleanUpDatasets() { - def segments = props.mergeBuild_datasetsToCleanUp.split(',') - - println "Deleting merge build PDSEs ${segments}" - segments.each { segment -> - def pds = "'${props.hlq}.${segment}'" - if (ZFile.dsExists(pds)) { - if (props.verbose) println "** Deleting ${pds}" - ZFile.remove("//$pds") - } - } -} + diff --git a/test/testScripts/resetBuild.groovy b/test/testScripts/resetBuild.groovy index f549afa5..419ef7d8 100644 --- a/test/testScripts/resetBuild.groovy +++ b/test/testScripts/resetBuild.groovy @@ -2,10 +2,12 @@ import groovy.transform.* import com.ibm.dbb.* import com.ibm.dbb.build.* -import com.ibm.jzos.ZFile @Field BuildProperties props = BuildProperties.getInstance() -println "\n** Executing test script resetBuild.groovy" + +println "\n**************************************************************" +println "** Executing test script ${this.class.getName()}.groovy" +println "**************************************************************" // Get the DBB_HOME location def dbbHome = EnvVars.getHome() @@ -20,9 +22,10 @@ resetBuildCommand << "--application ${props.app}" resetBuildCommand << (props.outDir ? "--outDir ${props.outDir}" : "--outDir ${props.zAppBuildDir}/out") resetBuildCommand << "--hlq ${props.hlq}" resetBuildCommand << "--logEncoding UTF-8" -resetBuildCommand << "--url ${props.url}" -resetBuildCommand << "--id ${props.id}" -resetBuildCommand << (props.pw ? "--pw ${props.pw}" : "--pwFile ${props.pwFile}") +resetBuildCommand << (props.url ? "--url ${props.url}" : "") +resetBuildCommand << (props.id ? "--id ${props.id}" : "") +resetBuildCommand << (props.pw ? "--pw ${props.pw}" : "") +resetBuildCommand << (props.pwFile ? "--pwFile ${props.pwFile}" : "") resetBuildCommand << (props.verbose ? "--verbose" : "") resetBuildCommand << (props.propFiles ? "--propFiles ${props.propFiles}" : "") resetBuildCommand << "--reset" diff --git a/test/utils/testUtilities.groovy b/test/utils/testUtilities.groovy index f78fd2cf..a359ebb8 100644 --- a/test/utils/testUtilities.groovy +++ b/test/utils/testUtilities.groovy @@ -1,11 +1,17 @@ @groovy.transform.BaseScript com.ibm.dbb.groovy.ScriptLoader baseScript +import groovy.transform.* import java.io.File +import com.ibm.dbb.* import com.ibm.dbb.build.* import java.util.regex.Pattern import java.util.regex.Matcher import com.ibm.dbb.build.report.BuildReport +import com.ibm.jzos.ZFile import com.ibm.dbb.build.report.records.* +// properties instance +@Field BuildProperties props = BuildProperties.getInstance() + /* * testUtilities * @@ -83,4 +89,186 @@ boolean buildReportIncludesOutput(BuildReport buildReport, String member, String } else { return false } +} + + +/** + * updateFileAndCommit + * is inserting a blank line at the end of the provided file + * and commits the file back to the repository + * + * used in impact build test scenarios + * + */ + +def updateFileAndCommit(String path, String changedFile) { + println "** Updating and committing ${path}/${changedFile}" + + def commentStmt = ' ' + + if (changedFile.endsWith("bms")) { // treat BMS files + commentStmt = '* Updated file \n END' + } + + def commands = """ + echo -en \'${commentStmt}\' >> ${path}/${changedFile} + cd ${path}/ + git add . + git commit . -m "edited program file $changedFile" +""" + def task = ['bash', '-c', commands].execute() + def outputStream = new StringBuffer(); + task.waitForProcessOutput(outputStream, System.err) +} + +/** + * copyAndCommit + * copies a reference file and commits it to the test branch + * + * used in impact build test scenarios + * + */ +def copyAndCommit(String changedFile) { + println "** Copying and committing ${props.zAppBuildDir}/test/applications/${props.app}/${changedFile} to ${props.appLocation}/${changedFile}" + def commands = """ + cp ${props.zAppBuildDir}/test/applications/${props.app}/${changedFile} ${props.appLocation}/${changedFile} + cd ${props.appLocation}/ + git add . + git commit . -m "edited program file $changedFile" +""" + def task = ['bash', '-c', commands].execute() + def outputStream = new StringBuffer(); + task.waitForProcessOutput(outputStream, System.err) +} + +/** + * cleanUpDatasets + * deletes datasets + * + * accepts a comma separated list of last level qualifiers (llq) + * iterates over the lists to delete them + * + */ +def cleanUpDatasets(String datasets) { + def segments = datasets.split(',') + + println "\n** Deleting build PDSEs ${segments}" + segments.each { segment -> + def pds = "'${props.hlq}.${segment}'" + if (ZFile.dsExists(pds)) { + if (props.verbose) println "** Deleting ${pds}" + ZFile.remove("//$pds") + } + } +} + +/* + * Create and checkout a local test branch for testing + */ +def createTestBranch() { + println "** Creating and checking out branch ${props.testBranch}" + def createTestBranch = """ + cd ${props.zAppBuildDir} + git checkout ${props.branch} + git checkout -b ${props.testBranch} ${props.branch} + git status +""" + def job = ['bash', '-c', createTestBranch].execute() + job.waitFor() + def createBranch = job.in.text + println "$createBranch" +} + +/* + * Deletes test branch + */ +def deleteTestBranch() { + println "\n** Deleting test branch ${props.testBranch}" + def deleteTestBranch = """ + cd ${props.zAppBuildDir} + rm -r out + git reset --hard ${props.testBranch} + git checkout ${props.branch} + git branch -D ${props.testBranch} + git status +""" + def job = ['bash', '-c', deleteTestBranch].execute() + job.waitFor() + def deleteBranch = job.in.text + println "$deleteBranch" +} + +/* + * Reset test branch + * to be used for any disruptive test scripts + */ +def resetTestBranch() { + println "\n** Resetting test branch ${props.testBranch}" + deleteTestBranch() + createTestBranch() +} + + +/** + * runBaselineBuild to initialize collections and build result history + * + * to be used by any test script which uses impact analysis + * + * input parms: + * + * testScriptPropFiles are used to configure + * the test via additional properties files + * that are loaded via the --propFiles cli argument + * + */ + +/* + * without arguments, it will not pass any test scripts specific configuration + * + */ + +def runBaselineBuild() { + runBaselineBuild(null) +} + +/* + * + */ + +def runBaselineBuild(String testScriptPropFiles) { + + println "\n** Running full build to set baseline" + + def dbbHome = EnvVars.getHome() + + def fullBuildCommand = [] + fullBuildCommand << "${dbbHome}/bin/groovyz" + fullBuildCommand << "${props.zAppBuildDir}/build.groovy" + fullBuildCommand << "--workspace ${props.workspace}" + fullBuildCommand << "--application ${props.app}" + fullBuildCommand << (props.outDir ? "--outDir ${props.outDir}" : "--outDir ${props.zAppBuildDir}/out") + fullBuildCommand << "--hlq ${props.hlq}" + fullBuildCommand << "--logEncoding UTF-8" + fullBuildCommand << (props.url ? "--url ${props.url}" : "") + fullBuildCommand << (props.id ? "--id ${props.id}" : "") + fullBuildCommand << (props.pw ? "--pw ${props.pw}" : "") + fullBuildCommand << (props.pwFile ? "--pwFile ${props.pwFile}" : "") + fullBuildCommand << (props.verbose ? "--verbose" : "") + if (props.propFiles && testScriptPropFiles) { + fullBuildCommand << "--propFiles ${props.propFiles},${testScriptPropFiles}" + } else if (props.propFiles) { + fullBuildCommand << "--propFiles ${props.propFiles}" + } + fullBuildCommand << "--fullBuild" + + // run impact build + println "** Executing ${fullBuildCommand.join(" ")}" + def outputStream = new StringBuffer() + def process = [ + 'bash', + '-c', + fullBuildCommand.join(" ") + ].execute() + process.waitForProcessOutput(outputStream, System.err) + } \ No newline at end of file From 3d434930d1208ace54ded83ce39c1d4c3da67a7c Mon Sep 17 00:00:00 2001 From: Dennis Behm Date: Wed, 21 Jun 2023 11:17:49 +0200 Subject: [PATCH 4/8] Ability to maintain consistent metadata store for dependencies on generated zunit test case (#368) * Skip building generated test cases and skip running impact build on generated test cases Signed-off-by: Dennis Behm --- languages/Cobol.groovy | 2 +- languages/PLI.groovy | 2 +- utilities/BuildUtilities.groovy | 12 ++++++++++++ utilities/ImpactUtilities.groovy | 15 +++++++++++++-- 4 files changed, 27 insertions(+), 4 deletions(-) diff --git a/languages/Cobol.groovy b/languages/Cobol.groovy index 7639304e..4c5f2ff7 100644 --- a/languages/Cobol.groovy +++ b/languages/Cobol.groovy @@ -37,7 +37,7 @@ sortedList.each { buildFile -> println "*** (${currentBuildFileNumber++}/${sortedList.size()}) Building file $buildFile" // Check if this a testcase - isZUnitTestCase = (props.getFileProperty('cobol_testcase', buildFile).equals('true')) ? true : false + isZUnitTestCase = buildUtils.isGeneratedzUnitTestCaseProgram(buildFile) // configure dependency resolution and create logical file String dependencySearch = props.getFileProperty('cobol_dependencySearch', buildFile) diff --git a/languages/PLI.groovy b/languages/PLI.groovy index e6f924cd..f6036373 100644 --- a/languages/PLI.groovy +++ b/languages/PLI.groovy @@ -35,7 +35,7 @@ sortedList.each { buildFile -> println "*** (${currentBuildFileNumber++}/${sortedList.size()}) Building file $buildFile" // Check if this a testcase - isZUnitTestCase = (props.getFileProperty('pli_testcase', buildFile).equals('true')) ? true : false + isZUnitTestCase = buildUtils.isGeneratedzUnitTestCaseProgram(buildFile) // configure SearchPathDependencyResolver String dependencySearch = props.getFileProperty('pli_dependencySearch', buildFile) diff --git a/utilities/BuildUtilities.groovy b/utilities/BuildUtilities.groovy index be366709..5963157b 100644 --- a/utilities/BuildUtilities.groovy +++ b/utilities/BuildUtilities.groovy @@ -849,3 +849,15 @@ def printLogicalFileAttributes(LogicalFile logicalFile) { } +/** + * Validates if a buildFile is a zUnit generated test case program + * + * returns true / false + * + */ +def isGeneratedzUnitTestCaseProgram(String buildFile) { + if (props.getFileProperty('cobol_testcase', buildFile).equals('true') || props.getFileProperty('pli_testcase', buildFile).equals('true')) { + return true + } + return false +} diff --git a/utilities/ImpactUtilities.groovy b/utilities/ImpactUtilities.groovy index fb57a3b2..0569fa16 100644 --- a/utilities/ImpactUtilities.groovy +++ b/utilities/ImpactUtilities.groovy @@ -62,8 +62,13 @@ def createImpactBuildList() { changedFiles.each { changedFile -> // if the changed file has a build script then add to build list if (ScriptMappings.getScriptName(changedFile)) { - buildSet.add(changedFile) - if (props.verbose) println "** Found build script mapping for $changedFile. Adding to build list" + // skip adding generated test cases, when the testing is disabled + if (buildUtils.isGeneratedzUnitTestCaseProgram(changedFile) || !(props.runzTests && props.runzTests.toBoolean())) { + if (props.verbose) println "** Identified $changedFile as a generated zunit test case program. Processing zUnit tests is not enabled for this build. Skip building this program." + } else { + buildSet.add(changedFile) + if (props.verbose) println "** Found build script mapping for $changedFile. Adding to build list" + } } // check if impact calculation should be performed, default true @@ -773,6 +778,12 @@ def boolean shouldCalculateImpacts(String changedFile){ // return false if changedFile found in skipImpactCalculationList if (onskipImpactCalculationList) return false + + // return false if the changed file is a generated test case program but testing is disabled + if (buildUtils.isGeneratedzUnitTestCaseProgram(changedFile) || !(props.runzTests && props.runzTests.toBoolean())) { + return false + } + return true //default } From 8a3dd0ab634486b4906da07ef93554d4a4293a74 Mon Sep 17 00:00:00 2001 From: Dennis Behm Date: Wed, 21 Jun 2023 11:18:47 +0200 Subject: [PATCH 5/8] Avoid additional scan of build file during impact analysis (#371) * Avoid additional scan of build file during impact analysis by adding the file to the cache Signed-off-by: Dennis Behm --- utilities/ImpactUtilities.groovy | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/utilities/ImpactUtilities.groovy b/utilities/ImpactUtilities.groovy index 0569fa16..eacfd9b4 100644 --- a/utilities/ImpactUtilities.groovy +++ b/utilities/ImpactUtilities.groovy @@ -8,6 +8,7 @@ import java.nio.file.PathMatcher import groovy.json.JsonSlurper import groovy.transform.* import java.util.regex.* +import com.ibm.dbb.dependency.internal.* // define script properties @Field BuildProperties props = BuildProperties.getInstance() @@ -554,9 +555,15 @@ def updateCollection(changedFiles, deletedFiles, renamedFiles) { if (props.verbose) println "*** Scanning file $file (${props.workspace}/${file} with ${scanner.getClass()})" logicalFile = scanner.scan(file, props.workspace) } else { + // The below logic should be replaced with Registration Scanner when available + // See reported idea: https://ibm-z-software-portal.ideas.ibm.com/ideas/DBB-I-48 if (props.verbose) println "*** Skipped scanning file $file (${props.workspace}/${file})" + // New logical file with Membername, buildfile, language set to file extension logicalFile = new LogicalFile(CopyToPDS.createMemberName(file), file, file.substring(file.lastIndexOf(".") + 1).toUpperCase(), false, false, false) + + // Add logicalFile to LogicalFileCache + LogicalFileCache.add(props.workspace, logicalFile) } if (props.verbose) println "*** Logical file for $file =\n$logicalFile" From ed7c200995c99b82996d96d9af8bba4da6fc99b7 Mon Sep 17 00:00:00 2001 From: Dennis Behm Date: Tue, 11 Jul 2023 16:34:52 +0200 Subject: [PATCH 6/8] Fix condition to evaluate generated test cases and zunit processing (#382) * Fix condition to evaluate generated test cases and zunit processing Signed-off-by: Dennis Behm --- utilities/ImpactUtilities.groovy | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utilities/ImpactUtilities.groovy b/utilities/ImpactUtilities.groovy index eacfd9b4..a4e165df 100644 --- a/utilities/ImpactUtilities.groovy +++ b/utilities/ImpactUtilities.groovy @@ -64,7 +64,7 @@ def createImpactBuildList() { // if the changed file has a build script then add to build list if (ScriptMappings.getScriptName(changedFile)) { // skip adding generated test cases, when the testing is disabled - if (buildUtils.isGeneratedzUnitTestCaseProgram(changedFile) || !(props.runzTests && props.runzTests.toBoolean())) { + if (buildUtils.isGeneratedzUnitTestCaseProgram(changedFile) && !(props.runzTests && props.runzTests.toBoolean())) { if (props.verbose) println "** Identified $changedFile as a generated zunit test case program. Processing zUnit tests is not enabled for this build. Skip building this program." } else { buildSet.add(changedFile) @@ -787,7 +787,7 @@ def boolean shouldCalculateImpacts(String changedFile){ if (onskipImpactCalculationList) return false // return false if the changed file is a generated test case program but testing is disabled - if (buildUtils.isGeneratedzUnitTestCaseProgram(changedFile) || !(props.runzTests && props.runzTests.toBoolean())) { + if (buildUtils.isGeneratedzUnitTestCaseProgram(changedFile) && !(props.runzTests && props.runzTests.toBoolean())) { return false } From e9c5ef3fb45d84ee2dff8718db1f4fc8203ba5a6 Mon Sep 17 00:00:00 2001 From: Dennis Behm Date: Wed, 12 Jul 2023 10:47:20 +0200 Subject: [PATCH 7/8] Tolerate but skip old dbb.scannerMapping configurations (#385) * Tolerate but skip old dbb.scannerMapping configurations Signed-off-by: Dennis Behm --- utilities/DependencyScannerUtilities.groovy | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/utilities/DependencyScannerUtilities.groovy b/utilities/DependencyScannerUtilities.groovy index 357c2649..3896013d 100644 --- a/utilities/DependencyScannerUtilities.groovy +++ b/utilities/DependencyScannerUtilities.groovy @@ -146,8 +146,11 @@ def parseConfigStringToMap(String configString) { } } - // validate existance of scannerClass definition - assert scannerConfigMap.scannerClass != null + if (scannerConfigMap.scannerClass == null) { + println "*! The provided scanner mapping configuration ($configString) is not formed correctly and skipped." + println "*! Sample syntax: 'dbb.scannerMapping = \"scannerClass\":\"DependencyScanner\", \"languageHint\":\"COB\" :: cbl,cpy,cob'" + return null + } return scannerConfigMap } \ No newline at end of file From 17a4b4dd0e607c93e06ec9606c547eda691c7957 Mon Sep 17 00:00:00 2001 From: Dennis Behm Date: Thu, 13 Jul 2023 08:40:26 +0200 Subject: [PATCH 8/8] Skip inspecting load modules when running in preview mode (#387) * Skip inspecting load modules when running in preview mode Signed-off-by: Dennis Behm --- utilities/ImpactUtilities.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utilities/ImpactUtilities.groovy b/utilities/ImpactUtilities.groovy index a4e165df..be4aa2bf 100644 --- a/utilities/ImpactUtilities.groovy +++ b/utilities/ImpactUtilities.groovy @@ -638,7 +638,7 @@ def updateCollection(changedFiles, deletedFiles, renamedFiles) { */ def saveStaticLinkDependencies(String buildFile, String loadPDS, LogicalFile logicalFile) { MetadataStore metadataStore = MetadataStoreFactory.getMetadataStore() - if (metadataStore && !props.error) { + if (metadataStore && !props.error && !props.preview) { LinkEditScanner scanner = new LinkEditScanner() if (props.verbose) println "*** Scanning load module for $buildFile" LogicalFile scannerLogicalFile = scanner.scan(buildUtils.relativizePath(buildFile), loadPDS)