diff --git a/.circleci/config.yml b/.circleci/config.yml index c18474e..14870e4 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -20,6 +20,7 @@ version: 2.1 - build-http - build-fpm - build-cli + - test-http-e2e: *test-http - test-fpm: &test-fpm requires: - build-http @@ -45,6 +46,7 @@ version: 2.1 - test-cli - test-fpm - test-http + - test-http-e2e - scan-vulnerability - push-fpm: *push-context - push-cli: *push-context @@ -56,6 +58,7 @@ version: 2.1 - build-fpm: *build-fpm - build-cli: *build-cli - test-http: *test-http + - test-http-e2e: *test-http - test-fpm: *test-fpm - test-cli: *test-cli - scan-vulnerability: *scan-vulnerability @@ -159,6 +162,17 @@ jobs: - run: make test-http - store_test_results: path: ./tmp/test-results + test-http-e2e: + machine: true + steps: + - checkout + - attach_workspace: + at: ./tmp + - docker_load: + image: http + - run: make test-http-e2e + - store_test_results: + path: ./tmp/test-results scan-vulnerability: machine: true steps: diff --git a/Makefile b/Makefile index 67e3dda..f09e0d6 100644 --- a/Makefile +++ b/Makefile @@ -74,6 +74,9 @@ test-http: ./tmp/build-http.tags ./tmp/build-fpm.tags xargs -I % ./test-http.sh $$(head -1 ./tmp/build-fpm.tags) % < ./tmp/build-http.tags xargs -I % ./test-http.sh $$(tail -1 ./tmp/build-fpm.tags) % < ./tmp/build-http.tags +test-http-e2e: ./tmp/build-http.tags + xargs -I % ./test-http-e2e.sh % < ./tmp/build-http.tags + scan-vulnerability: docker-compose -f test/security/docker-compose.yml -p clair-ci up -d RETRIES=0 && while ! wget -T 10 -q -O /dev/null http://localhost:6060/v1/namespaces ; do sleep 1 ; echo -n "." ; if [ $${RETRIES} -eq 10 ] ; then echo " Timeout, aborting." ; exit 1 ; fi ; RETRIES=$$(($${RETRIES}+1)) ; done diff --git a/src/http/nginx/conf/nginx.conf.template b/src/http/nginx/conf/nginx.conf.template index d581098..deb3c76 100644 --- a/src/http/nginx/conf/nginx.conf.template +++ b/src/http/nginx/conf/nginx.conf.template @@ -1,7 +1,7 @@ user nginx; worker_processes ${NGINX_WORKERS_PROCESSES}; -error_log /var/log/nginx/error.log warn; +error_log stderr warn; pid /var/run/nginx.pid; events { @@ -17,8 +17,8 @@ http { '${ESCAPE}status ${ESCAPE}body_bytes_sent "${ESCAPE}http_referer" ' '"${ESCAPE}http_user_agent" "${ESCAPE}http_x_forwarded_for"'; - access_log /var/log/nginx/access.log; - error_log /var/log/nginx/error.log notice; + access_log /dev/stdout; + error_log stderr notice; sendfile on; tcp_nopush on; diff --git a/test-http-e2e.sh b/test-http-e2e.sh new file mode 100755 index 0000000..f36b360 --- /dev/null +++ b/test-http-e2e.sh @@ -0,0 +1,23 @@ +#!/bin/bash +# +# A simple script to start a Docker container +# and run Testinfra in it +# Original script: https://gist.github.com/renatomefi/bbf44d4e8a2614b1390416c6189fbb8e +# Author: @renatomefi https://github.com/renatomefi +# + +set -eEuo pipefail + +# The first parameter is a Docker tag or image id +declare -r DOCKER_NGINX_TAG="$1" + +declare -r TEST_SUITE="nginx_e2e" + +# Finally, run the tests! +docker run --net="host" --rm -t \ + -v "$(pwd)/test/e2e:/tests" \ + -v "$(pwd)/tmp/test-results:/results" \ + -v /var/run/docker.sock:/var/run/docker.sock:ro \ + renatomefi/docker-testinfra:2 \ + -m "$TEST_SUITE" --junitxml="/results/http-e2e-$DOCKER_NGINX_TAG.xml" \ + --verbose --tag="$1" diff --git a/test/e2e/conftest.py b/test/e2e/conftest.py new file mode 100644 index 0000000..125ee50 --- /dev/null +++ b/test/e2e/conftest.py @@ -0,0 +1,21 @@ +import pytest + + +def pytest_addoption(parser): + parser.addoption( + "--tag", action="store", help="The docker tag" + ) + + +@pytest.fixture +def tag(request): + return request.config.getoption("--tag") + +@pytest.fixture +def container(host, tag): + container = host.check_output('docker run -p 80 -d {}'.format(tag)) + yield container + host.check_output('docker stop {}'.format(container)) + + # Remove afterwads thus the tests still have access to the logs + host.check_output('docker rm -f {}'.format(container)) diff --git a/test/e2e/test_nginx_entrypoint.py b/test/e2e/test_nginx_entrypoint.py new file mode 100644 index 0000000..e4cb87f --- /dev/null +++ b/test/e2e/test_nginx_entrypoint.py @@ -0,0 +1,19 @@ +import pytest + + +@pytest.mark.nginx_e2e +def test_nginx_sigterm_handling(host, container): + log_level = host.run('docker exec -t {} sh -c "sed -i \'s/error_log .*;/error_log stderr notice;/g\' /etc/nginx/nginx.conf"'.format(container)) + assert log_level.rc is 0 + assert u'stderr notice' in host.check_output('docker exec -t {} cat /etc/nginx/nginx.conf'.format(container)) + + nginx_reload = host.run('docker exec -t {} sh -c "nginx -s reload"'.format(container)) + assert nginx_reload.rc is 0 + + nginx_stop = host.run('docker stop -t 3 {}'.format(container)) + assert nginx_reload.rc is 0 + + logs = host.run('docker logs {}'.format(container)) + + assert u'signal 15 (SIGTERM) received, exiting' in logs.stderr + assert u'exit' in logs.stderr diff --git a/test/e2e/test_nginx_logs.py b/test/e2e/test_nginx_logs.py new file mode 100644 index 0000000..11fa7e5 --- /dev/null +++ b/test/e2e/test_nginx_logs.py @@ -0,0 +1,14 @@ +import pytest + + +@pytest.mark.nginx_e2e +def test_nginx_logs_to_stdout_and_stderr(host, container): + nginx_port = host.check_output("docker inspect " + container + " --format '{{ (index (index .NetworkSettings.Ports \"80/tcp\") 0).HostPort }}'") + + wget = host.run('wget -O /dev/null -S 127.0.0.1:{}/invalid'.format(nginx_port)) + assert wget.rc is not 0 + + logs = host.run('docker logs {}'.format(container)) + + assert 'GET /invalid' in logs.stdout + assert 'connect() to unix:/var/run/php-fpm.sock failed' in logs.stderr