diff options
Diffstat (limited to 'activestorage/test/service')
-rw-r--r-- | activestorage/test/service/azure_storage_service_test.rb | 13 | ||||
-rw-r--r-- | activestorage/test/service/configurations.yml | 30 | ||||
-rw-r--r-- | activestorage/test/service/configurator_test.rb | 14 | ||||
-rw-r--r-- | activestorage/test/service/disk_service_test.rb | 12 | ||||
-rw-r--r-- | activestorage/test/service/gcs_service_test.rb | 44 | ||||
-rw-r--r-- | activestorage/test/service/mirror_service_test.rb | 62 | ||||
-rw-r--r-- | activestorage/test/service/s3_service_test.rb | 57 | ||||
-rw-r--r-- | activestorage/test/service/shared_service_tests.rb | 67 |
8 files changed, 299 insertions, 0 deletions
diff --git a/activestorage/test/service/azure_storage_service_test.rb b/activestorage/test/service/azure_storage_service_test.rb new file mode 100644 index 0000000000..e2be510b60 --- /dev/null +++ b/activestorage/test/service/azure_storage_service_test.rb @@ -0,0 +1,13 @@ +require "service/shared_service_tests" +require "uri" + +if SERVICE_CONFIGURATIONS[:azure] + class ActiveStorage::Service::AzureStorageServiceTest < ActiveSupport::TestCase + SERVICE = ActiveStorage::Service.configure(:azure, SERVICE_CONFIGURATIONS) + + include ActiveStorage::Service::SharedServiceTests + end + +else + puts "Skipping Azure Storage Service tests because no Azure configuration was supplied" +end diff --git a/activestorage/test/service/configurations.yml b/activestorage/test/service/configurations.yml new file mode 100644 index 0000000000..d7aa672573 --- /dev/null +++ b/activestorage/test/service/configurations.yml @@ -0,0 +1,30 @@ +s3: + service: S3 + access_key_id: <%= ENV["AWS_ACCESS_KEY_ID"] %> + secret_access_key: <%= ENV["AWS_SECRET_KEY"] %> + region: us-east-2 + bucket: rails-ci-activestorage + +# gcs: +# service: GCS +# keyfile: { +# type: "service_account", +# project_id: "", +# private_key_id: "", +# private_key: "", +# client_email: "", +# client_id: "", +# auth_uri: "https://accounts.google.com/o/oauth2/auth", +# token_uri: "https://accounts.google.com/o/oauth2/token", +# auth_provider_x509_cert_url: "https://www.googleapis.com/oauth2/v1/certs", +# client_x509_cert_url: "" +# } +# project: +# bucket: +# +# azure: +# service: AzureStorage +# path: "" +# storage_account_name: "" +# storage_access_key: "" +# container: "" diff --git a/activestorage/test/service/configurator_test.rb b/activestorage/test/service/configurator_test.rb new file mode 100644 index 0000000000..c69b8d5087 --- /dev/null +++ b/activestorage/test/service/configurator_test.rb @@ -0,0 +1,14 @@ +require "service/shared_service_tests" + +class ActiveStorage::Service::ConfiguratorTest < ActiveSupport::TestCase + test "builds correct service instance based on service name" do + service = ActiveStorage::Service::Configurator.build(:foo, foo: { service: "Disk", root: "path" }) + assert_instance_of ActiveStorage::Service::DiskService, service + end + + test "raises error when passing non-existent service name" do + assert_raise RuntimeError do + ActiveStorage::Service::Configurator.build(:bigfoot, {}) + end + end +end diff --git a/activestorage/test/service/disk_service_test.rb b/activestorage/test/service/disk_service_test.rb new file mode 100644 index 0000000000..a625521601 --- /dev/null +++ b/activestorage/test/service/disk_service_test.rb @@ -0,0 +1,12 @@ +require "service/shared_service_tests" + +class ActiveStorage::Service::DiskServiceTest < ActiveSupport::TestCase + SERVICE = ActiveStorage::Service::DiskService.new(root: File.join(Dir.tmpdir, "active_storage")) + + include ActiveStorage::Service::SharedServiceTests + + test "url generation" do + assert_match /rails\/active_storage\/disk\/.*\/avatar\.png\?.+disposition=inline/, + @service.url(FIXTURE_KEY, expires_in: 5.minutes, disposition: :inline, filename: "avatar.png", content_type: "image/png") + end +end diff --git a/activestorage/test/service/gcs_service_test.rb b/activestorage/test/service/gcs_service_test.rb new file mode 100644 index 0000000000..03048731bc --- /dev/null +++ b/activestorage/test/service/gcs_service_test.rb @@ -0,0 +1,44 @@ +require "service/shared_service_tests" +require "net/http" + +if SERVICE_CONFIGURATIONS[:gcs] + class ActiveStorage::Service::GCSServiceTest < ActiveSupport::TestCase + SERVICE = ActiveStorage::Service.configure(:gcs, SERVICE_CONFIGURATIONS) + + include ActiveStorage::Service::SharedServiceTests + + test "direct upload" do + begin + key = SecureRandom.base58(24) + data = "Something else entirely!" + checksum = Digest::MD5.base64digest(data) + url = @service.url_for_direct_upload(key, expires_in: 5.minutes, content_type: "text/plain", content_length: data.size, checksum: checksum) + + uri = URI.parse url + request = Net::HTTP::Put.new uri.request_uri + request.body = data + request.add_field "Content-Type", "text/plain" + request.add_field "Content-MD5", checksum + Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http| + http.request request + end + + assert_equal data, @service.download(key) + ensure + @service.delete key + end + end + + test "signed URL generation" do + freeze_time do + url = SERVICE.bucket.signed_url(FIXTURE_KEY, expires: 120) + + "&response-content-disposition=inline%3B+filename%3D%22test.txt%22" + + "&response-content-type=text%2Fplain" + + assert_equal url, @service.url(FIXTURE_KEY, expires_in: 2.minutes, disposition: :inline, filename: "test.txt", content_type: "text/plain") + end + end + end +else + puts "Skipping GCS Service tests because no GCS configuration was supplied" +end diff --git a/activestorage/test/service/mirror_service_test.rb b/activestorage/test/service/mirror_service_test.rb new file mode 100644 index 0000000000..129e11d06f --- /dev/null +++ b/activestorage/test/service/mirror_service_test.rb @@ -0,0 +1,62 @@ +require "service/shared_service_tests" + +class ActiveStorage::Service::MirrorServiceTest < ActiveSupport::TestCase + mirror_config = (1..3).map do |i| + [ "mirror_#{i}", + service: "Disk", + root: Dir.mktmpdir("active_storage_tests_mirror_#{i}") ] + end.to_h + + config = mirror_config.merge \ + mirror: { service: "Mirror", primary: "primary", mirrors: mirror_config.keys }, + primary: { service: "Disk", root: Dir.mktmpdir("active_storage_tests_primary") } + + SERVICE = ActiveStorage::Service.configure :mirror, config + + include ActiveStorage::Service::SharedServiceTests + + test "uploading to all services" do + begin + data = "Something else entirely!" + key = upload(data, to: @service) + + assert_equal data, SERVICE.primary.download(key) + SERVICE.mirrors.each do |mirror| + assert_equal data, mirror.download(key) + end + ensure + @service.delete key + end + end + + test "downloading from primary service" do + data = "Something else entirely!" + key = upload(data, to: SERVICE.primary) + + assert_equal data, @service.download(key) + end + + test "deleting from all services" do + @service.delete FIXTURE_KEY + assert_not SERVICE.primary.exist?(FIXTURE_KEY) + SERVICE.mirrors.each do |mirror| + assert_not mirror.exist?(FIXTURE_KEY) + end + end + + test "URL generation in primary service" do + freeze_time do + assert_equal SERVICE.primary.url(FIXTURE_KEY, expires_in: 2.minutes, disposition: :inline, filename: "test.txt", content_type: "text/plain"), + @service.url(FIXTURE_KEY, expires_in: 2.minutes, disposition: :inline, filename: "test.txt", content_type: "text/plain") + end + end + + private + def upload(data, to:) + SecureRandom.base58(24).tap do |key| + io = StringIO.new(data).tap(&:read) + @service.upload key, io, checksum: Digest::MD5.base64digest(data) + assert io.eof? + end + end +end diff --git a/activestorage/test/service/s3_service_test.rb b/activestorage/test/service/s3_service_test.rb new file mode 100644 index 0000000000..6d613fd4fc --- /dev/null +++ b/activestorage/test/service/s3_service_test.rb @@ -0,0 +1,57 @@ +require "service/shared_service_tests" +require "net/http" + +if SERVICE_CONFIGURATIONS[:s3] && SERVICE_CONFIGURATIONS[:s3][:access_key_id].present? + class ActiveStorage::Service::S3ServiceTest < ActiveSupport::TestCase + SERVICE = ActiveStorage::Service.configure(:s3, SERVICE_CONFIGURATIONS) + + include ActiveStorage::Service::SharedServiceTests + + test "direct upload" do + begin + key = SecureRandom.base58(24) + data = "Something else entirely!" + checksum = Digest::MD5.base64digest(data) + url = @service.url_for_direct_upload(key, expires_in: 5.minutes, content_type: "text/plain", content_length: data.size, checksum: checksum) + + uri = URI.parse url + request = Net::HTTP::Put.new uri.request_uri + request.body = data + request.add_field "Content-Type", "text/plain" + request.add_field "Content-MD5", checksum + Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http| + http.request request + end + + assert_equal data, @service.download(key) + ensure + @service.delete key + end + end + + test "signed URL generation" do + url = @service.url(FIXTURE_KEY, expires_in: 5.minutes, + disposition: :inline, filename: "avatar.png", content_type: "image/png") + + assert_match /s3\.(\S+)?amazonaws.com.*response-content-disposition=inline.*avatar\.png.*response-content-type=image%2Fpng/, url + assert_match SERVICE_CONFIGURATIONS[:s3][:bucket], url + end + + test "uploading with server-side encryption" do + config = SERVICE_CONFIGURATIONS.deep_merge(s3: { upload: { server_side_encryption: "AES256" } }) + service = ActiveStorage::Service.configure(:s3, config) + + begin + key = SecureRandom.base58(24) + data = "Something else entirely!" + service.upload key, StringIO.new(data), checksum: Digest::MD5.base64digest(data) + + assert_equal "AES256", service.bucket.object(key).server_side_encryption + ensure + service.delete key + end + end + end +else + puts "Skipping S3 Service tests because no S3 configuration was supplied" +end diff --git a/activestorage/test/service/shared_service_tests.rb b/activestorage/test/service/shared_service_tests.rb new file mode 100644 index 0000000000..07620d91e4 --- /dev/null +++ b/activestorage/test/service/shared_service_tests.rb @@ -0,0 +1,67 @@ +require "test_helper" +require "active_support/core_ext/securerandom" + +module ActiveStorage::Service::SharedServiceTests + extend ActiveSupport::Concern + + FIXTURE_KEY = SecureRandom.base58(24) + FIXTURE_DATA = "\211PNG\r\n\032\n\000\000\000\rIHDR\000\000\000\020\000\000\000\020\001\003\000\000\000%=m\"\000\000\000\006PLTE\000\000\000\377\377\377\245\331\237\335\000\000\0003IDATx\234c\370\377\237\341\377_\206\377\237\031\016\2603\334?\314p\1772\303\315\315\f7\215\031\356\024\203\320\275\317\f\367\201R\314\f\017\300\350\377\177\000Q\206\027(\316]\233P\000\000\000\000IEND\256B`\202".force_encoding(Encoding::BINARY) + + included do + setup do + @service = self.class.const_get(:SERVICE) + @service.upload FIXTURE_KEY, StringIO.new(FIXTURE_DATA) + end + + teardown do + @service.delete FIXTURE_KEY + end + + test "uploading with integrity" do + begin + key = SecureRandom.base58(24) + data = "Something else entirely!" + @service.upload(key, StringIO.new(data), checksum: Digest::MD5.base64digest(data)) + + assert_equal data, @service.download(key) + ensure + @service.delete key + end + end + + test "uploading without integrity" do + begin + key = SecureRandom.base58(24) + data = "Something else entirely!" + + assert_raises(ActiveStorage::IntegrityError) do + @service.upload(key, StringIO.new(data), checksum: Digest::MD5.base64digest("bad data")) + end + + assert_not @service.exist?(key) + ensure + @service.delete key + end + end + + test "downloading" do + assert_equal FIXTURE_DATA, @service.download(FIXTURE_KEY) + end + + test "existing" do + assert @service.exist?(FIXTURE_KEY) + assert_not @service.exist?(FIXTURE_KEY + "nonsense") + end + + test "deleting" do + @service.delete FIXTURE_KEY + assert_not @service.exist?(FIXTURE_KEY) + end + + test "deleting nonexistent key" do + assert_nothing_raised do + @service.delete SecureRandom.base58(24) + end + end + end +end |