I'm currently working a lot on infrastructure-related tasks. As a software developer I really appreciate TDD with all the certainty I get for code changes. Many changes of the infrastructure stack can be tested manually using curl. For instance to check if a request to a certain URL succeeds, this is all you need:
~ curl -I "http://10.0.0.1/" HTTP/1.1 200 OK Server: nginx Date: Thu, 14 Jun 2012 10:19:33 GMT ...
You can easily add cookies, do virtual host routing and pretend SSL termination:
~ curl -I -H"Host: awwsnap.io" -H"X-Forwarded-Proto: https" \ -b"cookie=value" "http://10.0.0.1/"
Ok, that's old news. But, how about automating those tests and spec'ing your stack?
To accomplish this, I use roundup made by Blake Mizerany. It's a great testing framework that perfectly fits into UNIX environments. And its tests are written in plain bash. That's exactly what I need. Check it out, if you don't know it yet!
With roundup we can quickly put the example from before into a spec:
#!/usr/local/bin/roundup ### matchers function returns { cat | head -n1 | grep $1 } ### spec it_should_redirect_requests_to_root() { curl -I -H"Host: awwsnap.io" -H"X-Forwarded-Proto: https" \ -b"cookie=value" "http://10.0.0.1/" | returns 200 }
Roundup detects the success or failure of a test by its error status. In the previous example, the matcher function returns
uses grep to find 302
in the first line of the response header. If grep finds that http status code it returns 0 otherwise 1.
This enables me to describe the wanted behaviour of a system up-front and "fix it" in a more focused way.
One additional benefit during a rollout of a new configuration is that you can now run the test repeatedly against a host to validate the changes.
To stimulate your imagination a bit more, here are some additional examples:
#!/usr/local/bin/roundup ### matchers function returns { cat | head -n1 | grep $1 } # check for rails-specific header function is_rails { cat | grep "^X-Runtime: " } function redirects_to { res=$(cat) echo $res | returns 302 && echo $res | grep "Location: $1" } ### helpers # using tee makes debugging easier function get { curl -I -H"Host: awwsnap.io" -H "X-Forwarded-Proto: https" \ -b"cookie=value" | tee /dev/stderr } ### spec it_should_serve_root() { get "http://10.0.0.1/" | returns 200 } it_should_pass_to_rails_backend_for_admin() { get "http://10.0.0.1/admin" | is_rails } it_should_redirect_to_cdn_for_assets() { get "http://10.0.0.1/assets" | redirects_to "cdn.awwsnap.io" }
Nice one, didn't know about Roundup. The specs look clean and the code intuitive enough to get them right away, even though it's Bash :)
ReplyDelete