Skip to content

Improving CI for running tests #322

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

Merged
merged 8 commits into from
Feb 2, 2022
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
52 changes: 52 additions & 0 deletions .github/workflows/UnitTesting.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: Unit Testing
on:
push:
branches:
- master
pull_request:
branches:
- master

jobs:
test:
# "setup-python" action doesn't provide python 3.4 binaries for ubuntu-latest.
# Sticking to Ubuntu 18.04 as recommended here:
# https://github.com/actions/setup-python/issues/185#issuecomment-768232756
runs-on: ubuntu-18.04
env:
py27: 2.7
py34: 3.4
py35: 3.5
py36: 3.6
py37: 3.7
py38: 3.8
py39: 3.9
strategy:
fail-fast: false
matrix:
python-version: [py27, py34, py35, py36, py37, py38, py39]
testenv: [core, ext]
steps:
- name: Checkout repo
uses: actions/checkout@v2

- name: Setup Python
uses: actions/setup-python@v2
with:
python-version: ${{ env[matrix.python-version] }}

- name: Install tox
run: pip install -U tox-factor

- name: Cache tox environment
# Preserves .tox directory between runs for faster installs
uses: actions/cache@v2
with:
path: |
.tox
~/.cache/pip
key: tox-cache-${{ matrix.python-version }}-${{ matrix.testenv }}-${{ hashFiles('tox.ini') }}

- name: Run tox
run: |
tox -f ${{ matrix.python-version }}-${{ matrix.testenv }}
3 changes: 2 additions & 1 deletion aws_xray_sdk/core/sampling/local/sampler.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
from .sampling_rule import SamplingRule
from ...exceptions.exceptions import InvalidSamplingManifestError

local_sampling_rule = json.loads(pkgutil.get_data(__name__, 'sampling_rule.json'))
# `.decode('utf-8')` needed for Python 3.4, 3.5.
local_sampling_rule = json.loads(pkgutil.get_data(__name__, 'sampling_rule.json').decode('utf-8'))

SUPPORTED_RULE_VERSION = (1, 2)

Expand Down
4 changes: 2 additions & 2 deletions aws_xray_sdk/ext/boto_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@

from aws_xray_sdk.ext.util import inject_trace_header, to_snake_case


whitelist = json.loads(pkgutil.get_data(__name__, 'resources/aws_para_whitelist.json'))
# `.decode('utf-8')` needed for Python 3.4, 3.5
whitelist = json.loads(pkgutil.get_data(__name__, 'resources/aws_para_whitelist.json').decode('utf-8'))


def inject_header(wrapped, instance, args, kwargs):
Expand Down
14 changes: 7 additions & 7 deletions tests/ext/aiobotocore/test_aiobotocore.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import pytest

import aiobotocore
from aiobotocore.session import get_session
from botocore.stub import Stubber, ANY
from botocore.exceptions import ClientError

Expand Down Expand Up @@ -28,7 +28,7 @@ async def test_describe_table(loop, recorder):
req_id = '1234'
response = {'ResponseMetadata': {'RequestId': req_id, 'HTTPStatusCode': 403}}

session = aiobotocore.get_session()
session = get_session()
async with session.create_client('dynamodb', region_name='eu-west-2') as client:
with Stubber(client) as stubber:
stubber.add_response('describe_table', response, {'TableName': 'mytable'})
Expand All @@ -53,7 +53,7 @@ async def test_s3_parameter_capture(loop, recorder):
version_id = 'myversionid'
response = {'ResponseMetadata': {'RequestId': '1234', 'HTTPStatusCode': 200}}

session = aiobotocore.get_session()
session = get_session()
async with session.create_client('s3', region_name='eu-west-2') as client:
with Stubber(client) as stubber:
stubber.add_response('get_object', response,
Expand Down Expand Up @@ -87,7 +87,7 @@ async def test_list_parameter_counting(loop, recorder):
}
}

session = aiobotocore.get_session()
session = get_session()
async with session.create_client('sqs', region_name='eu-west-2') as client:
with Stubber(client) as stubber:
stubber.add_response('list_queues', response, {'QueueNamePrefix': queue_name_prefix})
Expand Down Expand Up @@ -117,7 +117,7 @@ async def test_map_parameter_grouping(loop, recorder):
}
}

session = aiobotocore.get_session()
session = get_session()
async with session.create_client('dynamodb', region_name='eu-west-2') as client:
with Stubber(client) as stubber:
stubber.add_response('batch_write_item', response, {'RequestItems': ANY})
Expand All @@ -137,7 +137,7 @@ async def test_context_missing_not_swallow_return(loop, recorder):

response = {'ResponseMetadata': {'RequestId': '1234', 'HTTPStatusCode': 403}}

session = aiobotocore.get_session()
session = get_session()
async with session.create_client('dynamodb', region_name='eu-west-2') as client:
with Stubber(client) as stubber:
stubber.add_response('describe_table', response, {'TableName': 'mytable'})
Expand All @@ -150,7 +150,7 @@ async def test_context_missing_not_suppress_exception(loop, recorder):
xray_recorder.configure(service='test', sampling=False,
context=AsyncContext(loop=loop), context_missing='LOG_ERROR')

session = aiobotocore.get_session()
session = get_session()
async with session.create_client('dynamodb', region_name='eu-west-2') as client:
with Stubber(client) as stubber:
stubber.add_client_error('describe_table', expected_params={'TableName': ANY})
Expand Down
3 changes: 2 additions & 1 deletion tests/test_local_sampling_benchmark.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
# Faster
def test_pkgutil_static_read(benchmark):
def get_sampling_rule():
return json.loads(pkgutil.get_data(__name__, 'mock_sampling_rule.json'))
# `.decode('utf-8')` needed for Python 3.4, 3.5
return json.loads(pkgutil.get_data(__name__, 'mock_sampling_rule.json').decode('utf-8'))
benchmark(get_sampling_rule)

# Slower
Expand Down
221 changes: 128 additions & 93 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,122 +1,157 @@
[tox]
skip_missing_interpreters = True
envlist =
py{27,34,35,36,37,38,39}-default
py{35,36,37,38,39}-aiohttp2
py{35,36,37,38,39}-django22
py{36,37,38,39}-django30
py{36,37,38,39}-django31
py{36,37,38,39}-django32
py{27,36,37,38,39}-sqlalchemy
py{34,35}-sqlalchemy
coverage-report
py{27,34,35,36,37,38,39}-core

skip_missing_interpreters = True
; Unavailable for python 2.7 & 3.4
py{35,36,37,38,39}-ext-aiobotocore

; Unavailable for python 2.7 & 3.4
py{35,36,37,38,39}-ext-aiohttp

py{27,34,35,36,37,38,39}-ext-botocore

py{27,34,35,36,37,38,39}-ext-bottle

; Django2 (2.2+) is only for python 3.5 +
py{35,36,37,38,39}-ext-django-2

; Django3 is only for python 3.6+
py{36,37,38,39}-ext-django-3

py{27,34,35,36,37,38,39}-ext-flask

py{27,34,35,36,37,38,39}-ext-flask_sqlalchemy

py{27,34,35,36,37,38,39}-ext-httplib

py{27,34,35,36,37,38,39}-ext-pg8000

py{27,34,35,36,37,38,39}-ext-psycopg2

py{27,34,35,36,37,38,39}-ext-pymysql

py{27,34,35,36,37,38,39}-ext-pynamodb

py{27,34,35,36,37,38,39}-ext-requests

py{27,34,35,36,37,38,39}-ext-sqlalchemy

py{27,34,35,36,37,38,39}-ext-sqlalchemy_core

py{27,34,35,36,37,38,39}-ext-sqlite3

[testenv]
passenv = TOXENV CI TRAVIS TRAVIS_* CODECOV_*
passenv = TOXENV CI CODECOV_*

deps =
; Testing packages
pytest > 3.0.0
pytest-benchmark
coverage==4.5.4
coverage == 4.5.4
codecov
requests
bottle >= 0.10
flask >= 0.10
sqlalchemy
Flask-SQLAlchemy

; Packages common to all test environments
future
django22: Django==2.2.*
django30: Django==3.0.*
django31: Django==3.1.*
django32: Django==3.2.*
django{22,30,31,32}: django-fake-model
pynamodb >= 3.3.1
psycopg2
pg8000
testing.postgresql
testing.mysqld
webtest
# Python2 only deps
py{27}: enum34 mock

# pymysql deps
py{27,34,35}: pymysql < 1.0.0
py{36,37,38,39}: pymysql >= 1.0.0

# Python3.4 only deps
wrapt

; Python 2.7 only deps
py{27}: enum34
py{27}: mock

; Python 3.4 only deps
py34: typing >= 3.7.4.3

# Python3.5+ only deps
py{35,36,37,38,39}: aiohttp >= 3.0.0
; Python 3.5+ only deps
; for some reason pytest-aiohttp is required for "core" tests
; TODO: find and replace by more direct dependency
py{35,36,37,38,39}: pytest-aiohttp
py{35,36,37,38,39}: aiobotocore >= 0.10.0

commands =
coverage erase
py{27,34}-default: coverage run --append --source aws_xray_sdk -m py.test tests --ignore tests/ext/aiohttp --ignore tests/ext/aiobotocore --ignore tests/ext/django --ignore tests/test_async_local_storage.py --ignore tests/test_async_recorder.py --ignore tests/ext/sqlalchemy_core
py{35,36,37,38,39}-default: coverage run --append --source aws_xray_sdk -m py.test tests --ignore tests/ext/django --ignore tests/ext/sqlalchemy_core
py{27,36,37,38,39}-default: coverage run --append --source aws_xray_sdk -m py.test tests/ext/sqlalchemy_core
py{34,35}-default: coverage run --append --source aws_xray_sdk -m py.test tests/ext/sqlalchemy_core/ --ignore tests/ext/sqlalchemy_core/test_sqlalchemy_core_2.py
django{22,30,31,32}: coverage run --append --source aws_xray_sdk -m py.test tests/ext/django
codecov
ext-aiobotocore: aiobotocore >= 0.10.0
ext-aiobotocore: pytest-aiohttp

ext-aiohttp: aiohttp >= 3.0.0
; Breaking change where the `test_client` fixture was renamed.
; Also, the stable version is only supported for Python 3.7+
ext-aiohttp: pytest-aiohttp < 1.0.0

ext-requests: requests

ext-bottle: bottle >= 0.10
ext-bottle: webtest

ext-flask: flask >= 0.10

ext-flask_sqlalchemy: flask >= 0.10
ext-flask_sqlalchemy: Flask-SQLAlchemy

ext-sqlalchemy: sqlalchemy

ext-sqlalchemy_core: sqlalchemy
ext-sqlalchemy_core: testing.postgresql
ext-sqlalchemy_core: psycopg2

ext-django-2: Django >=2.0,<3.0
ext-django-3: Django >=3.0,<4.0
ext-django: django-fake-model

ext-pynamodb: pynamodb >= 3.3.1

ext-psycopg2: psycopg2
ext-psycopg2: testing.postgresql

ext-pg8000: pg8000 <= 1.20.0
ext-pg8000: testing.postgresql

ext-pymysql: testing.mysqld
py{27,34,35}-ext-pymysql: pymysql < 1.0.0
py{36,37,38,39}-ext-pymysql: pymysql >= 1.0.0

setenv =
DJANGO_SETTINGS_MODULE = tests.ext.django.app.settings
AWS_SECRET_ACCESS_KEY = fake_key
AWS_ACCESS_KEY_ID=fake_id

[testenv:py35-aiohttp2]
deps =
pytest > 3.0.0
aiohttp >= 2.3.0,<3.0.0
pytest-aiohttp
botocore
coverage==4.5.4

commands =
py{35}: coverage run --source aws_xray_sdk -m py.test tests/ext/aiohttp --ignore tests/ext/aiohttp/test_client.py
coverage erase

[testenv:py36-aiohttp2]
deps =
pytest > 3.0.0
aiohttp >= 2.3.0,<3.0.0
pytest-aiohttp
botocore
coverage==4.5.4
; Async methods are only available for python 3.5+
py{27,34}-core: coverage run --append --source aws_xray_sdk -m pytest --ignore tests/ext --ignore tests/test_async_local_storage.py --ignore tests/test_async_recorder.py
py{35,36,37,38,39}-core: coverage run --append --source aws_xray_sdk -m pytest --ignore tests/ext

commands =
py{36}: coverage run --source aws_xray_sdk -m py.test tests/ext/aiohttp --ignore tests/ext/aiohttp/test_client.py
ext-aiobotocore: coverage run --append --source aws_xray_sdk -m pytest tests/ext/aiobotocore

[testenv:py37-aiohttp2]
deps =
pytest > 3.0.0
aiohttp >= 2.3.0,<3.0.0
pytest-aiohttp
botocore
coverage==4.5.4
ext-aiohttp: coverage run --append --source aws_xray_sdk -m pytest tests/ext/aiohttp

commands =
py{37}: coverage run --source aws_xray_sdk -m py.test tests/ext/aiohttp --ignore tests/ext/aiohttp/test_client.py
ext-botocore: coverage run --append --source aws_xray_sdk -m pytest tests/ext/botocore

[testenv:py38-aiohttp2]
deps =
pytest > 5.2.0
aiohttp >= 3.6
pytest-aiohttp
botocore
coverage==4.5.4
ext-bottle: coverage run --append --source aws_xray_sdk -m pytest tests/ext/bottle

commands =
py{38}: coverage run --source aws_xray_sdk -m py.test tests/ext/aiohttp --ignore tests/ext/aiohttp/test_client.py
ext-django: coverage run --append --source aws_xray_sdk -m pytest tests/ext/django

[testenv:coverage-report]
deps = coverage
skip_install = true
commands =
# might need to add coverage combine at some point
py{38}: coverage report
py{38}: coverage html
ext-flask: coverage run --append --source aws_xray_sdk -m pytest tests/ext/flask

ext-flask_sqlalchemy: coverage run --append --source aws_xray_sdk -m pytest tests/ext/flask_sqlalchemy

ext-httplib: coverage run --append --source aws_xray_sdk -m pytest tests/ext/httplib

ext-pg8000: coverage run --append --source aws_xray_sdk -m pytest tests/ext/pg8000

ext-psycopg2: coverage run --append --source aws_xray_sdk -m pytest tests/ext/psycopg2

ext-pymysql: coverage run --append --source aws_xray_sdk -m pytest tests/ext/pymysql

ext-pynamodb: coverage run --append --source aws_xray_sdk -m pytest tests/ext/pynamodb

ext-requests: coverage run --append --source aws_xray_sdk -m pytest tests/ext/requests

ext-sqlalchemy: coverage run --append --source aws_xray_sdk -m pytest tests/ext/sqlalchemy

; sqlalchemy_core - 2.0 style execution is not supported for python 3.4 & 3.5
py{27,36,37,38,39}-ext-sqlalchemy_core: coverage run --append --source aws_xray_sdk -m pytest tests/ext/sqlalchemy_core
py{34,35}-ext-sqlalchemy_core: coverage run --append --source aws_xray_sdk -m pytest tests/ext/sqlalchemy_core --ignore tests/ext/sqlalchemy_core/test_sqlalchemy_core_2.py

ext-sqlite3: coverage run --append --source aws_xray_sdk -m pytest tests/ext/sqlite3

[flake8]
max-line-length=120
exclude=tests
; TODO: add additional logic to combine coverage from "core" and "ext" test runs
; codecov