From ae7c20b00cdfcb4d2a4e8eaacb008c227d838115 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 7 Nov 2023 10:25:49 -0500 Subject: [PATCH] Move search and streaming spec manager classes to separate support files (#27727) --- spec/spec_helper.rb | 119 ----------------------- spec/support/search_data_manager.rb | 43 ++++++++ spec/support/streaming_server_manager.rb | 78 +++++++++++++++ 3 files changed, 121 insertions(+), 119 deletions(-) create mode 100644 spec/support/search_data_manager.rb create mode 100644 spec/support/streaming_server_manager.rb diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 39c4abe5c9..7c97d85953 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -71,122 +71,3 @@ def expect_push_bulk_to_match(klass, matcher) 'args' => matcher, })) end - -class StreamingServerManager - @running_thread = nil - - def initialize - at_exit { stop } - end - - def start(port: 4020) - return if @running_thread - - queue = Queue.new - - @queue = queue - - @running_thread = Thread.new do - Open3.popen2e( - { - 'REDIS_NAMESPACE' => ENV.fetch('REDIS_NAMESPACE'), - 'DB_NAME' => "#{ENV.fetch('DB_NAME', 'mastodon')}_test#{ENV.fetch('TEST_ENV_NUMBER', '')}", - 'RAILS_ENV' => ENV.fetch('RAILS_ENV', 'test'), - 'NODE_ENV' => ENV.fetch('STREAMING_NODE_ENV', 'development'), - 'PORT' => port.to_s, - }, - 'node index.js', # must not call yarn here, otherwise it will fail because yarn does not send signals to its child process - chdir: Rails.root.join('streaming') - ) do |_stdin, stdout_err, process_thread| - status = :starting - - # Spawn a thread to listen on streaming server output - output_thread = Thread.new do - stdout_err.each_line do |line| - Rails.logger.info "Streaming server: #{line}" - - if status == :starting && line.match('Streaming API now listening on') - status = :started - @queue.enq 'started' - end - end - end - - # And another thread to listen on commands from the main thread - loop do - msg = queue.pop - - case msg - when 'stop' - # we need to properly stop the reading thread - output_thread.kill - - # Then stop the node process - Process.kill('KILL', process_thread.pid) - - # And we stop ourselves - @running_thread.kill - end - end - end - end - - # wait for 10 seconds for the streaming server to start - Timeout.timeout(10) do - loop do - break if @queue.pop == 'started' - end - end - end - - def stop - return unless @running_thread - - @queue.enq 'stop' - - # Wait for the thread to end - @running_thread.join - end -end - -class SearchDataManager - def prepare_test_data - 4.times do |i| - username = "search_test_account_#{i}" - account = Fabricate.create(:account, username: username, indexable: i.even?, discoverable: i.even?, note: "Lover of #{i}.") - 2.times do |j| - Fabricate.create(:status, account: account, text: "#{username}'s #{j} post", visibility: j.even? ? :public : :private) - end - end - - 3.times do |i| - Fabricate.create(:tag, name: "search_test_tag_#{i}") - end - end - - def indexes - [ - AccountsIndex, - PublicStatusesIndex, - StatusesIndex, - TagsIndex, - ] - end - - def populate_indexes - indexes.each do |index_class| - index_class.purge! - index_class.import! - end - end - - def remove_indexes - indexes.each(&:delete!) - end - - def cleanup_test_data - Status.destroy_all - Account.destroy_all - Tag.destroy_all - end -end diff --git a/spec/support/search_data_manager.rb b/spec/support/search_data_manager.rb new file mode 100644 index 0000000000..24c95ae069 --- /dev/null +++ b/spec/support/search_data_manager.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +class SearchDataManager + def prepare_test_data + 4.times do |i| + username = "search_test_account_#{i}" + account = Fabricate.create(:account, username: username, indexable: i.even?, discoverable: i.even?, note: "Lover of #{i}.") + 2.times do |j| + Fabricate.create(:status, account: account, text: "#{username}'s #{j} post", visibility: j.even? ? :public : :private) + end + end + + 3.times do |i| + Fabricate.create(:tag, name: "search_test_tag_#{i}") + end + end + + def indexes + [ + AccountsIndex, + PublicStatusesIndex, + StatusesIndex, + TagsIndex, + ] + end + + def populate_indexes + indexes.each do |index_class| + index_class.purge! + index_class.import! + end + end + + def remove_indexes + indexes.each(&:delete!) + end + + def cleanup_test_data + Status.destroy_all + Account.destroy_all + Tag.destroy_all + end +end diff --git a/spec/support/streaming_server_manager.rb b/spec/support/streaming_server_manager.rb new file mode 100644 index 0000000000..93e1a6d17f --- /dev/null +++ b/spec/support/streaming_server_manager.rb @@ -0,0 +1,78 @@ +# frozen_string_literal: true + +class StreamingServerManager + @running_thread = nil + + def initialize + at_exit { stop } + end + + def start(port: 4020) + return if @running_thread + + queue = Queue.new + + @queue = queue + + @running_thread = Thread.new do + Open3.popen2e( + { + 'REDIS_NAMESPACE' => ENV.fetch('REDIS_NAMESPACE'), + 'DB_NAME' => "#{ENV.fetch('DB_NAME', 'mastodon')}_test#{ENV.fetch('TEST_ENV_NUMBER', '')}", + 'RAILS_ENV' => ENV.fetch('RAILS_ENV', 'test'), + 'NODE_ENV' => ENV.fetch('STREAMING_NODE_ENV', 'development'), + 'PORT' => port.to_s, + }, + 'node index.js', # must not call yarn here, otherwise it will fail because yarn does not send signals to its child process + chdir: Rails.root.join('streaming') + ) do |_stdin, stdout_err, process_thread| + status = :starting + + # Spawn a thread to listen on streaming server output + output_thread = Thread.new do + stdout_err.each_line do |line| + Rails.logger.info "Streaming server: #{line}" + + if status == :starting && line.match('Streaming API now listening on') + status = :started + @queue.enq 'started' + end + end + end + + # And another thread to listen on commands from the main thread + loop do + msg = queue.pop + + case msg + when 'stop' + # we need to properly stop the reading thread + output_thread.kill + + # Then stop the node process + Process.kill('KILL', process_thread.pid) + + # And we stop ourselves + @running_thread.kill + end + end + end + end + + # wait for 10 seconds for the streaming server to start + Timeout.timeout(10) do + loop do + break if @queue.pop == 'started' + end + end + end + + def stop + return unless @running_thread + + @queue.enq 'stop' + + # Wait for the thread to end + @running_thread.join + end +end