Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add URL tests that follow redirects and allow these to be run from the pipeline #3822

Merged
merged 3 commits into from
Feb 24, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ set -xe
: ${SELENIUM_HOST:="localhost"}
: ${SELENIUM_PORT:="4444"}
: ${BROWSER_NAME:="firefox"}
: ${TESTS_PATH:="tests/functional"}
: ${TESTS_PATH:="tests"}
: ${RESULTS_PATH:="${TESTS_PATH}/results"}

# Common arguments
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ FROM debian:jessie

WORKDIR /app
# Run the tests
CMD ["/app/bin/run-functional-tests.sh"]
CMD ["/app/bin/run-integration-tests.sh"]


RUN apt-get update && \
Expand All @@ -11,7 +11,7 @@ RUN apt-get update && \
# Defaults
ENV PYTEST_PROCESSES 5
ENV PRIVACY "public restricted"
ENV TESTS_PATH /app/tests/functional
ENV TESTS_PATH /app/tests
ENV RESULTS_PATH /app/results
ENV PYTHONDONTWRITEBYTECODE=1

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,21 @@
#!/bin/bash -xe
GIT_COMMIT=${GIT_COMMIT:-$(git rev-parse HEAD)}
cp docker/dockerfiles/bedrock_functional_tests Dockerfile
docker build -t bedrock_functional_tests:${GIT_COMMIT} --pull=true .
cp docker/dockerfiles/bedrock_integration_tests Dockerfile
docker build -t bedrock_integration_tests:${GIT_COMMIT} --pull=true .

if [ -z "${BASE_URL}" ]; then
# start bedrock
docker run -d \
--name bedrock-code-${BUILD_NUMBER} \
-e ALLOWED_HOSTS="*" \
-e SECRET_KEY=foo \
-e DEBUG=False \
-e DATABASE_URL=sqlite:////tmp/temp.db \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a note: if you don't need a DB that will stick around you can just set DATABASE_URL=sqlite:// which will cause it to use a purely in-memory database and never create a file.

mozorg/bedrock_code:${GIT_COMMIT}

DOCKER_LINKS=(--link bedrock-code-${BUILD_NUMBER}:bedrock)
BASE_URL="http://bedrock:8000"
fi

if [ "${DRIVER}" = "Remote" ]; then
# Start Selenium hub and NUMBER_OF_NODES (default 5) firefox nodes.
Expand All @@ -13,56 +27,41 @@ if [ "${DRIVER}" = "Remote" ]; then
docker pull selenium/hub:${SELENIUM_VERSION}
docker pull selenium/node-firefox:${SELENIUM_VERSION}

# start bedrock
docker run -d \
--name bedrock-code-${BUILD_NUMBER} \
-e ALLOWED_HOSTS="*" \
-e SECRET_KEY=foo \
-e DEBUG=False \
-e DATABASE_URL=sqlite:////tmp/temp.db \
mozorg/bedrock_code:$GIT_COMMIT

# start selenium grid hub
docker run -d \
--name bedrock-selenium-hub-${BUILD_NUMBER} \
selenium/hub:${SELENIUM_VERSION}
DOCKER_LINKS=(${DOCKER_LINKS[@]} --link bedrock-selenium-hub-${BUILD_NUMBER}:hub)
SELENIUM_HOST="hub"

# start selenium grid nodes
for NODE_NUMBER in `seq ${NUMBER_OF_NODES:-5}`; do
docker run -d \
--name bedrock-selenium-node-${NODE_NUMBER}-${BUILD_NUMBER} \
--link bedrock-selenium-hub-${BUILD_NUMBER}:hub \
--link bedrock-code-${BUILD_NUMBER}:bedrock \
${DOCKER_LINKS[@]} \
selenium/node-firefox:${SELENIUM_VERSION}
while ! ${SELENIUM_READY}; do
IP=`docker inspect --format '{{ .NetworkSettings.IPAddress }}' bedrock-selenium-node-${NODE_NUMBER}-${BUILD_NUMBER}`
CMD="docker run --link bedrock-selenium-hub-${BUILD_NUMBER}:hub tutum/curl curl http://hub:4444/grid/api/proxy/?id=http://${IP}:5555 | grep 'proxy found'"
if eval ${CMD}; then SELENIUM_READY=true; fi
done
done

docker run -v `pwd`/results:/app/results \
--link bedrock-selenium-hub-${BUILD_NUMBER}:hub \
--link bedrock-code-${BUILD_NUMBER}:bedrock \
-e BASE_URL=http://bedrock:8000 \
-e DRIVER=${DRIVER} \
-e SELENIUM_HOST=hub \
-e MARK_EXPRESSION=${MARK_EXPRESSION} \
bedrock_functional_tests:$GIT_COMMIT
else
# Runs functional tests that either don't require Selenium, use a local
# Selenium driver, or use a remote Selenium server (such as Sauce Labs).
docker run -v `pwd`/results:/app/results \
-e BASE_URL=${BASE_URL} \
-e DRIVER=${DRIVER} \
-e SAUCELABS_USERNAME=${SAUCELABS_USERNAME} \
-e SAUCELABS_API_KEY=${SAUCELABS_API_KEY} \
-e BROWSER_NAME="${BROWSER_NAME}" \
-e BROWSER_VERSION=${BROWSER_VERSION} \
-e PLATFORM="${PLATFORM}" \
-e SELENIUM_VERSION=${SELENIUM_VERSION} \
-e BUILD_TAG=${BUILD_TAG} \
-e SCREEN_RESOLUTION=${SCREEN_RESOLUTION} \
-e MARK_EXPRESSION="${MARK_EXPRESSION}" \
bedrock_functional_tests:${GIT_COMMIT}
fi

docker run -v `pwd`/results:/app/results \
${DOCKER_LINKS[@]} \
-e BASE_URL=${BASE_URL} \
-e DRIVER=${DRIVER} \
-e SAUCELABS_USERNAME=${SAUCELABS_USERNAME} \
-e SAUCELABS_API_KEY=${SAUCELABS_API_KEY} \
-e BROWSER_NAME="${BROWSER_NAME}" \
-e BROWSER_VERSION=${BROWSER_VERSION} \
-e PLATFORM="${PLATFORM}" \
-e SELENIUM_HOST=${SELENIUM_HOST} \
-e SELENIUM_PORT=${SELENIUM_PORT} \
-e SELENIUM_VERSION=${SELENIUM_VERSION} \
-e BUILD_TAG=${BUILD_TAG} \
-e SCREEN_RESOLUTION=${SCREEN_RESOLUTION} \
-e MARK_EXPRESSION="${MARK_EXPRESSION}" \
-e TESTS_PATH="${TESTS_PATH}" \
bedrock_integration_tests:${GIT_COMMIT}
23 changes: 17 additions & 6 deletions tests/redirects/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ def get_abs_url(url, base_url):


def url_test(url, location=None, status_code=requests.codes.moved_permanently,
req_headers=None, req_kwargs=None, resp_headers=None, query=None):
req_headers=None, req_kwargs=None, resp_headers=None, query=None,
follow_redirects=False, final_status_code=requests.codes.ok):
"""
Function for producing a config dict for the redirect test.

Expand Down Expand Up @@ -46,6 +47,8 @@ def url_test(url, location=None, status_code=requests.codes.moved_permanently,
:param req_kwargs: Extra arguments to pass to requests.get()
:param resp_headers: Dict of headers expected in the response.
:param query: Dict of expected query params in `location` URL.
:param follow_redirects: Boolean indicating whether redirects should be followed.
:param final_status_code: Expected status code after following any redirects.
:return: dict or list of dicts
"""
test_data = {
Expand All @@ -56,6 +59,8 @@ def url_test(url, location=None, status_code=requests.codes.moved_permanently,
'req_kwargs': req_kwargs,
'resp_headers': resp_headers,
'query': query,
'follow_redirects': follow_redirects,
'final_status_code': final_status_code,
}
expanded_urls = list(braceexpand(url))
num_urls = len(expanded_urls)
Expand Down Expand Up @@ -90,7 +95,8 @@ def url_test(url, location=None, status_code=requests.codes.moved_permanently,

def assert_valid_url(url, location=None, status_code=requests.codes.moved_permanently,
req_headers=None, req_kwargs=None, resp_headers=None,
query=None, base_url=None):
query=None, base_url=None, follow_redirects=False,
final_status_code=requests.codes.ok):
"""
Define a test of a URL's response.
:param url: The URL in question (absolute or relative).
Expand All @@ -101,8 +107,10 @@ def assert_valid_url(url, location=None, status_code=requests.codes.moved_perman
:param resp_headers: Dict of headers expected in the response.
:param base_url: Base URL for the site to test.
:param query: Dict of expected query params in `location` URL.
:param follow_redirects: Boolean indicating whether redirects should be followed.
:param final_status_code: Expected status code after following any redirects.
"""
kwargs = {'allow_redirects': False}
kwargs = {'allow_redirects': follow_redirects}
if req_headers:
kwargs['headers'] = req_headers
if req_kwargs:
Expand All @@ -112,8 +120,11 @@ def assert_valid_url(url, location=None, status_code=requests.codes.moved_perman
resp = requests.get(abs_url, **kwargs)
# so that the value will appear in locals in test output
resp_location = resp.headers.get('location')
assert resp.status_code == status_code
if location:
if follow_redirects:
assert resp.status_code == final_status_code
else:
assert resp.status_code == status_code
if location and not follow_redirects:
if query:
# all query values must be lists
for k, v in query.items():
Expand All @@ -133,7 +144,7 @@ def assert_valid_url(url, location=None, status_code=requests.codes.moved_perman
except AttributeError:
assert abs_location == resp_location

if resp_headers:
if resp_headers and not follow_redirects:
for name, value in resp_headers.items():
print name, value
assert name in resp.headers
Expand Down
5 changes: 4 additions & 1 deletion tests/redirects/map_globalconf.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@
# bug 860865, 1101220
url_test('/firefox/all-{beta,rc}{/,.html}', '/firefox/beta/all/'),
url_test('/firefox/all-aurora{/,.html}', '/firefox/developer/all/'),
url_test('/firefox/aurora/{all,notes,system-requirements}/'
url_test('/firefox/aurora/{all,notes,system-requirements}/',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch

'/firefox/developer/{all,notes,system-requirements}/'),
url_test('/firefox/organizations/all.html', '/firefox/organizations/all/'),

Expand Down Expand Up @@ -980,6 +980,9 @@
url_test('/en-US/firefox/notes/',
re.compile(r'/en-US/firefox/[\d\.]+/releasenotes/'),
status_code=requests.codes.found),
url_test('/firefox/brand/', '/styleguide/'),
url_test('/firefox/channel/android/', '/en-US/firefox/channel/android/'),
url_test('/en-US/firefox/channel/android/', '/firefox/channel/'),

# Bug 1243060
url_test('/firefox/tiles/',
Expand Down
45 changes: 45 additions & 0 deletions tests/redirects/test_redirects.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
"""Test redirects from the global.conf file."""
from __future__ import absolute_import
from operator import itemgetter

import pytest

from .base import assert_valid_url
from .map_htaccess import URLS as HTA_URLS
from .map_globalconf import URLS as GLOBAL_URLS
from .map_external import URLS as EXTERNAL_URLS
from .map_locales import URLS as LOCALE_URLS


@pytest.mark.smoke
@pytest.mark.headless
@pytest.mark.nondestructive
@pytest.mark.parametrize('url', GLOBAL_URLS, ids=itemgetter('url'))
def test_global_conf_url(url, base_url):
url['base_url'] = base_url
assert_valid_url(**url)


@pytest.mark.smoke
@pytest.mark.headless
@pytest.mark.nondestructive
@pytest.mark.parametrize('url', HTA_URLS, ids=itemgetter('url'))
def test_htaccess_url(url, base_url):
url['base_url'] = base_url
assert_valid_url(**url)


@pytest.mark.smoke
@pytest.mark.headless
@pytest.mark.nondestructive
@pytest.mark.parametrize('url', LOCALE_URLS)
def test_locale_url(url, base_url):
url['base_url'] = base_url
assert_valid_url(**url)


@pytest.mark.headless
@pytest.mark.nondestructive
@pytest.mark.parametrize('url', EXTERNAL_URLS, ids=itemgetter('url'))
def test_external_url(url):
assert_valid_url(**url)
77 changes: 46 additions & 31 deletions tests/redirects/test_urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,43 +7,15 @@

from .base import assert_valid_url
from .map_410 import URLS_410
from .map_htaccess import URLS as HTA_URLS
from .map_globalconf import URLS as GLOBAL_URLS
from .map_external import URLS as EXTERNAL_URLS
from .map_locales import URLS as LOCALE_URLS


@pytest.mark.smoke
@pytest.mark.headless
@pytest.mark.nondestructive
@pytest.mark.parametrize('url', GLOBAL_URLS, ids=itemgetter('url'))
def test_global_conf_url(url, base_url):
url['base_url'] = base_url
assert_valid_url(**url)


@pytest.mark.smoke
@pytest.mark.headless
@pytest.mark.nondestructive
@pytest.mark.parametrize('url', HTA_URLS, ids=itemgetter('url'))
def test_htaccess_url(url, base_url):
url['base_url'] = base_url
assert_valid_url(**url)


@pytest.mark.smoke
@pytest.mark.headless
@pytest.mark.nondestructive
@pytest.mark.parametrize('url', LOCALE_URLS)
def test_locale_url(url, base_url):
url['base_url'] = base_url
assert_valid_url(**url)


@pytest.mark.headless
@pytest.mark.nondestructive
@pytest.mark.parametrize('url', EXTERNAL_URLS, ids=itemgetter('url'))
def test_external_url(url):
del url['location']
url['follow_redirects'] = True
assert_valid_url(**url)


Expand All @@ -52,7 +24,7 @@ def test_external_url(url):
@pytest.mark.nondestructive
@pytest.mark.parametrize('url', URLS_410)
def test_410_url(url, base_url):
assert_valid_url(url, status_code=requests.codes.gone, base_url=base_url)
assert_valid_url(url, base_url=base_url, status_code=requests.codes.gone)


@pytest.mark.smoke
Expand All @@ -70,3 +42,46 @@ def test_404_url(base_url):
@pytest.mark.nondestructive
def test_x_robots_tag(base_url):
assert_valid_url(base_url, resp_headers={'x-robots-tag': 'noodp'})


@pytest.mark.headless
@pytest.mark.nondestructive
@pytest.mark.parametrize('url', [
'/firefox/',
'/firefox/all/',
'/firefox/android/',
'/firefox/android/faq/',
'/firefox/aurora/all/',
'/firefox/beta/all/',
'/firefox/brand/',
'/firefox/channel/',
'/firefox/channel/android/',
'/firefox/desktop/',
'/firefox/developer/',
'/firefox/geolocation/',
'/firefox/installer-help/',
'/firefox/interest-dashboard/',
'/firefox/latest/releasenotes/',
'/firefox/mobile/',
'/firefox/new/',
'/firefox/nightly/firstrun/',
'/firefox/organizations/',
'/firefox/os/',
'/firefox/os/notes/1.1/',
'/firefox/partners/',
'/firefox/releases/',
'/firefox/speed/',
'/firefox/sync/',
'/firefox/tiles/',
'/firefox/unsupported-systems/',
'/firefox/unsupported/EOL/',
# Legacy URLs (Bug 1110927)
'/firefox/panorama/',
'/firefox/start/central.html',
'/firefox/sync/firstrun.html',
# Thunberbird URLs
'/thunderbird/all/',
'/thunderbird/releases/'
])
def test_url(url, base_url):
assert_valid_url(url, base_url=base_url, follow_redirects=True)