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

[test] Improve testing of Swift features #76740

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

Conversation

drodriguez
Copy link
Contributor

@drodriguez drodriguez commented Sep 27, 2024

Features in Swift can be experimental, upcoming or base features. During their lifetime features evolve from one category to other categories. Usually experimental features are only available in "asserts" compilers, but they can also be experimental features in "non asserts" compilers. Upcoming and base features are available in both "asserts" and "non asserts" compilers.

When coding a new feature, the feature normally will start as an experimental feature. In the past this has required to mark the tests that use that feature with REQUIRES: asserts to avoid the test failing when testing in a "non asserts" compilers. This requisite is not always follow, and we forget to add those REQUIRES: asserts from time to time. This causes breakages for people that test the "non asserts" compilers. For some experimental features that are available in production compilers the REQUIRES: asserts is not even needed, which can make adding those lines work against one intentions. When the feature graduates from experimental to upcoming or base, we sometimes forget to update the the related tests to remove those REQUIRES: asserts, so a "non asserts" compiler will not actually execute those tests, and bugs can be introduced by mistake in those compilers.

The changes in this PR introduce a system that aims to simplify testing those experimental features and avoid some of the problems noted above.

The first change is take the canonical Features.def and transform its contents in something that LLVM Lit can create available_features for. This is done abusing the Clang preprocessor to transform the .def file into a Python file that can be loaded by lit.site.cfg during testing. This is done for each build and will pick up changes in the Features.def as they happen, so it will always be up-to-date. Additionally it understand when features as available depending on "asserts" or "non asserts" compilers, and will not incorrectly require an "asserts" compiler for non-production features, or let experimental features be tested in a "non asserts" compiler.

The second part of the change is keeping the tests up-to-date with the features they are testing, so each test that uses a feature is marked as such. This is done with a test itself, which greps through the existing tests, checks for the usage of -enable-experimental-feature or -enable-upcoming-feature and warns the user about the missing REQUIRES: lines (failing the test suite, so nobody can submit a test that skips the requirements).

Finally, the last change is modifying a huge number of tests to follow the new rules. All the tests that currently use -enable-experimental-feature or -enable-upcoming-feature have been annotated with REQUIRES: lines, and the (now unnecessary) REQUIRES: asserts have been removed.

@drodriguez
Copy link
Contributor Author

@swift-ci please test

@drodriguez
Copy link
Contributor Author

@swift-ci please test

@tshortli
Copy link
Contributor

This seems like a good idea to me.

test/ASTGen/attrs.swift Outdated Show resolved Hide resolved
@drodriguez
Copy link
Contributor Author

@swift-ci please test

Take the `Features.def` file used in other parts of the code and create
a file that can be used from the LLVM Lit configuration files to add new
available features that can be checked from the tests with `REQUIRES`
and others.

The file `lit.swift-features.cfg.inc` is preprocessed by Clang and
generates a file with Python syntax that can be loaded from both
`lit.site.cfg.in` files. The preprocessing output is copied into the
different test directories in the build directory, and added it is added
as a dependency of them, so it will be generate when the test run or
when `Features.def` changes.

`EXPERIMENTAL_FEATURES` are only enabled if they are available in
production or the compiler is being built with assertions, while
`UPCOMING_FEATURES` and the rest of the `LANGUAGE_FEATURES` are always
available.
Find all the usages of `--enable-experimental-feature` or
`--enable-upcoming-feature` in the tests and replace some of the
`REQUIRES: asserts` to use `REQUIRES: swift-feature-Foo` instead, which
should correctly apply to depending on the asserts/noasserts mode of the
toolchain for each feature.

Remove some comments that talked about enabling asserts since they don't
apply anymore (but I might had miss some).

All this was done with an automated script, so some formatting weirdness
might happen, but I hope I fixed most of those.

There might be some tests that were `REQUIRES: asserts` that might run
in `noasserts` toolchains now. This will normally be because their
feature went from experimental to upcoming/base and the tests were not
updated.
The test will look for other tests using `RUN:` lines that use
experimental or upcoming features and will check that the tests also are
checking with the right `REQUIRES:` lines for the used features. This
should avoid new tests being introduced without the right `REQUIRES` and
should avoid breaking the toolchain in less tested configurations.
@drodriguez
Copy link
Contributor Author

@swift-ci please test

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.

2 participants