diff --git a/integration-test/swan_api_create_test.go b/integration-test/swan_api_create_test.go index 7e547779..19ecaafc 100644 --- a/integration-test/swan_api_create_test.go +++ b/integration-test/swan_api_create_test.go @@ -2,6 +2,9 @@ package main import ( "fmt" + "net/http" + "regexp" + "strings" "time" check "gopkg.in/check.v1" @@ -52,3 +55,84 @@ func (s *ApiSuite) TestCreateApp(c *check.C) { c.Assert(err, check.IsNil) fmt.Println("TestCreateApp() removed") } + +func (s *ApiSuite) TestCreateInvalidApp(c *check.C) { + // Purge + // + err := s.purge(time.Second*30, c) + c.Assert(err, check.IsNil) + fmt.Println("TestCreateInvalidApp() purged") + + // Invalid Create Request + // + + // invalid Content-Type + req, err := s.newRawReq("POST", "/v1/apps", "....") + c.Assert(err, check.IsNil) + code, body, err := s.sendRawRequest(req) + c.Assert(err, check.IsNil) + c.Assert(code, check.Equals, http.StatusBadRequest) + c.Log(string(body)) + match, _ := regexp.MatchString("must be.*application/json", string(body)) + c.Assert(match, check.Equals, true) + fmt.Println("TestCreateInvalidApp() illegal content type verified") + + // invalid App Name + var invalidNames = [][2]string{ + [2]string{"de..mo", "character.*not allowed"}, + [2]string{"<**$", "character.*not allowed"}, + [2]string{" ", "character.*not allowed"}, + [2]string{strings.Repeat("x", 64), "appName empty or too long"}, + [2]string{"", "appName empty or too long"}, + } + for _, pairs := range invalidNames { + name, errmsg := pairs[0], pairs[1] + ver := demoVersion().setName(name).Get() + code, body, err := s.rawCreateApp(ver) + c.Assert(err, check.IsNil) + c.Assert(code, check.Equals, http.StatusBadRequest) + c.Log(string(body)) + match, _ = regexp.MatchString(errmsg, string(body)) + c.Assert(match, check.Equals, true) + } + fmt.Println("TestCreateInvalidApp() illegal app name verified") + + // invalid RunAs + var invalidRunAses = [][2]string{ + [2]string{"bbk.", "character.*not allowed"}, + [2]string{"<**$", "character.*not allowed"}, + [2]string{" ", "character.*not allowed"}, + [2]string{"", "runAs should not empty"}, + } + for _, pairs := range invalidRunAses { + runas, errmsg := pairs[0], pairs[1] + ver := demoVersion().setRunAs(runas).Get() + code, body, err := s.rawCreateApp(ver) + c.Assert(err, check.IsNil) + c.Assert(code, check.Equals, http.StatusBadRequest) + c.Log(string(body)) + match, _ = regexp.MatchString(errmsg, string(body)) + c.Assert(match, check.Equals, true) + } + fmt.Println("TestCreateInvalidApp() illegal app runAs verified") + + // invalid image + ver := demoVersion().setImage("").Get() + code, body, err = s.rawCreateApp(ver) + c.Assert(err, check.IsNil) + c.Assert(code, check.Equals, http.StatusBadRequest) + c.Log(string(body)) + match, _ = regexp.MatchString("image field required", string(body)) + c.Assert(match, check.Equals, true) + fmt.Println("TestCreateInvalidApp() illegal app image verified") + + // invalid instances + ver = demoVersion().setCount(0).Get() + code, body, err = s.rawCreateApp(ver) + c.Assert(err, check.IsNil) + c.Assert(code, check.Equals, http.StatusBadRequest) + c.Log(string(body)) + match, _ = regexp.MatchString("should greater than 0", string(body)) + c.Assert(match, check.Equals, true) + fmt.Println("TestCreateInvalidApp() illegal app count verified") +} diff --git a/integration-test/swan_api_utils.go b/integration-test/swan_api_utils.go index e0e547b3..59690217 100644 --- a/integration-test/swan_api_utils.go +++ b/integration-test/swan_api_utils.go @@ -50,15 +50,19 @@ func (s *ApiSuite) updateApp(id string, newVer *types.Version, c *check.C) { } func (s *ApiSuite) rollbackApp(id string, versionID string, c *check.C) { - uri := fmt.Sprintf("/v1/apps/%s/rollback?version=%s", id, versionID) - code, body, err := s.sendRequest("POST", uri, nil) + code, body, err := s.rawRollBackApp(id, versionID) c.Assert(err, check.IsNil) c.Log(string(body)) c.Assert(code, check.Equals, http.StatusAccepted) } +func (s *ApiSuite) rawRollBackApp(id string, versionID string) (int, []byte, error) { + uri := fmt.Sprintf("/v1/apps/%s/rollback?version=%s", id, versionID) + return s.sendRequest("POST", uri, nil) +} + func (s *ApiSuite) createApp(ver *types.Version, c *check.C) string { - code, body, err := s.sendRequest("POST", "/v1/apps", ver) + code, body, err := s.rawCreateApp(ver) c.Assert(err, check.IsNil) c.Log(string(body)) c.Assert(code, check.Equals, http.StatusCreated) @@ -74,6 +78,10 @@ func (s *ApiSuite) createApp(ver *types.Version, c *check.C) string { return resp.Id } +func (s *ApiSuite) rawCreateApp(ver *types.Version) (int, []byte, error) { + return s.sendRequest("POST", "/v1/apps", ver) +} + func (s *ApiSuite) listApps(c *check.C) []*types.Application { code, body, err := s.sendRequest("GET", "/v1/apps", nil) c.Assert(err, check.IsNil) @@ -187,19 +195,17 @@ func (s *ApiSuite) purge(maxWait time.Duration, c *check.C) error { } func (s *ApiSuite) sendRequest(method, uri string, data interface{}) (code int, body []byte, err error) { - buf := bytes.NewBuffer(nil) - if data != nil { - if err := json.NewEncoder(buf).Encode(data); err != nil { - return -1, nil, err - } - } - - req, err := http.NewRequest(method, "http://"+s.SwanHost+uri, buf) + req, err := s.newRawReq(method, uri, data) if err != nil { return -1, nil, err } + req.Header.Set("Content-Type", "application/json") + return s.sendRawRequest(req) +} + +func (s *ApiSuite) sendRawRequest(req *http.Request) (code int, body []byte, err error) { resp, err := http.DefaultClient.Do(req) if err != nil { return -1, nil, err @@ -214,6 +220,17 @@ func (s *ApiSuite) sendRequest(method, uri string, data interface{}) (code int, return resp.StatusCode, bs, nil } +func (s *ApiSuite) newRawReq(method, uri string, data interface{}) (*http.Request, error) { + buf := bytes.NewBuffer(nil) + if data != nil { + if err := json.NewEncoder(buf).Encode(data); err != nil { + return nil, err + } + } + + return http.NewRequest(method, "http://"+s.SwanHost+uri, buf) +} + func (s *ApiSuite) bind(data []byte, val interface{}) error { return json.Unmarshal(data, &val) } @@ -238,6 +255,11 @@ func (b *verBuilder) setName(name string) *verBuilder { return b } +func (b *verBuilder) setRunAs(runas string) *verBuilder { + b.RunAs = runas + return b +} + func (b *verBuilder) setCount(n int) *verBuilder { b.Instances = int32(n) return b @@ -260,7 +282,7 @@ func (b *verBuilder) setImage(image string) *verBuilder { func demoVersion() *verBuilder { return &verBuilder{ - Name: "", + Name: "demo", Instances: int32(1), Command: "", CPUs: 0.01,