mirror of https://github.com/docker/cli.git
Merge pull request #39 from tiborvass/rm_client
rm client and vendor it instead
This commit is contained in:
commit
2a5d6c8aac
|
@ -9,7 +9,6 @@ Docker EE products.
|
||||||
It's composed of 3 main folders
|
It's composed of 3 main folders
|
||||||
|
|
||||||
* `/cli` - all the commands code.
|
* `/cli` - all the commands code.
|
||||||
* `/client` - the API client, used by `/cli`.
|
|
||||||
* `/cmd/docker` - the entrypoint of the cli, aka the main.
|
* `/cmd/docker` - the entrypoint of the cli, aka the main.
|
||||||
|
|
||||||
Development
|
Development
|
||||||
|
|
|
@ -12,10 +12,10 @@ import (
|
||||||
"github.com/docker/cli/cli/config/configfile"
|
"github.com/docker/cli/cli/config/configfile"
|
||||||
"github.com/docker/cli/cli/config/credentials"
|
"github.com/docker/cli/cli/config/credentials"
|
||||||
cliflags "github.com/docker/cli/cli/flags"
|
cliflags "github.com/docker/cli/cli/flags"
|
||||||
"github.com/docker/cli/client"
|
|
||||||
"github.com/docker/docker/api"
|
"github.com/docker/docker/api"
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/api/types/versions"
|
"github.com/docker/docker/api/types/versions"
|
||||||
|
"github.com/docker/docker/client"
|
||||||
"github.com/docker/docker/dockerversion"
|
"github.com/docker/docker/dockerversion"
|
||||||
dopts "github.com/docker/docker/opts"
|
dopts "github.com/docker/docker/opts"
|
||||||
"github.com/docker/go-connections/sockets"
|
"github.com/docker/go-connections/sockets"
|
||||||
|
|
|
@ -8,10 +8,10 @@ import (
|
||||||
"github.com/docker/cli/cli"
|
"github.com/docker/cli/cli"
|
||||||
"github.com/docker/cli/cli/command"
|
"github.com/docker/cli/cli/command"
|
||||||
"github.com/docker/cli/cli/command/image"
|
"github.com/docker/cli/cli/command/image"
|
||||||
apiclient "github.com/docker/cli/client"
|
|
||||||
"github.com/docker/distribution/reference"
|
"github.com/docker/distribution/reference"
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
|
apiclient "github.com/docker/docker/client"
|
||||||
"github.com/docker/docker/pkg/jsonmessage"
|
"github.com/docker/docker/pkg/jsonmessage"
|
||||||
"github.com/docker/docker/registry"
|
"github.com/docker/docker/registry"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
|
|
@ -7,8 +7,8 @@ import (
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
"github.com/docker/cli/cli"
|
"github.com/docker/cli/cli"
|
||||||
"github.com/docker/cli/cli/command"
|
"github.com/docker/cli/cli/command"
|
||||||
apiclient "github.com/docker/cli/client"
|
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
|
apiclient "github.com/docker/docker/client"
|
||||||
options "github.com/docker/docker/opts"
|
options "github.com/docker/docker/opts"
|
||||||
"github.com/docker/docker/pkg/promise"
|
"github.com/docker/docker/pkg/promise"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
|
@ -9,8 +9,8 @@ import (
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
"github.com/docker/cli/cli/command/formatter"
|
"github.com/docker/cli/cli/command/formatter"
|
||||||
"github.com/docker/cli/client"
|
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
|
"github.com/docker/docker/client"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
|
|
|
@ -9,8 +9,8 @@ import (
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
"github.com/docker/cli/cli/command"
|
"github.com/docker/cli/cli/command"
|
||||||
"github.com/docker/cli/client"
|
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
|
"github.com/docker/docker/client"
|
||||||
"github.com/docker/docker/pkg/signal"
|
"github.com/docker/docker/pkg/signal"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
|
|
|
@ -5,11 +5,11 @@ import (
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
"github.com/docker/cli/cli/command"
|
"github.com/docker/cli/cli/command"
|
||||||
clientapi "github.com/docker/cli/client"
|
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/api/types/events"
|
"github.com/docker/docker/api/types/events"
|
||||||
"github.com/docker/docker/api/types/filters"
|
"github.com/docker/docker/api/types/filters"
|
||||||
"github.com/docker/docker/api/types/versions"
|
"github.com/docker/docker/api/types/versions"
|
||||||
|
clientapi "github.com/docker/docker/client"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package idresolver
|
package idresolver
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/docker/cli/client"
|
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/api/types/swarm"
|
"github.com/docker/docker/api/types/swarm"
|
||||||
|
"github.com/docker/docker/client"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -3,9 +3,9 @@ package idresolver
|
||||||
import (
|
import (
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
|
|
||||||
"github.com/docker/cli/client"
|
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/api/types/swarm"
|
"github.com/docker/docker/api/types/swarm"
|
||||||
|
"github.com/docker/docker/client"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -6,10 +6,10 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/docker/cli/client"
|
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/api/types/filters"
|
"github.com/docker/docker/api/types/filters"
|
||||||
"github.com/docker/docker/api/types/image"
|
"github.com/docker/docker/api/types/image"
|
||||||
|
"github.com/docker/docker/client"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package node
|
package node
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/docker/cli/client"
|
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/api/types/swarm"
|
"github.com/docker/docker/api/types/swarm"
|
||||||
|
"github.com/docker/docker/client"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,8 @@ import (
|
||||||
|
|
||||||
"github.com/docker/cli/cli"
|
"github.com/docker/cli/cli"
|
||||||
"github.com/docker/cli/cli/command"
|
"github.com/docker/cli/cli/command"
|
||||||
apiclient "github.com/docker/cli/client"
|
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
|
apiclient "github.com/docker/docker/client"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package secret
|
package secret
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/docker/cli/client"
|
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/api/types/swarm"
|
"github.com/docker/docker/api/types/swarm"
|
||||||
|
"github.com/docker/docker/client"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,8 @@ import (
|
||||||
"github.com/docker/cli/cli"
|
"github.com/docker/cli/cli"
|
||||||
"github.com/docker/cli/cli/command"
|
"github.com/docker/cli/cli/command"
|
||||||
"github.com/docker/cli/cli/command/formatter"
|
"github.com/docker/cli/cli/command/formatter"
|
||||||
apiclient "github.com/docker/cli/client"
|
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
|
apiclient "github.com/docker/docker/client"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
|
@ -12,9 +12,9 @@ import (
|
||||||
"github.com/docker/cli/cli"
|
"github.com/docker/cli/cli"
|
||||||
"github.com/docker/cli/cli/command"
|
"github.com/docker/cli/cli/command"
|
||||||
"github.com/docker/cli/cli/command/idresolver"
|
"github.com/docker/cli/cli/command/idresolver"
|
||||||
"github.com/docker/cli/client"
|
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/api/types/swarm"
|
"github.com/docker/docker/api/types/swarm"
|
||||||
|
"github.com/docker/docker/client"
|
||||||
"github.com/docker/docker/pkg/stdcopy"
|
"github.com/docker/docker/pkg/stdcopy"
|
||||||
"github.com/docker/docker/pkg/stringid"
|
"github.com/docker/docker/pkg/stringid"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
|
|
@ -7,9 +7,9 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/docker/cli/client"
|
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
"github.com/docker/docker/api/types/swarm"
|
"github.com/docker/docker/api/types/swarm"
|
||||||
|
"github.com/docker/docker/client"
|
||||||
"github.com/docker/docker/opts"
|
"github.com/docker/docker/opts"
|
||||||
runconfigopts "github.com/docker/docker/runconfig/opts"
|
runconfigopts "github.com/docker/docker/runconfig/opts"
|
||||||
"github.com/docker/swarmkit/api"
|
"github.com/docker/swarmkit/api"
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
package service
|
package service
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/docker/cli/client"
|
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/api/types/filters"
|
"github.com/docker/docker/api/types/filters"
|
||||||
swarmtypes "github.com/docker/docker/api/types/swarm"
|
swarmtypes "github.com/docker/docker/api/types/swarm"
|
||||||
|
"github.com/docker/docker/client"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
|
|
|
@ -8,10 +8,10 @@ import (
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/docker/cli/client"
|
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/api/types/filters"
|
"github.com/docker/docker/api/types/filters"
|
||||||
"github.com/docker/docker/api/types/swarm"
|
"github.com/docker/docker/api/types/swarm"
|
||||||
|
"github.com/docker/docker/client"
|
||||||
"github.com/docker/docker/pkg/progress"
|
"github.com/docker/docker/pkg/progress"
|
||||||
"github.com/docker/docker/pkg/streamformatter"
|
"github.com/docker/docker/pkg/streamformatter"
|
||||||
"github.com/docker/docker/pkg/stringid"
|
"github.com/docker/docker/pkg/stringid"
|
||||||
|
|
|
@ -8,12 +8,12 @@ import (
|
||||||
|
|
||||||
"github.com/docker/cli/cli"
|
"github.com/docker/cli/cli"
|
||||||
"github.com/docker/cli/cli/command"
|
"github.com/docker/cli/cli/command"
|
||||||
"github.com/docker/cli/client"
|
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
mounttypes "github.com/docker/docker/api/types/mount"
|
mounttypes "github.com/docker/docker/api/types/mount"
|
||||||
"github.com/docker/docker/api/types/swarm"
|
"github.com/docker/docker/api/types/swarm"
|
||||||
"github.com/docker/docker/api/types/versions"
|
"github.com/docker/docker/api/types/versions"
|
||||||
|
"github.com/docker/docker/client"
|
||||||
"github.com/docker/docker/opts"
|
"github.com/docker/docker/opts"
|
||||||
runconfigopts "github.com/docker/docker/runconfig/opts"
|
runconfigopts "github.com/docker/docker/runconfig/opts"
|
||||||
"github.com/docker/swarmkit/api/defaults"
|
"github.com/docker/swarmkit/api/defaults"
|
||||||
|
|
|
@ -4,10 +4,10 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/docker/cli/cli/compose/convert"
|
"github.com/docker/cli/cli/compose/convert"
|
||||||
"github.com/docker/cli/client"
|
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/api/types/filters"
|
"github.com/docker/docker/api/types/filters"
|
||||||
"github.com/docker/docker/api/types/swarm"
|
"github.com/docker/docker/api/types/swarm"
|
||||||
|
"github.com/docker/docker/client"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,10 @@ import (
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
|
|
||||||
"github.com/docker/cli/cli/compose/convert"
|
"github.com/docker/cli/cli/compose/convert"
|
||||||
"github.com/docker/cli/client"
|
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/api/types/filters"
|
"github.com/docker/docker/api/types/filters"
|
||||||
"github.com/docker/docker/api/types/swarm"
|
"github.com/docker/docker/api/types/swarm"
|
||||||
|
"github.com/docker/docker/client"
|
||||||
"github.com/docker/docker/opts"
|
"github.com/docker/docker/opts"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -12,10 +12,10 @@ import (
|
||||||
"github.com/docker/cli/cli/compose/convert"
|
"github.com/docker/cli/cli/compose/convert"
|
||||||
"github.com/docker/cli/cli/compose/loader"
|
"github.com/docker/cli/cli/compose/loader"
|
||||||
composetypes "github.com/docker/cli/cli/compose/types"
|
composetypes "github.com/docker/cli/cli/compose/types"
|
||||||
apiclient "github.com/docker/cli/client"
|
|
||||||
dockerclient "github.com/docker/cli/client"
|
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/api/types/swarm"
|
"github.com/docker/docker/api/types/swarm"
|
||||||
|
apiclient "github.com/docker/docker/client"
|
||||||
|
dockerclient "github.com/docker/docker/client"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
|
|
|
@ -7,8 +7,8 @@ import (
|
||||||
"github.com/docker/cli/cli/command"
|
"github.com/docker/cli/cli/command"
|
||||||
"github.com/docker/cli/cli/command/formatter"
|
"github.com/docker/cli/cli/command/formatter"
|
||||||
"github.com/docker/cli/cli/compose/convert"
|
"github.com/docker/cli/cli/compose/convert"
|
||||||
"github.com/docker/cli/client"
|
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
|
"github.com/docker/docker/client"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package swarm
|
package swarm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/docker/cli/client"
|
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/api/types/swarm"
|
"github.com/docker/docker/api/types/swarm"
|
||||||
|
"github.com/docker/docker/client"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,8 @@ import (
|
||||||
"github.com/docker/cli/cli"
|
"github.com/docker/cli/cli"
|
||||||
"github.com/docker/cli/cli/command"
|
"github.com/docker/cli/cli/command"
|
||||||
"github.com/docker/cli/cli/command/inspect"
|
"github.com/docker/cli/cli/command/inspect"
|
||||||
apiclient "github.com/docker/cli/client"
|
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
|
apiclient "github.com/docker/docker/client"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
package volume
|
package volume
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/docker/cli/client"
|
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/api/types/filters"
|
"github.com/docker/docker/api/types/filters"
|
||||||
volumetypes "github.com/docker/docker/api/types/volume"
|
volumetypes "github.com/docker/docker/api/types/volume"
|
||||||
|
"github.com/docker/docker/client"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -9,10 +9,10 @@ import (
|
||||||
|
|
||||||
servicecli "github.com/docker/cli/cli/command/service"
|
servicecli "github.com/docker/cli/cli/command/service"
|
||||||
composetypes "github.com/docker/cli/cli/compose/types"
|
composetypes "github.com/docker/cli/cli/compose/types"
|
||||||
"github.com/docker/cli/client"
|
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
"github.com/docker/docker/api/types/swarm"
|
"github.com/docker/docker/api/types/swarm"
|
||||||
"github.com/docker/docker/api/types/versions"
|
"github.com/docker/docker/api/types/versions"
|
||||||
|
"github.com/docker/docker/client"
|
||||||
"github.com/docker/docker/opts"
|
"github.com/docker/docker/opts"
|
||||||
runconfigopts "github.com/docker/docker/runconfig/opts"
|
runconfigopts "github.com/docker/docker/runconfig/opts"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
|
|
@ -226,11 +226,12 @@ type bintree struct {
|
||||||
Func func() (*asset, error)
|
Func func() (*asset, error)
|
||||||
Children map[string]*bintree
|
Children map[string]*bintree
|
||||||
}
|
}
|
||||||
|
|
||||||
var _bintree = &bintree{nil, map[string]*bintree{
|
var _bintree = &bintree{nil, map[string]*bintree{
|
||||||
"data": &bintree{nil, map[string]*bintree{
|
"data": {nil, map[string]*bintree{
|
||||||
"config_schema_v3.0.json": &bintree{dataConfig_schema_v30Json, map[string]*bintree{}},
|
"config_schema_v3.0.json": {dataConfig_schema_v30Json, map[string]*bintree{}},
|
||||||
"config_schema_v3.1.json": &bintree{dataConfig_schema_v31Json, map[string]*bintree{}},
|
"config_schema_v3.1.json": {dataConfig_schema_v31Json, map[string]*bintree{}},
|
||||||
"config_schema_v3.2.json": &bintree{dataConfig_schema_v32Json, map[string]*bintree{}},
|
"config_schema_v3.2.json": {dataConfig_schema_v32Json, map[string]*bintree{}},
|
||||||
}},
|
}},
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
@ -280,4 +281,3 @@ func _filePath(dir, name string) string {
|
||||||
cannonicalName := strings.Replace(name, "\\", "/", -1)
|
cannonicalName := strings.Replace(name, "\\", "/", -1)
|
||||||
return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...)
|
return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"github.com/docker/cli/cli/command"
|
"github.com/docker/cli/cli/command"
|
||||||
"github.com/docker/cli/cli/config/configfile"
|
"github.com/docker/cli/cli/config/configfile"
|
||||||
"github.com/docker/cli/cli/config/credentials"
|
"github.com/docker/cli/cli/config/credentials"
|
||||||
"github.com/docker/cli/client"
|
"github.com/docker/docker/client"
|
||||||
)
|
)
|
||||||
|
|
||||||
// FakeCli emulates the default DockerCli
|
// FakeCli emulates the default DockerCli
|
||||||
|
|
|
@ -1,73 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestCheckpointCreateError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
err := client.CheckpointCreate(context.Background(), "nothing", types.CheckpointCreateOptions{
|
|
||||||
CheckpointID: "noting",
|
|
||||||
Exit: true,
|
|
||||||
})
|
|
||||||
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCheckpointCreate(t *testing.T) {
|
|
||||||
expectedContainerID := "container_id"
|
|
||||||
expectedCheckpointID := "checkpoint_id"
|
|
||||||
expectedURL := "/containers/container_id/checkpoints"
|
|
||||||
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
|
|
||||||
if req.Method != "POST" {
|
|
||||||
return nil, fmt.Errorf("expected POST method, got %s", req.Method)
|
|
||||||
}
|
|
||||||
|
|
||||||
createOptions := &types.CheckpointCreateOptions{}
|
|
||||||
if err := json.NewDecoder(req.Body).Decode(createOptions); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if createOptions.CheckpointID != expectedCheckpointID {
|
|
||||||
return nil, fmt.Errorf("expected CheckpointID to be 'checkpoint_id', got %v", createOptions.CheckpointID)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !createOptions.Exit {
|
|
||||||
return nil, fmt.Errorf("expected Exit to be true")
|
|
||||||
}
|
|
||||||
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte(""))),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
err := client.CheckpointCreate(context.Background(), expectedContainerID, types.CheckpointCreateOptions{
|
|
||||||
CheckpointID: expectedCheckpointID,
|
|
||||||
Exit: true,
|
|
||||||
})
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,54 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestCheckpointDeleteError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
|
|
||||||
err := client.CheckpointDelete(context.Background(), "container_id", types.CheckpointDeleteOptions{
|
|
||||||
CheckpointID: "checkpoint_id",
|
|
||||||
})
|
|
||||||
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCheckpointDelete(t *testing.T) {
|
|
||||||
expectedURL := "/containers/container_id/checkpoints/checkpoint_id"
|
|
||||||
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
if req.Method != "DELETE" {
|
|
||||||
return nil, fmt.Errorf("expected DELETE method, got %s", req.Method)
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte(""))),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
err := client.CheckpointDelete(context.Background(), "container_id", types.CheckpointDeleteOptions{
|
|
||||||
CheckpointID: "checkpoint_id",
|
|
||||||
})
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,68 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestCheckpointListError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := client.CheckpointList(context.Background(), "container_id", types.CheckpointListOptions{})
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCheckpointList(t *testing.T) {
|
|
||||||
expectedURL := "/containers/container_id/checkpoints"
|
|
||||||
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
content, err := json.Marshal([]types.Checkpoint{
|
|
||||||
{
|
|
||||||
Name: "checkpoint",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader(content)),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
checkpoints, err := client.CheckpointList(context.Background(), "container_id", types.CheckpointListOptions{})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if len(checkpoints) != 1 {
|
|
||||||
t.Fatalf("expected 1 checkpoint, got %v", checkpoints)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCheckpointListContainerNotFound(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusNotFound, "Server error")),
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := client.CheckpointList(context.Background(), "unknown", types.CheckpointListOptions{})
|
|
||||||
if err == nil || !IsErrContainerNotFound(err) {
|
|
||||||
t.Fatalf("expected a containerNotFound error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,53 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
// transportFunc allows us to inject a mock transport for testing. We define it
|
|
||||||
// here so we can detect the tlsconfig and return nil for only this type.
|
|
||||||
type transportFunc func(*http.Request) (*http.Response, error)
|
|
||||||
|
|
||||||
func (tf transportFunc) RoundTrip(req *http.Request) (*http.Response, error) {
|
|
||||||
return tf(req)
|
|
||||||
}
|
|
||||||
|
|
||||||
func newMockClient(doer func(*http.Request) (*http.Response, error)) *http.Client {
|
|
||||||
return &http.Client{
|
|
||||||
Transport: transportFunc(doer),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func errorMock(statusCode int, message string) func(req *http.Request) (*http.Response, error) {
|
|
||||||
return func(req *http.Request) (*http.Response, error) {
|
|
||||||
header := http.Header{}
|
|
||||||
header.Set("Content-Type", "application/json")
|
|
||||||
|
|
||||||
body, err := json.Marshal(&types.ErrorResponse{
|
|
||||||
Message: message,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: statusCode,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader(body)),
|
|
||||||
Header: header,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func plainTextErrorMock(statusCode int, message string) func(req *http.Request) (*http.Response, error) {
|
|
||||||
return func(req *http.Request) (*http.Response, error) {
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: statusCode,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte(message))),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,284 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
"os"
|
|
||||||
"runtime"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api"
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestNewEnvClient(t *testing.T) {
|
|
||||||
if runtime.GOOS == "windows" {
|
|
||||||
t.Skip("skipping unix only test for windows")
|
|
||||||
}
|
|
||||||
cases := []struct {
|
|
||||||
envs map[string]string
|
|
||||||
expectedError string
|
|
||||||
expectedVersion string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
envs: map[string]string{},
|
|
||||||
expectedVersion: api.DefaultVersion,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
envs: map[string]string{
|
|
||||||
"DOCKER_CERT_PATH": "invalid/path",
|
|
||||||
},
|
|
||||||
expectedError: "Could not load X509 key pair: open invalid/path/cert.pem: no such file or directory",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
envs: map[string]string{
|
|
||||||
"DOCKER_CERT_PATH": "testdata/",
|
|
||||||
},
|
|
||||||
expectedVersion: api.DefaultVersion,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
envs: map[string]string{
|
|
||||||
"DOCKER_CERT_PATH": "testdata/",
|
|
||||||
"DOCKER_TLS_VERIFY": "1",
|
|
||||||
},
|
|
||||||
expectedVersion: api.DefaultVersion,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
envs: map[string]string{
|
|
||||||
"DOCKER_CERT_PATH": "testdata/",
|
|
||||||
"DOCKER_HOST": "https://notaunixsocket",
|
|
||||||
},
|
|
||||||
expectedVersion: api.DefaultVersion,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
envs: map[string]string{
|
|
||||||
"DOCKER_HOST": "host",
|
|
||||||
},
|
|
||||||
expectedError: "unable to parse docker host `host`",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
envs: map[string]string{
|
|
||||||
"DOCKER_HOST": "invalid://url",
|
|
||||||
},
|
|
||||||
expectedVersion: api.DefaultVersion,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
envs: map[string]string{
|
|
||||||
"DOCKER_API_VERSION": "anything",
|
|
||||||
},
|
|
||||||
expectedVersion: "anything",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
envs: map[string]string{
|
|
||||||
"DOCKER_API_VERSION": "1.22",
|
|
||||||
},
|
|
||||||
expectedVersion: "1.22",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, c := range cases {
|
|
||||||
recoverEnvs := setupEnvs(t, c.envs)
|
|
||||||
apiclient, err := NewEnvClient()
|
|
||||||
if c.expectedError != "" {
|
|
||||||
if err == nil {
|
|
||||||
t.Errorf("expected an error for %v", c)
|
|
||||||
} else if err.Error() != c.expectedError {
|
|
||||||
t.Errorf("expected an error %s, got %s, for %v", c.expectedError, err.Error(), c)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
version := apiclient.ClientVersion()
|
|
||||||
if version != c.expectedVersion {
|
|
||||||
t.Errorf("expected %s, got %s, for %v", c.expectedVersion, version, c)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.envs["DOCKER_TLS_VERIFY"] != "" {
|
|
||||||
// pedantic checking that this is handled correctly
|
|
||||||
tr := apiclient.client.Transport.(*http.Transport)
|
|
||||||
if tr.TLSClientConfig == nil {
|
|
||||||
t.Error("no TLS config found when DOCKER_TLS_VERIFY enabled")
|
|
||||||
}
|
|
||||||
|
|
||||||
if tr.TLSClientConfig.InsecureSkipVerify {
|
|
||||||
t.Error("TLS verification should be enabled")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
recoverEnvs(t)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func setupEnvs(t *testing.T, envs map[string]string) func(*testing.T) {
|
|
||||||
oldEnvs := map[string]string{}
|
|
||||||
for key, value := range envs {
|
|
||||||
oldEnv := os.Getenv(key)
|
|
||||||
oldEnvs[key] = oldEnv
|
|
||||||
err := os.Setenv(key, value)
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return func(t *testing.T) {
|
|
||||||
for key, value := range oldEnvs {
|
|
||||||
err := os.Setenv(key, value)
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetAPIPath(t *testing.T) {
|
|
||||||
cases := []struct {
|
|
||||||
v string
|
|
||||||
p string
|
|
||||||
q url.Values
|
|
||||||
e string
|
|
||||||
}{
|
|
||||||
{"", "/containers/json", nil, "/containers/json"},
|
|
||||||
{"", "/containers/json", url.Values{}, "/containers/json"},
|
|
||||||
{"", "/containers/json", url.Values{"s": []string{"c"}}, "/containers/json?s=c"},
|
|
||||||
{"1.22", "/containers/json", nil, "/v1.22/containers/json"},
|
|
||||||
{"1.22", "/containers/json", url.Values{}, "/v1.22/containers/json"},
|
|
||||||
{"1.22", "/containers/json", url.Values{"s": []string{"c"}}, "/v1.22/containers/json?s=c"},
|
|
||||||
{"v1.22", "/containers/json", nil, "/v1.22/containers/json"},
|
|
||||||
{"v1.22", "/containers/json", url.Values{}, "/v1.22/containers/json"},
|
|
||||||
{"v1.22", "/containers/json", url.Values{"s": []string{"c"}}, "/v1.22/containers/json?s=c"},
|
|
||||||
{"v1.22", "/networks/kiwl$%^", nil, "/v1.22/networks/kiwl$%25%5E"},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, cs := range cases {
|
|
||||||
c, err := NewClient("unix:///var/run/docker.sock", cs.v, nil, nil)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
g := c.getAPIPath(cs.p, cs.q)
|
|
||||||
if g != cs.e {
|
|
||||||
t.Fatalf("Expected %s, got %s", cs.e, g)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = c.Close()
|
|
||||||
if nil != err {
|
|
||||||
t.Fatalf("close client failed, error message: %s", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestParseHost(t *testing.T) {
|
|
||||||
cases := []struct {
|
|
||||||
host string
|
|
||||||
proto string
|
|
||||||
addr string
|
|
||||||
base string
|
|
||||||
err bool
|
|
||||||
}{
|
|
||||||
{"", "", "", "", true},
|
|
||||||
{"foobar", "", "", "", true},
|
|
||||||
{"foo://bar", "foo", "bar", "", false},
|
|
||||||
{"tcp://localhost:2476", "tcp", "localhost:2476", "", false},
|
|
||||||
{"tcp://localhost:2476/path", "tcp", "localhost:2476", "/path", false},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, cs := range cases {
|
|
||||||
p, a, b, e := ParseHost(cs.host)
|
|
||||||
if cs.err && e == nil {
|
|
||||||
t.Fatalf("expected error, got nil")
|
|
||||||
}
|
|
||||||
if !cs.err && e != nil {
|
|
||||||
t.Fatal(e)
|
|
||||||
}
|
|
||||||
if cs.proto != p {
|
|
||||||
t.Fatalf("expected proto %s, got %s", cs.proto, p)
|
|
||||||
}
|
|
||||||
if cs.addr != a {
|
|
||||||
t.Fatalf("expected addr %s, got %s", cs.addr, a)
|
|
||||||
}
|
|
||||||
if cs.base != b {
|
|
||||||
t.Fatalf("expected base %s, got %s", cs.base, b)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUpdateClientVersion(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
splitQuery := strings.Split(req.URL.Path, "/")
|
|
||||||
queryVersion := splitQuery[1]
|
|
||||||
b, err := json.Marshal(types.Version{
|
|
||||||
APIVersion: queryVersion,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader(b)),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
cases := []struct {
|
|
||||||
v string
|
|
||||||
}{
|
|
||||||
{"1.20"},
|
|
||||||
{"v1.21"},
|
|
||||||
{"1.22"},
|
|
||||||
{"v1.22"},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, cs := range cases {
|
|
||||||
client.UpdateClientVersion(cs.v)
|
|
||||||
r, err := client.ServerVersion(context.Background())
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if strings.TrimPrefix(r.APIVersion, "v") != strings.TrimPrefix(cs.v, "v") {
|
|
||||||
t.Fatalf("Expected %s, got %s", cs.v, r.APIVersion)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNewEnvClientSetsDefaultVersion(t *testing.T) {
|
|
||||||
// Unset environment variables
|
|
||||||
envVarKeys := []string{
|
|
||||||
"DOCKER_HOST",
|
|
||||||
"DOCKER_API_VERSION",
|
|
||||||
"DOCKER_TLS_VERIFY",
|
|
||||||
"DOCKER_CERT_PATH",
|
|
||||||
}
|
|
||||||
envVarValues := make(map[string]string)
|
|
||||||
for _, key := range envVarKeys {
|
|
||||||
envVarValues[key] = os.Getenv(key)
|
|
||||||
os.Setenv(key, "")
|
|
||||||
}
|
|
||||||
|
|
||||||
client, err := NewEnvClient()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if client.version != api.DefaultVersion {
|
|
||||||
t.Fatalf("Expected %s, got %s", api.DefaultVersion, client.version)
|
|
||||||
}
|
|
||||||
|
|
||||||
expected := "1.22"
|
|
||||||
os.Setenv("DOCKER_API_VERSION", expected)
|
|
||||||
client, err = NewEnvClient()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if client.version != expected {
|
|
||||||
t.Fatalf("Expected %s, got %s", expected, client.version)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Restore environment variables
|
|
||||||
for _, key := range envVarKeys {
|
|
||||||
os.Setenv(key, envVarValues[key])
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,96 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestContainerCommitError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
_, err := client.ContainerCommit(context.Background(), "nothing", types.ContainerCommitOptions{})
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContainerCommit(t *testing.T) {
|
|
||||||
expectedURL := "/commit"
|
|
||||||
expectedContainerID := "container_id"
|
|
||||||
specifiedReference := "repository_name:tag"
|
|
||||||
expectedRepositoryName := "repository_name"
|
|
||||||
expectedTag := "tag"
|
|
||||||
expectedComment := "comment"
|
|
||||||
expectedAuthor := "author"
|
|
||||||
expectedChanges := []string{"change1", "change2"}
|
|
||||||
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
query := req.URL.Query()
|
|
||||||
containerID := query.Get("container")
|
|
||||||
if containerID != expectedContainerID {
|
|
||||||
return nil, fmt.Errorf("container id not set in URL query properly. Expected '%s', got %s", expectedContainerID, containerID)
|
|
||||||
}
|
|
||||||
repo := query.Get("repo")
|
|
||||||
if repo != expectedRepositoryName {
|
|
||||||
return nil, fmt.Errorf("container repo not set in URL query properly. Expected '%s', got %s", expectedRepositoryName, repo)
|
|
||||||
}
|
|
||||||
tag := query.Get("tag")
|
|
||||||
if tag != expectedTag {
|
|
||||||
return nil, fmt.Errorf("container tag not set in URL query properly. Expected '%s', got %s'", expectedTag, tag)
|
|
||||||
}
|
|
||||||
comment := query.Get("comment")
|
|
||||||
if comment != expectedComment {
|
|
||||||
return nil, fmt.Errorf("container comment not set in URL query properly. Expected '%s', got %s'", expectedComment, comment)
|
|
||||||
}
|
|
||||||
author := query.Get("author")
|
|
||||||
if author != expectedAuthor {
|
|
||||||
return nil, fmt.Errorf("container author not set in URL query properly. Expected '%s', got %s'", expectedAuthor, author)
|
|
||||||
}
|
|
||||||
pause := query.Get("pause")
|
|
||||||
if pause != "0" {
|
|
||||||
return nil, fmt.Errorf("container pause not set in URL query properly. Expected 'true', got %v'", pause)
|
|
||||||
}
|
|
||||||
changes := query["changes"]
|
|
||||||
if len(changes) != len(expectedChanges) {
|
|
||||||
return nil, fmt.Errorf("expected container changes size to be '%d', got %d", len(expectedChanges), len(changes))
|
|
||||||
}
|
|
||||||
b, err := json.Marshal(types.IDResponse{
|
|
||||||
ID: "new_container_id",
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader(b)),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
r, err := client.ContainerCommit(context.Background(), expectedContainerID, types.ContainerCommitOptions{
|
|
||||||
Reference: specifiedReference,
|
|
||||||
Comment: expectedComment,
|
|
||||||
Author: expectedAuthor,
|
|
||||||
Changes: expectedChanges,
|
|
||||||
Pause: false,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if r.ID != "new_container_id" {
|
|
||||||
t.Fatalf("expected `new_container_id`, got %s", r.ID)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,244 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/base64"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestContainerStatPathError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
_, err := client.ContainerStatPath(context.Background(), "container_id", "path")
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContainerStatPathNoHeaderError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte(""))),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
_, err := client.ContainerStatPath(context.Background(), "container_id", "path/to/file")
|
|
||||||
if err == nil {
|
|
||||||
t.Fatalf("expected an error, got nothing")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContainerStatPath(t *testing.T) {
|
|
||||||
expectedURL := "/containers/container_id/archive"
|
|
||||||
expectedPath := "path/to/file"
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
if req.Method != "HEAD" {
|
|
||||||
return nil, fmt.Errorf("expected HEAD method, got %s", req.Method)
|
|
||||||
}
|
|
||||||
query := req.URL.Query()
|
|
||||||
path := query.Get("path")
|
|
||||||
if path != expectedPath {
|
|
||||||
return nil, fmt.Errorf("path not set in URL query properly")
|
|
||||||
}
|
|
||||||
content, err := json.Marshal(types.ContainerPathStat{
|
|
||||||
Name: "name",
|
|
||||||
Mode: 0700,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
base64PathStat := base64.StdEncoding.EncodeToString(content)
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte(""))),
|
|
||||||
Header: http.Header{
|
|
||||||
"X-Docker-Container-Path-Stat": []string{base64PathStat},
|
|
||||||
},
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
stat, err := client.ContainerStatPath(context.Background(), "container_id", expectedPath)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if stat.Name != "name" {
|
|
||||||
t.Fatalf("expected container path stat name to be 'name', got '%s'", stat.Name)
|
|
||||||
}
|
|
||||||
if stat.Mode != 0700 {
|
|
||||||
t.Fatalf("expected container path stat mode to be 0700, got '%v'", stat.Mode)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCopyToContainerError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
err := client.CopyToContainer(context.Background(), "container_id", "path/to/file", bytes.NewReader([]byte("")), types.CopyToContainerOptions{})
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCopyToContainerNotStatusOKError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusNoContent, "No content")),
|
|
||||||
}
|
|
||||||
err := client.CopyToContainer(context.Background(), "container_id", "path/to/file", bytes.NewReader([]byte("")), types.CopyToContainerOptions{})
|
|
||||||
if err == nil || err.Error() != "unexpected status code from daemon: 204" {
|
|
||||||
t.Fatalf("expected an unexpected status code error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCopyToContainer(t *testing.T) {
|
|
||||||
expectedURL := "/containers/container_id/archive"
|
|
||||||
expectedPath := "path/to/file"
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
if req.Method != "PUT" {
|
|
||||||
return nil, fmt.Errorf("expected PUT method, got %s", req.Method)
|
|
||||||
}
|
|
||||||
query := req.URL.Query()
|
|
||||||
path := query.Get("path")
|
|
||||||
if path != expectedPath {
|
|
||||||
return nil, fmt.Errorf("path not set in URL query properly, expected '%s', got %s", expectedPath, path)
|
|
||||||
}
|
|
||||||
noOverwriteDirNonDir := query.Get("noOverwriteDirNonDir")
|
|
||||||
if noOverwriteDirNonDir != "true" {
|
|
||||||
return nil, fmt.Errorf("noOverwriteDirNonDir not set in URL query properly, expected true, got %s", noOverwriteDirNonDir)
|
|
||||||
}
|
|
||||||
|
|
||||||
content, err := ioutil.ReadAll(req.Body)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if err := req.Body.Close(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if string(content) != "content" {
|
|
||||||
return nil, fmt.Errorf("expected content to be 'content', got %s", string(content))
|
|
||||||
}
|
|
||||||
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte(""))),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
err := client.CopyToContainer(context.Background(), "container_id", expectedPath, bytes.NewReader([]byte("content")), types.CopyToContainerOptions{
|
|
||||||
AllowOverwriteDirWithFile: false,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCopyFromContainerError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
_, _, err := client.CopyFromContainer(context.Background(), "container_id", "path/to/file")
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCopyFromContainerNotStatusOKError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusNoContent, "No content")),
|
|
||||||
}
|
|
||||||
_, _, err := client.CopyFromContainer(context.Background(), "container_id", "path/to/file")
|
|
||||||
if err == nil || err.Error() != "unexpected status code from daemon: 204" {
|
|
||||||
t.Fatalf("expected an unexpected status code error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCopyFromContainerNoHeaderError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte(""))),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
_, _, err := client.CopyFromContainer(context.Background(), "container_id", "path/to/file")
|
|
||||||
if err == nil {
|
|
||||||
t.Fatalf("expected an error, got nothing")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCopyFromContainer(t *testing.T) {
|
|
||||||
expectedURL := "/containers/container_id/archive"
|
|
||||||
expectedPath := "path/to/file"
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
if req.Method != "GET" {
|
|
||||||
return nil, fmt.Errorf("expected GET method, got %s", req.Method)
|
|
||||||
}
|
|
||||||
query := req.URL.Query()
|
|
||||||
path := query.Get("path")
|
|
||||||
if path != expectedPath {
|
|
||||||
return nil, fmt.Errorf("path not set in URL query properly, expected '%s', got %s", expectedPath, path)
|
|
||||||
}
|
|
||||||
|
|
||||||
headercontent, err := json.Marshal(types.ContainerPathStat{
|
|
||||||
Name: "name",
|
|
||||||
Mode: 0700,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
base64PathStat := base64.StdEncoding.EncodeToString(headercontent)
|
|
||||||
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte("content"))),
|
|
||||||
Header: http.Header{
|
|
||||||
"X-Docker-Container-Path-Stat": []string{base64PathStat},
|
|
||||||
},
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
r, stat, err := client.CopyFromContainer(context.Background(), "container_id", expectedPath)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if stat.Name != "name" {
|
|
||||||
t.Fatalf("expected container path stat name to be 'name', got '%s'", stat.Name)
|
|
||||||
}
|
|
||||||
if stat.Mode != 0700 {
|
|
||||||
t.Fatalf("expected container path stat mode to be 0700, got '%v'", stat.Mode)
|
|
||||||
}
|
|
||||||
content, err := ioutil.ReadAll(r)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if err := r.Close(); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if string(content) != "content" {
|
|
||||||
t.Fatalf("expected content to be 'content', got %s", string(content))
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,118 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types/container"
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestContainerCreateError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
_, err := client.ContainerCreate(context.Background(), nil, nil, nil, "nothing")
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error while testing StatusInternalServerError, got %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 404 doesn't automatically means an unknown image
|
|
||||||
client = &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusNotFound, "Server error")),
|
|
||||||
}
|
|
||||||
_, err = client.ContainerCreate(context.Background(), nil, nil, nil, "nothing")
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error while testing StatusNotFound, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContainerCreateImageNotFound(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusNotFound, "No such image")),
|
|
||||||
}
|
|
||||||
_, err := client.ContainerCreate(context.Background(), &container.Config{Image: "unknown_image"}, nil, nil, "unknown")
|
|
||||||
if err == nil || !IsErrImageNotFound(err) {
|
|
||||||
t.Fatalf("expected an imageNotFound error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContainerCreateWithName(t *testing.T) {
|
|
||||||
expectedURL := "/containers/create"
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
name := req.URL.Query().Get("name")
|
|
||||||
if name != "container_name" {
|
|
||||||
return nil, fmt.Errorf("container name not set in URL query properly. Expected `container_name`, got %s", name)
|
|
||||||
}
|
|
||||||
b, err := json.Marshal(container.ContainerCreateCreatedBody{
|
|
||||||
ID: "container_id",
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader(b)),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
r, err := client.ContainerCreate(context.Background(), nil, nil, nil, "container_name")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if r.ID != "container_id" {
|
|
||||||
t.Fatalf("expected `container_id`, got %s", r.ID)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestContainerCreateAutoRemove validates that a client using API 1.24 always disables AutoRemove. When using API 1.25
|
|
||||||
// or up, AutoRemove should not be disabled.
|
|
||||||
func TestContainerCreateAutoRemove(t *testing.T) {
|
|
||||||
autoRemoveValidator := func(expectedValue bool) func(req *http.Request) (*http.Response, error) {
|
|
||||||
return func(req *http.Request) (*http.Response, error) {
|
|
||||||
var config configWrapper
|
|
||||||
|
|
||||||
if err := json.NewDecoder(req.Body).Decode(&config); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if config.HostConfig.AutoRemove != expectedValue {
|
|
||||||
return nil, fmt.Errorf("expected AutoRemove to be %v, got %v", expectedValue, config.HostConfig.AutoRemove)
|
|
||||||
}
|
|
||||||
b, err := json.Marshal(container.ContainerCreateCreatedBody{
|
|
||||||
ID: "container_id",
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader(b)),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(autoRemoveValidator(false)),
|
|
||||||
version: "1.24",
|
|
||||||
}
|
|
||||||
if _, err := client.ContainerCreate(context.Background(), nil, &container.HostConfig{AutoRemove: true}, nil, ""); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
client = &Client{
|
|
||||||
client: newMockClient(autoRemoveValidator(true)),
|
|
||||||
version: "1.25",
|
|
||||||
}
|
|
||||||
if _, err := client.ContainerCreate(context.Background(), nil, &container.HostConfig{AutoRemove: true}, nil, ""); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,61 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types/container"
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestContainerDiffError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
_, err := client.ContainerDiff(context.Background(), "nothing")
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContainerDiff(t *testing.T) {
|
|
||||||
expectedURL := "/containers/container_id/changes"
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
b, err := json.Marshal([]container.ContainerChangeResponseItem{
|
|
||||||
{
|
|
||||||
Kind: 0,
|
|
||||||
Path: "/path/1",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Kind: 1,
|
|
||||||
Path: "/path/2",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader(b)),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
changes, err := client.ContainerDiff(context.Background(), "container_id")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if len(changes) != 2 {
|
|
||||||
t.Fatalf("expected an array of 2 changes, got %v", changes)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,157 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestContainerExecCreateError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
_, err := client.ContainerExecCreate(context.Background(), "container_id", types.ExecConfig{})
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContainerExecCreate(t *testing.T) {
|
|
||||||
expectedURL := "/containers/container_id/exec"
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
if req.Method != "POST" {
|
|
||||||
return nil, fmt.Errorf("expected POST method, got %s", req.Method)
|
|
||||||
}
|
|
||||||
// FIXME validate the content is the given ExecConfig ?
|
|
||||||
if err := req.ParseForm(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
execConfig := &types.ExecConfig{}
|
|
||||||
if err := json.NewDecoder(req.Body).Decode(execConfig); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if execConfig.User != "user" {
|
|
||||||
return nil, fmt.Errorf("expected an execConfig with User == 'user', got %v", execConfig)
|
|
||||||
}
|
|
||||||
b, err := json.Marshal(types.IDResponse{
|
|
||||||
ID: "exec_id",
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader(b)),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
r, err := client.ContainerExecCreate(context.Background(), "container_id", types.ExecConfig{
|
|
||||||
User: "user",
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if r.ID != "exec_id" {
|
|
||||||
t.Fatalf("expected `exec_id`, got %s", r.ID)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContainerExecStartError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
err := client.ContainerExecStart(context.Background(), "nothing", types.ExecStartCheck{})
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContainerExecStart(t *testing.T) {
|
|
||||||
expectedURL := "/exec/exec_id/start"
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
if err := req.ParseForm(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
execStartCheck := &types.ExecStartCheck{}
|
|
||||||
if err := json.NewDecoder(req.Body).Decode(execStartCheck); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if execStartCheck.Tty || !execStartCheck.Detach {
|
|
||||||
return nil, fmt.Errorf("expected execStartCheck{Detach:true,Tty:false}, got %v", execStartCheck)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte(""))),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
err := client.ContainerExecStart(context.Background(), "exec_id", types.ExecStartCheck{
|
|
||||||
Detach: true,
|
|
||||||
Tty: false,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContainerExecInspectError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
_, err := client.ContainerExecInspect(context.Background(), "nothing")
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContainerExecInspect(t *testing.T) {
|
|
||||||
expectedURL := "/exec/exec_id/json"
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
b, err := json.Marshal(types.ContainerExecInspect{
|
|
||||||
ExecID: "exec_id",
|
|
||||||
ContainerID: "container_id",
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader(b)),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
inspect, err := client.ContainerExecInspect(context.Background(), "exec_id")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if inspect.ExecID != "exec_id" {
|
|
||||||
t.Fatalf("expected ExecID to be `exec_id`, got %s", inspect.ExecID)
|
|
||||||
}
|
|
||||||
if inspect.ContainerID != "container_id" {
|
|
||||||
t.Fatalf("expected ContainerID `container_id`, got %s", inspect.ContainerID)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,50 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestContainerExportError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
_, err := client.ContainerExport(context.Background(), "nothing")
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContainerExport(t *testing.T) {
|
|
||||||
expectedURL := "/containers/container_id/export"
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(r *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(r.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, r.URL)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte("response"))),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
body, err := client.ContainerExport(context.Background(), "container_id")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer body.Close()
|
|
||||||
content, err := ioutil.ReadAll(body)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if string(content) != "response" {
|
|
||||||
t.Fatalf("expected response to contain 'response', got %s", string(content))
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,125 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestContainerInspectError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := client.ContainerInspect(context.Background(), "nothing")
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContainerInspectContainerNotFound(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusNotFound, "Server error")),
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := client.ContainerInspect(context.Background(), "unknown")
|
|
||||||
if err == nil || !IsErrContainerNotFound(err) {
|
|
||||||
t.Fatalf("expected a containerNotFound error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContainerInspect(t *testing.T) {
|
|
||||||
expectedURL := "/containers/container_id/json"
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
content, err := json.Marshal(types.ContainerJSON{
|
|
||||||
ContainerJSONBase: &types.ContainerJSONBase{
|
|
||||||
ID: "container_id",
|
|
||||||
Image: "image",
|
|
||||||
Name: "name",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader(content)),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
r, err := client.ContainerInspect(context.Background(), "container_id")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if r.ID != "container_id" {
|
|
||||||
t.Fatalf("expected `container_id`, got %s", r.ID)
|
|
||||||
}
|
|
||||||
if r.Image != "image" {
|
|
||||||
t.Fatalf("expected `image`, got %s", r.Image)
|
|
||||||
}
|
|
||||||
if r.Name != "name" {
|
|
||||||
t.Fatalf("expected `name`, got %s", r.Name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContainerInspectNode(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
content, err := json.Marshal(types.ContainerJSON{
|
|
||||||
ContainerJSONBase: &types.ContainerJSONBase{
|
|
||||||
ID: "container_id",
|
|
||||||
Image: "image",
|
|
||||||
Name: "name",
|
|
||||||
Node: &types.ContainerNode{
|
|
||||||
ID: "container_node_id",
|
|
||||||
Addr: "container_node",
|
|
||||||
Labels: map[string]string{"foo": "bar"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader(content)),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
r, err := client.ContainerInspect(context.Background(), "container_id")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if r.ID != "container_id" {
|
|
||||||
t.Fatalf("expected `container_id`, got %s", r.ID)
|
|
||||||
}
|
|
||||||
if r.Image != "image" {
|
|
||||||
t.Fatalf("expected `image`, got %s", r.Image)
|
|
||||||
}
|
|
||||||
if r.Name != "name" {
|
|
||||||
t.Fatalf("expected `name`, got %s", r.Name)
|
|
||||||
}
|
|
||||||
if r.Node.ID != "container_node_id" {
|
|
||||||
t.Fatalf("expected `container_node_id`, got %s", r.Node.ID)
|
|
||||||
}
|
|
||||||
if r.Node.Addr != "container_node" {
|
|
||||||
t.Fatalf("expected `container_node`, got %s", r.Node.Addr)
|
|
||||||
}
|
|
||||||
foo, ok := r.Node.Labels["foo"]
|
|
||||||
if foo != "bar" || !ok {
|
|
||||||
t.Fatalf("expected `bar` for label `foo`")
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,46 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestContainerKillError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
err := client.ContainerKill(context.Background(), "nothing", "SIGKILL")
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContainerKill(t *testing.T) {
|
|
||||||
expectedURL := "/containers/container_id/kill"
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
signal := req.URL.Query().Get("signal")
|
|
||||||
if signal != "SIGKILL" {
|
|
||||||
return nil, fmt.Errorf("signal not set in URL query properly. Expected 'SIGKILL', got %s", signal)
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte(""))),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
err := client.ContainerKill(context.Background(), "container_id", "SIGKILL")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,96 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
"github.com/docker/docker/api/types/filters"
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestContainerListError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
_, err := client.ContainerList(context.Background(), types.ContainerListOptions{})
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContainerList(t *testing.T) {
|
|
||||||
expectedURL := "/containers/json"
|
|
||||||
expectedFilters := `{"before":{"container":true},"label":{"label1":true,"label2":true}}`
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
query := req.URL.Query()
|
|
||||||
all := query.Get("all")
|
|
||||||
if all != "1" {
|
|
||||||
return nil, fmt.Errorf("all not set in URL query properly. Expected '1', got %s", all)
|
|
||||||
}
|
|
||||||
limit := query.Get("limit")
|
|
||||||
if limit != "0" {
|
|
||||||
return nil, fmt.Errorf("limit should have not be present in query. Expected '0', got %s", limit)
|
|
||||||
}
|
|
||||||
since := query.Get("since")
|
|
||||||
if since != "container" {
|
|
||||||
return nil, fmt.Errorf("since not set in URL query properly. Expected 'container', got %s", since)
|
|
||||||
}
|
|
||||||
before := query.Get("before")
|
|
||||||
if before != "" {
|
|
||||||
return nil, fmt.Errorf("before should have not be present in query, go %s", before)
|
|
||||||
}
|
|
||||||
size := query.Get("size")
|
|
||||||
if size != "1" {
|
|
||||||
return nil, fmt.Errorf("size not set in URL query properly. Expected '1', got %s", size)
|
|
||||||
}
|
|
||||||
filters := query.Get("filters")
|
|
||||||
if filters != expectedFilters {
|
|
||||||
return nil, fmt.Errorf("expected filters incoherent '%v' with actual filters %v", expectedFilters, filters)
|
|
||||||
}
|
|
||||||
|
|
||||||
b, err := json.Marshal([]types.Container{
|
|
||||||
{
|
|
||||||
ID: "container_id1",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: "container_id2",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader(b)),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
filters := filters.NewArgs()
|
|
||||||
filters.Add("label", "label1")
|
|
||||||
filters.Add("label", "label2")
|
|
||||||
filters.Add("before", "container")
|
|
||||||
containers, err := client.ContainerList(context.Background(), types.ContainerListOptions{
|
|
||||||
Size: true,
|
|
||||||
All: true,
|
|
||||||
Since: "container",
|
|
||||||
Filters: filters,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if len(containers) != 2 {
|
|
||||||
t.Fatalf("expected 2 containers, got %v", containers)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,133 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"log"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestContainerLogsError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
_, err := client.ContainerLogs(context.Background(), "container_id", types.ContainerLogsOptions{})
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
_, err = client.ContainerLogs(context.Background(), "container_id", types.ContainerLogsOptions{
|
|
||||||
Since: "2006-01-02TZ",
|
|
||||||
})
|
|
||||||
if err == nil || !strings.Contains(err.Error(), `parsing time "2006-01-02TZ"`) {
|
|
||||||
t.Fatalf("expected a 'parsing time' error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContainerLogs(t *testing.T) {
|
|
||||||
expectedURL := "/containers/container_id/logs"
|
|
||||||
cases := []struct {
|
|
||||||
options types.ContainerLogsOptions
|
|
||||||
expectedQueryParams map[string]string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"tail": "",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
options: types.ContainerLogsOptions{
|
|
||||||
Tail: "any",
|
|
||||||
},
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"tail": "any",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
options: types.ContainerLogsOptions{
|
|
||||||
ShowStdout: true,
|
|
||||||
ShowStderr: true,
|
|
||||||
Timestamps: true,
|
|
||||||
Details: true,
|
|
||||||
Follow: true,
|
|
||||||
},
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"tail": "",
|
|
||||||
"stdout": "1",
|
|
||||||
"stderr": "1",
|
|
||||||
"timestamps": "1",
|
|
||||||
"details": "1",
|
|
||||||
"follow": "1",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
options: types.ContainerLogsOptions{
|
|
||||||
// An complete invalid date, timestamp or go duration will be
|
|
||||||
// passed as is
|
|
||||||
Since: "invalid but valid",
|
|
||||||
},
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"tail": "",
|
|
||||||
"since": "invalid but valid",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, logCase := range cases {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(r *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(r.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, r.URL)
|
|
||||||
}
|
|
||||||
// Check query parameters
|
|
||||||
query := r.URL.Query()
|
|
||||||
for key, expected := range logCase.expectedQueryParams {
|
|
||||||
actual := query.Get(key)
|
|
||||||
if actual != expected {
|
|
||||||
return nil, fmt.Errorf("%s not set in URL query properly. Expected '%s', got %s", key, expected, actual)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte("response"))),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
body, err := client.ContainerLogs(context.Background(), "container_id", logCase.options)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer body.Close()
|
|
||||||
content, err := ioutil.ReadAll(body)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if string(content) != "response" {
|
|
||||||
t.Fatalf("expected response to contain 'response', got %s", string(content))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ExampleClient_ContainerLogs_withTimeout() {
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
client, _ := NewEnvClient()
|
|
||||||
reader, err := client.ContainerLogs(ctx, "container_id", types.ContainerLogsOptions{})
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = io.Copy(os.Stdout, reader)
|
|
||||||
if err != nil && err != io.EOF {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,41 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestContainerPauseError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
err := client.ContainerPause(context.Background(), "nothing")
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContainerPause(t *testing.T) {
|
|
||||||
expectedURL := "/containers/container_id/pause"
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte(""))),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
err := client.ContainerPause(context.Background(), "container_id")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,124 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
"github.com/docker/docker/api/types/filters"
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestContainersPruneError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
version: "1.25",
|
|
||||||
}
|
|
||||||
|
|
||||||
filters := filters.NewArgs()
|
|
||||||
|
|
||||||
_, err := client.ContainersPrune(context.Background(), filters)
|
|
||||||
assert.EqualError(t, err, "Error response from daemon: Server error")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContainersPrune(t *testing.T) {
|
|
||||||
expectedURL := "/v1.25/containers/prune"
|
|
||||||
|
|
||||||
danglingFilters := filters.NewArgs()
|
|
||||||
danglingFilters.Add("dangling", "true")
|
|
||||||
|
|
||||||
noDanglingFilters := filters.NewArgs()
|
|
||||||
noDanglingFilters.Add("dangling", "false")
|
|
||||||
|
|
||||||
danglingUntilFilters := filters.NewArgs()
|
|
||||||
danglingUntilFilters.Add("dangling", "true")
|
|
||||||
danglingUntilFilters.Add("until", "2016-12-15T14:00")
|
|
||||||
|
|
||||||
labelFilters := filters.NewArgs()
|
|
||||||
labelFilters.Add("dangling", "true")
|
|
||||||
labelFilters.Add("label", "label1=foo")
|
|
||||||
labelFilters.Add("label", "label2!=bar")
|
|
||||||
|
|
||||||
listCases := []struct {
|
|
||||||
filters filters.Args
|
|
||||||
expectedQueryParams map[string]string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
filters: filters.Args{},
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"until": "",
|
|
||||||
"filter": "",
|
|
||||||
"filters": "",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
filters: danglingFilters,
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"until": "",
|
|
||||||
"filter": "",
|
|
||||||
"filters": `{"dangling":{"true":true}}`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
filters: danglingUntilFilters,
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"until": "",
|
|
||||||
"filter": "",
|
|
||||||
"filters": `{"dangling":{"true":true},"until":{"2016-12-15T14:00":true}}`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
filters: noDanglingFilters,
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"until": "",
|
|
||||||
"filter": "",
|
|
||||||
"filters": `{"dangling":{"false":true}}`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
filters: labelFilters,
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"until": "",
|
|
||||||
"filter": "",
|
|
||||||
"filters": `{"dangling":{"true":true},"label":{"label1=foo":true,"label2!=bar":true}}`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, listCase := range listCases {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
query := req.URL.Query()
|
|
||||||
for key, expected := range listCase.expectedQueryParams {
|
|
||||||
actual := query.Get(key)
|
|
||||||
assert.Equal(t, expected, actual)
|
|
||||||
}
|
|
||||||
content, err := json.Marshal(types.ContainersPruneReport{
|
|
||||||
ContainersDeleted: []string{"container_id1", "container_id2"},
|
|
||||||
SpaceReclaimed: 9999,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader(content)),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
version: "1.25",
|
|
||||||
}
|
|
||||||
|
|
||||||
report, err := client.ContainersPrune(context.Background(), listCase.filters)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Len(t, report.ContainersDeleted, 2)
|
|
||||||
assert.Equal(t, uint64(9999), report.SpaceReclaimed)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,59 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestContainerRemoveError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
err := client.ContainerRemove(context.Background(), "container_id", types.ContainerRemoveOptions{})
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContainerRemove(t *testing.T) {
|
|
||||||
expectedURL := "/containers/container_id"
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
query := req.URL.Query()
|
|
||||||
volume := query.Get("v")
|
|
||||||
if volume != "1" {
|
|
||||||
return nil, fmt.Errorf("v (volume) not set in URL query properly. Expected '1', got %s", volume)
|
|
||||||
}
|
|
||||||
force := query.Get("force")
|
|
||||||
if force != "1" {
|
|
||||||
return nil, fmt.Errorf("force not set in URL query properly. Expected '1', got %s", force)
|
|
||||||
}
|
|
||||||
link := query.Get("link")
|
|
||||||
if link != "" {
|
|
||||||
return nil, fmt.Errorf("link should have not be present in query, go %s", link)
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte(""))),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
err := client.ContainerRemove(context.Background(), "container_id", types.ContainerRemoveOptions{
|
|
||||||
RemoveVolumes: true,
|
|
||||||
Force: true,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,46 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestContainerRenameError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
err := client.ContainerRename(context.Background(), "nothing", "newNothing")
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContainerRename(t *testing.T) {
|
|
||||||
expectedURL := "/containers/container_id/rename"
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
name := req.URL.Query().Get("name")
|
|
||||||
if name != "newName" {
|
|
||||||
return nil, fmt.Errorf("name not set in URL query properly. Expected 'newName', got %s", name)
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte(""))),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
err := client.ContainerRename(context.Background(), "container_id", "newName")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,82 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestContainerResizeError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
err := client.ContainerResize(context.Background(), "container_id", types.ResizeOptions{})
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContainerExecResizeError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
err := client.ContainerExecResize(context.Background(), "exec_id", types.ResizeOptions{})
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContainerResize(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(resizeTransport("/containers/container_id/resize")),
|
|
||||||
}
|
|
||||||
|
|
||||||
err := client.ContainerResize(context.Background(), "container_id", types.ResizeOptions{
|
|
||||||
Height: 500,
|
|
||||||
Width: 600,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContainerExecResize(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(resizeTransport("/exec/exec_id/resize")),
|
|
||||||
}
|
|
||||||
|
|
||||||
err := client.ContainerExecResize(context.Background(), "exec_id", types.ResizeOptions{
|
|
||||||
Height: 500,
|
|
||||||
Width: 600,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func resizeTransport(expectedURL string) func(req *http.Request) (*http.Response, error) {
|
|
||||||
return func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
query := req.URL.Query()
|
|
||||||
h := query.Get("h")
|
|
||||||
if h != "500" {
|
|
||||||
return nil, fmt.Errorf("h not set in URL query properly. Expected '500', got %s", h)
|
|
||||||
}
|
|
||||||
w := query.Get("w")
|
|
||||||
if w != "600" {
|
|
||||||
return nil, fmt.Errorf("w not set in URL query properly. Expected '600', got %s", w)
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte(""))),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,48 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestContainerRestartError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
timeout := 0 * time.Second
|
|
||||||
err := client.ContainerRestart(context.Background(), "nothing", &timeout)
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContainerRestart(t *testing.T) {
|
|
||||||
expectedURL := "/containers/container_id/restart"
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
t := req.URL.Query().Get("t")
|
|
||||||
if t != "100" {
|
|
||||||
return nil, fmt.Errorf("t (timeout) not set in URL query properly. Expected '100', got %s", t)
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte(""))),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
timeout := 100 * time.Second
|
|
||||||
err := client.ContainerRestart(context.Background(), "container_id", &timeout)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,58 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestContainerStartError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
err := client.ContainerStart(context.Background(), "nothing", types.ContainerStartOptions{})
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContainerStart(t *testing.T) {
|
|
||||||
expectedURL := "/containers/container_id/start"
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
// we're not expecting any payload, but if one is supplied, check it is valid.
|
|
||||||
if req.Header.Get("Content-Type") == "application/json" {
|
|
||||||
var startConfig interface{}
|
|
||||||
if err := json.NewDecoder(req.Body).Decode(&startConfig); err != nil {
|
|
||||||
return nil, fmt.Errorf("Unable to parse json: %s", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
checkpoint := req.URL.Query().Get("checkpoint")
|
|
||||||
if checkpoint != "checkpoint_id" {
|
|
||||||
return nil, fmt.Errorf("checkpoint not set in URL query properly. Expected 'checkpoint_id', got %s", checkpoint)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte(""))),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
err := client.ContainerStart(context.Background(), "container_id", types.ContainerStartOptions{CheckpointID: "checkpoint_id"})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,70 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestContainerStatsError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
_, err := client.ContainerStats(context.Background(), "nothing", false)
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContainerStats(t *testing.T) {
|
|
||||||
expectedURL := "/containers/container_id/stats"
|
|
||||||
cases := []struct {
|
|
||||||
stream bool
|
|
||||||
expectedStream string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
expectedStream: "0",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
stream: true,
|
|
||||||
expectedStream: "1",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, c := range cases {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(r *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(r.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, r.URL)
|
|
||||||
}
|
|
||||||
|
|
||||||
query := r.URL.Query()
|
|
||||||
stream := query.Get("stream")
|
|
||||||
if stream != c.expectedStream {
|
|
||||||
return nil, fmt.Errorf("stream not set in URL query properly. Expected '%s', got %s", c.expectedStream, stream)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte("response"))),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
resp, err := client.ContainerStats(context.Background(), "container_id", c.stream)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
content, err := ioutil.ReadAll(resp.Body)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if string(content) != "response" {
|
|
||||||
t.Fatalf("expected response to contain 'response', got %s", string(content))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,48 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestContainerStopError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
timeout := 0 * time.Second
|
|
||||||
err := client.ContainerStop(context.Background(), "nothing", &timeout)
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContainerStop(t *testing.T) {
|
|
||||||
expectedURL := "/containers/container_id/stop"
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
t := req.URL.Query().Get("t")
|
|
||||||
if t != "100" {
|
|
||||||
return nil, fmt.Errorf("t (timeout) not set in URL query properly. Expected '100', got %s", t)
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte(""))),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
timeout := 100 * time.Second
|
|
||||||
err := client.ContainerStop(context.Background(), "container_id", &timeout)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,74 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"reflect"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types/container"
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestContainerTopError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
_, err := client.ContainerTop(context.Background(), "nothing", []string{})
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContainerTop(t *testing.T) {
|
|
||||||
expectedURL := "/containers/container_id/top"
|
|
||||||
expectedProcesses := [][]string{
|
|
||||||
{"p1", "p2"},
|
|
||||||
{"p3"},
|
|
||||||
}
|
|
||||||
expectedTitles := []string{"title1", "title2"}
|
|
||||||
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
query := req.URL.Query()
|
|
||||||
args := query.Get("ps_args")
|
|
||||||
if args != "arg1 arg2" {
|
|
||||||
return nil, fmt.Errorf("args not set in URL query properly. Expected 'arg1 arg2', got %v", args)
|
|
||||||
}
|
|
||||||
|
|
||||||
b, err := json.Marshal(container.ContainerTopOKBody{
|
|
||||||
Processes: [][]string{
|
|
||||||
{"p1", "p2"},
|
|
||||||
{"p3"},
|
|
||||||
},
|
|
||||||
Titles: []string{"title1", "title2"},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader(b)),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
processList, err := client.ContainerTop(context.Background(), "container_id", []string{"arg1", "arg2"})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(expectedProcesses, processList.Processes) {
|
|
||||||
t.Fatalf("Processes: expected %v, got %v", expectedProcesses, processList.Processes)
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(expectedTitles, processList.Titles) {
|
|
||||||
t.Fatalf("Titles: expected %v, got %v", expectedTitles, processList.Titles)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,41 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestContainerUnpauseError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
err := client.ContainerUnpause(context.Background(), "nothing")
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContainerUnpause(t *testing.T) {
|
|
||||||
expectedURL := "/containers/container_id/unpause"
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte(""))),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
err := client.ContainerUnpause(context.Background(), "container_id")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,58 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types/container"
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestContainerUpdateError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
_, err := client.ContainerUpdate(context.Background(), "nothing", container.UpdateConfig{})
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContainerUpdate(t *testing.T) {
|
|
||||||
expectedURL := "/containers/container_id/update"
|
|
||||||
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
|
|
||||||
b, err := json.Marshal(container.ContainerUpdateOKBody{})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader(b)),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := client.ContainerUpdate(context.Background(), "container_id", container.UpdateConfig{
|
|
||||||
Resources: container.Resources{
|
|
||||||
CPUPeriod: 1,
|
|
||||||
},
|
|
||||||
RestartPolicy: container.RestartPolicy{
|
|
||||||
Name: "always",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,70 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"log"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types/container"
|
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestContainerWaitError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
code, err := client.ContainerWait(context.Background(), "nothing")
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
if code != -1 {
|
|
||||||
t.Fatalf("expected a status code equal to '-1', got %d", code)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContainerWait(t *testing.T) {
|
|
||||||
expectedURL := "/containers/container_id/wait"
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
b, err := json.Marshal(container.ContainerWaitOKBody{
|
|
||||||
StatusCode: 15,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader(b)),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
code, err := client.ContainerWait(context.Background(), "container_id")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if code != 15 {
|
|
||||||
t.Fatalf("expected a status code equal to '15', got %d", code)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ExampleClient_ContainerWait_withTimeout() {
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
client, _ := NewEnvClient()
|
|
||||||
_, err := client.ContainerWait(ctx, "container_id")
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,165 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
"github.com/docker/docker/api/types/events"
|
|
||||||
"github.com/docker/docker/api/types/filters"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestEventsErrorInOptions(t *testing.T) {
|
|
||||||
errorCases := []struct {
|
|
||||||
options types.EventsOptions
|
|
||||||
expectedError string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
options: types.EventsOptions{
|
|
||||||
Since: "2006-01-02TZ",
|
|
||||||
},
|
|
||||||
expectedError: `parsing time "2006-01-02TZ"`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
options: types.EventsOptions{
|
|
||||||
Until: "2006-01-02TZ",
|
|
||||||
},
|
|
||||||
expectedError: `parsing time "2006-01-02TZ"`,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, e := range errorCases {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
_, errs := client.Events(context.Background(), e.options)
|
|
||||||
err := <-errs
|
|
||||||
if err == nil || !strings.Contains(err.Error(), e.expectedError) {
|
|
||||||
t.Fatalf("expected an error %q, got %v", e.expectedError, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestEventsErrorFromServer(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
_, errs := client.Events(context.Background(), types.EventsOptions{})
|
|
||||||
err := <-errs
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestEvents(t *testing.T) {
|
|
||||||
|
|
||||||
expectedURL := "/events"
|
|
||||||
|
|
||||||
filters := filters.NewArgs()
|
|
||||||
filters.Add("type", events.ContainerEventType)
|
|
||||||
expectedFiltersJSON := fmt.Sprintf(`{"type":{"%s":true}}`, events.ContainerEventType)
|
|
||||||
|
|
||||||
eventsCases := []struct {
|
|
||||||
options types.EventsOptions
|
|
||||||
events []events.Message
|
|
||||||
expectedEvents map[string]bool
|
|
||||||
expectedQueryParams map[string]string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
options: types.EventsOptions{
|
|
||||||
Filters: filters,
|
|
||||||
},
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"filters": expectedFiltersJSON,
|
|
||||||
},
|
|
||||||
events: []events.Message{},
|
|
||||||
expectedEvents: make(map[string]bool),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
options: types.EventsOptions{
|
|
||||||
Filters: filters,
|
|
||||||
},
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"filters": expectedFiltersJSON,
|
|
||||||
},
|
|
||||||
events: []events.Message{
|
|
||||||
{
|
|
||||||
Type: "container",
|
|
||||||
ID: "1",
|
|
||||||
Action: "create",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Type: "container",
|
|
||||||
ID: "2",
|
|
||||||
Action: "die",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Type: "container",
|
|
||||||
ID: "3",
|
|
||||||
Action: "create",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
expectedEvents: map[string]bool{
|
|
||||||
"1": true,
|
|
||||||
"2": true,
|
|
||||||
"3": true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, eventsCase := range eventsCases {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
query := req.URL.Query()
|
|
||||||
|
|
||||||
for key, expected := range eventsCase.expectedQueryParams {
|
|
||||||
actual := query.Get(key)
|
|
||||||
if actual != expected {
|
|
||||||
return nil, fmt.Errorf("%s not set in URL query properly. Expected '%s', got %s", key, expected, actual)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer := new(bytes.Buffer)
|
|
||||||
|
|
||||||
for _, e := range eventsCase.events {
|
|
||||||
b, _ := json.Marshal(e)
|
|
||||||
buffer.Write(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(buffer),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
messages, errs := client.Events(context.Background(), eventsCase.options)
|
|
||||||
|
|
||||||
loop:
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case err := <-errs:
|
|
||||||
if err != nil && err != io.EOF {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
break loop
|
|
||||||
case e := <-messages:
|
|
||||||
_, ok := eventsCase.expectedEvents[e.ID]
|
|
||||||
if !ok {
|
|
||||||
t.Fatalf("event received not expected with action %s & id %s", e.Action, e.ID)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,233 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"reflect"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
"github.com/docker/docker/api/types/container"
|
|
||||||
"github.com/docker/go-units"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestImageBuildError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
_, err := client.ImageBuild(context.Background(), nil, types.ImageBuildOptions{})
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestImageBuild(t *testing.T) {
|
|
||||||
v1 := "value1"
|
|
||||||
v2 := "value2"
|
|
||||||
emptyRegistryConfig := "bnVsbA=="
|
|
||||||
buildCases := []struct {
|
|
||||||
buildOptions types.ImageBuildOptions
|
|
||||||
expectedQueryParams map[string]string
|
|
||||||
expectedTags []string
|
|
||||||
expectedRegistryConfig string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
buildOptions: types.ImageBuildOptions{
|
|
||||||
SuppressOutput: true,
|
|
||||||
NoCache: true,
|
|
||||||
Remove: true,
|
|
||||||
ForceRemove: true,
|
|
||||||
PullParent: true,
|
|
||||||
},
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"q": "1",
|
|
||||||
"nocache": "1",
|
|
||||||
"rm": "1",
|
|
||||||
"forcerm": "1",
|
|
||||||
"pull": "1",
|
|
||||||
},
|
|
||||||
expectedTags: []string{},
|
|
||||||
expectedRegistryConfig: emptyRegistryConfig,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
buildOptions: types.ImageBuildOptions{
|
|
||||||
SuppressOutput: false,
|
|
||||||
NoCache: false,
|
|
||||||
Remove: false,
|
|
||||||
ForceRemove: false,
|
|
||||||
PullParent: false,
|
|
||||||
},
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"q": "",
|
|
||||||
"nocache": "",
|
|
||||||
"rm": "0",
|
|
||||||
"forcerm": "",
|
|
||||||
"pull": "",
|
|
||||||
},
|
|
||||||
expectedTags: []string{},
|
|
||||||
expectedRegistryConfig: emptyRegistryConfig,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
buildOptions: types.ImageBuildOptions{
|
|
||||||
RemoteContext: "remoteContext",
|
|
||||||
Isolation: container.Isolation("isolation"),
|
|
||||||
CPUSetCPUs: "2",
|
|
||||||
CPUSetMems: "12",
|
|
||||||
CPUShares: 20,
|
|
||||||
CPUQuota: 10,
|
|
||||||
CPUPeriod: 30,
|
|
||||||
Memory: 256,
|
|
||||||
MemorySwap: 512,
|
|
||||||
ShmSize: 10,
|
|
||||||
CgroupParent: "cgroup_parent",
|
|
||||||
Dockerfile: "Dockerfile",
|
|
||||||
},
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"remote": "remoteContext",
|
|
||||||
"isolation": "isolation",
|
|
||||||
"cpusetcpus": "2",
|
|
||||||
"cpusetmems": "12",
|
|
||||||
"cpushares": "20",
|
|
||||||
"cpuquota": "10",
|
|
||||||
"cpuperiod": "30",
|
|
||||||
"memory": "256",
|
|
||||||
"memswap": "512",
|
|
||||||
"shmsize": "10",
|
|
||||||
"cgroupparent": "cgroup_parent",
|
|
||||||
"dockerfile": "Dockerfile",
|
|
||||||
"rm": "0",
|
|
||||||
},
|
|
||||||
expectedTags: []string{},
|
|
||||||
expectedRegistryConfig: emptyRegistryConfig,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
buildOptions: types.ImageBuildOptions{
|
|
||||||
BuildArgs: map[string]*string{
|
|
||||||
"ARG1": &v1,
|
|
||||||
"ARG2": &v2,
|
|
||||||
"ARG3": nil,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"buildargs": `{"ARG1":"value1","ARG2":"value2","ARG3":null}`,
|
|
||||||
"rm": "0",
|
|
||||||
},
|
|
||||||
expectedTags: []string{},
|
|
||||||
expectedRegistryConfig: emptyRegistryConfig,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
buildOptions: types.ImageBuildOptions{
|
|
||||||
Ulimits: []*units.Ulimit{
|
|
||||||
{
|
|
||||||
Name: "nproc",
|
|
||||||
Hard: 65557,
|
|
||||||
Soft: 65557,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "nofile",
|
|
||||||
Hard: 20000,
|
|
||||||
Soft: 40000,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"ulimits": `[{"Name":"nproc","Hard":65557,"Soft":65557},{"Name":"nofile","Hard":20000,"Soft":40000}]`,
|
|
||||||
"rm": "0",
|
|
||||||
},
|
|
||||||
expectedTags: []string{},
|
|
||||||
expectedRegistryConfig: emptyRegistryConfig,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
buildOptions: types.ImageBuildOptions{
|
|
||||||
AuthConfigs: map[string]types.AuthConfig{
|
|
||||||
"https://index.docker.io/v1/": {
|
|
||||||
Auth: "dG90bwo=",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"rm": "0",
|
|
||||||
},
|
|
||||||
expectedTags: []string{},
|
|
||||||
expectedRegistryConfig: "eyJodHRwczovL2luZGV4LmRvY2tlci5pby92MS8iOnsiYXV0aCI6ImRHOTBid289In19",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, buildCase := range buildCases {
|
|
||||||
expectedURL := "/build"
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(r *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(r.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, r.URL)
|
|
||||||
}
|
|
||||||
// Check request headers
|
|
||||||
registryConfig := r.Header.Get("X-Registry-Config")
|
|
||||||
if registryConfig != buildCase.expectedRegistryConfig {
|
|
||||||
return nil, fmt.Errorf("X-Registry-Config header not properly set in the request. Expected '%s', got %s", buildCase.expectedRegistryConfig, registryConfig)
|
|
||||||
}
|
|
||||||
contentType := r.Header.Get("Content-Type")
|
|
||||||
if contentType != "application/x-tar" {
|
|
||||||
return nil, fmt.Errorf("Content-type header not properly set in the request. Expected 'application/x-tar', got %s", contentType)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check query parameters
|
|
||||||
query := r.URL.Query()
|
|
||||||
for key, expected := range buildCase.expectedQueryParams {
|
|
||||||
actual := query.Get(key)
|
|
||||||
if actual != expected {
|
|
||||||
return nil, fmt.Errorf("%s not set in URL query properly. Expected '%s', got %s", key, expected, actual)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check tags
|
|
||||||
if len(buildCase.expectedTags) > 0 {
|
|
||||||
tags := query["t"]
|
|
||||||
if !reflect.DeepEqual(tags, buildCase.expectedTags) {
|
|
||||||
return nil, fmt.Errorf("t (tags) not set in URL query properly. Expected '%s', got %s", buildCase.expectedTags, tags)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
headers := http.Header{}
|
|
||||||
headers.Add("Server", "Docker/v1.23 (MyOS)")
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte("body"))),
|
|
||||||
Header: headers,
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
buildResponse, err := client.ImageBuild(context.Background(), nil, buildCase.buildOptions)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if buildResponse.OSType != "MyOS" {
|
|
||||||
t.Fatalf("expected OSType to be 'MyOS', got %s", buildResponse.OSType)
|
|
||||||
}
|
|
||||||
response, err := ioutil.ReadAll(buildResponse.Body)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
buildResponse.Body.Close()
|
|
||||||
if string(response) != "body" {
|
|
||||||
t.Fatalf("expected Body to contain 'body' string, got %s", response)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetDockerOS(t *testing.T) {
|
|
||||||
cases := map[string]string{
|
|
||||||
"Docker/v1.22 (linux)": "linux",
|
|
||||||
"Docker/v1.22 (windows)": "windows",
|
|
||||||
"Foo/v1.22 (bar)": "",
|
|
||||||
}
|
|
||||||
for header, os := range cases {
|
|
||||||
g := getDockerOS(header)
|
|
||||||
if g != os {
|
|
||||||
t.Fatalf("Expected %s, got %s", os, g)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,76 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestImageCreateError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
_, err := client.ImageCreate(context.Background(), "reference", types.ImageCreateOptions{})
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestImageCreate(t *testing.T) {
|
|
||||||
expectedURL := "/images/create"
|
|
||||||
expectedImage := "test:5000/my_image"
|
|
||||||
expectedTag := "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
|
|
||||||
expectedReference := fmt.Sprintf("%s@%s", expectedImage, expectedTag)
|
|
||||||
expectedRegistryAuth := "eyJodHRwczovL2luZGV4LmRvY2tlci5pby92MS8iOnsiYXV0aCI6ImRHOTBid289IiwiZW1haWwiOiJqb2huQGRvZS5jb20ifX0="
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(r *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(r.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, r.URL)
|
|
||||||
}
|
|
||||||
registryAuth := r.Header.Get("X-Registry-Auth")
|
|
||||||
if registryAuth != expectedRegistryAuth {
|
|
||||||
return nil, fmt.Errorf("X-Registry-Auth header not properly set in the request. Expected '%s', got %s", expectedRegistryAuth, registryAuth)
|
|
||||||
}
|
|
||||||
|
|
||||||
query := r.URL.Query()
|
|
||||||
fromImage := query.Get("fromImage")
|
|
||||||
if fromImage != expectedImage {
|
|
||||||
return nil, fmt.Errorf("fromImage not set in URL query properly. Expected '%s', got %s", expectedImage, fromImage)
|
|
||||||
}
|
|
||||||
|
|
||||||
tag := query.Get("tag")
|
|
||||||
if tag != expectedTag {
|
|
||||||
return nil, fmt.Errorf("tag not set in URL query properly. Expected '%s', got %s", expectedTag, tag)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte("body"))),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
createResponse, err := client.ImageCreate(context.Background(), expectedReference, types.ImageCreateOptions{
|
|
||||||
RegistryAuth: expectedRegistryAuth,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
response, err := ioutil.ReadAll(createResponse)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if err = createResponse.Close(); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if string(response) != "body" {
|
|
||||||
t.Fatalf("expected Body to contain 'body' string, got %s", response)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,60 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types/image"
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestImageHistoryError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
_, err := client.ImageHistory(context.Background(), "nothing")
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestImageHistory(t *testing.T) {
|
|
||||||
expectedURL := "/images/image_id/history"
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(r *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(r.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, r.URL)
|
|
||||||
}
|
|
||||||
b, err := json.Marshal([]image.HistoryResponseItem{
|
|
||||||
{
|
|
||||||
ID: "image_id1",
|
|
||||||
Tags: []string{"tag1", "tag2"},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: "image_id2",
|
|
||||||
Tags: []string{"tag1", "tag2"},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader(b)),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
imageHistories, err := client.ImageHistory(context.Background(), "image_id")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if len(imageHistories) != 2 {
|
|
||||||
t.Fatalf("expected 2 containers, got %v", imageHistories)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,81 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"reflect"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestImageImportError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
_, err := client.ImageImport(context.Background(), types.ImageImportSource{}, "image:tag", types.ImageImportOptions{})
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestImageImport(t *testing.T) {
|
|
||||||
expectedURL := "/images/create"
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(r *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(r.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, r.URL)
|
|
||||||
}
|
|
||||||
query := r.URL.Query()
|
|
||||||
fromSrc := query.Get("fromSrc")
|
|
||||||
if fromSrc != "image_source" {
|
|
||||||
return nil, fmt.Errorf("fromSrc not set in URL query properly. Expected 'image_source', got %s", fromSrc)
|
|
||||||
}
|
|
||||||
repo := query.Get("repo")
|
|
||||||
if repo != "repository_name:imported" {
|
|
||||||
return nil, fmt.Errorf("repo not set in URL query properly. Expected 'repository_name:imported', got %s", repo)
|
|
||||||
}
|
|
||||||
tag := query.Get("tag")
|
|
||||||
if tag != "imported" {
|
|
||||||
return nil, fmt.Errorf("tag not set in URL query properly. Expected 'imported', got %s", tag)
|
|
||||||
}
|
|
||||||
message := query.Get("message")
|
|
||||||
if message != "A message" {
|
|
||||||
return nil, fmt.Errorf("message not set in URL query properly. Expected 'A message', got %s", message)
|
|
||||||
}
|
|
||||||
changes := query["changes"]
|
|
||||||
expectedChanges := []string{"change1", "change2"}
|
|
||||||
if !reflect.DeepEqual(expectedChanges, changes) {
|
|
||||||
return nil, fmt.Errorf("changes not set in URL query properly. Expected %v, got %v", expectedChanges, changes)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte("response"))),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
importResponse, err := client.ImageImport(context.Background(), types.ImageImportSource{
|
|
||||||
Source: strings.NewReader("source"),
|
|
||||||
SourceName: "image_source",
|
|
||||||
}, "repository_name:imported", types.ImageImportOptions{
|
|
||||||
Tag: "imported",
|
|
||||||
Message: "A message",
|
|
||||||
Changes: []string{"change1", "change2"},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
response, err := ioutil.ReadAll(importResponse)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
importResponse.Close()
|
|
||||||
if string(response) != "response" {
|
|
||||||
t.Fatalf("expected response to contain 'response', got %s", string(response))
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,71 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"reflect"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestImageInspectError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
|
|
||||||
_, _, err := client.ImageInspectWithRaw(context.Background(), "nothing")
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestImageInspectImageNotFound(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusNotFound, "Server error")),
|
|
||||||
}
|
|
||||||
|
|
||||||
_, _, err := client.ImageInspectWithRaw(context.Background(), "unknown")
|
|
||||||
if err == nil || !IsErrImageNotFound(err) {
|
|
||||||
t.Fatalf("expected an imageNotFound error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestImageInspect(t *testing.T) {
|
|
||||||
expectedURL := "/images/image_id/json"
|
|
||||||
expectedTags := []string{"tag1", "tag2"}
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
content, err := json.Marshal(types.ImageInspect{
|
|
||||||
ID: "image_id",
|
|
||||||
RepoTags: expectedTags,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader(content)),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
imageInspect, _, err := client.ImageInspectWithRaw(context.Background(), "image_id")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if imageInspect.ID != "image_id" {
|
|
||||||
t.Fatalf("expected `image_id`, got %s", imageInspect.ID)
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(imageInspect.RepoTags, expectedTags) {
|
|
||||||
t.Fatalf("expected `%v`, got %v", expectedTags, imageInspect.RepoTags)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,159 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
"github.com/docker/docker/api/types/filters"
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestImageListError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := client.ImageList(context.Background(), types.ImageListOptions{})
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestImageList(t *testing.T) {
|
|
||||||
expectedURL := "/images/json"
|
|
||||||
|
|
||||||
noDanglingfilters := filters.NewArgs()
|
|
||||||
noDanglingfilters.Add("dangling", "false")
|
|
||||||
|
|
||||||
filters := filters.NewArgs()
|
|
||||||
filters.Add("label", "label1")
|
|
||||||
filters.Add("label", "label2")
|
|
||||||
filters.Add("dangling", "true")
|
|
||||||
|
|
||||||
listCases := []struct {
|
|
||||||
options types.ImageListOptions
|
|
||||||
expectedQueryParams map[string]string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
options: types.ImageListOptions{},
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"all": "",
|
|
||||||
"filter": "",
|
|
||||||
"filters": "",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
options: types.ImageListOptions{
|
|
||||||
Filters: filters,
|
|
||||||
},
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"all": "",
|
|
||||||
"filter": "",
|
|
||||||
"filters": `{"dangling":{"true":true},"label":{"label1":true,"label2":true}}`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
options: types.ImageListOptions{
|
|
||||||
Filters: noDanglingfilters,
|
|
||||||
},
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"all": "",
|
|
||||||
"filter": "",
|
|
||||||
"filters": `{"dangling":{"false":true}}`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, listCase := range listCases {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
query := req.URL.Query()
|
|
||||||
for key, expected := range listCase.expectedQueryParams {
|
|
||||||
actual := query.Get(key)
|
|
||||||
if actual != expected {
|
|
||||||
return nil, fmt.Errorf("%s not set in URL query properly. Expected '%s', got %s", key, expected, actual)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
content, err := json.Marshal([]types.ImageSummary{
|
|
||||||
{
|
|
||||||
ID: "image_id2",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: "image_id2",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader(content)),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
images, err := client.ImageList(context.Background(), listCase.options)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if len(images) != 2 {
|
|
||||||
t.Fatalf("expected 2 images, got %v", images)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestImageListApiBefore125(t *testing.T) {
|
|
||||||
expectedFilter := "image:tag"
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
query := req.URL.Query()
|
|
||||||
actualFilter := query.Get("filter")
|
|
||||||
if actualFilter != expectedFilter {
|
|
||||||
return nil, fmt.Errorf("filter not set in URL query properly. Expected '%s', got %s", expectedFilter, actualFilter)
|
|
||||||
}
|
|
||||||
actualFilters := query.Get("filters")
|
|
||||||
if actualFilters != "" {
|
|
||||||
return nil, fmt.Errorf("filters should have not been present, were with value: %s", actualFilters)
|
|
||||||
}
|
|
||||||
content, err := json.Marshal([]types.ImageSummary{
|
|
||||||
{
|
|
||||||
ID: "image_id2",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: "image_id2",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader(content)),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
version: "1.24",
|
|
||||||
}
|
|
||||||
|
|
||||||
filters := filters.NewArgs()
|
|
||||||
filters.Add("reference", "image:tag")
|
|
||||||
|
|
||||||
options := types.ImageListOptions{
|
|
||||||
Filters: filters,
|
|
||||||
}
|
|
||||||
|
|
||||||
images, err := client.ImageList(context.Background(), options)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if len(images) != 2 {
|
|
||||||
t.Fatalf("expected 2 images, got %v", images)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,95 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestImageLoadError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := client.ImageLoad(context.Background(), nil, true)
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestImageLoad(t *testing.T) {
|
|
||||||
expectedURL := "/images/load"
|
|
||||||
expectedInput := "inputBody"
|
|
||||||
expectedOutput := "outputBody"
|
|
||||||
loadCases := []struct {
|
|
||||||
quiet bool
|
|
||||||
responseContentType string
|
|
||||||
expectedResponseJSON bool
|
|
||||||
expectedQueryParams map[string]string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
quiet: false,
|
|
||||||
responseContentType: "text/plain",
|
|
||||||
expectedResponseJSON: false,
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"quiet": "0",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
quiet: true,
|
|
||||||
responseContentType: "application/json",
|
|
||||||
expectedResponseJSON: true,
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"quiet": "1",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, loadCase := range loadCases {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
contentType := req.Header.Get("Content-Type")
|
|
||||||
if contentType != "application/x-tar" {
|
|
||||||
return nil, fmt.Errorf("content-type not set in URL headers properly. Expected 'application/x-tar', got %s", contentType)
|
|
||||||
}
|
|
||||||
query := req.URL.Query()
|
|
||||||
for key, expected := range loadCase.expectedQueryParams {
|
|
||||||
actual := query.Get(key)
|
|
||||||
if actual != expected {
|
|
||||||
return nil, fmt.Errorf("%s not set in URL query properly. Expected '%s', got %s", key, expected, actual)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
headers := http.Header{}
|
|
||||||
headers.Add("Content-Type", loadCase.responseContentType)
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte(expectedOutput))),
|
|
||||||
Header: headers,
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
input := bytes.NewReader([]byte(expectedInput))
|
|
||||||
imageLoadResponse, err := client.ImageLoad(context.Background(), input, loadCase.quiet)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if imageLoadResponse.JSON != loadCase.expectedResponseJSON {
|
|
||||||
t.Fatalf("expected a JSON response, was not.")
|
|
||||||
}
|
|
||||||
body, err := ioutil.ReadAll(imageLoadResponse.Body)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if string(body) != expectedOutput {
|
|
||||||
t.Fatalf("expected %s, got %s", expectedOutput, string(body))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,119 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
"github.com/docker/docker/api/types/filters"
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestImagesPruneError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
version: "1.25",
|
|
||||||
}
|
|
||||||
|
|
||||||
filters := filters.NewArgs()
|
|
||||||
|
|
||||||
_, err := client.ImagesPrune(context.Background(), filters)
|
|
||||||
assert.EqualError(t, err, "Error response from daemon: Server error")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestImagesPrune(t *testing.T) {
|
|
||||||
expectedURL := "/v1.25/images/prune"
|
|
||||||
|
|
||||||
danglingFilters := filters.NewArgs()
|
|
||||||
danglingFilters.Add("dangling", "true")
|
|
||||||
|
|
||||||
noDanglingFilters := filters.NewArgs()
|
|
||||||
noDanglingFilters.Add("dangling", "false")
|
|
||||||
|
|
||||||
labelFilters := filters.NewArgs()
|
|
||||||
labelFilters.Add("dangling", "true")
|
|
||||||
labelFilters.Add("label", "label1=foo")
|
|
||||||
labelFilters.Add("label", "label2!=bar")
|
|
||||||
|
|
||||||
listCases := []struct {
|
|
||||||
filters filters.Args
|
|
||||||
expectedQueryParams map[string]string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
filters: filters.Args{},
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"until": "",
|
|
||||||
"filter": "",
|
|
||||||
"filters": "",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
filters: danglingFilters,
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"until": "",
|
|
||||||
"filter": "",
|
|
||||||
"filters": `{"dangling":{"true":true}}`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
filters: noDanglingFilters,
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"until": "",
|
|
||||||
"filter": "",
|
|
||||||
"filters": `{"dangling":{"false":true}}`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
filters: labelFilters,
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"until": "",
|
|
||||||
"filter": "",
|
|
||||||
"filters": `{"dangling":{"true":true},"label":{"label1=foo":true,"label2!=bar":true}}`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, listCase := range listCases {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
query := req.URL.Query()
|
|
||||||
for key, expected := range listCase.expectedQueryParams {
|
|
||||||
actual := query.Get(key)
|
|
||||||
assert.Equal(t, expected, actual)
|
|
||||||
}
|
|
||||||
content, err := json.Marshal(types.ImagesPruneReport{
|
|
||||||
ImagesDeleted: []types.ImageDeleteResponseItem{
|
|
||||||
{
|
|
||||||
Deleted: "image_id1",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Deleted: "image_id2",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
SpaceReclaimed: 9999,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader(content)),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
version: "1.25",
|
|
||||||
}
|
|
||||||
|
|
||||||
report, err := client.ImagesPrune(context.Background(), listCase.filters)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Len(t, report.ImagesDeleted, 2)
|
|
||||||
assert.Equal(t, uint64(9999), report.SpaceReclaimed)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,199 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestImagePullReferenceParseError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
return nil, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
// An empty reference is an invalid reference
|
|
||||||
_, err := client.ImagePull(context.Background(), "", types.ImagePullOptions{})
|
|
||||||
if err == nil || !strings.Contains(err.Error(), "invalid reference format") {
|
|
||||||
t.Fatalf("expected an error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestImagePullAnyError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
_, err := client.ImagePull(context.Background(), "myimage", types.ImagePullOptions{})
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestImagePullStatusUnauthorizedError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusUnauthorized, "Unauthorized error")),
|
|
||||||
}
|
|
||||||
_, err := client.ImagePull(context.Background(), "myimage", types.ImagePullOptions{})
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Unauthorized error" {
|
|
||||||
t.Fatalf("expected an Unauthorized Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestImagePullWithUnauthorizedErrorAndPrivilegeFuncError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusUnauthorized, "Unauthorized error")),
|
|
||||||
}
|
|
||||||
privilegeFunc := func() (string, error) {
|
|
||||||
return "", fmt.Errorf("Error requesting privilege")
|
|
||||||
}
|
|
||||||
_, err := client.ImagePull(context.Background(), "myimage", types.ImagePullOptions{
|
|
||||||
PrivilegeFunc: privilegeFunc,
|
|
||||||
})
|
|
||||||
if err == nil || err.Error() != "Error requesting privilege" {
|
|
||||||
t.Fatalf("expected an error requesting privilege, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestImagePullWithUnauthorizedErrorAndAnotherUnauthorizedError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusUnauthorized, "Unauthorized error")),
|
|
||||||
}
|
|
||||||
privilegeFunc := func() (string, error) {
|
|
||||||
return "a-auth-header", nil
|
|
||||||
}
|
|
||||||
_, err := client.ImagePull(context.Background(), "myimage", types.ImagePullOptions{
|
|
||||||
PrivilegeFunc: privilegeFunc,
|
|
||||||
})
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Unauthorized error" {
|
|
||||||
t.Fatalf("expected an Unauthorized Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestImagePullWithPrivilegedFuncNoError(t *testing.T) {
|
|
||||||
expectedURL := "/images/create"
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
auth := req.Header.Get("X-Registry-Auth")
|
|
||||||
if auth == "NotValid" {
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusUnauthorized,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte("Invalid credentials"))),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
if auth != "IAmValid" {
|
|
||||||
return nil, fmt.Errorf("Invalid auth header : expected %s, got %s", "IAmValid", auth)
|
|
||||||
}
|
|
||||||
query := req.URL.Query()
|
|
||||||
fromImage := query.Get("fromImage")
|
|
||||||
if fromImage != "myimage" {
|
|
||||||
return nil, fmt.Errorf("fromimage not set in URL query properly. Expected '%s', got %s", "myimage", fromImage)
|
|
||||||
}
|
|
||||||
tag := query.Get("tag")
|
|
||||||
if tag != "latest" {
|
|
||||||
return nil, fmt.Errorf("tag not set in URL query properly. Expected '%s', got %s", "latest", tag)
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte("hello world"))),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
privilegeFunc := func() (string, error) {
|
|
||||||
return "IAmValid", nil
|
|
||||||
}
|
|
||||||
resp, err := client.ImagePull(context.Background(), "myimage", types.ImagePullOptions{
|
|
||||||
RegistryAuth: "NotValid",
|
|
||||||
PrivilegeFunc: privilegeFunc,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
body, err := ioutil.ReadAll(resp)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if string(body) != "hello world" {
|
|
||||||
t.Fatalf("expected 'hello world', got %s", string(body))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestImagePullWithoutErrors(t *testing.T) {
|
|
||||||
expectedURL := "/images/create"
|
|
||||||
expectedOutput := "hello world"
|
|
||||||
pullCases := []struct {
|
|
||||||
all bool
|
|
||||||
reference string
|
|
||||||
expectedImage string
|
|
||||||
expectedTag string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
all: false,
|
|
||||||
reference: "myimage",
|
|
||||||
expectedImage: "myimage",
|
|
||||||
expectedTag: "latest",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
all: false,
|
|
||||||
reference: "myimage:tag",
|
|
||||||
expectedImage: "myimage",
|
|
||||||
expectedTag: "tag",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
all: true,
|
|
||||||
reference: "myimage",
|
|
||||||
expectedImage: "myimage",
|
|
||||||
expectedTag: "",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
all: true,
|
|
||||||
reference: "myimage:anything",
|
|
||||||
expectedImage: "myimage",
|
|
||||||
expectedTag: "",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, pullCase := range pullCases {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
query := req.URL.Query()
|
|
||||||
fromImage := query.Get("fromImage")
|
|
||||||
if fromImage != pullCase.expectedImage {
|
|
||||||
return nil, fmt.Errorf("fromimage not set in URL query properly. Expected '%s', got %s", pullCase.expectedImage, fromImage)
|
|
||||||
}
|
|
||||||
tag := query.Get("tag")
|
|
||||||
if tag != pullCase.expectedTag {
|
|
||||||
return nil, fmt.Errorf("tag not set in URL query properly. Expected '%s', got %s", pullCase.expectedTag, tag)
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte(expectedOutput))),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
resp, err := client.ImagePull(context.Background(), pullCase.reference, types.ImagePullOptions{
|
|
||||||
All: pullCase.all,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
body, err := ioutil.ReadAll(resp)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if string(body) != expectedOutput {
|
|
||||||
t.Fatalf("expected '%s', got %s", expectedOutput, string(body))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,180 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestImagePushReferenceError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
return nil, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
// An empty reference is an invalid reference
|
|
||||||
_, err := client.ImagePush(context.Background(), "", types.ImagePushOptions{})
|
|
||||||
if err == nil || !strings.Contains(err.Error(), "invalid reference format") {
|
|
||||||
t.Fatalf("expected an error, got %v", err)
|
|
||||||
}
|
|
||||||
// An canonical reference cannot be pushed
|
|
||||||
_, err = client.ImagePush(context.Background(), "repo@sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", types.ImagePushOptions{})
|
|
||||||
if err == nil || err.Error() != "cannot push a digest reference" {
|
|
||||||
t.Fatalf("expected an error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestImagePushAnyError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
_, err := client.ImagePush(context.Background(), "myimage", types.ImagePushOptions{})
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestImagePushStatusUnauthorizedError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusUnauthorized, "Unauthorized error")),
|
|
||||||
}
|
|
||||||
_, err := client.ImagePush(context.Background(), "myimage", types.ImagePushOptions{})
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Unauthorized error" {
|
|
||||||
t.Fatalf("expected an Unauthorized Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestImagePushWithUnauthorizedErrorAndPrivilegeFuncError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusUnauthorized, "Unauthorized error")),
|
|
||||||
}
|
|
||||||
privilegeFunc := func() (string, error) {
|
|
||||||
return "", fmt.Errorf("Error requesting privilege")
|
|
||||||
}
|
|
||||||
_, err := client.ImagePush(context.Background(), "myimage", types.ImagePushOptions{
|
|
||||||
PrivilegeFunc: privilegeFunc,
|
|
||||||
})
|
|
||||||
if err == nil || err.Error() != "Error requesting privilege" {
|
|
||||||
t.Fatalf("expected an error requesting privilege, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestImagePushWithUnauthorizedErrorAndAnotherUnauthorizedError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusUnauthorized, "Unauthorized error")),
|
|
||||||
}
|
|
||||||
privilegeFunc := func() (string, error) {
|
|
||||||
return "a-auth-header", nil
|
|
||||||
}
|
|
||||||
_, err := client.ImagePush(context.Background(), "myimage", types.ImagePushOptions{
|
|
||||||
PrivilegeFunc: privilegeFunc,
|
|
||||||
})
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Unauthorized error" {
|
|
||||||
t.Fatalf("expected an Unauthorized Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestImagePushWithPrivilegedFuncNoError(t *testing.T) {
|
|
||||||
expectedURL := "/images/myimage/push"
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
auth := req.Header.Get("X-Registry-Auth")
|
|
||||||
if auth == "NotValid" {
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusUnauthorized,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte("Invalid credentials"))),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
if auth != "IAmValid" {
|
|
||||||
return nil, fmt.Errorf("Invalid auth header : expected %s, got %s", "IAmValid", auth)
|
|
||||||
}
|
|
||||||
query := req.URL.Query()
|
|
||||||
tag := query.Get("tag")
|
|
||||||
if tag != "tag" {
|
|
||||||
return nil, fmt.Errorf("tag not set in URL query properly. Expected '%s', got %s", "tag", tag)
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte("hello world"))),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
privilegeFunc := func() (string, error) {
|
|
||||||
return "IAmValid", nil
|
|
||||||
}
|
|
||||||
resp, err := client.ImagePush(context.Background(), "myimage:tag", types.ImagePushOptions{
|
|
||||||
RegistryAuth: "NotValid",
|
|
||||||
PrivilegeFunc: privilegeFunc,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
body, err := ioutil.ReadAll(resp)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if string(body) != "hello world" {
|
|
||||||
t.Fatalf("expected 'hello world', got %s", string(body))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestImagePushWithoutErrors(t *testing.T) {
|
|
||||||
expectedOutput := "hello world"
|
|
||||||
expectedURLFormat := "/images/%s/push"
|
|
||||||
pullCases := []struct {
|
|
||||||
reference string
|
|
||||||
expectedImage string
|
|
||||||
expectedTag string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
reference: "myimage",
|
|
||||||
expectedImage: "myimage",
|
|
||||||
expectedTag: "",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
reference: "myimage:tag",
|
|
||||||
expectedImage: "myimage",
|
|
||||||
expectedTag: "tag",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, pullCase := range pullCases {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
expectedURL := fmt.Sprintf(expectedURLFormat, pullCase.expectedImage)
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
query := req.URL.Query()
|
|
||||||
tag := query.Get("tag")
|
|
||||||
if tag != pullCase.expectedTag {
|
|
||||||
return nil, fmt.Errorf("tag not set in URL query properly. Expected '%s', got %s", pullCase.expectedTag, tag)
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte(expectedOutput))),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
resp, err := client.ImagePush(context.Background(), pullCase.reference, types.ImagePushOptions{})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
body, err := ioutil.ReadAll(resp)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if string(body) != expectedOutput {
|
|
||||||
t.Fatalf("expected '%s', got %s", expectedOutput, string(body))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,95 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestImageRemoveError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := client.ImageRemove(context.Background(), "image_id", types.ImageRemoveOptions{})
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestImageRemove(t *testing.T) {
|
|
||||||
expectedURL := "/images/image_id"
|
|
||||||
removeCases := []struct {
|
|
||||||
force bool
|
|
||||||
pruneChildren bool
|
|
||||||
expectedQueryParams map[string]string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
force: false,
|
|
||||||
pruneChildren: false,
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"force": "",
|
|
||||||
"noprune": "1",
|
|
||||||
},
|
|
||||||
}, {
|
|
||||||
force: true,
|
|
||||||
pruneChildren: true,
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"force": "1",
|
|
||||||
"noprune": "",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, removeCase := range removeCases {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
if req.Method != "DELETE" {
|
|
||||||
return nil, fmt.Errorf("expected DELETE method, got %s", req.Method)
|
|
||||||
}
|
|
||||||
query := req.URL.Query()
|
|
||||||
for key, expected := range removeCase.expectedQueryParams {
|
|
||||||
actual := query.Get(key)
|
|
||||||
if actual != expected {
|
|
||||||
return nil, fmt.Errorf("%s not set in URL query properly. Expected '%s', got %s", key, expected, actual)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
b, err := json.Marshal([]types.ImageDeleteResponseItem{
|
|
||||||
{
|
|
||||||
Untagged: "image_id1",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Deleted: "image_id",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader(b)),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
imageDeletes, err := client.ImageRemove(context.Background(), "image_id", types.ImageRemoveOptions{
|
|
||||||
Force: removeCase.force,
|
|
||||||
PruneChildren: removeCase.pruneChildren,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if len(imageDeletes) != 2 {
|
|
||||||
t.Fatalf("expected 2 deleted images, got %v", imageDeletes)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,58 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"reflect"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestImageSaveError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
_, err := client.ImageSave(context.Background(), []string{"nothing"})
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestImageSave(t *testing.T) {
|
|
||||||
expectedURL := "/images/get"
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(r *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(r.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, r.URL)
|
|
||||||
}
|
|
||||||
query := r.URL.Query()
|
|
||||||
names := query["names"]
|
|
||||||
expectedNames := []string{"image_id1", "image_id2"}
|
|
||||||
if !reflect.DeepEqual(names, expectedNames) {
|
|
||||||
return nil, fmt.Errorf("names not set in URL query properly. Expected %v, got %v", names, expectedNames)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte("response"))),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
saveResponse, err := client.ImageSave(context.Background(), []string{"image_id1", "image_id2"})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
response, err := ioutil.ReadAll(saveResponse)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
saveResponse.Close()
|
|
||||||
if string(response) != "response" {
|
|
||||||
t.Fatalf("expected response to contain 'response', got %s", string(response))
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,166 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
|
|
||||||
"encoding/json"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
"github.com/docker/docker/api/types/filters"
|
|
||||||
"github.com/docker/docker/api/types/registry"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestImageSearchAnyError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
_, err := client.ImageSearch(context.Background(), "some-image", types.ImageSearchOptions{})
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestImageSearchStatusUnauthorizedError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusUnauthorized, "Unauthorized error")),
|
|
||||||
}
|
|
||||||
_, err := client.ImageSearch(context.Background(), "some-image", types.ImageSearchOptions{})
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Unauthorized error" {
|
|
||||||
t.Fatalf("expected an Unauthorized Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestImageSearchWithUnauthorizedErrorAndPrivilegeFuncError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusUnauthorized, "Unauthorized error")),
|
|
||||||
}
|
|
||||||
privilegeFunc := func() (string, error) {
|
|
||||||
return "", fmt.Errorf("Error requesting privilege")
|
|
||||||
}
|
|
||||||
_, err := client.ImageSearch(context.Background(), "some-image", types.ImageSearchOptions{
|
|
||||||
PrivilegeFunc: privilegeFunc,
|
|
||||||
})
|
|
||||||
if err == nil || err.Error() != "Error requesting privilege" {
|
|
||||||
t.Fatalf("expected an error requesting privilege, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestImageSearchWithUnauthorizedErrorAndAnotherUnauthorizedError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusUnauthorized, "Unauthorized error")),
|
|
||||||
}
|
|
||||||
privilegeFunc := func() (string, error) {
|
|
||||||
return "a-auth-header", nil
|
|
||||||
}
|
|
||||||
_, err := client.ImageSearch(context.Background(), "some-image", types.ImageSearchOptions{
|
|
||||||
PrivilegeFunc: privilegeFunc,
|
|
||||||
})
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Unauthorized error" {
|
|
||||||
t.Fatalf("expected an Unauthorized Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestImageSearchWithPrivilegedFuncNoError(t *testing.T) {
|
|
||||||
expectedURL := "/images/search"
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
auth := req.Header.Get("X-Registry-Auth")
|
|
||||||
if auth == "NotValid" {
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusUnauthorized,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte("Invalid credentials"))),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
if auth != "IAmValid" {
|
|
||||||
return nil, fmt.Errorf("Invalid auth header : expected 'IAmValid', got %s", auth)
|
|
||||||
}
|
|
||||||
query := req.URL.Query()
|
|
||||||
term := query.Get("term")
|
|
||||||
if term != "some-image" {
|
|
||||||
return nil, fmt.Errorf("term not set in URL query properly. Expected 'some-image', got %s", term)
|
|
||||||
}
|
|
||||||
content, err := json.Marshal([]registry.SearchResult{
|
|
||||||
{
|
|
||||||
Name: "anything",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader(content)),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
privilegeFunc := func() (string, error) {
|
|
||||||
return "IAmValid", nil
|
|
||||||
}
|
|
||||||
results, err := client.ImageSearch(context.Background(), "some-image", types.ImageSearchOptions{
|
|
||||||
RegistryAuth: "NotValid",
|
|
||||||
PrivilegeFunc: privilegeFunc,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if len(results) != 1 {
|
|
||||||
t.Fatalf("expected 1 result, got %v", results)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestImageSearchWithoutErrors(t *testing.T) {
|
|
||||||
expectedURL := "/images/search"
|
|
||||||
filterArgs := filters.NewArgs()
|
|
||||||
filterArgs.Add("is-automated", "true")
|
|
||||||
filterArgs.Add("stars", "3")
|
|
||||||
|
|
||||||
expectedFilters := `{"is-automated":{"true":true},"stars":{"3":true}}`
|
|
||||||
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
query := req.URL.Query()
|
|
||||||
term := query.Get("term")
|
|
||||||
if term != "some-image" {
|
|
||||||
return nil, fmt.Errorf("term not set in URL query properly. Expected 'some-image', got %s", term)
|
|
||||||
}
|
|
||||||
filters := query.Get("filters")
|
|
||||||
if filters != expectedFilters {
|
|
||||||
return nil, fmt.Errorf("filters not set in URL query properly. Expected '%s', got %s", expectedFilters, filters)
|
|
||||||
}
|
|
||||||
content, err := json.Marshal([]registry.SearchResult{
|
|
||||||
{
|
|
||||||
Name: "anything",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader(content)),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
results, err := client.ImageSearch(context.Background(), "some-image", types.ImageSearchOptions{
|
|
||||||
Filters: filterArgs,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if len(results) != 1 {
|
|
||||||
t.Fatalf("expected a result, got %v", results)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,143 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestImageTagError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
|
|
||||||
err := client.ImageTag(context.Background(), "image_id", "repo:tag")
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note: this is not testing all the InvalidReference as it's the responsibility
|
|
||||||
// of distribution/reference package.
|
|
||||||
func TestImageTagInvalidReference(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
|
|
||||||
err := client.ImageTag(context.Background(), "image_id", "aa/asdf$$^/aa")
|
|
||||||
if err == nil || err.Error() != `Error parsing reference: "aa/asdf$$^/aa" is not a valid repository/tag: invalid reference format` {
|
|
||||||
t.Fatalf("expected ErrReferenceInvalidFormat, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestImageTagInvalidSourceImageName(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
|
|
||||||
err := client.ImageTag(context.Background(), "invalid_source_image_name_", "repo:tag")
|
|
||||||
if err == nil || err.Error() != "Error parsing reference: \"invalid_source_image_name_\" is not a valid repository/tag: invalid reference format" {
|
|
||||||
t.Fatalf("expected Parsing Reference Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestImageTagHexSource(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusOK, "OK")),
|
|
||||||
}
|
|
||||||
|
|
||||||
err := client.ImageTag(context.Background(), "0d409d33b27e47423b049f7f863faa08655a8c901749c2b25b93ca67d01a470d", "repo:tag")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("got error: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestImageTag(t *testing.T) {
|
|
||||||
expectedURL := "/images/image_id/tag"
|
|
||||||
tagCases := []struct {
|
|
||||||
reference string
|
|
||||||
expectedQueryParams map[string]string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
reference: "repository:tag1",
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"repo": "repository",
|
|
||||||
"tag": "tag1",
|
|
||||||
},
|
|
||||||
}, {
|
|
||||||
reference: "another_repository:latest",
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"repo": "another_repository",
|
|
||||||
"tag": "latest",
|
|
||||||
},
|
|
||||||
}, {
|
|
||||||
reference: "another_repository",
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"repo": "another_repository",
|
|
||||||
"tag": "latest",
|
|
||||||
},
|
|
||||||
}, {
|
|
||||||
reference: "test/another_repository",
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"repo": "test/another_repository",
|
|
||||||
"tag": "latest",
|
|
||||||
},
|
|
||||||
}, {
|
|
||||||
reference: "test/another_repository:tag1",
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"repo": "test/another_repository",
|
|
||||||
"tag": "tag1",
|
|
||||||
},
|
|
||||||
}, {
|
|
||||||
reference: "test/test/another_repository:tag1",
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"repo": "test/test/another_repository",
|
|
||||||
"tag": "tag1",
|
|
||||||
},
|
|
||||||
}, {
|
|
||||||
reference: "test:5000/test/another_repository:tag1",
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"repo": "test:5000/test/another_repository",
|
|
||||||
"tag": "tag1",
|
|
||||||
},
|
|
||||||
}, {
|
|
||||||
reference: "test:5000/test/another_repository",
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"repo": "test:5000/test/another_repository",
|
|
||||||
"tag": "latest",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, tagCase := range tagCases {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
if req.Method != "POST" {
|
|
||||||
return nil, fmt.Errorf("expected POST method, got %s", req.Method)
|
|
||||||
}
|
|
||||||
query := req.URL.Query()
|
|
||||||
for key, expected := range tagCase.expectedQueryParams {
|
|
||||||
actual := query.Get(key)
|
|
||||||
if actual != expected {
|
|
||||||
return nil, fmt.Errorf("%s not set in URL query properly. Expected '%s', got %s", key, expected, actual)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte(""))),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
err := client.ImageTag(context.Background(), "image_id", tagCase.reference)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,76 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestInfoServerError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
_, err := client.Info(context.Background())
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestInfoInvalidResponseJSONError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte("invalid json"))),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
_, err := client.Info(context.Background())
|
|
||||||
if err == nil || !strings.Contains(err.Error(), "invalid character") {
|
|
||||||
t.Fatalf("expected a 'invalid character' error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestInfo(t *testing.T) {
|
|
||||||
expectedURL := "/info"
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
info := &types.Info{
|
|
||||||
ID: "daemonID",
|
|
||||||
Containers: 3,
|
|
||||||
}
|
|
||||||
b, err := json.Marshal(info)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader(b)),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
info, err := client.Info(context.Background())
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if info.ID != "daemonID" {
|
|
||||||
t.Fatalf("expected daemonID, got %s", info.ID)
|
|
||||||
}
|
|
||||||
|
|
||||||
if info.Containers != 3 {
|
|
||||||
t.Fatalf("expected 3 containers, got %d", info.Containers)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,111 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
"github.com/docker/docker/api/types/network"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestNetworkConnectError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
|
|
||||||
err := client.NetworkConnect(context.Background(), "network_id", "container_id", nil)
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNetworkConnectEmptyNilEndpointSettings(t *testing.T) {
|
|
||||||
expectedURL := "/networks/network_id/connect"
|
|
||||||
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
|
|
||||||
if req.Method != "POST" {
|
|
||||||
return nil, fmt.Errorf("expected POST method, got %s", req.Method)
|
|
||||||
}
|
|
||||||
|
|
||||||
var connect types.NetworkConnect
|
|
||||||
if err := json.NewDecoder(req.Body).Decode(&connect); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if connect.Container != "container_id" {
|
|
||||||
return nil, fmt.Errorf("expected 'container_id', got %s", connect.Container)
|
|
||||||
}
|
|
||||||
|
|
||||||
if connect.EndpointConfig != nil {
|
|
||||||
return nil, fmt.Errorf("expected connect.EndpointConfig to be nil, got %v", connect.EndpointConfig)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte(""))),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
err := client.NetworkConnect(context.Background(), "network_id", "container_id", nil)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNetworkConnect(t *testing.T) {
|
|
||||||
expectedURL := "/networks/network_id/connect"
|
|
||||||
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
|
|
||||||
if req.Method != "POST" {
|
|
||||||
return nil, fmt.Errorf("expected POST method, got %s", req.Method)
|
|
||||||
}
|
|
||||||
|
|
||||||
var connect types.NetworkConnect
|
|
||||||
if err := json.NewDecoder(req.Body).Decode(&connect); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if connect.Container != "container_id" {
|
|
||||||
return nil, fmt.Errorf("expected 'container_id', got %s", connect.Container)
|
|
||||||
}
|
|
||||||
|
|
||||||
if connect.EndpointConfig == nil {
|
|
||||||
return nil, fmt.Errorf("expected connect.EndpointConfig to be not nil, got %v", connect.EndpointConfig)
|
|
||||||
}
|
|
||||||
|
|
||||||
if connect.EndpointConfig.NetworkID != "NetworkID" {
|
|
||||||
return nil, fmt.Errorf("expected 'NetworkID', got %s", connect.EndpointConfig.NetworkID)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte(""))),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
err := client.NetworkConnect(context.Background(), "network_id", "container_id", &network.EndpointSettings{
|
|
||||||
NetworkID: "NetworkID",
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,72 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestNetworkCreateError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := client.NetworkCreate(context.Background(), "mynetwork", types.NetworkCreate{})
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNetworkCreate(t *testing.T) {
|
|
||||||
expectedURL := "/networks/create"
|
|
||||||
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
|
|
||||||
if req.Method != "POST" {
|
|
||||||
return nil, fmt.Errorf("expected POST method, got %s", req.Method)
|
|
||||||
}
|
|
||||||
|
|
||||||
content, err := json.Marshal(types.NetworkCreateResponse{
|
|
||||||
ID: "network_id",
|
|
||||||
Warning: "warning",
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader(content)),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
networkResponse, err := client.NetworkCreate(context.Background(), "mynetwork", types.NetworkCreate{
|
|
||||||
CheckDuplicate: true,
|
|
||||||
Driver: "mydriver",
|
|
||||||
EnableIPv6: true,
|
|
||||||
Internal: true,
|
|
||||||
Options: map[string]string{
|
|
||||||
"opt-key": "opt-value",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if networkResponse.ID != "network_id" {
|
|
||||||
t.Fatalf("expected networkResponse.ID to be 'network_id', got %s", networkResponse.ID)
|
|
||||||
}
|
|
||||||
if networkResponse.Warning != "warning" {
|
|
||||||
t.Fatalf("expected networkResponse.Warning to be 'warning', got %s", networkResponse.Warning)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,64 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestNetworkDisconnectError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
|
|
||||||
err := client.NetworkDisconnect(context.Background(), "network_id", "container_id", false)
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNetworkDisconnect(t *testing.T) {
|
|
||||||
expectedURL := "/networks/network_id/disconnect"
|
|
||||||
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
|
|
||||||
if req.Method != "POST" {
|
|
||||||
return nil, fmt.Errorf("expected POST method, got %s", req.Method)
|
|
||||||
}
|
|
||||||
|
|
||||||
var disconnect types.NetworkDisconnect
|
|
||||||
if err := json.NewDecoder(req.Body).Decode(&disconnect); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if disconnect.Container != "container_id" {
|
|
||||||
return nil, fmt.Errorf("expected 'container_id', got %s", disconnect.Container)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !disconnect.Force {
|
|
||||||
return nil, fmt.Errorf("expected Force to be true, got %v", disconnect.Force)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte(""))),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
err := client.NetworkDisconnect(context.Background(), "network_id", "container_id", true)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,96 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
"github.com/docker/docker/api/types/network"
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestNetworkInspectError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := client.NetworkInspect(context.Background(), "nothing", false)
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNetworkInspectContainerNotFound(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusNotFound, "Server error")),
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := client.NetworkInspect(context.Background(), "unknown", false)
|
|
||||||
if err == nil || !IsErrNetworkNotFound(err) {
|
|
||||||
t.Fatalf("expected a networkNotFound error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNetworkInspect(t *testing.T) {
|
|
||||||
expectedURL := "/networks/network_id"
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
if req.Method != "GET" {
|
|
||||||
return nil, fmt.Errorf("expected GET method, got %s", req.Method)
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
content []byte
|
|
||||||
err error
|
|
||||||
)
|
|
||||||
if strings.HasPrefix(req.URL.RawQuery, "verbose=true") {
|
|
||||||
s := map[string]network.ServiceInfo{
|
|
||||||
"web": {},
|
|
||||||
}
|
|
||||||
content, err = json.Marshal(types.NetworkResource{
|
|
||||||
Name: "mynetwork",
|
|
||||||
Services: s,
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
content, err = json.Marshal(types.NetworkResource{
|
|
||||||
Name: "mynetwork",
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader(content)),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
r, err := client.NetworkInspect(context.Background(), "network_id", false)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if r.Name != "mynetwork" {
|
|
||||||
t.Fatalf("expected `mynetwork`, got %s", r.Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
r, err = client.NetworkInspect(context.Background(), "network_id", true)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if r.Name != "mynetwork" {
|
|
||||||
t.Fatalf("expected `mynetwork`, got %s", r.Name)
|
|
||||||
}
|
|
||||||
_, ok := r.Services["web"]
|
|
||||||
if !ok {
|
|
||||||
t.Fatalf("expected service `web` missing in the verbose output")
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,108 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
"github.com/docker/docker/api/types/filters"
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestNetworkListError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := client.NetworkList(context.Background(), types.NetworkListOptions{
|
|
||||||
Filters: filters.NewArgs(),
|
|
||||||
})
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNetworkList(t *testing.T) {
|
|
||||||
expectedURL := "/networks"
|
|
||||||
|
|
||||||
noDanglingFilters := filters.NewArgs()
|
|
||||||
noDanglingFilters.Add("dangling", "false")
|
|
||||||
|
|
||||||
danglingFilters := filters.NewArgs()
|
|
||||||
danglingFilters.Add("dangling", "true")
|
|
||||||
|
|
||||||
labelFilters := filters.NewArgs()
|
|
||||||
labelFilters.Add("label", "label1")
|
|
||||||
labelFilters.Add("label", "label2")
|
|
||||||
|
|
||||||
listCases := []struct {
|
|
||||||
options types.NetworkListOptions
|
|
||||||
expectedFilters string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
options: types.NetworkListOptions{
|
|
||||||
Filters: filters.NewArgs(),
|
|
||||||
},
|
|
||||||
expectedFilters: "",
|
|
||||||
}, {
|
|
||||||
options: types.NetworkListOptions{
|
|
||||||
Filters: noDanglingFilters,
|
|
||||||
},
|
|
||||||
expectedFilters: `{"dangling":{"false":true}}`,
|
|
||||||
}, {
|
|
||||||
options: types.NetworkListOptions{
|
|
||||||
Filters: danglingFilters,
|
|
||||||
},
|
|
||||||
expectedFilters: `{"dangling":{"true":true}}`,
|
|
||||||
}, {
|
|
||||||
options: types.NetworkListOptions{
|
|
||||||
Filters: labelFilters,
|
|
||||||
},
|
|
||||||
expectedFilters: `{"label":{"label1":true,"label2":true}}`,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, listCase := range listCases {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
if req.Method != "GET" {
|
|
||||||
return nil, fmt.Errorf("expected GET method, got %s", req.Method)
|
|
||||||
}
|
|
||||||
query := req.URL.Query()
|
|
||||||
actualFilters := query.Get("filters")
|
|
||||||
if actualFilters != listCase.expectedFilters {
|
|
||||||
return nil, fmt.Errorf("filters not set in URL query properly. Expected '%s', got %s", listCase.expectedFilters, actualFilters)
|
|
||||||
}
|
|
||||||
content, err := json.Marshal([]types.NetworkResource{
|
|
||||||
{
|
|
||||||
Name: "network",
|
|
||||||
Driver: "bridge",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader(content)),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
networkResources, err := client.NetworkList(context.Background(), listCase.options)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if len(networkResources) != 1 {
|
|
||||||
t.Fatalf("expected 1 network resource, got %v", networkResources)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,112 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
"github.com/docker/docker/api/types/filters"
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestNetworksPruneError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
version: "1.25",
|
|
||||||
}
|
|
||||||
|
|
||||||
filters := filters.NewArgs()
|
|
||||||
|
|
||||||
_, err := client.NetworksPrune(context.Background(), filters)
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNetworksPrune(t *testing.T) {
|
|
||||||
expectedURL := "/v1.25/networks/prune"
|
|
||||||
|
|
||||||
danglingFilters := filters.NewArgs()
|
|
||||||
danglingFilters.Add("dangling", "true")
|
|
||||||
|
|
||||||
noDanglingFilters := filters.NewArgs()
|
|
||||||
noDanglingFilters.Add("dangling", "false")
|
|
||||||
|
|
||||||
labelFilters := filters.NewArgs()
|
|
||||||
labelFilters.Add("dangling", "true")
|
|
||||||
labelFilters.Add("label", "label1=foo")
|
|
||||||
labelFilters.Add("label", "label2!=bar")
|
|
||||||
|
|
||||||
listCases := []struct {
|
|
||||||
filters filters.Args
|
|
||||||
expectedQueryParams map[string]string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
filters: filters.Args{},
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"until": "",
|
|
||||||
"filter": "",
|
|
||||||
"filters": "",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
filters: danglingFilters,
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"until": "",
|
|
||||||
"filter": "",
|
|
||||||
"filters": `{"dangling":{"true":true}}`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
filters: noDanglingFilters,
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"until": "",
|
|
||||||
"filter": "",
|
|
||||||
"filters": `{"dangling":{"false":true}}`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
filters: labelFilters,
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"until": "",
|
|
||||||
"filter": "",
|
|
||||||
"filters": `{"dangling":{"true":true},"label":{"label1=foo":true,"label2!=bar":true}}`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, listCase := range listCases {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
query := req.URL.Query()
|
|
||||||
for key, expected := range listCase.expectedQueryParams {
|
|
||||||
actual := query.Get(key)
|
|
||||||
assert.Equal(t, expected, actual)
|
|
||||||
}
|
|
||||||
content, err := json.Marshal(types.NetworksPruneReport{
|
|
||||||
NetworksDeleted: []string{"network_id1", "network_id2"},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader(content)),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
version: "1.25",
|
|
||||||
}
|
|
||||||
|
|
||||||
report, err := client.NetworksPrune(context.Background(), listCase.filters)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Len(t, report.NetworksDeleted, 2)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,47 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestNetworkRemoveError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
|
|
||||||
err := client.NetworkRemove(context.Background(), "network_id")
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNetworkRemove(t *testing.T) {
|
|
||||||
expectedURL := "/networks/network_id"
|
|
||||||
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
if req.Method != "DELETE" {
|
|
||||||
return nil, fmt.Errorf("expected DELETE method, got %s", req.Method)
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte("body"))),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
err := client.NetworkRemove(context.Background(), "network_id")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,65 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types/swarm"
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestNodeInspectError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
|
|
||||||
_, _, err := client.NodeInspectWithRaw(context.Background(), "nothing")
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNodeInspectNodeNotFound(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusNotFound, "Server error")),
|
|
||||||
}
|
|
||||||
|
|
||||||
_, _, err := client.NodeInspectWithRaw(context.Background(), "unknown")
|
|
||||||
if err == nil || !IsErrNodeNotFound(err) {
|
|
||||||
t.Fatalf("expected a nodeNotFoundError error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNodeInspect(t *testing.T) {
|
|
||||||
expectedURL := "/nodes/node_id"
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
content, err := json.Marshal(swarm.Node{
|
|
||||||
ID: "node_id",
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader(content)),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
nodeInspect, _, err := client.NodeInspectWithRaw(context.Background(), "node_id")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if nodeInspect.ID != "node_id" {
|
|
||||||
t.Fatalf("expected `node_id`, got %s", nodeInspect.ID)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,94 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
"github.com/docker/docker/api/types/filters"
|
|
||||||
"github.com/docker/docker/api/types/swarm"
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestNodeListError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := client.NodeList(context.Background(), types.NodeListOptions{})
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNodeList(t *testing.T) {
|
|
||||||
expectedURL := "/nodes"
|
|
||||||
|
|
||||||
filters := filters.NewArgs()
|
|
||||||
filters.Add("label", "label1")
|
|
||||||
filters.Add("label", "label2")
|
|
||||||
|
|
||||||
listCases := []struct {
|
|
||||||
options types.NodeListOptions
|
|
||||||
expectedQueryParams map[string]string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
options: types.NodeListOptions{},
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"filters": "",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
options: types.NodeListOptions{
|
|
||||||
Filters: filters,
|
|
||||||
},
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"filters": `{"label":{"label1":true,"label2":true}}`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, listCase := range listCases {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
query := req.URL.Query()
|
|
||||||
for key, expected := range listCase.expectedQueryParams {
|
|
||||||
actual := query.Get(key)
|
|
||||||
if actual != expected {
|
|
||||||
return nil, fmt.Errorf("%s not set in URL query properly. Expected '%s', got %s", key, expected, actual)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
content, err := json.Marshal([]swarm.Node{
|
|
||||||
{
|
|
||||||
ID: "node_id1",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: "node_id2",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader(content)),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
nodes, err := client.NodeList(context.Background(), listCase.options)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if len(nodes) != 2 {
|
|
||||||
t.Fatalf("expected 2 nodes, got %v", nodes)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,69 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestNodeRemoveError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
|
|
||||||
err := client.NodeRemove(context.Background(), "node_id", types.NodeRemoveOptions{Force: false})
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNodeRemove(t *testing.T) {
|
|
||||||
expectedURL := "/nodes/node_id"
|
|
||||||
|
|
||||||
removeCases := []struct {
|
|
||||||
force bool
|
|
||||||
expectedForce string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
expectedForce: "",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
force: true,
|
|
||||||
expectedForce: "1",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, removeCase := range removeCases {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
if req.Method != "DELETE" {
|
|
||||||
return nil, fmt.Errorf("expected DELETE method, got %s", req.Method)
|
|
||||||
}
|
|
||||||
force := req.URL.Query().Get("force")
|
|
||||||
if force != removeCase.expectedForce {
|
|
||||||
return nil, fmt.Errorf("force not set in URL query properly. expected '%s', got %s", removeCase.expectedForce, force)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte("body"))),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
err := client.NodeRemove(context.Background(), "node_id", types.NodeRemoveOptions{Force: removeCase.force})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,49 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types/swarm"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestNodeUpdateError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
|
|
||||||
err := client.NodeUpdate(context.Background(), "node_id", swarm.Version{}, swarm.NodeSpec{})
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNodeUpdate(t *testing.T) {
|
|
||||||
expectedURL := "/nodes/node_id/update"
|
|
||||||
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
if req.Method != "POST" {
|
|
||||||
return nil, fmt.Errorf("expected POST method, got %s", req.Method)
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte("body"))),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
err := client.NodeUpdate(context.Background(), "node_id", swarm.Version{}, swarm.NodeSpec{})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,48 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestPluginDisableError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
|
|
||||||
err := client.PluginDisable(context.Background(), "plugin_name", types.PluginDisableOptions{})
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPluginDisable(t *testing.T) {
|
|
||||||
expectedURL := "/plugins/plugin_name/disable"
|
|
||||||
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
if req.Method != "POST" {
|
|
||||||
return nil, fmt.Errorf("expected POST method, got %s", req.Method)
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte(""))),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
err := client.PluginDisable(context.Background(), "plugin_name", types.PluginDisableOptions{})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,48 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestPluginEnableError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
|
|
||||||
err := client.PluginEnable(context.Background(), "plugin_name", types.PluginEnableOptions{})
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPluginEnable(t *testing.T) {
|
|
||||||
expectedURL := "/plugins/plugin_name/enable"
|
|
||||||
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
if req.Method != "POST" {
|
|
||||||
return nil, fmt.Errorf("expected POST method, got %s", req.Method)
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte(""))),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
err := client.PluginEnable(context.Background(), "plugin_name", types.PluginEnableOptions{})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,54 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestPluginInspectError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
|
|
||||||
_, _, err := client.PluginInspectWithRaw(context.Background(), "nothing")
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPluginInspect(t *testing.T) {
|
|
||||||
expectedURL := "/plugins/plugin_name"
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
content, err := json.Marshal(types.Plugin{
|
|
||||||
ID: "plugin_id",
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader(content)),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
pluginInspect, _, err := client.PluginInspectWithRaw(context.Background(), "plugin_name")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if pluginInspect.ID != "plugin_id" {
|
|
||||||
t.Fatalf("expected `plugin_id`, got %s", pluginInspect.ID)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,107 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
"github.com/docker/docker/api/types/filters"
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestPluginListError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := client.PluginList(context.Background(), filters.NewArgs())
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPluginList(t *testing.T) {
|
|
||||||
expectedURL := "/plugins"
|
|
||||||
|
|
||||||
enabledFilters := filters.NewArgs()
|
|
||||||
enabledFilters.Add("enabled", "true")
|
|
||||||
|
|
||||||
capabilityFilters := filters.NewArgs()
|
|
||||||
capabilityFilters.Add("capability", "volumedriver")
|
|
||||||
capabilityFilters.Add("capability", "authz")
|
|
||||||
|
|
||||||
listCases := []struct {
|
|
||||||
filters filters.Args
|
|
||||||
expectedQueryParams map[string]string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
filters: filters.NewArgs(),
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"all": "",
|
|
||||||
"filter": "",
|
|
||||||
"filters": "",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
filters: enabledFilters,
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"all": "",
|
|
||||||
"filter": "",
|
|
||||||
"filters": `{"enabled":{"true":true}}`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
filters: capabilityFilters,
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"all": "",
|
|
||||||
"filter": "",
|
|
||||||
"filters": `{"capability":{"authz":true,"volumedriver":true}}`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, listCase := range listCases {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
query := req.URL.Query()
|
|
||||||
for key, expected := range listCase.expectedQueryParams {
|
|
||||||
actual := query.Get(key)
|
|
||||||
if actual != expected {
|
|
||||||
return nil, fmt.Errorf("%s not set in URL query properly. Expected '%s', got %s", key, expected, actual)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
content, err := json.Marshal([]*types.Plugin{
|
|
||||||
{
|
|
||||||
ID: "plugin_id1",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: "plugin_id2",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader(content)),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
plugins, err := client.PluginList(context.Background(), listCase.filters)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if len(plugins) != 2 {
|
|
||||||
t.Fatalf("expected 2 plugins, got %v", plugins)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,51 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestPluginPushError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := client.PluginPush(context.Background(), "plugin_name", "")
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPluginPush(t *testing.T) {
|
|
||||||
expectedURL := "/plugins/plugin_name"
|
|
||||||
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
if req.Method != "POST" {
|
|
||||||
return nil, fmt.Errorf("expected POST method, got %s", req.Method)
|
|
||||||
}
|
|
||||||
auth := req.Header.Get("X-Registry-Auth")
|
|
||||||
if auth != "authtoken" {
|
|
||||||
return nil, fmt.Errorf("Invalid auth header : expected 'authtoken', got %s", auth)
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte(""))),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := client.PluginPush(context.Background(), "plugin_name", "authtoken")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,49 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestPluginRemoveError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
|
|
||||||
err := client.PluginRemove(context.Background(), "plugin_name", types.PluginRemoveOptions{})
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPluginRemove(t *testing.T) {
|
|
||||||
expectedURL := "/plugins/plugin_name"
|
|
||||||
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
if req.Method != "DELETE" {
|
|
||||||
return nil, fmt.Errorf("expected DELETE method, got %s", req.Method)
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte(""))),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
err := client.PluginRemove(context.Background(), "plugin_name", types.PluginRemoveOptions{})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,47 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestPluginSetError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
|
|
||||||
err := client.PluginSet(context.Background(), "plugin_name", []string{})
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPluginSet(t *testing.T) {
|
|
||||||
expectedURL := "/plugins/plugin_name/set"
|
|
||||||
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
if req.Method != "POST" {
|
|
||||||
return nil, fmt.Errorf("expected POST method, got %s", req.Method)
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte(""))),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
err := client.PluginSet(context.Background(), "plugin_name", []string{"arg1"})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,92 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
// TestSetHostHeader should set fake host for local communications, set real host
|
|
||||||
// for normal communications.
|
|
||||||
func TestSetHostHeader(t *testing.T) {
|
|
||||||
testURL := "/test"
|
|
||||||
testCases := []struct {
|
|
||||||
host string
|
|
||||||
expectedHost string
|
|
||||||
expectedURLHost string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
"unix:///var/run/docker.sock",
|
|
||||||
"docker",
|
|
||||||
"/var/run/docker.sock",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"npipe:////./pipe/docker_engine",
|
|
||||||
"docker",
|
|
||||||
"//./pipe/docker_engine",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"tcp://0.0.0.0:4243",
|
|
||||||
"",
|
|
||||||
"0.0.0.0:4243",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"tcp://localhost:4243",
|
|
||||||
"",
|
|
||||||
"localhost:4243",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for c, test := range testCases {
|
|
||||||
proto, addr, basePath, err := ParseHost(test.host)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, testURL) {
|
|
||||||
return nil, fmt.Errorf("Test Case #%d: Expected URL %q, got %q", c, testURL, req.URL)
|
|
||||||
}
|
|
||||||
if req.Host != test.expectedHost {
|
|
||||||
return nil, fmt.Errorf("Test Case #%d: Expected host %q, got %q", c, test.expectedHost, req.Host)
|
|
||||||
}
|
|
||||||
if req.URL.Host != test.expectedURLHost {
|
|
||||||
return nil, fmt.Errorf("Test Case #%d: Expected URL host %q, got %q", c, test.expectedURLHost, req.URL.Host)
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader(([]byte("")))),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
|
|
||||||
proto: proto,
|
|
||||||
addr: addr,
|
|
||||||
basePath: basePath,
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = client.sendRequest(context.Background(), "GET", testURL, nil, nil, nil)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestPlainTextError tests the server returning an error in plain text for
|
|
||||||
// backwards compatibility with API versions <1.24. All other tests use
|
|
||||||
// errors returned as JSON
|
|
||||||
func TestPlainTextError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(plainTextErrorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
_, err := client.ContainerList(context.Background(), types.ContainerListOptions{})
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,57 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
"github.com/docker/docker/api/types/swarm"
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestSecretCreateError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
_, err := client.SecretCreate(context.Background(), swarm.SecretSpec{})
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSecretCreate(t *testing.T) {
|
|
||||||
expectedURL := "/secrets/create"
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
if req.Method != "POST" {
|
|
||||||
return nil, fmt.Errorf("expected POST method, got %s", req.Method)
|
|
||||||
}
|
|
||||||
b, err := json.Marshal(types.SecretCreateResponse{
|
|
||||||
ID: "test_secret",
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusCreated,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader(b)),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
r, err := client.SecretCreate(context.Background(), swarm.SecretSpec{})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if r.ID != "test_secret" {
|
|
||||||
t.Fatalf("expected `test_secret`, got %s", r.ID)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,65 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types/swarm"
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestSecretInspectError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
|
|
||||||
_, _, err := client.SecretInspectWithRaw(context.Background(), "nothing")
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSecretInspectSecretNotFound(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusNotFound, "Server error")),
|
|
||||||
}
|
|
||||||
|
|
||||||
_, _, err := client.SecretInspectWithRaw(context.Background(), "unknown")
|
|
||||||
if err == nil || !IsErrSecretNotFound(err) {
|
|
||||||
t.Fatalf("expected a secretNotFoundError error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSecretInspect(t *testing.T) {
|
|
||||||
expectedURL := "/secrets/secret_id"
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
content, err := json.Marshal(swarm.Secret{
|
|
||||||
ID: "secret_id",
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader(content)),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
secretInspect, _, err := client.SecretInspectWithRaw(context.Background(), "secret_id")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if secretInspect.ID != "secret_id" {
|
|
||||||
t.Fatalf("expected `secret_id`, got %s", secretInspect.ID)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,94 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
"github.com/docker/docker/api/types/filters"
|
|
||||||
"github.com/docker/docker/api/types/swarm"
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestSecretListError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := client.SecretList(context.Background(), types.SecretListOptions{})
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSecretList(t *testing.T) {
|
|
||||||
expectedURL := "/secrets"
|
|
||||||
|
|
||||||
filters := filters.NewArgs()
|
|
||||||
filters.Add("label", "label1")
|
|
||||||
filters.Add("label", "label2")
|
|
||||||
|
|
||||||
listCases := []struct {
|
|
||||||
options types.SecretListOptions
|
|
||||||
expectedQueryParams map[string]string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
options: types.SecretListOptions{},
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"filters": "",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
options: types.SecretListOptions{
|
|
||||||
Filters: filters,
|
|
||||||
},
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"filters": `{"label":{"label1":true,"label2":true}}`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, listCase := range listCases {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
query := req.URL.Query()
|
|
||||||
for key, expected := range listCase.expectedQueryParams {
|
|
||||||
actual := query.Get(key)
|
|
||||||
if actual != expected {
|
|
||||||
return nil, fmt.Errorf("%s not set in URL query properly. Expected '%s', got %s", key, expected, actual)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
content, err := json.Marshal([]swarm.Secret{
|
|
||||||
{
|
|
||||||
ID: "secret_id1",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: "secret_id2",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader(content)),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
secrets, err := client.SecretList(context.Background(), listCase.options)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if len(secrets) != 2 {
|
|
||||||
t.Fatalf("expected 2 secrets, got %v", secrets)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,47 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestSecretRemoveError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
|
|
||||||
err := client.SecretRemove(context.Background(), "secret_id")
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSecretRemove(t *testing.T) {
|
|
||||||
expectedURL := "/secrets/secret_id"
|
|
||||||
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
if req.Method != "DELETE" {
|
|
||||||
return nil, fmt.Errorf("expected DELETE method, got %s", req.Method)
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte("body"))),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
err := client.SecretRemove(context.Background(), "secret_id")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,49 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types/swarm"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestSecretUpdateError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
|
|
||||||
err := client.SecretUpdate(context.Background(), "secret_id", swarm.Version{}, swarm.SecretSpec{})
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSecretUpdate(t *testing.T) {
|
|
||||||
expectedURL := "/secrets/secret_id/update"
|
|
||||||
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
if req.Method != "POST" {
|
|
||||||
return nil, fmt.Errorf("expected POST method, got %s", req.Method)
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte("body"))),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
err := client.SecretUpdate(context.Background(), "secret_id", swarm.Version{}, swarm.SecretSpec{})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,57 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
"github.com/docker/docker/api/types/swarm"
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestServiceCreateError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
_, err := client.ServiceCreate(context.Background(), swarm.ServiceSpec{}, types.ServiceCreateOptions{})
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestServiceCreate(t *testing.T) {
|
|
||||||
expectedURL := "/services/create"
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
if req.Method != "POST" {
|
|
||||||
return nil, fmt.Errorf("expected POST method, got %s", req.Method)
|
|
||||||
}
|
|
||||||
b, err := json.Marshal(types.ServiceCreateResponse{
|
|
||||||
ID: "service_id",
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader(b)),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
r, err := client.ServiceCreate(context.Background(), swarm.ServiceSpec{}, types.ServiceCreateOptions{})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if r.ID != "service_id" {
|
|
||||||
t.Fatalf("expected `service_id`, got %s", r.ID)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,66 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
"github.com/docker/docker/api/types/swarm"
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestServiceInspectError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
|
|
||||||
_, _, err := client.ServiceInspectWithRaw(context.Background(), "nothing", types.ServiceInspectOptions{})
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestServiceInspectServiceNotFound(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusNotFound, "Server error")),
|
|
||||||
}
|
|
||||||
|
|
||||||
_, _, err := client.ServiceInspectWithRaw(context.Background(), "unknown", types.ServiceInspectOptions{})
|
|
||||||
if err == nil || !IsErrServiceNotFound(err) {
|
|
||||||
t.Fatalf("expected a serviceNotFoundError error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestServiceInspect(t *testing.T) {
|
|
||||||
expectedURL := "/services/service_id"
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
content, err := json.Marshal(swarm.Service{
|
|
||||||
ID: "service_id",
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader(content)),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
serviceInspect, _, err := client.ServiceInspectWithRaw(context.Background(), "service_id", types.ServiceInspectOptions{})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if serviceInspect.ID != "service_id" {
|
|
||||||
t.Fatalf("expected `service_id`, got %s", serviceInspect.ID)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,94 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
"github.com/docker/docker/api/types/filters"
|
|
||||||
"github.com/docker/docker/api/types/swarm"
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestServiceListError(t *testing.T) {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := client.ServiceList(context.Background(), types.ServiceListOptions{})
|
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestServiceList(t *testing.T) {
|
|
||||||
expectedURL := "/services"
|
|
||||||
|
|
||||||
filters := filters.NewArgs()
|
|
||||||
filters.Add("label", "label1")
|
|
||||||
filters.Add("label", "label2")
|
|
||||||
|
|
||||||
listCases := []struct {
|
|
||||||
options types.ServiceListOptions
|
|
||||||
expectedQueryParams map[string]string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
options: types.ServiceListOptions{},
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"filters": "",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
options: types.ServiceListOptions{
|
|
||||||
Filters: filters,
|
|
||||||
},
|
|
||||||
expectedQueryParams: map[string]string{
|
|
||||||
"filters": `{"label":{"label1":true,"label2":true}}`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, listCase := range listCases {
|
|
||||||
client := &Client{
|
|
||||||
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
|
||||||
}
|
|
||||||
query := req.URL.Query()
|
|
||||||
for key, expected := range listCase.expectedQueryParams {
|
|
||||||
actual := query.Get(key)
|
|
||||||
if actual != expected {
|
|
||||||
return nil, fmt.Errorf("%s not set in URL query properly. Expected '%s', got %s", key, expected, actual)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
content, err := json.Marshal([]swarm.Service{
|
|
||||||
{
|
|
||||||
ID: "service_id1",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: "service_id2",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &http.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader(content)),
|
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
services, err := client.ServiceList(context.Background(), listCase.options)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if len(services) != 2 {
|
|
||||||
t.Fatalf("expected 2 services, got %v", services)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue