benchmark_test.go 2.8 KB

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