diff --git a/Gemfile b/Gemfile index 0ef42b96510..a306853bc96 100644 --- a/Gemfile +++ b/Gemfile @@ -138,7 +138,6 @@ group :test, :development do gem 'rspec-rails', require: false gem 'shoulda', require: false gem 'rspec-html-matchers' - gem 'spork-rails' gem 'pry-nav' gem 'byebug', require: ENV['RM_INFO'].nil? end diff --git a/Gemfile.lock b/Gemfile.lock index 6d672a14289..64098d55e2c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -362,10 +362,6 @@ GEM redis (~> 3.3, >= 3.3.3) simple-rss (1.3.1) slop (3.6.0) - spork (1.0.0rc4) - spork-rails (4.0.0) - rails (>= 3.0.0, < 5) - spork (>= 1.0rc0) sprockets (3.7.1) concurrent-ruby (~> 1.0) rack (> 1, < 3) @@ -488,7 +484,6 @@ DEPENDENCIES shoulda sidekiq simple-rss - spork-rails stackprof test_after_commit thor diff --git a/lib/autospec/manager.rb b/lib/autospec/manager.rb index 857967031cf..6e611a550a7 100644 --- a/lib/autospec/manager.rb +++ b/lib/autospec/manager.rb @@ -52,13 +52,8 @@ class Autospec::Manager private def ruby_runner - if ENV["SPORK"] - require "autospec/spork_runner" - Autospec::SporkRunner.new - else - require "autospec/simple_runner" - Autospec::SimpleRunner.new - end + require "autospec/simple_runner" + Autospec::SimpleRunner.new end def javascript_runner diff --git a/lib/autospec/spork_runner.rb b/lib/autospec/spork_runner.rb deleted file mode 100644 index b8ae2c8627e..00000000000 --- a/lib/autospec/spork_runner.rb +++ /dev/null @@ -1,115 +0,0 @@ -require "drb/drb" -require "autospec/rspec_runner" - -module Autospec - - class SporkRunner < RspecRunner - - def start - if already_running?(pid_file) - puts "autospec appears to be running, it is possible the pid file is old" - puts "if you are sure it is not running, delete #{pid_file}" - return - end - write_pid_file(pid_file, Process.pid) - start_spork - @spork_running = true - end - - def running? - # launch a thread that will wait for spork to die - @monitor_thread ||= - Thread.new do - Process.wait(@spork_pid) - @spork_running = false - end - - @spork_running - end - - def run(specs) - args = ["-r", "#{File.dirname(__FILE__)}/formatter.rb", - "-f", "Autospec::Formatter", specs.split].flatten - spork_service.run(args, $stderr, $stdout) - end - - def reload - stop_spork - sleep 1 - start_spork - end - - def abort - spork_service.abort - end - - def stop - stop_spork - end - - private - - def spork_pid_file - Rails.root + "tmp/pids/spork.pid" - end - - def pid_file - Rails.root + "tmp/pids/autospec.pid" - end - - def already_running?(pid_file) - if File.exists? pid_file - pid = File.read(pid_file).to_i - Process.getpgid(pid) rescue nil - end - end - - def write_pid_file(file, pid) - FileUtils.mkdir_p(Rails.root + "tmp/pids") - File.open(file, 'w') do |f| - f.write(pid) - end - end - - def spork_running? - spork_service.port rescue nil - end - - def spork_service - unless @drb_listener_running - begin - DRb.start_service("druby://127.0.0.1:0") - rescue SocketError, Errno::EADDRNOTAVAIL - DRb.start_service("druby://:0") - end - @drb_listener_running = true - end - - @spork_service ||= DRbObject.new_with_uri("druby://127.0.0.1:8989") - end - - def start_spork - if already_running?(spork_pid_file) - puts "Killing old orphan spork instance" - stop_spork - sleep 1 - end - - @spork_pid = Process.spawn({ 'RAILS_ENV' => 'test' }, "bundle exec spork") - write_pid_file(spork_pid_file, @spork_pid) - - running = false - while !running - running = spork_running? - sleep 0.01 - end - end - - def stop_spork - pid = File.read(spork_pid_file).to_i - Process.kill("SIGTERM", pid) rescue nil - end - - end - -end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 0a983d995bd..50f2d38a251 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -4,217 +4,178 @@ if ENV['COVERAGE'] end require 'rubygems' -require 'spork' require 'rbtrace' -#uncomment the following line to use spork with the debugger -#require 'spork/ext/ruby-debug' -Spork.prefork do - # Loading more in this block will cause your tests to run faster. However, - # if you change any configuration or code from libraries loaded here, you'll - # need to restart spork for it take effect. - require 'fabrication' - require 'mocha/api' - require 'certified' - require 'webmock/rspec' +# Loading more in this block will cause your tests to run faster. However, +# if you change any configuration or code from libraries loaded here, you'll +# need to restart spork for it take effect. +require 'fabrication' +require 'mocha/api' +require 'certified' +require 'webmock/rspec' - ENV["RAILS_ENV"] ||= 'test' - require File.expand_path("../../config/environment", __FILE__) - require 'rspec/rails' - require 'shoulda' - require 'sidekiq/testing' +ENV["RAILS_ENV"] ||= 'test' +require File.expand_path("../../config/environment", __FILE__) +require 'rspec/rails' +require 'shoulda' +require 'sidekiq/testing' - # Requires supporting ruby files with custom matchers and macros, etc, - # in spec/support/ and its subdirectories. - Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f } - Dir[Rails.root.join("spec/fabricators/*.rb")].each { |f| require f } +# Requires supporting ruby files with custom matchers and macros, etc, +# in spec/support/ and its subdirectories. +Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f } +Dir[Rails.root.join("spec/fabricators/*.rb")].each { |f| require f } - # Require plugin helpers at plugin/[plugin]/spec/plugin_helper.rb (includes symlinked plugins). - if ENV['LOAD_PLUGINS'] == "1" - Dir[Rails.root.join("plugins/*/spec/plugin_helper.rb")].each do |f| - require f - end - end - - # let's not run seed_fu every test - SeedFu.quiet = true if SeedFu.respond_to? :quiet - - SiteSetting.automatically_download_gravatars = false - - SeedFu.seed - - RSpec.configure do |config| - config.fail_fast = ENV['RSPEC_FAIL_FAST'] == "1" - config.include Helpers - config.include MessageBus - config.include RSpecHtmlMatchers - config.include IntegrationHelpers, type: :request - config.mock_framework = :mocha - config.order = 'random' - config.infer_spec_type_from_file_location! - - # If you're not using ActiveRecord, or you'd prefer not to run each of your - # examples within a transaction, remove the following line or assign false - # instead of true. - config.use_transactional_fixtures = true - - # If true, the base class of anonymous controllers will be inferred - # automatically. This will be the default behavior in future versions of - # rspec-rails. - config.infer_base_class_for_anonymous_controllers = true - - config.before(:suite) do - Sidekiq.error_handlers.clear - - # Ugly, but needed until we have a user creator - User.skip_callback(:create, :after, :ensure_in_trust_level_group) - - DiscoursePluginRegistry.clear if ENV['LOAD_PLUGINS'] != "1" - Discourse.current_user_provider = TestCurrentUserProvider - - SiteSetting.refresh! - - # Rebase defaults - # - # We nuke the DB storage provider from site settings, so need to yank out the existing settings - # and pretend they are default. - # There are a bunch of settings that are seeded, they must be loaded as defaults - SiteSetting.current.each do |k, v| - # skip setting defaults for settings that are in unloaded plugins - SiteSetting.defaults.set_regardless_of_locale(k, v) if SiteSetting.respond_to? k - end - - require_dependency 'site_settings/local_process_provider' - SiteSetting.provider = SiteSettings::LocalProcessProvider.new - - WebMock.disable_net_connect! - end - - class DiscourseMockRedis < MockRedis - def without_namespace - self - end - - def delete_prefixed(prefix) - keys("#{prefix}*").each { |k| del(k) } - end - end - - config.before :each do |x| - # TODO not sure about this, we could use a mock redis implementation here: - # this gives us really clean "flush" semantics, howere the side-effect is that - # we are no longer using a clean redis implementation, a preferable solution may - # be simply flushing before tests, trouble is that redis may be reused with dev - # so that would mean the dev would act weird - # - # perf benefit seems low (shaves 20 secs off a 4 minute test suite) - # - # $redis = DiscourseMockRedis.new - # - PostActionNotifier.disable - SearchIndexer.disable - UserActionCreator.disable - NotificationEmailer.disable - - SiteSetting.provider.all.each do |setting| - SiteSetting.remove_override!(setting.name) - end - SiteSetting.defaults.site_locale = SiteSettings::DefaultsProvider::DEFAULT_LOCALE - - # very expensive IO operations - SiteSetting.automatically_download_gravatars = false - - Discourse.clear_readonly! - - I18n.locale = :en - end - - class TestCurrentUserProvider < Auth::DefaultCurrentUserProvider - def log_on_user(user, session, cookies) - session[:current_user_id] = user.id - super - end - - def log_off_user(session, cookies) - session[:current_user_id] = nil - super - end - end - - end - - class TrackTimeStub - def self.stubbed - false - end - end - - def freeze_time(now = Time.now) - datetime = DateTime.parse(now.to_s) - time = Time.parse(now.to_s) - - if block_given? - raise "nested freeze time not supported" if TrackTimeStub.stubbed - end - - DateTime.stubs(:now).returns(datetime) - Time.stubs(:now).returns(time) - Date.stubs(:today).returns(datetime.to_date) - TrackTimeStub.stubs(:stubbed).returns(true) - - if block_given? - begin - yield - ensure - unfreeze_time - end - end - end - - def unfreeze_time - DateTime.unstub(:now) - Time.unstub(:now) - Date.unstub(:today) - TrackTimeStub.unstub(:stubbed) - end - - def file_from_fixtures(filename, directory = "images") - FileUtils.mkdir_p("#{Rails.root}/tmp/spec") unless Dir.exists?("#{Rails.root}/tmp/spec") - FileUtils.cp("#{Rails.root}/spec/fixtures/#{directory}/#{filename}", "#{Rails.root}/tmp/spec/#{filename}") - File.new("#{Rails.root}/tmp/spec/#{filename}") +# Require plugin helpers at plugin/[plugin]/spec/plugin_helper.rb (includes symlinked plugins). +if ENV['LOAD_PLUGINS'] == "1" + Dir[Rails.root.join("plugins/*/spec/plugin_helper.rb")].each do |f| + require f end end -Spork.each_run do - # This code will be run each time you run your specs. - Discourse.after_fork +# let's not run seed_fu every test +SeedFu.quiet = true if SeedFu.respond_to? :quiet + +SiteSetting.automatically_download_gravatars = false + +SeedFu.seed + +RSpec.configure do |config| + config.fail_fast = ENV['RSPEC_FAIL_FAST'] == "1" + config.include Helpers + config.include MessageBus + config.include RSpecHtmlMatchers + config.include IntegrationHelpers, type: :request + config.mock_framework = :mocha + config.order = 'random' + config.infer_spec_type_from_file_location! + + # If you're not using ActiveRecord, or you'd prefer not to run each of your + # examples within a transaction, remove the following line or assign false + # instead of true. + config.use_transactional_fixtures = true + + # If true, the base class of anonymous controllers will be inferred + # automatically. This will be the default behavior in future versions of + # rspec-rails. + config.infer_base_class_for_anonymous_controllers = true + + config.before(:suite) do + Sidekiq.error_handlers.clear + + # Ugly, but needed until we have a user creator + User.skip_callback(:create, :after, :ensure_in_trust_level_group) + + DiscoursePluginRegistry.clear if ENV['LOAD_PLUGINS'] != "1" + Discourse.current_user_provider = TestCurrentUserProvider + + SiteSetting.refresh! + + # Rebase defaults + # + # We nuke the DB storage provider from site settings, so need to yank out the existing settings + # and pretend they are default. + # There are a bunch of settings that are seeded, they must be loaded as defaults + SiteSetting.current.each do |k, v| + # skip setting defaults for settings that are in unloaded plugins + SiteSetting.defaults.set_regardless_of_locale(k, v) if SiteSetting.respond_to? k + end + + require_dependency 'site_settings/local_process_provider' + SiteSetting.provider = SiteSettings::LocalProcessProvider.new + + WebMock.disable_net_connect! + end + + class DiscourseMockRedis < MockRedis + def without_namespace + self + end + + def delete_prefixed(prefix) + keys("#{prefix}*").each { |k| del(k) } + end + end + + config.before :each do |x| + # TODO not sure about this, we could use a mock redis implementation here: + # this gives us really clean "flush" semantics, howere the side-effect is that + # we are no longer using a clean redis implementation, a preferable solution may + # be simply flushing before tests, trouble is that redis may be reused with dev + # so that would mean the dev would act weird + # + # perf benefit seems low (shaves 20 secs off a 4 minute test suite) + # + # $redis = DiscourseMockRedis.new + # + PostActionNotifier.disable + SearchIndexer.disable + UserActionCreator.disable + NotificationEmailer.disable + + SiteSetting.provider.all.each do |setting| + SiteSetting.remove_override!(setting.name) + end + SiteSetting.defaults.site_locale = SiteSettings::DefaultsProvider::DEFAULT_LOCALE + + # very expensive IO operations + SiteSetting.automatically_download_gravatars = false + + Discourse.clear_readonly! + + I18n.locale = :en + end + + class TestCurrentUserProvider < Auth::DefaultCurrentUserProvider + def log_on_user(user, session, cookies) + session[:current_user_id] = user.id + super + end + + def log_off_user(session, cookies) + session[:current_user_id] = nil + super + end + end + end -# --- Instructions --- -# Sort the contents of this file into a Spork.prefork and a Spork.each_run -# block. -# -# The Spork.prefork block is run only once when the spork server is started. -# You typically want to place most of your (slow) initializer code in here, in -# particular, require'ing any 3rd-party gems that you don't normally modify -# during development. -# -# The Spork.each_run block is run each time you run your specs. In case you -# need to load files that tend to change during development, require them here. -# With Rails, your application modules are loaded automatically, so sometimes -# this block can remain empty. -# -# Note: You can modify files loaded *from* the Spork.each_run block without -# restarting the spork server. However, this file itself will not be reloaded, -# so if you change any of the code inside the each_run block, you still need to -# restart the server. In general, if you have non-trivial code in this file, -# it's advisable to move it into a separate file so you can easily edit it -# without restarting spork. (For example, with RSpec, you could move -# non-trivial code into a file spec/support/my_helper.rb, making sure that the -# spec/support/* files are require'd from inside the each_run block.) -# -# Any code that is left outside the two blocks will be run during preforking -# *and* during each_run -- that's probably not what you want. -# -# These instructions should self-destruct in 10 seconds. If they don't, feel -# free to delete them. +class TrackTimeStub + def self.stubbed + false + end +end + +def freeze_time(now = Time.now) + datetime = DateTime.parse(now.to_s) + time = Time.parse(now.to_s) + + if block_given? + raise "nested freeze time not supported" if TrackTimeStub.stubbed + end + + DateTime.stubs(:now).returns(datetime) + Time.stubs(:now).returns(time) + Date.stubs(:today).returns(datetime.to_date) + TrackTimeStub.stubs(:stubbed).returns(true) + + if block_given? + begin + yield + ensure + unfreeze_time + end + end +end + +def unfreeze_time + DateTime.unstub(:now) + Time.unstub(:now) + Date.unstub(:today) + TrackTimeStub.unstub(:stubbed) +end + +def file_from_fixtures(filename, directory = "images") + FileUtils.mkdir_p("#{Rails.root}/tmp/spec") unless Dir.exists?("#{Rails.root}/tmp/spec") + FileUtils.cp("#{Rails.root}/spec/fixtures/#{directory}/#{filename}", "#{Rails.root}/tmp/spec/#{filename}") + File.new("#{Rails.root}/tmp/spec/#{filename}") +end