Intro: Time to move from manual to automated testing
One of my (many) job roles here at Hurricane is that of a build engineer. This means much of my time is spent building different kinds of maybe weird, good, and sometimes even useful things in GitLab’s Continuous Integration (CI) product.
For Hurricane Labs, the use of this tool is more about continuous testing rather than actual integration, but I’m all for industry standard terms. Anyway, lately it has been all about performance testing–determining if our software and sites perform well and, of course, are secure.
After doing all the testing manually and on schedules, I realized how much this process was becoming a time sink for me, and I wanted to figure out a better option.
Question: What was missing in our performance testing?
First up was performance testing. Is this site–our portal in this case–speedy enough in responding?
We have this kind of monitoring already, so we know how each component performs, how long it takes to respond, and so on. What we were missing, however, is mapping changes to that component to the actual code commits and deployments.
Initially, I thought about running a tool inside of Gitlab during our build process, which it turns out wasn’t a completely garbage idea. I found all sorts of articles–ranging in complexity–out there about how to do this.
I’m a simple man, so when I first found https://sitespeed.io, I thought, “awesome!” and I was right. It is pretty awesome. Sitespeed.io comes in a Docker container, which is great for CI work because you’re not having to write a bunch of code to actually build the thing you’re trying to run. Needless to say, I was jazzed about that and sat about the work, and that’s when it happened. I had just spent a bunch of time solving a problem that was already solved.
After I spent a little while getting this all going–creating a stanza or ten to get it just right–that’s, of course, when I found it. This automation is already built into Gitlab-CI; it’s in a template.
Surprise: I was working on something that already exists!
Here’s an example:
include: template: Verify/Browser-Performance.gitlab-ci.yml
performance: stage: performance variables: URL: https://website-you-built.example.com only: - master
Basically, the template does everything I did to set up sitespeed.io and get it ready for CI work.
- The template pulls down the Docker images, runs the build process, etc.
- You pass the URL variable, which is the site you want to test, and off you go.
I only use this template when we merge to our master branch in Git, as that is what makes production update.
Using this template, I can now see when a given commit caused a performance problem, which ultimately helps us track down problems much faster.
Security: Fun times with (web) vulnerability scanners
Now onto the fun(?)–yeah, let’s call it fun–security stuff.
I have a love-hate relationship with vulnerability scanners, and even more on the hate side with web vulnerability scanners. On one hand, they do have the ability to find some hideous vulnerabilities in your web app; on the other hand, they often don’t accomplish this and are very noisy. Regardless, they’re a necessary evil.
The vulnerability scanner we use and have had the most luck with is called Detectify. This one does a great job of finding the horrible vulnerabilities while also avoiding a lot of false positive noise–of course, your mileage may vary.
Setting this up in GitLab-CI to run was not difficult, so it really suited me. This is what you do:
- Get a Detectify account. None of this will work without one :-)
- Generate an API key, preferably also with a secret key
- Grab their sample code in the GitLab-friendly language of choice
- Create environment variables in your CI settings to use in your script (e.g. API key, scan profile, secret key)
- Change the sample code to read your environment variables
- Commit the changes and watch it go
Here’s what ours looks like:
detectify: image: python:latest stage: dast script: - curl https://gitlab-raw-path-to-script/runScan.py > runScan.py - python runScan.py tags: - docker only: - master
This setups the Detectify task, defines which Docker container to run in, defines which stage to include it in, grabs the GitLab-friendly modified script (Python in my case), and runs it. Again, we only run this when production changes.
Caveat to note here: these scans take a LONG time to run, so I don’t block the build. This process kicks off the scan and does nothing else. I then have an alert when Detectify finds something I need to pay attention to. Much like the performance setup above, this allows me to tie a new security problem into a specific commit, which really reduces troubleshooting time.
Hope this helps
Hopefully someone finds this to be useful–including me in a few months when I forget how I set all this up. Enjoy!