github.com/Prakhar-Agarwal-byte/moby@v0.0.0-20231027092010-a14e3e8ab87e/integration/service/list_test.go (about)

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