Technical Articles
Step 16 with SAP Cloud SDK: Quality Checks
Disclaimer: The SAP Cloud SDK for Continuous Delivery and its features have been merged into project “Piper”. Therefore we recommend to use the General Purpose Pipeline of project “Piper” instead of the SAP Cloud SDK pipeline. The reasoning for this change, as well as further information on how to adopt the General Purpose Pipeline are described in this guide.
The following steps will introduce the Quality Checks stage of the SAP Cloud SDK Pipeline, which is executed if the application finishes all the previous stages, including Build stage, Local Tests stage and Remote Tests stage.
Note: This post is part of a series. For a complete overview visit the SAP Cloud SDK Overview.
Prerequisite
Read the tutorials:
- Step 5 with SAP Cloud SDK: Resilience with Hystrix
- Step 13 with SAP Cloud SDK: Automated Testing
- Step 14 with SAP Cloud SDK: Continuous integration and delivery
Goal of this Blog Post
This blog post covers the following tutorials:
- Introduce what is checked inside the Quality Checks stage and why they are essential from quality perspective.
- Demonstrate which behaviour can result in failing pipeline build with real examples.
- Explain how to fix these examples with debugging steps.
Overview
Basically, the Quality Checks stage consists of the following three sections:
- Check Hystrix
- Check Service Used
- Check Code Coverage
Only applications passing all these sections are allowed to go through the whole stage.
Check Hystrix
First of all, I’ll introduce the section of Check Hystrix.
As shown in the Step 5 with SAP Cloud SDK: Resilience with Hystrix, by using Hystrix, your application can achieve higher availability in terms of remote call service onto the SAP Cloud Platform, e.g., OData and BAPI call.
In order to provide resilient service for the customer, the Quality Checks stage also verifies your source code to make sure all the remote call services are equipped with Hystrix.
Example of failing build
Failing to do so will result in the following error message, causing the FAILURE
result of the pipeline build.
How to fix
To fix the Jenkins build, all the service call listed in the error message should be wrapped in an ErpCommand
. A useful hint here is that you can search for some keywords to navigate the problematic code. In our case, we can search for “FCO_PI_COST_CENTER
“, and below is the search result which should be fixed:
public class HealthCheckCommand
{
private ErpConfigContext configContext;
public HealthCheckCommand(final ErpConfigContext configContext )
{
this.configContext = configContext;
}
public List<CostCenterDetails> execute() throws Exception
{
final List<CostCenterDetails> costCenterDetails =
ODataQueryBuilder
.withEntity("/sap/FCO_PI_COST_CENTER", "CostCenterCollection")
.select("CostCenterID")
.top(1)
.build()
.execute(configContext)
.asList(CostCenterDetails.class);
return costCenterDetails;
}
}
Please check the Step 5 with SAP Cloud SDK: Resilience with Hystrix for more details regarding Hystrix.
Check Services Used
Secondly, let’s have a look at the next section, Check Service Used.
Users can benefit from the S/4 HAHA Cloud SDK, when leveraging OData, BAPI and RFM service call from their applications on the SAP Cloud Platform. On the other hand, however, only official services are permitted to be utilised in order to build your applications with high quality.
The Quality Checks stage helps detect non-official service call. Your Jenkins pipeline build will not be successful if services beyond the whitelist are found.
Example of failing build
The error message below shows a real example which violates the rules, leading to the failing build.
How to fix
Again, the service keywords from the error message (FCO_PI_COST_CENTER_PRIVATE
) can be used as a hint, helping search for the class which should be fixed like below:
private static class GetPrivateCostCenterCommand extends ErpCommand<List<CostCenterDetails>>
{
GetPrivateCostCenterCommand( final ErpEndpoint erpEndpoint )
{
super(GetPrivateCostCenterCommand.class, erpEndpoint);
}
@Override
protected List<CostCenterDetails> run()
throws Exception
{
final ODataQueryBuilder builder =
ODataQueryBuilder.withEntity("/sap/FCO_PI_COST_CENTER_PRIVATE", "CostCenterCollection");
return builder.build().execute(getErpEndpoint()).asList(CostCenterDetails.class);
}
}
Please find all the current official services in the Appendix.
Check Code Coverage
And last but not least, let me show you our Check Code Coverage section.
Code coverage is a measure of the amount of the source code of the application executed when running automated tests. Applications with higher code coverage are more likely to avoid undetected bugs. Usually, the code coverage is expressed as percentages for different categories, such as classes, methods and lines.
The Quality Checks stage collects test reports generated from Backend Unit Tests stage and Backend Integration Tests stage, aggregates them and presents the historical code coverage trend for the users.
By clicking the link of a single Jenkins build, you are able to view the overall coverage, the package coverage, and the source file coverage statistics.
When getting into the source file coverage report, your source code is marked with different background colours indicating which lines are covered or not covered by your automated tests.
All the coverage trend report (line charts), the coverage summary (bar charts) and the source code report highlighted by colourful background above are produced by JaCoCo Jenkins Plug-in.
JaCoCo Configuration
JaCoCo Maven Plug-in provides the JaCoCo runtime agent for your tests and generates basic coverage criteria, such as line coverage, method coverage and class coverage and so on.
Below is the pom.xml
file which you can find in the unit-tests
module as well as in the integration-tests
module of the archetype project.
<properties>
......
<jacoco.destFile>${project.build.directory}/coverage-reports/jacoco-ut.exec</jacoco.destFile>
</properties>
......
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.9</version>
<configuration>
<destFile>${jacoco.destFile}</destFile>
</configuration>
......
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.20</version>
<configuration>
<argLine>@{argLine}
-Xmx${surefire.maxMemorySize}
-XX:MaxPermSize=${surefire.maxPermSize}
</argLine>
</configuration>
</plugin>
......
</plugins>
</build>
Note: The destFile
configuration is used as a path where the execution data file will be exported by JaCoCo. The @{argLine}
is the placeholder of a property prepared that points to the JaCoCo runtime agent. Both of these configurations should not be modified to ensure that the JaCoCo Jenkins Plug-in creates precise code coverage reports.
Example of failing build
The console output illustrates the situation when your build fails due to low code coverage:
How to fix
It says, the JaCoCo Jenkins Plug-in is configured in the way that if
- line coverage >= 70%, then the build status is SUCCESSFUL.
- line coverage < 65%, then the build status is FAILURE.
- line coverage between 65% (inclusive) and 70% (exclusive), then the build status is UNSTABLE.
In order to fix the Jenkins build, therefore, you should write additional tests to achieve at least 70% line coverage threshold, which can either be unit tests or integration tests.
Customise excludes
You can also exclude some source code from the code coverage report by configuring the pipeline_config.yml
like below, which can be found in the root folder of your archetype. This configuration, however, is just a convenient tool, and is not recommended. You should always consider adding more tests instead of making use of this config file.
s4SdkQualityChecks:
jacocoExcludes:
- 'com/sap/cloud/sdk/tutorial/SpringBootWebApplication.class'
Now you understand the Quality Checks stage in-depth and are able to find clues to make your broken pipeline green again, if your build is aborted in the Quality Checks stage.
Questions and Bugs
Are you facing a development question? Then check out Stack Overflow, the main place for SAP Cloud SDK related questions. If you do not find an answer, feel free to post it and make sure to attach the tag ‘s4sdk’. Our team, as well as the whole Stack Overflow community, are at your service and will quickly react to your question.
For an overview of SAP Cloud SDK related questions, go to https://stackoverflow.com/questions/tagged/s4sdk.
You think that you found a bug in one of our Continuous Delivery artifacts? Feel free to open an issue in our Pipeline GitHub repository on https://github.com/SAP/cloud-s4-sdk-pipeline/issues.
Appendix: Official Services
BAPIs and RFMs
- BAPI_TRANSACTION_COMMIT
- BAPI_TRANSACTION_ROLLBACK
- BAPI_COSTCENTER_CREATEMULTIPLE
- BAPI_ACCSTMT_CREATEFROMPREVDAY
- BAPI_ACC_PRIMARY_COSTS_POST
- BAPI_ACC_PRIMARY_COSTS_CHECK
- BAPI_ACC_MANUAL_ALLOC_POST
- BAPI_ACC_MANUAL_ALLOC_CHECK
- BAPI_ACC_DOCUMENT_POST
- BAPI_ACC_DOCUMENT_CHECK
- BAPI_ACC_ACTIVITY_ALLOC_POST
- BAPI_ACC_ACTIVITY_ALLOC_CHECK
- BAPI_FIXEDASSET_CHANGE
- BAPI_FIXEDASSET_CREATE1
- BAPI_FIXEDASSET_GETLIST
- BAPI_FTR_FXT_DEALGET
- BAPI_FTR_FXOPTION_GETDETAIL
- BAPI_FTR_FXT_DEALCREATE
- BAPI_FTR_FXT_CREATESWAP
- BAPI_FTR_CREATE_FXOPTIONS
- FCXL_GET_ASPECT_DEFINITION
- FCXL_GET_ATTRIBUTE_VALUE
- FCXL_GET_CHAR_ATTRIBUTES
- FCXL_GET_CHAR_HIERARCHIES
- FCXL_GET_CHAR_SETS
- FCXL_GET_CHAR_VALUES
- FCXL_GET_CONSOLIDATION_ASPECTS
- FCXL_GET_DATA
- FCXL_GET_HIERARCHY_VALUES
- FCXL_GET_MASS_DATA
- FCXL_GET_PROGRAM_TEXTS
- FCXL_GET_SET_VALUES
- FCXL_GET_UPDATEABLE
- FCXL_SET_DATA
- FC_ITEM_PROP_GET_RFC
- FC_ITGRP_PROP_GET_RFC
- FC_GLOBAL_PARAMS_IMPORT_RFC
- FC_GLOBAL_PARAMS_EXPORT_RFC
OData
- API_BILL_OF_MATERIAL_SRV
- API_BUSINESS_PARTNER
- API_CHANGEMASTER
- API_CREDIT_MEMO_REQUEST_SRV
- API_CUSTOMER_MATERIAL_SRV
- API_CUSTOMER_RETURN_SRV
- API_CV_ATTACHMENT_SRV
- API_DEBIT_MEMO_REQUEST_SRV
- API_DEFECTCATEGORY_SRV
- API_DEFECTCLASS_SRV
- API_DEFECTCODE_SRV
- API_DEFECT_SRV
- API_FORECAST_DEMAND_SRV
- API_INSPECTIONMETHOD_SRV
- API_LEGAL_TRANSACTION_SRV
- API_MASTERINSPCHARACTERISTIC_SRV
- API_MATERIAL_DOCUMENT_SRV
- API_MATERIAL_STOCK_SRV
- API_MATERIAL_VALUATION_SRV
- API_OUTBOUND_DELIVERY_SRV
- API_PHYSICAL_INVENTORY_DOC_SRV
- API_PLANNED_ORDERS
- API_PROCESS_ORDERS
- API_PROC_ORDER_CONFIRMATION
- API_PRODUCTION_ORDERS
- API_PRODUCT_ALLOCATION_OBJECT_SRV
- API_PRODUCT_ALLOC_SEQUENCE_SRV
- API_PRODUCT_AVAILY_INFO_BASIC
- API_PRODUCT_SRV
- API_PROD_ORDER_CONFIRMATION
- API_PURCHASECONTRACT_PROCESS_SRV
- API_PURCHASEORDER_PROCESS_SRV
- API_PURCHASEREQ_PROCESS_SRV
- API_PURCHASING_CATEGORY_SRV
- API_QTN_PROCESS_SRV
- API_RAWSUBSTANCE
- API_REALSUBSTANCE
- API_RECIPE
- API_RFQ_PROCESS_SRV
- API_SALES_CONTRACT_SRV
- API_SALES_INQUIRY_SRV
- API_SALES_ORDER_SRV
- API_SALES_QUOTATION_SRV
- API_SCHED_AGRMT_PROCESS_SRV
- API_SERVICE_ENTRY_SHEET_SRV
- API_SUPLR_EVAL_RESPONSE_SRV
- API_SUPLR_EVAL_SCORECARD_SRV
- API_SUPPLIERINVOICE_PROCESS_SRV
- API_SUPPLIER_ACTIVITY_SRV
- API_SUPPLIER_ACTIVITY_TASK_SRV
- API_WORK_CENTERS
- BC_EXT_APPJOB_MANAGEMENT
- CA_BEH_SUBSCRIPTION_SRV
- CO_FNDEI_CURRENCY_RL
- CO_FNDEI_EXCHANGERATE_RL
- CO_FNDEI_INCOTERMS_RL
- CO_FNDEI_ITEMCATEGORY_RL
- CO_FNDEI_MATERIALGROUP_RL
- CO_FNDEI_REGION_RL
- CO_FNDEI_UNITOFMEASUREMENT_RL
- CO_MDG_BP_RELATIONSHIP_CNF_OUT
- CO_MDG_BP_RELATIONSHIP_OUT
- CO_MDG_BP_RPLCTCO
- CO_MDG_BP_RPLCTRQ
- CO_MDM_PRD_BULK_REPL_REQ_OUT
- CO_MDM_PRD_BULK_REP_CONF_OUT
- CO_PSWBSELEMENT_MASTER_DATA_RE
- C_BEHQUEUEDATA_CDS
- ECC_PROJBYIDQR
- FCO_PI_COST_CENTER
- II_FINS_JOURNAL_ENTRY_CREATE_R
- II_IVE_SUPLRINVCERPCRTRC
- II_MDG_BP_BUSINESS_PARTNER_RE1
- II_MDG_BP_BUSINESS_PARTNER_REL
- II_MDG_BP_RPLCTCO
- II_MDG_BP_RPLCTRQ
- II_MDM_PRD_BULK_REP_CONF_IN
- II_MDM_PRD_BULK_REP_REQ
- II_PRS_PRJ_WBS_BY_ID_QR
- II_PRS_PRJ_WBW_QR
- II_SHP_OUTBDELIVREQ003QR
- II_SHP_OUTBOUNDDELIVERY100QR
- II_SHP_OUTBOUNDDELIVERYCNCRC
- II_SHP_OUTBOUNDDELIVERYCWRRC
- _CPD_SC_EXTERNAL_SERVICES_SRV
See the next tutorial in the series here: Step 17 with SAP Cloud SDK: Monitoring.
Hi,
I am trying to check and run the Quality checks in Local before deploying it to the pipeline. But it shows me with the below error and am not getting any code coverage result in the target directly.(Static code check works in local for PMD and findbugs).
"Skipping JaCoCo execution due to missing classes directory"
Please let me know how to rectify this
Thanks
Arun
Hi Arun,
could you try the following configuration of JaCoCo and Surefire?
Kind regards
Sander
Hi Arun,
Is it solved? Otherwise, please provide more information about what you are trying to do.
By default when running "mvn test" you should see a coverage report folder in the target directories of unit-test and integration-tests.
Best regards,
Daniel