donal
2018-07-03 1a8071fbaa5d256f7582b00bc437e90bc7b6e4d2
commit | author | age
ed818c 1 # The Non-Functionals Strike back
64c32e 2 > In this exercise we explore the non-functional side of testing.
6b9713 3
D 4 ![death-star-vent](../images/exercise5/death-star-vent.jpeg)
542e51 5
D 6 ## Exercise Intro
5e7a31 7 Non-functional testing provides valuable insights into code quality and application performance. Often overlooked but usually one of the most essential types of testing, non-functional testing types can include, but are not limited to
542e51 8 - Performance Testing
D 9 - Security testing
10 - Static Code analysis
11 - Vulnerability scanning
12
5e7a31 13 There are many tools out there for supporting these testing types but often they are left to the end of a delivery. Many traditional projects will leave Performance testing or security sign off to a few weeks before Go Live. This raises the question of what do we do if things do not pass these tests? Do we hold off the Go Live or accept the risk? In most cases we can learn earlier if things will be show stoppers and more importantly we can automate them.
542e51 14
853f0c 15 For example; imagine a developer called `Sam` has checked in some poorly performing function into an API that spikes its response time. Let's call this `Sam Code`. This `Sam Code` may not be caught by our Unit Tests but could have very big impact on application usability. Before building code on top this and it becoming more of an issue at the end of a project; we could code and capture metrics around API response time and track these over time and hopefully spot regressions earlier.
542e51 16
cc6b97 17 Another one of the age old questions is "How do we know we're testing enough?". Well the simple answer is you can never do enough testing! But how do we know we are testing the right things? Code coverage metrics can be run on our application while running the tests. They can identify what files are being tested and a line by line of how many times a test executes against a block of code. Reporting these metrics in our pipeline gives a greater handle on the quality of our testing.
542e51 18
cc6b97 19 Static code analysis can provide great insights into the quality of the code we've written. By analysing code without executing it bugs and common gotchas can be identified. Code complexity can be assessed using tooling such as SonarQube. Linting of code is a useful thing for non compiled languages such as JavaScript and can be executed in a build to provide some feedback.
542e51 20
D 21 Integrating these tools into the developer workflow can greatly improve quality and readability of code. Putting them in the pipeline ensures they are executed - removing the _"It works on my machine"_ view some may take.
22
23 #### Why run non functional tests?
24 - Early identify common code gotchas and pitfalls
25 - Tighten our feedback loop by executing non functional tests earlier in a project lifecycle
26 - Improve Code readability with agreeing a coding standard and then codifying it.
27 - Improve trust in the code quality and bring together security teams with dev teams earlier
28 - They can be automated; so why not run them as part of a build!
29
5a16fd 30 _____
D 31
32 ## Learning Outcomes
33 As a learner you will be able to
ea88bb 34 - Create additional Jenkins stages to scan for security vulnerabilities in the Apps
ed818c 35 - Assess test quality by producing coverage reports as part of a build
ea88bb 36 - Improve code readability with linting
D 37 - Do some light performance testing to monitor throughput of APIs
5a16fd 38
D 39 ## Tools and Frameworks
867471 40 > Below is a collection of the new frameworks and tools that will be used in this exercise
5a16fd 41
ea88bb 42 1. [eslint](https://eslint.org/) - ESLint is an open source JavaScript linting utility originally created by Nicholas C. Zakas in June 2013. Code linting is a type of static analysis that is frequently used to find problematic patterns or code that doesn’t adhere to certain style guidelines. There are code linters for most programming languages, and compilers sometimes incorporate linting into the compilation process.
cc6b97 43 1. [Zed Attack Proxy](https://www.owasp.org/index.php/OWASP_Zed_Attack_Proxy_Project) - The OWASP Zed Attack Proxy (ZAP) is one of the world’s most popular free security tools and is actively maintained by hundreds of international volunteers*. It can help you automatically find security vulnerabilities in your web applications while you are developing and testing your applications. Its also a great tool for experienced pentesters to use for manual security testing.
D 44 1. [Arachni Crawler](http://www.arachni-scanner.com/) - Arachni is a feature-full, modular, high-performance Ruby framework aimed towards helping penetration testers and administrators evaluate the security of modern web applications. It is free, with its source code public and available for review. It is versatile enough to cover a great deal of use cases, ranging from a simple command line scanner utility, to a global high performance grid of scanners, to a Ruby library allowing for scripted audits, to a multi-user multi-scan web collaboration platform. In addition, its simple REST API makes integration a cinch.
542e51 45 1. [stryker](http://stryker-mutator.io/) - Mutation testing! What is it? Bugs, or mutants, are automatically inserted into your production code. Your tests are run for each mutant. If your tests fail then the mutant is killed. If your tests passed, the mutant survived. The higher the percentage of mutants killed, the more effective your tests are. It's really that simple.
5a16fd 46
D 47 ## Big Picture
1a8071 48 > From the previous exercise; we introduced pipeline-as-code and new Jenkins Slave nodes. This exercise focuses on extending the pipeline with Non-functional testin and some automated security testing.
D 49
50 ![big-picture](../images/big-picture/big-picture-4.jpg)
5a16fd 51
D 52 _____
53
54 ## 10,000 Ft View
ed818c 55 > This lesson will use the Exercise 4's Zap Slave and Arachni scanner to improve the pipeline. Linting will be included in the build and code coverage too.
5a16fd 56
ea88bb 57 2. Add a parallel stage after the e2e tests on the front end to run OWASP Zap and Arachni against the deployed apps.
5a16fd 58
cc6b97 59 2. Add Code Coverage reporting to the build for gaining greater insight into test improvements.
ea88bb 60
542e51 61 2. Add `npm run lint` to the Frontend and report the result using the Checkstyle Plugin in Jenkins.
ea88bb 62
D 63 2. Create a new Jenkins job to run some light performance testing against the API layer using the perf tests tasks.
5a16fd 64
D 65 ## Step by Step Instructions
ea88bb 66 > This is a well structured guide with references to exact filenames and indications as to what should be done.
5a16fd 67
5e7a31 68 ### Part 1 - Add Security scanning to the pipeline
e33cae 69 > _In this exercise the first of our non-functional testing is explored in the form of some security scanning. We will add the scans to our Jenkinsfile and have them run as new stages_
5a16fd 70
e33cae 71 2. Open the `todolist-fe` application's `Jenkinsfile` in your favourite editor. The file is stored in the root of the project.
D 72
853f0c 73 2. The file is laid out with a collection of stages that correspond to each part of our build as seen below. We will create a new stage to execute in parallel.
c452bb 74 ![stages](../images/exercise5/stages.png)
e33cae 75
5e7a31 76 2. Create a new Parallel Stage called `security scanning` underneath the `stage("e2e test") { }` section as shown below. The contents of the `e2e test` have been removed for simplicity.
e33cae 77 ```groovy
D 78         stage("e2e test") {
79             // ... stuff in here ....
80         }
81         stage("security scanning") {
82             parallel {
83                 stage('OWASP Scan') {
84
85                 }
86                 stage('Arachni Scan') {
87
88                 }
89             }
90         }
5a16fd 91 ```
e33cae 92
ed818c 93 2. Let's start filling out the configuration for the OWASP Zap scan first. We will set the label to our slave created in previous exercise and a `when` condition of the master or develop branch.
e33cae 94 ```groovy
D 95 stage('OWASP Scan') {
96     agent {
97         node {
98             label "jenkins-slave-zap"
99         }
100     }
101     when {
102         expression { GIT_BRANCH ==~ /(.*master|.*develop)/ }
103     }
104 }
5a16fd 105 ```
e33cae 106
ac41ef 107 2.  Add a `step` with a `sh` command to run the tool by passing in the URL of the app we're going to test.
e33cae 108 ```groovy
D 109 stage('OWASP Scan') {
ac41ef 110         agent {
D 111             node {
112                 label "jenkins-slave-zap"
113             }
e33cae 114         }
ac41ef 115         when {
D 116             expression { GIT_BRANCH ==~ /(.*master|.*develop)/ }
117         }
118         steps {
119             sh '''
120                 /zap/zap-baseline.py -r index.html -t ${E2E_TEST_ROUTE} || return_code=$?
121                 echo "exit value was  - " $return_code
122             '''
123         }
e33cae 124 }
D 125 ```
126
853f0c 127 2.  Finally add the reporting for Jenkins in `post` hook of our Declarative Pipeline. This is to report the findings of the scan in Jenkins as an HTML report.
e33cae 128 ```groovy
D 129 stage('OWASP Scan') {
130     agent {
131         node {
132             label "jenkins-slave-zap"
133         }
134     }
135     when {
136         expression { GIT_BRANCH ==~ /(.*master|.*develop)/ }
137     }
138     steps {
139         sh '''
ac41ef 140             /zap/zap-baseline.py -r index.html -t http://${E2E_TEST_ROUTE} || return_code=$?
D 141             echo "exit value was  - " $return_code
e33cae 142         '''
D 143     }
144     post {
145         always {
146           // publish html
147           publishHTML target: [
148               allowMissing: false,
149               alwaysLinkToLastBuild: false,
150               keepAll: true,
151               reportDir: '/zap/wrk',
152               reportFiles: 'index.html',
153               reportName: 'Zap Branniscan'
154             ]
155         }
156     }
157 }
158 ```
159
ed818c 160 2. Let's add our Arachni Scan to the second part of the parallel block. The main difference between these sections is Jenkins will report an XML report too for failing the build accordingly. Below is the snippet for the Arachni scanning.
e33cae 161 ```groovy
D 162     stage('Arachni Scan') {
163         agent {
164             node {
165                 label "jenkins-slave-arachni"
166             }
167         }
168         when {
169             expression { GIT_BRANCH ==~ /(.*master|.*develop)/ }
170         }
171         steps {
172             sh '''
ccc1ac 173                 /arachni/bin/arachni http://${E2E_TEST_ROUTE} --report-save-path=arachni-report.afr
e33cae 174                 /arachni/bin/arachni_reporter arachni-report.afr --reporter=xunit:outfile=report.xml --reporter=html:outfile=web-report.zip
D 175                 unzip web-report.zip -d arachni-web-report
176             '''
177         }
178         post {
179             always {
180                 junit 'report.xml'
181                 publishHTML target: [
182                     allowMissing: false,
183                     alwaysLinkToLastBuild: false,
184                     keepAll: true,
185                     reportDir: 'arachni-web-report',
186                     reportFiles: 'index.html',
187                     reportName: 'Arachni Web Crawl'
188                     ]
189             }
190         }
191     }
192 ```
193
db90ef 194 2. With this config in place run a build on Jenkins. To do this; commit your code (from your terminal):
D 195 ```bash
58480f 196 git add .
D 197 ```
198 ```bash
199 git commit -m "ADD - security scanning tools to pipeline"
200 ```
201 ```bash
202 git push
db90ef 203 ```
D 204
ac41ef 205 2. Check out the Blue Ocean Jenkins view for how the parallel stage is viewed!
D 206 ![jenkins-parallel](../images/exercise5/jenkins-parallel.png)
207
db90ef 208 2. Once the Jobs have completed; navigate to the Jobs status and see the scores. You can find the graphs and test reports on overview of the Job. Explore the results!
c452bb 209 ![report-arachni](../images/exercise5/report-arachni.png)
D 210 ![jenkins-arachni](../images/exercise5/jenkins-arachni.png)
211
212 <p class="tip">
ac41ef 213 NOTE - your build may have failed because of the a security failure but the reports should still be generated, it is OK to proceed with the next exercise!
c452bb 214 </p>
5a16fd 215
a82977 216 2. TODO - add solution for failing Security scans!
D 217
ea88bb 218 ### Part 2 - Add Code Coverage & Linting to the pipeline
887bbe 219 > _Let's continue to enhance our pipeline with some non-functional testing. Static code analysis and testing coverage reports can provide a useful indicator on code quality and testing distribution_
5a16fd 220
887bbe 221 3. Coverage reports are already being generated as part of the tests. We can have Jenkins produce a HTML report showing in detail where our testing is lacking. Open the `todolist-fe` in your favourite editor.
D 222
5e7a31 223 3. Open the `Jenkinsfile` in the root of the project; move to the `stage("node-build"){ ... }` section. In the `post` section add a block for producing a `HTML` report as part of our builds. This is all that is needed for Jenkins to report the coverage stats.
887bbe 224 ```groovy
D 225     // Post can be used both on individual stages and for the entire build.
226     post {
227         always {
228             archive "**"
229             junit 'test-report.xml'
230             // publish html
231             publishHTML target: [
232                 allowMissing: false,
233                 alwaysLinkToLastBuild: false,
234                 keepAll: true,
235                 reportDir: 'reports/coverage',
236                 reportFiles: 'index.html',
237                 reportName: 'Code Coverage'
238             ]
239         }
240 ```
241
5e7a31 242 3. To get the linting working; we will add a new step to our `stage("node-build"){ }` section to lint the JavaScript code. Continuing in the `Jenkinsfile`, After the `npm install`; add a command to run the linting.
887bbe 243 ```groovy
D 244 echo '### Install deps ###'
245 sh 'npm install'
246 echo '### Running linting ###'
ac41ef 247 sh 'npm run lint'
887bbe 248 ```
D 249
250 3. Save the `Jenkinsfile` and commit it to trigger a build with some more enhancements.
251 ```bash
58480f 252 git add .
D 253 ```
254 ```bash
255 git commit -m "ADD - linting and coverage to the pipeline"
256 ```
257 ```bash
258 git push
887bbe 259 ```
D 260
ac41ef 261 3. When the build has completed; fix the linting errors if there are any and commit your changes. Look in Jenkins log for what the issue might be....
D 262 ![linting-issue](../images/exercise5/linting-issue.png)
263
5e7a31 264 3. To view the coverage graph; go to the job's build page and open the `Code Coverage` report from the nav bar on the side.
c26359 265 <p class="tip">
A 266 NOTE - Sometimes this won't display on the `yourjenkins.com/job/todolist-fe/job/branch/` sidebar, click on an individual build in the build history and it should appear on the side navbar.
267 </p>
ac41ef 268 ![report-location](../images/exercise5/report-location.png)
D 269
5e7a31 270 3. Open the report to drill down into detail of where testing coverage could be improved!
64c32e 271 ![report-coverage](../images/exercise5/report-coverage.png)
D 272 <p class="tip">
5e7a31 273 NOTE - a good practice for teams is to try and increase the code coverage metrics over the life of a project. Teams will often start low and use practices such as retrospective to increase the quality at specific times.
64c32e 274 </p>
D 275
887bbe 276 3. (Optional Step) - Install the Checkstyle plugin; and add `checkstyle pattern: 'eslint-report.xml'` below the `publishHTML` block to add reporting to Jenkins!
D 277
64c32e 278 ### Part 3 - Nightly light performance testing
5e7a31 279 > _In this exercise, we will execute the light performance tasks in our API to collect data about throughput time in hopes if the API ever has some `Sam` quality code checked in, we will spot it_
887bbe 280
5e7a31 281 An arbitrary value for the APIs to respond in has been chosen. It is set in the `todolist-api/tasks/perf-test.js` file. In this exercise we will get Jenkins to execute the tests and fail based on the score set there!
64c32e 282
a82977 283 4. Create a new Item on Jenkins, `nightly-perf-test` and make it a freestyle job.
D 284 ![new-job](../images/exercise5/new-job.png)
285
286 4. Set the `label` on `Restrict where this project can be run` to `jenkins-slave-npm` one used by the build jobs previously.
287 ![slave-label](../images/exercise5/slave-label.png)
64c32e 288
D 289 4. In the SCM section; set the project to use the `todolist-api` git project. Set the credentials accordingly.
a82977 290 ![git-settings](../images/exercise5/git-settings.png)
D 291
292 4. Set the build to execute each night; for example 0300 in the morning. Hit `Build periodically` on the Build Triggers section and set it to `H 3 * * *`.
293 ![build-schedule](../images/exercise5/build-schedule.png)
294
295 4. Set the `Color ANSI Console Output` on the Build Environment section.
64c32e 296
45eb81 297 4. Click `add build step` and select `execute shell` and add the following to it, replacing `<YOUR_NAME>` as expected. We will just test the `create` and `show` API for the moment. We are grabbing the response code of the perf-test to keep Jenkins running both shells steps and then exiting with whichever fails:
64c32e 298 ```bash
45eb81 299 export E2E_TEST_ROUTE=todolist-api-<YOUR_NAME>-dev.apps.lader.rht-labs.com
64c32e 300 npm install
D 301 set +e
302 npm run perf-test:create
303 rc1=$?
304 npm run perf-test:show
305 rc2=$?
306 set ­-e
307 exit $(($rc1 | $rc2))
308 ```
309
310 4. On the Post Build actions section we will plot the data from the perf tests in Jenkins. Add a `Post-build Action > Plot Build Data`.
311
5e7a31 312 4. On the new dialog, name the Plot group e.g. `benchmark-tests` and add `create­-api` as the Plot title. Set the `Number of Builds to Include` to a large number like `100`. Set the Data Series file to be `reports/server/perf/create-perf-score.csv` and mark the `Load data from CSV field` checkbox. Apply those changes
64c32e 313 ![jenkins-plot](../images/exercise5/jenkins-plot.png)
D 314
c26359 315 4. Hit `Add Plot` to add another. Set Plot group to `benchmark-tests` again but this time setting the Plot title to `show­-api`. Set the Data Series file to be `reports/server/perf/show-perf-score.csv` and mark the `Load data from CSV` radio button. Save those changes and run the job (Job could take a while to execute!).
64c32e 316
D 317 4. Run it a few times to start to generate the data points on the plot. The `bench-tests` plot is available on the job's homepage
318 ![result-plot](../images/exercise5/result-plot.png)
5a16fd 319
D 320 _____
321
322 ## Extension Tasks
323 > _Ideas for go-getters. Advanced topic for doers to get on with if they finish early. These will usually not have a solution and are provided for additional scope._
324
887bbe 325  - Enhance the `todolist-api` with the security scanning tools as you've done for the `todolist-api`
D 326  - Enhance the `todolist-api` with the coverage reporting as you've done for `todolist-api`
ea88bb 327  - Add Black Duck or other package scanning tooling for our NodeJS app
D 328  - Add Container Vulnerability scanning tooling to the pipeline
64c32e 329  - Add `Stryker` to create mutants and do additional non functional testing of the App
887bbe 330  - Add the Checkstyle plugin to Jenkins for reporting scores
5a16fd 331
D 332 ## Additional Reading
333 > List of links or other reading that might be of use / reference for the exercise
334
4f0295 335 ## Slide Links
RH 336
337 - [Intro](https://docs.google.com/presentation/d/1YQ0hUV3o7DW8O40SiI-BQZXCOSVeQGjo2iTxCL2GZfk/)
338 - [Wrap-up](https://docs.google.com/presentation/d/102hRHDlC9PUIsMs3m1fZy8QUaB5UKzBlhBPdehRWw38/)
5e7a31 339 - [All Material](https://drive.google.com/drive/folders/1seT0V3ABHNonvtFvORNt836NgSeYPuWW)