diff --git a/.rspec b/.rspec new file mode 100644 index 0000000000..16f9cdb013 --- /dev/null +++ b/.rspec @@ -0,0 +1,2 @@ +--color +--format documentation diff --git a/Gemfile b/Gemfile index 2fcd3c2710..01703f0b04 100755 --- a/Gemfile +++ b/Gemfile @@ -2,14 +2,26 @@ source 'http://rubygems.org' # Need 3+ for ActiveSupport::Concern gem 'activesupport', '>= 3.0.0' +# Needed for Msf::DbManager +gem 'activerecord' +# Database models shared between framework and Pro. +gem 'metasploit_data_models', :git => 'git://github.com/rapid7/metasploit_data_models.git' # Needed for module caching in Mdm::ModuleDetails gem 'pg', '>= 0.11' group :development do - # running documentation generation tasks - gem 'rake' # Markdown formatting for yard gem 'redcarpet' # generating documentation gem 'yard' end + +group :development, :test do + # running documentation generation tasks and rspec tasks + gem 'rake' +end + +group :test do + # testing framework + gem 'rspec' +end diff --git a/Gemfile.lock b/Gemfile.lock index 2d7fe0b05b..a666ef8540 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,22 +1,62 @@ +GIT + remote: git://github.com/rapid7/metasploit_data_models.git + revision: dd6c3a31c5ad8b55f4913b5ba20307178ba9c7bf + specs: + metasploit_data_models (0.0.2) + activerecord + activesupport + pg + pry + GEM remote: http://rubygems.org/ specs: + activemodel (3.2.8) + activesupport (= 3.2.8) + builder (~> 3.0.0) + activerecord (3.2.8) + activemodel (= 3.2.8) + activesupport (= 3.2.8) + arel (~> 3.0.2) + tzinfo (~> 0.3.29) activesupport (3.2.8) i18n (~> 0.6) multi_json (~> 1.0) + arel (3.0.2) + builder (3.0.3) + coderay (1.0.8) + diff-lcs (1.1.3) i18n (0.6.1) + method_source (0.8) multi_json (1.3.6) pg (0.14.1) + pry (0.9.10) + coderay (~> 1.0.5) + method_source (~> 0.8) + slop (~> 3.3.1) rake (0.9.2.2) redcarpet (2.1.1) + rspec (2.11.0) + rspec-core (~> 2.11.0) + rspec-expectations (~> 2.11.0) + rspec-mocks (~> 2.11.0) + rspec-core (2.11.1) + rspec-expectations (2.11.3) + diff-lcs (~> 1.1.3) + rspec-mocks (2.11.3) + slop (3.3.3) + tzinfo (0.3.33) yard (0.8.2.1) PLATFORMS ruby DEPENDENCIES + activerecord activesupport (>= 3.0.0) + metasploit_data_models! pg (>= 0.11) rake redcarpet + rspec yard diff --git a/Rakefile b/Rakefile index d21d5d6ddd..aea3251b40 100644 --- a/Rakefile +++ b/Rakefile @@ -1,7 +1,12 @@ require 'bundler/setup' +require 'rspec/core/rake_task' require 'yard' +RSpec::Core::RakeTask.new(:spec) + +task :default => :spec + namespace :yard do yard_files = [ # Ruby source files first diff --git a/lib/msf/core/db_manager.rb b/lib/msf/core/db_manager.rb index 63783a8005..3c8fcee761 100644 --- a/lib/msf/core/db_manager.rb +++ b/lib/msf/core/db_manager.rb @@ -1,6 +1,7 @@ # -*- coding: binary -*- require "active_record" +require 'msf/base/config' require 'msf/core' require 'msf/core/db' require 'msf/core/task_manager' diff --git a/lib/msf/core/module_manager/module_paths.rb b/lib/msf/core/module_manager/module_paths.rb index 3c50599fd8..3a87dc04df 100644 --- a/lib/msf/core/module_manager/module_paths.rb +++ b/lib/msf/core/module_manager/module_paths.rb @@ -15,24 +15,22 @@ module Msf::ModuleManager::ModulePaths nested_paths = [] # remove trailing file separator - path.sub!(/#{File::SEPARATOR}$/, '') + path_without_trailing_file_separator = path.sub(/#{File::SEPARATOR}$/, '') - pathname = Pathname.new(path) + # Make the path completely canonical + pathname = Pathname.new(path_without_trailing_file_separator).expand_path extension = pathname.extname if extension == Msf::Modules::Loader::Archive::ARCHIVE_EXTENSION unless pathname.exist? - raise RuntimeError, "The path supplied does not exist", caller + raise ArgumentError, "The path supplied does not exist", caller end - nested_paths << pathname.expand_path.to_s + nested_paths << pathname.to_s else - # Make the path completely canonical - pathname = Pathname.new(path).expand_path - # Make sure the path is a valid directory unless pathname.directory? - raise RuntimeError, "The path supplied is not a valid directory.", caller + raise ArgumentError, "The path supplied is not a valid directory.", caller end nested_paths << pathname.to_s @@ -41,7 +39,7 @@ module Msf::ModuleManager::ModulePaths fastlib_glob = pathname.join('**', "*#{Msf::Modules::Loader::Archive::ARCHIVE_EXTENSION}") Dir.glob(fastlib_glob).each do |fastlib_path| - nested_pathnames << fastlib_path + nested_paths << fastlib_path end end diff --git a/spec/msf/core/module_manager_spec.rb b/spec/msf/core/module_manager_spec.rb new file mode 100644 index 0000000000..78730a8c66 --- /dev/null +++ b/spec/msf/core/module_manager_spec.rb @@ -0,0 +1,110 @@ +require 'spec_helper' + +# +# Core +# + +# Temporary files +require 'tempfile' +# add mktmpdir to Dir +require 'tmpdir' + +# +# Project +# + +require 'msf/core' + +describe Msf::ModuleManager do + let(:archive_basename) do + [basename_prefix, archive_extension] + end + + let(:archive_extension) do + '.fastlib' + end + + let(:basename_prefix) do + 'rspec' + end + + let(:framework) do + Msf::Framework.new + end + + subject do + described_class.new(framework) + end + + context '#add_module_path' do + it 'should strip trailing File::SEPARATOR from the path' do + Dir.mktmpdir do |path| + path_with_trailing_separator = path + File::SEPARATOR + subject.add_module_path(path_with_trailing_separator) + + subject.send(:module_paths).should_not include(path_with_trailing_separator) + subject.send(:module_paths).should include(path) + end + end + + context 'with Fastlib archive' do + it 'should raise an ArgumentError unless the File exists' do + file = Tempfile.new(archive_basename) + # unlink will clear path, so copy it to a variable + path = file.path + file.unlink + + File.exist?(path).should be_false + + expect { + subject.add_module_path(path) + }.to raise_error(ArgumentError, "The path supplied does not exist") + end + + it 'should add the path to #module_paths if the File exists' do + Tempfile.open(archive_basename) do |temporary_file| + path = temporary_file.path + + File.exist?(path).should be_true + + subject.add_module_path(path) + + subject.send(:module_paths).should include(path) + end + end + end + + context 'with directory' do + it 'should add path to #module_paths' do + Dir.mktmpdir do |path| + subject.add_module_path(path) + + subject.send(:module_paths).should include(path) + end + end + + context 'containing Fastlib archives' do + it 'should add each Fastlib archive to #module_paths' do + Dir.mktmpdir do |directory| + Tempfile.open(archive_basename, directory) do |file| + subject.add_module_path(directory) + + subject.send(:module_paths).should include(directory) + subject.send(:module_paths).should include(file.path) + end + end + end + end + end + + context 'with other file' do + it 'should raise ArgumentError' do + Tempfile.open(basename_prefix) do |file| + expect { + subject.add_module_path(file.path) + }.to raise_error(ArgumentError, 'The path supplied is not a valid directory.') + end + end + end + end +end \ No newline at end of file diff --git a/spec/msf/database_manager_spec.rb b/spec/msf/database_manager_spec.rb deleted file mode 100644 index 957c1b1bbe..0000000000 --- a/spec/msf/database_manager_spec.rb +++ /dev/null @@ -1,7 +0,0 @@ -require "spec_helper" - -module Msf - describe DBManager do - - end -end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 3d72003677..f62338294f 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1 +1,24 @@ -require "../lib/msf/core.rb" +require 'rubygems' +require 'bundler' +Bundler.setup(:default, :test) + +# add project lib directory to load path +spec_pathname = Pathname.new(__FILE__).dirname +root_pathname = spec_pathname.join('..').expand_path +lib_pathname = root_pathname.join('lib') +$LOAD_PATH.unshift(lib_pathname.to_s) + +require 'rspec/core' + +# Requires supporting ruby files with custom matchers and macros, etc, +# in spec/support/ and its subdirectories. +support_glob = root_pathname.join('spec', 'support', '**', '*.rb') + +Dir.glob(support_glob) do |path| + require path +end + +RSpec.configure do |config| + config.mock_with :rspec +end +