Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/lib/metasploit/framework/spec/constants/each.rb
Views: 11789
# @note This should only temporarily be used in `spec/spec_helper.rb` when1# `Metasploit::Framework::Spec::Constants::Suite.configure!` detects a leak. Permanently having2# `Metasploit::Framework::Spec::Constants::Each.configure!` can lead to false positives when modules are purposely3# loaded in a `before(:all)` and cleaned up in a `after(:all)`.4#5# Fails example if it leaks module loading constants.6module Metasploit::Framework::Spec::Constants::Each7#8# CONSTANTS9#1011LOG_PATHNAME = Pathname.new('log/metasploit/framework/spec/constants/each.log')1213#14# Module Methods15#1617class << self18attr_accessor :leaks_cleaned19end2021# Is Metasploit::Framework::Spec::Constants::Each.configure! still necessary or should it be removed?22#23# @return [true] if {configure!}'s `before(:each)` cleaned up leaked constants24# @return [false] otherwise25def self.leaks_cleaned?26!!@leaks_cleaned27end2829# Configures after(:each) callback for RSpe to fail example if leaked constants.30#31# @return [void]32def self.configure!33unless @configured34RSpec.configure do |config|35config.before(:each) do |example|36leaks_cleaned = Metasploit::Framework::Spec::Constants.clean3738if leaks_cleaned39$stderr.puts "Cleaned leaked constants before #{example.metadata.full_description}"40end4142# clean so that leaks from earlier example aren't attributed to this example43Metasploit::Framework::Spec::Constants::Each.leaks_cleaned ||= leaks_cleaned44end4546config.after(:each) do |example|47child_names = Metasploit::Framework::Spec::Constants.to_enum(:each).to_a4849if child_names.length > 050lines = ['Leaked constants:']5152child_names.sort.each do |child_name|53lines << " #{child_name}"54end5556lines << ''57lines << "Add `include_context 'Metasploit::Framework::Spec::Constants cleaner'` to clean up constants from #{example.metadata.full_description}"5859message = lines.join("\n")6061# use caller metadata so that Jump to Source in the Rubymine RSpec running jumps to the example instead of62# here63fail RuntimeError, message, example.metadata[:caller]64end65end6667config.after(:suite) do68if Metasploit::Framework::Spec::Constants::Each.leaks_cleaned?69if LOG_PATHNAME.exist?70LOG_PATHNAME.delete71end72else73LOG_PATHNAME.open('w') { |f|74f.puts "No leaks were cleaned by `Metasploit::Framework::Spec::Constants::Each.configured!`. Remove " \75"it from `spec/spec_helper.rb` so it does not interfere with contexts that persist loaded " \76"modules for entire context and clean up modules in `after(:all)`"77}78end79end80end8182@configured = true83end84end8586# Whether {configure!} was called87#88# @return [Boolean]89def self.configured?90!!@configured91end9293# Adds action to `spec` task so that `rake spec` fails if configured! is unnecessary in `spec/spec_helper.rb` and94# should be removed95#96# @return [void]97def self.define_task98Rake::Task.define_task('metasploit:framework:spec:constant:each:clean') do99if LOG_PATHNAME.exist?100LOG_PATHNAME.delete101end102end103104Rake::Task.define_task(spec: 'metasploit:framework:spec:constant:each:clean')105106Rake::Task.define_task(:spec) do107if LOG_PATHNAME.exist?108LOG_PATHNAME.open { |f|109f.each_line do |line|110$stderr.write line111end112}113114exit(1)115end116end117end118end119120121