Module: Metasploit::Framework::Spec::Constants::Suite
- Defined in:
- lib/metasploit/framework/spec/constants/suite.rb
Overview
Logs if constants created by module loading are left over after suite has completed.
Constant Summary collapse
- LOGS_PATHNAME =
CONSTANTS
Pathname.new('log/metasploit/framework/spec/constants/suite')
Class Method Summary collapse
-
.configure! ⇒ Object
Configures after(:suite) callback for RSpec to check for leaked constants.
-
.define_task ⇒ void
Adds action to ‘spec` task so that `rake spec` fails if `log/leaked-constants.log` exists after printing out the leaked constants.
-
.log_leaked_constants(hook, message) ⇒ void
Logs leaked constants to LOG_PATHNAME and prints ‘message` to stderr.
- .log_pathname(hook) ⇒ Object
-
.print_leaked_constants(hook) ⇒ true, false
Prints logged leaked constants to stderr.
Class Method Details
.configure! ⇒ Object
Configures after(:suite) callback for RSpec to check for leaked constants.
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/metasploit/framework/spec/constants/suite.rb', line 35 def self.configure! unless @configured RSpec.configure do |config| config.before(:suite) do Metasploit::Framework::Spec::Constants::Suite.log_leaked_constants( :before, 'Modules are being loaded outside callbacks before suite starts.' ) end config.after(:suite) do Metasploit::Framework::Spec::Constants::Suite.log_leaked_constants( :after, 'Modules are being loaded inside callbacks or examples during suite run.' ) end end @configured = true end end |
.define_task ⇒ void
This method returns an undefined value.
Adds action to ‘spec` task so that `rake spec` fails if `log/leaked-constants.log` exists after printing out the leaked constants.
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/metasploit/framework/spec/constants/suite.rb', line 61 def self.define_task Rake::Task.define_task(:spec) do leaked_before = Metasploit::Framework::Spec::Constants::Suite.print_leaked_constants(:before) leaked_after = Metasploit::Framework::Spec::Constants::Suite.print_leaked_constants(:after) # leaks after suite can be be cleaned up by {Metasploit::Framework::Spec::Constants::Each.configure!}, but # leaks before suite require user intervention to find the leaks since it's a programming error in how the specs # are written where Modules are being loaded in the context scope. if leaked_after $stderr.puts $stderr.puts "Add `Metasploit::Framework::Spec::Constants::Each.configure!` to `spec/spec_helper.rb` " \ "**NOTE: `Metasploit::Framework::Spec::Constants::Each` may report false leaks if `after(:all)` " \ "is used to clean up constants instead of `after(:each)`**" end if leaked_before || leaked_after exit 1 end end end |
.log_leaked_constants(hook, message) ⇒ void
This method returns an undefined value.
Logs leaked constants to LOG_PATHNAME and prints ‘message` to stderr.
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/metasploit/framework/spec/constants/suite.rb', line 14 def self.log_leaked_constants(hook, ) count = 0 hook_log_pathname = log_pathname(hook) hook_log_pathname.parent.mkpath hook_log_pathname.open('w') do |f| count = Metasploit::Framework::Spec::Constants.each do |child_name| f.puts child_name end end if count > 0 $stderr.puts "#{count} #{'constant'.pluralize(count)} leaked under " \ "#{Metasploit::Framework::Spec::Constants::PARENT_CONSTANT}. #{} See #{hook_log_pathname} " \ "for details." else hook_log_pathname.delete end end |
.log_pathname(hook) ⇒ Object
84 85 86 |
# File 'lib/metasploit/framework/spec/constants/suite.rb', line 84 def self.log_pathname(hook) LOGS_PATHNAME.join("#{hook}.log") end |
.print_leaked_constants(hook) ⇒ true, false
Prints logged leaked constants to stderr.
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/metasploit/framework/spec/constants/suite.rb', line 94 def self.print_leaked_constants(hook) hook_log_pathname = log_pathname(hook) leaks = false if hook_log_pathname.exist? leaks = true $stderr.puts "Leaked constants detected under #{Metasploit::Framework::Spec::Constants::PARENT_CONSTANT} #{hook} suite:" hook_log_pathname.open do |f| f.each_line do |line| constant_name = line.strip full_name = Metasploit::Framework::Spec::Constants.full_name(constant_name) if full_name formatted_full_name = " # #{full_name}" end $stderr.puts " #{constant_name}#{formatted_full_name}" end end end leaks end |