daemon.go 4.2 KB

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