Ver Fonte

Merge pull request #39771 from thaJeztah/cleanup_TestTemplatedConfig

Integration: fix various issues in "config" and "secret" tests
Brian Goff há 5 anos atrás
pai
commit
eac618caaa
2 ficheiros alterados com 173 adições e 222 exclusões
  1. 102 136
      integration/config/config_test.go
  2. 71 86
      integration/secret/secret_test.go

+ 102 - 136
integration/config/config_test.go

@@ -14,6 +14,7 @@ import (
 	"github.com/docker/docker/api/types/filters"
 	swarmtypes "github.com/docker/docker/api/types/swarm"
 	"github.com/docker/docker/client"
+	"github.com/docker/docker/errdefs"
 	"github.com/docker/docker/integration/internal/swarm"
 	"github.com/docker/docker/pkg/stdcopy"
 	"github.com/docker/docker/testutil/daemon"
@@ -23,19 +24,42 @@ import (
 	"gotest.tools/v3/skip"
 )
 
-func TestConfigList(t *testing.T) {
+func TestConfigInspect(t *testing.T) {
 	skip.If(t, testEnv.DaemonInfo.OSType == "windows")
 
 	defer setupTest(t)()
 	d := swarm.NewSwarm(t, testEnv)
 	defer d.Stop(t)
-	client := d.NewClientT(t)
-	defer client.Close()
+	c := d.NewClientT(t)
+	defer c.Close()
+
+	ctx := context.Background()
+
+	testName := t.Name()
+	configID := createConfig(ctx, t, c, testName, []byte("TESTINGDATA"), nil)
+
+	insp, body, err := c.ConfigInspectWithRaw(ctx, configID)
+	assert.NilError(t, err)
+	assert.Check(t, is.Equal(insp.Spec.Name, testName))
+
+	var config swarmtypes.Config
+	err = json.Unmarshal(body, &config)
+	assert.NilError(t, err)
+	assert.Check(t, is.DeepEqual(config, insp))
+}
 
+func TestConfigList(t *testing.T) {
+	skip.If(t, testEnv.DaemonInfo.OSType == "windows")
+
+	defer setupTest(t)()
+	d := swarm.NewSwarm(t, testEnv)
+	defer d.Stop(t)
+	c := d.NewClientT(t)
+	defer c.Close()
 	ctx := context.Background()
 
 	// This test case is ported from the original TestConfigsEmptyList
-	configs, err := client.ConfigList(ctx, types.ConfigListOptions{})
+	configs, err := c.ConfigList(ctx, types.ConfigListOptions{})
 	assert.NilError(t, err)
 	assert.Check(t, is.Equal(len(configs), 0))
 
@@ -45,12 +69,12 @@ func TestConfigList(t *testing.T) {
 	sort.Strings(testNames)
 
 	// create config test0
-	createConfig(ctx, t, client, testName0, []byte("TESTINGDATA0"), map[string]string{"type": "test"})
+	createConfig(ctx, t, c, testName0, []byte("TESTINGDATA0"), map[string]string{"type": "test"})
 
-	config1ID := createConfig(ctx, t, client, testName1, []byte("TESTINGDATA1"), map[string]string{"type": "production"})
+	config1ID := createConfig(ctx, t, c, testName1, []byte("TESTINGDATA1"), map[string]string{"type": "production"})
 
 	// test by `config ls`
-	entries, err := client.ConfigList(ctx, types.ConfigListOptions{})
+	entries, err := c.ConfigList(ctx, types.ConfigListOptions{})
 	assert.NilError(t, err)
 	assert.Check(t, is.DeepEqual(configNamesFromList(entries), testNames))
 
@@ -83,7 +107,7 @@ func TestConfigList(t *testing.T) {
 		},
 	}
 	for _, tc := range testCases {
-		entries, err = client.ConfigList(ctx, types.ConfigListOptions{
+		entries, err = c.ConfigList(ctx, types.ConfigListOptions{
 			Filters: tc.filters,
 		})
 		assert.NilError(t, err)
@@ -111,26 +135,36 @@ func TestConfigsCreateAndDelete(t *testing.T) {
 	defer setupTest(t)()
 	d := swarm.NewSwarm(t, testEnv)
 	defer d.Stop(t)
-	client := d.NewClientT(t)
-	defer client.Close()
-
+	c := d.NewClientT(t)
+	defer c.Close()
 	ctx := context.Background()
 
 	testName := "test_config-" + t.Name()
+	configID := createConfig(ctx, t, c, testName, []byte("TESTINGDATA"), nil)
 
-	// This test case is ported from the original TestConfigsCreate
-	configID := createConfig(ctx, t, client, testName, []byte("TESTINGDATA"), nil)
-
-	insp, _, err := client.ConfigInspectWithRaw(ctx, configID)
+	err := c.ConfigRemove(ctx, configID)
 	assert.NilError(t, err)
-	assert.Check(t, is.Equal(insp.Spec.Name, testName))
 
-	// This test case is ported from the original TestConfigsDelete
-	err = client.ConfigRemove(ctx, configID)
-	assert.NilError(t, err)
+	_, _, err = c.ConfigInspectWithRaw(ctx, configID)
+	assert.Check(t, errdefs.IsNotFound(err))
+	assert.Check(t, is.ErrorContains(err, configID))
 
-	insp, _, err = client.ConfigInspectWithRaw(ctx, configID)
-	assert.Check(t, is.ErrorContains(err, "No such config"))
+	err = c.ConfigRemove(ctx, "non-existing")
+	assert.Check(t, errdefs.IsNotFound(err))
+	assert.Check(t, is.ErrorContains(err, "non-existing"))
+
+	testName = "test_secret_with_labels_" + t.Name()
+	configID = createConfig(ctx, t, c, testName, []byte("TESTINGDATA"), map[string]string{
+		"key1": "value1",
+		"key2": "value2",
+	})
+
+	insp, _, err := c.ConfigInspectWithRaw(ctx, configID)
+	assert.NilError(t, err)
+	assert.Check(t, is.Equal(insp.Spec.Name, testName))
+	assert.Check(t, is.Equal(len(insp.Spec.Labels), 2))
+	assert.Check(t, is.Equal(insp.Spec.Labels["key1"], "value1"))
+	assert.Check(t, is.Equal(insp.Spec.Labels["key2"], "value2"))
 }
 
 func TestConfigsUpdate(t *testing.T) {
@@ -139,51 +173,49 @@ func TestConfigsUpdate(t *testing.T) {
 	defer setupTest(t)()
 	d := swarm.NewSwarm(t, testEnv)
 	defer d.Stop(t)
-	client := d.NewClientT(t)
-	defer client.Close()
-
+	c := d.NewClientT(t)
+	defer c.Close()
 	ctx := context.Background()
 
 	testName := "test_config-" + t.Name()
+	configID := createConfig(ctx, t, c, testName, []byte("TESTINGDATA"), nil)
 
-	// This test case is ported from the original TestConfigsCreate
-	configID := createConfig(ctx, t, client, testName, []byte("TESTINGDATA"), nil)
-
-	insp, _, err := client.ConfigInspectWithRaw(ctx, configID)
+	insp, _, err := c.ConfigInspectWithRaw(ctx, configID)
 	assert.NilError(t, err)
 	assert.Check(t, is.Equal(insp.ID, configID))
 
 	// test UpdateConfig with full ID
 	insp.Spec.Labels = map[string]string{"test": "test1"}
-	err = client.ConfigUpdate(ctx, configID, insp.Version, insp.Spec)
+	err = c.ConfigUpdate(ctx, configID, insp.Version, insp.Spec)
 	assert.NilError(t, err)
 
-	insp, _, err = client.ConfigInspectWithRaw(ctx, configID)
+	insp, _, err = c.ConfigInspectWithRaw(ctx, configID)
 	assert.NilError(t, err)
 	assert.Check(t, is.Equal(insp.Spec.Labels["test"], "test1"))
 
 	// test UpdateConfig with full name
 	insp.Spec.Labels = map[string]string{"test": "test2"}
-	err = client.ConfigUpdate(ctx, testName, insp.Version, insp.Spec)
+	err = c.ConfigUpdate(ctx, testName, insp.Version, insp.Spec)
 	assert.NilError(t, err)
 
-	insp, _, err = client.ConfigInspectWithRaw(ctx, configID)
+	insp, _, err = c.ConfigInspectWithRaw(ctx, configID)
 	assert.NilError(t, err)
 	assert.Check(t, is.Equal(insp.Spec.Labels["test"], "test2"))
 
 	// test UpdateConfig with prefix ID
 	insp.Spec.Labels = map[string]string{"test": "test3"}
-	err = client.ConfigUpdate(ctx, configID[:1], insp.Version, insp.Spec)
+	err = c.ConfigUpdate(ctx, configID[:1], insp.Version, insp.Spec)
 	assert.NilError(t, err)
 
-	insp, _, err = client.ConfigInspectWithRaw(ctx, configID)
+	insp, _, err = c.ConfigInspectWithRaw(ctx, configID)
 	assert.NilError(t, err)
 	assert.Check(t, is.Equal(insp.Spec.Labels["test"], "test3"))
 
 	// test UpdateConfig in updating Data which is not supported in daemon
 	// this test will produce an error in func UpdateConfig
 	insp.Spec.Data = []byte("TESTINGDATA2")
-	err = client.ConfigUpdate(ctx, configID, insp.Version, insp.Spec)
+	err = c.ConfigUpdate(ctx, configID, insp.Version, insp.Spec)
+	assert.Check(t, errdefs.IsInvalidParameter(err))
 	assert.Check(t, is.ErrorContains(err, "only updates to Labels are allowed"))
 }
 
@@ -191,8 +223,8 @@ func TestTemplatedConfig(t *testing.T) {
 	skip.If(t, testEnv.DaemonInfo.OSType == "windows")
 	d := swarm.NewSwarm(t, testEnv)
 	defer d.Stop(t)
-	client := d.NewClientT(t)
-	defer client.Close()
+	c := d.NewClientT(t)
+	defer c.Close()
 	ctx := context.Background()
 
 	referencedSecretName := "referencedsecret-" + t.Name()
@@ -202,7 +234,7 @@ func TestTemplatedConfig(t *testing.T) {
 		},
 		Data: []byte("this is a secret"),
 	}
-	referencedSecret, err := client.SecretCreate(ctx, referencedSecretSpec)
+	referencedSecret, err := c.SecretCreate(ctx, referencedSecretSpec)
 	assert.Check(t, err)
 
 	referencedConfigName := "referencedconfig-" + t.Name()
@@ -212,7 +244,7 @@ func TestTemplatedConfig(t *testing.T) {
 		},
 		Data: []byte("this is a config"),
 	}
-	referencedConfig, err := client.ConfigCreate(ctx, referencedConfigSpec)
+	referencedConfig, err := c.ConfigCreate(ctx, referencedConfigSpec)
 	assert.Check(t, err)
 
 	templatedConfigName := "templated_config-" + t.Name()
@@ -228,14 +260,15 @@ func TestTemplatedConfig(t *testing.T) {
 			"{{config \"referencedconfigtarget\"}}\n"),
 	}
 
-	templatedConfig, err := client.ConfigCreate(ctx, configSpec)
+	templatedConfig, err := c.ConfigCreate(ctx, configSpec)
 	assert.Check(t, err)
 
+	serviceName := "svc_" + t.Name()
 	serviceID := swarm.CreateService(t, d,
 		swarm.ServiceWithConfig(
 			&swarmtypes.ConfigReference{
 				File: &swarmtypes.ConfigReferenceFileTarget{
-					Name: "/" + templatedConfigName,
+					Name: "templated_config",
 					UID:  "0",
 					GID:  "0",
 					Mode: 0600,
@@ -268,105 +301,31 @@ func TestTemplatedConfig(t *testing.T) {
 				SecretName: referencedSecretName,
 			},
 		),
-		swarm.ServiceWithName("svc"),
+		swarm.ServiceWithName(serviceName),
 	)
 
-	var tasks []swarmtypes.Task
-	getRunningTasks := func(log poll.LogT) poll.Result {
-		tasks = swarm.GetRunningTasks(t, client, serviceID)
-		if len(tasks) > 0 {
-			return poll.Success()
-		}
-		return poll.Continue("task still waiting")
-	}
-	poll.WaitOn(t, getRunningTasks, swarm.ServicePoll, poll.WithTimeout(1*time.Minute))
-
-	task := tasks[0]
-	getTask := func(log poll.LogT) poll.Result {
-		if task.NodeID == "" || (task.Status.ContainerStatus == nil || task.Status.ContainerStatus.ContainerID == "") {
-			task, _, _ = client.TaskInspectWithRaw(context.Background(), task.ID)
-		}
-		if task.NodeID != "" && task.Status.ContainerStatus != nil && task.Status.ContainerStatus.ContainerID != "" {
-			return poll.Success()
-		}
-		return poll.Continue("task still waiting")
-	}
-	poll.WaitOn(t, getTask, swarm.ServicePoll, poll.WithTimeout(1*time.Minute))
+	poll.WaitOn(t, swarm.RunningTasksCount(c, serviceID, 1), swarm.ServicePoll, poll.WithTimeout(1*time.Minute))
 
-	attach := swarm.ExecTask(t, d, task, types.ExecConfig{
-		Cmd:          []string{"/bin/cat", "/" + templatedConfigName},
+	tasks := swarm.GetRunningTasks(t, c, serviceID)
+	assert.Assert(t, len(tasks) > 0, "no running tasks found for service %s", serviceID)
+
+	attach := swarm.ExecTask(t, d, tasks[0], types.ExecConfig{
+		Cmd:          []string{"/bin/cat", "/templated_config"},
 		AttachStdout: true,
 		AttachStderr: true,
 	})
 
-	expect := "SERVICE_NAME=svc\n" +
+	expect := "SERVICE_NAME=" + serviceName + "\n" +
 		"this is a secret\n" +
 		"this is a config\n"
 	assertAttachedStream(t, attach, expect)
 
-	attach = swarm.ExecTask(t, d, task, types.ExecConfig{
+	attach = swarm.ExecTask(t, d, tasks[0], types.ExecConfig{
 		Cmd:          []string{"mount"},
 		AttachStdout: true,
 		AttachStderr: true,
 	})
-	assertAttachedStream(t, attach, "tmpfs on /"+templatedConfigName+" type tmpfs")
-}
-
-func assertAttachedStream(t *testing.T, attach types.HijackedResponse, expect string) {
-	buf := bytes.NewBuffer(nil)
-	_, err := stdcopy.StdCopy(buf, buf, attach.Reader)
-	assert.NilError(t, err)
-	assert.Check(t, is.Contains(buf.String(), expect))
-}
-
-func TestConfigInspect(t *testing.T) {
-	skip.If(t, testEnv.DaemonInfo.OSType == "windows")
-
-	defer setupTest(t)()
-	d := swarm.NewSwarm(t, testEnv)
-	defer d.Stop(t)
-	client := d.NewClientT(t)
-	defer client.Close()
-
-	ctx := context.Background()
-
-	testName := t.Name()
-	configID := createConfig(ctx, t, client, testName, []byte("TESTINGDATA"), nil)
-
-	insp, body, err := client.ConfigInspectWithRaw(ctx, configID)
-	assert.NilError(t, err)
-	assert.Check(t, is.Equal(insp.Spec.Name, testName))
-
-	var config swarmtypes.Config
-	err = json.Unmarshal(body, &config)
-	assert.NilError(t, err)
-	assert.Check(t, is.DeepEqual(config, insp))
-}
-
-func TestConfigCreateWithLabels(t *testing.T) {
-	skip.If(t, testEnv.DaemonInfo.OSType != "linux")
-
-	defer setupTest(t)()
-	d := swarm.NewSwarm(t, testEnv)
-	defer d.Stop(t)
-	client := d.NewClientT(t)
-	defer client.Close()
-
-	ctx := context.Background()
-
-	labels := map[string]string{
-		"key1": "value1",
-		"key2": "value2",
-	}
-	testName := t.Name()
-	configID := createConfig(ctx, t, client, testName, []byte("TESTINGDATA"), labels)
-
-	insp, _, err := client.ConfigInspectWithRaw(ctx, configID)
-	assert.NilError(t, err)
-	assert.Check(t, is.Equal(insp.Spec.Name, testName))
-	assert.Check(t, is.Equal(2, len(insp.Spec.Labels)))
-	assert.Check(t, is.Equal("value1", insp.Spec.Labels["key1"]))
-	assert.Check(t, is.Equal("value2", insp.Spec.Labels["key2"]))
+	assertAttachedStream(t, attach, "tmpfs on /templated_config type tmpfs")
 }
 
 // Test case for 28884
@@ -376,27 +335,27 @@ func TestConfigCreateResolve(t *testing.T) {
 	defer setupTest(t)()
 	d := swarm.NewSwarm(t, testEnv)
 	defer d.Stop(t)
-	client := d.NewClientT(t)
-	defer client.Close()
+	c := d.NewClientT(t)
+	defer c.Close()
 
 	ctx := context.Background()
 
 	configName := "test_config_" + t.Name()
+	configID := createConfig(ctx, t, c, configName, []byte("foo"), nil)
 
-	configID := createConfig(ctx, t, client, configName, []byte("foo"), nil)
 	fakeName := configID
-	fakeID := createConfig(ctx, t, client, fakeName, []byte("fake foo"), nil)
+	fakeID := createConfig(ctx, t, c, fakeName, []byte("fake foo"), nil)
 
-	entries, err := client.ConfigList(ctx, types.ConfigListOptions{})
+	entries, err := c.ConfigList(ctx, types.ConfigListOptions{})
 	assert.NilError(t, err)
 	assert.Assert(t, is.Contains(configNamesFromList(entries), configName))
 	assert.Assert(t, is.Contains(configNamesFromList(entries), fakeName))
 
-	err = client.ConfigRemove(ctx, configID)
+	err = c.ConfigRemove(ctx, configID)
 	assert.NilError(t, err)
 
 	// Fake one will remain
-	entries, err = client.ConfigList(ctx, types.ConfigListOptions{})
+	entries, err = c.ConfigList(ctx, types.ConfigListOptions{})
 	assert.NilError(t, err)
 	assert.Assert(t, is.DeepEqual(configNamesFromList(entries), []string{fakeName}))
 
@@ -406,16 +365,16 @@ func TestConfigCreateResolve(t *testing.T) {
 	// - Full ID
 	// - Full Name
 	// - Partial ID (prefix)
-	err = client.ConfigRemove(ctx, configID[:5])
+	err = c.ConfigRemove(ctx, configID[:5])
 	assert.Assert(t, nil != err)
-	entries, err = client.ConfigList(ctx, types.ConfigListOptions{})
+	entries, err = c.ConfigList(ctx, types.ConfigListOptions{})
 	assert.NilError(t, err)
 	assert.Assert(t, is.DeepEqual(configNamesFromList(entries), []string{fakeName}))
 
 	// Remove based on ID prefix of the fake one should succeed
-	err = client.ConfigRemove(ctx, fakeID[:5])
+	err = c.ConfigRemove(ctx, fakeID[:5])
 	assert.NilError(t, err)
-	entries, err = client.ConfigList(ctx, types.ConfigListOptions{})
+	entries, err = c.ConfigList(ctx, types.ConfigListOptions{})
 	assert.NilError(t, err)
 	assert.Assert(t, is.Equal(0, len(entries)))
 }
@@ -440,6 +399,13 @@ func TestConfigDaemonLibtrustID(t *testing.T) {
 	assert.Equal(t, info.ID, "WTJ3:YSIP:CE2E:G6KJ:PSBD:YX2Y:WEYD:M64G:NU2V:XPZV:H2CR:VLUB")
 }
 
+func assertAttachedStream(t *testing.T, attach types.HijackedResponse, expect string) {
+	buf := bytes.NewBuffer(nil)
+	_, err := stdcopy.StdCopy(buf, buf, attach.Reader)
+	assert.NilError(t, err)
+	assert.Check(t, is.Contains(buf.String(), expect))
+}
+
 func configNamesFromList(entries []swarmtypes.Config) []string {
 	var values []string
 	for _, entry := range entries {

+ 71 - 86
integration/secret/secret_test.go

@@ -3,6 +3,7 @@ package secret // import "github.com/docker/docker/integration/secret"
 import (
 	"bytes"
 	"context"
+	"encoding/json"
 	"sort"
 	"testing"
 	"time"
@@ -11,10 +12,12 @@ import (
 	"github.com/docker/docker/api/types/filters"
 	swarmtypes "github.com/docker/docker/api/types/swarm"
 	"github.com/docker/docker/client"
+	"github.com/docker/docker/errdefs"
 	"github.com/docker/docker/integration/internal/swarm"
 	"github.com/docker/docker/pkg/stdcopy"
 	"gotest.tools/v3/assert"
 	is "gotest.tools/v3/assert/cmp"
+	"gotest.tools/v3/poll"
 	"gotest.tools/v3/skip"
 )
 
@@ -24,21 +27,22 @@ func TestSecretInspect(t *testing.T) {
 	defer setupTest(t)()
 	d := swarm.NewSwarm(t, testEnv)
 	defer d.Stop(t)
-	client := d.NewClientT(t)
-	defer client.Close()
+	c := d.NewClientT(t)
+	defer c.Close()
 
 	ctx := context.Background()
 
-	testName := "test_secret_" + t.Name()
-	secretID := createSecret(ctx, t, client, testName, []byte("TESTINGDATA"), nil)
+	testName := t.Name()
+	secretID := createSecret(ctx, t, c, testName, []byte("TESTINGDATA"), nil)
 
-	secret, _, err := client.SecretInspectWithRaw(context.Background(), secretID)
+	insp, body, err := c.SecretInspectWithRaw(ctx, secretID)
 	assert.NilError(t, err)
-	assert.Check(t, is.Equal(secret.Spec.Name, testName))
+	assert.Check(t, is.Equal(insp.Spec.Name, testName))
 
-	secret, _, err = client.SecretInspectWithRaw(context.Background(), testName)
+	var secret swarmtypes.Secret
+	err = json.Unmarshal(body, &secret)
 	assert.NilError(t, err)
-	assert.Check(t, is.Equal(secretID, secretID))
+	assert.Check(t, is.DeepEqual(secret, insp))
 }
 
 func TestSecretList(t *testing.T) {
@@ -47,23 +51,27 @@ func TestSecretList(t *testing.T) {
 	defer setupTest(t)()
 	d := swarm.NewSwarm(t, testEnv)
 	defer d.Stop(t)
-	client := d.NewClientT(t)
-	defer client.Close()
+	c := d.NewClientT(t)
+	defer c.Close()
 	ctx := context.Background()
 
+	configs, err := c.SecretList(ctx, types.SecretListOptions{})
+	assert.NilError(t, err)
+	assert.Check(t, is.Equal(len(configs), 0))
+
 	testName0 := "test0_" + t.Name()
 	testName1 := "test1_" + t.Name()
 	testNames := []string{testName0, testName1}
 	sort.Strings(testNames)
 
 	// create secret test0
-	createSecret(ctx, t, client, testName0, []byte("TESTINGDATA0"), map[string]string{"type": "test"})
+	createSecret(ctx, t, c, testName0, []byte("TESTINGDATA0"), map[string]string{"type": "test"})
 
 	// create secret test1
-	secret1ID := createSecret(ctx, t, client, testName1, []byte("TESTINGDATA1"), map[string]string{"type": "production"})
+	secret1ID := createSecret(ctx, t, c, testName1, []byte("TESTINGDATA1"), map[string]string{"type": "production"})
 
 	// test by `secret ls`
-	entries, err := client.SecretList(ctx, types.SecretListOptions{})
+	entries, err := c.SecretList(ctx, types.SecretListOptions{})
 	assert.NilError(t, err)
 	assert.Check(t, is.DeepEqual(secretNamesFromList(entries), testNames))
 
@@ -96,7 +104,7 @@ func TestSecretList(t *testing.T) {
 		},
 	}
 	for _, tc := range testCases {
-		entries, err = client.SecretList(ctx, types.SecretListOptions{
+		entries, err = c.SecretList(ctx, types.SecretListOptions{
 			Filters: tc.filters,
 		})
 		assert.NilError(t, err)
@@ -124,40 +132,41 @@ func TestSecretsCreateAndDelete(t *testing.T) {
 	defer setupTest(t)()
 	d := swarm.NewSwarm(t, testEnv)
 	defer d.Stop(t)
-	client := d.NewClientT(t)
-	defer client.Close()
+	c := d.NewClientT(t)
+	defer c.Close()
 	ctx := context.Background()
 
 	testName := "test_secret_" + t.Name()
-	secretID := createSecret(ctx, t, client, testName, []byte("TESTINGDATA"), nil)
+	secretID := createSecret(ctx, t, c, testName, []byte("TESTINGDATA"), nil)
 
-	// create an already existin secret, daemon should return a status code of 409
-	_, err := client.SecretCreate(ctx, swarmtypes.SecretSpec{
+	// create an already existing secret, daemon should return a status code of 409
+	_, err := c.SecretCreate(ctx, swarmtypes.SecretSpec{
 		Annotations: swarmtypes.Annotations{
 			Name: testName,
 		},
 		Data: []byte("TESTINGDATA"),
 	})
-	assert.Check(t, is.ErrorContains(err, "already exists"))
+	assert.Check(t, errdefs.IsConflict(err))
+	assert.Check(t, is.ErrorContains(err, testName))
 
-	// Ported from original TestSecretsDelete
-	err = client.SecretRemove(ctx, secretID)
+	err = c.SecretRemove(ctx, secretID)
 	assert.NilError(t, err)
 
-	_, _, err = client.SecretInspectWithRaw(ctx, secretID)
-	assert.Check(t, is.ErrorContains(err, "No such secret"))
+	_, _, err = c.SecretInspectWithRaw(ctx, secretID)
+	assert.Check(t, errdefs.IsNotFound(err))
+	assert.Check(t, is.ErrorContains(err, secretID))
 
-	err = client.SecretRemove(ctx, "non-existin")
-	assert.Check(t, is.ErrorContains(err, "No such secret: non-existin"))
+	err = c.SecretRemove(ctx, "non-existing")
+	assert.Check(t, errdefs.IsNotFound(err))
+	assert.Check(t, is.ErrorContains(err, "non-existing"))
 
-	// Ported from original TestSecretsCreteaWithLabels
 	testName = "test_secret_with_labels_" + t.Name()
-	secretID = createSecret(ctx, t, client, testName, []byte("TESTINGDATA"), map[string]string{
+	secretID = createSecret(ctx, t, c, testName, []byte("TESTINGDATA"), map[string]string{
 		"key1": "value1",
 		"key2": "value2",
 	})
 
-	insp, _, err := client.SecretInspectWithRaw(ctx, secretID)
+	insp, _, err := c.SecretInspectWithRaw(ctx, secretID)
 	assert.NilError(t, err)
 	assert.Check(t, is.Equal(insp.Spec.Name, testName))
 	assert.Check(t, is.Equal(len(insp.Spec.Labels), 2))
@@ -171,48 +180,49 @@ func TestSecretsUpdate(t *testing.T) {
 	defer setupTest(t)()
 	d := swarm.NewSwarm(t, testEnv)
 	defer d.Stop(t)
-	client := d.NewClientT(t)
-	defer client.Close()
+	c := d.NewClientT(t)
+	defer c.Close()
 	ctx := context.Background()
 
 	testName := "test_secret_" + t.Name()
-	secretID := createSecret(ctx, t, client, testName, []byte("TESTINGDATA"), nil)
+	secretID := createSecret(ctx, t, c, testName, []byte("TESTINGDATA"), nil)
 
-	insp, _, err := client.SecretInspectWithRaw(ctx, secretID)
+	insp, _, err := c.SecretInspectWithRaw(ctx, secretID)
 	assert.NilError(t, err)
 	assert.Check(t, is.Equal(insp.ID, secretID))
 
 	// test UpdateSecret with full ID
 	insp.Spec.Labels = map[string]string{"test": "test1"}
-	err = client.SecretUpdate(ctx, secretID, insp.Version, insp.Spec)
+	err = c.SecretUpdate(ctx, secretID, insp.Version, insp.Spec)
 	assert.NilError(t, err)
 
-	insp, _, err = client.SecretInspectWithRaw(ctx, secretID)
+	insp, _, err = c.SecretInspectWithRaw(ctx, secretID)
 	assert.NilError(t, err)
 	assert.Check(t, is.Equal(insp.Spec.Labels["test"], "test1"))
 
 	// test UpdateSecret with full name
 	insp.Spec.Labels = map[string]string{"test": "test2"}
-	err = client.SecretUpdate(ctx, testName, insp.Version, insp.Spec)
+	err = c.SecretUpdate(ctx, testName, insp.Version, insp.Spec)
 	assert.NilError(t, err)
 
-	insp, _, err = client.SecretInspectWithRaw(ctx, secretID)
+	insp, _, err = c.SecretInspectWithRaw(ctx, secretID)
 	assert.NilError(t, err)
 	assert.Check(t, is.Equal(insp.Spec.Labels["test"], "test2"))
 
 	// test UpdateSecret with prefix ID
 	insp.Spec.Labels = map[string]string{"test": "test3"}
-	err = client.SecretUpdate(ctx, secretID[:1], insp.Version, insp.Spec)
+	err = c.SecretUpdate(ctx, secretID[:1], insp.Version, insp.Spec)
 	assert.NilError(t, err)
 
-	insp, _, err = client.SecretInspectWithRaw(ctx, secretID)
+	insp, _, err = c.SecretInspectWithRaw(ctx, secretID)
 	assert.NilError(t, err)
 	assert.Check(t, is.Equal(insp.Spec.Labels["test"], "test3"))
 
 	// test UpdateSecret in updating Data which is not supported in daemon
 	// this test will produce an error in func UpdateSecret
 	insp.Spec.Data = []byte("TESTINGDATA2")
-	err = client.SecretUpdate(ctx, secretID, insp.Version, insp.Spec)
+	err = c.SecretUpdate(ctx, secretID, insp.Version, insp.Spec)
+	assert.Check(t, errdefs.IsInvalidParameter(err))
 	assert.Check(t, is.ErrorContains(err, "only updates to Labels are allowed"))
 }
 
@@ -220,8 +230,8 @@ func TestTemplatedSecret(t *testing.T) {
 	skip.If(t, testEnv.DaemonInfo.OSType == "windows")
 	d := swarm.NewSwarm(t, testEnv)
 	defer d.Stop(t)
-	client := d.NewClientT(t)
-	defer client.Close()
+	c := d.NewClientT(t)
+	defer c.Close()
 	ctx := context.Background()
 
 	referencedSecretName := "referencedsecret_" + t.Name()
@@ -231,7 +241,7 @@ func TestTemplatedSecret(t *testing.T) {
 		},
 		Data: []byte("this is a secret"),
 	}
-	referencedSecret, err := client.SecretCreate(ctx, referencedSecretSpec)
+	referencedSecret, err := c.SecretCreate(ctx, referencedSecretSpec)
 	assert.Check(t, err)
 
 	referencedConfigName := "referencedconfig_" + t.Name()
@@ -241,7 +251,7 @@ func TestTemplatedSecret(t *testing.T) {
 		},
 		Data: []byte("this is a config"),
 	}
-	referencedConfig, err := client.ConfigCreate(ctx, referencedConfigSpec)
+	referencedConfig, err := c.ConfigCreate(ctx, referencedConfigSpec)
 	assert.Check(t, err)
 
 	templatedSecretName := "templated_secret_" + t.Name()
@@ -257,7 +267,7 @@ func TestTemplatedSecret(t *testing.T) {
 			"{{config \"referencedconfigtarget\"}}\n"),
 	}
 
-	templatedSecret, err := client.SecretCreate(ctx, secretSpec)
+	templatedSecret, err := c.SecretCreate(ctx, secretSpec)
 	assert.Check(t, err)
 
 	serviceName := "svc_" + t.Name()
@@ -301,21 +311,12 @@ func TestTemplatedSecret(t *testing.T) {
 		swarm.ServiceWithName(serviceName),
 	)
 
-	var tasks []swarmtypes.Task
-	waitAndAssert(t, 60*time.Second, func(t *testing.T) bool {
-		tasks = swarm.GetRunningTasks(t, client, serviceID)
-		return len(tasks) > 0
-	})
+	poll.WaitOn(t, swarm.RunningTasksCount(c, serviceID, 1), swarm.ServicePoll, poll.WithTimeout(1*time.Minute))
 
-	task := tasks[0]
-	waitAndAssert(t, 60*time.Second, func(t *testing.T) bool {
-		if task.NodeID == "" || (task.Status.ContainerStatus == nil || task.Status.ContainerStatus.ContainerID == "") {
-			task, _, _ = client.TaskInspectWithRaw(context.Background(), task.ID)
-		}
-		return task.NodeID != "" && task.Status.ContainerStatus != nil && task.Status.ContainerStatus.ContainerID != ""
-	})
+	tasks := swarm.GetRunningTasks(t, c, serviceID)
+	assert.Assert(t, len(tasks) > 0, "no running tasks found for service %s", serviceID)
 
-	attach := swarm.ExecTask(t, d, task, types.ExecConfig{
+	attach := swarm.ExecTask(t, d, tasks[0], types.ExecConfig{
 		Cmd:          []string{"/bin/cat", "/run/secrets/templated_secret"},
 		AttachStdout: true,
 		AttachStderr: true,
@@ -326,7 +327,7 @@ func TestTemplatedSecret(t *testing.T) {
 		"this is a config\n"
 	assertAttachedStream(t, attach, expect)
 
-	attach = swarm.ExecTask(t, d, task, types.ExecConfig{
+	attach = swarm.ExecTask(t, d, tasks[0], types.ExecConfig{
 		Cmd:          []string{"mount"},
 		AttachStdout: true,
 		AttachStderr: true,
@@ -341,27 +342,27 @@ func TestSecretCreateResolve(t *testing.T) {
 	defer setupTest(t)()
 	d := swarm.NewSwarm(t, testEnv)
 	defer d.Stop(t)
-	client := d.NewClientT(t)
-	defer client.Close()
+	c := d.NewClientT(t)
+	defer c.Close()
 
 	ctx := context.Background()
 
 	testName := "test_secret_" + t.Name()
-	secretID := createSecret(ctx, t, client, testName, []byte("foo"), nil)
+	secretID := createSecret(ctx, t, c, testName, []byte("foo"), nil)
 
 	fakeName := secretID
-	fakeID := createSecret(ctx, t, client, fakeName, []byte("fake foo"), nil)
+	fakeID := createSecret(ctx, t, c, fakeName, []byte("fake foo"), nil)
 
-	entries, err := client.SecretList(ctx, types.SecretListOptions{})
+	entries, err := c.SecretList(ctx, types.SecretListOptions{})
 	assert.NilError(t, err)
 	assert.Check(t, is.Contains(secretNamesFromList(entries), testName))
 	assert.Check(t, is.Contains(secretNamesFromList(entries), fakeName))
 
-	err = client.SecretRemove(ctx, secretID)
+	err = c.SecretRemove(ctx, secretID)
 	assert.NilError(t, err)
 
 	// Fake one will remain
-	entries, err = client.SecretList(ctx, types.SecretListOptions{})
+	entries, err = c.SecretList(ctx, types.SecretListOptions{})
 	assert.NilError(t, err)
 	assert.Assert(t, is.DeepEqual(secretNamesFromList(entries), []string{fakeName}))
 
@@ -370,16 +371,16 @@ func TestSecretCreateResolve(t *testing.T) {
 	// - Full ID
 	// - Full Name
 	// - Partial ID (prefix)
-	err = client.SecretRemove(ctx, fakeName[:5])
+	err = c.SecretRemove(ctx, fakeName[:5])
 	assert.Assert(t, nil != err)
-	entries, err = client.SecretList(ctx, types.SecretListOptions{})
+	entries, err = c.SecretList(ctx, types.SecretListOptions{})
 	assert.NilError(t, err)
 	assert.Assert(t, is.DeepEqual(secretNamesFromList(entries), []string{fakeName}))
 
 	// Remove based on ID prefix of the fake one should succeed
-	err = client.SecretRemove(ctx, fakeID[:5])
+	err = c.SecretRemove(ctx, fakeID[:5])
 	assert.NilError(t, err)
-	entries, err = client.SecretList(ctx, types.SecretListOptions{})
+	entries, err = c.SecretList(ctx, types.SecretListOptions{})
 	assert.NilError(t, err)
 	assert.Assert(t, is.Equal(0, len(entries)))
 }
@@ -391,22 +392,6 @@ func assertAttachedStream(t *testing.T, attach types.HijackedResponse, expect st
 	assert.Check(t, is.Contains(buf.String(), expect))
 }
 
-func waitAndAssert(t *testing.T, timeout time.Duration, f func(*testing.T) bool) {
-	t.Helper()
-	after := time.After(timeout)
-	for {
-		select {
-		case <-after:
-			t.Fatal("timed out waiting for condition")
-		default:
-		}
-		if f(t) {
-			return
-		}
-		time.Sleep(100 * time.Millisecond)
-	}
-}
-
 func secretNamesFromList(entries []swarmtypes.Secret) []string {
 	var values []string
 	for _, entry := range entries {