container_test.go 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. package container // import "github.com/docker/docker/integration/container"
  2. import (
  3. "net/http"
  4. "runtime"
  5. "testing"
  6. "github.com/docker/docker/testutil"
  7. "github.com/docker/docker/testutil/request"
  8. "gotest.tools/v3/assert"
  9. is "gotest.tools/v3/assert/cmp"
  10. )
  11. // TestContainerInvalidJSON tests that POST endpoints that expect a body return
  12. // the correct error when sending invalid JSON requests.
  13. func TestContainerInvalidJSON(t *testing.T) {
  14. ctx := setupTest(t)
  15. // POST endpoints that accept / expect a JSON body;
  16. endpoints := []string{
  17. "/commit",
  18. "/containers/create",
  19. "/containers/foobar/exec",
  20. "/containers/foobar/update",
  21. "/exec/foobar/start",
  22. }
  23. // windows doesnt support API < v1.24
  24. if runtime.GOOS != "windows" {
  25. endpoints = append(
  26. endpoints,
  27. "/v1.23/containers/foobar/copy", // deprecated since 1.8 (API v1.20), errors out since 1.12 (API v1.24)
  28. "/v1.23/containers/foobar/start", // accepts a body on API < v1.24
  29. )
  30. }
  31. for _, ep := range endpoints {
  32. ep := ep
  33. t.Run(ep[1:], func(t *testing.T) {
  34. t.Parallel()
  35. t.Run("invalid content type", func(t *testing.T) {
  36. ctx := testutil.StartSpan(ctx, t)
  37. res, body, err := request.Post(ctx, ep, request.RawString("{}"), request.ContentType("text/plain"))
  38. assert.NilError(t, err)
  39. assert.Check(t, is.Equal(res.StatusCode, http.StatusBadRequest))
  40. buf, err := request.ReadBody(body)
  41. assert.NilError(t, err)
  42. assert.Check(t, is.Contains(string(buf), "unsupported Content-Type header (text/plain): must be 'application/json'"))
  43. })
  44. t.Run("invalid JSON", func(t *testing.T) {
  45. ctx := testutil.StartSpan(ctx, t)
  46. res, body, err := request.Post(ctx, ep, request.RawString("{invalid json"), request.JSON)
  47. assert.NilError(t, err)
  48. assert.Check(t, is.Equal(res.StatusCode, http.StatusBadRequest))
  49. buf, err := request.ReadBody(body)
  50. assert.NilError(t, err)
  51. assert.Check(t, is.Contains(string(buf), "invalid JSON: invalid character 'i' looking for beginning of object key string"))
  52. })
  53. t.Run("extra content after JSON", func(t *testing.T) {
  54. ctx := testutil.StartSpan(ctx, t)
  55. res, body, err := request.Post(ctx, ep, request.RawString(`{} trailing content`), request.JSON)
  56. assert.NilError(t, err)
  57. assert.Check(t, is.Equal(res.StatusCode, http.StatusBadRequest))
  58. buf, err := request.ReadBody(body)
  59. assert.NilError(t, err)
  60. assert.Check(t, is.Contains(string(buf), "unexpected content after JSON"))
  61. })
  62. t.Run("empty body", func(t *testing.T) {
  63. ctx := testutil.StartSpan(ctx, t)
  64. // empty body should not produce an 500 internal server error, or
  65. // any 5XX error (this is assuming the request does not produce
  66. // an internal server error for another reason, but it shouldn't)
  67. res, _, err := request.Post(ctx, ep, request.RawString(``), request.JSON)
  68. assert.NilError(t, err)
  69. assert.Check(t, res.StatusCode < http.StatusInternalServerError)
  70. })
  71. })
  72. }
  73. }