update_linux_test.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. package container
  2. import (
  3. "bytes"
  4. "context"
  5. "fmt"
  6. "strconv"
  7. "strings"
  8. "testing"
  9. "time"
  10. "github.com/docker/docker/api/types"
  11. "github.com/docker/docker/api/types/container"
  12. "github.com/docker/docker/integration/util/request"
  13. "github.com/docker/docker/pkg/stdcopy"
  14. )
  15. func TestUpdateCPUQUota(t *testing.T) {
  16. t.Parallel()
  17. client := request.NewAPIClient(t)
  18. ctx := context.Background()
  19. c, err := client.ContainerCreate(ctx, &container.Config{
  20. Image: "busybox",
  21. Cmd: []string{"top"},
  22. }, nil, nil, "")
  23. if err != nil {
  24. t.Fatal(err)
  25. }
  26. defer func() {
  27. if err := client.ContainerRemove(ctx, c.ID, types.ContainerRemoveOptions{Force: true}); err != nil {
  28. panic(fmt.Sprintf("failed to clean up after test: %v", err))
  29. }
  30. }()
  31. if err := client.ContainerStart(ctx, c.ID, types.ContainerStartOptions{}); err != nil {
  32. t.Fatal(err)
  33. }
  34. for _, test := range []struct {
  35. desc string
  36. update int64
  37. }{
  38. {desc: "some random value", update: 15000},
  39. {desc: "a higher value", update: 20000},
  40. {desc: "a lower value", update: 10000},
  41. {desc: "unset value", update: -1},
  42. } {
  43. if _, err := client.ContainerUpdate(ctx, c.ID, container.UpdateConfig{
  44. Resources: container.Resources{
  45. CPUQuota: test.update,
  46. },
  47. }); err != nil {
  48. t.Fatal(err)
  49. }
  50. inspect, err := client.ContainerInspect(ctx, c.ID)
  51. if err != nil {
  52. t.Fatal(err)
  53. }
  54. if inspect.HostConfig.CPUQuota != test.update {
  55. t.Fatalf("quota not updated in the API, expected %d, got: %d", test.update, inspect.HostConfig.CPUQuota)
  56. }
  57. execCreate, err := client.ContainerExecCreate(ctx, c.ID, types.ExecConfig{
  58. Cmd: []string{"/bin/cat", "/sys/fs/cgroup/cpu/cpu.cfs_quota_us"},
  59. AttachStdout: true,
  60. AttachStderr: true,
  61. })
  62. if err != nil {
  63. t.Fatal(err)
  64. }
  65. attach, err := client.ContainerExecAttach(ctx, execCreate.ID, types.ExecStartCheck{})
  66. if err != nil {
  67. t.Fatal(err)
  68. }
  69. if err := client.ContainerExecStart(ctx, execCreate.ID, types.ExecStartCheck{}); err != nil {
  70. t.Fatal(err)
  71. }
  72. buf := bytes.NewBuffer(nil)
  73. ready := make(chan error)
  74. go func() {
  75. _, err := stdcopy.StdCopy(buf, buf, attach.Reader)
  76. ready <- err
  77. }()
  78. select {
  79. case <-time.After(60 * time.Second):
  80. t.Fatal("timeout waiting for exec to complete")
  81. case err := <-ready:
  82. if err != nil {
  83. t.Fatal(err)
  84. }
  85. }
  86. actual := strings.TrimSpace(buf.String())
  87. if actual != strconv.Itoa(int(test.update)) {
  88. t.Fatalf("expected cgroup value %d, got: %s", test.update, actual)
  89. }
  90. }
  91. }