github.com/docker/docker@v299999999.0.0-20200612211812-aaf470eca7b5+incompatible/integration/service/jobs_test.go (about)

     1  package service
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  
     7  	"github.com/docker/docker/api/types"
     8  	swarmtypes "github.com/docker/docker/api/types/swarm"
     9  	"github.com/docker/docker/integration/internal/swarm"
    10  	"gotest.tools/v3/assert"
    11  	"gotest.tools/v3/poll"
    12  	"gotest.tools/v3/skip"
    13  )
    14  
    15  // The file jobs_test.go contains tests that verify that services which are in
    16  // the mode ReplicatedJob or GlobalJob.
    17  
    18  // TestCreateJob tests that a Service can be created and run with
    19  // mode ReplicatedJob
    20  func TestCreateJob(t *testing.T) {
    21  	skip.If(t, testEnv.IsRemoteDaemon)
    22  	skip.If(t, testEnv.DaemonInfo.OSType == "windows")
    23  
    24  	defer setupTest(t)
    25  
    26  	d := swarm.NewSwarm(t, testEnv)
    27  	defer d.Stop(t)
    28  
    29  	client := d.NewClientT(t)
    30  	defer client.Close()
    31  
    32  	for _, mode := range []swarmtypes.ServiceMode{
    33  		{ReplicatedJob: &swarmtypes.ReplicatedJob{}},
    34  		{GlobalJob: &swarmtypes.GlobalJob{}},
    35  	} {
    36  		id := swarm.CreateService(t, d, swarm.ServiceWithMode(mode))
    37  
    38  		poll.WaitOn(t, swarm.RunningTasksCount(client, id, 1), swarm.ServicePoll)
    39  	}
    40  }
    41  
    42  // TestReplicatedJob tests that running a replicated job starts the requisite
    43  // number of tasks,
    44  func TestReplicatedJob(t *testing.T) {
    45  	skip.If(t, testEnv.IsRemoteDaemon)
    46  	skip.If(t, testEnv.DaemonInfo.OSType == "windows")
    47  
    48  	// we need variables, because the replicas field takes a pointer
    49  	maxConcurrent := uint64(2)
    50  	// there is overhead, especially in the test environment, associated with
    51  	// starting tasks. if total is set too high, then the time needed to
    52  	// complete the test, even if everything is proceeding ideally, may exceed
    53  	// the time the test has to execute
    54  	//
    55  	// in CI,the test has been seen to time out with as few as 7 completions
    56  	// after 15 seconds. this means 7 completions ought not be too many.
    57  	total := uint64(7)
    58  
    59  	defer setupTest(t)
    60  
    61  	d := swarm.NewSwarm(t, testEnv)
    62  	defer d.Stop(t)
    63  
    64  	client := d.NewClientT(t)
    65  	defer client.Close()
    66  
    67  	id := swarm.CreateService(t, d,
    68  		swarm.ServiceWithMode(swarmtypes.ServiceMode{
    69  			ReplicatedJob: &swarmtypes.ReplicatedJob{
    70  				MaxConcurrent:    &maxConcurrent,
    71  				TotalCompletions: &total,
    72  			},
    73  		}),
    74  		// just run a command to execute and exit peacefully.
    75  		swarm.ServiceWithCommand([]string{"true"}),
    76  	)
    77  
    78  	service, _, err := client.ServiceInspectWithRaw(
    79  		context.Background(), id, types.ServiceInspectOptions{},
    80  	)
    81  	assert.NilError(t, err)
    82  
    83  	poll.WaitOn(t, swarm.JobComplete(client, service), swarm.ServicePoll)
    84  }
    85  
    86  // TestUpdateJob tests that a job can be updated, and that it runs with the
    87  // correct parameters.
    88  func TestUpdateReplicatedJob(t *testing.T) {
    89  	skip.If(t, testEnv.IsRemoteDaemon)
    90  	skip.If(t, testEnv.DaemonInfo.OSType == "windows")
    91  
    92  	defer setupTest(t)()
    93  
    94  	d := swarm.NewSwarm(t, testEnv)
    95  	defer d.Stop(t)
    96  
    97  	client := d.NewClientT(t)
    98  	defer client.Close()
    99  
   100  	// avoid writing "context.Background()" over and over again
   101  	ctx := context.Background()
   102  
   103  	// Create the job service
   104  	id := swarm.CreateService(t, d,
   105  		swarm.ServiceWithMode(swarmtypes.ServiceMode{
   106  			ReplicatedJob: &swarmtypes.ReplicatedJob{
   107  				// use the default, empty values.
   108  			},
   109  		}),
   110  		// run "true" so the task exits with 0
   111  		swarm.ServiceWithCommand([]string{"true"}),
   112  	)
   113  
   114  	service, _, err := client.ServiceInspectWithRaw(
   115  		ctx, id, types.ServiceInspectOptions{},
   116  	)
   117  	assert.NilError(t, err)
   118  
   119  	// wait for the job to completed
   120  	poll.WaitOn(t, swarm.JobComplete(client, service), swarm.ServicePoll)
   121  
   122  	// update the job.
   123  	spec := service.Spec
   124  	spec.TaskTemplate.ForceUpdate++
   125  
   126  	_, err = client.ServiceUpdate(
   127  		ctx, id, service.Version, spec, types.ServiceUpdateOptions{},
   128  	)
   129  	assert.NilError(t, err)
   130  
   131  	service2, _, err := client.ServiceInspectWithRaw(
   132  		ctx, id, types.ServiceInspectOptions{},
   133  	)
   134  	assert.NilError(t, err)
   135  
   136  	// assert that the job iteration has increased
   137  	assert.Assert(t,
   138  		service.JobStatus.JobIteration.Index < service2.JobStatus.JobIteration.Index,
   139  	)
   140  
   141  	// now wait for the service to complete a second time.
   142  	poll.WaitOn(t, swarm.JobComplete(client, service2), swarm.ServicePoll)
   143  }