| 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) |
| } |