File: jobs_test.go

package info (click to toggle)
docker.io 20.10.24%2Bdfsg1-1%2Bdeb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bookworm-proposed-updates
  • size: 60,824 kB
  • sloc: sh: 5,621; makefile: 593; ansic: 179; python: 162; asm: 7
file content (143 lines) | stat: -rw-r--r-- 3,980 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package service

import (
	"context"
	"testing"

	"github.com/docker/docker/api/types"
	swarmtypes "github.com/docker/docker/api/types/swarm"
	"github.com/docker/docker/integration/internal/swarm"
	"gotest.tools/v3/assert"
	"gotest.tools/v3/poll"
	"gotest.tools/v3/skip"
)

// The file jobs_test.go contains tests that verify that services which are in
// the mode ReplicatedJob or GlobalJob.

// TestCreateJob tests that a Service can be created and run with
// mode ReplicatedJob
func TestCreateJob(t *testing.T) {
	skip.If(t, testEnv.IsRemoteDaemon)
	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()

	for _, mode := range []swarmtypes.ServiceMode{
		{ReplicatedJob: &swarmtypes.ReplicatedJob{}},
		{GlobalJob: &swarmtypes.GlobalJob{}},
	} {
		id := swarm.CreateService(t, d, swarm.ServiceWithMode(mode))

		poll.WaitOn(t, swarm.RunningTasksCount(client, id, 1), swarm.ServicePoll)
	}
}

// TestReplicatedJob tests that running a replicated job starts the requisite
// number of tasks,
func TestReplicatedJob(t *testing.T) {
	skip.If(t, testEnv.IsRemoteDaemon)
	skip.If(t, testEnv.DaemonInfo.OSType == "windows")

	// we need variables, because the replicas field takes a pointer
	maxConcurrent := uint64(2)
	// there is overhead, especially in the test environment, associated with
	// starting tasks. if total is set too high, then the time needed to
	// complete the test, even if everything is proceeding ideally, may exceed
	// the time the test has to execute
	//
	// in CI,the test has been seen to time out with as few as 7 completions
	// after 15 seconds. this means 7 completions ought not be too many.
	total := uint64(7)

	defer setupTest(t)

	d := swarm.NewSwarm(t, testEnv)
	defer d.Stop(t)

	client := d.NewClientT(t)
	defer client.Close()

	id := swarm.CreateService(t, d,
		swarm.ServiceWithMode(swarmtypes.ServiceMode{
			ReplicatedJob: &swarmtypes.ReplicatedJob{
				MaxConcurrent:    &maxConcurrent,
				TotalCompletions: &total,
			},
		}),
		// just run a command to execute and exit peacefully.
		swarm.ServiceWithCommand([]string{"true"}),
	)

	service, _, err := client.ServiceInspectWithRaw(
		context.Background(), id, types.ServiceInspectOptions{},
	)
	assert.NilError(t, err)

	poll.WaitOn(t, swarm.JobComplete(client, service), swarm.ServicePoll)
}

// TestUpdateJob tests that a job can be updated, and that it runs with the
// correct parameters.
func TestUpdateReplicatedJob(t *testing.T) {
	skip.If(t, testEnv.IsRemoteDaemon)
	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()

	// avoid writing "context.Background()" over and over again
	ctx := context.Background()

	// Create the job service
	id := swarm.CreateService(t, d,
		swarm.ServiceWithMode(swarmtypes.ServiceMode{
			ReplicatedJob: &swarmtypes.ReplicatedJob{
				// use the default, empty values.
			},
		}),
		// run "true" so the task exits with 0
		swarm.ServiceWithCommand([]string{"true"}),
	)

	service, _, err := client.ServiceInspectWithRaw(
		ctx, id, types.ServiceInspectOptions{},
	)
	assert.NilError(t, err)

	// wait for the job to completed
	poll.WaitOn(t, swarm.JobComplete(client, service), swarm.ServicePoll)

	// update the job.
	spec := service.Spec
	spec.TaskTemplate.ForceUpdate++

	_, err = client.ServiceUpdate(
		ctx, id, service.Version, spec, types.ServiceUpdateOptions{},
	)
	assert.NilError(t, err)

	service2, _, err := client.ServiceInspectWithRaw(
		ctx, id, types.ServiceInspectOptions{},
	)
	assert.NilError(t, err)

	// assert that the job iteration has increased
	assert.Assert(t,
		service.JobStatus.JobIteration.Index < service2.JobStatus.JobIteration.Index,
	)

	// now wait for the service to complete a second time.
	poll.WaitOn(t, swarm.JobComplete(client, service2), swarm.ServicePoll)
}