diff --git a/app/controllers/concerns/transcoded_stream_concern.rb b/app/controllers/concerns/transcoded_stream_concern.rb index e95a9b9a..5f573115 100644 --- a/app/controllers/concerns/transcoded_stream_concern.rb +++ b/app/controllers/concerns/transcoded_stream_concern.rb @@ -42,12 +42,12 @@ def find_cache end def valid_cache? - return unless File.exist?(@stream.transcode_cache_file_path) - # Compare duration of cache file and original file to check integrity of cache file. # Because the different format of the file, the duration will have a little difference, # so the duration difference in two seconds are considered no problem. cache_file_tag = WahWah.open(@stream.transcode_cache_file_path) (@stream.duration - cache_file_tag.duration).abs <= 2 + rescue + false end end diff --git a/test/application_system_test_case.rb b/test/application_system_test_case.rb index 01d79ba4..0596a152 100644 --- a/test/application_system_test_case.rb +++ b/test/application_system_test_case.rb @@ -9,7 +9,8 @@ class ApplicationSystemTestCase < ActionDispatch::SystemTestCase driven_by :cuprite, screen_size: [1400, 900], options: { browser_options: {"no-sandbox": nil}, url_blacklist: ["https://www.gravatar.com"], - timeout: 10 + timeout: 10, + process_timeout: 20 } def login_as(user) diff --git a/test/controllers/api/v1/transcoded_stream_controller_test.rb b/test/controllers/api/v1/transcoded_stream_controller_test.rb index bf06c211..80218e79 100644 --- a/test/controllers/api/v1/transcoded_stream_controller_test.rb +++ b/test/controllers/api/v1/transcoded_stream_controller_test.rb @@ -3,79 +3,109 @@ require "test_helper" class Api::V1::TranscodedStreamControllerTest < ActionDispatch::IntegrationTest + class StreamMock < Stream + def initialize(song) + super(song) + @tmp_cache_file = Tempfile.new(["", ".#{TRANSCODE_FORMAT}"]) + end + + def transcode_cache_file_path + @tmp_cache_file.path + end + + def close_tmp_cache_file + @tmp_cache_file.close + @tmp_cache_file.unlink + end + end + setup do + @stream_mock = StreamMock.new(songs(:flac_sample)) @user = users(:visitor1) + end - cache_directory = "#{Stream::TRANSCODE_CACHE_DIRECTORY}/#{songs(:flac_sample).id}" - if Dir.exist?(cache_directory) - FileUtils.remove_dir(cache_directory) - end + teardown do + @stream_mock.close_tmp_cache_file end test "should get new stream for transcode format" do - get new_api_v1_transcoded_stream_url(song_id: songs(:flac_sample).id), headers: api_token_header(@user) - assert_response :success + Stream.stub(:new, @stream_mock) do + get new_api_v1_transcoded_stream_url(song_id: songs(:flac_sample).id), headers: api_token_header(@user) + assert_response :success + end end test "should get transcoded data" do - get new_api_v1_transcoded_stream_url(song_id: songs(:flac_sample).id), headers: api_token_header(@user) + Stream.stub(:new, @stream_mock) do + get new_api_v1_transcoded_stream_url(song_id: songs(:flac_sample).id), headers: api_token_header(@user) - create_tmp_file(format: "mp3") do |tmp_file_path| - File.write(tmp_file_path, response.body) + create_tmp_file(format: "mp3") do |tmp_file_path| + File.write(tmp_file_path, response.body) - assert_equal 128, audio_bitrate(tmp_file_path) + assert_equal 128, audio_bitrate(tmp_file_path) + end end end test "should write cache when don't find cache" do - stream = Stream.new(songs(:flac_sample)) - assert_not File.exist? stream.transcode_cache_file_path + Stream.stub(:new, @stream_mock) do + stream = Stream.new(songs(:flac_sample)) + assert File.empty? stream.transcode_cache_file_path - get new_api_v1_transcoded_stream_url(song_id: songs(:flac_sample).id), headers: api_token_header(@user) + get new_api_v1_transcoded_stream_url(song_id: songs(:flac_sample).id), headers: api_token_header(@user) - assert_response :success - assert File.exist? stream.transcode_cache_file_path + assert_response :success + assert_not File.empty? stream.transcode_cache_file_path + end end test "should send cached transcoded stream file when found cache" do - get new_api_v1_transcoded_stream_url(song_id: songs(:flac_sample).id), headers: api_token_header(@user) - assert_response :success + Stream.stub(:new, @stream_mock) do + get new_api_v1_transcoded_stream_url(song_id: songs(:flac_sample).id), headers: api_token_header(@user) + assert_response :success - get new_api_v1_transcoded_stream_url(song_id: songs(:flac_sample).id), headers: api_token_header(@user) - assert_equal binary_data(Stream.new(songs(:flac_sample)).transcode_cache_file_path), response.body + get new_api_v1_transcoded_stream_url(song_id: songs(:flac_sample).id), headers: api_token_header(@user) + assert_equal binary_data(Stream.new(songs(:flac_sample)).transcode_cache_file_path), response.body + end end test "should send cached transcoded stream file when found cache and send file with nginx" do - get new_api_v1_transcoded_stream_url(song_id: songs(:flac_sample).id), headers: api_token_header(@user) - assert_response :success - - with_env("NGINX_SENDFILE" => "true") do + Stream.stub(:new, @stream_mock) do get new_api_v1_transcoded_stream_url(song_id: songs(:flac_sample).id), headers: api_token_header(@user) - assert_equal "/private_cache_media/2/ZmxhY19zYW1wbGVfbWQ1X2hhc2g=_128.mp3", @response.get_header("X-Accel-Redirect") - assert_equal "audio/mpeg", @response.get_header("Content-Type") + assert_response :success + + with_env("NGINX_SENDFILE" => "true") do + get new_api_v1_transcoded_stream_url(song_id: songs(:flac_sample).id), headers: api_token_header(@user) + assert_equal "/private_cache_media#{@stream_mock.transcode_cache_file_path}", @response.get_header("X-Accel-Redirect") + assert_equal "audio/mpeg", @response.get_header("Content-Type") + end end end test "should regenerate new cache when cache is invalid" do - stream = Stream.new(songs(:flac_sample)) + Stream.stub(:new, @stream_mock) do + stream = Stream.new(songs(:flac_sample)) - get new_api_v1_transcoded_stream_url(song_id: songs(:flac_sample).id), headers: api_token_header(@user) - assert_response :success + get new_api_v1_transcoded_stream_url(song_id: songs(:flac_sample).id), headers: api_token_header(@user) + assert_response :success - original_cache_file_mtime = File.mtime(stream.transcode_cache_file_path) + original_cache_file_mtime = File.mtime(stream.transcode_cache_file_path) - # Make the duration of the song different from the duration of the cache, - # so that the cache will be treated as invalid - songs(:flac_sample).update(duration: 12.0) + # Make the duration of the song different from the duration of the cache, + # so that the cache will be treated as invalid + songs(:flac_sample).update(duration: 12.0) - get new_api_v1_transcoded_stream_url(song_id: songs(:flac_sample).id), headers: api_token_header(@user) - assert_response :success + get new_api_v1_transcoded_stream_url(song_id: songs(:flac_sample).id), headers: api_token_header(@user) + assert_response :success - assert_not_equal original_cache_file_mtime, File.mtime(stream.transcode_cache_file_path) + assert_not_equal original_cache_file_mtime, File.mtime(stream.transcode_cache_file_path) + end end test "should set correct content type header" do - get new_api_v1_transcoded_stream_url(song_id: songs(:flac_sample).id), headers: api_token_header(@user) - assert_equal "audio/mpeg", @response.get_header("Content-Type") + Stream.stub(:new, @stream_mock) do + get new_api_v1_transcoded_stream_url(song_id: songs(:flac_sample).id), headers: api_token_header(@user) + assert_equal "audio/mpeg", @response.get_header("Content-Type") + end end end diff --git a/test/models/media_listener_test.rb b/test/models/media_listener_test.rb index b569978c..a06f6dda 100644 --- a/test/models/media_listener_test.rb +++ b/test/models/media_listener_test.rb @@ -3,20 +3,13 @@ require "test_helper" class MediaListenerTest < ActiveSupport::TestCase - teardown do - MediaListener.stop - end + test "running listener" do + assert_not MediaListener.running? - test "start listening" do MediaListener.start - assert MediaListener.running? - end - test "stop listening" do - MediaListener.start MediaListener.stop - assert_not MediaListener.running? end end diff --git a/test/test_helper.rb b/test/test_helper.rb index 842ed571..ff8c4314 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -39,6 +39,19 @@ class ActiveSupport::TestCase include Turbo::Broadcastable::TestHelper + + # Run tests in parallel with specified workers + parallelize(workers: :number_of_processors) + + # Fix SimpleCov to work with parallel tests, see: https://github.com/simplecov-ruby/simplecov/issues/718#issuecomment-538201587 + parallelize_setup do |worker| + SimpleCov.command_name "#{SimpleCov.command_name}-#{worker}" + end + + parallelize_teardown do |worker| + SimpleCov.result + end + # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order. fixtures :all