mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
testutil: use testing.TB instead of assert.TestingT
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
parent
0d4ffa3588
commit
51ca8081d8
13 changed files with 152 additions and 288 deletions
|
@ -2,10 +2,10 @@ package daemon
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
"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/testutil"
|
|
||||||
"gotest.tools/assert"
|
"gotest.tools/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -13,10 +13,8 @@ import (
|
||||||
type ConfigConstructor func(*swarm.Config)
|
type ConfigConstructor func(*swarm.Config)
|
||||||
|
|
||||||
// CreateConfig creates a config given the specified spec
|
// CreateConfig creates a config given the specified spec
|
||||||
func (d *Daemon) CreateConfig(t assert.TestingT, configSpec swarm.ConfigSpec) string {
|
func (d *Daemon) CreateConfig(t testing.TB, configSpec swarm.ConfigSpec) string {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
cli := d.NewClientT(t)
|
cli := d.NewClientT(t)
|
||||||
defer cli.Close()
|
defer cli.Close()
|
||||||
|
|
||||||
|
@ -26,10 +24,8 @@ func (d *Daemon) CreateConfig(t assert.TestingT, configSpec swarm.ConfigSpec) st
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListConfigs returns the list of the current swarm configs
|
// ListConfigs returns the list of the current swarm configs
|
||||||
func (d *Daemon) ListConfigs(t assert.TestingT) []swarm.Config {
|
func (d *Daemon) ListConfigs(t testing.TB) []swarm.Config {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
cli := d.NewClientT(t)
|
cli := d.NewClientT(t)
|
||||||
defer cli.Close()
|
defer cli.Close()
|
||||||
|
|
||||||
|
@ -39,10 +35,8 @@ func (d *Daemon) ListConfigs(t assert.TestingT) []swarm.Config {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetConfig returns a swarm config identified by the specified id
|
// GetConfig returns a swarm config identified by the specified id
|
||||||
func (d *Daemon) GetConfig(t assert.TestingT, id string) *swarm.Config {
|
func (d *Daemon) GetConfig(t testing.TB, id string) *swarm.Config {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
cli := d.NewClientT(t)
|
cli := d.NewClientT(t)
|
||||||
defer cli.Close()
|
defer cli.Close()
|
||||||
|
|
||||||
|
@ -52,10 +46,8 @@ func (d *Daemon) GetConfig(t assert.TestingT, id string) *swarm.Config {
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteConfig removes the swarm config identified by the specified id
|
// DeleteConfig removes the swarm config identified by the specified id
|
||||||
func (d *Daemon) DeleteConfig(t assert.TestingT, id string) {
|
func (d *Daemon) DeleteConfig(t testing.TB, id string) {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
cli := d.NewClientT(t)
|
cli := d.NewClientT(t)
|
||||||
defer cli.Close()
|
defer cli.Close()
|
||||||
|
|
||||||
|
@ -65,10 +57,8 @@ func (d *Daemon) DeleteConfig(t assert.TestingT, id string) {
|
||||||
|
|
||||||
// UpdateConfig updates the swarm config identified by the specified id
|
// UpdateConfig updates the swarm config identified by the specified id
|
||||||
// Currently, only label update is supported.
|
// Currently, only label update is supported.
|
||||||
func (d *Daemon) UpdateConfig(t assert.TestingT, id string, f ...ConfigConstructor) {
|
func (d *Daemon) UpdateConfig(t testing.TB, id string, f ...ConfigConstructor) {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
cli := d.NewClientT(t)
|
cli := d.NewClientT(t)
|
||||||
defer cli.Close()
|
defer cli.Close()
|
||||||
|
|
||||||
|
|
|
@ -2,17 +2,15 @@ package daemon
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/testutil"
|
|
||||||
"gotest.tools/assert"
|
"gotest.tools/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ActiveContainers returns the list of ids of the currently running containers
|
// ActiveContainers returns the list of ids of the currently running containers
|
||||||
func (d *Daemon) ActiveContainers(t assert.TestingT) []string {
|
func (d *Daemon) ActiveContainers(t testing.TB) []string {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
cli := d.NewClientT(t)
|
cli := d.NewClientT(t)
|
||||||
defer cli.Close()
|
defer cli.Close()
|
||||||
|
|
||||||
|
@ -27,10 +25,8 @@ func (d *Daemon) ActiveContainers(t assert.TestingT) []string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindContainerIP returns the ip of the specified container
|
// FindContainerIP returns the ip of the specified container
|
||||||
func (d *Daemon) FindContainerIP(t assert.TestingT, id string) string {
|
func (d *Daemon) FindContainerIP(t testing.TB, id string) string {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
cli := d.NewClientT(t)
|
cli := d.NewClientT(t)
|
||||||
defer cli.Close()
|
defer cli.Close()
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,6 @@ import (
|
||||||
"github.com/docker/docker/opts"
|
"github.com/docker/docker/opts"
|
||||||
"github.com/docker/docker/pkg/ioutils"
|
"github.com/docker/docker/pkg/ioutils"
|
||||||
"github.com/docker/docker/pkg/stringid"
|
"github.com/docker/docker/pkg/stringid"
|
||||||
"github.com/docker/docker/testutil"
|
|
||||||
"github.com/docker/docker/testutil/request"
|
"github.com/docker/docker/testutil/request"
|
||||||
"github.com/docker/go-connections/sockets"
|
"github.com/docker/go-connections/sockets"
|
||||||
"github.com/docker/go-connections/tlsconfig"
|
"github.com/docker/go-connections/tlsconfig"
|
||||||
|
@ -34,7 +33,7 @@ type logT interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
// nopLog is a no-op implementation of logT that is used in daemons created by
|
// nopLog is a no-op implementation of logT that is used in daemons created by
|
||||||
// NewDaemon (where no testingT is available).
|
// NewDaemon (where no testing.TB is available).
|
||||||
type nopLog struct{}
|
type nopLog struct{}
|
||||||
|
|
||||||
func (nopLog) Logf(string, ...interface{}) {}
|
func (nopLog) Logf(string, ...interface{}) {}
|
||||||
|
@ -194,10 +193,8 @@ func (d *Daemon) ReadLogFile() ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewClientT creates new client based on daemon's socket path
|
// NewClientT creates new client based on daemon's socket path
|
||||||
func (d *Daemon) NewClientT(t assert.TestingT, extraOpts ...client.Opt) *client.Client {
|
func (d *Daemon) NewClientT(t testing.TB, extraOpts ...client.Opt) *client.Client {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
|
|
||||||
c, err := d.NewClient(extraOpts...)
|
c, err := d.NewClient(extraOpts...)
|
||||||
assert.NilError(t, err, "cannot create daemon client")
|
assert.NilError(t, err, "cannot create daemon client")
|
||||||
|
@ -595,10 +592,8 @@ func (d *Daemon) ReloadConfig() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadBusybox image into the daemon
|
// LoadBusybox image into the daemon
|
||||||
func (d *Daemon) LoadBusybox(t assert.TestingT) {
|
func (d *Daemon) LoadBusybox(t testing.TB) {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
clientHost, err := client.NewClientWithOpts(client.FromEnv)
|
clientHost, err := client.NewClientWithOpts(client.FromEnv)
|
||||||
assert.NilError(t, err, "failed to create client")
|
assert.NilError(t, err, "failed to create client")
|
||||||
defer clientHost.Close()
|
defer clientHost.Close()
|
||||||
|
@ -709,10 +704,8 @@ func (d *Daemon) queryRootDir() (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Info returns the info struct for this daemon
|
// Info returns the info struct for this daemon
|
||||||
func (d *Daemon) Info(t assert.TestingT) types.Info {
|
func (d *Daemon) Info(t testing.TB) types.Info {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
c := d.NewClientT(t)
|
c := d.NewClientT(t)
|
||||||
info, err := c.Info(context.Background())
|
info, err := c.Info(context.Background())
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
|
@ -3,11 +3,11 @@ package daemon
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"strings"
|
"strings"
|
||||||
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"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/testutil"
|
|
||||||
"gotest.tools/assert"
|
"gotest.tools/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -15,10 +15,8 @@ import (
|
||||||
type NodeConstructor func(*swarm.Node)
|
type NodeConstructor func(*swarm.Node)
|
||||||
|
|
||||||
// GetNode returns a swarm node identified by the specified id
|
// GetNode returns a swarm node identified by the specified id
|
||||||
func (d *Daemon) GetNode(t assert.TestingT, id string, errCheck ...func(error) bool) *swarm.Node {
|
func (d *Daemon) GetNode(t testing.TB, id string, errCheck ...func(error) bool) *swarm.Node {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
cli := d.NewClientT(t)
|
cli := d.NewClientT(t)
|
||||||
defer cli.Close()
|
defer cli.Close()
|
||||||
|
|
||||||
|
@ -36,10 +34,8 @@ func (d *Daemon) GetNode(t assert.TestingT, id string, errCheck ...func(error) b
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoveNode removes the specified node
|
// RemoveNode removes the specified node
|
||||||
func (d *Daemon) RemoveNode(t assert.TestingT, id string, force bool) {
|
func (d *Daemon) RemoveNode(t testing.TB, id string, force bool) {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
cli := d.NewClientT(t)
|
cli := d.NewClientT(t)
|
||||||
defer cli.Close()
|
defer cli.Close()
|
||||||
|
|
||||||
|
@ -51,10 +47,8 @@ func (d *Daemon) RemoveNode(t assert.TestingT, id string, force bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateNode updates a swarm node with the specified node constructor
|
// UpdateNode updates a swarm node with the specified node constructor
|
||||||
func (d *Daemon) UpdateNode(t assert.TestingT, id string, f ...NodeConstructor) {
|
func (d *Daemon) UpdateNode(t testing.TB, id string, f ...NodeConstructor) {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
cli := d.NewClientT(t)
|
cli := d.NewClientT(t)
|
||||||
defer cli.Close()
|
defer cli.Close()
|
||||||
|
|
||||||
|
@ -75,10 +69,8 @@ func (d *Daemon) UpdateNode(t assert.TestingT, id string, f ...NodeConstructor)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListNodes returns the list of the current swarm nodes
|
// ListNodes returns the list of the current swarm nodes
|
||||||
func (d *Daemon) ListNodes(t assert.TestingT) []swarm.Node {
|
func (d *Daemon) ListNodes(t testing.TB) []swarm.Node {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
cli := d.NewClientT(t)
|
cli := d.NewClientT(t)
|
||||||
defer cli.Close()
|
defer cli.Close()
|
||||||
|
|
||||||
|
|
|
@ -2,15 +2,15 @@ package daemon
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/client"
|
"github.com/docker/docker/client"
|
||||||
"gotest.tools/assert"
|
|
||||||
"gotest.tools/poll"
|
"gotest.tools/poll"
|
||||||
)
|
)
|
||||||
|
|
||||||
// PluginIsRunning provides a poller to check if the specified plugin is running
|
// PluginIsRunning provides a poller to check if the specified plugin is running
|
||||||
func (d *Daemon) PluginIsRunning(t assert.TestingT, name string) func(poll.LogT) poll.Result {
|
func (d *Daemon) PluginIsRunning(t testing.TB, name string) func(poll.LogT) poll.Result {
|
||||||
return withClient(t, d, withPluginInspect(name, func(plugin *types.Plugin, t poll.LogT) poll.Result {
|
return withClient(t, d, withPluginInspect(name, func(plugin *types.Plugin, t poll.LogT) poll.Result {
|
||||||
if plugin.Enabled {
|
if plugin.Enabled {
|
||||||
return poll.Success()
|
return poll.Success()
|
||||||
|
@ -20,7 +20,7 @@ func (d *Daemon) PluginIsRunning(t assert.TestingT, name string) func(poll.LogT)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PluginIsNotRunning provides a poller to check if the specified plugin is not running
|
// PluginIsNotRunning provides a poller to check if the specified plugin is not running
|
||||||
func (d *Daemon) PluginIsNotRunning(t assert.TestingT, name string) func(poll.LogT) poll.Result {
|
func (d *Daemon) PluginIsNotRunning(t testing.TB, name string) func(poll.LogT) poll.Result {
|
||||||
return withClient(t, d, withPluginInspect(name, func(plugin *types.Plugin, t poll.LogT) poll.Result {
|
return withClient(t, d, withPluginInspect(name, func(plugin *types.Plugin, t poll.LogT) poll.Result {
|
||||||
if !plugin.Enabled {
|
if !plugin.Enabled {
|
||||||
return poll.Success()
|
return poll.Success()
|
||||||
|
@ -30,7 +30,7 @@ func (d *Daemon) PluginIsNotRunning(t assert.TestingT, name string) func(poll.Lo
|
||||||
}
|
}
|
||||||
|
|
||||||
// PluginIsNotPresent provides a poller to check if the specified plugin is not present
|
// PluginIsNotPresent provides a poller to check if the specified plugin is not present
|
||||||
func (d *Daemon) PluginIsNotPresent(t assert.TestingT, name string) func(poll.LogT) poll.Result {
|
func (d *Daemon) PluginIsNotPresent(t testing.TB, name string) func(poll.LogT) poll.Result {
|
||||||
return withClient(t, d, func(c client.APIClient, t poll.LogT) poll.Result {
|
return withClient(t, d, func(c client.APIClient, t poll.LogT) poll.Result {
|
||||||
_, _, err := c.PluginInspectWithRaw(context.Background(), name)
|
_, _, err := c.PluginInspectWithRaw(context.Background(), name)
|
||||||
if client.IsErrNotFound(err) {
|
if client.IsErrNotFound(err) {
|
||||||
|
@ -44,7 +44,7 @@ func (d *Daemon) PluginIsNotPresent(t assert.TestingT, name string) func(poll.Lo
|
||||||
}
|
}
|
||||||
|
|
||||||
// PluginReferenceIs provides a poller to check if the specified plugin has the specified reference
|
// PluginReferenceIs provides a poller to check if the specified plugin has the specified reference
|
||||||
func (d *Daemon) PluginReferenceIs(t assert.TestingT, name, expectedRef string) func(poll.LogT) poll.Result {
|
func (d *Daemon) PluginReferenceIs(t testing.TB, name, expectedRef string) func(poll.LogT) poll.Result {
|
||||||
return withClient(t, d, withPluginInspect(name, func(plugin *types.Plugin, t poll.LogT) poll.Result {
|
return withClient(t, d, withPluginInspect(name, func(plugin *types.Plugin, t poll.LogT) poll.Result {
|
||||||
if plugin.PluginReference == expectedRef {
|
if plugin.PluginReference == expectedRef {
|
||||||
return poll.Success()
|
return poll.Success()
|
||||||
|
@ -67,7 +67,7 @@ func withPluginInspect(name string, f func(*types.Plugin, poll.LogT) poll.Result
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func withClient(t assert.TestingT, d *Daemon, f func(client.APIClient, poll.LogT) poll.Result) func(poll.LogT) poll.Result {
|
func withClient(t testing.TB, d *Daemon, f func(client.APIClient, poll.LogT) poll.Result) func(poll.LogT) poll.Result {
|
||||||
return func(pt poll.LogT) poll.Result {
|
return func(pt poll.LogT) poll.Result {
|
||||||
c := d.NewClientT(t)
|
c := d.NewClientT(t)
|
||||||
return f(c, pt)
|
return f(c, pt)
|
||||||
|
|
|
@ -2,10 +2,10 @@ package daemon
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
"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/testutil"
|
|
||||||
"gotest.tools/assert"
|
"gotest.tools/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -13,10 +13,8 @@ import (
|
||||||
type SecretConstructor func(*swarm.Secret)
|
type SecretConstructor func(*swarm.Secret)
|
||||||
|
|
||||||
// CreateSecret creates a secret given the specified spec
|
// CreateSecret creates a secret given the specified spec
|
||||||
func (d *Daemon) CreateSecret(t assert.TestingT, secretSpec swarm.SecretSpec) string {
|
func (d *Daemon) CreateSecret(t testing.TB, secretSpec swarm.SecretSpec) string {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
cli := d.NewClientT(t)
|
cli := d.NewClientT(t)
|
||||||
defer cli.Close()
|
defer cli.Close()
|
||||||
|
|
||||||
|
@ -27,10 +25,8 @@ func (d *Daemon) CreateSecret(t assert.TestingT, secretSpec swarm.SecretSpec) st
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListSecrets returns the list of the current swarm secrets
|
// ListSecrets returns the list of the current swarm secrets
|
||||||
func (d *Daemon) ListSecrets(t assert.TestingT) []swarm.Secret {
|
func (d *Daemon) ListSecrets(t testing.TB) []swarm.Secret {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
cli := d.NewClientT(t)
|
cli := d.NewClientT(t)
|
||||||
defer cli.Close()
|
defer cli.Close()
|
||||||
|
|
||||||
|
@ -40,10 +36,8 @@ func (d *Daemon) ListSecrets(t assert.TestingT) []swarm.Secret {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSecret returns a swarm secret identified by the specified id
|
// GetSecret returns a swarm secret identified by the specified id
|
||||||
func (d *Daemon) GetSecret(t assert.TestingT, id string) *swarm.Secret {
|
func (d *Daemon) GetSecret(t testing.TB, id string) *swarm.Secret {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
cli := d.NewClientT(t)
|
cli := d.NewClientT(t)
|
||||||
defer cli.Close()
|
defer cli.Close()
|
||||||
|
|
||||||
|
@ -53,10 +47,8 @@ func (d *Daemon) GetSecret(t assert.TestingT, id string) *swarm.Secret {
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteSecret removes the swarm secret identified by the specified id
|
// DeleteSecret removes the swarm secret identified by the specified id
|
||||||
func (d *Daemon) DeleteSecret(t assert.TestingT, id string) {
|
func (d *Daemon) DeleteSecret(t testing.TB, id string) {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
cli := d.NewClientT(t)
|
cli := d.NewClientT(t)
|
||||||
defer cli.Close()
|
defer cli.Close()
|
||||||
|
|
||||||
|
@ -66,10 +58,8 @@ func (d *Daemon) DeleteSecret(t assert.TestingT, id string) {
|
||||||
|
|
||||||
// UpdateSecret updates the swarm secret identified by the specified id
|
// UpdateSecret updates the swarm secret identified by the specified id
|
||||||
// Currently, only label update is supported.
|
// Currently, only label update is supported.
|
||||||
func (d *Daemon) UpdateSecret(t assert.TestingT, id string, f ...SecretConstructor) {
|
func (d *Daemon) UpdateSecret(t testing.TB, id string, f ...SecretConstructor) {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
cli := d.NewClientT(t)
|
cli := d.NewClientT(t)
|
||||||
defer cli.Close()
|
defer cli.Close()
|
||||||
|
|
||||||
|
|
|
@ -2,22 +2,20 @@ package daemon
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"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/testutil"
|
|
||||||
"gotest.tools/assert"
|
"gotest.tools/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ServiceConstructor defines a swarm service constructor function
|
// ServiceConstructor defines a swarm service constructor function
|
||||||
type ServiceConstructor func(*swarm.Service)
|
type ServiceConstructor func(*swarm.Service)
|
||||||
|
|
||||||
func (d *Daemon) createServiceWithOptions(t assert.TestingT, opts types.ServiceCreateOptions, f ...ServiceConstructor) string {
|
func (d *Daemon) createServiceWithOptions(t testing.TB, opts types.ServiceCreateOptions, f ...ServiceConstructor) string {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
var service swarm.Service
|
var service swarm.Service
|
||||||
for _, fn := range f {
|
for _, fn := range f {
|
||||||
fn(&service)
|
fn(&service)
|
||||||
|
@ -35,18 +33,14 @@ func (d *Daemon) createServiceWithOptions(t assert.TestingT, opts types.ServiceC
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateService creates a swarm service given the specified service constructor
|
// CreateService creates a swarm service given the specified service constructor
|
||||||
func (d *Daemon) CreateService(t assert.TestingT, f ...ServiceConstructor) string {
|
func (d *Daemon) CreateService(t testing.TB, f ...ServiceConstructor) string {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
return d.createServiceWithOptions(t, types.ServiceCreateOptions{}, f...)
|
return d.createServiceWithOptions(t, types.ServiceCreateOptions{}, f...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetService returns the swarm service corresponding to the specified id
|
// GetService returns the swarm service corresponding to the specified id
|
||||||
func (d *Daemon) GetService(t assert.TestingT, id string) *swarm.Service {
|
func (d *Daemon) GetService(t testing.TB, id string) *swarm.Service {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
cli := d.NewClientT(t)
|
cli := d.NewClientT(t)
|
||||||
defer cli.Close()
|
defer cli.Close()
|
||||||
|
|
||||||
|
@ -56,10 +50,8 @@ func (d *Daemon) GetService(t assert.TestingT, id string) *swarm.Service {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetServiceTasks returns the swarm tasks for the specified service
|
// GetServiceTasks returns the swarm tasks for the specified service
|
||||||
func (d *Daemon) GetServiceTasks(t assert.TestingT, service string, additionalFilters ...filters.KeyValuePair) []swarm.Task {
|
func (d *Daemon) GetServiceTasks(t testing.TB, service string, additionalFilters ...filters.KeyValuePair) []swarm.Task {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
cli := d.NewClientT(t)
|
cli := d.NewClientT(t)
|
||||||
defer cli.Close()
|
defer cli.Close()
|
||||||
|
|
||||||
|
@ -80,10 +72,8 @@ func (d *Daemon) GetServiceTasks(t assert.TestingT, service string, additionalFi
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateService updates a swarm service with the specified service constructor
|
// UpdateService updates a swarm service with the specified service constructor
|
||||||
func (d *Daemon) UpdateService(t assert.TestingT, service *swarm.Service, f ...ServiceConstructor) {
|
func (d *Daemon) UpdateService(t testing.TB, service *swarm.Service, f ...ServiceConstructor) {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
cli := d.NewClientT(t)
|
cli := d.NewClientT(t)
|
||||||
defer cli.Close()
|
defer cli.Close()
|
||||||
|
|
||||||
|
@ -96,10 +86,8 @@ func (d *Daemon) UpdateService(t assert.TestingT, service *swarm.Service, f ...S
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoveService removes the specified service
|
// RemoveService removes the specified service
|
||||||
func (d *Daemon) RemoveService(t assert.TestingT, id string) {
|
func (d *Daemon) RemoveService(t testing.TB, id string) {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
cli := d.NewClientT(t)
|
cli := d.NewClientT(t)
|
||||||
defer cli.Close()
|
defer cli.Close()
|
||||||
|
|
||||||
|
@ -108,10 +96,8 @@ func (d *Daemon) RemoveService(t assert.TestingT, id string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListServices returns the list of the current swarm services
|
// ListServices returns the list of the current swarm services
|
||||||
func (d *Daemon) ListServices(t assert.TestingT) []swarm.Service {
|
func (d *Daemon) ListServices(t testing.TB) []swarm.Service {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
cli := d.NewClientT(t)
|
cli := d.NewClientT(t)
|
||||||
defer cli.Close()
|
defer cli.Close()
|
||||||
|
|
||||||
|
@ -121,10 +107,8 @@ func (d *Daemon) ListServices(t assert.TestingT) []swarm.Service {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTask returns the swarm task identified by the specified id
|
// GetTask returns the swarm task identified by the specified id
|
||||||
func (d *Daemon) GetTask(t assert.TestingT, id string) swarm.Task {
|
func (d *Daemon) GetTask(t testing.TB, id string) swarm.Task {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
cli := d.NewClientT(t)
|
cli := d.NewClientT(t)
|
||||||
defer cli.Close()
|
defer cli.Close()
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/docker/api/types/swarm"
|
"github.com/docker/docker/api/types/swarm"
|
||||||
"github.com/docker/docker/testutil"
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"gotest.tools/assert"
|
"gotest.tools/assert"
|
||||||
)
|
)
|
||||||
|
@ -78,10 +77,8 @@ func (d *Daemon) NodeID() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// SwarmInit initializes a new swarm cluster.
|
// SwarmInit initializes a new swarm cluster.
|
||||||
func (d *Daemon) SwarmInit(t assert.TestingT, req swarm.InitRequest) {
|
func (d *Daemon) SwarmInit(t testing.TB, req swarm.InitRequest) {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
if req.ListenAddr == "" {
|
if req.ListenAddr == "" {
|
||||||
req.ListenAddr = fmt.Sprintf("%s:%d", d.swarmListenAddr, d.SwarmPort)
|
req.ListenAddr = fmt.Sprintf("%s:%d", d.swarmListenAddr, d.SwarmPort)
|
||||||
}
|
}
|
||||||
|
@ -100,10 +97,8 @@ func (d *Daemon) SwarmInit(t assert.TestingT, req swarm.InitRequest) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// SwarmJoin joins a daemon to an existing cluster.
|
// SwarmJoin joins a daemon to an existing cluster.
|
||||||
func (d *Daemon) SwarmJoin(t assert.TestingT, req swarm.JoinRequest) {
|
func (d *Daemon) SwarmJoin(t testing.TB, req swarm.JoinRequest) {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
if req.ListenAddr == "" {
|
if req.ListenAddr == "" {
|
||||||
req.ListenAddr = fmt.Sprintf("%s:%d", d.swarmListenAddr, d.SwarmPort)
|
req.ListenAddr = fmt.Sprintf("%s:%d", d.swarmListenAddr, d.SwarmPort)
|
||||||
}
|
}
|
||||||
|
@ -116,20 +111,18 @@ func (d *Daemon) SwarmJoin(t assert.TestingT, req swarm.JoinRequest) {
|
||||||
|
|
||||||
// SwarmLeave forces daemon to leave current cluster.
|
// SwarmLeave forces daemon to leave current cluster.
|
||||||
//
|
//
|
||||||
// The passed in TestingT is only used to validate that the client was successfully created
|
// The passed in testing.TB is only used to validate that the client was successfully created
|
||||||
// Some tests rely on error checking the result of the actual unlock, so allow
|
// Some tests rely on error checking the result of the actual unlock, so allow
|
||||||
// the error to be returned.
|
// the error to be returned.
|
||||||
func (d *Daemon) SwarmLeave(t assert.TestingT, force bool) error {
|
func (d *Daemon) SwarmLeave(t testing.TB, force bool) error {
|
||||||
cli := d.NewClientT(t)
|
cli := d.NewClientT(t)
|
||||||
defer cli.Close()
|
defer cli.Close()
|
||||||
return cli.SwarmLeave(context.Background(), force)
|
return cli.SwarmLeave(context.Background(), force)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SwarmInfo returns the swarm information of the daemon
|
// SwarmInfo returns the swarm information of the daemon
|
||||||
func (d *Daemon) SwarmInfo(t assert.TestingT) swarm.Info {
|
func (d *Daemon) SwarmInfo(t testing.TB) swarm.Info {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
cli := d.NewClientT(t)
|
cli := d.NewClientT(t)
|
||||||
info, err := cli.Info(context.Background())
|
info, err := cli.Info(context.Background())
|
||||||
assert.NilError(t, err, "get swarm info")
|
assert.NilError(t, err, "get swarm info")
|
||||||
|
@ -138,10 +131,10 @@ func (d *Daemon) SwarmInfo(t assert.TestingT) swarm.Info {
|
||||||
|
|
||||||
// SwarmUnlock tries to unlock a locked swarm
|
// SwarmUnlock tries to unlock a locked swarm
|
||||||
//
|
//
|
||||||
// The passed in TestingT is only used to validate that the client was successfully created
|
// The passed in testing.TB is only used to validate that the client was successfully created
|
||||||
// Some tests rely on error checking the result of the actual unlock, so allow
|
// Some tests rely on error checking the result of the actual unlock, so allow
|
||||||
// the error to be returned.
|
// the error to be returned.
|
||||||
func (d *Daemon) SwarmUnlock(t assert.TestingT, req swarm.UnlockRequest) error {
|
func (d *Daemon) SwarmUnlock(t testing.TB, req swarm.UnlockRequest) error {
|
||||||
cli := d.NewClientT(t)
|
cli := d.NewClientT(t)
|
||||||
defer cli.Close()
|
defer cli.Close()
|
||||||
|
|
||||||
|
@ -153,10 +146,8 @@ func (d *Daemon) SwarmUnlock(t assert.TestingT, req swarm.UnlockRequest) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSwarm returns the current swarm object
|
// GetSwarm returns the current swarm object
|
||||||
func (d *Daemon) GetSwarm(t assert.TestingT) swarm.Swarm {
|
func (d *Daemon) GetSwarm(t testing.TB) swarm.Swarm {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
cli := d.NewClientT(t)
|
cli := d.NewClientT(t)
|
||||||
defer cli.Close()
|
defer cli.Close()
|
||||||
|
|
||||||
|
@ -166,10 +157,8 @@ func (d *Daemon) GetSwarm(t assert.TestingT) swarm.Swarm {
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateSwarm updates the current swarm object with the specified spec constructors
|
// UpdateSwarm updates the current swarm object with the specified spec constructors
|
||||||
func (d *Daemon) UpdateSwarm(t assert.TestingT, f ...SpecConstructor) {
|
func (d *Daemon) UpdateSwarm(t testing.TB, f ...SpecConstructor) {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
cli := d.NewClientT(t)
|
cli := d.NewClientT(t)
|
||||||
defer cli.Close()
|
defer cli.Close()
|
||||||
|
|
||||||
|
@ -183,10 +172,8 @@ func (d *Daemon) UpdateSwarm(t assert.TestingT, f ...SpecConstructor) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// RotateTokens update the swarm to rotate tokens
|
// RotateTokens update the swarm to rotate tokens
|
||||||
func (d *Daemon) RotateTokens(t assert.TestingT) {
|
func (d *Daemon) RotateTokens(t testing.TB) {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
cli := d.NewClientT(t)
|
cli := d.NewClientT(t)
|
||||||
defer cli.Close()
|
defer cli.Close()
|
||||||
|
|
||||||
|
@ -203,10 +190,8 @@ func (d *Daemon) RotateTokens(t assert.TestingT) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// JoinTokens returns the current swarm join tokens
|
// JoinTokens returns the current swarm join tokens
|
||||||
func (d *Daemon) JoinTokens(t assert.TestingT) swarm.JoinTokens {
|
func (d *Daemon) JoinTokens(t testing.TB) swarm.JoinTokens {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
cli := d.NewClientT(t)
|
cli := d.NewClientT(t)
|
||||||
defer cli.Close()
|
defer cli.Close()
|
||||||
|
|
||||||
|
|
|
@ -4,21 +4,19 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
"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/client"
|
"github.com/docker/docker/client"
|
||||||
"github.com/docker/docker/testutil"
|
|
||||||
"gotest.tools/assert"
|
"gotest.tools/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Clean the environment, preserving protected objects (images, containers, ...)
|
// Clean the environment, preserving protected objects (images, containers, ...)
|
||||||
// and removing everything else. It's meant to run after any tests so that they don't
|
// and removing everything else. It's meant to run after any tests so that they don't
|
||||||
// depend on each others.
|
// depend on each others.
|
||||||
func (e *Execution) Clean(t assert.TestingT) {
|
func (e *Execution) Clean(t testing.TB) {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
client := e.APIClient()
|
client := e.APIClient()
|
||||||
|
|
||||||
platform := e.OSType
|
platform := e.OSType
|
||||||
|
@ -34,10 +32,8 @@ func (e *Execution) Clean(t assert.TestingT) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func unpauseAllContainers(t assert.TestingT, client client.ContainerAPIClient) {
|
func unpauseAllContainers(t testing.TB, client client.ContainerAPIClient) {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
containers := getPausedContainers(ctx, t, client)
|
containers := getPausedContainers(ctx, t, client)
|
||||||
if len(containers) > 0 {
|
if len(containers) > 0 {
|
||||||
|
@ -48,10 +44,8 @@ func unpauseAllContainers(t assert.TestingT, client client.ContainerAPIClient) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getPausedContainers(ctx context.Context, t assert.TestingT, client client.ContainerAPIClient) []types.Container {
|
func getPausedContainers(ctx context.Context, t testing.TB, client client.ContainerAPIClient) []types.Container {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
filter := filters.NewArgs()
|
filter := filters.NewArgs()
|
||||||
filter.Add("status", "paused")
|
filter.Add("status", "paused")
|
||||||
containers, err := client.ContainerList(ctx, types.ContainerListOptions{
|
containers, err := client.ContainerList(ctx, types.ContainerListOptions{
|
||||||
|
@ -65,10 +59,8 @@ func getPausedContainers(ctx context.Context, t assert.TestingT, client client.C
|
||||||
|
|
||||||
var alreadyExists = regexp.MustCompile(`Error response from daemon: removal of container (\w+) is already in progress`)
|
var alreadyExists = regexp.MustCompile(`Error response from daemon: removal of container (\w+) is already in progress`)
|
||||||
|
|
||||||
func deleteAllContainers(t assert.TestingT, apiclient client.ContainerAPIClient, protectedContainers map[string]struct{}) {
|
func deleteAllContainers(t testing.TB, apiclient client.ContainerAPIClient, protectedContainers map[string]struct{}) {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
containers := getAllContainers(ctx, t, apiclient)
|
containers := getAllContainers(ctx, t, apiclient)
|
||||||
if len(containers) == 0 {
|
if len(containers) == 0 {
|
||||||
|
@ -90,10 +82,8 @@ func deleteAllContainers(t assert.TestingT, apiclient client.ContainerAPIClient,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getAllContainers(ctx context.Context, t assert.TestingT, client client.ContainerAPIClient) []types.Container {
|
func getAllContainers(ctx context.Context, t testing.TB, client client.ContainerAPIClient) []types.Container {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
containers, err := client.ContainerList(ctx, types.ContainerListOptions{
|
containers, err := client.ContainerList(ctx, types.ContainerListOptions{
|
||||||
Quiet: true,
|
Quiet: true,
|
||||||
All: true,
|
All: true,
|
||||||
|
@ -102,10 +92,8 @@ func getAllContainers(ctx context.Context, t assert.TestingT, client client.Cont
|
||||||
return containers
|
return containers
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteAllImages(t assert.TestingT, apiclient client.ImageAPIClient, protectedImages map[string]struct{}) {
|
func deleteAllImages(t testing.TB, apiclient client.ImageAPIClient, protectedImages map[string]struct{}) {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
images, err := apiclient.ImageList(context.Background(), types.ImageListOptions{})
|
images, err := apiclient.ImageList(context.Background(), types.ImageListOptions{})
|
||||||
assert.Check(t, err, "failed to list images")
|
assert.Check(t, err, "failed to list images")
|
||||||
|
|
||||||
|
@ -124,10 +112,8 @@ func deleteAllImages(t assert.TestingT, apiclient client.ImageAPIClient, protect
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func removeImage(ctx context.Context, t assert.TestingT, apiclient client.ImageAPIClient, ref string) {
|
func removeImage(ctx context.Context, t testing.TB, apiclient client.ImageAPIClient, ref string) {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
_, err := apiclient.ImageRemove(ctx, ref, types.ImageRemoveOptions{
|
_, err := apiclient.ImageRemove(ctx, ref, types.ImageRemoveOptions{
|
||||||
Force: true,
|
Force: true,
|
||||||
})
|
})
|
||||||
|
@ -137,10 +123,8 @@ func removeImage(ctx context.Context, t assert.TestingT, apiclient client.ImageA
|
||||||
assert.Check(t, err, "failed to remove image %s", ref)
|
assert.Check(t, err, "failed to remove image %s", ref)
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteAllVolumes(t assert.TestingT, c client.VolumeAPIClient, protectedVolumes map[string]struct{}) {
|
func deleteAllVolumes(t testing.TB, c client.VolumeAPIClient, protectedVolumes map[string]struct{}) {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
volumes, err := c.VolumeList(context.Background(), filters.Args{})
|
volumes, err := c.VolumeList(context.Background(), filters.Args{})
|
||||||
assert.Check(t, err, "failed to list volumes")
|
assert.Check(t, err, "failed to list volumes")
|
||||||
|
|
||||||
|
@ -157,10 +141,8 @@ func deleteAllVolumes(t assert.TestingT, c client.VolumeAPIClient, protectedVolu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteAllNetworks(t assert.TestingT, c client.NetworkAPIClient, daemonPlatform string, protectedNetworks map[string]struct{}) {
|
func deleteAllNetworks(t testing.TB, c client.NetworkAPIClient, daemonPlatform string, protectedNetworks map[string]struct{}) {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
networks, err := c.NetworkList(context.Background(), types.NetworkListOptions{})
|
networks, err := c.NetworkList(context.Background(), types.NetworkListOptions{})
|
||||||
assert.Check(t, err, "failed to list networks")
|
assert.Check(t, err, "failed to list networks")
|
||||||
|
|
||||||
|
@ -180,10 +162,8 @@ func deleteAllNetworks(t assert.TestingT, c client.NetworkAPIClient, daemonPlatf
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteAllPlugins(t assert.TestingT, c client.PluginAPIClient, protectedPlugins map[string]struct{}) {
|
func deleteAllPlugins(t testing.TB, c client.PluginAPIClient, protectedPlugins map[string]struct{}) {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
plugins, err := c.PluginList(context.Background(), filters.Args{})
|
plugins, err := c.PluginList(context.Background(), filters.Args{})
|
||||||
// Docker EE does not allow cluster-wide plugin management.
|
// Docker EE does not allow cluster-wide plugin management.
|
||||||
if client.IsErrNotImplemented(err) {
|
if client.IsErrNotImplemented(err) {
|
||||||
|
|
|
@ -6,11 +6,11 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
"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/client"
|
"github.com/docker/docker/client"
|
||||||
"github.com/docker/docker/testutil"
|
|
||||||
"github.com/docker/docker/testutil/fixtures/load"
|
"github.com/docker/docker/testutil/fixtures/load"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"gotest.tools/assert"
|
"gotest.tools/assert"
|
||||||
|
@ -165,10 +165,7 @@ func (e *Execution) IsUserNamespace() bool {
|
||||||
// HasExistingImage checks whether there is an image with the given reference.
|
// HasExistingImage checks whether there is an image with the given reference.
|
||||||
// Note that this is done by filtering and then checking whether there were any
|
// Note that this is done by filtering and then checking whether there were any
|
||||||
// results -- so ambiguous references might result in false-positives.
|
// results -- so ambiguous references might result in false-positives.
|
||||||
func (e *Execution) HasExistingImage(t assert.TestingT, reference string) bool {
|
func (e *Execution) HasExistingImage(t testing.TB, reference string) bool {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
client := e.APIClient()
|
client := e.APIClient()
|
||||||
filter := filters.NewArgs()
|
filter := filters.NewArgs()
|
||||||
filter.Add("dangling", "false")
|
filter.Add("dangling", "false")
|
||||||
|
|
|
@ -2,11 +2,11 @@ package environment
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
"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"
|
||||||
dclient "github.com/docker/docker/client"
|
dclient "github.com/docker/docker/client"
|
||||||
"github.com/docker/docker/testutil"
|
|
||||||
"gotest.tools/assert"
|
"gotest.tools/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -33,10 +33,8 @@ func newProtectedElements() protectedElements {
|
||||||
// ProtectAll protects the existing environment (containers, images, networks,
|
// ProtectAll protects the existing environment (containers, images, networks,
|
||||||
// volumes, and, on Linux, plugins) from being cleaned up at the end of test
|
// volumes, and, on Linux, plugins) from being cleaned up at the end of test
|
||||||
// runs
|
// runs
|
||||||
func ProtectAll(t assert.TestingT, testEnv *Execution) {
|
func ProtectAll(t testing.TB, testEnv *Execution) {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
ProtectContainers(t, testEnv)
|
ProtectContainers(t, testEnv)
|
||||||
ProtectImages(t, testEnv)
|
ProtectImages(t, testEnv)
|
||||||
ProtectNetworks(t, testEnv)
|
ProtectNetworks(t, testEnv)
|
||||||
|
@ -48,10 +46,8 @@ func ProtectAll(t assert.TestingT, testEnv *Execution) {
|
||||||
|
|
||||||
// ProtectContainer adds the specified container(s) to be protected in case of
|
// ProtectContainer adds the specified container(s) to be protected in case of
|
||||||
// clean
|
// clean
|
||||||
func (e *Execution) ProtectContainer(t assert.TestingT, containers ...string) {
|
func (e *Execution) ProtectContainer(t testing.TB, containers ...string) {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
for _, container := range containers {
|
for _, container := range containers {
|
||||||
e.protectedElements.containers[container] = struct{}{}
|
e.protectedElements.containers[container] = struct{}{}
|
||||||
}
|
}
|
||||||
|
@ -59,18 +55,14 @@ func (e *Execution) ProtectContainer(t assert.TestingT, containers ...string) {
|
||||||
|
|
||||||
// ProtectContainers protects existing containers from being cleaned up at the
|
// ProtectContainers protects existing containers from being cleaned up at the
|
||||||
// end of test runs
|
// end of test runs
|
||||||
func ProtectContainers(t assert.TestingT, testEnv *Execution) {
|
func ProtectContainers(t testing.TB, testEnv *Execution) {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
containers := getExistingContainers(t, testEnv)
|
containers := getExistingContainers(t, testEnv)
|
||||||
testEnv.ProtectContainer(t, containers...)
|
testEnv.ProtectContainer(t, containers...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getExistingContainers(t assert.TestingT, testEnv *Execution) []string {
|
func getExistingContainers(t testing.TB, testEnv *Execution) []string {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
client := testEnv.APIClient()
|
client := testEnv.APIClient()
|
||||||
containerList, err := client.ContainerList(context.Background(), types.ContainerListOptions{
|
containerList, err := client.ContainerList(context.Background(), types.ContainerListOptions{
|
||||||
All: true,
|
All: true,
|
||||||
|
@ -85,10 +77,8 @@ func getExistingContainers(t assert.TestingT, testEnv *Execution) []string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProtectImage adds the specified image(s) to be protected in case of clean
|
// ProtectImage adds the specified image(s) to be protected in case of clean
|
||||||
func (e *Execution) ProtectImage(t assert.TestingT, images ...string) {
|
func (e *Execution) ProtectImage(t testing.TB, images ...string) {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
for _, image := range images {
|
for _, image := range images {
|
||||||
e.protectedElements.images[image] = struct{}{}
|
e.protectedElements.images[image] = struct{}{}
|
||||||
}
|
}
|
||||||
|
@ -96,10 +86,8 @@ func (e *Execution) ProtectImage(t assert.TestingT, images ...string) {
|
||||||
|
|
||||||
// ProtectImages protects existing images and on linux frozen images from being
|
// ProtectImages protects existing images and on linux frozen images from being
|
||||||
// cleaned up at the end of test runs
|
// cleaned up at the end of test runs
|
||||||
func ProtectImages(t assert.TestingT, testEnv *Execution) {
|
func ProtectImages(t testing.TB, testEnv *Execution) {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
images := getExistingImages(t, testEnv)
|
images := getExistingImages(t, testEnv)
|
||||||
|
|
||||||
if testEnv.OSType == "linux" {
|
if testEnv.OSType == "linux" {
|
||||||
|
@ -108,10 +96,8 @@ func ProtectImages(t assert.TestingT, testEnv *Execution) {
|
||||||
testEnv.ProtectImage(t, images...)
|
testEnv.ProtectImage(t, images...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getExistingImages(t assert.TestingT, testEnv *Execution) []string {
|
func getExistingImages(t testing.TB, testEnv *Execution) []string {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
client := testEnv.APIClient()
|
client := testEnv.APIClient()
|
||||||
filter := filters.NewArgs()
|
filter := filters.NewArgs()
|
||||||
filter.Add("dangling", "false")
|
filter.Add("dangling", "false")
|
||||||
|
@ -145,10 +131,8 @@ func tagsFromImageSummary(image types.ImageSummary) []string {
|
||||||
|
|
||||||
// ProtectNetwork adds the specified network(s) to be protected in case of
|
// ProtectNetwork adds the specified network(s) to be protected in case of
|
||||||
// clean
|
// clean
|
||||||
func (e *Execution) ProtectNetwork(t assert.TestingT, networks ...string) {
|
func (e *Execution) ProtectNetwork(t testing.TB, networks ...string) {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
for _, network := range networks {
|
for _, network := range networks {
|
||||||
e.protectedElements.networks[network] = struct{}{}
|
e.protectedElements.networks[network] = struct{}{}
|
||||||
}
|
}
|
||||||
|
@ -156,18 +140,14 @@ func (e *Execution) ProtectNetwork(t assert.TestingT, networks ...string) {
|
||||||
|
|
||||||
// ProtectNetworks protects existing networks from being cleaned up at the end
|
// ProtectNetworks protects existing networks from being cleaned up at the end
|
||||||
// of test runs
|
// of test runs
|
||||||
func ProtectNetworks(t assert.TestingT, testEnv *Execution) {
|
func ProtectNetworks(t testing.TB, testEnv *Execution) {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
networks := getExistingNetworks(t, testEnv)
|
networks := getExistingNetworks(t, testEnv)
|
||||||
testEnv.ProtectNetwork(t, networks...)
|
testEnv.ProtectNetwork(t, networks...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getExistingNetworks(t assert.TestingT, testEnv *Execution) []string {
|
func getExistingNetworks(t testing.TB, testEnv *Execution) []string {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
client := testEnv.APIClient()
|
client := testEnv.APIClient()
|
||||||
networkList, err := client.NetworkList(context.Background(), types.NetworkListOptions{})
|
networkList, err := client.NetworkList(context.Background(), types.NetworkListOptions{})
|
||||||
assert.NilError(t, err, "failed to list networks")
|
assert.NilError(t, err, "failed to list networks")
|
||||||
|
@ -180,10 +160,8 @@ func getExistingNetworks(t assert.TestingT, testEnv *Execution) []string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProtectPlugin adds the specified plugin(s) to be protected in case of clean
|
// ProtectPlugin adds the specified plugin(s) to be protected in case of clean
|
||||||
func (e *Execution) ProtectPlugin(t assert.TestingT, plugins ...string) {
|
func (e *Execution) ProtectPlugin(t testing.TB, plugins ...string) {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
for _, plugin := range plugins {
|
for _, plugin := range plugins {
|
||||||
e.protectedElements.plugins[plugin] = struct{}{}
|
e.protectedElements.plugins[plugin] = struct{}{}
|
||||||
}
|
}
|
||||||
|
@ -191,18 +169,14 @@ func (e *Execution) ProtectPlugin(t assert.TestingT, plugins ...string) {
|
||||||
|
|
||||||
// ProtectPlugins protects existing plugins from being cleaned up at the end of
|
// ProtectPlugins protects existing plugins from being cleaned up at the end of
|
||||||
// test runs
|
// test runs
|
||||||
func ProtectPlugins(t assert.TestingT, testEnv *Execution) {
|
func ProtectPlugins(t testing.TB, testEnv *Execution) {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
plugins := getExistingPlugins(t, testEnv)
|
plugins := getExistingPlugins(t, testEnv)
|
||||||
testEnv.ProtectPlugin(t, plugins...)
|
testEnv.ProtectPlugin(t, plugins...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getExistingPlugins(t assert.TestingT, testEnv *Execution) []string {
|
func getExistingPlugins(t testing.TB, testEnv *Execution) []string {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
client := testEnv.APIClient()
|
client := testEnv.APIClient()
|
||||||
pluginList, err := client.PluginList(context.Background(), filters.Args{})
|
pluginList, err := client.PluginList(context.Background(), filters.Args{})
|
||||||
// Docker EE does not allow cluster-wide plugin management.
|
// Docker EE does not allow cluster-wide plugin management.
|
||||||
|
@ -219,10 +193,8 @@ func getExistingPlugins(t assert.TestingT, testEnv *Execution) []string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProtectVolume adds the specified volume(s) to be protected in case of clean
|
// ProtectVolume adds the specified volume(s) to be protected in case of clean
|
||||||
func (e *Execution) ProtectVolume(t assert.TestingT, volumes ...string) {
|
func (e *Execution) ProtectVolume(t testing.TB, volumes ...string) {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
for _, volume := range volumes {
|
for _, volume := range volumes {
|
||||||
e.protectedElements.volumes[volume] = struct{}{}
|
e.protectedElements.volumes[volume] = struct{}{}
|
||||||
}
|
}
|
||||||
|
@ -230,18 +202,14 @@ func (e *Execution) ProtectVolume(t assert.TestingT, volumes ...string) {
|
||||||
|
|
||||||
// ProtectVolumes protects existing volumes from being cleaned up at the end of
|
// ProtectVolumes protects existing volumes from being cleaned up at the end of
|
||||||
// test runs
|
// test runs
|
||||||
func ProtectVolumes(t assert.TestingT, testEnv *Execution) {
|
func ProtectVolumes(t testing.TB, testEnv *Execution) {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
volumes := getExistingVolumes(t, testEnv)
|
volumes := getExistingVolumes(t, testEnv)
|
||||||
testEnv.ProtectVolume(t, volumes...)
|
testEnv.ProtectVolume(t, volumes...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getExistingVolumes(t assert.TestingT, testEnv *Execution) []string {
|
func getExistingVolumes(t testing.TB, testEnv *Execution) []string {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
client := testEnv.APIClient()
|
client := testEnv.APIClient()
|
||||||
volumeList, err := client.VolumeList(context.Background(), filters.Args{})
|
volumeList, err := client.VolumeList(context.Background(), filters.Args{})
|
||||||
assert.NilError(t, err, "failed to list volumes")
|
assert.NilError(t, err, "failed to list volumes")
|
||||||
|
|
|
@ -10,8 +10,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/docker/docker/testutil"
|
"github.com/opencontainers/go-digest"
|
||||||
digest "github.com/opencontainers/go-digest"
|
|
||||||
"gotest.tools/assert"
|
"gotest.tools/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -176,10 +175,8 @@ func (r *V2) getBlobFilename(blobDigest digest.Digest) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadBlobContents read the file corresponding to the specified digest
|
// ReadBlobContents read the file corresponding to the specified digest
|
||||||
func (r *V2) ReadBlobContents(t assert.TestingT, blobDigest digest.Digest) []byte {
|
func (r *V2) ReadBlobContents(t testing.TB, blobDigest digest.Digest) []byte {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
// Load the target manifest blob.
|
// Load the target manifest blob.
|
||||||
manifestBlob, err := ioutil.ReadFile(r.getBlobFilename(blobDigest))
|
manifestBlob, err := ioutil.ReadFile(r.getBlobFilename(blobDigest))
|
||||||
assert.NilError(t, err, "unable to read blob")
|
assert.NilError(t, err, "unable to read blob")
|
||||||
|
@ -187,10 +184,8 @@ func (r *V2) ReadBlobContents(t assert.TestingT, blobDigest digest.Digest) []byt
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteBlobContents write the file corresponding to the specified digest with the given content
|
// WriteBlobContents write the file corresponding to the specified digest with the given content
|
||||||
func (r *V2) WriteBlobContents(t assert.TestingT, blobDigest digest.Digest, data []byte) {
|
func (r *V2) WriteBlobContents(t testing.TB, blobDigest digest.Digest, data []byte) {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
err := ioutil.WriteFile(r.getBlobFilename(blobDigest), data, os.FileMode(0644))
|
err := ioutil.WriteFile(r.getBlobFilename(blobDigest), data, os.FileMode(0644))
|
||||||
assert.NilError(t, err, "unable to write malicious data blob")
|
assert.NilError(t, err, "unable to write malicious data blob")
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,12 +11,12 @@ import (
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/docker/docker/client"
|
"github.com/docker/docker/client"
|
||||||
"github.com/docker/docker/opts"
|
"github.com/docker/docker/opts"
|
||||||
"github.com/docker/docker/pkg/ioutils"
|
"github.com/docker/docker/pkg/ioutils"
|
||||||
"github.com/docker/docker/testutil"
|
|
||||||
"github.com/docker/docker/testutil/environment"
|
"github.com/docker/docker/testutil/environment"
|
||||||
"github.com/docker/go-connections/sockets"
|
"github.com/docker/go-connections/sockets"
|
||||||
"github.com/docker/go-connections/tlsconfig"
|
"github.com/docker/go-connections/tlsconfig"
|
||||||
|
@ -25,10 +25,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewAPIClient returns a docker API client configured from environment variables
|
// NewAPIClient returns a docker API client configured from environment variables
|
||||||
func NewAPIClient(t assert.TestingT, ops ...client.Opt) client.APIClient {
|
func NewAPIClient(t testing.TB, ops ...client.Opt) client.APIClient {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
ops = append([]client.Opt{client.FromEnv}, ops...)
|
ops = append([]client.Opt{client.FromEnv}, ops...)
|
||||||
clt, err := client.NewClientWithOpts(ops...)
|
clt, err := client.NewClientWithOpts(ops...)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
@ -36,10 +34,8 @@ func NewAPIClient(t assert.TestingT, ops ...client.Opt) client.APIClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
// DaemonTime provides the current time on the daemon host
|
// DaemonTime provides the current time on the daemon host
|
||||||
func DaemonTime(ctx context.Context, t assert.TestingT, client client.APIClient, testEnv *environment.Execution) time.Time {
|
func DaemonTime(ctx context.Context, t testing.TB, client client.APIClient, testEnv *environment.Execution) time.Time {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
if testEnv.IsLocalDaemon() {
|
if testEnv.IsLocalDaemon() {
|
||||||
return time.Now()
|
return time.Now()
|
||||||
}
|
}
|
||||||
|
@ -54,10 +50,8 @@ func DaemonTime(ctx context.Context, t assert.TestingT, client client.APIClient,
|
||||||
|
|
||||||
// DaemonUnixTime returns the current time on the daemon host with nanoseconds precision.
|
// DaemonUnixTime returns the current time on the daemon host with nanoseconds precision.
|
||||||
// It return the time formatted how the client sends timestamps to the server.
|
// It return the time formatted how the client sends timestamps to the server.
|
||||||
func DaemonUnixTime(ctx context.Context, t assert.TestingT, client client.APIClient, testEnv *environment.Execution) string {
|
func DaemonUnixTime(ctx context.Context, t testing.TB, client client.APIClient, testEnv *environment.Execution) string {
|
||||||
if ht, ok := t.(testutil.HelperT); ok {
|
t.Helper()
|
||||||
ht.Helper()
|
|
||||||
}
|
|
||||||
dt := DaemonTime(ctx, t, client, testEnv)
|
dt := DaemonTime(ctx, t, client, testEnv)
|
||||||
return fmt.Sprintf("%d.%09d", dt.Unix(), int64(dt.Nanosecond()))
|
return fmt.Sprintf("%d.%09d", dt.Unix(), int64(dt.Nanosecond()))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue