github.com/rawahars/moby@v24.0.4+incompatible/integration/service/list_test.go (about)

     1  package service // import "github.com/docker/docker/integration/service"
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"testing"
     7  
     8  	"github.com/docker/docker/api/types"
     9  	"github.com/docker/docker/api/types/filters"
    10  	swarmtypes "github.com/docker/docker/api/types/swarm"
    11  	"github.com/docker/docker/api/types/versions"
    12  	"github.com/docker/docker/integration/internal/swarm"
    13  	"gotest.tools/v3/assert"
    14  	is "gotest.tools/v3/assert/cmp"
    15  	"gotest.tools/v3/poll"
    16  	"gotest.tools/v3/skip"
    17  )
    18  
    19  // TestServiceListWithStatuses tests that performing a ServiceList operation
    20  // correctly uses the Status parameter, and that the resulting response
    21  // contains correct service statuses.
    22  //
    23  // NOTE(dperny): because it's a pain to elicit the behavior of an unconverged
    24  // service reliably, I'm not testing that an unconverged service returns X
    25  // running and Y desired tasks. Instead, I'm just going to trust that I can
    26  // successfully assign a value to another value without screwing it up. The
    27  // logic for computing service statuses is in swarmkit anyway, not in the
    28  // engine, and is well-tested there, so this test just needs to make sure that
    29  // statuses get correctly associated with the right services.
    30  func TestServiceListWithStatuses(t *testing.T) {
    31  	skip.If(t, testEnv.IsRemoteDaemon)
    32  	skip.If(t, testEnv.DaemonInfo.OSType == "windows")
    33  	// statuses were added in API version 1.41
    34  	skip.If(t, versions.LessThan(testEnv.DaemonInfo.ServerVersion, "1.41"))
    35  	defer setupTest(t)()
    36  	d := swarm.NewSwarm(t, testEnv)
    37  	defer d.Stop(t)
    38  	client := d.NewClientT(t)
    39  	defer client.Close()
    40  
    41  	ctx := context.Background()
    42  
    43  	serviceCount := 3
    44  	// create some services.
    45  	for i := 0; i < serviceCount; i++ {
    46  		spec := fullSwarmServiceSpec(fmt.Sprintf("test-list-%d", i), uint64(i+1))
    47  		// for whatever reason, the args "-u root", when included, cause these
    48  		// tasks to fail and exit. instead, we'll just pass no args, which
    49  		// works.
    50  		spec.TaskTemplate.ContainerSpec.Args = []string{}
    51  		resp, err := client.ServiceCreate(ctx, spec, types.ServiceCreateOptions{
    52  			QueryRegistry: false,
    53  		})
    54  		assert.NilError(t, err)
    55  		id := resp.ID
    56  		// we need to wait specifically for the tasks to be running, which the
    57  		// serviceContainerCount function does not do. instead, we'll use a
    58  		// bespoke closure right here.
    59  		poll.WaitOn(t, func(log poll.LogT) poll.Result {
    60  			tasks, err := client.TaskList(context.Background(), types.TaskListOptions{
    61  				Filters: filters.NewArgs(filters.Arg("service", id)),
    62  			})
    63  
    64  			running := 0
    65  			for _, task := range tasks {
    66  				if task.Status.State == swarmtypes.TaskStateRunning {
    67  					running++
    68  				}
    69  			}
    70  
    71  			switch {
    72  			case err != nil:
    73  				return poll.Error(err)
    74  			case running == i+1:
    75  				return poll.Success()
    76  			default:
    77  				return poll.Continue(
    78  					"running task count %d (%d total), waiting for %d",
    79  					running, len(tasks), i+1,
    80  				)
    81  			}
    82  		})
    83  	}
    84  
    85  	// now, let's do the list operation with no status arg set.
    86  	resp, err := client.ServiceList(ctx, types.ServiceListOptions{})
    87  	assert.NilError(t, err)
    88  	assert.Check(t, is.Len(resp, serviceCount))
    89  	for _, service := range resp {
    90  		assert.Check(t, is.Nil(service.ServiceStatus))
    91  	}
    92  
    93  	// now try again, but with Status: true. This time, we should have statuses
    94  	resp, err = client.ServiceList(ctx, types.ServiceListOptions{Status: true})
    95  	assert.NilError(t, err)
    96  	assert.Check(t, is.Len(resp, serviceCount))
    97  	for _, service := range resp {
    98  		replicas := *service.Spec.Mode.Replicated.Replicas
    99  
   100  		assert.Assert(t, service.ServiceStatus != nil)
   101  		// Use assert.Check to not fail out of the test if this fails
   102  		assert.Check(t, is.Equal(service.ServiceStatus.DesiredTasks, replicas))
   103  		assert.Check(t, is.Equal(service.ServiceStatus.RunningTasks, replicas))
   104  	}
   105  }