daemon.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. package daemon // import "github.com/docker/docker/integration-cli/daemon"
  2. import (
  3. "fmt"
  4. "strings"
  5. "testing"
  6. "time"
  7. "github.com/docker/docker/testutil/daemon"
  8. "github.com/pkg/errors"
  9. "gotest.tools/v3/assert"
  10. "gotest.tools/v3/icmd"
  11. )
  12. // Daemon represents a Docker daemon for the testing framework.
  13. type Daemon struct {
  14. *daemon.Daemon
  15. dockerBinary string
  16. }
  17. // New returns a Daemon instance to be used for testing.
  18. // This will create a directory such as d123456789 in the folder specified by $DOCKER_INTEGRATION_DAEMON_DEST or $DEST.
  19. // The daemon will not automatically start.
  20. func New(t testing.TB, dockerBinary string, dockerdBinary string, ops ...daemon.Option) *Daemon {
  21. t.Helper()
  22. ops = append(ops, daemon.WithDockerdBinary(dockerdBinary))
  23. d := daemon.New(t, ops...)
  24. return &Daemon{
  25. Daemon: d,
  26. dockerBinary: dockerBinary,
  27. }
  28. }
  29. // Cmd executes a docker CLI command against this daemon.
  30. // Example: d.Cmd("version") will run docker -H unix://path/to/unix.sock version
  31. func (d *Daemon) Cmd(args ...string) (string, error) {
  32. result := icmd.RunCmd(d.Command(args...))
  33. return result.Combined(), result.Error
  34. }
  35. // Command creates a docker CLI command against this daemon, to be executed later.
  36. // Example: d.Command("version") creates a command to run "docker -H unix://path/to/unix.sock version"
  37. func (d *Daemon) Command(args ...string) icmd.Cmd {
  38. return icmd.Command(d.dockerBinary, d.PrependHostArg(args)...)
  39. }
  40. // PrependHostArg prepend the specified arguments by the daemon host flags
  41. func (d *Daemon) PrependHostArg(args []string) []string {
  42. for _, arg := range args {
  43. if arg == "--host" || arg == "-H" {
  44. return args
  45. }
  46. }
  47. return append([]string{"--host", d.Sock()}, args...)
  48. }
  49. // GetIDByName returns the ID of an object (container, volume, …) given its name
  50. func (d *Daemon) GetIDByName(name string) (string, error) {
  51. return d.inspectFieldWithError(name, "Id")
  52. }
  53. // InspectField returns the field filter by 'filter'
  54. func (d *Daemon) InspectField(name, filter string) (string, error) {
  55. return d.inspectFilter(name, filter)
  56. }
  57. func (d *Daemon) inspectFilter(name, filter string) (string, error) {
  58. format := fmt.Sprintf("{{%s}}", filter)
  59. out, err := d.Cmd("inspect", "-f", format, name)
  60. if err != nil {
  61. return "", errors.Errorf("failed to inspect %s: %s", name, out)
  62. }
  63. return strings.TrimSpace(out), nil
  64. }
  65. func (d *Daemon) inspectFieldWithError(name, field string) (string, error) {
  66. return d.inspectFilter(name, "."+field)
  67. }
  68. // CheckActiveContainerCount returns the number of active containers
  69. // FIXME(vdemeester) should re-use ActivateContainers in some way
  70. func (d *Daemon) CheckActiveContainerCount(t *testing.T) (interface{}, string) {
  71. t.Helper()
  72. out, err := d.Cmd("ps", "-q")
  73. assert.NilError(t, err)
  74. if len(strings.TrimSpace(out)) == 0 {
  75. return 0, ""
  76. }
  77. return len(strings.Split(strings.TrimSpace(out), "\n")), fmt.Sprintf("output: %q", out)
  78. }
  79. // WaitRun waits for a container to be running for 10s
  80. func (d *Daemon) WaitRun(contID string) error {
  81. args := []string{"--host", d.Sock()}
  82. return WaitInspectWithArgs(d.dockerBinary, contID, "{{.State.Running}}", "true", 10*time.Second, args...)
  83. }
  84. // WaitInspectWithArgs waits for the specified expression to be equals to the specified expected string in the given time.
  85. // Deprecated: use cli.WaitCmd instead
  86. func WaitInspectWithArgs(dockerBinary, name, expr, expected string, timeout time.Duration, arg ...string) error {
  87. after := time.After(timeout)
  88. args := append(arg, "inspect", "-f", expr, name)
  89. for {
  90. result := icmd.RunCommand(dockerBinary, args...)
  91. if result.Error != nil {
  92. if !strings.Contains(strings.ToLower(result.Stderr()), "no such") {
  93. return errors.Errorf("error executing docker inspect: %v\n%s",
  94. result.Stderr(), result.Stdout())
  95. }
  96. select {
  97. case <-after:
  98. return result.Error
  99. default:
  100. time.Sleep(10 * time.Millisecond)
  101. continue
  102. }
  103. }
  104. out := strings.TrimSpace(result.Stdout())
  105. if out == expected {
  106. break
  107. }
  108. select {
  109. case <-after:
  110. return errors.Errorf("condition \"%q == %q\" not true in time (%v)", out, expected, timeout)
  111. default:
  112. }
  113. time.Sleep(100 * time.Millisecond)
  114. }
  115. return nil
  116. }