update vendor/ dir to latest w/o heroku, moby

had to lock a lot of things in place
This commit is contained in:
Reed Allman
2017-08-03 02:38:15 -07:00
parent 780791da1c
commit 30f3c45dbc
5637 changed files with 191713 additions and 1133103 deletions

View File

@@ -3,6 +3,7 @@ sudo: required
go:
- 1.7.x
- 1.8.x
- 1.9rc1
- tip
os:
- linux

View File

@@ -36,7 +36,9 @@ Changping Chen
Cheah Chu Yeow
cheneydeng
Chris Bednarski
Chris Stavropoulos
Christian Stewart
Christophe Mourette
CMGS
Colin Hebert
Craig Jellick
@@ -45,10 +47,12 @@ Dan Williams
Daniel, Dao Quang Minh
Daniel Garcia
Daniel Hiltgen
Daniel Tsui
Darren Shepherd
Dave Choi
David Huie
Dawn Chen
Derek Petersen
Dinesh Subhraveti
Drew Wells
Ed
@@ -75,6 +79,7 @@ He Simei
Ivan Mikushin
James Bardin
James Nugent
Jamie Snell
Januar Wayong
Jari Kolehmainen
Jason Wilder
@@ -86,6 +91,7 @@ Jen Andre
Jérôme Laurens
Jim Minter
Johan Euphrosine
Johannes Scheuermann
John Hughes
Jorge Marey
Julian Einwag

View File

@@ -110,3 +110,16 @@ Commited code must pass:
Running `make test` will check all of these. If your editor does not
automatically call ``gofmt -s``, `make fmt` will format all go files in this
repository.
## Using with Docker 1.9 and Go 1.4
There's a tag for using go-dockerclient with Docker 1.9 (which requires
compiling go-dockerclient with Go 1.4), the tag name is ``docker-1.9/go-1.4``.
The instructions below can be used to get a version of go-dockerclient that compiles with Go 1.4:
```
% git clone -b docker-1.9/go-1.4 https://github.com/fsouza/go-dockerclient.git $GOPATH/src/github.com/fsouza/go-dockerclient
% git clone -b v1.9.1 https://github.com/docker/docker.git $GOPATH/src/github.com/docker/docker
% go get github.com/fsouza/go-dockerclient
```

View File

@@ -6,15 +6,16 @@ environment:
GOPATH: c:\gopath
matrix:
- GOVERSION: 1.7.5
- GOVERSION: 1.8.1
- GOVERSION: 1.8.3
- GOVERSION: 1.9rc1
install:
- set PATH=%GOPATH%\bin;c:\go\bin;%PATH%
- rmdir c:\go /s /q
- appveyor DownloadFile https://storage.googleapis.com/golang/go%GOVERSION%.windows-amd64.zip
- 7z x go%GOVERSION%.windows-amd64.zip -y -oC:\ > NUL
build_script:
- go get -d -t ./...
- go get -race -d -t ./...
test_script:
- go test -v ./...
- go test -race ./...
matrix:
fast_finish: true

View File

@@ -16,6 +16,7 @@ import (
)
func TestAuthConfigurationSearchPath(t *testing.T) {
t.Parallel()
var testData = []struct {
dockerConfigEnv string
homeEnv string
@@ -35,6 +36,7 @@ func TestAuthConfigurationSearchPath(t *testing.T) {
}
func TestAuthConfigurationsFromFile(t *testing.T) {
t.Parallel()
tmpDir, err := ioutil.TempDir("", "go-dockerclient-auth-test")
if err != nil {
t.Errorf("Unable to create temporary directory for TestAuthConfigurationsFromFile: %s", err)
@@ -56,6 +58,7 @@ func TestAuthConfigurationsFromFile(t *testing.T) {
}
func TestAuthLegacyConfig(t *testing.T) {
t.Parallel()
auth := base64.StdEncoding.EncodeToString([]byte("user:pa:ss"))
read := strings.NewReader(fmt.Sprintf(`{"docker.io":{"auth":"%s","email":"user@example.com"}}`, auth))
ac, err := NewAuthConfigurations(read)
@@ -81,6 +84,7 @@ func TestAuthLegacyConfig(t *testing.T) {
}
func TestAuthBadConfig(t *testing.T) {
t.Parallel()
auth := base64.StdEncoding.EncodeToString([]byte("userpass"))
read := strings.NewReader(fmt.Sprintf(`{"docker.io":{"auth":"%s","email":"user@example.com"}}`, auth))
ac, err := NewAuthConfigurations(read)
@@ -93,6 +97,7 @@ func TestAuthBadConfig(t *testing.T) {
}
func TestAuthAndOtherFields(t *testing.T) {
t.Parallel()
auth := base64.StdEncoding.EncodeToString([]byte("user:pass"))
read := strings.NewReader(fmt.Sprintf(`{
"auths":{"docker.io":{"auth":"%s","email":"user@example.com"}},
@@ -121,6 +126,7 @@ func TestAuthAndOtherFields(t *testing.T) {
}
}
func TestAuthConfig(t *testing.T) {
t.Parallel()
auth := base64.StdEncoding.EncodeToString([]byte("user:pass"))
read := strings.NewReader(fmt.Sprintf(`{"auths":{"docker.io":{"auth":"%s","email":"user@example.com"}}}`, auth))
ac, err := NewAuthConfigurations(read)
@@ -146,6 +152,7 @@ func TestAuthConfig(t *testing.T) {
}
func TestAuthCheck(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{status: http.StatusOK}
client := newTestClient(fakeRT)
if _, err := client.AuthCheck(nil); err == nil {

View File

@@ -18,6 +18,7 @@ import (
)
func TestBuildImageMultipleContextsError(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "", status: http.StatusOK}
client := newTestClient(fakeRT)
var buf bytes.Buffer
@@ -39,6 +40,7 @@ func TestBuildImageMultipleContextsError(t *testing.T) {
}
func TestBuildImageContextDirDockerignoreParsing(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "", status: http.StatusOK}
client := newTestClient(fakeRT)
@@ -110,6 +112,7 @@ func TestBuildImageContextDirDockerignoreParsing(t *testing.T) {
}
func TestBuildImageSendXRegistryConfig(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "", status: http.StatusOK}
client := newTestClient(fakeRT)
var buf bytes.Buffer

View File

@@ -7,6 +7,7 @@ package docker
import "testing"
func TestChangeString(t *testing.T) {
t.Parallel()
var tests = []struct {
change Change
expected string

View File

@@ -498,6 +498,7 @@ type streamOptions struct {
in io.Reader
stdout io.Writer
stderr io.Writer
reqSent chan struct{}
// timeout is the initial connection timeout
timeout time.Duration
// Timeout with no data is received, it's reset every time new data
@@ -576,6 +577,9 @@ func (c *Client) stream(method, path string, streamOptions streamOptions) error
dial.SetDeadline(time.Now().Add(streamOptions.timeout))
}
if streamOptions.reqSent != nil {
close(streamOptions.reqSent)
}
if resp, err = http.ReadResponse(breader, req); err != nil {
// Cancel timeout for future I/O operations
if streamOptions.timeout > 0 {
@@ -594,6 +598,9 @@ func (c *Client) stream(method, path string, streamOptions streamOptions) error
}
return chooseError(subCtx, err)
}
if streamOptions.reqSent != nil {
close(streamOptions.reqSent)
}
}
defer resp.Body.Close()
if resp.StatusCode < 200 || resp.StatusCode >= 400 {

View File

@@ -19,6 +19,7 @@ import (
)
func TestClientDoConcurrentStress(t *testing.T) {
t.Parallel()
var reqs []*http.Request
var mu sync.Mutex
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

View File

@@ -23,6 +23,7 @@ import (
)
func TestNewAPIClient(t *testing.T) {
t.Parallel()
endpoint := "http://localhost:4243"
client, err := NewClient(endpoint)
if err != nil {
@@ -56,6 +57,7 @@ func newTLSClient(endpoint string) (*Client, error) {
}
func TestNewTSLAPIClient(t *testing.T) {
t.Parallel()
endpoint := "https://localhost:4243"
client, err := newTLSClient(endpoint)
if err != nil {
@@ -73,6 +75,7 @@ func TestNewTSLAPIClient(t *testing.T) {
}
func TestNewVersionedClient(t *testing.T) {
t.Parallel()
endpoint := "http://localhost:4243"
client, err := NewVersionedClient(endpoint, "1.12")
if err != nil {
@@ -90,6 +93,7 @@ func TestNewVersionedClient(t *testing.T) {
}
func TestNewVersionedClientFromEnv(t *testing.T) {
t.Parallel()
endpoint := "tcp://localhost:2376"
endpointURL := "http://localhost:2376"
os.Setenv("DOCKER_HOST", endpoint)
@@ -113,6 +117,7 @@ func TestNewVersionedClientFromEnv(t *testing.T) {
}
func TestNewVersionedClientFromEnvTLS(t *testing.T) {
t.Parallel()
endpoint := "tcp://localhost:2376"
endpointURL := "https://localhost:2376"
base, _ := os.Getwd()
@@ -138,6 +143,7 @@ func TestNewVersionedClientFromEnvTLS(t *testing.T) {
}
func TestNewTLSVersionedClient(t *testing.T) {
t.Parallel()
certPath := "testing/data/cert.pem"
keyPath := "testing/data/key.pem"
caPath := "testing/data/ca.pem"
@@ -158,6 +164,7 @@ func TestNewTLSVersionedClient(t *testing.T) {
}
func TestNewTLSVersionedClientNoClientCert(t *testing.T) {
t.Parallel()
certPath := "testing/data/cert_doesnotexist.pem"
keyPath := "testing/data/key_doesnotexist.pem"
caPath := "testing/data/ca.pem"
@@ -178,6 +185,7 @@ func TestNewTLSVersionedClientNoClientCert(t *testing.T) {
}
func TestNewTLSVersionedClientInvalidCA(t *testing.T) {
t.Parallel()
certPath := "testing/data/cert.pem"
keyPath := "testing/data/key.pem"
caPath := "testing/data/key.pem"
@@ -189,6 +197,7 @@ func TestNewTLSVersionedClientInvalidCA(t *testing.T) {
}
func TestNewTLSVersionedClientInvalidCANoClientCert(t *testing.T) {
t.Parallel()
certPath := "testing/data/cert_doesnotexist.pem"
keyPath := "testing/data/key_doesnotexist.pem"
caPath := "testing/data/key.pem"
@@ -200,6 +209,7 @@ func TestNewTLSVersionedClientInvalidCANoClientCert(t *testing.T) {
}
func TestNewClientInvalidEndpoint(t *testing.T) {
t.Parallel()
cases := []string{
"htp://localhost:3243", "http://localhost:a",
"", "http://localhost:8080:8383", "http://localhost:65536",
@@ -217,6 +227,7 @@ func TestNewClientInvalidEndpoint(t *testing.T) {
}
func TestNewClientNoSchemeEndpoint(t *testing.T) {
t.Parallel()
cases := []string{"localhost", "localhost:8080"}
for _, c := range cases {
client, err := NewClient(c)
@@ -230,6 +241,7 @@ func TestNewClientNoSchemeEndpoint(t *testing.T) {
}
func TestNewTLSClient(t *testing.T) {
t.Parallel()
var tests = []struct {
endpoint string
expected string
@@ -252,6 +264,7 @@ func TestNewTLSClient(t *testing.T) {
}
func TestEndpoint(t *testing.T) {
t.Parallel()
client, err := NewVersionedClient("http://localhost:4243", "1.12")
if err != nil {
t.Fatal(err)
@@ -262,6 +275,7 @@ func TestEndpoint(t *testing.T) {
}
func TestGetURL(t *testing.T) {
t.Parallel()
var tests = []struct {
endpoint string
path string
@@ -286,6 +300,7 @@ func TestGetURL(t *testing.T) {
}
func TestGetFakeNativeURL(t *testing.T) {
t.Parallel()
var tests = []struct {
endpoint string
path string
@@ -307,6 +322,7 @@ func TestGetFakeNativeURL(t *testing.T) {
}
func TestError(t *testing.T) {
t.Parallel()
fakeBody := ioutil.NopCloser(bytes.NewBufferString("bad parameter"))
resp := &http.Response{
StatusCode: 400,
@@ -324,6 +340,7 @@ func TestError(t *testing.T) {
}
func TestQueryString(t *testing.T) {
t.Parallel()
v := float32(2.4)
f32QueryString := fmt.Sprintf("w=%s&x=10&y=10.35", strconv.FormatFloat(float64(v), 'f', -1, 64))
jsonPerson := url.QueryEscape(`{"Name":"gopher","age":4}`)
@@ -355,6 +372,7 @@ func TestQueryString(t *testing.T) {
}
func TestAPIVersions(t *testing.T) {
t.Parallel()
var tests = []struct {
a string
b string
@@ -402,6 +420,7 @@ func TestAPIVersions(t *testing.T) {
}
func TestPing(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "", status: http.StatusOK}
client := newTestClient(fakeRT)
err := client.Ping()
@@ -411,6 +430,7 @@ func TestPing(t *testing.T) {
}
func TestPingFailing(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "", status: http.StatusInternalServerError}
client := newTestClient(fakeRT)
err := client.Ping()
@@ -424,6 +444,7 @@ func TestPingFailing(t *testing.T) {
}
func TestPingFailingWrongStatus(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "", status: http.StatusAccepted}
client := newTestClient(fakeRT)
err := client.Ping()
@@ -437,6 +458,7 @@ func TestPingFailingWrongStatus(t *testing.T) {
}
func TestPingErrorWithNativeClient(t *testing.T) {
t.Parallel()
srv, cleanup, err := newNativeServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("aaaaaaaaaaa-invalid-aaaaaaaaaaa"))
}))
@@ -458,6 +480,7 @@ func TestPingErrorWithNativeClient(t *testing.T) {
}
func TestClientStreamTimeoutNotHit(t *testing.T) {
t.Parallel()
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
for i := 0; i < 5; i++ {
fmt.Fprintf(w, "%d\n", i)
@@ -488,6 +511,7 @@ func TestClientStreamTimeoutNotHit(t *testing.T) {
}
func TestClientStreamInactivityTimeout(t *testing.T) {
t.Parallel()
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
for i := 0; i < 5; i++ {
fmt.Fprintf(w, "%d\n", i)
@@ -518,6 +542,7 @@ func TestClientStreamInactivityTimeout(t *testing.T) {
}
func TestClientStreamContextDeadline(t *testing.T) {
t.Parallel()
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "abc\n")
if f, ok := w.(http.Flusher); ok {
@@ -552,6 +577,7 @@ func TestClientStreamContextDeadline(t *testing.T) {
}
func TestClientStreamContextCancel(t *testing.T) {
t.Parallel()
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "abc\n")
if f, ok := w.(http.Flusher); ok {
@@ -621,6 +647,7 @@ var mockPullOutput = `{"status":"Pulling from tsuru/static","id":"latest"}
`
func TestClientStreamJSONDecode(t *testing.T) {
t.Parallel()
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(mockPullOutput))
}))
@@ -672,6 +699,7 @@ func (b *terminalBuffer) IsTerminal() bool {
}
func TestClientStreamJSONDecodeWithTerminal(t *testing.T) {
t.Parallel()
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(mockPullOutput))
}))
@@ -700,6 +728,7 @@ func TestClientStreamJSONDecodeWithTerminal(t *testing.T) {
}
func TestClientDoContextDeadline(t *testing.T) {
t.Parallel()
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
time.Sleep(500 * time.Millisecond)
}))
@@ -718,6 +747,7 @@ func TestClientDoContextDeadline(t *testing.T) {
}
func TestClientDoContextCancel(t *testing.T) {
t.Parallel()
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
time.Sleep(500 * time.Millisecond)
}))
@@ -739,6 +769,7 @@ func TestClientDoContextCancel(t *testing.T) {
}
func TestClientStreamTimeoutNativeClient(t *testing.T) {
t.Parallel()
srv, cleanup, err := newNativeServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
for i := 0; i < 5; i++ {
fmt.Fprintf(w, "%d\n", i)

View File

@@ -23,7 +23,7 @@ func (c *Client) initializeNativeClient() {
socketPath := c.endpointURL.Path
tr := cleanhttp.DefaultTransport()
tr.Dial = func(network, addr string) (net.Conn, error) {
return c.Dialer.Dial(network, addr)
return c.Dialer.Dial(unixProtocol, socketPath)
}
tr.DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) {
return c.Dialer.Dial(unixProtocol, socketPath)

View File

@@ -22,6 +22,7 @@ const (
)
func TestNewTSLAPIClientUnixEndpoint(t *testing.T) {
t.Parallel()
srv, cleanup, err := newNativeServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("ok"))
}))

View File

@@ -204,7 +204,7 @@ func (s *State) StateString() string {
// PortBinding represents the host/container port mapping as returned in the
// `docker inspect` json
type PortBinding struct {
HostIP string `json:"HostIP,omitempty" yaml:"HostIP,omitempty" toml:"HostIP,omitempty"`
HostIP string `json:"HostIp,omitempty" yaml:"HostIp,omitempty" toml:"HostIp,omitempty"`
HostPort string `json:"HostPort,omitempty" yaml:"HostPort,omitempty" toml:"HostPort,omitempty"`
}
@@ -736,6 +736,10 @@ type HostConfig struct {
AutoRemove bool `json:"AutoRemove,omitempty" yaml:"AutoRemove,omitempty" toml:"AutoRemove,omitempty"`
StorageOpt map[string]string `json:"StorageOpt,omitempty" yaml:"StorageOpt,omitempty" toml:"StorageOpt,omitempty"`
Sysctls map[string]string `json:"Sysctls,omitempty" yaml:"Sysctls,omitempty" toml:"Sysctls,omitempty"`
CPUCount int64 `json:"CpuCount,omitempty" yaml:"CpuCount,omitempty"`
CPUPercent int64 `json:"CpuPercent,omitempty" yaml:"CpuPercent,omitempty"`
IOMaximumBandwidth int64 `json:"IOMaximumBandwidth,omitempty" yaml:"IOMaximumBandwidth,omitempty"`
IOMaximumIOps int64 `json:"IOMaximumIOps,omitempty" yaml:"IOMaximumIOps,omitempty"`
}
// NetworkingConfig represents the container's networking configuration for each of its interfaces
@@ -911,6 +915,8 @@ func (c *Client) TopContainer(id string, psArgs string) (TopResult, error) {
// See https://goo.gl/Dk3Xio for more details.
type Stats struct {
Read time.Time `json:"read,omitempty" yaml:"read,omitempty" toml:"read,omitempty"`
PreRead time.Time `json:"preread,omitempty" yaml:"preread,omitempty" toml:"preread,omitempty"`
NumProcs uint32 `json:"num_procs" yaml:"num_procs" toml:"num_procs"`
PidsStats struct {
Current uint64 `json:"current,omitempty" yaml:"current,omitempty"`
} `json:"pids_stats,omitempty" yaml:"pids_stats,omitempty" toml:"pids_stats,omitempty"`
@@ -950,10 +956,13 @@ type Stats struct {
HierarchicalMemswLimit uint64 `json:"hierarchical_memsw_limit,omitempty" yaml:"hierarchical_memsw_limit,omitempty" toml:"hierarchical_memsw_limit,omitempty"`
Swap uint64 `json:"swap,omitempty" yaml:"swap,omitempty" toml:"swap,omitempty"`
} `json:"stats,omitempty" yaml:"stats,omitempty" toml:"stats,omitempty"`
MaxUsage uint64 `json:"max_usage,omitempty" yaml:"max_usage,omitempty" toml:"max_usage,omitempty"`
Usage uint64 `json:"usage,omitempty" yaml:"usage,omitempty" toml:"usage,omitempty"`
Failcnt uint64 `json:"failcnt,omitempty" yaml:"failcnt,omitempty" toml:"failcnt,omitempty"`
Limit uint64 `json:"limit,omitempty" yaml:"limit,omitempty" toml:"limit,omitempty"`
MaxUsage uint64 `json:"max_usage,omitempty" yaml:"max_usage,omitempty" toml:"max_usage,omitempty"`
Usage uint64 `json:"usage,omitempty" yaml:"usage,omitempty" toml:"usage,omitempty"`
Failcnt uint64 `json:"failcnt,omitempty" yaml:"failcnt,omitempty" toml:"failcnt,omitempty"`
Limit uint64 `json:"limit,omitempty" yaml:"limit,omitempty" toml:"limit,omitempty"`
Commit uint64 `json:"commitbytes,omitempty" yaml:"commitbytes,omitempty" toml:"privateworkingset,omitempty"`
CommitPeak uint64 `json:"commitpeakbytes,omitempty" yaml:"commitpeakbytes,omitempty" toml:"commitpeakbytes,omitempty"`
PrivateWorkingSet uint64 `json:"privateworkingset,omitempty" yaml:"privateworkingset,omitempty" toml:"privateworkingset,omitempty"`
} `json:"memory_stats,omitempty" yaml:"memory_stats,omitempty" toml:"memory_stats,omitempty"`
BlkioStats struct {
IOServiceBytesRecursive []BlkioStatsEntry `json:"io_service_bytes_recursive,omitempty" yaml:"io_service_bytes_recursive,omitempty" toml:"io_service_bytes_recursive,omitempty"`
@@ -965,8 +974,14 @@ type Stats struct {
IOTimeRecursive []BlkioStatsEntry `json:"io_time_recursive,omitempty" yaml:"io_time_recursive,omitempty" toml:"io_time_recursive,omitempty"`
SectorsRecursive []BlkioStatsEntry `json:"sectors_recursive,omitempty" yaml:"sectors_recursive,omitempty" toml:"sectors_recursive,omitempty"`
} `json:"blkio_stats,omitempty" yaml:"blkio_stats,omitempty" toml:"blkio_stats,omitempty"`
CPUStats CPUStats `json:"cpu_stats,omitempty" yaml:"cpu_stats,omitempty" toml:"cpu_stats,omitempty"`
PreCPUStats CPUStats `json:"precpu_stats,omitempty"`
CPUStats CPUStats `json:"cpu_stats,omitempty" yaml:"cpu_stats,omitempty" toml:"cpu_stats,omitempty"`
PreCPUStats CPUStats `json:"precpu_stats,omitempty"`
StorageStats struct {
ReadCountNormalized uint64 `json:"read_count_normalized,omitempty" yaml:"read_count_normalized,omitempty" toml:"read_count_normalized,omitempty"`
ReadSizeBytes uint64 `json:"read_size_bytes,omitempty" yaml:"read_size_bytes,omitempty" toml:"read_size_bytes,omitempty"`
WriteCountNormalized uint64 `json:"write_count_normalized,omitempty" yaml:"write_count_normalized,omitempty" toml:"write_count_normalized,omitempty"`
WriteSizeBytes uint64 `json:"write_size_bytes,omitempty" yaml:"write_size_bytes,omitempty" toml:"write_size_bytes,omitempty"`
} `json:"storage_stats,omitempty" yaml:"storage_stats,omitempty" toml:"storage_stats,omitempty"`
}
// NetworkStats is a stats entry for network stats
@@ -1052,6 +1067,7 @@ func (c *Client) Stats(opts StatsOptions) (retErr error) {
}
}()
reqSent := make(chan struct{})
go func() {
err := c.stream("GET", fmt.Sprintf("/containers/%s/stats?stream=%v", opts.ID, opts.Stream), streamOptions{
rawJSONStream: true,
@@ -1060,6 +1076,7 @@ func (c *Client) Stats(opts StatsOptions) (retErr error) {
timeout: opts.Timeout,
inactivityTimeout: opts.InactivityTimeout,
context: opts.Context,
reqSent: reqSent,
})
if err != nil {
dockerError, ok := err.(*Error)
@@ -1090,6 +1107,7 @@ func (c *Client) Stats(opts StatsOptions) (retErr error) {
decoder := json.NewDecoder(readCloser)
stats := new(Stats)
<-reqSent
for err := decoder.Decode(stats); err != io.EOF; err = decoder.Decode(stats) {
if err != nil {
return err

View File

@@ -26,6 +26,7 @@ import (
)
func TestStateString(t *testing.T) {
t.Parallel()
started := time.Now().Add(-3 * time.Hour)
var tests = []struct {
input State
@@ -48,6 +49,7 @@ func TestStateString(t *testing.T) {
}
func TestStateStateString(t *testing.T) {
t.Parallel()
started := time.Now().Add(-3 * time.Hour)
var tests = []struct {
input State
@@ -68,6 +70,7 @@ func TestStateStateString(t *testing.T) {
}
func TestListContainers(t *testing.T) {
t.Parallel()
jsonContainers := `[
{
"Id": "8dfafdbc3a40",
@@ -118,6 +121,7 @@ func TestListContainers(t *testing.T) {
}
func TestListContainersParams(t *testing.T) {
t.Parallel()
var tests = []struct {
input ListContainersOptions
params map[string][]string
@@ -160,6 +164,7 @@ func TestListContainersParams(t *testing.T) {
}
func TestListContainersFailure(t *testing.T) {
t.Parallel()
var tests = []struct {
status int
message string
@@ -181,6 +186,7 @@ func TestListContainersFailure(t *testing.T) {
}
func TestInspectContainer(t *testing.T) {
t.Parallel()
jsonContainer := `{
"Id": "4fa6e0f0c6786287e131c3852c58a2e01cc697a68231826813597e4994f1d6e2",
"AppArmorProfile": "Profile",
@@ -290,6 +296,7 @@ func TestInspectContainer(t *testing.T) {
}
func TestInspectContainerWithContext(t *testing.T) {
t.Parallel()
jsonContainer := `{
"Id": "4fa6e0f0c6786287e131c3852c58a2e01cc697a68231826813597e4994f1d6e2",
"AppArmorProfile": "Profile",
@@ -435,6 +442,7 @@ func TestInspectContainerWithContext(t *testing.T) {
}
func TestInspectContainerNetwork(t *testing.T) {
t.Parallel()
jsonContainer := `{
"Id": "81e1bbe20b5508349e1c804eb08b7b6ca8366751dbea9f578b3ea0773fa66c1c",
"Created": "2015-11-12T14:54:04.791485659Z",
@@ -678,6 +686,7 @@ func TestInspectContainerNetwork(t *testing.T) {
}
func TestInspectContainerNegativeSwap(t *testing.T) {
t.Parallel()
jsonContainer := `{
"Id": "4fa6e0f0c6786287e131c3852c58a2e01cc697a68231826813597e4994f1d6e2",
"Created": "2013-05-07T14:51:42.087658+02:00",
@@ -760,6 +769,7 @@ func TestInspectContainerNegativeSwap(t *testing.T) {
}
func TestInspectContainerFailure(t *testing.T) {
t.Parallel()
client := newTestClient(&FakeRoundTripper{message: "server error", status: 500})
expected := Error{Status: 500, Message: "server error"}
container, err := client.InspectContainer("abe033")
@@ -772,6 +782,7 @@ func TestInspectContainerFailure(t *testing.T) {
}
func TestInspectContainerNotFound(t *testing.T) {
t.Parallel()
client := newTestClient(&FakeRoundTripper{message: "no such container", status: 404})
container, err := client.InspectContainer("abe033")
if container != nil {
@@ -784,6 +795,7 @@ func TestInspectContainerNotFound(t *testing.T) {
}
func TestContainerChanges(t *testing.T) {
t.Parallel()
jsonChanges := `[
{
"Path":"/dev",
@@ -820,6 +832,7 @@ func TestContainerChanges(t *testing.T) {
}
func TestContainerChangesFailure(t *testing.T) {
t.Parallel()
client := newTestClient(&FakeRoundTripper{message: "server error", status: 500})
expected := Error{Status: 500, Message: "server error"}
changes, err := client.ContainerChanges("abe033")
@@ -832,6 +845,7 @@ func TestContainerChangesFailure(t *testing.T) {
}
func TestContainerChangesNotFound(t *testing.T) {
t.Parallel()
client := newTestClient(&FakeRoundTripper{message: "no such container", status: 404})
changes, err := client.ContainerChanges("abe033")
if changes != nil {
@@ -844,6 +858,7 @@ func TestContainerChangesNotFound(t *testing.T) {
}
func TestCreateContainer(t *testing.T) {
t.Parallel()
jsonContainer := `{
"Id": "4fa6e0f0c6786287e131c3852c58a2e01cc697a68231826813597e4994f1d6e2",
"Warnings": []
@@ -881,6 +896,7 @@ func TestCreateContainer(t *testing.T) {
}
func TestCreateContainerImageNotFound(t *testing.T) {
t.Parallel()
client := newTestClient(&FakeRoundTripper{message: "No such image", status: http.StatusNotFound})
config := Config{AttachStdout: true, AttachStdin: true}
container, err := client.CreateContainer(CreateContainerOptions{Config: &config})
@@ -893,6 +909,7 @@ func TestCreateContainerImageNotFound(t *testing.T) {
}
func TestCreateContainerDuplicateName(t *testing.T) {
t.Parallel()
client := newTestClient(&FakeRoundTripper{message: "No such image", status: http.StatusConflict})
config := Config{AttachStdout: true, AttachStdin: true}
container, err := client.CreateContainer(CreateContainerOptions{Config: &config})
@@ -905,6 +922,7 @@ func TestCreateContainerDuplicateName(t *testing.T) {
}
func TestCreateContainerWithHostConfig(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "{}", status: http.StatusOK}
client := newTestClient(fakeRT)
config := Config{}
@@ -926,6 +944,7 @@ func TestCreateContainerWithHostConfig(t *testing.T) {
}
func TestUpdateContainer(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "", status: http.StatusOK}
client := newTestClient(fakeRT)
id := "4fa6e0f0c6786287e131c3852c58a2e01cc697a68231826813597e4994f1d6e2"
@@ -956,6 +975,7 @@ func TestUpdateContainer(t *testing.T) {
}
func TestStartContainer(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "", status: http.StatusOK}
client := newTestClient(fakeRT)
id := "4fa6e0f0c6786287e131c3852c58a2e01cc697a68231826813597e4994f1d6e2"
@@ -978,6 +998,7 @@ func TestStartContainer(t *testing.T) {
}
func TestStartContainerHostConfigAPI124(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "", status: http.StatusOK}
client := newTestClient(fakeRT)
client.serverAPIVersion = apiVersion124
@@ -1005,6 +1026,7 @@ func TestStartContainerHostConfigAPI124(t *testing.T) {
}
func TestStartContainerNilHostConfig(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "", status: http.StatusOK}
client := newTestClient(fakeRT)
id := "4fa6e0f0c6786287e131c3852c58a2e01cc697a68231826813597e4994f1d6e2"
@@ -1032,6 +1054,7 @@ func TestStartContainerNilHostConfig(t *testing.T) {
}
func TestStartContainerWithContext(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "", status: http.StatusOK}
client := newTestClient(fakeRT)
id := "4fa6e0f0c6786287e131c3852c58a2e01cc697a68231826813597e4994f1d6e2"
@@ -1067,6 +1090,7 @@ func TestStartContainerWithContext(t *testing.T) {
}
func TestStartContainerNotFound(t *testing.T) {
t.Parallel()
client := newTestClient(&FakeRoundTripper{message: "no such container", status: http.StatusNotFound})
err := client.StartContainer("a2344", &HostConfig{})
expected := &NoSuchContainer{ID: "a2344", Err: err.(*NoSuchContainer).Err}
@@ -1076,6 +1100,7 @@ func TestStartContainerNotFound(t *testing.T) {
}
func TestStartContainerAlreadyRunning(t *testing.T) {
t.Parallel()
client := newTestClient(&FakeRoundTripper{message: "container already running", status: http.StatusNotModified})
err := client.StartContainer("a2334", &HostConfig{})
expected := &ContainerAlreadyRunning{ID: "a2334"}
@@ -1085,6 +1110,7 @@ func TestStartContainerAlreadyRunning(t *testing.T) {
}
func TestStopContainer(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "", status: http.StatusNoContent}
client := newTestClient(fakeRT)
id := "4fa6e0f0c6786287e131c3852c58a2e01cc697a68231826813597e4994f1d6e2"
@@ -1103,6 +1129,7 @@ func TestStopContainer(t *testing.T) {
}
func TestStopContainerWithContext(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "", status: http.StatusNoContent}
client := newTestClient(fakeRT)
id := "4fa6e0f0c6786287e131c3852c58a2e01cc697a68231826813597e4994f1d6e2"
@@ -1134,6 +1161,7 @@ func TestStopContainerWithContext(t *testing.T) {
}
func TestStopContainerNotFound(t *testing.T) {
t.Parallel()
client := newTestClient(&FakeRoundTripper{message: "no such container", status: http.StatusNotFound})
err := client.StopContainer("a2334", 10)
expected := &NoSuchContainer{ID: "a2334"}
@@ -1143,6 +1171,7 @@ func TestStopContainerNotFound(t *testing.T) {
}
func TestStopContainerNotRunning(t *testing.T) {
t.Parallel()
client := newTestClient(&FakeRoundTripper{message: "container not running", status: http.StatusNotModified})
err := client.StopContainer("a2334", 10)
expected := &ContainerNotRunning{ID: "a2334"}
@@ -1152,6 +1181,7 @@ func TestStopContainerNotRunning(t *testing.T) {
}
func TestRestartContainer(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "", status: http.StatusNoContent}
client := newTestClient(fakeRT)
id := "4fa6e0f0c6786287e131c3852c58a2e01cc697a68231826813597e4994f1d6e2"
@@ -1170,6 +1200,7 @@ func TestRestartContainer(t *testing.T) {
}
func TestRestartContainerNotFound(t *testing.T) {
t.Parallel()
client := newTestClient(&FakeRoundTripper{message: "no such container", status: http.StatusNotFound})
err := client.RestartContainer("a2334", 10)
expected := &NoSuchContainer{ID: "a2334"}
@@ -1179,6 +1210,7 @@ func TestRestartContainerNotFound(t *testing.T) {
}
func TestPauseContainer(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "", status: http.StatusNoContent}
client := newTestClient(fakeRT)
id := "4fa6e0f0c6786287e131c3852c58a2e01cc697a68231826813597e4994f1d6e2"
@@ -1197,6 +1229,7 @@ func TestPauseContainer(t *testing.T) {
}
func TestPauseContainerNotFound(t *testing.T) {
t.Parallel()
client := newTestClient(&FakeRoundTripper{message: "no such container", status: http.StatusNotFound})
err := client.PauseContainer("a2334")
expected := &NoSuchContainer{ID: "a2334"}
@@ -1206,6 +1239,7 @@ func TestPauseContainerNotFound(t *testing.T) {
}
func TestUnpauseContainer(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "", status: http.StatusNoContent}
client := newTestClient(fakeRT)
id := "4fa6e0f0c6786287e131c3852c58a2e01cc697a68231826813597e4994f1d6e2"
@@ -1224,6 +1258,7 @@ func TestUnpauseContainer(t *testing.T) {
}
func TestUnpauseContainerNotFound(t *testing.T) {
t.Parallel()
client := newTestClient(&FakeRoundTripper{message: "no such container", status: http.StatusNotFound})
err := client.UnpauseContainer("a2334")
expected := &NoSuchContainer{ID: "a2334"}
@@ -1233,6 +1268,7 @@ func TestUnpauseContainerNotFound(t *testing.T) {
}
func TestKillContainer(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "", status: http.StatusNoContent}
client := newTestClient(fakeRT)
id := "4fa6e0f0c6786287e131c3852c58a2e01cc697a68231826813597e4994f1d6e2"
@@ -1251,6 +1287,7 @@ func TestKillContainer(t *testing.T) {
}
func TestKillContainerSignal(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "", status: http.StatusNoContent}
client := newTestClient(fakeRT)
id := "4fa6e0f0c6786287e131c3852c58a2e01cc697a68231826813597e4994f1d6e2"
@@ -1268,6 +1305,7 @@ func TestKillContainerSignal(t *testing.T) {
}
func TestKillContainerNotFound(t *testing.T) {
t.Parallel()
client := newTestClient(&FakeRoundTripper{message: "no such container", status: http.StatusNotFound})
err := client.KillContainer(KillContainerOptions{ID: "a2334"})
expected := &NoSuchContainer{ID: "a2334"}
@@ -1277,6 +1315,7 @@ func TestKillContainerNotFound(t *testing.T) {
}
func TestRemoveContainer(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "", status: http.StatusOK}
client := newTestClient(fakeRT)
id := "4fa6e0f0c6786287e131c3852c58a2e01cc697a68231826813597e4994f1d6e2"
@@ -1296,6 +1335,7 @@ func TestRemoveContainer(t *testing.T) {
}
func TestRemoveContainerRemoveVolumes(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "", status: http.StatusOK}
client := newTestClient(fakeRT)
id := "4fa6e0f0c6786287e131c3852c58a2e01cc697a68231826813597e4994f1d6e2"
@@ -1313,6 +1353,7 @@ func TestRemoveContainerRemoveVolumes(t *testing.T) {
}
func TestRemoveContainerNotFound(t *testing.T) {
t.Parallel()
client := newTestClient(&FakeRoundTripper{message: "no such container", status: http.StatusNotFound})
err := client.RemoveContainer(RemoveContainerOptions{ID: "a2334"})
expected := &NoSuchContainer{ID: "a2334"}
@@ -1322,6 +1363,7 @@ func TestRemoveContainerNotFound(t *testing.T) {
}
func TestResizeContainerTTY(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "", status: http.StatusOK}
client := newTestClient(fakeRT)
id := "4fa6e0f0c6786287e131c3852c58a2e01cc697a68231826813597e4994f1d6e2"
@@ -1348,6 +1390,7 @@ func TestResizeContainerTTY(t *testing.T) {
}
func TestWaitContainer(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: `{"StatusCode": 56}`, status: http.StatusOK}
client := newTestClient(fakeRT)
id := "4fa6e0f0c6786287e131c3852c58a2e01cc697a68231826813597e4994f1d6e2"
@@ -1369,6 +1412,7 @@ func TestWaitContainer(t *testing.T) {
}
func TestWaitContainerWithContext(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: `{"StatusCode": 56}`, status: http.StatusOK}
client := newTestClient(fakeRT)
id := "4fa6e0f0c6786287e131c3852c58a2e01cc697a68231826813597e4994f1d6e2"
@@ -1406,6 +1450,7 @@ func TestWaitContainerWithContext(t *testing.T) {
}
func TestWaitContainerNotFound(t *testing.T) {
t.Parallel()
client := newTestClient(&FakeRoundTripper{message: "no such container", status: http.StatusNotFound})
_, err := client.WaitContainer("a2334")
expected := &NoSuchContainer{ID: "a2334"}
@@ -1415,6 +1460,7 @@ func TestWaitContainerNotFound(t *testing.T) {
}
func TestCommitContainer(t *testing.T) {
t.Parallel()
response := `{"Id":"596069db4bf5"}`
client := newTestClient(&FakeRoundTripper{message: response, status: http.StatusOK})
id := "596069db4bf5"
@@ -1428,6 +1474,7 @@ func TestCommitContainer(t *testing.T) {
}
func TestCommitContainerParams(t *testing.T) {
t.Parallel()
cfg := Config{Memory: 67108864}
json, _ := json.Marshal(&cfg)
var tests = []struct {
@@ -1479,6 +1526,7 @@ func TestCommitContainerParams(t *testing.T) {
}
func TestCommitContainerFailure(t *testing.T) {
t.Parallel()
client := newTestClient(&FakeRoundTripper{message: "no such container", status: http.StatusInternalServerError})
_, err := client.CommitContainer(CommitContainerOptions{})
if err == nil {
@@ -1487,6 +1535,7 @@ func TestCommitContainerFailure(t *testing.T) {
}
func TestCommitContainerNotFound(t *testing.T) {
t.Parallel()
client := newTestClient(&FakeRoundTripper{message: "no such container", status: http.StatusNotFound})
_, err := client.CommitContainer(CommitContainerOptions{})
expected := &NoSuchContainer{ID: ""}
@@ -1496,6 +1545,7 @@ func TestCommitContainerNotFound(t *testing.T) {
}
func TestAttachToContainerLogs(t *testing.T) {
t.Parallel()
var req http.Request
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte{1, 0, 0, 0, 0, 0, 0, 19})
@@ -1540,6 +1590,7 @@ func TestAttachToContainerLogs(t *testing.T) {
}
func TestAttachToContainer(t *testing.T) {
t.Parallel()
var reader = strings.NewReader("send value")
var req http.Request
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
@@ -1579,6 +1630,7 @@ func TestAttachToContainer(t *testing.T) {
}
func TestAttachToContainerSentinel(t *testing.T) {
t.Parallel()
var reader = strings.NewReader("send value")
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte{1, 0, 0, 0, 0, 0, 0, 5})
@@ -1612,6 +1664,7 @@ func TestAttachToContainerSentinel(t *testing.T) {
}
func TestAttachToContainerNilStdout(t *testing.T) {
t.Parallel()
var reader = strings.NewReader("send value")
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte{1, 0, 0, 0, 0, 0, 0, 5})
@@ -1639,6 +1692,7 @@ func TestAttachToContainerNilStdout(t *testing.T) {
}
func TestAttachToContainerNilStderr(t *testing.T) {
t.Parallel()
var reader = strings.NewReader("send value")
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte{1, 0, 0, 0, 0, 0, 0, 5})
@@ -1665,6 +1719,7 @@ func TestAttachToContainerNilStderr(t *testing.T) {
}
func TestAttachToContainerStdinOnly(t *testing.T) {
t.Parallel()
var reader = strings.NewReader("send value")
serverFinished := make(chan struct{})
clientFinished := make(chan struct{})
@@ -1711,6 +1766,7 @@ func TestAttachToContainerStdinOnly(t *testing.T) {
}
func TestAttachToContainerRawTerminalFalse(t *testing.T) {
t.Parallel()
input := strings.NewReader("send value")
var req http.Request
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
@@ -1766,6 +1822,7 @@ func TestAttachToContainerRawTerminalFalse(t *testing.T) {
}
func TestAttachToContainerWithoutContainer(t *testing.T) {
t.Parallel()
var client Client
err := client.AttachToContainer(AttachToContainerOptions{})
expected := &NoSuchContainer{ID: ""}
@@ -1775,6 +1832,7 @@ func TestAttachToContainerWithoutContainer(t *testing.T) {
}
func TestLogs(t *testing.T) {
t.Parallel()
var req http.Request
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
prefix := []byte{1, 0, 0, 0, 0, 0, 0, 19}
@@ -1823,6 +1881,7 @@ func TestLogs(t *testing.T) {
}
func TestLogsNilStdoutDoesntFail(t *testing.T) {
t.Parallel()
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
prefix := []byte{1, 0, 0, 0, 0, 0, 0, 19}
w.Write(prefix)
@@ -1845,6 +1904,7 @@ func TestLogsNilStdoutDoesntFail(t *testing.T) {
}
func TestLogsNilStderrDoesntFail(t *testing.T) {
t.Parallel()
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
prefix := []byte{2, 0, 0, 0, 0, 0, 0, 19}
w.Write(prefix)
@@ -1867,6 +1927,7 @@ func TestLogsNilStderrDoesntFail(t *testing.T) {
}
func TestLogsSpecifyingTail(t *testing.T) {
t.Parallel()
var req http.Request
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
prefix := []byte{1, 0, 0, 0, 0, 0, 0, 19}
@@ -1916,6 +1977,7 @@ func TestLogsSpecifyingTail(t *testing.T) {
}
func TestLogsRawTerminal(t *testing.T) {
t.Parallel()
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("something happened!"))
}))
@@ -1944,6 +2006,7 @@ func TestLogsRawTerminal(t *testing.T) {
}
func TestLogsNoContainer(t *testing.T) {
t.Parallel()
var client Client
err := client.Logs(LogsOptions{})
expected := &NoSuchContainer{ID: ""}
@@ -1953,6 +2016,7 @@ func TestLogsNoContainer(t *testing.T) {
}
func TestNoSuchContainerError(t *testing.T) {
t.Parallel()
var err = &NoSuchContainer{ID: "i345"}
expected := "No such container: i345"
if got := err.Error(); got != expected {
@@ -1961,6 +2025,7 @@ func TestNoSuchContainerError(t *testing.T) {
}
func TestNoSuchContainerErrorMessage(t *testing.T) {
t.Parallel()
var err = &NoSuchContainer{ID: "i345", Err: errors.New("some advanced error info")}
expected := "some advanced error info"
if got := err.Error(); got != expected {
@@ -1969,6 +2034,7 @@ func TestNoSuchContainerErrorMessage(t *testing.T) {
}
func TestExportContainer(t *testing.T) {
t.Parallel()
content := "exported container tar content"
out := stdoutMock{bytes.NewBufferString(content)}
client := newTestClient(&FakeRoundTripper{status: http.StatusOK})
@@ -2015,6 +2081,7 @@ func tempfile(filename string) string {
}
func TestExportContainerNoId(t *testing.T) {
t.Parallel()
client := Client{}
out := stdoutMock{bytes.NewBufferString("")}
err := client.ExportContainer(ExportContainerOptions{OutputStream: out})
@@ -2028,6 +2095,7 @@ func TestExportContainerNoId(t *testing.T) {
}
func TestUploadToContainer(t *testing.T) {
t.Parallel()
content := "File content"
in := stdinMock{bytes.NewBufferString(content)}
fakeRT := &FakeRoundTripper{status: http.StatusOK}
@@ -2054,6 +2122,7 @@ func TestUploadToContainer(t *testing.T) {
}
func TestDownloadFromContainer(t *testing.T) {
t.Parallel()
filecontent := "File content"
client := newTestClient(&FakeRoundTripper{message: filecontent, status: http.StatusOK})
@@ -2071,6 +2140,7 @@ func TestDownloadFromContainer(t *testing.T) {
}
func TestCopyFromContainer(t *testing.T) {
t.Parallel()
content := "File content"
out := stdoutMock{bytes.NewBufferString(content)}
client := newTestClient(&FakeRoundTripper{status: http.StatusOK})
@@ -2088,6 +2158,7 @@ func TestCopyFromContainer(t *testing.T) {
}
func TestCopyFromContainerEmptyContainer(t *testing.T) {
t.Parallel()
client := newTestClient(&FakeRoundTripper{status: http.StatusOK})
err := client.CopyFromContainer(CopyFromContainerOptions{})
_, ok := err.(*NoSuchContainer)
@@ -2097,6 +2168,7 @@ func TestCopyFromContainerEmptyContainer(t *testing.T) {
}
func TestCopyFromContainerDockerAPI124(t *testing.T) {
t.Parallel()
client := newTestClient(&FakeRoundTripper{status: http.StatusOK})
client.serverAPIVersion = apiVersion124
opts := CopyFromContainerOptions{
@@ -2113,6 +2185,7 @@ func TestCopyFromContainerDockerAPI124(t *testing.T) {
}
func TestPassingNameOptToCreateContainerReturnsItInContainer(t *testing.T) {
t.Parallel()
jsonContainer := `{
"Id": "4fa6e0f0c6786287e131c3852c58a2e01cc697a68231826813597e4994f1d6e2",
"Warnings": []
@@ -2131,6 +2204,7 @@ func TestPassingNameOptToCreateContainerReturnsItInContainer(t *testing.T) {
}
func TestAlwaysRestart(t *testing.T) {
t.Parallel()
policy := AlwaysRestart()
if policy.Name != "always" {
t.Errorf("AlwaysRestart(): wrong policy name. Want %q. Got %q", "always", policy.Name)
@@ -2141,6 +2215,7 @@ func TestAlwaysRestart(t *testing.T) {
}
func TestRestartOnFailure(t *testing.T) {
t.Parallel()
const retry = 5
policy := RestartOnFailure(retry)
if policy.Name != "on-failure" {
@@ -2152,6 +2227,7 @@ func TestRestartOnFailure(t *testing.T) {
}
func TestRestartUnlessStopped(t *testing.T) {
t.Parallel()
policy := RestartUnlessStopped()
if policy.Name != "unless-stopped" {
t.Errorf("RestartUnlessStopped(): wrong policy name. Want %q. Got %q", "unless-stopped", policy.Name)
@@ -2162,6 +2238,7 @@ func TestRestartUnlessStopped(t *testing.T) {
}
func TestNeverRestart(t *testing.T) {
t.Parallel()
policy := NeverRestart()
if policy.Name != "no" {
t.Errorf("NeverRestart(): wrong policy name. Want %q. Got %q", "always", policy.Name)
@@ -2172,6 +2249,7 @@ func TestNeverRestart(t *testing.T) {
}
func TestTopContainer(t *testing.T) {
t.Parallel()
jsonTop := `{
"Processes": [
[
@@ -2232,6 +2310,7 @@ func TestTopContainer(t *testing.T) {
}
func TestTopContainerNotFound(t *testing.T) {
t.Parallel()
client := newTestClient(&FakeRoundTripper{message: "no such container", status: http.StatusNotFound})
_, err := client.TopContainer("abef348", "")
expected := &NoSuchContainer{ID: "abef348"}
@@ -2241,6 +2320,7 @@ func TestTopContainerNotFound(t *testing.T) {
}
func TestTopContainerWithPsArgs(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "no such container", status: http.StatusNotFound}
client := newTestClient(fakeRT)
expectedErr := &NoSuchContainer{ID: "abef348"}
@@ -2254,6 +2334,7 @@ func TestTopContainerWithPsArgs(t *testing.T) {
}
func TestStats(t *testing.T) {
t.Parallel()
jsonStats1 := `{
"read" : "2015-01-08T22:57:31.547920715Z",
"network" : {
@@ -2561,6 +2642,7 @@ func TestStats(t *testing.T) {
}
func TestStatsContainerNotFound(t *testing.T) {
t.Parallel()
client := newTestClient(&FakeRoundTripper{message: "no such container", status: http.StatusNotFound})
statsC := make(chan *Stats)
done := make(chan bool)
@@ -2573,6 +2655,7 @@ func TestStatsContainerNotFound(t *testing.T) {
}
func TestRenameContainer(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "", status: http.StatusOK}
client := newTestClient(fakeRT)
opts := RenameContainerOptions{ID: "something_old", Name: "something_new"}
@@ -2607,6 +2690,7 @@ func (rt *sleepyRoudTripper) RoundTrip(r *http.Request) (*http.Response, error)
}
func TestInspectContainerWhenContextTimesOut(t *testing.T) {
t.Parallel()
rt := sleepyRoudTripper{sleepDuration: 200 * time.Millisecond}
client := newTestClient(&rt)
@@ -2621,6 +2705,7 @@ func TestInspectContainerWhenContextTimesOut(t *testing.T) {
}
func TestStartContainerWhenContextTimesOut(t *testing.T) {
t.Parallel()
rt := sleepyRoudTripper{sleepDuration: 200 * time.Millisecond}
client := newTestClient(&rt)
@@ -2635,6 +2720,7 @@ func TestStartContainerWhenContextTimesOut(t *testing.T) {
}
func TestStopContainerWhenContextTimesOut(t *testing.T) {
t.Parallel()
rt := sleepyRoudTripper{sleepDuration: 200 * time.Millisecond}
client := newTestClient(&rt)
@@ -2649,6 +2735,7 @@ func TestStopContainerWhenContextTimesOut(t *testing.T) {
}
func TestWaitContainerWhenContextTimesOut(t *testing.T) {
t.Parallel()
rt := sleepyRoudTripper{sleepDuration: 200 * time.Millisecond}
client := newTestClient(&rt)
@@ -2663,6 +2750,7 @@ func TestWaitContainerWhenContextTimesOut(t *testing.T) {
}
func TestPruneContainers(t *testing.T) {
t.Parallel()
results := `{
"ContainersDeleted": [
"a", "b", "c"

View File

@@ -20,6 +20,7 @@ import (
)
func TestExportContainerViaUnixSocket(t *testing.T) {
t.Parallel()
content := "exported container tar content"
var buf []byte
out := bytes.NewBuffer(buf)
@@ -51,6 +52,7 @@ func TestExportContainerViaUnixSocket(t *testing.T) {
}
func TestStatsTimeoutUnixSocket(t *testing.T) {
t.Parallel()
tmpdir, err := ioutil.TempDir("", "socket")
if err != nil {
t.Fatal(err)

View File

@@ -13,6 +13,7 @@ import (
)
func TestGet(t *testing.T) {
t.Parallel()
var tests = []struct {
input []string
query string
@@ -33,6 +34,7 @@ func TestGet(t *testing.T) {
}
func TestExists(t *testing.T) {
t.Parallel()
var tests = []struct {
input []string
query string
@@ -52,6 +54,7 @@ func TestExists(t *testing.T) {
}
func TestGetBool(t *testing.T) {
t.Parallel()
var tests = []struct {
input string
expected bool
@@ -74,6 +77,7 @@ func TestGetBool(t *testing.T) {
}
func TestSetBool(t *testing.T) {
t.Parallel()
var tests = []struct {
input bool
expected string
@@ -90,6 +94,7 @@ func TestSetBool(t *testing.T) {
}
func TestGetInt(t *testing.T) {
t.Parallel()
var tests = []struct {
input string
expected int
@@ -106,6 +111,7 @@ func TestGetInt(t *testing.T) {
}
func TestSetInt(t *testing.T) {
t.Parallel()
var tests = []struct {
input int
expected string
@@ -123,6 +129,7 @@ func TestSetInt(t *testing.T) {
}
func TestGetInt64(t *testing.T) {
t.Parallel()
var tests = []struct {
input string
expected int64
@@ -139,6 +146,7 @@ func TestGetInt64(t *testing.T) {
}
func TestSetInt64(t *testing.T) {
t.Parallel()
var tests = []struct {
input int64
expected string
@@ -156,6 +164,7 @@ func TestSetInt64(t *testing.T) {
}
func TestGetJSON(t *testing.T) {
t.Parallel()
var p struct {
Name string `json:"name"`
Age int `json:"age"`
@@ -175,6 +184,7 @@ func TestGetJSON(t *testing.T) {
}
func TestGetJSONAbsent(t *testing.T) {
t.Parallel()
var l []string
var env Env
err := env.GetJSON("person", &l)
@@ -187,6 +197,7 @@ func TestGetJSONAbsent(t *testing.T) {
}
func TestGetJSONFailure(t *testing.T) {
t.Parallel()
var p []string
var env Env
env.Set("list-person", `{"name":"Gopher","age":5}`)
@@ -197,6 +208,7 @@ func TestGetJSONFailure(t *testing.T) {
}
func TestSetJSON(t *testing.T) {
t.Parallel()
var p1 = struct {
Name string `json:"name"`
Age int `json:"age"`
@@ -220,6 +232,7 @@ func TestSetJSON(t *testing.T) {
}
func TestSetJSONFailure(t *testing.T) {
t.Parallel()
var env Env
err := env.SetJSON("person", unmarshable{})
if err == nil {
@@ -231,6 +244,7 @@ func TestSetJSONFailure(t *testing.T) {
}
func TestGetList(t *testing.T) {
t.Parallel()
var tests = []struct {
input string
expected []string
@@ -249,6 +263,7 @@ func TestGetList(t *testing.T) {
}
func TestSetList(t *testing.T) {
t.Parallel()
list := []string{"a", "b", "c"}
var env Env
if err := env.SetList("SOME", list); err != nil {
@@ -260,6 +275,7 @@ func TestSetList(t *testing.T) {
}
func TestSet(t *testing.T) {
t.Parallel()
var env Env
env.Set("PATH", "/home/bin:/bin")
env.Set("SOMETHING", "/usr/bin")
@@ -273,6 +289,7 @@ func TestSet(t *testing.T) {
}
func TestDecode(t *testing.T) {
t.Parallel()
var tests = []struct {
input string
expectedOut []string
@@ -306,6 +323,7 @@ func TestDecode(t *testing.T) {
}
func TestSetAuto(t *testing.T) {
t.Parallel()
buf := bytes.NewBufferString("oi")
var tests = []struct {
input interface{}
@@ -327,6 +345,7 @@ func TestSetAuto(t *testing.T) {
}
func TestMap(t *testing.T) {
t.Parallel()
var tests = []struct {
input []string
expected map[string]string

View File

@@ -216,7 +216,7 @@ func (eventState *eventMonitoringState) monitorEvents(c *Client) {
return
}
eventState.updateLastSeen(ev)
go eventState.sendEvent(ev)
eventState.sendEvent(ev)
case err = <-eventState.errC:
if err == ErrNoListeners {
eventState.disableEventMonitoring()
@@ -274,7 +274,10 @@ func (eventState *eventMonitoringState) sendEvent(event *APIEvents) {
}
for _, listener := range eventState.listeners {
listener <- event
select {
case listener <- event:
default:
}
}
}
}
@@ -342,11 +345,12 @@ func (c *Client) eventHijack(startTime int64, eventChan chan *APIEvents, errChan
if event.Time == 0 {
continue
}
if !c.eventMonitor.isEnabled() || c.eventMonitor.C != eventChan {
return
}
transformEvent(&event)
eventChan <- &event
c.eventMonitor.RLock()
if c.eventMonitor.enabled && c.eventMonitor.C == eventChan {
eventChan <- &event
}
c.eventMonitor.RUnlock()
}
}(res, conn)
return nil

View File

@@ -11,17 +11,20 @@ import (
"io/ioutil"
"net/http"
"net/http/httptest"
"reflect"
"strings"
"testing"
"time"
"github.com/google/go-cmp/cmp"
)
func TestEventListeners(t *testing.T) {
t.Parallel()
testEventListeners("TestEventListeners", t, httptest.NewServer, NewClient)
}
func TestTLSEventListeners(t *testing.T) {
t.Parallel()
testEventListeners("TestTLSEventListeners", t, func(handler http.Handler) *httptest.Server {
server := httptest.NewUnstartedServer(handler)
@@ -61,7 +64,17 @@ func testEventListeners(testName string, t *testing.T, buildServer func(http.Han
{"status":"destroy","id":"dfdf82bd3881","from":"base:latest","time":1374067970}
{"Action":"create","Actor":{"Attributes":{"HAProxyMode":"http","HealthCheck":"HttpGet","HealthCheckArgs":"http://127.0.0.1:39051/status/check","ServicePort_8080":"17801","image":"datanerd.us/siteeng/sample-app-go:latest","name":"sample-app-client-go-69818c1223ddb5"},"ID":"a925eaf4084d5c3bcf337b2abb05f566ebb94276dff34f6effb00d8ecd380e16"},"Type":"container","from":"datanerd.us/siteeng/sample-app-go:latest","id":"a925eaf4084d5c3bcf337b2abb05f566ebb94276dff34f6effb00d8ecd380e16","status":"create","time":1459133932,"timeNano":1459133932961735842}`
wantResponse := []*APIEvents{
server := buildServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
rsc := bufio.NewScanner(strings.NewReader(response))
for rsc.Scan() {
w.Write(rsc.Bytes())
w.(http.Flusher).Flush()
time.Sleep(10 * time.Millisecond)
}
}))
defer server.Close()
wantedEvents := []APIEvents{
{
Action: "pull",
Type: "image",
@@ -213,15 +226,6 @@ func testEventListeners(testName string, t *testing.T, buildServer func(http.Han
},
},
}
server := buildServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
rsc := bufio.NewScanner(strings.NewReader(response))
for rsc.Scan() {
w.Write([]byte(rsc.Text()))
w.(http.Flusher).Flush()
time.Sleep(10 * time.Millisecond)
}
}))
defer server.Close()
client, err := buildClient(server.URL)
if err != nil {
@@ -229,9 +233,8 @@ func testEventListeners(testName string, t *testing.T, buildServer func(http.Han
}
client.SkipServerVersionCheck = true
listener := make(chan *APIEvents, 10)
listener := make(chan *APIEvents, len(wantedEvents)+1)
defer func() {
time.Sleep(10 * time.Millisecond)
if err = client.RemoveEventListener(listener); err != nil {
t.Error(err)
}
@@ -242,22 +245,31 @@ func testEventListeners(testName string, t *testing.T, buildServer func(http.Han
t.Errorf("Failed to add event listener: %s", err)
}
timeout := time.After(1 * time.Second)
timeout := time.After(5 * time.Second)
events := make([]APIEvents, 0, len(wantedEvents))
for i := 0; i < 9; i++ {
loop:
for i := range wantedEvents {
select {
case msg := <-listener:
t.Logf("%d: Received: %v", i, msg)
if !reflect.DeepEqual(msg, wantResponse[i]) {
t.Fatalf("%d: wanted: %#v\n got: %#v", i, wantResponse[i], msg)
case msg, ok := <-listener:
if !ok {
break loop
}
events = append(events, *msg)
case <-timeout:
t.Fatalf("%s timed out waiting on events", testName)
t.Fatalf("%s: timed out waiting on events after %d events", testName, i)
}
}
cmpr := cmp.Comparer(func(e1, e2 APIEvents) bool {
return e1.Action == e2.Action && e1.Actor.ID == e2.Actor.ID
})
if dff := cmp.Diff(events, wantedEvents, cmpr); dff != "" {
t.Errorf("wrong events:\n%s", dff)
}
}
func TestEventListenerReAdding(t *testing.T) {
t.Parallel()
endChan := make(chan bool)
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
<-endChan

View File

@@ -6,6 +6,7 @@ package docker
import (
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
@@ -29,6 +30,7 @@ type CreateExecOptions struct {
AttachStdout bool `json:"AttachStdout,omitempty" yaml:"AttachStdout,omitempty" toml:"AttachStdout,omitempty"`
AttachStderr bool `json:"AttachStderr,omitempty" yaml:"AttachStderr,omitempty" toml:"AttachStderr,omitempty"`
Tty bool `json:"Tty,omitempty" yaml:"Tty,omitempty" toml:"Tty,omitempty"`
Env []string `json:"Env,omitempty" yaml:"Env,omitempty" toml:"Env,omitempty"`
Cmd []string `json:"Cmd,omitempty" yaml:"Cmd,omitempty" toml:"Cmd,omitempty"`
Container string `json:"Container,omitempty" yaml:"Container,omitempty" toml:"Container,omitempty"`
User string `json:"User,omitempty" yaml:"User,omitempty" toml:"User,omitempty"`
@@ -41,6 +43,9 @@ type CreateExecOptions struct {
//
// See https://goo.gl/60TeBP for more details
func (c *Client) CreateExec(opts CreateExecOptions) (*Exec, error) {
if len(opts.Env) > 0 && c.serverAPIVersion.LessThan(apiVersion125) {
return nil, errors.New("exec configuration Env is only supported in API#1.25 and above")
}
path := fmt.Sprintf("/containers/%s/exec", opts.Container)
resp, err := c.do("POST", path, doOptions{data: opts, context: opts.Context})
if err != nil {

View File

@@ -7,6 +7,7 @@ package docker
import (
"bytes"
"encoding/json"
"net"
"net/http"
"net/http/httptest"
"net/url"
@@ -16,6 +17,7 @@ import (
)
func TestExecCreate(t *testing.T) {
t.Parallel()
jsonContainer := `{"Id": "4fa6e0f0c6786287e131c3852c58a2e01cc697a68231826813597e4994f1d6e2"}`
var expected struct{ ID string }
err := json.Unmarshal([]byte(jsonContainer), &expected)
@@ -56,7 +58,70 @@ func TestExecCreate(t *testing.T) {
}
}
func TestExecCreateWithEnvErr(t *testing.T) {
t.Parallel()
jsonContainer := `{"Id": "4fa6e0f0c6786287e131c3852c58a2e01cc697a68231826813597e4994f1d6e2"}`
var expected struct{ ID string }
err := json.Unmarshal([]byte(jsonContainer), &expected)
if err != nil {
t.Fatal(err)
}
fakeRT := &FakeRoundTripper{message: jsonContainer, status: http.StatusOK}
client := newTestClient(fakeRT)
config := CreateExecOptions{
Container: "test",
AttachStdin: true,
AttachStdout: true,
AttachStderr: false,
Tty: false,
Env: []string{"foo=bar"},
Cmd: []string{"touch", "/tmp/file"},
User: "a-user",
}
_, err = client.CreateExec(config)
if err == nil || err.Error() != "exec configuration Env is only supported in API#1.25 and above" {
t.Error("CreateExec: options contain Env for unsupported api version")
}
}
func TestExecCreateWithEnv(t *testing.T) {
t.Parallel()
jsonContainer := `{"Id": "4fa6e0f0c6786287e131c3852c58a2e01cc697a68231826813597e4994f1d6e2"}`
var expected struct{ ID string }
err := json.Unmarshal([]byte(jsonContainer), &expected)
if err != nil {
t.Fatal(err)
}
fakeRT := &FakeRoundTripper{message: jsonContainer, status: http.StatusOK}
endpoint := "http://localhost:4243"
u, _ := parseEndpoint("http://localhost:4243", false)
testAPIVersion, _ := NewAPIVersion("1.25")
client := Client{
HTTPClient: &http.Client{Transport: fakeRT},
Dialer: &net.Dialer{},
endpoint: endpoint,
endpointURL: u,
SkipServerVersionCheck: true,
serverAPIVersion: testAPIVersion,
}
config := CreateExecOptions{
Container: "test",
AttachStdin: true,
AttachStdout: true,
AttachStderr: false,
Tty: false,
Env: []string{"foo=bar"},
Cmd: []string{"touch", "/tmp/file"},
User: "a-user",
}
_, err = client.CreateExec(config)
if err != nil {
t.Error(err)
}
}
func TestExecStartDetached(t *testing.T) {
t.Parallel()
execID := "4fa6e0f0c6786287e131c3852c58a2e01cc697a68231826813597e4994f1d6e2"
fakeRT := &FakeRoundTripper{status: http.StatusOK}
client := newTestClient(fakeRT)
@@ -114,6 +179,7 @@ func TestExecStartAndAttach(t *testing.T) {
}
func TestExecResize(t *testing.T) {
t.Parallel()
execID := "4fa6e0f0c6786287e131c3852c58a2e01cc697a68231826813597e4994f1d6e2"
fakeRT := &FakeRoundTripper{status: http.StatusOK}
client := newTestClient(fakeRT)
@@ -132,6 +198,7 @@ func TestExecResize(t *testing.T) {
}
func TestExecInspect(t *testing.T) {
t.Parallel()
jsonExec := `{
"CanRemove": false,
"ContainerID": "b53ee82b53a40c7dca428523e34f741f3abc51d9f297a14ff874bf761b995126",

View File

@@ -51,6 +51,7 @@ func (m stdinMock) Close() error {
}
func TestListImages(t *testing.T) {
t.Parallel()
body := `[
{
"Repository":"base",
@@ -103,6 +104,7 @@ func TestListImages(t *testing.T) {
}
func TestListImagesParameters(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "null", status: http.StatusOK}
client := newTestClient(fakeRT)
_, err := client.ListImages(ListImagesOptions{All: false})
@@ -145,6 +147,7 @@ func TestListImagesParameters(t *testing.T) {
}
func TestImageHistory(t *testing.T) {
t.Parallel()
body := `[
{
"Id": "25daec02219d2d852f7526137213a9b199926b4b24e732eab5b8bc6c49bd470e",
@@ -187,6 +190,7 @@ func TestImageHistory(t *testing.T) {
}
func TestRemoveImage(t *testing.T) {
t.Parallel()
name := "test"
fakeRT := &FakeRoundTripper{message: "", status: http.StatusNoContent}
client := newTestClient(fakeRT)
@@ -206,6 +210,7 @@ func TestRemoveImage(t *testing.T) {
}
func TestRemoveImageNotFound(t *testing.T) {
t.Parallel()
client := newTestClient(&FakeRoundTripper{message: "no such image", status: http.StatusNotFound})
err := client.RemoveImage("test:")
if err != ErrNoSuchImage {
@@ -214,6 +219,7 @@ func TestRemoveImageNotFound(t *testing.T) {
}
func TestRemoveImageExtended(t *testing.T) {
t.Parallel()
name := "test"
fakeRT := &FakeRoundTripper{message: "", status: http.StatusNoContent}
client := newTestClient(fakeRT)
@@ -237,6 +243,7 @@ func TestRemoveImageExtended(t *testing.T) {
}
func TestInspectImage(t *testing.T) {
t.Parallel()
body := `{
"Id":"b750fe79269d2ec9a3c593ef05b4332b1d1a02a62b4accb2c21d589ff2f5f2dc",
"Parent":"27cf784147099545",
@@ -295,6 +302,7 @@ func TestInspectImage(t *testing.T) {
}
func TestInspectImageNotFound(t *testing.T) {
t.Parallel()
client := newTestClient(&FakeRoundTripper{message: "no such image", status: http.StatusNotFound})
name := "test"
image, err := client.InspectImage(name)
@@ -307,6 +315,7 @@ func TestInspectImageNotFound(t *testing.T) {
}
func TestPushImage(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "Pushing 1/100", status: http.StatusOK}
client := newTestClient(fakeRT)
var buf bytes.Buffer
@@ -341,6 +350,7 @@ func TestPushImage(t *testing.T) {
}
func TestPushImageWithRawJSON(t *testing.T) {
t.Parallel()
body := `
{"status":"Pushing..."}
{"status":"Pushing", "progress":"1/? (n/a)", "progressDetail":{"current":1}}}
@@ -370,6 +380,7 @@ func TestPushImageWithRawJSON(t *testing.T) {
}
func TestPushImageWithAuthentication(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "Pushing 1/100", status: http.StatusOK}
client := newTestClient(fakeRT)
var buf bytes.Buffer
@@ -400,6 +411,7 @@ func TestPushImageWithAuthentication(t *testing.T) {
}
func TestPushImageCustomRegistry(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "Pushing 1/100", status: http.StatusOK}
client := newTestClient(fakeRT)
var authConfig AuthConfiguration
@@ -420,6 +432,7 @@ func TestPushImageCustomRegistry(t *testing.T) {
}
func TestPushImageNoName(t *testing.T) {
t.Parallel()
client := Client{}
err := client.PushImage(PushImageOptions{}, AuthConfiguration{})
if err != ErrNoSuchImage {
@@ -428,6 +441,7 @@ func TestPushImageNoName(t *testing.T) {
}
func TestPullImage(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "Pulling 1/100", status: http.StatusOK}
client := newTestClient(fakeRT)
var buf bytes.Buffer
@@ -455,6 +469,7 @@ func TestPullImage(t *testing.T) {
}
func TestPullImageWithDigest(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "Pulling 1/100", status: http.StatusOK}
client := newTestClient(fakeRT)
var buf bytes.Buffer
@@ -490,6 +505,7 @@ func TestPullImageWithDigestAndTag(t *testing.T) {
// This is probably a wrong use of the Docker API, but let's let users
// send the request to the API. And also changing this behavior would
// be a breaking change on go-dockerclient.
t.Parallel()
fakeRT := &FakeRoundTripper{message: "Pulling 1/100", status: http.StatusOK}
client := newTestClient(fakeRT)
var buf bytes.Buffer
@@ -523,6 +539,7 @@ func TestPullImageWithDigestAndTag(t *testing.T) {
}
func TestPullImageWithRawJSON(t *testing.T) {
t.Parallel()
body := `
{"status":"Pulling..."}
{"status":"Pulling", "progress":"1 B/ 100 B", "progressDetail":{"current":1, "total":100}}
@@ -550,6 +567,7 @@ func TestPullImageWithRawJSON(t *testing.T) {
}
func TestPullImageWithoutOutputStream(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "Pulling 1/100", status: http.StatusOK}
client := newTestClient(fakeRT)
opts := PullImageOptions{
@@ -569,6 +587,7 @@ func TestPullImageWithoutOutputStream(t *testing.T) {
}
func TestPullImageCustomRegistry(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "Pulling 1/100", status: http.StatusOK}
client := newTestClient(fakeRT)
var buf bytes.Buffer
@@ -590,6 +609,7 @@ func TestPullImageCustomRegistry(t *testing.T) {
}
func TestPullImageTag(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "Pulling 1/100", status: http.StatusOK}
client := newTestClient(fakeRT)
var buf bytes.Buffer
@@ -612,6 +632,7 @@ func TestPullImageTag(t *testing.T) {
}
func TestPullImageNoRepository(t *testing.T) {
t.Parallel()
var opts PullImageOptions
client := Client{}
err := client.PullImage(opts, AuthConfiguration{})
@@ -621,6 +642,7 @@ func TestPullImageNoRepository(t *testing.T) {
}
func TestImportImageFromUrl(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "", status: http.StatusOK}
client := newTestClient(fakeRT)
var buf bytes.Buffer
@@ -643,6 +665,7 @@ func TestImportImageFromUrl(t *testing.T) {
}
func TestImportImageFromInput(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "", status: http.StatusOK}
client := newTestClient(fakeRT)
in := bytes.NewBufferString("tar content")
@@ -672,7 +695,8 @@ func TestImportImageFromInput(t *testing.T) {
}
}
func TestImportImageDoesNotPassesInputIfSourceIsNotDash(t *testing.T) {
func TestImportImageDoesNotPassInputIfSourceIsNotDash(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "", status: http.StatusOK}
client := newTestClient(fakeRT)
var buf bytes.Buffer
@@ -701,6 +725,7 @@ func TestImportImageDoesNotPassesInputIfSourceIsNotDash(t *testing.T) {
}
func TestImportImageShouldPassTarContentToBodyWhenSourceIsFilePath(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "", status: http.StatusOK}
client := newTestClient(fakeRT)
var buf bytes.Buffer
@@ -729,6 +754,7 @@ func TestImportImageShouldPassTarContentToBodyWhenSourceIsFilePath(t *testing.T)
}
func TestImportImageShouldChangeSourceToDashWhenItsAFilePath(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "", status: http.StatusOK}
client := newTestClient(fakeRT)
var buf bytes.Buffer
@@ -750,6 +776,7 @@ func TestImportImageShouldChangeSourceToDashWhenItsAFilePath(t *testing.T) {
}
func TestBuildImageParameters(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "", status: http.StatusOK}
client := newTestClient(fakeRT)
var buf bytes.Buffer
@@ -806,6 +833,7 @@ func TestBuildImageParameters(t *testing.T) {
}
func TestBuildImageParametersForRemoteBuild(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "", status: http.StatusOK}
client := newTestClient(fakeRT)
var buf bytes.Buffer
@@ -828,6 +856,7 @@ func TestBuildImageParametersForRemoteBuild(t *testing.T) {
}
func TestBuildImageMissingRepoAndNilInput(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "", status: http.StatusOK}
client := newTestClient(fakeRT)
var buf bytes.Buffer
@@ -843,6 +872,7 @@ func TestBuildImageMissingRepoAndNilInput(t *testing.T) {
}
func TestBuildImageMissingOutputStream(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "", status: http.StatusOK}
client := newTestClient(fakeRT)
opts := BuildImageOptions{Name: "testImage"}
@@ -853,6 +883,7 @@ func TestBuildImageMissingOutputStream(t *testing.T) {
}
func TestBuildImageWithRawJSON(t *testing.T) {
t.Parallel()
body := `
{"stream":"Step 0 : FROM ubuntu:latest\n"}
{"stream":" ---\u003e 4300eb9d3c8d\n"}
@@ -891,6 +922,7 @@ func TestBuildImageWithRawJSON(t *testing.T) {
}
func TestBuildImageRemoteWithoutName(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "", status: http.StatusOK}
client := newTestClient(fakeRT)
var buf bytes.Buffer
@@ -912,6 +944,7 @@ func TestBuildImageRemoteWithoutName(t *testing.T) {
}
func TestTagImageParameters(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "", status: http.StatusOK}
client := newTestClient(fakeRT)
opts := TagImageOptions{Repo: "testImage"}
@@ -928,6 +961,7 @@ func TestTagImageParameters(t *testing.T) {
}
func TestTagImageMissingRepo(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "", status: http.StatusOK}
client := newTestClient(fakeRT)
opts := TagImageOptions{Repo: "testImage"}
@@ -939,6 +973,7 @@ func TestTagImageMissingRepo(t *testing.T) {
}
func TestIsUrl(t *testing.T) {
t.Parallel()
url := "http://foo.bar/"
result := isURL(url)
if !result {
@@ -952,6 +987,7 @@ func TestIsUrl(t *testing.T) {
}
func TestLoadImage(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "", status: http.StatusOK}
client := newTestClient(fakeRT)
tar, err := os.Open("testing/data/container.tar")
@@ -975,6 +1011,7 @@ func TestLoadImage(t *testing.T) {
}
func TestExportImage(t *testing.T) {
t.Parallel()
var buf bytes.Buffer
fakeRT := &FakeRoundTripper{message: "", status: http.StatusOK}
client := newTestClient(fakeRT)
@@ -994,6 +1031,7 @@ func TestExportImage(t *testing.T) {
}
func TestExportImages(t *testing.T) {
t.Parallel()
var buf bytes.Buffer
fakeRT := &FakeRoundTripper{message: "", status: http.StatusOK}
client := newTestClient(fakeRT)
@@ -1014,6 +1052,7 @@ func TestExportImages(t *testing.T) {
}
func TestExportImagesNoNames(t *testing.T) {
t.Parallel()
var buf bytes.Buffer
fakeRT := &FakeRoundTripper{message: "", status: http.StatusOK}
client := newTestClient(fakeRT)
@@ -1028,6 +1067,7 @@ func TestExportImagesNoNames(t *testing.T) {
}
func TestSearchImages(t *testing.T) {
t.Parallel()
body := `[
{
"description":"A container with Cassandra 2.0.3",
@@ -1068,6 +1108,7 @@ func TestSearchImages(t *testing.T) {
}
func TestSearchImagesEx(t *testing.T) {
t.Parallel()
body := `[
{
"description":"A container with Cassandra 2.0.3",
@@ -1109,6 +1150,7 @@ func TestSearchImagesEx(t *testing.T) {
}
func TestPruneImages(t *testing.T) {
t.Parallel()
results := `{
"ImagesDeleted": [
{"Deleted": "a"},

View File

@@ -19,6 +19,7 @@ type DockerVersion struct {
}
func TestVersion(t *testing.T) {
t.Parallel()
body := `{
"Version":"0.2.2",
"GitCommit":"5a2a5cc+CHANGES",
@@ -56,6 +57,7 @@ func TestVersion(t *testing.T) {
}
func TestVersionError(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "internal error", status: http.StatusInternalServerError}
client := newTestClient(fakeRT)
version, err := client.Version()
@@ -68,6 +70,7 @@ func TestVersionError(t *testing.T) {
}
func TestInfo(t *testing.T) {
t.Parallel()
body := `{
"Containers":11,
"Images":16,
@@ -133,6 +136,7 @@ func TestInfo(t *testing.T) {
}
func TestInfoError(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "internal error", status: http.StatusInternalServerError}
client := newTestClient(fakeRT)
version, err := client.Info()
@@ -145,6 +149,7 @@ func TestInfoError(t *testing.T) {
}
func TestParseRepositoryTag(t *testing.T) {
t.Parallel()
var tests = []struct {
input string
expectedRepo string

View File

@@ -14,6 +14,7 @@ import (
)
func TestListNetworks(t *testing.T) {
t.Parallel()
jsonNetworks := `[
{
"ID": "8dfafdbc3a40",
@@ -44,6 +45,7 @@ func TestListNetworks(t *testing.T) {
}
func TestFilteredListNetworks(t *testing.T) {
t.Parallel()
jsonNetworks := `[
{
"ID": "9fb1e39c",
@@ -77,6 +79,7 @@ func TestFilteredListNetworks(t *testing.T) {
}
func TestNetworkInfo(t *testing.T) {
t.Parallel()
jsonNetwork := `{
"ID": "8dfafdbc3a40",
"Name": "blah",
@@ -130,6 +133,7 @@ func TestNetworkCreate(t *testing.T) {
}
func TestNetworkRemove(t *testing.T) {
t.Parallel()
id := "8dfafdbc3a40"
fakeRT := &FakeRoundTripper{message: "", status: http.StatusNoContent}
client := newTestClient(fakeRT)
@@ -149,6 +153,7 @@ func TestNetworkRemove(t *testing.T) {
}
func TestNetworkConnect(t *testing.T) {
t.Parallel()
id := "8dfafdbc3a40"
fakeRT := &FakeRoundTripper{message: "", status: http.StatusNoContent}
client := newTestClient(fakeRT)
@@ -169,6 +174,7 @@ func TestNetworkConnect(t *testing.T) {
}
func TestNetworkConnectWithEndpoint(t *testing.T) {
t.Parallel()
wantJSON := `{"Container":"foobar","EndpointConfig":{"IPAMConfig":{"IPv4Address":"8.8.8.8"},"Links":null,"Aliases":null},"Force":false}`
var wantObj NetworkConnectionOptions
json.NewDecoder(bytes.NewBuffer([]byte(wantJSON))).Decode(&wantObj)
@@ -206,6 +212,7 @@ func TestNetworkConnectWithEndpoint(t *testing.T) {
}
func TestNetworkConnectNotFound(t *testing.T) {
t.Parallel()
client := newTestClient(&FakeRoundTripper{message: "no such network container", status: http.StatusNotFound})
opts := NetworkConnectionOptions{Container: "foobar"}
err := client.ConnectNetwork("8dfafdbc3a40", opts)
@@ -215,6 +222,7 @@ func TestNetworkConnectNotFound(t *testing.T) {
}
func TestNetworkDisconnect(t *testing.T) {
t.Parallel()
id := "8dfafdbc3a40"
fakeRT := &FakeRoundTripper{message: "", status: http.StatusNoContent}
client := newTestClient(fakeRT)
@@ -235,6 +243,7 @@ func TestNetworkDisconnect(t *testing.T) {
}
func TestNetworkDisconnectNotFound(t *testing.T) {
t.Parallel()
client := newTestClient(&FakeRoundTripper{message: "no such network container", status: http.StatusNotFound})
opts := NetworkConnectionOptions{Container: "foobar"}
err := client.DisconnectNetwork("8dfafdbc3a40", opts)
@@ -244,6 +253,7 @@ func TestNetworkDisconnectNotFound(t *testing.T) {
}
func TestPruneNetworks(t *testing.T) {
t.Parallel()
results := `{
"NetworksDeleted": [
"a", "b", "c"

View File

@@ -15,6 +15,7 @@ import (
)
func TestListNodes(t *testing.T) {
t.Parallel()
jsonNodes := `[
{
"ID": "24ifsmvkjbyhk",
@@ -93,6 +94,7 @@ func TestListNodes(t *testing.T) {
}
func TestInspectNode(t *testing.T) {
t.Parallel()
jsonNode := `{
"ID": "24ifsmvkjbyhk",
"Version": {
@@ -176,6 +178,7 @@ func TestInspectNode(t *testing.T) {
}
func TestInspectNodeNotFound(t *testing.T) {
t.Parallel()
client := newTestClient(&FakeRoundTripper{message: "no such node", status: http.StatusNotFound})
node, err := client.InspectNode("notfound")
if node != nil {
@@ -188,6 +191,7 @@ func TestInspectNodeNotFound(t *testing.T) {
}
func TestUpdateNode(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "", status: http.StatusOK}
client := newTestClient(fakeRT)
id := "4fa6e0f0c6786287e131c3852c58a2e01cc697a68231826813597e4994f1d6e2"
@@ -218,6 +222,7 @@ func TestUpdateNode(t *testing.T) {
}
func TestUpdateNodeNotFound(t *testing.T) {
t.Parallel()
client := newTestClient(&FakeRoundTripper{message: "no such node", status: http.StatusNotFound})
err := client.UpdateNode("notfound", UpdateNodeOptions{})
expected := &NoSuchNode{ID: "notfound"}
@@ -227,6 +232,7 @@ func TestUpdateNodeNotFound(t *testing.T) {
}
func TestRemoveNode(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "", status: http.StatusOK}
client := newTestClient(fakeRT)
id := "4fa6e0f0c6786287e131c3852c58a2e01cc697a68231826813597e4994f1d6e2"
@@ -245,6 +251,7 @@ func TestRemoveNode(t *testing.T) {
}
func TestRemoveNodeNotFound(t *testing.T) {
t.Parallel()
client := newTestClient(&FakeRoundTripper{message: "no such node", status: http.StatusNotFound})
err := client.RemoveNode(RemoveNodeOptions{ID: "notfound"})
expected := &NoSuchNode{ID: "notfound"}

View File

@@ -6,9 +6,11 @@ package docker
import (
"encoding/json"
"io"
"net/http"
"net/url"
"strconv"
"time"
"github.com/docker/docker/api/types/swarm"
"golang.org/x/net/context"
@@ -167,3 +169,48 @@ func (c *Client) ListServices(opts ListServicesOptions) ([]swarm.Service, error)
}
return services, nil
}
// LogsServiceOptions represents the set of options used when getting logs from a
// service.
type LogsServiceOptions struct {
Context context.Context
Service string `qs:"-"`
OutputStream io.Writer `qs:"-"`
ErrorStream io.Writer `qs:"-"`
InactivityTimeout time.Duration `qs:"-"`
Tail string
// Use raw terminal? Usually true when the container contains a TTY.
RawTerminal bool `qs:"-"`
Since int64
Follow bool
Stdout bool
Stderr bool
Timestamps bool
Details bool
}
// GetServiceLogs gets stdout and stderr logs from the specified service.
//
// When LogsServiceOptions.RawTerminal is set to false, go-dockerclient will multiplex
// the streams and send the containers stdout to LogsServiceOptions.OutputStream, and
// stderr to LogsServiceOptions.ErrorStream.
//
// When LogsServiceOptions.RawTerminal is true, callers will get the raw stream on
// LogsServiceOptions.OutputStream.
func (c *Client) GetServiceLogs(opts LogsServiceOptions) error {
if opts.Service == "" {
return &NoSuchService{ID: opts.Service}
}
if opts.Tail == "" {
opts.Tail = "all"
}
path := "/services/" + opts.Service + "/logs?" + queryString(opts)
return c.stream("GET", path, streamOptions{
setRawTerminal: opts.RawTerminal,
stdout: opts.OutputStream,
stderr: opts.ErrorStream,
inactivityTimeout: opts.InactivityTimeout,
context: opts.Context,
})
}

View File

@@ -5,18 +5,22 @@
package docker
import (
"bytes"
"encoding/json"
"net/http"
"net/http/httptest"
"net/url"
"reflect"
"testing"
"encoding/base64"
"github.com/docker/docker/api/types/swarm"
"strings"
"github.com/docker/docker/api/types/swarm"
)
func TestCreateService(t *testing.T) {
t.Parallel()
result := `{
"Id": "4fa6e0f0c6786287e131c3852c58a2e01cc697a68231826813597e4994f1d6e2"
}`
@@ -61,6 +65,7 @@ func TestCreateService(t *testing.T) {
}
func TestCreateServiceWithAuthentication(t *testing.T) {
t.Parallel()
result := `{
"Id": "4fa6e0f0c6786287e131c3852c58a2e01cc697a68231826813597e4994f1d6e2"
}`
@@ -115,6 +120,7 @@ func TestCreateServiceWithAuthentication(t *testing.T) {
}
func TestRemoveService(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "", status: http.StatusOK}
client := newTestClient(fakeRT)
id := "4fa6e0f0c6786287e131c3852c58a2e01cc697a68231826813597e4994f1d6e2"
@@ -134,6 +140,7 @@ func TestRemoveService(t *testing.T) {
}
func TestRemoveServiceNotFound(t *testing.T) {
t.Parallel()
client := newTestClient(&FakeRoundTripper{message: "no such service", status: http.StatusNotFound})
err := client.RemoveService(RemoveServiceOptions{ID: "a2334"})
expected := &NoSuchService{ID: "a2334"}
@@ -143,6 +150,7 @@ func TestRemoveServiceNotFound(t *testing.T) {
}
func TestUpdateService(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "", status: http.StatusOK}
client := newTestClient(fakeRT)
id := "4fa6e0f0c6786287e131c3852c58a2e01cc697a68231826813597e4994f1d6e2"
@@ -174,6 +182,7 @@ func TestUpdateService(t *testing.T) {
}
func TestUpdateServiceWithAuthentication(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "", status: http.StatusOK}
client := newTestClient(fakeRT)
id := "4fa6e0f0c6786287e131c3852c58a2e01cc697a68231826813597e4994f1d6e2"
@@ -222,6 +231,7 @@ func TestUpdateServiceWithAuthentication(t *testing.T) {
}
func TestUpdateServiceNotFound(t *testing.T) {
t.Parallel()
client := newTestClient(&FakeRoundTripper{message: "no such service", status: http.StatusNotFound})
update := UpdateServiceOptions{}
err := client.UpdateService("notfound", update)
@@ -232,6 +242,7 @@ func TestUpdateServiceNotFound(t *testing.T) {
}
func TestInspectServiceNotFound(t *testing.T) {
t.Parallel()
client := newTestClient(&FakeRoundTripper{message: "no such service", status: http.StatusNotFound})
service, err := client.InspectService("notfound")
if service != nil {
@@ -244,6 +255,7 @@ func TestInspectServiceNotFound(t *testing.T) {
}
func TestInspectService(t *testing.T) {
t.Parallel()
jsonService := `{
"ID": "ak7w3gjqoa3kuz8xcpnyy0pvl",
"Version": {
@@ -324,6 +336,7 @@ func TestInspectService(t *testing.T) {
}
func TestListServices(t *testing.T) {
t.Parallel()
jsonServices := `[
{
"ID": "9mnpnzenvg8p8tdbtq4wvbkcz",
@@ -402,3 +415,183 @@ func TestListServices(t *testing.T) {
t.Errorf("ListServices: Expected %#v. Got %#v.", expected, services)
}
}
/// ##################################################""
func TestGetServiceLogs(t *testing.T) {
var req http.Request
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
prefix := []byte{1, 0, 0, 0, 0, 0, 0, 19}
w.Write(prefix)
w.Write([]byte("something happened!"))
req = *r
}))
defer server.Close()
client, _ := NewClient(server.URL)
client.SkipServerVersionCheck = true
var buf bytes.Buffer
opts := LogsServiceOptions{
Service: "a123456",
OutputStream: &buf,
Follow: true,
Stdout: true,
Stderr: true,
Timestamps: true,
}
err := client.GetServiceLogs(opts)
if err != nil {
t.Fatal(err)
}
expected := "something happened!"
if buf.String() != expected {
t.Errorf("Logs: wrong output. Want %q. Got %q.", expected, buf.String())
}
if req.Method != "GET" {
t.Errorf("Logs: wrong HTTP method. Want GET. Got %s.", req.Method)
}
u, _ := url.Parse(client.getURL("/services/a123456/logs"))
if req.URL.Path != u.Path {
t.Errorf("AttachToContainer for logs: wrong HTTP path. Want %q. Got %q.", u.Path, req.URL.Path)
}
expectedQs := map[string][]string{
"follow": {"1"},
"stdout": {"1"},
"stderr": {"1"},
"timestamps": {"1"},
"tail": {"all"},
}
got := map[string][]string(req.URL.Query())
if !reflect.DeepEqual(got, expectedQs) {
t.Errorf("Logs: wrong query string. Want %#v. Got %#v.", expectedQs, got)
}
}
func TesGetServicetLogsNilStdoutDoesntFail(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
prefix := []byte{1, 0, 0, 0, 0, 0, 0, 19}
w.Write(prefix)
w.Write([]byte("something happened!"))
}))
defer server.Close()
client, _ := NewClient(server.URL)
client.SkipServerVersionCheck = true
opts := LogsServiceOptions{
Service: "a123456",
Follow: true,
Stdout: true,
Stderr: true,
Timestamps: true,
}
err := client.GetServiceLogs(opts)
if err != nil {
t.Fatal(err)
}
}
func TestGetServiceLogsNilStderrDoesntFail(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
prefix := []byte{2, 0, 0, 0, 0, 0, 0, 19}
w.Write(prefix)
w.Write([]byte("something happened!"))
}))
defer server.Close()
client, _ := NewClient(server.URL)
client.SkipServerVersionCheck = true
opts := LogsServiceOptions{
Service: "a123456",
Follow: true,
Stdout: true,
Stderr: true,
Timestamps: true,
}
err := client.GetServiceLogs(opts)
if err != nil {
t.Fatal(err)
}
}
func TestGetServiceLogsSpecifyingTail(t *testing.T) {
var req http.Request
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
prefix := []byte{1, 0, 0, 0, 0, 0, 0, 19}
w.Write(prefix)
w.Write([]byte("something happened!"))
req = *r
}))
defer server.Close()
client, _ := NewClient(server.URL)
client.SkipServerVersionCheck = true
var buf bytes.Buffer
opts := LogsServiceOptions{
Service: "a123456",
OutputStream: &buf,
Follow: true,
Stdout: true,
Stderr: true,
Timestamps: true,
Tail: "100",
}
err := client.GetServiceLogs(opts)
if err != nil {
t.Fatal(err)
}
expected := "something happened!"
if buf.String() != expected {
t.Errorf("Logs: wrong output. Want %q. Got %q.", expected, buf.String())
}
if req.Method != "GET" {
t.Errorf("Logs: wrong HTTP method. Want GET. Got %s.", req.Method)
}
u, _ := url.Parse(client.getURL("/services/a123456/logs"))
if req.URL.Path != u.Path {
t.Errorf("AttachToContainer for logs: wrong HTTP path. Want %q. Got %q.", u.Path, req.URL.Path)
}
expectedQs := map[string][]string{
"follow": {"1"},
"stdout": {"1"},
"stderr": {"1"},
"timestamps": {"1"},
"tail": {"100"},
}
got := map[string][]string(req.URL.Query())
if !reflect.DeepEqual(got, expectedQs) {
t.Errorf("Logs: wrong query string. Want %#v. Got %#v.", expectedQs, got)
}
}
func TestGetServiceLogsRawTerminal(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("something happened!"))
}))
defer server.Close()
client, _ := NewClient(server.URL)
client.SkipServerVersionCheck = true
var buf bytes.Buffer
opts := LogsServiceOptions{
Service: "a123456",
OutputStream: &buf,
Follow: true,
RawTerminal: true,
Stdout: true,
Stderr: true,
Timestamps: true,
Tail: "100",
}
err := client.GetServiceLogs(opts)
if err != nil {
t.Fatal(err)
}
expected := "something happened!"
if buf.String() != expected {
t.Errorf("Logs: wrong output. Want %q. Got %q.", expected, buf.String())
}
}
func TestGetServiceLogsNoContainer(t *testing.T) {
var client Client
err := client.GetServiceLogs(LogsServiceOptions{})
expected := &NoSuchService{ID: ""}
if !reflect.DeepEqual(err, expected) {
t.Errorf("AttachToContainer: wrong error. Want %#v. Got %#v.", expected, err)
}
}

View File

@@ -14,6 +14,7 @@ import (
)
func TestInitSwarm(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: `"body"`, status: http.StatusOK}
client := newTestClient(fakeRT)
response, err := client.InitSwarm(InitSwarmOptions{})
@@ -36,6 +37,7 @@ func TestInitSwarm(t *testing.T) {
}
func TestInitSwarmAlreadyInSwarm(t *testing.T) {
t.Parallel()
client := newTestClient(&FakeRoundTripper{message: "", status: http.StatusNotAcceptable})
_, err := client.InitSwarm(InitSwarmOptions{})
if err != ErrNodeAlreadyInSwarm {
@@ -49,6 +51,7 @@ func TestInitSwarmAlreadyInSwarm(t *testing.T) {
}
func TestJoinSwarm(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "", status: http.StatusOK}
client := newTestClient(fakeRT)
err := client.JoinSwarm(JoinSwarmOptions{})
@@ -67,6 +70,7 @@ func TestJoinSwarm(t *testing.T) {
}
func TestJoinSwarmAlreadyInSwarm(t *testing.T) {
t.Parallel()
client := newTestClient(&FakeRoundTripper{message: "", status: http.StatusNotAcceptable})
err := client.JoinSwarm(JoinSwarmOptions{})
if err != ErrNodeAlreadyInSwarm {
@@ -80,6 +84,7 @@ func TestJoinSwarmAlreadyInSwarm(t *testing.T) {
}
func TestLeaveSwarm(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "", status: http.StatusOK}
client := newTestClient(fakeRT)
var testData = []struct {
@@ -107,6 +112,7 @@ func TestLeaveSwarm(t *testing.T) {
}
func TestLeaveSwarmNotInSwarm(t *testing.T) {
t.Parallel()
client := newTestClient(&FakeRoundTripper{message: "", status: http.StatusNotAcceptable})
err := client.LeaveSwarm(LeaveSwarmOptions{})
if err != ErrNodeNotInSwarm {
@@ -120,6 +126,7 @@ func TestLeaveSwarmNotInSwarm(t *testing.T) {
}
func TestUpdateSwarm(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "", status: http.StatusOK}
client := newTestClient(fakeRT)
opts := UpdateSwarmOptions{
@@ -152,6 +159,7 @@ func TestUpdateSwarm(t *testing.T) {
}
func TestUpdateSwarmNotInSwarm(t *testing.T) {
t.Parallel()
client := newTestClient(&FakeRoundTripper{message: "", status: http.StatusNotAcceptable})
err := client.UpdateSwarm(UpdateSwarmOptions{})
if err != ErrNodeNotInSwarm {
@@ -165,6 +173,7 @@ func TestUpdateSwarmNotInSwarm(t *testing.T) {
}
func TestInspectSwarm(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: `{"ID": "123"}`, status: http.StatusOK}
client := newTestClient(fakeRT)
response, err := client.InspectSwarm(nil)
@@ -187,6 +196,7 @@ func TestInspectSwarm(t *testing.T) {
}
func TestInspectSwarmNotInSwarm(t *testing.T) {
t.Parallel()
client := newTestClient(&FakeRoundTripper{message: "", status: http.StatusNotAcceptable})
_, err := client.InspectSwarm(nil)
if err != ErrNodeNotInSwarm {

View File

@@ -15,6 +15,7 @@ import (
)
func TestListTasks(t *testing.T) {
t.Parallel()
jsonTasks := `[
{
"ID": "0kzzo1i0y4jz6027t0k7aezc7",
@@ -236,6 +237,7 @@ func TestListTasks(t *testing.T) {
}
func TestInspectTask(t *testing.T) {
t.Parallel()
jsonTask := `{
"ID": "0kzzo1i0y4jz6027t0k7aezc7",
"Version": {
@@ -361,6 +363,7 @@ func TestInspectTask(t *testing.T) {
}
func TestInspectTaskNotFound(t *testing.T) {
t.Parallel()
client := newTestClient(&FakeRoundTripper{message: "no such task", status: http.StatusNotFound})
task, err := client.InspectTask("notfound")
if task != nil {

View File

@@ -1411,7 +1411,7 @@ func (s *DockerServer) removeVolume(w http.ResponseWriter, r *http.Request) {
http.Error(w, "volume in use and cannot be removed", http.StatusConflict)
return
}
s.volStore[vol.volume.Name] = nil
delete(s.volStore, vol.volume.Name)
w.WriteHeader(http.StatusNoContent)
}

View File

@@ -27,6 +27,7 @@ import (
)
func TestNewServer(t *testing.T) {
t.Parallel()
server, err := NewServer("127.0.0.1:0", nil, nil)
if err != nil {
t.Fatal(err)
@@ -40,6 +41,7 @@ func TestNewServer(t *testing.T) {
}
func TestNewTLSServer(t *testing.T) {
t.Parallel()
tlsConfig := TLSConfig{
CertPath: "./data/server.pem",
CertKeyPath: "./data/serverkey.pem",
@@ -66,6 +68,7 @@ func TestNewTLSServer(t *testing.T) {
}
func TestServerStop(t *testing.T) {
t.Parallel()
const retries = 3
server, err := NewServer("127.0.0.1:0", nil, nil)
if err != nil {
@@ -83,11 +86,13 @@ func TestServerStop(t *testing.T) {
}
func TestServerStopNoListener(t *testing.T) {
t.Parallel()
server := DockerServer{}
server.Stop()
}
func TestServerURL(t *testing.T) {
t.Parallel()
server, err := NewServer("127.0.0.1:0", nil, nil)
if err != nil {
t.Fatal(err)
@@ -100,6 +105,7 @@ func TestServerURL(t *testing.T) {
}
func TestServerURLNoListener(t *testing.T) {
t.Parallel()
server := DockerServer{}
url := server.URL()
if url != "" {
@@ -108,6 +114,7 @@ func TestServerURLNoListener(t *testing.T) {
}
func TestHandleWithHook(t *testing.T) {
t.Parallel()
var called bool
server, _ := NewServer("127.0.0.1:0", nil, func(*http.Request) { called = true })
defer server.Stop()
@@ -120,6 +127,7 @@ func TestHandleWithHook(t *testing.T) {
}
func TestSetHook(t *testing.T) {
t.Parallel()
var called bool
server, _ := NewServer("127.0.0.1:0", nil, nil)
defer server.Stop()
@@ -133,6 +141,7 @@ func TestSetHook(t *testing.T) {
}
func TestCustomHandler(t *testing.T) {
t.Parallel()
var called bool
server, _ := NewServer("127.0.0.1:0", nil, nil)
defer server.Stop()
@@ -153,6 +162,7 @@ func TestCustomHandler(t *testing.T) {
}
func TestCustomHandlerRegexp(t *testing.T) {
t.Parallel()
var called bool
server, _ := NewServer("127.0.0.1:0", nil, nil)
defer server.Stop()
@@ -173,6 +183,7 @@ func TestCustomHandlerRegexp(t *testing.T) {
}
func TestListContainers(t *testing.T) {
t.Parallel()
server := DockerServer{}
addContainers(&server, 2)
server.buildMuxer()
@@ -206,6 +217,7 @@ func TestListContainers(t *testing.T) {
}
func TestListRunningContainers(t *testing.T) {
t.Parallel()
server := DockerServer{}
addContainers(&server, 2)
server.buildMuxer()
@@ -226,6 +238,7 @@ func TestListRunningContainers(t *testing.T) {
}
func TestCreateContainer(t *testing.T) {
t.Parallel()
server := DockerServer{}
server.imgIDs = map[string]string{"base": "a1234"}
server.uploadedFiles = map[string]string{"a1234": "/abcd"}
@@ -271,6 +284,7 @@ func TestCreateContainer(t *testing.T) {
}
func TestCreateContainerWithNotifyChannel(t *testing.T) {
t.Parallel()
ch := make(chan *docker.Container, 1)
server := DockerServer{}
server.imgIDs = map[string]string{"base": "a1234"}
@@ -290,6 +304,7 @@ func TestCreateContainerWithNotifyChannel(t *testing.T) {
}
func TestCreateContainerInvalidBody(t *testing.T) {
t.Parallel()
server := DockerServer{}
server.buildMuxer()
recorder := httptest.NewRecorder()
@@ -301,6 +316,7 @@ func TestCreateContainerInvalidBody(t *testing.T) {
}
func TestCreateContainerDuplicateName(t *testing.T) {
t.Parallel()
server := DockerServer{}
server.buildMuxer()
server.imgIDs = map[string]string{"base": "a1234"}
@@ -317,6 +333,7 @@ func TestCreateContainerDuplicateName(t *testing.T) {
}
func TestCreateMultipleContainersEmptyName(t *testing.T) {
t.Parallel()
server := DockerServer{}
server.buildMuxer()
server.imgIDs = map[string]string{"base": "a1234"}
@@ -352,6 +369,7 @@ func TestCreateMultipleContainersEmptyName(t *testing.T) {
}
func TestCreateContainerInvalidName(t *testing.T) {
t.Parallel()
server := DockerServer{}
server.buildMuxer()
recorder := httptest.NewRecorder()
@@ -370,6 +388,7 @@ func TestCreateContainerInvalidName(t *testing.T) {
}
func TestCreateContainerImageNotFound(t *testing.T) {
t.Parallel()
server := DockerServer{}
server.buildMuxer()
recorder := httptest.NewRecorder()
@@ -384,6 +403,7 @@ func TestCreateContainerImageNotFound(t *testing.T) {
}
func TestRenameContainer(t *testing.T) {
t.Parallel()
server := DockerServer{}
addContainers(&server, 2)
server.buildMuxer()
@@ -402,6 +422,7 @@ func TestRenameContainer(t *testing.T) {
}
func TestRenameContainerNotFound(t *testing.T) {
t.Parallel()
server := DockerServer{}
server.buildMuxer()
recorder := httptest.NewRecorder()
@@ -413,6 +434,7 @@ func TestRenameContainerNotFound(t *testing.T) {
}
func TestCommitContainer(t *testing.T) {
t.Parallel()
server := DockerServer{}
addContainers(&server, 2)
server.uploadedFiles = map[string]string{server.containers[0].ID: "/abcd"}
@@ -438,6 +460,7 @@ func TestCommitContainer(t *testing.T) {
}
func TestCommitContainerComplete(t *testing.T) {
t.Parallel()
server := DockerServer{}
server.imgIDs = make(map[string]string)
addContainers(&server, 2)
@@ -476,6 +499,7 @@ func TestCommitContainerComplete(t *testing.T) {
}
func TestCommitContainerWithTag(t *testing.T) {
t.Parallel()
server := DockerServer{}
server.imgIDs = make(map[string]string)
addContainers(&server, 2)
@@ -497,6 +521,7 @@ func TestCommitContainerWithTag(t *testing.T) {
}
func TestCommitContainerInvalidRun(t *testing.T) {
t.Parallel()
server := DockerServer{}
addContainers(&server, 1)
server.buildMuxer()
@@ -509,6 +534,7 @@ func TestCommitContainerInvalidRun(t *testing.T) {
}
func TestCommitContainerNotFound(t *testing.T) {
t.Parallel()
server := DockerServer{}
server.buildMuxer()
recorder := httptest.NewRecorder()
@@ -520,6 +546,7 @@ func TestCommitContainerNotFound(t *testing.T) {
}
func TestInspectContainer(t *testing.T) {
t.Parallel()
server := DockerServer{}
addContainers(&server, 2)
server.buildMuxer()
@@ -553,6 +580,7 @@ func TestInspectContainer(t *testing.T) {
}
func TestInspectContainerNotFound(t *testing.T) {
t.Parallel()
server := DockerServer{}
server.buildMuxer()
recorder := httptest.NewRecorder()
@@ -564,6 +592,7 @@ func TestInspectContainerNotFound(t *testing.T) {
}
func TestTopContainer(t *testing.T) {
t.Parallel()
server := DockerServer{}
addContainers(&server, 1)
server.containers[0].State.Running = true
@@ -592,6 +621,7 @@ func TestTopContainer(t *testing.T) {
}
func TestTopContainerNotFound(t *testing.T) {
t.Parallel()
server := DockerServer{}
server.buildMuxer()
recorder := httptest.NewRecorder()
@@ -603,6 +633,7 @@ func TestTopContainerNotFound(t *testing.T) {
}
func TestTopContainerStopped(t *testing.T) {
t.Parallel()
server := DockerServer{}
addContainers(&server, 1)
server.buildMuxer()
@@ -616,6 +647,7 @@ func TestTopContainerStopped(t *testing.T) {
}
func TestStartContainer(t *testing.T) {
t.Parallel()
server := DockerServer{}
addContainers(&server, 1)
server.buildMuxer()
@@ -644,6 +676,7 @@ func TestStartContainer(t *testing.T) {
}
func TestStartContainerNoHostConfig(t *testing.T) {
t.Parallel()
server := DockerServer{}
addContainers(&server, 1)
server.buildMuxer()
@@ -666,6 +699,7 @@ func TestStartContainerNoHostConfig(t *testing.T) {
}
func TestStartContainerChangeNetwork(t *testing.T) {
t.Parallel()
server := DockerServer{}
addContainers(&server, 1)
server.buildMuxer()
@@ -696,6 +730,7 @@ func TestStartContainerChangeNetwork(t *testing.T) {
}
func TestStartContainerWithNotifyChannel(t *testing.T) {
t.Parallel()
ch := make(chan *docker.Container, 1)
server := DockerServer{}
server.cChan = ch
@@ -715,6 +750,7 @@ func TestStartContainerWithNotifyChannel(t *testing.T) {
}
func TestStartContainerNotFound(t *testing.T) {
t.Parallel()
server := DockerServer{}
server.buildMuxer()
recorder := httptest.NewRecorder()
@@ -727,6 +763,7 @@ func TestStartContainerNotFound(t *testing.T) {
}
func TestStartContainerAlreadyRunning(t *testing.T) {
t.Parallel()
server := DockerServer{}
addContainers(&server, 1)
server.containers[0].State.Running = true
@@ -741,6 +778,7 @@ func TestStartContainerAlreadyRunning(t *testing.T) {
}
func TestStopContainer(t *testing.T) {
t.Parallel()
server := DockerServer{}
addContainers(&server, 1)
server.containers[0].State.Running = true
@@ -758,6 +796,7 @@ func TestStopContainer(t *testing.T) {
}
func TestKillContainer(t *testing.T) {
t.Parallel()
server := DockerServer{}
addContainers(&server, 1)
server.containers[0].State.Running = true
@@ -775,6 +814,7 @@ func TestKillContainer(t *testing.T) {
}
func TestStopContainerWithNotifyChannel(t *testing.T) {
t.Parallel()
ch := make(chan *docker.Container, 1)
server := DockerServer{}
server.cChan = ch
@@ -795,6 +835,7 @@ func TestStopContainerWithNotifyChannel(t *testing.T) {
}
func TestStopContainerNotFound(t *testing.T) {
t.Parallel()
server := DockerServer{}
server.buildMuxer()
recorder := httptest.NewRecorder()
@@ -807,6 +848,7 @@ func TestStopContainerNotFound(t *testing.T) {
}
func TestStopContainerNotRunning(t *testing.T) {
t.Parallel()
server := DockerServer{}
addContainers(&server, 1)
server.buildMuxer()
@@ -820,6 +862,7 @@ func TestStopContainerNotRunning(t *testing.T) {
}
func TestPauseContainer(t *testing.T) {
t.Parallel()
server := DockerServer{}
addContainers(&server, 1)
server.buildMuxer()
@@ -836,6 +879,7 @@ func TestPauseContainer(t *testing.T) {
}
func TestPauseContainerAlreadyPaused(t *testing.T) {
t.Parallel()
server := DockerServer{}
addContainers(&server, 1)
server.containers[0].State.Paused = true
@@ -850,6 +894,7 @@ func TestPauseContainerAlreadyPaused(t *testing.T) {
}
func TestPauseContainerNotFound(t *testing.T) {
t.Parallel()
server := DockerServer{}
server.buildMuxer()
recorder := httptest.NewRecorder()
@@ -862,6 +907,7 @@ func TestPauseContainerNotFound(t *testing.T) {
}
func TestUnpauseContainer(t *testing.T) {
t.Parallel()
server := DockerServer{}
addContainers(&server, 1)
server.containers[0].State.Paused = true
@@ -879,6 +925,7 @@ func TestUnpauseContainer(t *testing.T) {
}
func TestUnpauseContainerNotPaused(t *testing.T) {
t.Parallel()
server := DockerServer{}
addContainers(&server, 1)
server.buildMuxer()
@@ -892,6 +939,7 @@ func TestUnpauseContainerNotPaused(t *testing.T) {
}
func TestUnpauseContainerNotFound(t *testing.T) {
t.Parallel()
server := DockerServer{}
server.buildMuxer()
recorder := httptest.NewRecorder()
@@ -904,6 +952,7 @@ func TestUnpauseContainerNotFound(t *testing.T) {
}
func TestWaitContainer(t *testing.T) {
t.Parallel()
server := DockerServer{}
addContainers(&server, 1)
server.containers[0].State.Running = true
@@ -927,6 +976,7 @@ func TestWaitContainer(t *testing.T) {
}
func TestWaitContainerStatus(t *testing.T) {
t.Parallel()
server := DockerServer{}
addContainers(&server, 1)
server.buildMuxer()
@@ -945,6 +995,7 @@ func TestWaitContainerStatus(t *testing.T) {
}
func TestWaitContainerNotFound(t *testing.T) {
t.Parallel()
server := DockerServer{}
server.buildMuxer()
recorder := httptest.NewRecorder()
@@ -976,6 +1027,7 @@ func (r *HijackableResponseRecorder) HijackBuffer() string {
}
func TestLogContainer(t *testing.T) {
t.Parallel()
server := DockerServer{}
addContainers(&server, 1)
server.containers[0].State.Running = true
@@ -990,6 +1042,7 @@ func TestLogContainer(t *testing.T) {
}
func TestLogContainerNotFound(t *testing.T) {
t.Parallel()
server := DockerServer{}
server.buildMuxer()
recorder := httptest.NewRecorder()
@@ -1002,6 +1055,7 @@ func TestLogContainerNotFound(t *testing.T) {
}
func TestAttachContainer(t *testing.T) {
t.Parallel()
server := DockerServer{}
addContainers(&server, 1)
server.containers[0].State.Running = true
@@ -1022,6 +1076,7 @@ func TestAttachContainer(t *testing.T) {
}
func TestAttachContainerNotFound(t *testing.T) {
t.Parallel()
server := DockerServer{}
server.buildMuxer()
recorder := &HijackableResponseRecorder{}
@@ -1034,6 +1089,7 @@ func TestAttachContainerNotFound(t *testing.T) {
}
func TestAttachContainerWithStreamBlocks(t *testing.T) {
t.Parallel()
server := DockerServer{}
addContainers(&server, 1)
server.containers[0].State.Running = true
@@ -1072,6 +1128,7 @@ func TestAttachContainerWithStreamBlocks(t *testing.T) {
}
func TestAttachContainerWithStreamBlocksOnCreatedContainers(t *testing.T) {
t.Parallel()
server := DockerServer{}
addContainers(&server, 1)
server.containers[0].State.Running = false
@@ -1111,6 +1168,7 @@ func TestAttachContainerWithStreamBlocksOnCreatedContainers(t *testing.T) {
}
func TestRemoveContainer(t *testing.T) {
t.Parallel()
server := DockerServer{}
addContainers(&server, 1)
server.buildMuxer()
@@ -1127,6 +1185,7 @@ func TestRemoveContainer(t *testing.T) {
}
func TestRemoveContainerByName(t *testing.T) {
t.Parallel()
server := DockerServer{}
addContainers(&server, 1)
server.buildMuxer()
@@ -1143,6 +1202,7 @@ func TestRemoveContainerByName(t *testing.T) {
}
func TestRemoveContainerNotFound(t *testing.T) {
t.Parallel()
server := DockerServer{}
server.buildMuxer()
recorder := httptest.NewRecorder()
@@ -1155,6 +1215,7 @@ func TestRemoveContainerNotFound(t *testing.T) {
}
func TestRemoveContainerRunning(t *testing.T) {
t.Parallel()
server := DockerServer{}
addContainers(&server, 1)
server.containers[0].State.Running = true
@@ -1172,6 +1233,7 @@ func TestRemoveContainerRunning(t *testing.T) {
}
func TestRemoveContainerRunningForce(t *testing.T) {
t.Parallel()
server := DockerServer{}
addContainers(&server, 1)
server.containers[0].State.Running = true
@@ -1189,6 +1251,7 @@ func TestRemoveContainerRunningForce(t *testing.T) {
}
func TestPullImage(t *testing.T) {
t.Parallel()
server := DockerServer{imgIDs: make(map[string]string)}
server.buildMuxer()
recorder := httptest.NewRecorder()
@@ -1209,6 +1272,7 @@ func TestPullImage(t *testing.T) {
}
func TestPullImageWithTag(t *testing.T) {
t.Parallel()
server := DockerServer{imgIDs: make(map[string]string)}
server.buildMuxer()
recorder := httptest.NewRecorder()
@@ -1226,6 +1290,7 @@ func TestPullImageWithTag(t *testing.T) {
}
func TestPullImageWithShaTag(t *testing.T) {
t.Parallel()
server := DockerServer{imgIDs: make(map[string]string)}
server.buildMuxer()
recorder := httptest.NewRecorder()
@@ -1243,6 +1308,7 @@ func TestPullImageWithShaTag(t *testing.T) {
}
func TestPushImage(t *testing.T) {
t.Parallel()
server := DockerServer{imgIDs: map[string]string{"tsuru/python": "a123"}}
server.buildMuxer()
recorder := httptest.NewRecorder()
@@ -1254,6 +1320,7 @@ func TestPushImage(t *testing.T) {
}
func TestPushImageWithTag(t *testing.T) {
t.Parallel()
server := DockerServer{imgIDs: map[string]string{"tsuru/python:v1": "a123"}}
server.buildMuxer()
recorder := httptest.NewRecorder()
@@ -1265,6 +1332,7 @@ func TestPushImageWithTag(t *testing.T) {
}
func TestPushImageNotFound(t *testing.T) {
t.Parallel()
server := DockerServer{}
server.buildMuxer()
recorder := httptest.NewRecorder()
@@ -1276,6 +1344,7 @@ func TestPushImageNotFound(t *testing.T) {
}
func TestTagImage(t *testing.T) {
t.Parallel()
server := DockerServer{imgIDs: map[string]string{"tsuru/python": "a123"}}
server.buildMuxer()
recorder := httptest.NewRecorder()
@@ -1290,6 +1359,7 @@ func TestTagImage(t *testing.T) {
}
func TestTagImageWithRepoAndTag(t *testing.T) {
t.Parallel()
server := DockerServer{imgIDs: map[string]string{"tsuru/python": "a123"}}
server.buildMuxer()
recorder := httptest.NewRecorder()
@@ -1304,6 +1374,7 @@ func TestTagImageWithRepoAndTag(t *testing.T) {
}
func TestTagImageNotFound(t *testing.T) {
t.Parallel()
server := DockerServer{}
server.buildMuxer()
recorder := httptest.NewRecorder()
@@ -1381,6 +1452,7 @@ func addImages(server *DockerServer, n int, repo bool) {
}
func TestListImages(t *testing.T) {
t.Parallel()
server := DockerServer{}
addImages(&server, 2, true)
server.buildMuxer()
@@ -1409,6 +1481,7 @@ func TestListImages(t *testing.T) {
}
func TestRemoveImage(t *testing.T) {
t.Parallel()
server := DockerServer{}
addImages(&server, 1, false)
server.buildMuxer()
@@ -1425,6 +1498,7 @@ func TestRemoveImage(t *testing.T) {
}
func TestRemoveImageByName(t *testing.T) {
t.Parallel()
server := DockerServer{}
addImages(&server, 1, true)
server.buildMuxer()
@@ -1446,6 +1520,7 @@ func TestRemoveImageByName(t *testing.T) {
}
func TestRemoveImageWithMultipleTags(t *testing.T) {
t.Parallel()
server := DockerServer{}
addImages(&server, 1, true)
server.buildMuxer()
@@ -1476,6 +1551,7 @@ func TestRemoveImageWithMultipleTags(t *testing.T) {
}
func TestPrepareFailure(t *testing.T) {
t.Parallel()
server := DockerServer{failures: make(map[string]string)}
server.buildMuxer()
errorID := "my_error"
@@ -1492,6 +1568,7 @@ func TestPrepareFailure(t *testing.T) {
}
func TestPrepareMultiFailures(t *testing.T) {
t.Parallel()
server := DockerServer{multiFailures: []map[string]string{}}
server.buildMuxer()
errorID := "multi error"
@@ -1527,6 +1604,7 @@ func TestPrepareMultiFailures(t *testing.T) {
}
func TestRemoveFailure(t *testing.T) {
t.Parallel()
server := DockerServer{failures: make(map[string]string)}
server.buildMuxer()
errorID := "my_error"
@@ -1547,6 +1625,7 @@ func TestRemoveFailure(t *testing.T) {
}
func TestResetMultiFailures(t *testing.T) {
t.Parallel()
server := DockerServer{multiFailures: []map[string]string{}}
server.buildMuxer()
errorID := "multi error"
@@ -1562,6 +1641,7 @@ func TestResetMultiFailures(t *testing.T) {
}
func TestMutateContainer(t *testing.T) {
t.Parallel()
server := DockerServer{failures: make(map[string]string)}
server.buildMuxer()
server.containers = append(server.containers, &docker.Container{ID: "id123"})
@@ -1577,6 +1657,7 @@ func TestMutateContainer(t *testing.T) {
}
func TestMutateContainerNotFound(t *testing.T) {
t.Parallel()
server := DockerServer{failures: make(map[string]string)}
server.buildMuxer()
state := docker.State{Running: false, ExitCode: 1}
@@ -1590,6 +1671,7 @@ func TestMutateContainerNotFound(t *testing.T) {
}
func TestBuildImageWithContentTypeTar(t *testing.T) {
t.Parallel()
server := DockerServer{imgIDs: make(map[string]string)}
imageName := "teste"
recorder := httptest.NewRecorder()
@@ -1611,6 +1693,7 @@ func TestBuildImageWithContentTypeTar(t *testing.T) {
}
func TestBuildImageWithRemoteDockerfile(t *testing.T) {
t.Parallel()
server := DockerServer{imgIDs: make(map[string]string)}
imageName := "teste"
recorder := httptest.NewRecorder()
@@ -1622,6 +1705,7 @@ func TestBuildImageWithRemoteDockerfile(t *testing.T) {
}
func TestPing(t *testing.T) {
t.Parallel()
server := DockerServer{}
recorder := httptest.NewRecorder()
request, _ := http.NewRequest("GET", "/_ping", nil)
@@ -1635,6 +1719,7 @@ func TestPing(t *testing.T) {
}
func TestDefaultHandler(t *testing.T) {
t.Parallel()
server, err := NewServer("127.0.0.1:0", nil, nil)
if err != nil {
t.Fatal(err)
@@ -1646,6 +1731,7 @@ func TestDefaultHandler(t *testing.T) {
}
func TestCreateExecContainer(t *testing.T) {
t.Parallel()
server := DockerServer{}
addContainers(&server, 2)
server.buildMuxer()
@@ -1682,6 +1768,7 @@ func TestCreateExecContainer(t *testing.T) {
}
func TestInspectExecContainer(t *testing.T) {
t.Parallel()
server := DockerServer{}
addContainers(&server, 1)
server.buildMuxer()
@@ -1724,6 +1811,7 @@ func TestInspectExecContainer(t *testing.T) {
}
func TestStartExecContainer(t *testing.T) {
t.Parallel()
server, _ := NewServer("127.0.0.1:0", nil, nil)
defer server.Stop()
addContainers(server, 1)
@@ -1778,6 +1866,7 @@ func TestStartExecContainer(t *testing.T) {
}
func TestStartExecContainerWildcardCallback(t *testing.T) {
t.Parallel()
server, _ := NewServer("127.0.0.1:0", nil, nil)
defer server.Stop()
addContainers(server, 1)
@@ -1832,6 +1921,7 @@ func TestStartExecContainerWildcardCallback(t *testing.T) {
}
func TestStartExecContainerNotFound(t *testing.T) {
t.Parallel()
server, _ := NewServer("127.0.0.1:0", nil, nil)
defer server.Stop()
addContainers(server, 1)
@@ -1856,6 +1946,7 @@ func waitExec(url, execID string, running bool, maxTry int) (*docker.ExecInspect
}
func TestStatsContainer(t *testing.T) {
t.Parallel()
server, err := NewServer("127.0.0.1:0", nil, nil)
if err != nil {
t.Fatal(err)
@@ -1882,6 +1973,7 @@ func TestStatsContainer(t *testing.T) {
t.Fatal(err)
}
got.Read = time.Time{}
got.PreRead = time.Time{}
if !reflect.DeepEqual(got, expected) {
t.Errorf("StatsContainer: wrong value. Want %#v. Got %#v.", expected, got)
}
@@ -1899,6 +1991,7 @@ func (w *safeWriter) Write(buf []byte) (int, error) {
}
func TestStatsContainerStream(t *testing.T) {
t.Parallel()
server, err := NewServer("127.0.0.1:0", nil, nil)
if err != nil {
t.Fatal(err)
@@ -1934,6 +2027,7 @@ func TestStatsContainerStream(t *testing.T) {
t.Fatal(err)
}
got.Read = time.Time{}
got.PreRead = time.Time{}
if !reflect.DeepEqual(got, expected) {
t.Errorf("StatsContainer: wrong value. Want %#v. Got %#v.", expected, got)
}
@@ -1960,6 +2054,7 @@ func addNetworks(server *DockerServer, n int) {
}
func TestListNetworks(t *testing.T) {
t.Parallel()
server := DockerServer{}
addNetworks(&server, 2)
server.buildMuxer()
@@ -1993,6 +2088,7 @@ type createNetworkResponse struct {
}
func TestCreateNetwork(t *testing.T) {
t.Parallel()
server := DockerServer{}
server.buildMuxer()
recorder := httptest.NewRecorder()
@@ -2017,6 +2113,7 @@ func TestCreateNetwork(t *testing.T) {
}
func TestCreateNetworkInvalidBody(t *testing.T) {
t.Parallel()
server := DockerServer{}
server.buildMuxer()
recorder := httptest.NewRecorder()
@@ -2028,6 +2125,7 @@ func TestCreateNetworkInvalidBody(t *testing.T) {
}
func TestCreateNetworkDuplicateName(t *testing.T) {
t.Parallel()
server := DockerServer{}
server.buildMuxer()
addNetworks(&server, 1)
@@ -2042,6 +2140,7 @@ func TestCreateNetworkDuplicateName(t *testing.T) {
}
func TestRemoveNetwork(t *testing.T) {
t.Parallel()
server := DockerServer{}
server.buildMuxer()
recorder := httptest.NewRecorder()
@@ -2070,6 +2169,7 @@ func TestRemoveNetwork(t *testing.T) {
}
func TestListVolumes(t *testing.T) {
t.Parallel()
server := DockerServer{}
server.buildMuxer()
expected := []docker.Volume{{
@@ -2106,6 +2206,7 @@ func TestListVolumes(t *testing.T) {
}
func TestCreateVolume(t *testing.T) {
t.Parallel()
server := DockerServer{}
server.buildMuxer()
recorder := httptest.NewRecorder()
@@ -2132,6 +2233,7 @@ func TestCreateVolume(t *testing.T) {
}
func TestCreateVolumeAlreadExists(t *testing.T) {
t.Parallel()
server := DockerServer{}
server.buildMuxer()
server.volStore = make(map[string]*volumeCounter)
@@ -2167,6 +2269,7 @@ func TestCreateVolumeAlreadExists(t *testing.T) {
}
func TestInspectVolume(t *testing.T) {
t.Parallel()
server := DockerServer{}
server.buildMuxer()
recorder := httptest.NewRecorder()
@@ -2204,6 +2307,7 @@ func TestInspectVolume(t *testing.T) {
}
func TestInspectVolumeNotFound(t *testing.T) {
t.Parallel()
server := DockerServer{}
server.buildMuxer()
recorder := httptest.NewRecorder()
@@ -2215,6 +2319,7 @@ func TestInspectVolumeNotFound(t *testing.T) {
}
func TestRemoveVolume(t *testing.T) {
t.Parallel()
server := DockerServer{}
server.buildMuxer()
server.volStore = make(map[string]*volumeCounter)
@@ -2235,6 +2340,7 @@ func TestRemoveVolume(t *testing.T) {
}
func TestRemoveMissingVolume(t *testing.T) {
t.Parallel()
server := DockerServer{}
server.buildMuxer()
recorder := httptest.NewRecorder()
@@ -2246,6 +2352,7 @@ func TestRemoveMissingVolume(t *testing.T) {
}
func TestRemoveVolumeInuse(t *testing.T) {
t.Parallel()
server := DockerServer{}
server.buildMuxer()
server.volStore = make(map[string]*volumeCounter)
@@ -2266,6 +2373,7 @@ func TestRemoveVolumeInuse(t *testing.T) {
}
func TestUploadToContainer(t *testing.T) {
t.Parallel()
server := DockerServer{}
server.buildMuxer()
cont := &docker.Container{
@@ -2291,6 +2399,7 @@ func TestUploadToContainer(t *testing.T) {
}
func TestUploadToContainerWithBodyTarFile(t *testing.T) {
t.Parallel()
server := DockerServer{}
server.buildMuxer()
cont := &docker.Container{
@@ -2327,6 +2436,7 @@ func TestUploadToContainerWithBodyTarFile(t *testing.T) {
}
func TestUploadToContainerBodyNotTarFile(t *testing.T) {
t.Parallel()
server := DockerServer{}
server.buildMuxer()
cont := &docker.Container{
@@ -2353,6 +2463,7 @@ func TestUploadToContainerBodyNotTarFile(t *testing.T) {
}
func TestUploadToContainerMissingContainer(t *testing.T) {
t.Parallel()
server := DockerServer{}
server.buildMuxer()
recorder := httptest.NewRecorder()
@@ -2364,6 +2475,7 @@ func TestUploadToContainerMissingContainer(t *testing.T) {
}
func TestInfoDocker(t *testing.T) {
t.Parallel()
server, _ := NewServer("127.0.0.1:0", nil, nil)
defer server.Stop()
addContainers(server, 1)
@@ -2388,6 +2500,7 @@ func TestInfoDocker(t *testing.T) {
}
func TestInfoDockerWithSwarm(t *testing.T) {
t.Parallel()
srv1, srv2 := setUpSwarm(t)
defer srv1.Stop()
defer srv2.Stop()
@@ -2415,6 +2528,7 @@ func TestInfoDockerWithSwarm(t *testing.T) {
}
func TestVersionDocker(t *testing.T) {
t.Parallel()
server, _ := NewServer("127.0.0.1:0", nil, nil)
defer server.Stop()
server.buildMuxer()
@@ -2427,6 +2541,7 @@ func TestVersionDocker(t *testing.T) {
}
func TestDownloadFromContainer(t *testing.T) {
t.Parallel()
server := DockerServer{}
server.buildMuxer()
cont := &docker.Container{

View File

@@ -190,7 +190,7 @@ func TestSwarmJoinWithService(t *testing.T) {
serviceCreateOpts := docker.CreateServiceOptions{
ServiceSpec: swarm.ServiceSpec{
TaskTemplate: swarm.TaskSpec{
ContainerSpec: swarm.ContainerSpec{
ContainerSpec: &swarm.ContainerSpec{
Image: "test/test",
},
},
@@ -341,7 +341,7 @@ func TestServiceCreate(t *testing.T) {
Name: "test",
},
TaskTemplate: swarm.TaskSpec{
ContainerSpec: swarm.ContainerSpec{
ContainerSpec: &swarm.ContainerSpec{
Image: "test/test",
Command: []string{"sh"},
Args: []string{"--test"},
@@ -437,7 +437,7 @@ func TestServiceCreateDynamicPort(t *testing.T) {
Name: "test",
},
TaskTemplate: swarm.TaskSpec{
ContainerSpec: swarm.ContainerSpec{
ContainerSpec: &swarm.ContainerSpec{
Image: "test/test",
Command: []string{"sh"},
Args: []string{"--test"},
@@ -993,7 +993,7 @@ func TestServiceUpdate(t *testing.T) {
Name: "test",
},
TaskTemplate: swarm.TaskSpec{
ContainerSpec: swarm.ContainerSpec{
ContainerSpec: &swarm.ContainerSpec{
Image: "test/test2",
Args: []string{"--test2"},
Env: []string{"ENV=2"},
@@ -1088,7 +1088,7 @@ func TestServiceUpdateMoreReplicas(t *testing.T) {
Name: "test",
},
TaskTemplate: swarm.TaskSpec{
ContainerSpec: swarm.ContainerSpec{
ContainerSpec: &swarm.ContainerSpec{
Image: "test/test2",
Args: []string{"--test2"},
Env: []string{"ENV=2"},
@@ -1133,7 +1133,7 @@ func TestServiceUpdateNotFound(t *testing.T) {
Name: "test",
},
TaskTemplate: swarm.TaskSpec{
ContainerSpec: swarm.ContainerSpec{
ContainerSpec: &swarm.ContainerSpec{
Image: "test/test2",
Args: []string{"--test2"},
Env: []string{"ENV=2"},
@@ -1297,7 +1297,7 @@ func addTestService(server *DockerServer) (*swarm.Service, error) {
},
},
TaskTemplate: swarm.TaskSpec{
ContainerSpec: swarm.ContainerSpec{
ContainerSpec: &swarm.ContainerSpec{
Image: "test/test",
Args: []string{"--test"},
Env: []string{"ENV=1"},

View File

@@ -13,6 +13,7 @@ import (
)
func TestListVolumes(t *testing.T) {
t.Parallel()
volumesData := `[
{
"Name": "tardis",
@@ -41,6 +42,7 @@ func TestListVolumes(t *testing.T) {
}
func TestCreateVolume(t *testing.T) {
t.Parallel()
body := `{
"Name": "tardis",
"Driver": "local",
@@ -79,6 +81,7 @@ func TestCreateVolume(t *testing.T) {
}
func TestInspectVolume(t *testing.T) {
t.Parallel()
body := `{
"Name": "tardis",
"Driver": "local",
@@ -110,6 +113,7 @@ func TestInspectVolume(t *testing.T) {
}
func TestRemoveVolume(t *testing.T) {
t.Parallel()
name := "test"
fakeRT := &FakeRoundTripper{message: "", status: http.StatusNoContent}
client := newTestClient(fakeRT)
@@ -128,6 +132,7 @@ func TestRemoveVolume(t *testing.T) {
}
func TestRemoveVolumeNotFound(t *testing.T) {
t.Parallel()
client := newTestClient(&FakeRoundTripper{message: "no such volume", status: http.StatusNotFound})
if err := client.RemoveVolume("test:"); err != ErrNoSuchVolume {
t.Errorf("RemoveVolume: wrong error. Want %#v. Got %#v.", ErrNoSuchVolume, err)
@@ -135,6 +140,7 @@ func TestRemoveVolumeNotFound(t *testing.T) {
}
func TestRemoveVolumeInUse(t *testing.T) {
t.Parallel()
client := newTestClient(&FakeRoundTripper{message: "volume in use and cannot be removed", status: http.StatusConflict})
if err := client.RemoveVolume("test:"); err != ErrVolumeInUse {
t.Errorf("RemoveVolume: wrong error. Want %#v. Got %#v.", ErrVolumeInUse, err)
@@ -142,6 +148,7 @@ func TestRemoveVolumeInUse(t *testing.T) {
}
func TestPruneVolumes(t *testing.T) {
t.Parallel()
results := `{
"VolumesDeleted": [
"a", "b", "c"