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

Use a script to populate parts of tox.ini #3920

Closed
wants to merge 79 commits into from
Closed
Changes from 1 commit
Commits
Show all changes
79 commits
Select commit Hold shift + click to select a range
f54a018
Use a script to populate parts of tox.ini
sentrivana Jan 13, 2025
9c829da
ignore everything for starters
sentrivana Jan 13, 2025
c365900
fix
sentrivana Jan 13, 2025
cb7a0aa
.
sentrivana Jan 13, 2025
51de6a2
add more min versions
sentrivana Jan 13, 2025
33e66b2
.
sentrivana Jan 13, 2025
153bae2
try ariadne
sentrivana Jan 13, 2025
d4d44b1
try aiohttp
sentrivana Jan 13, 2025
fbe73b8
Merge branch 'master' into ivana/populate-tox-step-by-step
sentrivana Jan 13, 2025
6c2edd0
try anthropic
sentrivana Jan 13, 2025
7470a9b
.
sentrivana Jan 13, 2025
16a4ba2
?
sentrivana Jan 13, 2025
ec3d9cb
try arq
sentrivana Jan 13, 2025
04a2ab6
asyncpg
sentrivana Jan 13, 2025
b44f195
rename
sentrivana Jan 14, 2025
a1e7da7
Merge branch 'master' into ivana/populate-tox-step-by-step
sentrivana Jan 14, 2025
8345859
lets see
sentrivana Jan 14, 2025
971d4ab
replicate py versions
sentrivana Jan 14, 2025
fe62214
.
sentrivana Jan 14, 2025
15fa2d2
beam
sentrivana Jan 14, 2025
e0e6b20
bottle
sentrivana Jan 14, 2025
e14f2c4
Merge branch 'master' into ivana/populate-tox-step-by-step
sentrivana Jan 14, 2025
b8d29b3
try boto
sentrivana Jan 14, 2025
c6f1c65
celery
sentrivana Jan 14, 2025
97a7ae7
chalice
sentrivana Jan 16, 2025
875fa6e
clickhouse
sentrivana Jan 16, 2025
7ed6109
dramatiq
sentrivana Jan 16, 2025
5c05100
falcon
sentrivana Jan 16, 2025
267dc07
falcon fix
sentrivana Jan 16, 2025
5cff258
fastapi
sentrivana Jan 16, 2025
e392825
better py version picking
sentrivana Jan 16, 2025
30effcf
Merge branch 'master' into ivana/populate-tox-step-by-step
sentrivana Jan 16, 2025
912c981
celery, flask
sentrivana Jan 16, 2025
7d45cc6
metata lol
sentrivana Jan 16, 2025
6d0ab22
lets try...
sentrivana Jan 16, 2025
f60018e
dramatiq v2
sentrivana Jan 16, 2025
c4dab11
add lower version for dramatiq
sentrivana Jan 16, 2025
1068830
huey
sentrivana Jan 16, 2025
67502e7
huggingface
sentrivana Jan 16, 2025
91ea137
whitespace
sentrivana Jan 16, 2025
fcfb731
gql, langchains
sentrivana Jan 16, 2025
37d0e25
launchdarkly, pyramid
sentrivana Jan 16, 2025
a96e1a4
pymongo
sentrivana Jan 16, 2025
ef0af89
quart, ray
sentrivana Jan 16, 2025
b37519b
try
sentrivana Jan 16, 2025
659d859
starlite, strawberry, redis_py_cluster
sentrivana Jan 16, 2025
f23c8be
unleash, typer
sentrivana Jan 16, 2025
e330704
.
sentrivana Jan 16, 2025
26638a5
fixes, hopefully
sentrivana Jan 16, 2025
bb4c84e
try
sentrivana Jan 16, 2025
beb2271
requests
sentrivana Jan 16, 2025
dca044e
tornado, sqlalchemy
sentrivana Jan 16, 2025
9f2ce18
fix
sentrivana Jan 17, 2025
9c45ece
loguru
sentrivana Jan 17, 2025
dd2a531
sanic, starlette
sentrivana Jan 17, 2025
6927592
try to fix starlette
sentrivana Jan 17, 2025
1ae16bf
graphene, spark
sentrivana Jan 17, 2025
6176ea5
grpc, openfeature, fix graphene
sentrivana Jan 17, 2025
b17e51d
.
sentrivana Jan 17, 2025
6ef2e19
aiohttp, trytond
sentrivana Jan 17, 2025
82b8a60
anthropic
sentrivana Jan 17, 2025
0adedc7
revert anthropic
sentrivana Jan 17, 2025
b0a0772
docs
sentrivana Jan 17, 2025
d7721ad
fail-on-changes
sentrivana Jan 17, 2025
057a1dc
readme
sentrivana Jan 17, 2025
5b9da4b
run split tox too
sentrivana Jan 17, 2025
10f96a7
trying something with httpx
sentrivana Jan 17, 2025
26fcd99
.
sentrivana Jan 17, 2025
ce869ec
.
sentrivana Jan 17, 2025
d9eead4
...
sentrivana Jan 17, 2025
e54e888
....
sentrivana Jan 17, 2025
8b11b74
.....?
sentrivana Jan 17, 2025
feca999
......
sentrivana Jan 17, 2025
975862c
fix path
sentrivana Jan 20, 2025
5524412
path fixes
sentrivana Jan 20, 2025
d6b4257
Merge branch 'master' into ivana/populate-tox-step-by-step
sentrivana Jan 20, 2025
386d4ef
Merge branch 'master' into ivana/populate-tox-step-by-step
sentrivana Jan 20, 2025
0bf2a2b
merge master
sentrivana Jan 20, 2025
64ced2f
readme
sentrivana Jan 20, 2025
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
Prev Previous commit
Next Next commit
docs
sentrivana committed Jan 17, 2025
commit b0a0772bfc42c2c744faaba65a774e3db39d5cef
16 changes: 16 additions & 0 deletions scripts/generate-test-files.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/bin/bash

# This script generates tox.ini and CI YAML files in one go.

set -xe

SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )

python -m venv .venv
source .venv/bin/activate

pip install -r "$SCRIPT_DIR/populate_tox/requirements.txt"
pip install -r "$SCRIPT_DIR/split_tox_gh_actions/requirements.txt"

python scripts/populate_tox/populate_tox.py
python scripts/split_tox_gh_actions/split_tox_gh_actions.py
111 changes: 111 additions & 0 deletions scripts/populate_tox/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# Populate Tox

We integrate with a number of frameworks and libraries and have a test suite for
each. The tests run against different versions of the framework/library to make
sure we support everything we claim to.

This `populate_tox.py` script is responsible for picking reasonable versions to
test automatically and generating parts of `tox.ini` to capture this.

## How it works

There is a template in this directory called `tox.jinja` which contains a
combination of hardcoded and generated entries.

The `populate_tox.py` script fills out the auto-generated part of that template.
It does this by querying PYPI for each framework's package and its metadata and
then determining which versions make sense to test to get good coverage.

The lowest supported and latest version of a framework are always tested, with
a number of releases in between:
- If the package has majors, we pick the highest version of each major. For the
latest major, we also pick the lowest version in that major.
- If the package doesn't have multiple majors, we pick two versions in between
lowest and highest.


### How to add a test suite

1. Add the minimum supported version of the framework/library to `_MIN_VERSIONS`
in `integrations/__init__.py`. This should be the lowest version of the
framework that we can guarantee works with the SDK. If you've just added the
integration, it's fine to set this to the latest version of the framework
at the time.
2. Add the integration and any constraints to `TEST_SUITE_CONFIG`. See below
for the format (or copy-paste one of the existing entries).
3. Add the integration to one of the groups in the `GROUPS` dictionary in
`scripts/split_tox_gh_actions/split_tox_gh_actions.py`.
4. Add the `TESTPATH` for the test suite in `tox.jinja`'s `setenv` section.
5. Run `scripts/generate-test-files.sh` and commit the changes.

#### Caveats

- Make sure the integration name is the same everywhere. If it consists of
multiple words, use an underscore instead of a hyphen.

## Defining constraints

The `TEST_SUITE_CONFIG` dictionary defines, for each integration test suite,
the main package (framework, library) to test with; any additional test
dependencies, optionally gated behind specific conditions; and optionally
the Python versions to test on.

The format is:
Copy link
Member

Choose a reason for hiding this comment

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

Should we consider formalizing these formats as TypedDicts, or by using some other structured data type?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We can do this in a follow up PR, might be nice.


```
integration_name: {
"package": name_of_main_package_on_pypi,
"deps": {
rule1: [package1, package2, ...],
rule2: [package3, package4, ...],
},
"python": python_version_specifier,
}
```

The following can be set as a rule:
- `*`: packages will be always installed
- a version specifier on the main package (e.g. `<=0.32`): packages will only
be installed if the main package falls into the version bounds specified
- specific Python version(s) in the form `py3.8,py3.9`: packages will only be
installed if the Python version matches one from the list

Rules can be used to specify version bounds on older versions of the main
package's dependencies, for example. If e.g. Flask tests generally need
Werkzeug and don't care about its version, but Flask older than 3.0 needs
a specific Werkzeug version to work, you can say:

```
"flask": {
"deps": {
"*": ["Werkzeug"],
"<3.0": ["Werkzeug<2.1.0"],
}
}
````
Sometimes, things depend on the Python version installed. If the integration
test should only run on specific Python version, e.g. if you want AIOHTTP
tests to only run on Python 3.7+, you can say:
```
"aiohttp": {
...
"python": ">=3.7",
}
```
If, on the other hand, you need to install a specific version of a secondary
dependency on specific Python versions (so the test suite should still run on
said Python versions, just with different dependency-of-a-dependency bounds),
you can say:
```
"celery": {
...
"deps": {
"*": ["newrelic", "redis"],
"py3.7": ["importlib-metadata<5.0"],
},
},
```
34 changes: 1 addition & 33 deletions scripts/populate_tox/config.py
Original file line number Diff line number Diff line change
@@ -3,39 +3,7 @@
# dependencies, optionally gated behind specific conditions; and optionally
# the Python versions to test on.
#
# The format is:
# ```
# integration_name: {
# "package": name_of_main_package_on_pypi,
# "deps": {
# rule1: [package1, package2, ...],
# rule2: [package3, package4, ...],
# },
# "python": python_version_specifier,
# }
# ```
#
# The following can be set as a rule:
# - `*`: packages will be always installed
# - a version specifier on the main package (e.g. `<=0.32`): packages will only
# be installed if the main package falls into the version bounds specified
# - specific Python version(s) in the form `py3.8,py3.9`: packages will only be
# installed if the Python version matches one from the list
#
# Rules can be used to specify version bounds on older versions of the main
# package's dependencies, for example. If e.g. Flask tests generally need
# Werkzeug and don't care about its version, but Flask older than 3.0 needs
# a specific Werkzeug version to work, you can say:
#
# ```
# "flask": {
# "deps": {
# "*": ["Werkzeug"],
# "<3.0": ["Werkzeug<2.1.0"],
# }
# }
# ````

# See scripts/populate_tox/README.md for more info on the format and examples.

TEST_SUITE_CONFIG = {
"aiohttp": {
3 changes: 1 addition & 2 deletions scripts/populate_tox/populate_tox.py
Original file line number Diff line number Diff line change
@@ -424,8 +424,7 @@ def write_tox_file(packages: dict) -> None:
release.python_versions
)

# Give PYPI some breathing room
time.sleep(0.25)
time.sleep(0.1) # give PYPI some breathing room

test_releases = [
release for release in test_releases if release.python_versions
3 changes: 3 additions & 0 deletions scripts/populate_tox/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
jinja2
packaging
requests
Comment on lines +1 to +3
Copy link
Member

Choose a reason for hiding this comment

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

Perhaps we should pin these to specific versions to avoid breaking the script in the event of a breaking change in these packages

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think this is fine to leave as is. We're only using very basic public APIs. If anything changes we can pin the version then.

7 changes: 5 additions & 2 deletions scripts/populate_tox/tox.jinja
Original file line number Diff line number Diff line change
@@ -4,8 +4,11 @@
# and then run "tox" from this directory.
#
# This file has been generated from a template
# by scripts/populate_tox/populate_tox.py. Any changes to the file should be made
# in the script and the file regenerated.
# by "scripts/populate_tox/populate_tox.py". Any changes to the file should
# be made in the template (if you want to change a hardcoded part of the file)
# or in the script (if you want to change the auto-generated part).
# The file (and all resulting CI YAMLs) then need to be regenerated via
# "scripts/generate-test-files.sh".

[tox]
requires =