diff --git a/lib/metasploit/framework/spec/untested_payloads.rb b/lib/metasploit/framework/spec/untested_payloads.rb index d1999c406c..8c29844e93 100644 --- a/lib/metasploit/framework/spec/untested_payloads.rb +++ b/lib/metasploit/framework/spec/untested_payloads.rb @@ -1,5 +1,5 @@ # @note needs to use explicit nesting. so this file can be loaded directly without loading 'metasploit/framework' which -# allows for faster loading of rake tasks +# allows for faster loading of rake tasks. module Metasploit module Framework module Spec @@ -10,6 +10,34 @@ module Metasploit # Adds action to `spec` tasks so that `rake spec` fails if `log/untested-payloads.log` exists and prints out untested # payloads from that log to stderr. # + # # @example Using `Metasploit::Framework::Spec::UntestedPayloads.define_task` with 'payload can be instantiated' shared examples and 'untested payloads' shared context + # # Rakefile + # require 'metasploit/framework/spec/untested_payloads' + # + # # defined spec task with rspec-rails + # My::Application.load_tasks + # # extends spec task to fail when there are untested payloads + # Metasploit::Framework::Spec::UntestedPayloads.define_task + # + # # spec/modules/payloads_spec.rb + # require 'spec_helper' + # + # describe 'modules/payloads' do + # modules_pathname = Pathname.new(__FILE__).parent.parent.parent.join('modules') + # + # include_context 'untested payloads', modules_pathname: modules_pathname + # + # context 'my/staged/payload/handler' do + # it_should_behave_like 'payload can be instantiated', + # ancestor_reference_names: [ + # 'stages/my/payload', + # 'stagers/my/payload/handler' + # ], + # modules_pathname: modules_pathname, + # reference_name: 'my/staged/payload/handler' + # end + # end + # # @return [void] def self.define_task Rake::Task.define_task :spec do diff --git a/spec/support/shared/contexts/untested_payloads.rb b/spec/support/shared/contexts/untested_payloads.rb index 8eb4216ab3..8a7f8b2e13 100644 --- a/spec/support/shared/contexts/untested_payloads.rb +++ b/spec/support/shared/contexts/untested_payloads.rb @@ -1,7 +1,37 @@ # Use along with `it_should_behave_like 'payload can be instantiated'` to detect if a payload under `:modules_pathname` # was not tested. If any payloads are untested, an error will be written to stderr and the names of untested payloads # will be logged to `log/untested-payloads.log`. This log is reset for run of context, so if there were previously -# untested payloads and there aren't anymore, then `log/untested-payloads.log` will be deleted. +# untested payloads and there aren't anymore, then `log/untested-payloads.log` will be deleted. Can be used with +# {Metasploit::Framework::Spec::UntestedPayloads.define_task} so that the `spec` task fails if there are untested +# payloads. +# +# @example Using 'untested payloads' with `Metasploit::Framework::Spec::UntestedPayloads.define_task` and 'payloads can be instantiated' shared examples +# # Rakefile +# require 'metasploit/framework/spec/untested_payloads' +# +# # defined spec task with rspec-rails +# My::Application.load_tasks +# # extends spec task to fail when there are untested payloads +# Metasploit::Framework::Spec::UntestedPayloads.define_task +# +# # spec/modules/payloads_spec.rb +# require 'spec_helper' +# +# describe 'modules/payloads' do +# modules_pathname = Pathname.new(__FILE__).parent.parent.parent.join('modules') +# +# include_context 'untested payloads', modules_pathname: modules_pathname +# +# context 'my/staged/payload/handler' do +# it_should_behave_like 'payload can be instantiated', +# ancestor_reference_names: [ +# 'stages/my/payload', +# 'stagers/my/payload/handler', +# modules_pathname: modules_pathname, +# reference_name: 'my/staged/payload/handler' +# ] +# end +# end # # @param options [Hash{Symbol => Pathname}] # @option options [Pathname] :modules_pathname Pathname of `modules` directory underwhich payloads are defined on the diff --git a/spec/support/shared/examples/payload_can_be_instantiated.rb b/spec/support/shared/examples/payload_can_be_instantiated.rb index 39c9322e2d..561dbe3e1e 100644 --- a/spec/support/shared/examples/payload_can_be_instantiated.rb +++ b/spec/support/shared/examples/payload_can_be_instantiated.rb @@ -1,3 +1,43 @@ +# @note Requires use of 'untested payloads' shared context for tracking of `@actual_ancestor_reference_name_set`. +# +# Tests that the `:ancestor_reference_names` can be loaded from `:modules_pathname` and once the ancestors are loaded +# that `:reference_name` can be instantiated. +# +# @example Using 'payload can be instantiated' with `Metasploit::Framework::Spec::UntestedPayloads.define_task` and 'untested payloads' shared context +# # Rakefile +# require 'metasploit/framework/spec/untested_payloads' +# +# # defined spec task with rspec-rails +# My::Application.load_tasks +# # extends spec task to fail when there are untested payloads +# Metasploit::Framework::Spec::UntestedPayloads.define_task +# +# # spec/modules/payloads_spec.rb +# require 'spec_helper' +# +# describe 'modules/payloads' do +# modules_pathname = Pathname.new(__FILE__).parent.parent.parent.join('modules') +# +# include_context 'untested payloads', modules_pathname: modules_pathname +# +# context 'my/staged/payload/handler' do +# it_should_behave_like 'payload can be instantiated', +# ancestor_reference_names: [ +# 'stages/my/payload', +# 'stagers/my/payload/handler' +# ], +# modules_pathname: modules_pathname, +# reference_name: 'my/staged/payload/handler' +# end +# end +# +# @param options [Hash{Symbol => Array, Pathname, String}] +# @option options [Array] :ancestor_reference_names The reference names of the payload modules that are included +# in {Msf::Payload} to make the `:reference_name` payload. +# @option options [Pathname] :modules_pathname The `modules` directory from which to load `:ancestor_reference_names`. +# @option options [String] :reference_name The reference name for payload class that should be instantiated from mixing +# `:ancestor_reference_names`. +# @return [void] shared_examples_for 'payload can be instantiated' do |options| options.assert_valid_keys(:ancestor_reference_names, :modules_pathname, :reference_name)