cachable: make sure to clear caches between tests

This adds a registry for all modules and classes that
cachable is included in. The registry allows us to
programmatically clear all caches in between tests
so that we don't forget to do that when adding a new
class or refactoring code. The goal here is to reduce
the number of flaky tests in the future.
This commit is contained in:
apainintheneck 2024-02-25 15:14:22 -08:00
parent e9cb65bfba
commit 536ae08a44
5 changed files with 48 additions and 25 deletions

View File

@ -10,9 +10,9 @@ module Homebrew
#
# @api private
module Cask
class << self
include Cachable
extend Cachable
class << self
private :cache
sig { params(token: String).returns(Hash) }

View File

@ -10,9 +10,9 @@ module Homebrew
#
# @api private
module Formula
class << self
include Cachable
extend Cachable
class << self
private :cache
sig { params(name: String).returns(Hash) }

View File

@ -1,4 +1,4 @@
# typed: strict
# typed: true
# frozen_string_literal: true
module Cachable
@ -11,4 +11,43 @@ module Cachable
def clear_cache
cache.clear
end
# Collect all classes that mix in Cachable so that those caches can be cleared in-between tests.
if ENV["HOMEBREW_TESTS"]
def self.included(klass)
raise ArgumentError, "Don't use Cachable with singleton classes" if klass.singleton_class?
super if defined?(super)
end
# Ignore classes that get inherited from a lot and that have
# caches that we don't need to clear on the class level.
IGNORE_INHERITED_CLASSES = %w[Formula Cask].freeze
private_constant :IGNORE_INHERITED_CLASSES
def self.extended(klass)
Registry.list << klass
klass.extend(Inherited) unless IGNORE_INHERITED_CLASSES.include?(klass.name)
super if defined?(super)
end
module Inherited
def inherited(klass)
# A class might inherit Cachable at the instance level
# and in that case we just want to skip registering it.
Registry.list << klass if klass.respond_to?(:clear_cache)
super if defined?(super)
end
end
module Registry
def self.list
@list ||= []
end
def self.clear_all_caches
list.each(&:clear_cache)
end
end
end
end

View File

@ -9,8 +9,9 @@ require "system_command"
#
# @api private
module Readall
extend Cachable
class << self
include Cachable
include SystemCommand::Mixin
# TODO: remove this once the `MacOS` module is undefined on Linux

View File

@ -202,16 +202,7 @@ RSpec.configure do |config|
config.around do |example|
Homebrew.raise_deprecation_exceptions = true
Formulary.clear_cache
Tap.each(&:clear_cache)
Tap.clear_cache
DependencyCollector.clear_cache
Formula.clear_cache
Keg.clear_cache
Tab.clear_cache
Dependency.clear_cache
Requirement.clear_cache
Readall.clear_cache if defined?(Readall)
Cachable::Registry.clear_all_caches
FormulaInstaller.clear_attempted
FormulaInstaller.clear_installed
FormulaInstaller.clear_fetched
@ -263,15 +254,7 @@ RSpec.configure do |config|
@__stderr.close
@__stdin.close
Formulary.clear_cache
Tap.clear_cache
DependencyCollector.clear_cache
Formula.clear_cache
Keg.clear_cache
Tab.clear_cache
Dependency.clear_cache
Requirement.clear_cache
Readall.clear_cache if defined?(Readall)
Cachable::Registry.clear_all_caches
FileUtils.rm_rf [
*TEST_DIRECTORIES,