Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
974eed2d
Commit
974eed2d
authored
Jan 23, 2018
by
Micaël Bergeron
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add specs around the migration code
parent
fcff2995
Changes
13
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
163 additions
and
91 deletions
+163
-91
app/uploaders/avatar_uploader.rb
app/uploaders/avatar_uploader.rb
+0
-11
app/uploaders/gitlab_uploader.rb
app/uploaders/gitlab_uploader.rb
+2
-2
config/initializers/1_settings.rb
config/initializers/1_settings.rb
+2
-2
ee/app/uploaders/object_storage.rb
ee/app/uploaders/object_storage.rb
+26
-16
spec/support/shared_examples/uploaders/object_storage_shared_examples.rb
...ared_examples/uploaders/object_storage_shared_examples.rb
+72
-0
spec/uploaders/attachment_uploader_spec.rb
spec/uploaders/attachment_uploader_spec.rb
+17
-18
spec/uploaders/avatar_uploader_spec.rb
spec/uploaders/avatar_uploader_spec.rb
+13
-12
spec/uploaders/file_uploader_spec.rb
spec/uploaders/file_uploader_spec.rb
+8
-10
spec/uploaders/lfs_object_uploader_spec.rb
spec/uploaders/lfs_object_uploader_spec.rb
+0
-12
spec/uploaders/namespace_file_uploader_spec.rb
spec/uploaders/namespace_file_uploader_spec.rb
+10
-0
spec/uploaders/object_storage_spec.rb
spec/uploaders/object_storage_spec.rb
+1
-6
spec/uploaders/personal_file_uploader_spec.rb
spec/uploaders/personal_file_uploader_spec.rb
+10
-0
spec/uploaders/records_uploads_spec.rb
spec/uploaders/records_uploads_spec.rb
+2
-2
No files found.
app/uploaders/avatar_uploader.rb
View file @
974eed2d
...
@@ -10,17 +10,6 @@ class AvatarUploader < GitlabUploader
...
@@ -10,17 +10,6 @@ class AvatarUploader < GitlabUploader
model
.
avatar
.
file
&&
model
.
avatar
.
file
.
present?
model
.
avatar
.
file
&&
model
.
avatar
.
file
.
present?
end
end
# We set move_to_store and move_to_cache to 'false' to prevent stealing
# the avatar file from a project when forking it.
# https://gitlab.com/gitlab-org/gitlab-ce/issues/26158
def
move_to_store
false
end
def
move_to_cache
false
end
private
private
def
dynamic_segment
def
dynamic_segment
...
...
app/uploaders/gitlab_uploader.rb
View file @
974eed2d
...
@@ -32,12 +32,12 @@ class GitlabUploader < CarrierWave::Uploader::Base
...
@@ -32,12 +32,12 @@ class GitlabUploader < CarrierWave::Uploader::Base
# Reduce disk IO
# Reduce disk IO
def
move_to_cache
def
move_to_cache
true
super
||
true
end
end
# Reduce disk IO
# Reduce disk IO
def
move_to_store
def
move_to_store
true
super
||
true
end
end
def
exists?
def
exists?
...
...
config/initializers/1_settings.rb
View file @
974eed2d
ee/app/uploaders/object_storage.rb
View file @
974eed2d
...
@@ -68,6 +68,7 @@ module ObjectStorage
...
@@ -68,6 +68,7 @@ module ObjectStorage
base
.
include
(
ObjectStorage
)
base
.
include
(
ObjectStorage
)
before
:store
,
:verify_license!
before
:store
,
:verify_license!
after
:migrate
,
:delete_migrated_file
end
end
class_methods
do
class_methods
do
...
@@ -155,26 +156,29 @@ module ObjectStorage
...
@@ -155,26 +156,29 @@ module ObjectStorage
return
unless
object_store
!=
new_store
return
unless
object_store
!=
new_store
return
unless
file
return
unless
file
new_file
=
nil
file_to_delete
=
file
file_to_delete
=
file
from_object_store
=
object_store
self
.
object_store
=
new_store
# changes the storage and file
self
.
object_store
=
new_store
# changes the storage and file
cache_stored_file!
if
file_storage?
cache_stored_file!
if
file_storage?
with_callbacks
(
:migrate
,
file_to_delete
)
do
with_callbacks
(
:store
,
file_to_delete
)
do
# for #store_versions!
with_callbacks
(
:store
,
file_to_delete
)
do
# for #store_versions!
storage
.
store!
(
file
).
tap
do
|
new_file
|
new_file
=
storage
.
store!
(
file
)
begin
@file
=
new_file
persist_object_store!
persist_object_store!
file_to_delete
.
delete
if
new_file
.
exists?
self
.
file
=
new_file
rescue
=>
e
# in case of failure delete new file
new_file
.
delete
raise
e
end
end
end
end
end
file
file
rescue
=>
e
# in case of failure delete new file
new_file
.
delete
unless
new_file
.
nil?
# revert back to the old file
self
.
object_store
=
from_object_store
self
.
file
=
file_to_delete
raise
e
end
end
def
schedule_migration_to_object_storage
(
*
args
)
def
schedule_migration_to_object_storage
(
*
args
)
...
@@ -199,15 +203,15 @@ module ObjectStorage
...
@@ -199,15 +203,15 @@ module ObjectStorage
end
end
def
move_to_store
def
move_to_store
return
true
if
Store
::
LOCAL
false
file
.
try
(
:storage
)
==
storage
end
end
def
move_to_cache
def
move_to_cache
return
true
if
object_store
==
Store
::
LOCAL
false
end
file
.
try
(
:storage
)
==
cache_storage
def
delete_migrated_file
(
migrated_file
)
migrated_file
.
delete
if
exists?
end
end
def
verify_license!
(
_file
)
def
verify_license!
(
_file
)
...
@@ -245,6 +249,12 @@ module ObjectStorage
...
@@ -245,6 +249,12 @@ module ObjectStorage
private
private
# this is a hack around CarrierWave. The #migrate method needs to be
# able to force the current file to the migrated file upon success.
def
file
=
(
file
)
@file
=
file
end
def
serialization_column
def
serialization_column
model
.
class
.
uploader_options
.
dig
(
mounted_as
,
:mount_on
)
||
mounted_as
model
.
class
.
uploader_options
.
dig
(
mounted_as
,
:mount_on
)
||
mounted_as
end
end
...
...
spec/support/shared_examples/uploaders/object_storage_shared_examples.rb
View file @
974eed2d
...
@@ -4,6 +4,78 @@ shared_context 'with storage' do |store, **stub_params|
...
@@ -4,6 +4,78 @@ shared_context 'with storage' do |store, **stub_params|
end
end
end
end
shared_examples
"migrates"
do
|
to_store:
,
from_store:
nil
|
let
(
:to
)
{
to_store
}
let
(
:from
)
{
from_store
||
subject
.
object_store
}
def
migrate
(
to
)
subject
.
migrate!
(
to
)
end
def
checksum
Digest
::
SHA256
.
hexdigest
(
subject
.
read
)
end
before
do
migrate
(
from
)
end
it
'does nothing when migrating to the current store'
do
expect
{
migrate
(
from
)
}.
not_to
change
{
subject
.
object_store
}.
from
(
from
)
end
it
'migrate to the specified store'
do
from_checksum
=
checksum
expect
{
migrate
(
to
)
}.
to
change
{
subject
.
object_store
}.
from
(
from
).
to
(
to
)
expect
(
checksum
).
to
eq
(
from_checksum
)
end
it
'removes the original file after the migration'
do
original_file
=
subject
.
file
.
path
migrate
(
to
)
expect
(
File
.
exist?
(
original_file
)).
to
be_falsey
end
context
'migration is unsuccessful'
do
shared_examples
"handles gracefully"
do
|
error
:|
it
'does not update the object_store'
do
expect
{
migrate
(
to
)
}.
to
raise_error
(
error
)
expect
(
subject
.
object_store
).
to
eq
(
from
)
end
it
'does not delete the original file'
do
expect
{
migrate
(
to
)
}.
to
raise_error
(
error
)
expect
(
subject
.
exists?
).
to
be_truthy
end
end
context
'when the store is not supported'
do
let
(
:to
)
{
-
1
}
# not a valid store
include_examples
"handles gracefully"
,
error:
ObjectStorage
::
UnknownStoreError
end
context
'upon a fog failure'
do
before
do
storage_class
=
subject
.
send
(
:storage_for
,
to
).
class
expect_any_instance_of
(
storage_class
).
to
receive
(
:store!
).
and_raise
(
"Store failure."
)
end
include_examples
"handles gracefully"
,
error:
"Store failure."
end
context
'upon a database failure'
do
before
do
expect
(
uploader
).
to
receive
(
:persist_object_store!
).
and_raise
(
"ActiveRecord failure."
)
end
include_examples
"handles gracefully"
,
error:
"ActiveRecord failure."
end
end
end
shared_examples
"matches the method pattern"
do
|
method
|
shared_examples
"matches the method pattern"
do
|
method
|
let
(
:target
)
{
subject
}
let
(
:target
)
{
subject
}
let
(
:args
)
{
nil
}
let
(
:args
)
{
nil
}
...
...
spec/uploaders/attachment_uploader_spec.rb
View file @
974eed2d
require
'spec_helper'
require
'spec_helper'
describe
AttachmentUploader
do
describe
AttachmentUploader
do
let
(
:uploader
)
{
described_class
.
new
(
build_stubbed
(
:user
),
:attachment
)
}
let
(
:note
)
{
create
(
:note
,
:with_attachment
)
}
let
(
:uploader
)
{
note
.
attachment
}
let
(
:upload
)
{
create
(
:upload
,
:attachment_upload
,
model:
uploader
.
model
)
}
let
(
:upload
)
{
create
(
:upload
,
:attachment_upload
,
model:
uploader
.
model
)
}
subject
{
uploader
}
subject
{
uploader
}
it_behaves_like
'builds correct paths'
,
it_behaves_like
'builds correct paths'
,
store_dir:
%r[uploads/-/system/user/attachment/]
,
store_dir:
%r[uploads/-/system/note/attachment/]
,
upload_path:
%r[uploads/-/system/user/attachment/]
,
upload_path:
%r[uploads/-/system/note/attachment/]
,
absolute_path:
%r[
#{
CarrierWave
.
root
}
/uploads/-/system/user/attachment/]
absolute_path:
%r[
#{
CarrierWave
.
root
}
/uploads/-/system/note/attachment/]
describe
'#move_to_cache'
do
it
'is true'
do
expect
(
uploader
.
move_to_cache
).
to
eq
(
true
)
end
end
describe
'#move_to_store'
do
it
'is true'
do
expect
(
uploader
.
move_to_store
).
to
eq
(
true
)
end
end
# EE-specific
# EE-specific
context
"object_store is REMOTE"
do
context
"object_store is REMOTE"
do
...
@@ -32,7 +21,17 @@ describe AttachmentUploader do
...
@@ -32,7 +21,17 @@ describe AttachmentUploader do
include_context
'with storage'
,
described_class
::
Store
::
REMOTE
include_context
'with storage'
,
described_class
::
Store
::
REMOTE
it_behaves_like
'builds correct paths'
,
it_behaves_like
'builds correct paths'
,
store_dir:
%r[user/attachment/]
,
store_dir:
%r[note/attachment/]
,
upload_path:
%r[user/attachment/]
upload_path:
%r[note/attachment/]
end
describe
"#migrate!"
do
before
do
uploader
.
store!
(
fixture_file_upload
(
Rails
.
root
.
join
(
'spec/fixtures/doc_sample.txt'
)))
stub_uploads_object_storage
end
it_behaves_like
"migrates"
,
to_store:
described_class
::
Store
::
REMOTE
it_behaves_like
"migrates"
,
from_store:
described_class
::
Store
::
REMOTE
,
to_store:
described_class
::
Store
::
LOCAL
end
end
end
end
spec/uploaders/avatar_uploader_spec.rb
View file @
974eed2d
...
@@ -12,18 +12,6 @@ describe AvatarUploader do
...
@@ -12,18 +12,6 @@ describe AvatarUploader do
upload_path:
%r[uploads/-/system/user/avatar/]
,
upload_path:
%r[uploads/-/system/user/avatar/]
,
absolute_path:
%r[
#{
CarrierWave
.
root
}
/uploads/-/system/user/avatar/]
absolute_path:
%r[
#{
CarrierWave
.
root
}
/uploads/-/system/user/avatar/]
describe
'#move_to_cache'
do
it
'is false'
do
expect
(
uploader
.
move_to_cache
).
to
eq
(
false
)
end
end
describe
'#move_to_store'
do
it
'is false'
do
expect
(
uploader
.
move_to_store
).
to
eq
(
false
)
end
end
# EE-specific
# EE-specific
context
"object_store is REMOTE"
do
context
"object_store is REMOTE"
do
before
do
before
do
...
@@ -36,4 +24,17 @@ describe AvatarUploader do
...
@@ -36,4 +24,17 @@ describe AvatarUploader do
store_dir:
%r[user/avatar/]
,
store_dir:
%r[user/avatar/]
,
upload_path:
%r[user/avatar/]
upload_path:
%r[user/avatar/]
end
end
context
"with a file"
do
let
(
:project
)
{
create
(
:project
,
:with_avatar
)
}
let
(
:uploader
)
{
project
.
avatar
}
let
(
:upload
)
{
uploader
.
upload
}
before
do
stub_uploads_object_storage
end
it_behaves_like
"migrates"
,
to_store:
described_class
::
Store
::
REMOTE
it_behaves_like
"migrates"
,
from_store:
described_class
::
Store
::
REMOTE
,
to_store:
described_class
::
Store
::
LOCAL
end
end
end
spec/uploaders/file_uploader_spec.rb
View file @
974eed2d
...
@@ -2,7 +2,7 @@ require 'spec_helper'
...
@@ -2,7 +2,7 @@ require 'spec_helper'
describe
FileUploader
do
describe
FileUploader
do
let
(
:group
)
{
create
(
:group
,
name:
'awesome'
)
}
let
(
:group
)
{
create
(
:group
,
name:
'awesome'
)
}
let
(
:project
)
{
build_stubbed
(
:project
,
namespace:
group
,
name:
'project'
)
}
let
(
:project
)
{
create
(
:project
,
namespace:
group
,
name:
'project'
)
}
let
(
:uploader
)
{
described_class
.
new
(
project
)
}
let
(
:uploader
)
{
described_class
.
new
(
project
)
}
let
(
:upload
)
{
double
(
model:
project
,
path:
'secret/foo.jpg'
)
}
let
(
:upload
)
{
double
(
model:
project
,
path:
'secret/foo.jpg'
)
}
...
@@ -17,7 +17,7 @@ describe FileUploader do
...
@@ -17,7 +17,7 @@ describe FileUploader do
shared_examples
'uses hashed storage'
do
shared_examples
'uses hashed storage'
do
context
'when rolled out attachments'
do
context
'when rolled out attachments'
do
before
do
before
do
expect
(
project
).
to
receive
(
:disk_path
).
and_return
(
'ca/fe/fe/ed'
)
allow
(
project
).
to
receive
(
:disk_path
).
and_return
(
'ca/fe/fe/ed'
)
end
end
let
(
:project
)
{
build_stubbed
(
:project
,
:hashed
,
namespace:
group
,
name:
'project'
)
}
let
(
:project
)
{
build_stubbed
(
:project
,
:hashed
,
namespace:
group
,
name:
'project'
)
}
...
@@ -66,15 +66,13 @@ describe FileUploader do
...
@@ -66,15 +66,13 @@ describe FileUploader do
end
end
end
end
describe
'#move_to_cache'
do
describe
"#migrate!"
do
it
'is true'
do
before
do
expect
(
uploader
.
move_to_cache
).
to
eq
(
true
)
uploader
.
store!
(
fixture_file_upload
(
Rails
.
root
.
join
(
'spec/fixtures/dk.png'
))
)
end
stub_uploads_object_storage
end
end
describe
'#move_to_store'
do
it_behaves_like
"migrates"
,
to_store:
described_class
::
Store
::
REMOTE
it
'is true'
do
it_behaves_like
"migrates"
,
from_store:
described_class
::
Store
::
REMOTE
,
to_store:
described_class
::
Store
::
LOCAL
expect
(
uploader
.
move_to_store
).
to
eq
(
true
)
end
end
end
end
end
spec/uploaders/lfs_object_uploader_spec.rb
View file @
974eed2d
...
@@ -23,18 +23,6 @@ describe LfsObjectUploader do
...
@@ -23,18 +23,6 @@ describe LfsObjectUploader do
store_dir:
%r[
\h
{2}/
\h
{2}]
store_dir:
%r[
\h
{2}/
\h
{2}]
end
end
describe
'#move_to_cache'
do
it
'is true'
do
expect
(
uploader
.
move_to_cache
).
to
eq
(
true
)
end
end
describe
'#move_to_store'
do
it
'is true'
do
expect
(
uploader
.
move_to_store
).
to
eq
(
true
)
end
end
describe
'migration to object storage'
do
describe
'migration to object storage'
do
context
'with object storage disabled'
do
context
'with object storage disabled'
do
it
"is skipped"
do
it
"is skipped"
do
...
...
spec/uploaders/namespace_file_uploader_spec.rb
View file @
974eed2d
...
@@ -26,4 +26,14 @@ describe NamespaceFileUploader do
...
@@ -26,4 +26,14 @@ describe NamespaceFileUploader do
store_dir:
%r[namespace/
\d
+/
\h
+]
,
store_dir:
%r[namespace/
\d
+/
\h
+]
,
upload_path:
IDENTIFIER
upload_path:
IDENTIFIER
end
end
describe
"#migrate!"
do
before
do
uploader
.
store!
(
fixture_file_upload
(
Rails
.
root
.
join
(
'spec/fixtures/doc_sample.txt'
)))
stub_uploads_object_storage
end
it_behaves_like
"migrates"
,
to_store:
described_class
::
Store
::
REMOTE
it_behaves_like
"migrates"
,
from_store:
described_class
::
Store
::
REMOTE
,
to_store:
described_class
::
Store
::
LOCAL
end
end
end
spec/uploaders/object_storage_spec.rb
View file @
974eed2d
...
@@ -83,7 +83,7 @@ describe ObjectStorage do
...
@@ -83,7 +83,7 @@ describe ObjectStorage do
expect
(
object
).
to
receive
(
:file_store
).
and_return
(
described_class
::
Store
::
REMOTE
)
expect
(
object
).
to
receive
(
:file_store
).
and_return
(
described_class
::
Store
::
REMOTE
)
end
end
it
"returns given value"
do
it
"returns
the
given value"
do
expect
(
uploader
.
object_store
).
to
eq
(
described_class
::
Store
::
REMOTE
)
expect
(
uploader
.
object_store
).
to
eq
(
described_class
::
Store
::
REMOTE
)
end
end
end
end
...
@@ -143,11 +143,6 @@ describe ObjectStorage do
...
@@ -143,11 +143,6 @@ describe ObjectStorage do
it
"uploader include described_class::Concern"
do
it
"uploader include described_class::Concern"
do
expect
(
uploader
).
to
be_a
(
described_class
::
Concern
)
expect
(
uploader
).
to
be_a
(
described_class
::
Concern
)
end
end
it
'moves files locally'
do
expect
(
uploader
.
move_to_store
).
to
be
(
true
)
expect
(
uploader
.
move_to_cache
).
to
be
(
true
)
end
end
end
describe
'#use_file'
do
describe
'#use_file'
do
...
...
spec/uploaders/personal_file_uploader_spec.rb
View file @
974eed2d
...
@@ -43,4 +43,14 @@ describe PersonalFileUploader do
...
@@ -43,4 +43,14 @@ describe PersonalFileUploader do
)
)
end
end
end
end
describe
"#migrate!"
do
before
do
uploader
.
store!
(
fixture_file_upload
(
Rails
.
root
.
join
(
'spec/fixtures/doc_sample.txt'
)))
stub_uploads_object_storage
end
it_behaves_like
"migrates"
,
to_store:
described_class
::
Store
::
REMOTE
it_behaves_like
"migrates"
,
from_store:
described_class
::
Store
::
REMOTE
,
to_store:
described_class
::
Store
::
LOCAL
end
end
end
spec/uploaders/records_uploads_spec.rb
View file @
974eed2d
...
@@ -59,13 +59,13 @@ describe RecordsUploads do
...
@@ -59,13 +59,13 @@ describe RecordsUploads do
it
"does not create an Upload record when the file doesn't exist"
do
it
"does not create an Upload record when the file doesn't exist"
do
allow
(
uploader
).
to
receive
(
:file
).
and_return
(
double
(
exists?:
false
))
allow
(
uploader
).
to
receive
(
:file
).
and_return
(
double
(
exists?:
false
))
expect
{
uploader
.
store!
(
upload_fixture
(
'rails_sample.jpg'
))
}.
to_not
change
{
Upload
.
count
}
expect
{
uploader
.
store!
(
upload_fixture
(
'rails_sample.jpg'
))
}.
not_to
change
{
Upload
.
count
}
end
end
it
'does not create an Upload record if model is missing'
do
it
'does not create an Upload record if model is missing'
do
allow_any_instance_of
(
RecordsUploadsExampleUploader
).
to
receive
(
:model
).
and_return
(
nil
)
allow_any_instance_of
(
RecordsUploadsExampleUploader
).
to
receive
(
:model
).
and_return
(
nil
)
expect
{
uploader
.
store!
(
upload_fixture
(
'rails_sample.jpg'
))
}.
to_not
change
{
Upload
.
count
}
expect
{
uploader
.
store!
(
upload_fixture
(
'rails_sample.jpg'
))
}.
not_to
change
{
Upload
.
count
}
end
end
it
'it destroys Upload records at the same path before recording'
do
it
'it destroys Upload records at the same path before recording'
do
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment