benchmark_test.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. package main
  2. import (
  3. "context"
  4. "fmt"
  5. "os"
  6. "runtime"
  7. "strings"
  8. "sync"
  9. "testing"
  10. "time"
  11. "github.com/docker/docker/integration-cli/cli"
  12. "gotest.tools/v3/assert"
  13. )
  14. type DockerBenchmarkSuite struct {
  15. ds *DockerSuite
  16. }
  17. func (s *DockerBenchmarkSuite) TearDownTest(ctx context.Context, c *testing.T) {
  18. s.ds.TearDownTest(ctx, c)
  19. }
  20. func (s *DockerBenchmarkSuite) OnTimeout(c *testing.T) {
  21. s.ds.OnTimeout(c)
  22. }
  23. func (s *DockerBenchmarkSuite) BenchmarkConcurrentContainerActions(c *testing.B) {
  24. maxConcurrency := runtime.GOMAXPROCS(0)
  25. numIterations := c.N
  26. outerGroup := &sync.WaitGroup{}
  27. outerGroup.Add(maxConcurrency)
  28. chErr := make(chan error, numIterations*2*maxConcurrency)
  29. for i := 0; i < maxConcurrency; i++ {
  30. go func() {
  31. defer outerGroup.Done()
  32. innerGroup := &sync.WaitGroup{}
  33. innerGroup.Add(2)
  34. go func() {
  35. defer innerGroup.Done()
  36. for i := 0; i < numIterations; i++ {
  37. args := []string{"run", "-d", "busybox"}
  38. args = append(args, sleepCommandForDaemonPlatform()...)
  39. out, _, err := dockerCmdWithError(args...)
  40. if err != nil {
  41. chErr <- fmt.Errorf(out)
  42. return
  43. }
  44. id := strings.TrimSpace(out)
  45. tmpDir, err := os.MkdirTemp("", "docker-concurrent-test-"+id)
  46. if err != nil {
  47. chErr <- err
  48. return
  49. }
  50. defer os.RemoveAll(tmpDir)
  51. out, _, err = dockerCmdWithError("cp", id+":/tmp", tmpDir)
  52. if err != nil {
  53. chErr <- fmt.Errorf(out)
  54. return
  55. }
  56. out, _, err = dockerCmdWithError("kill", id)
  57. if err != nil {
  58. chErr <- fmt.Errorf(out)
  59. }
  60. out, _, err = dockerCmdWithError("start", id)
  61. if err != nil {
  62. chErr <- fmt.Errorf(out)
  63. }
  64. out, _, err = dockerCmdWithError("kill", id)
  65. if err != nil {
  66. chErr <- fmt.Errorf(out)
  67. }
  68. // don't do an rm -f here since it can potentially ignore errors from the graphdriver
  69. out, _, err = dockerCmdWithError("rm", id)
  70. if err != nil {
  71. chErr <- fmt.Errorf(out)
  72. }
  73. }
  74. }()
  75. go func() {
  76. defer innerGroup.Done()
  77. for i := 0; i < numIterations; i++ {
  78. out, _, err := dockerCmdWithError("ps")
  79. if err != nil {
  80. chErr <- fmt.Errorf(out)
  81. }
  82. }
  83. }()
  84. innerGroup.Wait()
  85. }()
  86. }
  87. outerGroup.Wait()
  88. close(chErr)
  89. for err := range chErr {
  90. assert.NilError(c, err)
  91. }
  92. }
  93. func (s *DockerBenchmarkSuite) BenchmarkLogsCLIRotateFollow(c *testing.B) {
  94. out := cli.DockerCmd(c, "run", "-d", "--log-opt", "max-size=1b", "--log-opt", "max-file=10", "busybox", "sh", "-c", "while true; do usleep 50000; echo hello; done").Combined()
  95. id := strings.TrimSpace(out)
  96. ch := make(chan error, 1)
  97. go func() {
  98. ch <- nil
  99. out, _, _ := dockerCmdWithError("logs", "-f", id)
  100. // if this returns at all, it's an error
  101. ch <- fmt.Errorf(out)
  102. }()
  103. <-ch
  104. select {
  105. case <-time.After(30 * time.Second):
  106. // ran for 30 seconds with no problem
  107. return
  108. case err := <-ch:
  109. if err != nil {
  110. c.Fatal(err)
  111. }
  112. }
  113. }