Remove string checking in API error handling

Use strongly typed errors to set HTTP status codes.
Error interfaces are defined in the api/errors package and errors
returned from controllers are checked against these interfaces.

Errors can be wraeped in a pkg/errors.Causer, as long as somewhere in the
line of causes one of the interfaces is implemented. The special error
interfaces take precedence over Causer, meaning if both Causer and one
of the new error interfaces are implemented, the Causer is not
traversed.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: ebcb7d6b406fe50ea9a237c73004d75884184c33
Component: engine
This commit is contained in:
Brian Goff
2017-08-15 16:01:11 -04:00
parent 7eea9c9616
commit 30f1b651e2
127 changed files with 1791 additions and 885 deletions
@@ -508,7 +508,7 @@ func (s *DockerSuite) TestContainerAPIBadPort(c *check.C) {
status, body, err := request.SockRequest("POST", "/containers/create", config, daemonHost())
c.Assert(err, checker.IsNil)
c.Assert(status, checker.Equals, http.StatusInternalServerError)
c.Assert(status, checker.Equals, http.StatusBadRequest)
c.Assert(getErrorMessage(c, body), checker.Equals, `invalid port specification: "aa80"`, check.Commentf("Incorrect error msg: %s", body))
}
@@ -537,7 +537,7 @@ func (s *DockerSuite) TestContainerAPICreateEmptyConfig(c *check.C) {
status, body, err := request.SockRequest("POST", "/containers/create", config, daemonHost())
c.Assert(err, checker.IsNil)
c.Assert(status, checker.Equals, http.StatusInternalServerError)
c.Assert(status, checker.Equals, http.StatusBadRequest)
expected := "Config cannot be empty in order to create a container"
c.Assert(getErrorMessage(c, body), checker.Equals, expected)
@@ -673,13 +673,13 @@ func (s *DockerSuite) TestContainerAPIVerifyHeader(c *check.C) {
// Try with no content-type
res, body, err := create("")
c.Assert(err, checker.IsNil)
c.Assert(res.StatusCode, checker.Equals, http.StatusInternalServerError)
c.Assert(res.StatusCode, checker.Equals, http.StatusBadRequest)
body.Close()
// Try with wrong content-type
res, body, err = create("application/xml")
c.Assert(err, checker.IsNil)
c.Assert(res.StatusCode, checker.Equals, http.StatusInternalServerError)
c.Assert(res.StatusCode, checker.Equals, http.StatusBadRequest)
body.Close()
// now application/json
@@ -705,7 +705,7 @@ func (s *DockerSuite) TestContainerAPIInvalidPortSyntax(c *check.C) {
res, body, err := request.Post("/containers/create", request.RawString(config), request.JSON)
c.Assert(err, checker.IsNil)
c.Assert(res.StatusCode, checker.Equals, http.StatusInternalServerError)
c.Assert(res.StatusCode, checker.Equals, http.StatusBadRequest)
b, err := testutil.ReadBody(body)
c.Assert(err, checker.IsNil)
@@ -725,7 +725,7 @@ func (s *DockerSuite) TestContainerAPIRestartPolicyInvalidPolicyName(c *check.C)
res, body, err := request.Post("/containers/create", request.RawString(config), request.JSON)
c.Assert(err, checker.IsNil)
c.Assert(res.StatusCode, checker.Equals, http.StatusInternalServerError)
c.Assert(res.StatusCode, checker.Equals, http.StatusBadRequest)
b, err := testutil.ReadBody(body)
c.Assert(err, checker.IsNil)
@@ -745,7 +745,7 @@ func (s *DockerSuite) TestContainerAPIRestartPolicyRetryMismatch(c *check.C) {
res, body, err := request.Post("/containers/create", request.RawString(config), request.JSON)
c.Assert(err, checker.IsNil)
c.Assert(res.StatusCode, checker.Equals, http.StatusInternalServerError)
c.Assert(res.StatusCode, checker.Equals, http.StatusBadRequest)
b, err := testutil.ReadBody(body)
c.Assert(err, checker.IsNil)
@@ -765,7 +765,7 @@ func (s *DockerSuite) TestContainerAPIRestartPolicyNegativeRetryCount(c *check.C
res, body, err := request.Post("/containers/create", request.RawString(config), request.JSON)
c.Assert(err, checker.IsNil)
c.Assert(res.StatusCode, checker.Equals, http.StatusInternalServerError)
c.Assert(res.StatusCode, checker.Equals, http.StatusBadRequest)
b, err := testutil.ReadBody(body)
c.Assert(err, checker.IsNil)
@@ -850,7 +850,7 @@ func (s *DockerSuite) TestCreateWithTooLowMemoryLimit(c *check.C) {
b, err2 := testutil.ReadBody(body)
c.Assert(err2, checker.IsNil)
c.Assert(res.StatusCode, checker.Equals, http.StatusInternalServerError)
c.Assert(res.StatusCode, checker.Equals, http.StatusBadRequest)
c.Assert(string(b), checker.Contains, "Minimum memory limit allowed is 4MB")
}
@@ -1005,7 +1005,7 @@ func (s *DockerSuite) TestContainerAPICopyPre124(c *check.C) {
c.Assert(found, checker.True)
}
func (s *DockerSuite) TestContainerAPICopyResourcePathEmptyPr124(c *check.C) {
func (s *DockerSuite) TestContainerAPICopyResourcePathEmptyPre124(c *check.C) {
testRequires(c, DaemonIsLinux) // Windows only supports 1.25 or later
name := "test-container-api-copy-resource-empty"
dockerCmd(c, "run", "--name", name, "busybox", "touch", "/test.txt")
@@ -1016,7 +1016,7 @@ func (s *DockerSuite) TestContainerAPICopyResourcePathEmptyPr124(c *check.C) {
status, body, err := request.SockRequest("POST", "/v1.23/containers/"+name+"/copy", postData, daemonHost())
c.Assert(err, checker.IsNil)
c.Assert(status, checker.Equals, http.StatusInternalServerError)
c.Assert(status, checker.Equals, http.StatusBadRequest)
c.Assert(string(body), checker.Matches, "Path cannot be empty\n")
}
@@ -1031,7 +1031,7 @@ func (s *DockerSuite) TestContainerAPICopyResourcePathNotFoundPre124(c *check.C)
status, body, err := request.SockRequest("POST", "/v1.23/containers/"+name+"/copy", postData, daemonHost())
c.Assert(err, checker.IsNil)
c.Assert(status, checker.Equals, http.StatusInternalServerError)
c.Assert(status, checker.Equals, http.StatusNotFound)
c.Assert(string(body), checker.Matches, "Could not find the file /notexist in container "+name+"\n")
}
@@ -1301,7 +1301,7 @@ func (s *DockerSuite) TestPostContainersCreateWithWrongCpusetValues(c *check.C)
name := "wrong-cpuset-cpus"
status, body, err := request.SockRequest("POST", "/containers/create?name="+name, c1, daemonHost())
c.Assert(err, checker.IsNil)
c.Assert(status, checker.Equals, http.StatusInternalServerError)
c.Assert(status, checker.Equals, http.StatusBadRequest)
expected := "Invalid value 1-42,, for cpuset cpus"
c.Assert(getErrorMessage(c, body), checker.Equals, expected)
@@ -1312,7 +1312,7 @@ func (s *DockerSuite) TestPostContainersCreateWithWrongCpusetValues(c *check.C)
name = "wrong-cpuset-mems"
status, body, err = request.SockRequest("POST", "/containers/create?name="+name, c2, daemonHost())
c.Assert(err, checker.IsNil)
c.Assert(status, checker.Equals, http.StatusInternalServerError)
c.Assert(status, checker.Equals, http.StatusBadRequest)
expected = "Invalid value 42-3,1-- for cpuset mems"
c.Assert(getErrorMessage(c, body), checker.Equals, expected)
}
@@ -1327,7 +1327,7 @@ func (s *DockerSuite) TestPostContainersCreateShmSizeNegative(c *check.C) {
status, body, err := request.SockRequest("POST", "/containers/create", config, daemonHost())
c.Assert(err, check.IsNil)
c.Assert(status, check.Equals, http.StatusInternalServerError)
c.Assert(status, check.Equals, http.StatusBadRequest)
c.Assert(getErrorMessage(c, body), checker.Contains, "SHM size can not be less than 0")
}
@@ -1463,7 +1463,7 @@ func (s *DockerSuite) TestPostContainersCreateWithOomScoreAdjInvalidRange(c *che
name := "oomscoreadj-over"
status, b, err := request.SockRequest("POST", "/containers/create?name="+name, config, daemonHost())
c.Assert(err, check.IsNil)
c.Assert(status, check.Equals, http.StatusInternalServerError)
c.Assert(status, check.Equals, http.StatusBadRequest)
expected := "Invalid value 1001, range for oom score adj is [-1000, 1000]"
msg := getErrorMessage(c, b)
@@ -1478,7 +1478,7 @@ func (s *DockerSuite) TestPostContainersCreateWithOomScoreAdjInvalidRange(c *che
name = "oomscoreadj-low"
status, b, err = request.SockRequest("POST", "/containers/create?name="+name, config, daemonHost())
c.Assert(err, check.IsNil)
c.Assert(status, check.Equals, http.StatusInternalServerError)
c.Assert(status, check.Equals, http.StatusBadRequest)
expected = "Invalid value -1001, range for oom score adj is [-1000, 1000]"
msg = getErrorMessage(c, b)
if !strings.Contains(msg, expected) {
@@ -1488,10 +1488,9 @@ func (s *DockerSuite) TestPostContainersCreateWithOomScoreAdjInvalidRange(c *che
// test case for #22210 where an empty container name caused panic.
func (s *DockerSuite) TestContainerAPIDeleteWithEmptyName(c *check.C) {
status, out, err := request.SockRequest("DELETE", "/containers/", nil, daemonHost())
status, _, err := request.SockRequest("DELETE", "/containers/", nil, daemonHost())
c.Assert(err, checker.IsNil)
c.Assert(status, checker.Equals, http.StatusBadRequest)
c.Assert(string(out), checker.Contains, "No container name or ID supplied")
}
func (s *DockerSuite) TestContainerAPIStatsWithNetworkDisabled(c *check.C) {
@@ -25,7 +25,7 @@ func (s *DockerSuite) TestAPICreateWithInvalidHealthcheckParams(c *check.C) {
status, body, err := request.SockRequest("POST", "/containers/create?name="+name, config, daemonHost())
c.Assert(err, check.IsNil)
c.Assert(status, check.Equals, http.StatusInternalServerError)
c.Assert(status, check.Equals, http.StatusBadRequest)
expected := fmt.Sprintf("Interval in Healthcheck cannot be less than %s", container.MinimumDuration)
c.Assert(getErrorMessage(c, body), checker.Contains, expected)
@@ -41,7 +41,7 @@ func (s *DockerSuite) TestAPICreateWithInvalidHealthcheckParams(c *check.C) {
}
status, body, err = request.SockRequest("POST", "/containers/create?name="+name, config, daemonHost())
c.Assert(err, check.IsNil)
c.Assert(status, check.Equals, http.StatusInternalServerError)
c.Assert(status, check.Equals, http.StatusBadRequest)
c.Assert(getErrorMessage(c, body), checker.Contains, expected)
// test invalid Timeout in Healthcheck: less than 1ms
@@ -56,7 +56,7 @@ func (s *DockerSuite) TestAPICreateWithInvalidHealthcheckParams(c *check.C) {
}
status, body, err = request.SockRequest("POST", "/containers/create?name="+name, config, daemonHost())
c.Assert(err, check.IsNil)
c.Assert(status, check.Equals, http.StatusInternalServerError)
c.Assert(status, check.Equals, http.StatusBadRequest)
expected = fmt.Sprintf("Timeout in Healthcheck cannot be less than %s", container.MinimumDuration)
c.Assert(getErrorMessage(c, body), checker.Contains, expected)
@@ -72,7 +72,7 @@ func (s *DockerSuite) TestAPICreateWithInvalidHealthcheckParams(c *check.C) {
}
status, body, err = request.SockRequest("POST", "/containers/create?name="+name, config, daemonHost())
c.Assert(err, check.IsNil)
c.Assert(status, check.Equals, http.StatusInternalServerError)
c.Assert(status, check.Equals, http.StatusBadRequest)
expected = "Retries in Healthcheck cannot be negative"
c.Assert(getErrorMessage(c, body), checker.Contains, expected)
@@ -89,7 +89,7 @@ func (s *DockerSuite) TestAPICreateWithInvalidHealthcheckParams(c *check.C) {
}
status, body, err = request.SockRequest("POST", "/containers/create?name="+name, config, daemonHost())
c.Assert(err, check.IsNil)
c.Assert(status, check.Equals, http.StatusInternalServerError)
c.Assert(status, check.Equals, http.StatusBadRequest)
expected = fmt.Sprintf("StartPeriod in Healthcheck cannot be less than %s", container.MinimumDuration)
c.Assert(getErrorMessage(c, body), checker.Contains, expected)
}
@@ -22,7 +22,7 @@ func (s *DockerSuite) TestExecResizeAPIHeightWidthNoInt(c *check.C) {
endpoint := "/exec/" + cleanedContainerID + "/resize?h=foo&w=bar"
status, _, err := request.SockRequest("POST", endpoint, nil, daemonHost())
c.Assert(err, checker.IsNil)
c.Assert(status, checker.Equals, http.StatusInternalServerError)
c.Assert(status, checker.Equals, http.StatusBadRequest)
}
// Part of #14845
@@ -23,7 +23,7 @@ func (s *DockerSuite) TestExecAPICreateNoCmd(c *check.C) {
status, body, err := request.SockRequest("POST", fmt.Sprintf("/containers/%s/exec", name), map[string]interface{}{"Cmd": nil}, daemonHost())
c.Assert(err, checker.IsNil)
c.Assert(status, checker.Equals, http.StatusInternalServerError)
c.Assert(status, checker.Equals, http.StatusBadRequest)
comment := check.Commentf("Expected message when creating exec command with no Cmd specified")
c.Assert(getErrorMessage(c, body), checker.Contains, "No exec command specified", comment)
@@ -40,7 +40,7 @@ func (s *DockerSuite) TestExecAPICreateNoValidContentType(c *check.C) {
res, body, err := request.Post(fmt.Sprintf("/containers/%s/exec", name), request.RawContent(ioutil.NopCloser(jsonData)), request.ContentType("test/plain"))
c.Assert(err, checker.IsNil)
c.Assert(res.StatusCode, checker.Equals, http.StatusInternalServerError)
c.Assert(res.StatusCode, checker.Equals, http.StatusBadRequest)
b, err := testutil.ReadBody(body)
c.Assert(err, checker.IsNil)
@@ -177,7 +177,7 @@ func (s *DockerSuite) TestExecAPIStartInvalidCommand(c *check.C) {
dockerCmd(c, "run", "-d", "-t", "--name", name, "busybox", "/bin/sh")
id := createExecCmd(c, name, "invalid")
startExec(c, id, http.StatusNotFound)
startExec(c, id, http.StatusBadRequest)
waitForExec(c, id)
var inspectJSON struct{ ExecIDs []string }
@@ -25,7 +25,7 @@ func (s *DockerSuite) TestResizeAPIHeightWidthNoInt(c *check.C) {
endpoint := "/containers/" + cleanedContainerID + "/resize?h=foo&w=bar"
status, _, err := request.SockRequest("POST", endpoint, nil, daemonHost())
c.Assert(status, check.Equals, http.StatusInternalServerError)
c.Assert(status, check.Equals, http.StatusBadRequest)
c.Assert(err, check.IsNil)
}
@@ -38,7 +38,7 @@ func (s *DockerSuite) TestResizeAPIResponseWhenContainerNotStarted(c *check.C) {
endpoint := "/containers/" + cleanedContainerID + "/resize?h=40&w=40"
status, body, err := request.SockRequest("POST", endpoint, nil, daemonHost())
c.Assert(status, check.Equals, http.StatusInternalServerError)
c.Assert(status, check.Equals, http.StatusConflict)
c.Assert(err, check.IsNil)
c.Assert(getErrorMessage(c, body), checker.Contains, "is not running", check.Commentf("resize should fail with message 'Container is not running'"))
@@ -80,7 +80,7 @@ func (s *DockerSuite) TestAPIDockerAPIVersion(c *check.C) {
func (s *DockerSuite) TestAPIErrorJSON(c *check.C) {
httpResp, body, err := request.Post("/containers/create", request.JSONBody(struct{}{}))
c.Assert(err, checker.IsNil)
c.Assert(httpResp.StatusCode, checker.Equals, http.StatusInternalServerError)
c.Assert(httpResp.StatusCode, checker.Equals, http.StatusBadRequest)
c.Assert(httpResp.Header.Get("Content-Type"), checker.Equals, "application/json")
b, err := testutil.ReadBody(body)
c.Assert(err, checker.IsNil)
@@ -93,7 +93,7 @@ func (s *DockerSuite) TestAPIErrorPlainText(c *check.C) {
testRequires(c, DaemonIsLinux)
httpResp, body, err := request.Post("/v1.23/containers/create", request.JSONBody(struct{}{}))
c.Assert(err, checker.IsNil)
c.Assert(httpResp.StatusCode, checker.Equals, http.StatusInternalServerError)
c.Assert(httpResp.StatusCode, checker.Equals, http.StatusBadRequest)
c.Assert(httpResp.Header.Get("Content-Type"), checker.Contains, "text/plain")
b, err := testutil.ReadBody(body)
c.Assert(err, checker.IsNil)
@@ -64,19 +64,17 @@ func (s *DockerSuite) TestCpFromErrDstParentNotExists(c *check.C) {
// Try with a file source.
srcPath := containerCpPath(containerID, "/file1")
dstPath := cpPath(tmpDir, "notExists", "file1")
_, dstStatErr := os.Lstat(filepath.Dir(dstPath))
c.Assert(os.IsNotExist(dstStatErr), checker.True)
err := runDockerCp(c, srcPath, dstPath, nil)
c.Assert(err, checker.NotNil)
c.Assert(isCpNotExist(err), checker.True, check.Commentf("expected IsNotExist error, but got %T: %s", err, err))
c.Assert(err.Error(), checker.Contains, dstStatErr.Error())
// Try with a directory source.
srcPath = containerCpPath(containerID, "/dir1")
err = runDockerCp(c, srcPath, dstPath, nil)
c.Assert(err, checker.NotNil)
c.Assert(isCpNotExist(err), checker.True, check.Commentf("expected IsNotExist error, but got %T: %s", err, err))
c.Assert(err.Error(), checker.Contains, dstStatErr.Error())
}
// Test for error when DST ends in a trailing
@@ -2,6 +2,7 @@ package main
import (
"os"
"strings"
"github.com/docker/docker/integration-cli/checker"
"github.com/go-check/check"
@@ -30,11 +31,11 @@ func (s *DockerSuite) TestCpToErrSrcNotExists(c *check.C) {
srcPath := cpPath(tmpDir, "file1")
dstPath := containerCpPath(containerID, "file1")
_, srcStatErr := os.Stat(srcPath)
c.Assert(os.IsNotExist(srcStatErr), checker.True)
err := runDockerCp(c, srcPath, dstPath, nil)
c.Assert(err, checker.NotNil)
c.Assert(isCpNotExist(err), checker.True, check.Commentf("expected IsNotExist error, but got %T: %s", err, err))
c.Assert(strings.ToLower(err.Error()), checker.Contains, strings.ToLower(srcStatErr.Error()))
}
// Test for error when SRC ends in a trailing
@@ -231,7 +231,7 @@ func getTestDir(c *check.C, label string) (tmpDir string) {
}
func isCpNotExist(err error) bool {
return strings.Contains(err.Error(), "no such file or directory") || strings.Contains(err.Error(), "cannot find the file specified")
return strings.Contains(strings.ToLower(err.Error()), "could not find the file")
}
func isCpDirNotExist(err error) bool {
@@ -463,6 +463,5 @@ func (s *DockerSuite) TestInspectInvalidReference(c *check.C) {
// This test should work on both Windows and Linux
out, _, err := dockerCmdWithError("inspect", "FooBar")
c.Assert(err, checker.NotNil)
c.Assert(out, checker.Contains, "Error: No such object: FooBar")
c.Assert(err.Error(), checker.Contains, "Error: No such object: FooBar")
c.Assert(out, checker.Contains, "no such image: FooBar")
}
@@ -28,7 +28,7 @@ func (s *DockerSuite) TestLinksInvalidContainerTarget(c *check.C) {
// an invalid container target should produce an error
c.Assert(err, checker.NotNil, check.Commentf("out: %s", out))
// an invalid container target should produce an error
c.Assert(out, checker.Contains, "Could not get container")
c.Assert(out, checker.Contains, "could not get container")
}
func (s *DockerSuite) TestLinksPingLinkedContainers(c *check.C) {
@@ -1,6 +1,8 @@
package main
import (
"strings"
"github.com/docker/docker/integration-cli/checker"
"github.com/docker/docker/runconfig"
"github.com/go-check/check"
@@ -47,7 +49,7 @@ func (s *DockerSuite) TestNetHostname(c *check.C) {
c.Assert(out, checker.Contains, "Invalid network mode: invalid container format container:<name|id>")
out, _ = dockerCmdWithFail(c, "run", "--net=weird", "busybox", "ps")
c.Assert(out, checker.Contains, "network weird not found")
c.Assert(strings.ToLower(out), checker.Contains, "no such network")
}
func (s *DockerSuite) TestConflictContainerNetworkAndLinks(c *check.C) {
@@ -208,7 +208,7 @@ func (s *DockerSuite) TestPsListContainersFilterStatus(c *check.C) {
result := cli.Docker(cli.Args("ps", "-a", "-q", "--filter=status=rubbish"), cli.WithTimeout(time.Second*60))
c.Assert(result, icmd.Matches, icmd.Expected{
ExitCode: 1,
Err: "Unrecognised filter value for status",
Err: "Invalid filter 'status=rubbish'",
})
// Windows doesn't support pausing of containers
@@ -1887,7 +1887,7 @@ func (s *DockerSwarmSuite) TestNetworkInspectWithDuplicateNames(c *check.C) {
// Name with duplicates
out, err = d.Cmd("network", "inspect", "--format", "{{.ID}}", name)
c.Assert(err, checker.NotNil, check.Commentf(out))
c.Assert(out, checker.Contains, "network foo is ambiguous (2 matches found based on name)")
c.Assert(out, checker.Contains, "2 matches found based on name")
out, err = d.Cmd("network", "rm", n2.ID)
c.Assert(err, checker.IsNil, check.Commentf(out))
@@ -1912,7 +1912,7 @@ func (s *DockerSwarmSuite) TestNetworkInspectWithDuplicateNames(c *check.C) {
// Name with duplicates
out, err = d.Cmd("network", "inspect", "--format", "{{.ID}}", name)
c.Assert(err, checker.NotNil, check.Commentf(out))
c.Assert(out, checker.Contains, "network foo is ambiguous (2 matches found based on name)")
c.Assert(out, checker.Contains, "2 matches found based on name")
}
func (s *DockerSwarmSuite) TestSwarmStopSignal(c *check.C) {
@@ -23,10 +23,9 @@ func (s *DockerSuite) TestDeprecatedContainerAPIStartHostConfig(c *check.C) {
config := map[string]interface{}{
"Binds": []string{"/aa:/bb"},
}
status, body, err := request.SockRequest("POST", "/containers/"+name+"/start", config, daemonHost())
status, _, err := request.SockRequest("POST", "/containers/"+name+"/start", config, daemonHost())
c.Assert(err, checker.IsNil)
c.Assert(status, checker.Equals, http.StatusBadRequest)
c.Assert(string(body), checker.Contains, "was deprecated since v1.10")
}
func (s *DockerSuite) TestDeprecatedContainerAPIStartVolumeBinds(c *check.C) {
@@ -81,7 +80,7 @@ func (s *DockerSuite) TestDeprecatedContainerAPIStartDupVolumeBinds(c *check.C)
}
status, body, err := request.SockRequest("POST", formatV123StartAPIURL("/containers/"+name+"/start"), config, daemonHost())
c.Assert(err, checker.IsNil)
c.Assert(status, checker.Equals, http.StatusInternalServerError)
c.Assert(status, checker.Equals, http.StatusBadRequest)
c.Assert(string(body), checker.Contains, "Duplicate mount point", check.Commentf("Expected failure due to duplicate bind mounts to same path, instead got: %q with error: %v", string(body), err))
}
@@ -154,7 +153,7 @@ func (s *DockerSuite) TestDeprecatedStartWithTooLowMemoryLimit(c *check.C) {
c.Assert(err, checker.IsNil)
b, err2 := testutil.ReadBody(body)
c.Assert(err2, checker.IsNil)
c.Assert(res.StatusCode, checker.Equals, http.StatusInternalServerError)
c.Assert(res.StatusCode, checker.Equals, http.StatusBadRequest)
c.Assert(string(b), checker.Contains, "Minimum memory limit allowed is 4MB")
}