Skip to content

build: Set Django version for tests more safely; drop support for non-GHA - #31387

Merged
timmc-edx merged 2 commits into
masterfrom
timmc/django-pins
Dec 12, 2022
Merged

build: Set Django version for tests more safely; drop support for non-GHA#31387
timmc-edx merged 2 commits into
masterfrom
timmc/django-pins

Conversation

@timmc-edx

@timmc-edx timmc-edx commented Dec 1, 2022

Copy link
Copy Markdown
Contributor

This is for #31374

We have a need to lock the version of Django for production and tests, but also to test on newer versions of Django so that we can get the repo ready for long-term-support releases.

We've been doing that by extracting the django==x.y.z from the pip-compiled files and moving it to a django.txt that is then co-installed but can be overridden during tests. The problem is that this can result in broken packages.

The approach here is to have make test-requirements continue to ensure a consistent set of packages, and then install a different Django on top of that in the CI script -- and call pip check to make sure that combination isn't broken.

Adding Django 4.0 to the unit-tests.yml matrix will now correctly result in this error and a failing job: django-splash 1.2.1 has requirement Django<4.0, but you have django 4.0.8.

The other half of this is to change other CI runners to remove their ability to control the Django version, since it's complicated to make this work, and we probably only need it in unit-tests.yml. Convert them to just use make test-requirements.

Also:

  • Simplify handling of pip --src by setting PIP_SRC (rather than our own PIP_SRC_DIR, which pip ignores because --src-dir isn't an option that it knows). This is needed to allow make test-requirements to do the pip calls. An alternative would be to set a pip-options env var for the make target to use, but PIP_SRC already exists.
  • Remove outdated modifications to common_constraints
  • Add comment explaining why pylint tests need dev-requirements

Guide to the files in this PR:

  • Makefile: Used by all of the other files here -- make test-requirements is what we'll use for all test-dependencies installation going forward. Only changes here are to make compile-requirements (shared by make upgrade) in order to undo the testing.txt/django.txt split.
    • requirements/edx/testing.txt and requirements/edx/django.txt are changed as part of this
  • .github/workflows/unit-tests.yml: Our main pytest CI runner; runs as a GitHub Action but uses the edx-platform-runner hosted by 2U. Only runs for edx-platform's main copy and a private fork.
    • scripts/ci-runner.Dockerfile seems to be the docker image for this runner
    • ✔️ The changes to this file are tested by the checks running on this PR. I've also confirmed that adding 4.0 to the matrix causes the appropriate failures (conflict with django-splash).
  • .github/workflows/unit-tests-gh-hosted.yml: Same role, but runs on any other fork of edx-platform instead, and uses GHA runners (slower). Should be otherwise identical.
  • .github/workflows/pylint-checks.yml: Our main pylint` checks
    • ✔️ Tested on this PR
  • .github/workflows/quality-checks.yml: Runs various other quality checks using scripts/generic-ci-tests.sh(via./scripts/all-tests.sh`, unaffected here) which calls paver via tox
    • ✔️ Tested on this PR
  • tox.ini: Configures the tox testing environment, used here for quality checks; I've removed the "django" specifiers from its environments.
    • ✔️ Invoked by quality tests here
  • scripts/xdist/prepare_xdist_nodes.sh calls scripts/xdist/setup_worker.sh
    • scripts/unit-tests.sh (unaffected by PR) calls in to these via generic-ci-tests.sh, but only if environment variable TEST_SUITE is set to one of lms-unit, cms-unit, or pavelib-unit
    • They're used in splitting up and farming out pytest runs to multiple workers. Can allegedly be run locally, Maybe these were used only on Jenkins, or maybe the new hosted test runner still uses these?
    • ✔️ I was able to run TEST_SUITE=lms-unit SHARD=1 scripts/generic-ci-tests.sh successfully after running make lms-up in devstack. Calling that good enough.
  • scripts/jenkins-common.sh seems to be part of our old (now shut down) Jenkins test runners
    • ❓ Probably can't test any more
  • pavelib/prereqs.py installs Python dependencies for paver runs (used for quality checks, among other things)
    • pavelib/utils/envs.py is used by this
    • Their own unit tests were also affected: pavelib/tests.py and pavelib/utils/test/suites/pytest_suite.py
    • ✔️ I think these can be considered tested thanks to the quality checks that run

Comment thread pavelib/prereqs.py Outdated

@timmc-edx timmc-edx Dec 1, 2022

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

[Author's note] I believe that sh will pass through the PIP_SRC environment variable. This sh is actually from paver.shell, but it defaults to env=None and passes that to Popen, which should pass through the caller's environment for None.

Comment thread pavelib/prereqs.py Outdated

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

[Author's note] I'm not sure if this was really correct in the first place -- shouldn't the quality checks be using dev deps (pylint will complain about missing django-debug-toolbar) and pytest be using just testing deps?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We're looking into the feasibility of ripping out this paver code anyway; note that the GitHub Actions workflows already use pylint directly instead of going through paver.

@timmc-edx
timmc-edx marked this pull request as ready for review December 1, 2022 19:37
@timmc-edx timmc-edx changed the title ci: Override Django version for tests in a safer way build: Set Django version for tests more safely; drop support for non-GHA Dec 2, 2022
…-GHA

We have a need to lock the version of Django for production and tests, but
also to test on newer versions of Django so that we can get the repo ready
for long-term-support releases.

We've been doing that by extracting the `django==x.y.z` from the
pip-compiled files and moving it to a django.txt that is then co-installed
but can be overridden during tests. The problem is that this can result
in broken packages.

The approach here is to have `make test-requirements` continue to
ensure a consistent set of packages, and then install a different
Django on top of that in the CI script -- and call `pip check` to make
sure that combination isn't broken.

Adding Django 4.0 to the unit-tests.yml matrix will now correctly
result in this error and a failing job:
`django-splash 1.2.1 has requirement Django<4.0, but you have django 4.0.8.`

The other half of this is to change other CI runners to remove their
ability to control the Django version, since it's complicated to make
this work, and we probably only need it in unit-tests.yml. Convert them
to just use `make test-requirements`.

Also:

- Simplify handling of `pip --src` by setting `PIP_SRC` (rather than our
  own `PIP_SRC_DIR`, which pip ignores because `--src-dir` isn't an option
  that it knows). This is needed to allow `make test-requirements` to do
  the pip calls. An alternative would be to set a pip-options env var for
  the make target to use, but `PIP_SRC` already exists.
- Remove outdated modifications to common_constraints
- Add comment explaining why pylint tests need dev-requirements

@jmbowman jmbowman left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Would have saved you some time if we'd already done the cleanup pass of all the old Jenkins cruft first...oh well. Looks pretty good, just a couple of suggestions.

Comment thread pavelib/prereqs.py Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We're looking into the feasibility of ripping out this paver code anyway; note that the GitHub Actions workflows already use pylint directly instead of going through paver.

distlib==0.3.6
# via virtualenv
django==3.2.16
# via

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Ha, kind of funny that we were ripping out the dependency but leaving the comments for it.

COPY requirements/edx/django.txt requirements/edx/django.txt
RUN pip install -r requirements/pip.txt && \
pip install -r requirements/edx/testing.txt -r requirements/edx/django.txt
RUN make test-requirements

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Don't you need to copy in the Makefile also to be able to run this?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Hmm, seems likely! Adding that. :-)

Comment thread tox.ini
@@ -1,5 +1,5 @@
[tox]
envlist = py38-django{32}, quality-django{32}
envlist = py38, quality

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can we leave this as it was, but still make your change later in the file? I think the suffixes are harmless for now, and will be needed later when we start testing 4.0 and 4.1. And I like being more explicit about which Django version is being tested.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I'm not sure what benefit they would provide -- tox would no longer be controlling the Django version, and still wouldn't be once 4.x testing starts.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It would be for local testing of the 4.x upgrade. But I suppose it would be clearer to remove this for now and just add it back once it's actually implemented when we start that testing.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think for local testing what we'd want is just a branch where Django is upgraded to 4.x and tests are otherwise run as normal.

@iamsobanjaved iamsobanjaved left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM. All changes were nicely explained

@timmc-edx
timmc-edx merged commit b8a34f0 into master Dec 12, 2022
@timmc-edx
timmc-edx deleted the timmc/django-pins branch December 12, 2022 21:45
@edx-pipeline-bot

Copy link
Copy Markdown
Contributor

EdX Release Notice: This PR has been deployed to the staging environment in preparation for a release to production.

@edx-pipeline-bot

Copy link
Copy Markdown
Contributor

EdX Release Notice: This PR has been deployed to the production environment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants