Make BuildViewTestCase's use of custom RuleClassProviders and bzl inlining less error prone

This refactoring aims to convert the hours I wasted into saved time for somebody else.

Problem:

BuildViewTestCase allows you to supply an alternative RuleClassProvider by overriding getRuleClassProvider(). Although named as an accessor ("get..."), most overrides actually construct a new RuleClassProvider inside the implementation. This is safe so long as the method is only called once, in initializeSkyframeExecutor().

However, this interracts poorly with another, less common paradigm: Testing of BzlLoadFunction inlining. This is done in StarlarkIntegrationTest by defining a @Before hook (initializeLookupFunctions()) that grabs the current Skyframe executor's PackageFunction and tells it to use a newly constructed BzlLoadFunction -- a BzlLoadFunction that obtains its RuleClassProvider by... you guessed it, calling getRuleClassProvider(). Yet this too is safe, so long as the default implementation of getRuleClassProvider() is used, which memoizes its result deep inside the AnalysisMock.

But combining these two features together leads to disaster. You end up with bzl loading machinery whose native rule definitions (`native.cc_library`, etc.) are cloned versions of those in the rest of the Skyframe machinery. This can lead to infuriatingly subtle failures down the line.

Solution:

BuildViewTestCase's getRuleClassProvider() is renamed to createRuleClassProvider() to make it clear that it is not freely repeatable. A true accessor, getRuleClassProvider(), is introduced to take its place and declared `final`.

initializeLookupFunctions() is factored into BuildViewTestCase. Subclasses can simply override usesInliningBzlLoadFunction() to request inlining.

Thanks to shreyax@ for the debugging assistance.

Cleanup work on way toward #11437.

RELNOTES: None
PiperOrigin-RevId: 315329662
24 files changed
tree: 9e4eb82e2e662fc574abee929049edb285512f6d
  1. .bazelci/
  2. examples/
  3. scripts/
  4. site/
  5. src/
  6. third_party/
  7. tools/
  8. .bazelrc
  9. .gitattributes
  10. .gitignore
  11. AUTHORS
  12. BUILD
  13. CHANGELOG.md
  14. CODEOWNERS
  15. combine_distfiles.py
  16. combine_distfiles_to_tar.sh
  17. compile.sh
  18. CONTRIBUTING.md
  19. CONTRIBUTORS
  20. distdir.bzl
  21. ISSUE_TEMPLATE.md
  22. LICENSE
  23. README.md
  24. WORKSPACE
README.md

Bazel

{Fast, Correct} - Choose two

Build and test software of any size, quickly and reliably.

  • Speed up your builds and tests: Bazel rebuilds only what is necessary. With advanced local and distributed caching, optimized dependency analysis and parallel execution, you get fast and incremental builds.

  • One tool, multiple languages: Build and test Java, C++, Android, iOS, Go, and a wide variety of other language platforms. Bazel runs on Windows, macOS, and Linux.

  • Scalable: Bazel helps you scale your organization, codebase, and continuous integration solution. It handles codebases of any size, in multiple repositories or a huge monorepo.

  • Extensible to your needs: Easily add support for new languages and platforms with Bazel's familiar extension language. Share and re-use language rules written by the growing Bazel community.

Getting Started

Documentation

Contributing to Bazel

See CONTRIBUTING.md

Build status