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
81bcc097
Commit
81bcc097
authored
Jul 04, 2018
by
Kamil Trzciński
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Prevent uploading two files as artifacts in single request
parent
ebb62ecc
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
98 additions
and
47 deletions
+98
-47
internal/artifacts/artifacts_store_test.go
internal/artifacts/artifacts_store_test.go
+6
-5
internal/artifacts/artifacts_upload.go
internal/artifacts/artifacts_upload.go
+5
-5
internal/artifacts/artifacts_upload_test.go
internal/artifacts/artifacts_upload_test.go
+73
-35
internal/testhelper/testhelper.go
internal/testhelper/testhelper.go
+14
-2
No files found.
internal/artifacts/artifacts_store_test.go
View file @
81bcc097
...
@@ -136,7 +136,8 @@ func TestUploadHandlerSendingToExternalStorage(t *testing.T) {
...
@@ -136,7 +136,8 @@ func TestUploadHandlerSendingToExternalStorage(t *testing.T) {
contentBuffer
,
contentType
:=
createTestMultipartForm
(
t
,
archiveData
)
contentBuffer
,
contentType
:=
createTestMultipartForm
(
t
,
archiveData
)
response
:=
testUploadArtifacts
(
contentType
,
&
contentBuffer
,
t
,
ts
)
response
:=
testUploadArtifacts
(
contentType
,
&
contentBuffer
,
t
,
ts
)
testhelper
.
AssertResponseCode
(
t
,
response
,
200
)
testhelper
.
AssertResponseCode
(
t
,
response
,
http
.
StatusOK
)
testhelper
.
AssertResponseHeader
(
t
,
response
,
MetadataHeaderKey
,
MetadataHeaderPresent
)
assert
.
Equal
(
t
,
1
,
storeServerCalled
,
"store should be called only once"
)
assert
.
Equal
(
t
,
1
,
storeServerCalled
,
"store should be called only once"
)
assert
.
Equal
(
t
,
1
,
responseProcessorCalled
,
"response processor should be called only once"
)
assert
.
Equal
(
t
,
1
,
responseProcessorCalled
,
"response processor should be called only once"
)
})
})
...
@@ -166,7 +167,7 @@ func TestUploadHandlerSendingToExternalStorageAndStorageServerUnreachable(t *tes
...
@@ -166,7 +167,7 @@ func TestUploadHandlerSendingToExternalStorageAndStorageServerUnreachable(t *tes
defer
ts
.
Close
()
defer
ts
.
Close
()
response
:=
testUploadArtifactsFromTestZip
(
t
,
ts
)
response
:=
testUploadArtifactsFromTestZip
(
t
,
ts
)
testhelper
.
AssertResponseCode
(
t
,
response
,
500
)
testhelper
.
AssertResponseCode
(
t
,
response
,
http
.
StatusInternalServerError
)
}
}
func
TestUploadHandlerSendingToExternalStorageAndInvalidURLIsUsed
(
t
*
testing
.
T
)
{
func
TestUploadHandlerSendingToExternalStorageAndInvalidURLIsUsed
(
t
*
testing
.
T
)
{
...
@@ -192,7 +193,7 @@ func TestUploadHandlerSendingToExternalStorageAndInvalidURLIsUsed(t *testing.T)
...
@@ -192,7 +193,7 @@ func TestUploadHandlerSendingToExternalStorageAndInvalidURLIsUsed(t *testing.T)
defer
ts
.
Close
()
defer
ts
.
Close
()
response
:=
testUploadArtifactsFromTestZip
(
t
,
ts
)
response
:=
testUploadArtifactsFromTestZip
(
t
,
ts
)
testhelper
.
AssertResponseCode
(
t
,
response
,
500
)
testhelper
.
AssertResponseCode
(
t
,
response
,
http
.
StatusInternalServerError
)
}
}
func
TestUploadHandlerSendingToExternalStorageAndItReturnsAnError
(
t
*
testing
.
T
)
{
func
TestUploadHandlerSendingToExternalStorageAndItReturnsAnError
(
t
*
testing
.
T
)
{
...
@@ -230,7 +231,7 @@ func TestUploadHandlerSendingToExternalStorageAndItReturnsAnError(t *testing.T)
...
@@ -230,7 +231,7 @@ func TestUploadHandlerSendingToExternalStorageAndItReturnsAnError(t *testing.T)
defer
ts
.
Close
()
defer
ts
.
Close
()
response
:=
testUploadArtifactsFromTestZip
(
t
,
ts
)
response
:=
testUploadArtifactsFromTestZip
(
t
,
ts
)
testhelper
.
AssertResponseCode
(
t
,
response
,
500
)
testhelper
.
AssertResponseCode
(
t
,
response
,
http
.
StatusInternalServerError
)
assert
.
Equal
(
t
,
1
,
putCalledTimes
,
"upload should be called only once"
)
assert
.
Equal
(
t
,
1
,
putCalledTimes
,
"upload should be called only once"
)
}
}
...
@@ -271,7 +272,7 @@ func TestUploadHandlerSendingToExternalStorageAndSupportRequestTimeout(t *testin
...
@@ -271,7 +272,7 @@ func TestUploadHandlerSendingToExternalStorageAndSupportRequestTimeout(t *testin
defer
ts
.
Close
()
defer
ts
.
Close
()
response
:=
testUploadArtifactsFromTestZip
(
t
,
ts
)
response
:=
testUploadArtifactsFromTestZip
(
t
,
ts
)
testhelper
.
AssertResponseCode
(
t
,
response
,
500
)
testhelper
.
AssertResponseCode
(
t
,
response
,
http
.
StatusInternalServerError
)
assert
.
Equal
(
t
,
1
,
putCalledTimes
,
"upload should be called only once"
)
assert
.
Equal
(
t
,
1
,
putCalledTimes
,
"upload should be called only once"
)
}
}
...
...
internal/artifacts/artifacts_upload.go
View file @
81bcc097
...
@@ -18,9 +18,8 @@ import (
...
@@ -18,9 +18,8 @@ import (
)
)
type
artifactsUploadProcessor
struct
{
type
artifactsUploadProcessor
struct
{
opts
*
filestore
.
SaveFileOpts
opts
*
filestore
.
SaveFileOpts
metadataFile
string
stored
bool
stored
bool
}
}
func
(
a
*
artifactsUploadProcessor
)
generateMetadataFromZip
(
ctx
context
.
Context
,
file
*
filestore
.
FileHandler
)
(
*
filestore
.
FileHandler
,
error
)
{
func
(
a
*
artifactsUploadProcessor
)
generateMetadataFromZip
(
ctx
context
.
Context
,
file
*
filestore
.
FileHandler
)
(
*
filestore
.
FileHandler
,
error
)
{
...
@@ -80,9 +79,10 @@ func (a *artifactsUploadProcessor) ProcessFile(ctx context.Context, formName str
...
@@ -80,9 +79,10 @@ func (a *artifactsUploadProcessor) ProcessFile(ctx context.Context, formName str
if
formName
!=
"file"
{
if
formName
!=
"file"
{
return
fmt
.
Errorf
(
"Invalid form field: %q"
,
formName
)
return
fmt
.
Errorf
(
"Invalid form field: %q"
,
formName
)
}
}
if
a
.
metadataFile
!=
""
{
if
a
.
stored
{
return
fmt
.
Errorf
(
"Artifacts request contains more than one file
!
"
)
return
fmt
.
Errorf
(
"Artifacts request contains more than one file"
)
}
}
a
.
stored
=
true
select
{
select
{
case
<-
ctx
.
Done
()
:
case
<-
ctx
.
Done
()
:
...
...
internal/artifacts/artifacts_upload_test.go
View file @
81bcc097
...
@@ -23,6 +23,12 @@ import (
...
@@ -23,6 +23,12 @@ import (
"gitlab.com/gitlab-org/gitlab-workhorse/internal/zipartifacts"
"gitlab.com/gitlab-org/gitlab-workhorse/internal/zipartifacts"
)
)
const
(
MetadataHeaderKey
=
"Metadata-Status"
MetadataHeaderPresent
=
"present"
MetadataHeaderMissing
=
"missing"
)
func
testArtifactsUploadServer
(
t
*
testing
.
T
,
authResponse
api
.
Response
,
bodyProcessor
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
))
*
httptest
.
Server
{
func
testArtifactsUploadServer
(
t
*
testing
.
T
,
authResponse
api
.
Response
,
bodyProcessor
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
))
*
httptest
.
Server
{
mux
:=
http
.
NewServeMux
()
mux
:=
http
.
NewServeMux
()
mux
.
HandleFunc
(
"/url/path/authorize"
,
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
mux
.
HandleFunc
(
"/url/path/authorize"
,
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
...
@@ -46,52 +52,54 @@ func testArtifactsUploadServer(t *testing.T, authResponse api.Response, bodyProc
...
@@ -46,52 +52,54 @@ func testArtifactsUploadServer(t *testing.T, authResponse api.Response, bodyProc
}
}
if
opts
.
IsLocal
()
{
if
opts
.
IsLocal
()
{
if
r
.
FormValue
(
"file.path"
)
==
""
{
if
r
.
FormValue
(
"file.path"
)
==
""
{
w
.
WriteHeader
(
501
)
t
.
Fatal
(
"Expected file to be present"
)
return
return
}
}
_
,
err
:=
ioutil
.
ReadFile
(
r
.
FormValue
(
"file.path"
))
_
,
err
:=
ioutil
.
ReadFile
(
r
.
FormValue
(
"file.path"
))
if
err
!=
nil
{
if
err
!=
nil
{
w
.
WriteHeader
(
404
)
t
.
Fatal
(
"Expected file to be readable"
)
return
}
}
else
if
opts
.
IsRemote
()
{
if
r
.
FormValue
(
"file.remote_url"
)
==
""
{
t
.
Fatal
(
"Expected file to be remote accessible"
)
return
return
}
}
}
}
if
opts
.
IsRemote
()
&&
r
.
FormValue
(
"file.remote_url"
)
==
""
{
if
r
.
FormValue
(
"metadata.path"
)
!=
""
{
w
.
WriteHeader
(
501
)
metadata
,
err
:=
ioutil
.
ReadFile
(
r
.
FormValue
(
"metadata.path"
))
return
if
err
!=
nil
{
}
t
.
Fatal
(
"Expected metadata to be readable"
)
return
}
gz
,
err
:=
gzip
.
NewReader
(
bytes
.
NewReader
(
metadata
))
if
err
!=
nil
{
t
.
Fatal
(
"Expected metadata to be valid gzip"
)
return
}
defer
gz
.
Close
()
metadata
,
err
=
ioutil
.
ReadAll
(
gz
)
if
err
!=
nil
{
t
.
Fatal
(
"Expected metadata to be valid"
)
return
}
if
!
bytes
.
HasPrefix
(
metadata
,
[]
byte
(
zipartifacts
.
MetadataHeaderPrefix
+
zipartifacts
.
MetadataHeader
))
{
t
.
Fatal
(
"Expected metadata to be of valid format"
)
return
}
if
r
.
FormValue
(
"metadata.path"
)
==
""
{
w
.
Header
()
.
Set
(
MetadataHeaderKey
,
MetadataHeaderPresent
)
w
.
WriteHeader
(
502
)
return
}
metadata
,
err
:=
ioutil
.
ReadFile
(
r
.
FormValue
(
"metadata.path"
))
}
else
{
if
err
!=
nil
{
w
.
Header
()
.
Set
(
MetadataHeaderKey
,
MetadataHeaderMissing
)
w
.
WriteHeader
(
404
)
return
}
gz
,
err
:=
gzip
.
NewReader
(
bytes
.
NewReader
(
metadata
))
if
err
!=
nil
{
w
.
WriteHeader
(
405
)
return
}
defer
gz
.
Close
()
metadata
,
err
=
ioutil
.
ReadAll
(
gz
)
if
err
!=
nil
{
w
.
WriteHeader
(
404
)
return
}
if
!
bytes
.
HasPrefix
(
metadata
,
[]
byte
(
zipartifacts
.
MetadataHeaderPrefix
+
zipartifacts
.
MetadataHeader
))
{
w
.
WriteHeader
(
400
)
return
}
}
w
.
WriteHeader
(
http
.
StatusOK
)
if
bodyProcessor
!=
nil
{
if
bodyProcessor
!=
nil
{
bodyProcessor
(
w
,
r
)
bodyProcessor
(
w
,
r
)
}
else
{
w
.
WriteHeader
(
200
)
}
}
})
})
return
testhelper
.
TestServerWithHandler
(
nil
,
mux
.
ServeHTTP
)
return
testhelper
.
TestServerWithHandler
(
nil
,
mux
.
ServeHTTP
)
...
@@ -141,7 +149,8 @@ func TestUploadHandlerAddingMetadata(t *testing.T) {
...
@@ -141,7 +149,8 @@ func TestUploadHandlerAddingMetadata(t *testing.T) {
writer
.
Close
()
writer
.
Close
()
response
:=
testUploadArtifacts
(
writer
.
FormDataContentType
(),
&
buffer
,
t
,
ts
)
response
:=
testUploadArtifacts
(
writer
.
FormDataContentType
(),
&
buffer
,
t
,
ts
)
testhelper
.
AssertResponseCode
(
t
,
response
,
200
)
testhelper
.
AssertResponseCode
(
t
,
response
,
http
.
StatusOK
)
testhelper
.
AssertResponseHeader
(
t
,
response
,
MetadataHeaderKey
,
MetadataHeaderPresent
)
}
}
func
TestUploadHandlerForUnsupportedArchive
(
t
*
testing
.
T
)
{
func
TestUploadHandlerForUnsupportedArchive
(
t
*
testing
.
T
)
{
...
@@ -164,8 +173,37 @@ func TestUploadHandlerForUnsupportedArchive(t *testing.T) {
...
@@ -164,8 +173,37 @@ func TestUploadHandlerForUnsupportedArchive(t *testing.T) {
writer
.
Close
()
writer
.
Close
()
response
:=
testUploadArtifacts
(
writer
.
FormDataContentType
(),
&
buffer
,
t
,
ts
)
response
:=
testUploadArtifacts
(
writer
.
FormDataContentType
(),
&
buffer
,
t
,
ts
)
// 502 is a custom response code from the mock server in testUploadArtifacts
testhelper
.
AssertResponseCode
(
t
,
response
,
http
.
StatusOK
)
testhelper
.
AssertResponseCode
(
t
,
response
,
502
)
testhelper
.
AssertResponseHeader
(
t
,
response
,
MetadataHeaderKey
,
MetadataHeaderMissing
)
}
func
TestUploadHandlerForMultipleFiles
(
t
*
testing
.
T
)
{
tempPath
,
err
:=
ioutil
.
TempDir
(
""
,
"uploads"
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
defer
os
.
RemoveAll
(
tempPath
)
ts
:=
testArtifactsUploadServer
(
t
,
api
.
Response
{
TempPath
:
tempPath
},
nil
)
defer
ts
.
Close
()
var
buffer
bytes
.
Buffer
writer
:=
multipart
.
NewWriter
(
&
buffer
)
file
,
err
:=
writer
.
CreateFormFile
(
"file"
,
"my.file"
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
fmt
.
Fprint
(
file
,
"test"
)
file
,
err
=
writer
.
CreateFormFile
(
"file"
,
"my.file"
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
fmt
.
Fprint
(
file
,
"test"
)
writer
.
Close
()
response
:=
testUploadArtifacts
(
writer
.
FormDataContentType
(),
&
buffer
,
t
,
ts
)
testhelper
.
AssertResponseCode
(
t
,
response
,
http
.
StatusInternalServerError
)
}
}
func
TestUploadFormProcessing
(
t
*
testing
.
T
)
{
func
TestUploadFormProcessing
(
t
*
testing
.
T
)
{
...
@@ -188,5 +226,5 @@ func TestUploadFormProcessing(t *testing.T) {
...
@@ -188,5 +226,5 @@ func TestUploadFormProcessing(t *testing.T) {
writer
.
Close
()
writer
.
Close
()
response
:=
testUploadArtifacts
(
writer
.
FormDataContentType
(),
&
buffer
,
t
,
ts
)
response
:=
testUploadArtifacts
(
writer
.
FormDataContentType
(),
&
buffer
,
t
,
ts
)
testhelper
.
AssertResponseCode
(
t
,
response
,
500
)
testhelper
.
AssertResponseCode
(
t
,
response
,
http
.
StatusInternalServerError
)
}
}
internal/testhelper/testhelper.go
View file @
81bcc097
...
@@ -78,8 +78,20 @@ func AssertResponseWriterHeader(t *testing.T, w http.ResponseWriter, header stri
...
@@ -78,8 +78,20 @@ func AssertResponseWriterHeader(t *testing.T, w http.ResponseWriter, header stri
assertHeaderExists
(
t
,
header
,
actual
,
expected
)
assertHeaderExists
(
t
,
header
,
actual
,
expected
)
}
}
func
AssertResponseHeader
(
t
*
testing
.
T
,
w
*
http
.
Response
,
header
string
,
expected
...
string
)
{
func
AssertResponseHeader
(
t
*
testing
.
T
,
w
interface
{},
header
string
,
expected
...
string
)
{
actual
:=
w
.
Header
[
http
.
CanonicalHeaderKey
(
header
)]
var
actual
[]
string
header
=
http
.
CanonicalHeaderKey
(
header
)
if
resp
,
ok
:=
w
.
(
*
http
.
Response
);
ok
{
actual
=
resp
.
Header
[
header
]
}
else
if
resp
,
ok
:=
w
.
(
http
.
ResponseWriter
);
ok
{
actual
=
resp
.
Header
()[
header
]
}
else
if
resp
,
ok
:=
w
.
(
*
httptest
.
ResponseRecorder
);
ok
{
actual
=
resp
.
Header
()[
header
]
}
else
{
t
.
Fatalf
(
"invalid type of w passed AssertResponseHeader"
)
}
assertHeaderExists
(
t
,
header
,
actual
,
expected
)
assertHeaderExists
(
t
,
header
,
actual
,
expected
)
}
}
...
...
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