list_test.go 3.6 KB

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