Daniel Scott
Daniel Scott

Reputation: 7961

Unit testing apache httpconfig

I have a big, complex config file for httpd, which contains many reverse proxy blocks, redirects, IP whitelists and aliases.

Is it possible to run unit tests against this config file?

i.e.

  1. Request to /account/login should be sent to the reverse proxy loginserver.example.com
  2. Request to /admin should be served from /var/www/html/content if the IP of the client is 192.168.1.10
  3. Request to /admin should give response code 403 if the IP of the client is 192.168.1.100
  4. Request to /old/page should give a 301 redirect

My current process is integration testing which requires that I run a full server, and have all of the reverse proxies running, and it's difficult to test ip whitelists. I'm looking to automate all of that without all of the dependencies.

An ideal solution would have to hook deeply into apache, so that it can see the routing decisions made - an http client wouldn't know that the request was served by a reverse proxy. Also, the request to /admin would only return a 200 if there was actually content in the location (which there won't be while testing) so the system would only test that apache would serve content from the location, not require that there's actually content there.

Upvotes: 2

Views: 815

Answers (1)

William Greenly
William Greenly

Reputation: 3989

How about this:

  1. install bats - https://github.com/bats-core/bats-core
  2. install docker - https://docs.docker.com
  3. install host-manager - https://github.com/macmade/host-manager

Example BATS test suite:

EDITED TO INCLUDE DUMMY LOGIN SERVER AND WEB ROOT

#!/usr/bin/env bats

setup () {
 #change port and volumes accordingly 
 docker run -d -h -v /directory/with/apache/conf/for/simulation:/opt/docker/etc/httpd/conf.d loginserver.example.com --name reverse webdevops/base:ubuntu-16.04
 docker run -d -p 80:80 -v /directory/for/200:/app -v /directory/with/apache/conf:/opt/docker/etc/httpd/conf.d  --name web --link="reverse" webdevops/base:ubuntu-16.04
 #if you need a host name
 host-manager -add website.host.name 127.0.0.1
 docker run -d
}

@test "Request to /account/login should be sent to the reverse proxy loginserver.example.com" {
 result="$(curl -I http://website.host.name/account/login | sed '4q;d')" 
 [ "$result" -eq "Location: http://loginserver.example.com" ]
}

@test "Request to /admin should be served if the IP of the client is 192.168.1.10" {
 result="$(curl -I --header 'REMOTE_ADDR:192.168.1.10' http://website.host.name/admin | sed '1q;d' | cut -d$' ' -f2)" 
 [ "$result" -eq 200 ]
}

@test "Request to /admin should give response code 403 if the IP of the client is 192.168.1.100" {
 result="$(curl -I --header 'REMOTE_ADDR:192.168.1.100' http://website.host.name/admin | sed '1q;d' | cut -d$' ' -f2)" 
 [ "$result" -eq 403 ]
}

@test "Request to /old/page should give a 301 redirect" {
 result="$(curl -I --header 'REMOTE_ADDR:192.168.1.100' http://website.host.name/old/page | sed '1q;d' | cut -d$' ' -f2)" 
 [ "$result" -eq 301 ]
}


teardown() {
 docker kill web
 docker rm web
 docker kill reverse
 docker rm reverse
 host-manager -remove website.host.name
}

Upvotes: 1

Related Questions