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
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-workhorse
Commits
e7a352d9
Commit
e7a352d9
authored
Mar 08, 2017
by
Nick Thomas
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch '110-support-v4-ci-api' into 'master'
Support v4 CI API Closes #110 See merge request !133
parents
18c22793
b06db824
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
930 additions
and
13 deletions
+930
-13
internal/upstream/routes.go
internal/upstream/routes.go
+3
-1
jobs_test.go
jobs_test.go
+60
-0
upload_test.go
upload_test.go
+28
-12
vendor/github.com/stretchr/testify/require/doc.go
vendor/github.com/stretchr/testify/require/doc.go
+28
-0
vendor/github.com/stretchr/testify/require/forward_requirements.go
...thub.com/stretchr/testify/require/forward_requirements.go
+16
-0
vendor/github.com/stretchr/testify/require/require.go
vendor/github.com/stretchr/testify/require/require.go
+423
-0
vendor/github.com/stretchr/testify/require/require.go.tmpl
vendor/github.com/stretchr/testify/require/require.go.tmpl
+6
-0
vendor/github.com/stretchr/testify/require/require_forward.go
...or/github.com/stretchr/testify/require/require_forward.go
+347
-0
vendor/github.com/stretchr/testify/require/require_forward.go.tmpl
...thub.com/stretchr/testify/require/require_forward.go.tmpl
+4
-0
vendor/github.com/stretchr/testify/require/requirements.go
vendor/github.com/stretchr/testify/require/requirements.go
+9
-0
vendor/vendor.json
vendor/vendor.json
+6
-0
No files found.
internal/upstream/routes.go
View file @
e7a352d9
...
@@ -130,12 +130,14 @@ func (u *Upstream) configureRoutes() {
...
@@ -130,12 +130,14 @@ func (u *Upstream) configureRoutes() {
route
(
"PUT"
,
gitProjectPattern
+
`gitlab-lfs/objects/([0-9a-f]{64})/([0-9]+)\z`
,
lfs
.
PutStore
(
api
,
proxy
),
isContentType
(
"application/octet-stream"
)),
route
(
"PUT"
,
gitProjectPattern
+
`gitlab-lfs/objects/([0-9a-f]{64})/([0-9]+)\z`
,
lfs
.
PutStore
(
api
,
proxy
),
isContentType
(
"application/octet-stream"
)),
// CI Artifacts
// CI Artifacts
route
(
"POST"
,
apiPattern
+
`v4/jobs/[0-9]+/artifacts\z`
,
contentEncodingHandler
(
artifacts
.
UploadArtifacts
(
api
,
proxy
))),
route
(
"POST"
,
ciAPIPattern
+
`v1/builds/[0-9]+/artifacts\z`
,
contentEncodingHandler
(
artifacts
.
UploadArtifacts
(
api
,
proxy
))),
route
(
"POST"
,
ciAPIPattern
+
`v1/builds/[0-9]+/artifacts\z`
,
contentEncodingHandler
(
artifacts
.
UploadArtifacts
(
api
,
proxy
))),
// Terminal websocket
// Terminal websocket
wsRoute
(
projectPattern
+
`environments/[0-9]+/terminal.ws\z`
,
terminal
.
Handler
(
api
)),
wsRoute
(
projectPattern
+
`environments/[0-9]+/terminal.ws\z`
,
terminal
.
Handler
(
api
)),
// Long poll and limit capacity given to builds/register.json
// Long poll and limit capacity given to jobs/request and builds/register.json
route
(
""
,
apiPattern
+
`v4/jobs/request\z`
,
ciAPILongPolling
),
route
(
""
,
ciAPIPattern
+
`v1/builds/register.json\z`
,
ciAPILongPolling
),
route
(
""
,
ciAPIPattern
+
`v1/builds/register.json\z`
,
ciAPILongPolling
),
// Explicitly proxy API requests
// Explicitly proxy API requests
...
...
build
s_test.go
→
job
s_test.go
View file @
e7a352d9
...
@@ -16,29 +16,45 @@ func startWorkhorseServerWithLongPolling(authBackend string, pollingDuration tim
...
@@ -16,29 +16,45 @@ func startWorkhorseServerWithLongPolling(authBackend string, pollingDuration tim
return
startWorkhorseServerWithConfig
(
uc
)
return
startWorkhorseServerWithConfig
(
uc
)
}
}
func
postBuildsRegister
(
url
string
,
body
io
.
Reader
)
(
*
http
.
Response
,
error
)
{
type
requestJobFunction
func
(
url
string
,
body
io
.
Reader
)
(
*
http
.
Response
,
error
)
func
requestJobV1
(
url
string
,
body
io
.
Reader
)
(
*
http
.
Response
,
error
)
{
resource
:=
`/ci/api/v1/builds/register.json`
resource
:=
`/ci/api/v1/builds/register.json`
return
http
.
Post
(
url
+
resource
,
`application/json`
,
body
)
return
http
.
Post
(
url
+
resource
,
`application/json`
,
body
)
}
}
func
TestBuildsLongPullingEndpointDisabled
(
t
*
testing
.
T
)
{
func
requestJobV4
(
url
string
,
body
io
.
Reader
)
(
*
http
.
Response
,
error
)
{
ws
:=
startWorkhorseServerWithLongPolling
(
"http://localhost/"
,
0
)
resource
:=
`/api/v4/jobs/request`
return
http
.
Post
(
url
+
resource
,
`application/json`
,
body
)
}
func
testJobsLongPolling
(
t
*
testing
.
T
,
pollingDuration
time
.
Duration
,
requestJob
requestJobFunction
)
*
http
.
Response
{
ws
:=
startWorkhorseServerWithLongPolling
(
"http://localhost/"
,
pollingDuration
)
defer
ws
.
Close
()
defer
ws
.
Close
()
resp
,
err
:=
postBuildsRegister
(
ws
.
URL
,
nil
)
resp
,
err
:=
requestJob
(
ws
.
URL
,
nil
)
assert
.
NoError
(
t
,
err
)
assert
.
NoError
(
t
,
err
)
defer
resp
.
Body
.
Close
()
defer
resp
.
Body
.
Close
()
return
resp
}
func
testJobsLongPollingEndpointDisabled
(
t
*
testing
.
T
,
requestJob
requestJobFunction
)
{
resp
:=
testJobsLongPolling
(
t
,
0
,
requestJob
)
assert
.
NotEqual
(
t
,
"yes"
,
resp
.
Header
.
Get
(
"Gitlab-Ci-Builds-Polling"
))
assert
.
NotEqual
(
t
,
"yes"
,
resp
.
Header
.
Get
(
"Gitlab-Ci-Builds-Polling"
))
}
}
func
TestBuildsLongPullingEndpoint
(
t
*
testing
.
T
)
{
func
testJobsLongPollingEndpoint
(
t
*
testing
.
T
,
requestJob
requestJobFunction
)
{
ws
:=
startWorkhorseServerWithLongPolling
(
"http://localhost/"
,
time
.
Minute
)
resp
:=
testJobsLongPolling
(
t
,
time
.
Minute
,
requestJob
)
defer
ws
.
Close
()
assert
.
Equal
(
t
,
"yes"
,
resp
.
Header
.
Get
(
"Gitlab-Ci-Builds-Polling"
))
}
resp
,
err
:=
postBuildsRegister
(
ws
.
URL
,
nil
)
func
TestJobsLongPollingEndpointDisabled
(
t
*
testing
.
T
)
{
assert
.
NoError
(
t
,
err
)
testJobsLongPollingEndpointDisabled
(
t
,
requestJobV1
)
defer
resp
.
Body
.
Close
()
testJobsLongPollingEndpointDisabled
(
t
,
requestJobV4
)
}
assert
.
Equal
(
t
,
"yes"
,
resp
.
Header
.
Get
(
"Gitlab-Ci-Builds-Polling"
))
func
TestJobsLongPollingEndpoint
(
t
*
testing
.
T
)
{
testJobsLongPollingEndpoint
(
t
,
requestJobV1
)
testJobsLongPollingEndpoint
(
t
,
requestJobV4
)
}
}
upload_test.go
View file @
e7a352d9
...
@@ -17,28 +17,44 @@ import (
...
@@ -17,28 +17,44 @@ import (
"gitlab.com/gitlab-org/gitlab-workhorse/internal/upload"
"gitlab.com/gitlab-org/gitlab-workhorse/internal/upload"
"github.com/dgrijalva/jwt-go"
"github.com/dgrijalva/jwt-go"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
)
func
TestArtifactsUpload
(
t
*
testing
.
T
)
{
type
uploadArtifactsFunction
func
(
url
,
contentType
string
,
body
io
.
Reader
)
(
*
http
.
Response
,
error
,
string
)
func
uploadArtifactsV1
(
url
,
contentType
string
,
body
io
.
Reader
)
(
*
http
.
Response
,
error
,
string
)
{
resource
:=
`/ci/api/v1/builds/123/artifacts`
resp
,
err
:=
http
.
Post
(
url
+
resource
,
contentType
,
body
)
return
resp
,
err
,
resource
}
func
uploadArtifactsV4
(
url
,
contentType
string
,
body
io
.
Reader
)
(
*
http
.
Response
,
error
,
string
)
{
resource
:=
`/api/v4/jobs/123/artifacts`
resp
,
err
:=
http
.
Post
(
url
+
resource
,
contentType
,
body
)
return
resp
,
err
,
resource
}
func
testArtifactsUpload
(
t
*
testing
.
T
,
uploadArtifacts
uploadArtifactsFunction
)
{
reqBody
,
contentType
,
err
:=
multipartBodyWithFile
()
reqBody
,
contentType
,
err
:=
multipartBodyWithFile
()
if
err
!=
nil
{
require
.
NoError
(
t
,
err
)
t
.
Fatal
(
err
)
}
ts
:=
uploadTestServer
(
t
,
nil
)
ts
:=
uploadTestServer
(
t
,
nil
)
defer
ts
.
Close
()
defer
ts
.
Close
()
ws
:=
startWorkhorseServer
(
ts
.
URL
)
ws
:=
startWorkhorseServer
(
ts
.
URL
)
defer
ws
.
Close
()
defer
ws
.
Close
()
resource
:=
`/ci/api/v1/builds/123/artifacts`
resp
,
err
,
resource
:=
uploadArtifacts
(
ws
.
URL
,
contentType
,
reqBody
)
resp
,
err
:=
http
.
Post
(
ws
.
URL
+
resource
,
contentType
,
reqBody
)
assert
.
NoError
(
t
,
err
)
if
err
!=
nil
{
t
.
Error
(
err
)
}
defer
resp
.
Body
.
Close
()
defer
resp
.
Body
.
Close
()
if
resp
.
StatusCode
!=
200
{
t
.
Errorf
(
"GET %q: expected 200, got %d"
,
resource
,
resp
.
StatusCode
)
assert
.
Equal
(
t
,
200
,
resp
.
StatusCode
,
"GET %q: expected 200, got %d"
,
resource
,
resp
.
StatusCode
)
}
}
func
TestArtifactsUpload
(
t
*
testing
.
T
)
{
testArtifactsUpload
(
t
,
uploadArtifactsV1
)
testArtifactsUpload
(
t
,
uploadArtifactsV4
)
}
}
func
uploadTestServer
(
t
*
testing
.
T
,
extraTests
func
(
r
*
http
.
Request
))
*
httptest
.
Server
{
func
uploadTestServer
(
t
*
testing
.
T
,
extraTests
func
(
r
*
http
.
Request
))
*
httptest
.
Server
{
...
...
vendor/github.com/stretchr/testify/require/doc.go
0 → 100644
View file @
e7a352d9
// Package require implements the same assertions as the `assert` package but
// stops test execution when a test fails.
//
// Example Usage
//
// The following is a complete example using require in a standard test function:
// import (
// "testing"
// "github.com/stretchr/testify/require"
// )
//
// func TestSomething(t *testing.T) {
//
// var a string = "Hello"
// var b string = "Hello"
//
// require.Equal(t, a, b, "The two words should be the same.")
//
// }
//
// Assertions
//
// The `require` package have same global functions as in the `assert` package,
// but instead of returning a boolean result they call `t.FailNow()`.
//
// Every assertion function also takes an optional string message as the final argument,
// allowing custom error messages to be appended to the message the assertion method outputs.
package
require
vendor/github.com/stretchr/testify/require/forward_requirements.go
0 → 100644
View file @
e7a352d9
package
require
// Assertions provides assertion methods around the
// TestingT interface.
type
Assertions
struct
{
t
TestingT
}
// New makes a new Assertions object for the specified TestingT.
func
New
(
t
TestingT
)
*
Assertions
{
return
&
Assertions
{
t
:
t
,
}
}
//go:generate go run ../_codegen/main.go -output-package=require -template=require_forward.go.tmpl
vendor/github.com/stretchr/testify/require/require.go
0 → 100644
View file @
e7a352d9
/*
* CODE GENERATED AUTOMATICALLY WITH github.com/stretchr/testify/_codegen
* THIS FILE MUST NOT BE EDITED BY HAND
*/
package
require
import
(
assert
"github.com/stretchr/testify/assert"
http
"net/http"
url
"net/url"
time
"time"
)
// Condition uses a Comparison to assert a complex condition.
func
Condition
(
t
TestingT
,
comp
assert
.
Comparison
,
msgAndArgs
...
interface
{})
{
if
!
assert
.
Condition
(
t
,
comp
,
msgAndArgs
...
)
{
t
.
FailNow
()
}
}
// Contains asserts that the specified string, list(array, slice...) or map contains the
// specified substring or element.
//
// assert.Contains(t, "Hello World", "World", "But 'Hello World' does contain 'World'")
// assert.Contains(t, ["Hello", "World"], "World", "But ["Hello", "World"] does contain 'World'")
// assert.Contains(t, {"Hello": "World"}, "Hello", "But {'Hello': 'World'} does contain 'Hello'")
//
// Returns whether the assertion was successful (true) or not (false).
func
Contains
(
t
TestingT
,
s
interface
{},
contains
interface
{},
msgAndArgs
...
interface
{})
{
if
!
assert
.
Contains
(
t
,
s
,
contains
,
msgAndArgs
...
)
{
t
.
FailNow
()
}
}
// Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either
// a slice or a channel with len == 0.
//
// assert.Empty(t, obj)
//
// Returns whether the assertion was successful (true) or not (false).
func
Empty
(
t
TestingT
,
object
interface
{},
msgAndArgs
...
interface
{})
{
if
!
assert
.
Empty
(
t
,
object
,
msgAndArgs
...
)
{
t
.
FailNow
()
}
}
// Equal asserts that two objects are equal.
//
// assert.Equal(t, 123, 123, "123 and 123 should be equal")
//
// Returns whether the assertion was successful (true) or not (false).
func
Equal
(
t
TestingT
,
expected
interface
{},
actual
interface
{},
msgAndArgs
...
interface
{})
{
if
!
assert
.
Equal
(
t
,
expected
,
actual
,
msgAndArgs
...
)
{
t
.
FailNow
()
}
}
// EqualError asserts that a function returned an error (i.e. not `nil`)
// and that it is equal to the provided error.
//
// actualObj, err := SomeFunction()
// assert.EqualError(t, err, expectedErrorString, "An error was expected")
//
// Returns whether the assertion was successful (true) or not (false).
func
EqualError
(
t
TestingT
,
theError
error
,
errString
string
,
msgAndArgs
...
interface
{})
{
if
!
assert
.
EqualError
(
t
,
theError
,
errString
,
msgAndArgs
...
)
{
t
.
FailNow
()
}
}
// EqualValues asserts that two objects are equal or convertable to the same types
// and equal.
//
// assert.EqualValues(t, uint32(123), int32(123), "123 and 123 should be equal")
//
// Returns whether the assertion was successful (true) or not (false).
func
EqualValues
(
t
TestingT
,
expected
interface
{},
actual
interface
{},
msgAndArgs
...
interface
{})
{
if
!
assert
.
EqualValues
(
t
,
expected
,
actual
,
msgAndArgs
...
)
{
t
.
FailNow
()
}
}
// Error asserts that a function returned an error (i.e. not `nil`).
//
// actualObj, err := SomeFunction()
// if assert.Error(t, err, "An error was expected") {
// assert.Equal(t, err, expectedError)
// }
//
// Returns whether the assertion was successful (true) or not (false).
func
Error
(
t
TestingT
,
err
error
,
msgAndArgs
...
interface
{})
{
if
!
assert
.
Error
(
t
,
err
,
msgAndArgs
...
)
{
t
.
FailNow
()
}
}
// Exactly asserts that two objects are equal is value and type.
//
// assert.Exactly(t, int32(123), int64(123), "123 and 123 should NOT be equal")
//
// Returns whether the assertion was successful (true) or not (false).
func
Exactly
(
t
TestingT
,
expected
interface
{},
actual
interface
{},
msgAndArgs
...
interface
{})
{
if
!
assert
.
Exactly
(
t
,
expected
,
actual
,
msgAndArgs
...
)
{
t
.
FailNow
()
}
}
// Fail reports a failure through
func
Fail
(
t
TestingT
,
failureMessage
string
,
msgAndArgs
...
interface
{})
{
if
!
assert
.
Fail
(
t
,
failureMessage
,
msgAndArgs
...
)
{
t
.
FailNow
()
}
}
// FailNow fails test
func
FailNow
(
t
TestingT
,
failureMessage
string
,
msgAndArgs
...
interface
{})
{
if
!
assert
.
FailNow
(
t
,
failureMessage
,
msgAndArgs
...
)
{
t
.
FailNow
()
}
}
// False asserts that the specified value is false.
//
// assert.False(t, myBool, "myBool should be false")
//
// Returns whether the assertion was successful (true) or not (false).
func
False
(
t
TestingT
,
value
bool
,
msgAndArgs
...
interface
{})
{
if
!
assert
.
False
(
t
,
value
,
msgAndArgs
...
)
{
t
.
FailNow
()
}
}
// HTTPBodyContains asserts that a specified handler returns a
// body that contains a string.
//
// assert.HTTPBodyContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky")
//
// Returns whether the assertion was successful (true) or not (false).
func
HTTPBodyContains
(
t
TestingT
,
handler
http
.
HandlerFunc
,
method
string
,
url
string
,
values
url
.
Values
,
str
interface
{})
{
if
!
assert
.
HTTPBodyContains
(
t
,
handler
,
method
,
url
,
values
,
str
)
{
t
.
FailNow
()
}
}
// HTTPBodyNotContains asserts that a specified handler returns a
// body that does not contain a string.
//
// assert.HTTPBodyNotContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky")
//
// Returns whether the assertion was successful (true) or not (false).
func
HTTPBodyNotContains
(
t
TestingT
,
handler
http
.
HandlerFunc
,
method
string
,
url
string
,
values
url
.
Values
,
str
interface
{})
{
if
!
assert
.
HTTPBodyNotContains
(
t
,
handler
,
method
,
url
,
values
,
str
)
{
t
.
FailNow
()
}
}
// HTTPError asserts that a specified handler returns an error status code.
//
// assert.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}}
//
// Returns whether the assertion was successful (true) or not (false).
func
HTTPError
(
t
TestingT
,
handler
http
.
HandlerFunc
,
method
string
,
url
string
,
values
url
.
Values
)
{
if
!
assert
.
HTTPError
(
t
,
handler
,
method
,
url
,
values
)
{
t
.
FailNow
()
}
}
// HTTPRedirect asserts that a specified handler returns a redirect status code.
//
// assert.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}}
//
// Returns whether the assertion was successful (true) or not (false).
func
HTTPRedirect
(
t
TestingT
,
handler
http
.
HandlerFunc
,
method
string
,
url
string
,
values
url
.
Values
)
{
if
!
assert
.
HTTPRedirect
(
t
,
handler
,
method
,
url
,
values
)
{
t
.
FailNow
()
}
}
// HTTPSuccess asserts that a specified handler returns a success status code.
//
// assert.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil)
//
// Returns whether the assertion was successful (true) or not (false).
func
HTTPSuccess
(
t
TestingT
,
handler
http
.
HandlerFunc
,
method
string
,
url
string
,
values
url
.
Values
)
{
if
!
assert
.
HTTPSuccess
(
t
,
handler
,
method
,
url
,
values
)
{
t
.
FailNow
()
}
}
// Implements asserts that an object is implemented by the specified interface.
//
// assert.Implements(t, (*MyInterface)(nil), new(MyObject), "MyObject")
func
Implements
(
t
TestingT
,
interfaceObject
interface
{},
object
interface
{},
msgAndArgs
...
interface
{})
{
if
!
assert
.
Implements
(
t
,
interfaceObject
,
object
,
msgAndArgs
...
)
{
t
.
FailNow
()
}
}
// InDelta asserts that the two numerals are within delta of each other.
//
// assert.InDelta(t, math.Pi, (22 / 7.0), 0.01)
//
// Returns whether the assertion was successful (true) or not (false).
func
InDelta
(
t
TestingT
,
expected
interface
{},
actual
interface
{},
delta
float64
,
msgAndArgs
...
interface
{})
{
if
!
assert
.
InDelta
(
t
,
expected
,
actual
,
delta
,
msgAndArgs
...
)
{
t
.
FailNow
()
}
}
// InDeltaSlice is the same as InDelta, except it compares two slices.
func
InDeltaSlice
(
t
TestingT
,
expected
interface
{},
actual
interface
{},
delta
float64
,
msgAndArgs
...
interface
{})
{
if
!
assert
.
InDeltaSlice
(
t
,
expected
,
actual
,
delta
,
msgAndArgs
...
)
{
t
.
FailNow
()
}
}
// InEpsilon asserts that expected and actual have a relative error less than epsilon
//
// Returns whether the assertion was successful (true) or not (false).
func
InEpsilon
(
t
TestingT
,
expected
interface
{},
actual
interface
{},
epsilon
float64
,
msgAndArgs
...
interface
{})
{
if
!
assert
.
InEpsilon
(
t
,
expected
,
actual
,
epsilon
,
msgAndArgs
...
)
{
t
.
FailNow
()
}
}
// InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices.
func
InEpsilonSlice
(
t
TestingT
,
expected
interface
{},
actual
interface
{},
epsilon
float64
,
msgAndArgs
...
interface
{})
{
if
!
assert
.
InEpsilonSlice
(
t
,
expected
,
actual
,
epsilon
,
msgAndArgs
...
)
{
t
.
FailNow
()
}
}
// IsType asserts that the specified objects are of the same type.
func
IsType
(
t
TestingT
,
expectedType
interface
{},
object
interface
{},
msgAndArgs
...
interface
{})
{
if
!
assert
.
IsType
(
t
,
expectedType
,
object
,
msgAndArgs
...
)
{
t
.
FailNow
()
}
}
// JSONEq asserts that two JSON strings are equivalent.
//
// assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
//
// Returns whether the assertion was successful (true) or not (false).
func
JSONEq
(
t
TestingT
,
expected
string
,
actual
string
,
msgAndArgs
...
interface
{})
{
if
!
assert
.
JSONEq
(
t
,
expected
,
actual
,
msgAndArgs
...
)
{
t
.
FailNow
()
}
}
// Len asserts that the specified object has specific length.
// Len also fails if the object has a type that len() not accept.
//
// assert.Len(t, mySlice, 3, "The size of slice is not 3")
//
// Returns whether the assertion was successful (true) or not (false).
func
Len
(
t
TestingT
,
object
interface
{},
length
int
,
msgAndArgs
...
interface
{})
{
if
!
assert
.
Len
(
t
,
object
,
length
,
msgAndArgs
...
)
{
t
.
FailNow
()
}
}
// Nil asserts that the specified object is nil.
//
// assert.Nil(t, err, "err should be nothing")
//
// Returns whether the assertion was successful (true) or not (false).
func
Nil
(
t
TestingT
,
object
interface
{},
msgAndArgs
...
interface
{})
{
if
!
assert
.
Nil
(
t
,
object
,
msgAndArgs
...
)
{
t
.
FailNow
()
}
}
// NoError asserts that a function returned no error (i.e. `nil`).
//
// actualObj, err := SomeFunction()
// if assert.NoError(t, err) {
// assert.Equal(t, actualObj, expectedObj)
// }
//
// Returns whether the assertion was successful (true) or not (false).
func
NoError
(
t
TestingT
,
err
error
,
msgAndArgs
...
interface
{})
{
if
!
assert
.
NoError
(
t
,
err
,
msgAndArgs
...
)
{
t
.
FailNow
()
}
}
// NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the
// specified substring or element.
//
// assert.NotContains(t, "Hello World", "Earth", "But 'Hello World' does NOT contain 'Earth'")
// assert.NotContains(t, ["Hello", "World"], "Earth", "But ['Hello', 'World'] does NOT contain 'Earth'")
// assert.NotContains(t, {"Hello": "World"}, "Earth", "But {'Hello': 'World'} does NOT contain 'Earth'")
//
// Returns whether the assertion was successful (true) or not (false).
func
NotContains
(
t
TestingT
,
s
interface
{},
contains
interface
{},
msgAndArgs
...
interface
{})
{
if
!
assert
.
NotContains
(
t
,
s
,
contains
,
msgAndArgs
...
)
{
t
.
FailNow
()
}
}
// NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either
// a slice or a channel with len == 0.
//
// if assert.NotEmpty(t, obj) {
// assert.Equal(t, "two", obj[1])
// }
//
// Returns whether the assertion was successful (true) or not (false).
func
NotEmpty
(
t
TestingT
,
object
interface
{},
msgAndArgs
...
interface
{})
{
if
!
assert
.
NotEmpty
(
t
,
object
,
msgAndArgs
...
)
{
t
.
FailNow
()
}
}
// NotEqual asserts that the specified values are NOT equal.
//
// assert.NotEqual(t, obj1, obj2, "two objects shouldn't be equal")
//
// Returns whether the assertion was successful (true) or not (false).
func
NotEqual
(
t
TestingT
,
expected
interface
{},
actual
interface
{},
msgAndArgs
...
interface
{})
{
if
!
assert
.
NotEqual
(
t
,
expected
,
actual
,
msgAndArgs
...
)
{
t
.
FailNow
()
}
}
// NotNil asserts that the specified object is not nil.
//
// assert.NotNil(t, err, "err should be something")
//
// Returns whether the assertion was successful (true) or not (false).
func
NotNil
(
t
TestingT
,
object
interface
{},
msgAndArgs
...
interface
{})
{
if
!
assert
.
NotNil
(
t
,
object
,
msgAndArgs
...
)
{
t
.
FailNow
()
}
}
// NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic.
//
// assert.NotPanics(t, func(){
// RemainCalm()
// }, "Calling RemainCalm() should NOT panic")
//
// Returns whether the assertion was successful (true) or not (false).
func
NotPanics
(
t
TestingT
,
f
assert
.
PanicTestFunc
,
msgAndArgs
...
interface
{})
{
if
!
assert
.
NotPanics
(
t
,
f
,
msgAndArgs
...
)
{
t
.
FailNow
()
}
}
// NotRegexp asserts that a specified regexp does not match a string.
//
// assert.NotRegexp(t, regexp.MustCompile("starts"), "it's starting")
// assert.NotRegexp(t, "^start", "it's not starting")
//
// Returns whether the assertion was successful (true) or not (false).
func
NotRegexp
(
t
TestingT
,
rx
interface
{},
str
interface
{},
msgAndArgs
...
interface
{})
{
if
!
assert
.
NotRegexp
(
t
,
rx
,
str
,
msgAndArgs
...
)
{
t
.
FailNow
()
}
}
// NotZero asserts that i is not the zero value for its type and returns the truth.
func
NotZero
(
t
TestingT
,
i
interface
{},
msgAndArgs
...
interface
{})
{
if
!
assert
.
NotZero
(
t
,
i
,
msgAndArgs
...
)
{
t
.
FailNow
()
}
}
// Panics asserts that the code inside the specified PanicTestFunc panics.
//
// assert.Panics(t, func(){
// GoCrazy()
// }, "Calling GoCrazy() should panic")
//
// Returns whether the assertion was successful (true) or not (false).
func
Panics
(
t
TestingT
,
f
assert
.
PanicTestFunc
,
msgAndArgs
...
interface
{})
{
if
!
assert
.
Panics
(
t
,
f
,
msgAndArgs
...
)
{
t
.
FailNow
()
}
}
// Regexp asserts that a specified regexp matches a string.
//
// assert.Regexp(t, regexp.MustCompile("start"), "it's starting")
// assert.Regexp(t, "start...$", "it's not starting")
//
// Returns whether the assertion was successful (true) or not (false).
func
Regexp
(
t
TestingT
,
rx
interface
{},
str
interface
{},
msgAndArgs
...
interface
{})
{
if
!
assert
.
Regexp
(
t
,
rx
,
str
,
msgAndArgs
...
)
{
t
.
FailNow
()
}
}
// True asserts that the specified value is true.
//
// assert.True(t, myBool, "myBool should be true")
//
// Returns whether the assertion was successful (true) or not (false).
func
True
(
t
TestingT
,
value
bool
,
msgAndArgs
...
interface
{})
{
if
!
assert
.
True
(
t
,
value
,
msgAndArgs
...
)
{
t
.
FailNow
()
}
}
// WithinDuration asserts that the two times are within duration delta of each other.
//
// assert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second, "The difference should not be more than 10s")
//
// Returns whether the assertion was successful (true) or not (false).
func
WithinDuration
(
t
TestingT
,
expected
time
.
Time
,
actual
time
.
Time
,
delta
time
.
Duration
,
msgAndArgs
...
interface
{})
{
if
!
assert
.
WithinDuration
(
t
,
expected
,
actual
,
delta
,
msgAndArgs
...
)
{
t
.
FailNow
()
}
}
// Zero asserts that i is the zero value for its type and returns the truth.
func
Zero
(
t
TestingT
,
i
interface
{},
msgAndArgs
...
interface
{})
{
if
!
assert
.
Zero
(
t
,
i
,
msgAndArgs
...
)
{
t
.
FailNow
()
}
}
vendor/github.com/stretchr/testify/require/require.go.tmpl
0 → 100644
View file @
e7a352d9
{{.Comment}}
func {{.DocInfo.Name}}(t TestingT, {{.Params}}) {
if !assert.{{.DocInfo.Name}}(t, {{.ForwardedParams}}) {
t.FailNow()
}
}
vendor/github.com/stretchr/testify/require/require_forward.go
0 → 100644
View file @
e7a352d9
/*
* CODE GENERATED AUTOMATICALLY WITH github.com/stretchr/testify/_codegen
* THIS FILE MUST NOT BE EDITED BY HAND
*/
package
require
import
(
assert
"github.com/stretchr/testify/assert"
http
"net/http"
url
"net/url"
time
"time"
)
// Condition uses a Comparison to assert a complex condition.
func
(
a
*
Assertions
)
Condition
(
comp
assert
.
Comparison
,
msgAndArgs
...
interface
{})
{
Condition
(
a
.
t
,
comp
,
msgAndArgs
...
)
}
// Contains asserts that the specified string, list(array, slice...) or map contains the
// specified substring or element.
//
// a.Contains("Hello World", "World", "But 'Hello World' does contain 'World'")
// a.Contains(["Hello", "World"], "World", "But ["Hello", "World"] does contain 'World'")
// a.Contains({"Hello": "World"}, "Hello", "But {'Hello': 'World'} does contain 'Hello'")
//
// Returns whether the assertion was successful (true) or not (false).
func
(
a
*
Assertions
)
Contains
(
s
interface
{},
contains
interface
{},
msgAndArgs
...
interface
{})
{
Contains
(
a
.
t
,
s
,
contains
,
msgAndArgs
...
)
}
// Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either
// a slice or a channel with len == 0.
//
// a.Empty(obj)
//
// Returns whether the assertion was successful (true) or not (false).
func
(
a
*
Assertions
)
Empty
(
object
interface
{},
msgAndArgs
...
interface
{})
{
Empty
(
a
.
t
,
object
,
msgAndArgs
...
)
}
// Equal asserts that two objects are equal.
//
// a.Equal(123, 123, "123 and 123 should be equal")
//
// Returns whether the assertion was successful (true) or not (false).
func
(
a
*
Assertions
)
Equal
(
expected
interface
{},
actual
interface
{},
msgAndArgs
...
interface
{})
{
Equal
(
a
.
t
,
expected
,
actual
,
msgAndArgs
...
)
}
// EqualError asserts that a function returned an error (i.e. not `nil`)
// and that it is equal to the provided error.
//
// actualObj, err := SomeFunction()
// a.EqualError(err, expectedErrorString, "An error was expected")
//
// Returns whether the assertion was successful (true) or not (false).
func
(
a
*
Assertions
)
EqualError
(
theError
error
,
errString
string
,
msgAndArgs
...
interface
{})
{
EqualError
(
a
.
t
,
theError
,
errString
,
msgAndArgs
...
)
}
// EqualValues asserts that two objects are equal or convertable to the same types
// and equal.
//
// a.EqualValues(uint32(123), int32(123), "123 and 123 should be equal")
//
// Returns whether the assertion was successful (true) or not (false).
func
(
a
*
Assertions
)
EqualValues
(
expected
interface
{},
actual
interface
{},
msgAndArgs
...
interface
{})
{
EqualValues
(
a
.
t
,
expected
,
actual
,
msgAndArgs
...
)
}
// Error asserts that a function returned an error (i.e. not `nil`).
//
// actualObj, err := SomeFunction()
// if a.Error(err, "An error was expected") {
// assert.Equal(t, err, expectedError)
// }
//
// Returns whether the assertion was successful (true) or not (false).
func
(
a
*
Assertions
)
Error
(
err
error
,
msgAndArgs
...
interface
{})
{
Error
(
a
.
t
,
err
,
msgAndArgs
...
)
}
// Exactly asserts that two objects are equal is value and type.
//
// a.Exactly(int32(123), int64(123), "123 and 123 should NOT be equal")
//
// Returns whether the assertion was successful (true) or not (false).
func
(
a
*
Assertions
)
Exactly
(
expected
interface
{},
actual
interface
{},
msgAndArgs
...
interface
{})
{
Exactly
(
a
.
t
,
expected
,
actual
,
msgAndArgs
...
)
}
// Fail reports a failure through
func
(
a
*
Assertions
)
Fail
(
failureMessage
string
,
msgAndArgs
...
interface
{})
{
Fail
(
a
.
t
,
failureMessage
,
msgAndArgs
...
)
}
// FailNow fails test
func
(
a
*
Assertions
)
FailNow
(
failureMessage
string
,
msgAndArgs
...
interface
{})
{
FailNow
(
a
.
t
,
failureMessage
,
msgAndArgs
...
)
}
// False asserts that the specified value is false.
//
// a.False(myBool, "myBool should be false")
//
// Returns whether the assertion was successful (true) or not (false).
func
(
a
*
Assertions
)
False
(
value
bool
,
msgAndArgs
...
interface
{})
{
False
(
a
.
t
,
value
,
msgAndArgs
...
)
}
// HTTPBodyContains asserts that a specified handler returns a
// body that contains a string.
//
// a.HTTPBodyContains(myHandler, "www.google.com", nil, "I'm Feeling Lucky")
//
// Returns whether the assertion was successful (true) or not (false).
func
(
a
*
Assertions
)
HTTPBodyContains
(
handler
http
.
HandlerFunc
,
method
string
,
url
string
,
values
url
.
Values
,
str
interface
{})
{
HTTPBodyContains
(
a
.
t
,
handler
,
method
,
url
,
values
,
str
)
}
// HTTPBodyNotContains asserts that a specified handler returns a
// body that does not contain a string.
//
// a.HTTPBodyNotContains(myHandler, "www.google.com", nil, "I'm Feeling Lucky")
//
// Returns whether the assertion was successful (true) or not (false).
func
(
a
*
Assertions
)
HTTPBodyNotContains
(
handler
http
.
HandlerFunc
,
method
string
,
url
string
,
values
url
.
Values
,
str
interface
{})
{
HTTPBodyNotContains
(
a
.
t
,
handler
,
method
,
url
,
values
,
str
)
}
// HTTPError asserts that a specified handler returns an error status code.
//
// a.HTTPError(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}}
//
// Returns whether the assertion was successful (true) or not (false).
func
(
a
*
Assertions
)
HTTPError
(
handler
http
.
HandlerFunc
,
method
string
,
url
string
,
values
url
.
Values
)
{
HTTPError
(
a
.
t
,
handler
,
method
,
url
,
values
)
}
// HTTPRedirect asserts that a specified handler returns a redirect status code.
//
// a.HTTPRedirect(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}}
//
// Returns whether the assertion was successful (true) or not (false).
func
(
a
*
Assertions
)
HTTPRedirect
(
handler
http
.
HandlerFunc
,
method
string
,
url
string
,
values
url
.
Values
)
{
HTTPRedirect
(
a
.
t
,
handler
,
method
,
url
,
values
)
}
// HTTPSuccess asserts that a specified handler returns a success status code.
//
// a.HTTPSuccess(myHandler, "POST", "http://www.google.com", nil)
//
// Returns whether the assertion was successful (true) or not (false).
func
(
a
*
Assertions
)
HTTPSuccess
(
handler
http
.
HandlerFunc
,
method
string
,
url
string
,
values
url
.
Values
)
{
HTTPSuccess
(
a
.
t
,
handler
,
method
,
url
,
values
)
}
// Implements asserts that an object is implemented by the specified interface.
//
// a.Implements((*MyInterface)(nil), new(MyObject), "MyObject")
func
(
a
*
Assertions
)
Implements
(
interfaceObject
interface
{},
object
interface
{},
msgAndArgs
...
interface
{})
{
Implements
(
a
.
t
,
interfaceObject
,
object
,
msgAndArgs
...
)
}
// InDelta asserts that the two numerals are within delta of each other.
//
// a.InDelta(math.Pi, (22 / 7.0), 0.01)
//
// Returns whether the assertion was successful (true) or not (false).
func
(
a
*
Assertions
)
InDelta
(
expected
interface
{},
actual
interface
{},
delta
float64
,
msgAndArgs
...
interface
{})
{
InDelta
(
a
.
t
,
expected
,
actual
,
delta
,
msgAndArgs
...
)
}
// InDeltaSlice is the same as InDelta, except it compares two slices.
func
(
a
*
Assertions
)
InDeltaSlice
(
expected
interface
{},
actual
interface
{},
delta
float64
,
msgAndArgs
...
interface
{})
{
InDeltaSlice
(
a
.
t
,
expected
,
actual
,
delta
,
msgAndArgs
...
)
}
// InEpsilon asserts that expected and actual have a relative error less than epsilon
//
// Returns whether the assertion was successful (true) or not (false).
func
(
a
*
Assertions
)
InEpsilon
(
expected
interface
{},
actual
interface
{},
epsilon
float64
,
msgAndArgs
...
interface
{})
{
InEpsilon
(
a
.
t
,
expected
,
actual
,
epsilon
,
msgAndArgs
...
)
}
// InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices.
func
(
a
*
Assertions
)
InEpsilonSlice
(
expected
interface
{},
actual
interface
{},
epsilon
float64
,
msgAndArgs
...
interface
{})
{
InEpsilonSlice
(
a
.
t
,
expected
,
actual
,
epsilon
,
msgAndArgs
...
)
}
// IsType asserts that the specified objects are of the same type.
func
(
a
*
Assertions
)
IsType
(
expectedType
interface
{},
object
interface
{},
msgAndArgs
...
interface
{})
{
IsType
(
a
.
t
,
expectedType
,
object
,
msgAndArgs
...
)
}
// JSONEq asserts that two JSON strings are equivalent.
//
// a.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
//
// Returns whether the assertion was successful (true) or not (false).
func
(
a
*
Assertions
)
JSONEq
(
expected
string
,
actual
string
,
msgAndArgs
...
interface
{})
{
JSONEq
(
a
.
t
,
expected
,
actual
,
msgAndArgs
...
)
}
// Len asserts that the specified object has specific length.
// Len also fails if the object has a type that len() not accept.
//
// a.Len(mySlice, 3, "The size of slice is not 3")
//
// Returns whether the assertion was successful (true) or not (false).
func
(
a
*
Assertions
)
Len
(
object
interface
{},
length
int
,
msgAndArgs
...
interface
{})
{
Len
(
a
.
t
,
object
,
length
,
msgAndArgs
...
)
}
// Nil asserts that the specified object is nil.
//
// a.Nil(err, "err should be nothing")
//
// Returns whether the assertion was successful (true) or not (false).
func
(
a
*
Assertions
)
Nil
(
object
interface
{},
msgAndArgs
...
interface
{})
{
Nil
(
a
.
t
,
object
,
msgAndArgs
...
)
}
// NoError asserts that a function returned no error (i.e. `nil`).
//
// actualObj, err := SomeFunction()
// if a.NoError(err) {
// assert.Equal(t, actualObj, expectedObj)
// }
//
// Returns whether the assertion was successful (true) or not (false).
func
(
a
*
Assertions
)
NoError
(
err
error
,
msgAndArgs
...
interface
{})
{
NoError
(
a
.
t
,
err
,
msgAndArgs
...
)
}
// NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the
// specified substring or element.
//
// a.NotContains("Hello World", "Earth", "But 'Hello World' does NOT contain 'Earth'")
// a.NotContains(["Hello", "World"], "Earth", "But ['Hello', 'World'] does NOT contain 'Earth'")
// a.NotContains({"Hello": "World"}, "Earth", "But {'Hello': 'World'} does NOT contain 'Earth'")
//
// Returns whether the assertion was successful (true) or not (false).
func
(
a
*
Assertions
)
NotContains
(
s
interface
{},
contains
interface
{},
msgAndArgs
...
interface
{})
{
NotContains
(
a
.
t
,
s
,
contains
,
msgAndArgs
...
)
}
// NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either
// a slice or a channel with len == 0.
//
// if a.NotEmpty(obj) {
// assert.Equal(t, "two", obj[1])
// }
//
// Returns whether the assertion was successful (true) or not (false).
func
(
a
*
Assertions
)
NotEmpty
(
object
interface
{},
msgAndArgs
...
interface
{})
{
NotEmpty
(
a
.
t
,
object
,
msgAndArgs
...
)
}
// NotEqual asserts that the specified values are NOT equal.
//
// a.NotEqual(obj1, obj2, "two objects shouldn't be equal")
//
// Returns whether the assertion was successful (true) or not (false).
func
(
a
*
Assertions
)
NotEqual
(
expected
interface
{},
actual
interface
{},
msgAndArgs
...
interface
{})
{
NotEqual
(
a
.
t
,
expected
,
actual
,
msgAndArgs
...
)
}
// NotNil asserts that the specified object is not nil.
//
// a.NotNil(err, "err should be something")
//
// Returns whether the assertion was successful (true) or not (false).
func
(
a
*
Assertions
)
NotNil
(
object
interface
{},
msgAndArgs
...
interface
{})
{
NotNil
(
a
.
t
,
object
,
msgAndArgs
...
)
}
// NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic.
//
// a.NotPanics(func(){
// RemainCalm()
// }, "Calling RemainCalm() should NOT panic")
//
// Returns whether the assertion was successful (true) or not (false).
func
(
a
*
Assertions
)
NotPanics
(
f
assert
.
PanicTestFunc
,
msgAndArgs
...
interface
{})
{
NotPanics
(
a
.
t
,
f
,
msgAndArgs
...
)
}
// NotRegexp asserts that a specified regexp does not match a string.
//
// a.NotRegexp(regexp.MustCompile("starts"), "it's starting")
// a.NotRegexp("^start", "it's not starting")
//
// Returns whether the assertion was successful (true) or not (false).
func
(
a
*
Assertions
)
NotRegexp
(
rx
interface
{},
str
interface
{},
msgAndArgs
...
interface
{})
{
NotRegexp
(
a
.
t
,
rx
,
str
,
msgAndArgs
...
)
}
// NotZero asserts that i is not the zero value for its type and returns the truth.
func
(
a
*
Assertions
)
NotZero
(
i
interface
{},
msgAndArgs
...
interface
{})
{
NotZero
(
a
.
t
,
i
,
msgAndArgs
...
)
}
// Panics asserts that the code inside the specified PanicTestFunc panics.
//
// a.Panics(func(){
// GoCrazy()
// }, "Calling GoCrazy() should panic")
//
// Returns whether the assertion was successful (true) or not (false).
func
(
a
*
Assertions
)
Panics
(
f
assert
.
PanicTestFunc
,
msgAndArgs
...
interface
{})
{
Panics
(
a
.
t
,
f
,
msgAndArgs
...
)
}
// Regexp asserts that a specified regexp matches a string.
//
// a.Regexp(regexp.MustCompile("start"), "it's starting")
// a.Regexp("start...$", "it's not starting")
//
// Returns whether the assertion was successful (true) or not (false).
func
(
a
*
Assertions
)
Regexp
(
rx
interface
{},
str
interface
{},
msgAndArgs
...
interface
{})
{
Regexp
(
a
.
t
,
rx
,
str
,
msgAndArgs
...
)
}
// True asserts that the specified value is true.
//
// a.True(myBool, "myBool should be true")
//
// Returns whether the assertion was successful (true) or not (false).
func
(
a
*
Assertions
)
True
(
value
bool
,
msgAndArgs
...
interface
{})
{
True
(
a
.
t
,
value
,
msgAndArgs
...
)
}
// WithinDuration asserts that the two times are within duration delta of each other.
//
// a.WithinDuration(time.Now(), time.Now(), 10*time.Second, "The difference should not be more than 10s")
//
// Returns whether the assertion was successful (true) or not (false).
func
(
a
*
Assertions
)
WithinDuration
(
expected
time
.
Time
,
actual
time
.
Time
,
delta
time
.
Duration
,
msgAndArgs
...
interface
{})
{
WithinDuration
(
a
.
t
,
expected
,
actual
,
delta
,
msgAndArgs
...
)
}
// Zero asserts that i is the zero value for its type and returns the truth.
func
(
a
*
Assertions
)
Zero
(
i
interface
{},
msgAndArgs
...
interface
{})
{
Zero
(
a
.
t
,
i
,
msgAndArgs
...
)
}
vendor/github.com/stretchr/testify/require/require_forward.go.tmpl
0 → 100644
View file @
e7a352d9
{{.CommentWithoutT "a"}}
func (a *Assertions) {{.DocInfo.Name}}({{.Params}}) {
{{.DocInfo.Name}}(a.t, {{.ForwardedParams}})
}
vendor/github.com/stretchr/testify/require/requirements.go
0 → 100644
View file @
e7a352d9
package
require
// TestingT is an interface wrapper around *testing.T
type
TestingT
interface
{
Errorf
(
format
string
,
args
...
interface
{})
FailNow
()
}
//go:generate go run ../_codegen/main.go -output-package=require -template=require.go.tmpl
vendor/vendor.json
View file @
e7a352d9
...
@@ -115,6 +115,12 @@
...
@@ -115,6 +115,12 @@
"revision"
:
"18a02ba4a312f95da08ff4cfc0055750ce50ae9e"
,
"revision"
:
"18a02ba4a312f95da08ff4cfc0055750ce50ae9e"
,
"revisionTime"
:
"2016-11-17T07:43:51Z"
"revisionTime"
:
"2016-11-17T07:43:51Z"
},
},
{
"checksumSHA1"
:
"omdvCNu8sJIc9FbOfObC484M7Dg="
,
"path"
:
"github.com/stretchr/testify/require"
,
"revision"
:
"18a02ba4a312f95da08ff4cfc0055750ce50ae9e"
,
"revisionTime"
:
"2016-11-17T07:43:51Z"
},
{
{
"checksumSHA1"
:
"HWuFvDMQ5zp554X4QpVjBUgW5wk="
,
"checksumSHA1"
:
"HWuFvDMQ5zp554X4QpVjBUgW5wk="
,
"path"
:
"gitlab.com/gitlab-org/gitaly-proto/go"
,
"path"
:
"gitlab.com/gitlab-org/gitaly-proto/go"
,
...
...
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