Skip to content

Mnt/multi imageset #25734

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

Draft
wants to merge 45 commits into
base: main
Choose a base branch
from
Draft

Conversation

tacaswell
Copy link
Member

PR Summary

This is not ready for review at all yet, but opening so that I can refer to it in the readme of https://github.com/tacaswell/mpl-imageset-demo. This code is .... sub optimal and needs to be refactored (the compare method should not sometimes write out baseline images and sometimes do comparisons!), but it

The rough scheme is as such:

  1. replace the baseline directory with a text file (currently called image_list.txt where each line is a : separated tuple of (relative path to file, revision number, timestamp)
  2. using git blame we can extract the last commit where any given line was changed
  3. via ENV (and eventually better interfaces) you can re-direct where the image comparison machinery looks for images
  4. in one mode running the test suite will generate the baseline images and write out a json file noting the rev number (from the file), the sha the image was last changed in, and the current version of Matplotlib
  5. in the normal mode the test suite will read the json file and verify that the image in the baseline images is consistent with what we get from image_list.txt

An example of the image list file looks like

test_a/A.pdf:1:1681408722.5270584
test_a/A.png:0:1681408661.3898573
test_a/A.svg:0:1681408661.3898566
test2/B.pdf:0:1681408661.389891
test2/B.png:0:1681408661.3898895

The logic on this format is :

  • use : as a separator because it forbidden in windows paths the leading paths will be relative (so no drive letters)
  • information must be in one line so git blame is easy to reason about
  • version rev number is for humans to read and reason about
  • the timestamp is to ensure that two people versioning reving the same image in different PRs will cause a merge conflict. There needs to be something semi-unique here. An alternative might be to add a short note justifying why, your initials, asking people to hit random keys, using uuid4, or ... would also work.

The json dumped in the generated baseline directory looks like

{
  "test_basic/image.png": {
    "mpl_version": "3.8.0.dev913+g8ce98ade16.d20230420",
    "rev": 0,
    "sha": "8691c2d2bf868a23c80f6ac85ba184a917e49f03"
  },
  "test_basic/line.pdf": {
    "mpl_version": "3.8.0.dev913+g8ce98ade16.d20230420",
    "rev": 0,
    "sha": "8691c2d2bf868a23c80f6ac85ba184a917e49f03"
  },
  "test_basic/line.png": {
    "mpl_version": "3.8.0.dev913+g8ce98ade16.d20230420",
    "rev": 0,
    "sha": "8691c2d2bf868a23c80f6ac85ba184a917e49f03"
  },
  "test_basic/line.svg": {
    "mpl_version": "3.8.0.dev913+g8ce98ade16.d20230420",
    "rev": 0,
    "sha": "8691c2d2bf868a23c80f6ac85ba184a917e49f03"
  },
  "test_other/hist.png": {
    "mpl_version": "3.8.0.dev913+g8ce98ade16.d20230420",
    "rev": 1,
    "sha": "0000000000000000000000000000000000000000"
  },
  "test_other/scatter.pdf": {
    "mpl_version": "3.8.0.dev913+g8ce98ade16.d20230420",
    "rev": 0,
    "sha": "8691c2d2bf868a23c80f6ac85ba184a917e49f03"
  },
  "test_other/scatter.png": {
    "mpl_version": "3.8.0.dev913+g8ce98ade16.d20230420",
    "rev": 0,
    "sha": "8691c2d2bf868a23c80f6ac85ba184a917e49f03"
  },
  "test_other/scatter.svg": {
    "mpl_version": "3.8.0.dev913+g8ce98ade16.d20230420",
    "rev": 0,
    "sha": "8691c2d2bf868a23c80f6ac85ba184a917e49f03"
  }
}

The sha is for the computer, the rev is for the human, and the mpl version is for debugging.

open questions

  • how do deal with non-git checkouts. As this is mostly going to be around released versions so I think that narrows the problem space quite a bit.
  • tooling around updating these
  • how to post diffs when images are changed
  • how to generate cached version of the baseline on merge to main
  • how to generate and distribute "blessed" versions on tag

PR Checklist

Documentation and Tests

  • Has pytest style unit tests (and pytest passes)
  • Documentation is sphinx and numpydoc compliant (the docs should build without error).
  • New plotting related features are documented with examples.

Release Notes

  • New features are marked with a .. versionadded:: directive in the docstring and documented in doc/users/next_whats_new/
  • API changes are marked with a .. versionchanged:: directive in the docstring and documented in doc/api/next_api_changes/
  • Release notes conform with instructions in next_whats_new/README.rst or next_api_changes/README.rst

@tacaswell tacaswell added this to the v3.8.0 milestone Apr 20, 2023
@tacaswell
Copy link
Member Author

See tacaswell/mpl-imageset-demo#1 for what a PR would look like

see https://github.com/tacaswell/mpl-imageset-demo#operation for a skeletal user guide but it covers:

  • how to run tests
  • how to regenerate the baseline images
  • how to validate that the baseline set is consistent with the current checkout
  • tell the system we have changed a test image
  • tell the system about a new test image

Presumably manage_baseline_images.py will end up in our tools directory and the the envs will be folded into a pytest plugin / some other way to thread that configuration through.

@tacaswell tacaswell force-pushed the mnt/multi_imageset branch from c047f0b to 8dab81f Compare May 18, 2023 16:20
@tacaswell tacaswell force-pushed the mnt/multi_imageset branch 2 times, most recently from 26911a3 to 4a0d7ad Compare May 18, 2023 21:20
@tacaswell
Copy link
Member Author

tacaswell commented May 19, 2023

Of course there are complications 🤣

  • 2 of the eps tests actually compare against a pdf output (and there is some special casing in the baseline lookup code for that (has been there from ~2011). Given that we will no longer be storing the files, we can probably drop that long term
  • think I have fixed the windows vs posix path issues

Tasks:

  • pull apart the "compare" and "generate" functionality
  • integrate with pytest test discovery to when in generate mode do not run non-image tests (save time!)
  • try to find better internal names for everything in the compare / generate methods
  • write docs on how to bootstrap your own test images
  • write docs of how to add image
  • write docs of how to remove and image
  • write docs on how to update an image
  • write helper to zip up and systematically name a set of images
  • sort out how to leverage caching (on all of the CI services)
  • write GHA to generate above zip/tar balls of images (or do git)
  • ..and push those someplace (?)
  • make a wheel with the images (?)
  • write docs on how to use pre-generated images
  • look at sqlite instead of json of md cache

@tacaswell
Copy link
Member Author

The image_lists.txt for Matplotlib are now checked in so people can take a look at what those look like at full scale.

@ksunden
Copy link
Member

ksunden commented May 19, 2023

Should the metadata.json files be included in the repo? or are those intended to be local only?

@tacaswell
Copy link
Member Author

Should the metadata.json files be included in the repo? or are those intended to be local only?

They are intended to go with the generated sets of images, however given that we are not at the point where we can actually pull the images out of the repo, but I still want the tests to run they need to be checked in for now. The final version of this PR will squash them out of existence.

@tacaswell
Copy link
Member Author

I think this is at a point where (modulo the metadata.json files) where it is starting to be reviewable.

The internal names are...not great, but I think I have pulled it apart enough that it is not complete spaghetti code.

MPLTESTIMAGEPATH='/tmp/test_images2' MPLGENERATEBASELINE=1 pytest

should work and generate you a full tree of test images on this branch!

@tacaswell
Copy link
Member Author

This now includes a pytest plugin (😱) so that

pytest --image-baseline=/tmp/test_images --generate-images   # generate the baseline images
pytest --image-baseline=/tmp/test_images -n 20               # test against them

works. The $MPLTESTIMAGEPATH and $MPLGENERATEBASELINE also still work (but the flags "win").

All of these names need some feedback.

@tacaswell tacaswell modified the milestones: v3.8.0, v3.9.0 Jun 21, 2023
@tacaswell
Copy link
Member Author

This seems to be working (successfully generated test images with a new freetype and it passed against them)!

I'm now sure that this is going to work, but lots of details left.

@tacaswell
Copy link
Member Author

not going to get this done in the next few weeks.

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

Successfully merging this pull request may close these issues.

3 participants