Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-workhorse
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
0
Merge Requests
0
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
Kazuhiko Shiozaki
gitlab-workhorse
Commits
e845314b
Commit
e845314b
authored
Jan 15, 2016
by
Jacob Vosmaer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Move test helpers into seperate package
parent
2893a29b
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
51 additions
and
92 deletions
+51
-92
authorization_test.go
authorization_test.go
+2
-1
internal/helper/only_for_test.go
internal/helper/only_for_test.go
+0
-45
internal/staticpages/deploy_page_test.go
internal/staticpages/deploy_page_test.go
+3
-3
internal/staticpages/error_pages_test.go
internal/staticpages/error_pages_test.go
+7
-7
internal/staticpages/servefile_test.go
internal/staticpages/servefile_test.go
+9
-9
internal/upload/uploads_test.go
internal/upload/uploads_test.go
+6
-5
internal/upstream/development_test.go
internal/upstream/development_test.go
+2
-2
internal/upstream/handlers_test.go
internal/upstream/handlers_test.go
+4
-4
main_test.go
main_test.go
+6
-5
proxy_test.go
proxy_test.go
+12
-11
No files found.
authorization_test.go
View file @
e845314b
...
...
@@ -3,6 +3,7 @@ package main
import
(
"./internal/api"
"./internal/helper"
"./internal/testhelper"
"fmt"
"net/http"
"net/http/httptest"
...
...
@@ -29,7 +30,7 @@ func runPreAuthorizeHandler(t *testing.T, suffix string, url *regexp.Regexp, api
response
:=
httptest
.
NewRecorder
()
a
.
PreAuthorizeHandler
(
okHandler
,
suffix
)
.
ServeHTTP
(
response
,
httpRequest
)
helper
.
AssertResponseCode
(
t
,
response
,
expectedCode
)
test
helper
.
AssertResponseCode
(
t
,
response
,
expectedCode
)
return
response
}
...
...
internal/helper/only_for_test.go
deleted
100644 → 0
View file @
2893a29b
package
helper
import
(
"log"
"net/http"
"net/http/httptest"
"regexp"
"testing"
)
func
AssertResponseCode
(
t
*
testing
.
T
,
response
*
httptest
.
ResponseRecorder
,
expectedCode
int
)
{
if
response
.
Code
!=
expectedCode
{
t
.
Fatalf
(
"for HTTP request expected to get %d, got %d instead"
,
expectedCode
,
response
.
Code
)
}
}
func
AssertResponseBody
(
t
*
testing
.
T
,
response
*
httptest
.
ResponseRecorder
,
expectedBody
string
)
{
if
response
.
Body
.
String
()
!=
expectedBody
{
t
.
Fatalf
(
"for HTTP request expected to receive %q, got %q instead as body"
,
expectedBody
,
response
.
Body
.
String
())
}
}
func
AssertResponseHeader
(
t
*
testing
.
T
,
response
*
httptest
.
ResponseRecorder
,
header
string
,
expectedValue
string
)
{
if
response
.
Header
()
.
Get
(
header
)
!=
expectedValue
{
t
.
Fatalf
(
"for HTTP request expected to receive the header %q with %q, got %q"
,
header
,
expectedValue
,
response
.
Header
()
.
Get
(
header
))
}
}
func
TestServerWithHandler
(
url
*
regexp
.
Regexp
,
handler
http
.
HandlerFunc
)
*
httptest
.
Server
{
return
httptest
.
NewServer
(
http
.
HandlerFunc
(
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
if
url
!=
nil
&&
!
url
.
MatchString
(
r
.
URL
.
Path
)
{
log
.
Println
(
"UPSTREAM"
,
r
.
Method
,
r
.
URL
,
"DENY"
)
w
.
WriteHeader
(
404
)
return
}
if
version
:=
r
.
Header
.
Get
(
"Gitlab-Workhorse"
);
version
==
""
{
log
.
Println
(
"UPSTREAM"
,
r
.
Method
,
r
.
URL
,
"DENY"
)
w
.
WriteHeader
(
403
)
return
}
handler
(
w
,
r
)
}))
}
internal/staticpages/deploy_page_test.go
View file @
e845314b
package
staticpages
import
(
"../helper"
"../
test
helper"
"io/ioutil"
"net/http"
"net/http/httptest"
...
...
@@ -51,6 +51,6 @@ func TestIfDeployPageExist(t *testing.T) {
}
w
.
Flush
()
helper
.
AssertResponseCode
(
t
,
w
,
200
)
helper
.
AssertResponseBody
(
t
,
w
,
deployPage
)
test
helper
.
AssertResponseCode
(
t
,
w
,
200
)
test
helper
.
AssertResponseBody
(
t
,
w
,
deployPage
)
}
internal/staticpages/error_pages_test.go
View file @
e845314b
package
staticpages
import
(
"../helper"
"../
test
helper"
"fmt"
"io/ioutil"
"net/http"
...
...
@@ -30,8 +30,8 @@ func TestIfErrorPageIsPresented(t *testing.T) {
st
.
ErrorPages
(
true
,
h
)
.
ServeHTTP
(
w
,
nil
)
w
.
Flush
()
helper
.
AssertResponseCode
(
t
,
w
,
404
)
helper
.
AssertResponseBody
(
t
,
w
,
errorPage
)
test
helper
.
AssertResponseCode
(
t
,
w
,
404
)
test
helper
.
AssertResponseBody
(
t
,
w
,
errorPage
)
}
func
TestIfErrorPassedIfNoErrorPageIsFound
(
t
*
testing
.
T
)
{
...
...
@@ -51,8 +51,8 @@ func TestIfErrorPassedIfNoErrorPageIsFound(t *testing.T) {
st
.
ErrorPages
(
true
,
h
)
.
ServeHTTP
(
w
,
nil
)
w
.
Flush
()
helper
.
AssertResponseCode
(
t
,
w
,
404
)
helper
.
AssertResponseBody
(
t
,
w
,
errorResponse
)
test
helper
.
AssertResponseCode
(
t
,
w
,
404
)
test
helper
.
AssertResponseBody
(
t
,
w
,
errorResponse
)
}
func
TestIfErrorPageIsIgnoredInDevelopment
(
t
*
testing
.
T
)
{
...
...
@@ -74,6 +74,6 @@ func TestIfErrorPageIsIgnoredInDevelopment(t *testing.T) {
st
:=
&
Static
{
dir
}
st
.
ErrorPages
(
false
,
h
)
.
ServeHTTP
(
w
,
nil
)
w
.
Flush
()
helper
.
AssertResponseCode
(
t
,
w
,
500
)
helper
.
AssertResponseBody
(
t
,
w
,
serverError
)
test
helper
.
AssertResponseCode
(
t
,
w
,
500
)
test
helper
.
AssertResponseBody
(
t
,
w
,
serverError
)
}
internal/staticpages/servefile_test.go
View file @
e845314b
package
staticpages
import
(
"../helper"
"../
test
helper"
"bytes"
"compress/gzip"
"io/ioutil"
...
...
@@ -19,7 +19,7 @@ func TestServingNonExistingFile(t *testing.T) {
w
:=
httptest
.
NewRecorder
()
st
:=
&
Static
{
dir
}
st
.
ServeExisting
(
"/"
,
CacheDisabled
,
nil
)
.
ServeHTTP
(
w
,
httpRequest
)
helper
.
AssertResponseCode
(
t
,
w
,
404
)
test
helper
.
AssertResponseCode
(
t
,
w
,
404
)
}
func
TestServingDirectory
(
t
*
testing
.
T
)
{
...
...
@@ -33,7 +33,7 @@ func TestServingDirectory(t *testing.T) {
w
:=
httptest
.
NewRecorder
()
st
:=
&
Static
{
dir
}
st
.
ServeExisting
(
"/"
,
CacheDisabled
,
nil
)
.
ServeHTTP
(
w
,
httpRequest
)
helper
.
AssertResponseCode
(
t
,
w
,
404
)
test
helper
.
AssertResponseCode
(
t
,
w
,
404
)
}
func
TestServingMalformedUri
(
t
*
testing
.
T
)
{
...
...
@@ -43,7 +43,7 @@ func TestServingMalformedUri(t *testing.T) {
w
:=
httptest
.
NewRecorder
()
st
:=
&
Static
{
dir
}
st
.
ServeExisting
(
"/"
,
CacheDisabled
,
nil
)
.
ServeHTTP
(
w
,
httpRequest
)
helper
.
AssertResponseCode
(
t
,
w
,
404
)
test
helper
.
AssertResponseCode
(
t
,
w
,
404
)
}
func
TestExecutingHandlerWhenNoFileFound
(
t
*
testing
.
T
)
{
...
...
@@ -75,7 +75,7 @@ func TestServingTheActualFile(t *testing.T) {
w
:=
httptest
.
NewRecorder
()
st
:=
&
Static
{
dir
}
st
.
ServeExisting
(
"/"
,
CacheDisabled
,
nil
)
.
ServeHTTP
(
w
,
httpRequest
)
helper
.
AssertResponseCode
(
t
,
w
,
200
)
test
helper
.
AssertResponseCode
(
t
,
w
,
200
)
if
w
.
Body
.
String
()
!=
fileContent
{
t
.
Error
(
"We should serve the file: "
,
w
.
Body
.
String
())
}
...
...
@@ -107,15 +107,15 @@ func testServingThePregzippedFile(t *testing.T, enableGzip bool) {
w
:=
httptest
.
NewRecorder
()
st
:=
&
Static
{
dir
}
st
.
ServeExisting
(
"/"
,
CacheDisabled
,
nil
)
.
ServeHTTP
(
w
,
httpRequest
)
helper
.
AssertResponseCode
(
t
,
w
,
200
)
test
helper
.
AssertResponseCode
(
t
,
w
,
200
)
if
enableGzip
{
helper
.
AssertResponseHeader
(
t
,
w
,
"Content-Encoding"
,
"gzip"
)
test
helper
.
AssertResponseHeader
(
t
,
w
,
"Content-Encoding"
,
"gzip"
)
if
bytes
.
Compare
(
w
.
Body
.
Bytes
(),
fileGzipContent
.
Bytes
())
!=
0
{
t
.
Error
(
"We should serve the pregzipped file"
)
}
}
else
{
helper
.
AssertResponseCode
(
t
,
w
,
200
)
helper
.
AssertResponseHeader
(
t
,
w
,
"Content-Encoding"
,
""
)
test
helper
.
AssertResponseCode
(
t
,
w
,
200
)
test
helper
.
AssertResponseHeader
(
t
,
w
,
"Content-Encoding"
,
""
)
if
w
.
Body
.
String
()
!=
fileContent
{
t
.
Error
(
"We should serve the file: "
,
w
.
Body
.
String
())
}
...
...
internal/upload/uploads_test.go
View file @
e845314b
...
...
@@ -3,6 +3,7 @@ package upload
import
(
"../helper"
"../proxy"
"../testhelper"
"bytes"
"fmt"
"io"
...
...
@@ -22,11 +23,11 @@ func TestUploadTempPathRequirement(t *testing.T) {
response
:=
httptest
.
NewRecorder
()
request
:=
&
http
.
Request
{}
handleFileUploads
(
nilHandler
)
.
ServeHTTP
(
response
,
request
)
helper
.
AssertResponseCode
(
t
,
response
,
500
)
test
helper
.
AssertResponseCode
(
t
,
response
,
500
)
}
func
TestUploadHandlerForwardingRawData
(
t
*
testing
.
T
)
{
ts
:=
helper
.
TestServerWithHandler
(
regexp
.
MustCompile
(
`/url/path\z`
),
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
ts
:=
test
helper
.
TestServerWithHandler
(
regexp
.
MustCompile
(
`/url/path\z`
),
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
if
r
.
Method
!=
"PATCH"
{
t
.
Fatal
(
"Expected PATCH request"
)
}
...
...
@@ -58,7 +59,7 @@ func TestUploadHandlerForwardingRawData(t *testing.T) {
httpRequest
.
Header
.
Set
(
tempPathHeader
,
tempPath
)
handleFileUploads
(
proxy
.
NewProxy
(
helper
.
URLMustParse
(
ts
.
URL
),
"123"
,
nil
))
.
ServeHTTP
(
response
,
httpRequest
)
helper
.
AssertResponseCode
(
t
,
response
,
202
)
test
helper
.
AssertResponseCode
(
t
,
response
,
202
)
if
response
.
Body
.
String
()
!=
"RESPONSE"
{
t
.
Fatal
(
"Expected RESPONSE in response body"
)
}
...
...
@@ -73,7 +74,7 @@ func TestUploadHandlerRewritingMultiPartData(t *testing.T) {
}
defer
os
.
RemoveAll
(
tempPath
)
ts
:=
helper
.
TestServerWithHandler
(
regexp
.
MustCompile
(
`/url/path\z`
),
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
ts
:=
test
helper
.
TestServerWithHandler
(
regexp
.
MustCompile
(
`/url/path\z`
),
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
if
r
.
Method
!=
"PUT"
{
t
.
Fatal
(
"Expected PUT request"
)
}
...
...
@@ -132,7 +133,7 @@ func TestUploadHandlerRewritingMultiPartData(t *testing.T) {
response
:=
httptest
.
NewRecorder
()
handleFileUploads
(
proxy
.
NewProxy
(
helper
.
URLMustParse
(
ts
.
URL
),
"123"
,
nil
))
.
ServeHTTP
(
response
,
httpRequest
)
helper
.
AssertResponseCode
(
t
,
response
,
202
)
test
helper
.
AssertResponseCode
(
t
,
response
,
202
)
if
_
,
err
:=
os
.
Stat
(
filePath
);
!
os
.
IsNotExist
(
err
)
{
t
.
Fatal
(
"expected the file to be deleted"
)
...
...
internal/upstream/development_test.go
View file @
e845314b
package
upstream
import
(
"../helper"
"../
test
helper"
"net/http"
"net/http/httptest"
"testing"
...
...
@@ -35,5 +35,5 @@ func TestDevelopmentModeDisabled(t *testing.T) {
if
executed
{
t
.
Error
(
"The handler should not get executed"
)
}
helper
.
AssertResponseCode
(
t
,
w
,
404
)
test
helper
.
AssertResponseCode
(
t
,
w
,
404
)
}
internal/upstream/handlers_test.go
View file @
e845314b
package
upstream
import
(
"../helper"
"../
test
helper"
"bytes"
"compress/gzip"
"fmt"
...
...
@@ -37,7 +37,7 @@ func TestGzipEncoding(t *testing.T) {
}
}))
.
ServeHTTP
(
resp
,
req
)
helper
.
AssertResponseCode
(
t
,
resp
,
200
)
test
helper
.
AssertResponseCode
(
t
,
resp
,
200
)
}
func
TestNoEncoding
(
t
*
testing
.
T
)
{
...
...
@@ -61,7 +61,7 @@ func TestNoEncoding(t *testing.T) {
}
}))
.
ServeHTTP
(
resp
,
req
)
helper
.
AssertResponseCode
(
t
,
resp
,
200
)
test
helper
.
AssertResponseCode
(
t
,
resp
,
200
)
}
func
TestInvalidEncoding
(
t
*
testing
.
T
)
{
...
...
@@ -77,5 +77,5 @@ func TestInvalidEncoding(t *testing.T) {
t
.
Fatal
(
"it shouldn't be executed"
)
}))
.
ServeHTTP
(
resp
,
req
)
helper
.
AssertResponseCode
(
t
,
resp
,
500
)
test
helper
.
AssertResponseCode
(
t
,
resp
,
500
)
}
main_test.go
View file @
e845314b
...
...
@@ -3,6 +3,7 @@ package main
import
(
"./internal/api"
"./internal/helper"
"./internal/testhelper"
"./internal/upstream"
"bytes"
"encoding/json"
...
...
@@ -329,7 +330,7 @@ func TestAllowedStaticFile(t *testing.T) {
}
proxied
:=
false
ts
:=
helper
.
TestServerWithHandler
(
regexp
.
MustCompile
(
`.`
),
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
ts
:=
test
helper
.
TestServerWithHandler
(
regexp
.
MustCompile
(
`.`
),
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
proxied
=
true
w
.
WriteHeader
(
404
)
})
...
...
@@ -369,7 +370,7 @@ func TestAllowedPublicUploadsFile(t *testing.T) {
}
proxied
:=
false
ts
:=
helper
.
TestServerWithHandler
(
regexp
.
MustCompile
(
`.`
),
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
ts
:=
test
helper
.
TestServerWithHandler
(
regexp
.
MustCompile
(
`.`
),
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
proxied
=
true
w
.
Header
()
.
Add
(
"X-Sendfile"
,
*
documentRoot
+
r
.
URL
.
Path
)
w
.
WriteHeader
(
200
)
...
...
@@ -410,7 +411,7 @@ func TestDeniedPublicUploadsFile(t *testing.T) {
}
proxied
:=
false
ts
:=
helper
.
TestServerWithHandler
(
regexp
.
MustCompile
(
`.`
),
func
(
w
http
.
ResponseWriter
,
_
*
http
.
Request
)
{
ts
:=
test
helper
.
TestServerWithHandler
(
regexp
.
MustCompile
(
`.`
),
func
(
w
http
.
ResponseWriter
,
_
*
http
.
Request
)
{
proxied
=
true
w
.
WriteHeader
(
404
)
})
...
...
@@ -453,7 +454,7 @@ func TestArtifactsUpload(t *testing.T) {
fmt
.
Fprint
(
file
,
"SHOULD BE ON DISK, NOT IN MULTIPART"
)
writer
.
Close
()
ts
:=
helper
.
TestServerWithHandler
(
regexp
.
MustCompile
(
`.`
),
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
ts
:=
test
helper
.
TestServerWithHandler
(
regexp
.
MustCompile
(
`.`
),
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
if
strings
.
HasSuffix
(
r
.
URL
.
Path
,
"/authorize"
)
{
if
_
,
err
:=
fmt
.
Fprintf
(
w
,
`{"TempPath":"%s"}`
,
scratchDir
);
err
!=
nil
{
t
.
Fatal
(
err
)
...
...
@@ -525,7 +526,7 @@ func newBranch() string {
}
func
testAuthServer
(
url
*
regexp
.
Regexp
,
code
int
,
body
interface
{})
*
httptest
.
Server
{
return
helper
.
TestServerWithHandler
(
url
,
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
return
test
helper
.
TestServerWithHandler
(
url
,
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
// Write pure string
if
data
,
ok
:=
body
.
(
string
);
ok
{
log
.
Println
(
"UPSTREAM"
,
r
.
Method
,
r
.
URL
,
code
)
...
...
proxy_test.go
View file @
e845314b
...
...
@@ -4,6 +4,7 @@ import (
"./internal/badgateway"
"./internal/helper"
"./internal/proxy"
"./internal/testhelper"
"bytes"
"fmt"
"io"
...
...
@@ -20,7 +21,7 @@ func newProxy(url string, rt *badgateway.RoundTripper) *proxy.Proxy {
}
func
TestProxyRequest
(
t
*
testing
.
T
)
{
ts
:=
helper
.
TestServerWithHandler
(
regexp
.
MustCompile
(
`/url/path\z`
),
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
ts
:=
test
helper
.
TestServerWithHandler
(
regexp
.
MustCompile
(
`/url/path\z`
),
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
if
r
.
Method
!=
"POST"
{
t
.
Fatal
(
"Expected POST request"
)
}
...
...
@@ -48,8 +49,8 @@ func TestProxyRequest(t *testing.T) {
w
:=
httptest
.
NewRecorder
()
newProxy
(
ts
.
URL
,
nil
)
.
ServeHTTP
(
w
,
httpRequest
)
helper
.
AssertResponseCode
(
t
,
w
,
202
)
helper
.
AssertResponseBody
(
t
,
w
,
"RESPONSE"
)
test
helper
.
AssertResponseCode
(
t
,
w
,
202
)
test
helper
.
AssertResponseBody
(
t
,
w
,
"RESPONSE"
)
if
w
.
Header
()
.
Get
(
"Custom-Response-Header"
)
!=
"test"
{
t
.
Fatal
(
"Expected custom response header"
)
...
...
@@ -65,12 +66,12 @@ func TestProxyError(t *testing.T) {
w
:=
httptest
.
NewRecorder
()
newProxy
(
"http://localhost:655575/"
,
nil
)
.
ServeHTTP
(
w
,
httpRequest
)
helper
.
AssertResponseCode
(
t
,
w
,
502
)
helper
.
AssertResponseBody
(
t
,
w
,
"dial tcp: invalid port 655575"
)
test
helper
.
AssertResponseCode
(
t
,
w
,
502
)
test
helper
.
AssertResponseBody
(
t
,
w
,
"dial tcp: invalid port 655575"
)
}
func
TestProxyReadTimeout
(
t
*
testing
.
T
)
{
ts
:=
helper
.
TestServerWithHandler
(
nil
,
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
ts
:=
test
helper
.
TestServerWithHandler
(
nil
,
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
time
.
Sleep
(
time
.
Minute
)
})
...
...
@@ -94,12 +95,12 @@ func TestProxyReadTimeout(t *testing.T) {
p
:=
newProxy
(
ts
.
URL
,
rt
)
w
:=
httptest
.
NewRecorder
()
p
.
ServeHTTP
(
w
,
httpRequest
)
helper
.
AssertResponseCode
(
t
,
w
,
502
)
helper
.
AssertResponseBody
(
t
,
w
,
"net/http: timeout awaiting response headers"
)
test
helper
.
AssertResponseCode
(
t
,
w
,
502
)
test
helper
.
AssertResponseBody
(
t
,
w
,
"net/http: timeout awaiting response headers"
)
}
func
TestProxyHandlerTimeout
(
t
*
testing
.
T
)
{
ts
:=
helper
.
TestServerWithHandler
(
nil
,
ts
:=
test
helper
.
TestServerWithHandler
(
nil
,
http
.
TimeoutHandler
(
http
.
HandlerFunc
(
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
time
.
Sleep
(
time
.
Second
)
}),
time
.
Millisecond
,
"Request took too long"
)
.
ServeHTTP
,
...
...
@@ -112,6 +113,6 @@ func TestProxyHandlerTimeout(t *testing.T) {
w
:=
httptest
.
NewRecorder
()
newProxy
(
ts
.
URL
,
nil
)
.
ServeHTTP
(
w
,
httpRequest
)
helper
.
AssertResponseCode
(
t
,
w
,
503
)
helper
.
AssertResponseBody
(
t
,
w
,
"Request took too long"
)
test
helper
.
AssertResponseCode
(
t
,
w
,
503
)
test
helper
.
AssertResponseBody
(
t
,
w
,
"Request took too long"
)
}
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