diff options
author | Wolfy-J <[email protected]> | 2018-06-13 20:49:26 +0300 |
---|---|---|
committer | Wolfy-J <[email protected]> | 2018-06-13 20:49:26 +0300 |
commit | fba45ff53a51bf173471e6d046fc46f0cbaf89e3 (patch) | |
tree | 0855eda2eb334d4d4f26157438649e0f58151f9d | |
parent | 87fff670cc5a446f4c396c30d330ce7958e9f40f (diff) |
http service test + status test
-rw-r--r-- | cmd/rr/cmd/root.go | 2 | ||||
-rw-r--r-- | php-src/tests/http/echo.php | 2 | ||||
-rw-r--r-- | service/container.go | 4 | ||||
-rw-r--r-- | service/container_test.go | 18 | ||||
-rw-r--r-- | service/http/config_test.go | 2 | ||||
-rw-r--r-- | service/http/handler_test.go | 2 | ||||
-rw-r--r-- | service/http/request.go | 6 | ||||
-rw-r--r-- | service/http/service.go | 9 | ||||
-rw-r--r-- | service/http/service_test.go | 159 |
9 files changed, 185 insertions, 19 deletions
diff --git a/cmd/rr/cmd/root.go b/cmd/rr/cmd/root.go index e31eb332..bea42747 100644 --- a/cmd/rr/cmd/root.go +++ b/cmd/rr/cmd/root.go @@ -88,7 +88,7 @@ func init() { } if cfg := initConfig(cfgFile, []string{"."}, ".rr"); cfg != nil { - if err := Container.Configure(cfg); err != nil { + if err := Container.Init(cfg); err != nil { utils.Printf("<red+hb>Error:</reset> <red>%s</reset>\n", err) os.Exit(1) } diff --git a/php-src/tests/http/echo.php b/php-src/tests/http/echo.php index eeccc7e5..7004ada0 100644 --- a/php-src/tests/http/echo.php +++ b/php-src/tests/http/echo.php @@ -6,5 +6,5 @@ use \Psr\Http\Message\ResponseInterface; function handleRequest(ServerRequestInterface $req, ResponseInterface $resp): ResponseInterface { $resp->getBody()->write(strtoupper($req->getQueryParams()['hello'])); - return $resp; + return $resp->withStatus(201); }
\ No newline at end of file diff --git a/service/container.go b/service/container.go index 7c7633e7..ce9146bc 100644 --- a/service/container.go +++ b/service/container.go @@ -23,7 +23,7 @@ type Container interface { Register(name string, service Service) // Reconfigure configures all underlying services with given configuration. - Configure(cfg Config) error + Init(cfg Config) error // Check if svc has been registered. Has(service string) bool @@ -96,7 +96,7 @@ func (c *container) Get(target string) (svc Service, status int) { } // Init configures all underlying services with given configuration. -func (c *container) Configure(cfg Config) error { +func (c *container) Init(cfg Config) error { for _, e := range c.services { if e.getStatus() >= StatusConfigured { return fmt.Errorf("service [%s] has already been configured", e.name) diff --git a/service/container_test.go b/service/container_test.go index 58dd9dde..3c2f8761 100644 --- a/service/container_test.go +++ b/service/container_test.go @@ -140,7 +140,7 @@ func TestContainer_Configure(t *testing.T) { c.Register("test", svc) assert.Equal(t, 1, len(hook.Entries)) - assert.NoError(t, c.Configure(&testCfg{`{"test":"something"}`})) + assert.NoError(t, c.Init(&testCfg{`{"test":"something"}`})) s, st := c.Get("test") assert.IsType(t, &testService{}, s) @@ -157,7 +157,7 @@ func TestContainer_ConfigureNull(t *testing.T) { c.Register("test", svc) assert.Equal(t, 1, len(hook.Entries)) - assert.NoError(t, c.Configure(&testCfg{`{"another":"something"}`})) + assert.NoError(t, c.Init(&testCfg{`{"another":"something"}`})) assert.Equal(t, 2, len(hook.Entries)) s, st := c.Get("test") @@ -175,7 +175,7 @@ func TestContainer_ConfigureDisabled(t *testing.T) { c.Register("test", svc) assert.Equal(t, 1, len(hook.Entries)) - assert.NoError(t, c.Configure(&testCfg{`{"test":"something"}`})) + assert.NoError(t, c.Init(&testCfg{`{"test":"something"}`})) assert.Equal(t, 1, len(hook.Entries)) s, st := c.Get("test") @@ -196,7 +196,7 @@ func TestContainer_ConfigureError(t *testing.T) { c.Register("test", svc) assert.Equal(t, 1, len(hook.Entries)) - err := c.Configure(&testCfg{`{"test":"something"}`}) + err := c.Init(&testCfg{`{"test":"something"}`}) assert.Error(t, err) assert.Contains(t, err.Error(), "configure error") assert.Contains(t, err.Error(), "test") @@ -216,8 +216,8 @@ func TestContainer_ConfigureTwice(t *testing.T) { c.Register("test", svc) assert.Equal(t, 1, len(hook.Entries)) - assert.NoError(t, c.Configure(&testCfg{`{"test":"something"}`})) - assert.Error(t, c.Configure(&testCfg{`{"test":"something"}`})) + assert.NoError(t, c.Init(&testCfg{`{"test":"something"}`})) + assert.Error(t, c.Init(&testCfg{`{"test":"something"}`})) } func TestContainer_ServeEmptyContainer(t *testing.T) { @@ -246,7 +246,7 @@ func TestContainer_Serve(t *testing.T) { c := NewContainer(logger) c.Register("test", svc) assert.Equal(t, 1, len(hook.Entries)) - assert.NoError(t, c.Configure(&testCfg{`{"test":"something"}`})) + assert.NoError(t, c.Init(&testCfg{`{"test":"something"}`})) go func() { assert.NoError(t, c.Serve()) @@ -278,7 +278,7 @@ func TestContainer_ServeError(t *testing.T) { c := NewContainer(logger) c.Register("test", svc) assert.Equal(t, 1, len(hook.Entries)) - assert.NoError(t, c.Configure(&testCfg{`{"test":"something"}`})) + assert.NoError(t, c.Init(&testCfg{`{"test":"something"}`})) err := c.Serve() assert.Error(t, err) @@ -310,7 +310,7 @@ func TestContainer_ServeErrorMultiple(t *testing.T) { c.Register("test2", svc2) c.Register("test", svc) assert.Equal(t, 2, len(hook.Entries)) - assert.NoError(t, c.Configure(&testCfg{`{"test":"something", "test2":"something-else"}`})) + assert.NoError(t, c.Init(&testCfg{`{"test":"something", "test2":"something-else"}`})) err := c.Serve() assert.Error(t, err) diff --git a/service/http/config_test.go b/service/http/config_test.go index 18e8ab3e..b806b79b 100644 --- a/service/http/config_test.go +++ b/service/http/config_test.go @@ -64,7 +64,7 @@ func Test_Config_NoWorkers(t *testing.T) { assert.Error(t, cfg.Valid()) } -func Test_Confi_InvalidAddress(t *testing.T) { +func Test_Config_InvalidAddress(t *testing.T) { cfg := &Config{ Enable: true, Address: "", diff --git a/service/http/handler_test.go b/service/http/handler_test.go index 0e236df0..98379117 100644 --- a/service/http/handler_test.go +++ b/service/http/handler_test.go @@ -58,7 +58,7 @@ func TestServer_Echo(t *testing.T) { body, r, err := get("http://localhost:8077/?hello=world") assert.NoError(t, err) - assert.Equal(t, 200, r.StatusCode) + assert.Equal(t, 201, r.StatusCode) assert.Equal(t, "WORLD", body) } diff --git a/service/http/request.go b/service/http/request.go index 80998b11..e02d3cdb 100644 --- a/service/http/request.go +++ b/service/http/request.go @@ -12,7 +12,7 @@ import ( const ( defaultMaxMemory = 32 << 20 // 32 MB contentNone = iota + 900 - contentUndefined + contentStream contentMultipart contentFormData ) @@ -66,7 +66,7 @@ func NewRequest(r *http.Request, cfg *UploadsConfig) (req *Request, err error) { case contentNone: return req, nil - case contentUndefined: + case contentStream: req.body, err = ioutil.ReadAll(r.Body) return req, err @@ -142,7 +142,7 @@ func (r *Request) contentType() int { return contentMultipart } - return contentUndefined + return contentStream } // uri fetches full uri from request in a form of string (including https scheme if TLS connection is enabled). diff --git a/service/http/service.go b/service/http/service.go index 881c862d..2b30cd1c 100644 --- a/service/http/service.go +++ b/service/http/service.go @@ -6,6 +6,7 @@ import ( "context" "github.com/spiral/roadrunner" "github.com/spiral/roadrunner/service/rpc" + "sync" ) // Name contains default svc name. @@ -18,8 +19,10 @@ type middleware func(w http.ResponseWriter, r *http.Request) bool type Service struct { cfg *Config lsns []func(event int, ctx interface{}) - rr *roadrunner.Server mdws []middleware + + mu sync.Mutex + rr *roadrunner.Server srv *Handler http *http.Server } @@ -63,6 +66,7 @@ func (s *Service) Init(cfg service.Config, c service.Container) (bool, error) { // Serve serves the svc. func (s *Service) Serve() error { + s.mu.Lock() rr := roadrunner.NewServer(s.cfg.Workers) s.rr = rr @@ -77,6 +81,7 @@ func (s *Service) Serve() error { } else { s.http.Handler = s } + s.mu.Unlock() if err := rr.Start(); err != nil { return err @@ -92,6 +97,8 @@ func (s *Service) Serve() error { // Stop stops the svc. func (s *Service) Stop() { + s.mu.Lock() + defer s.mu.Unlock() if s.http == nil { return } diff --git a/service/http/service_test.go b/service/http/service_test.go new file mode 100644 index 00000000..08dc8a5b --- /dev/null +++ b/service/http/service_test.go @@ -0,0 +1,159 @@ +package http + +import ( + "testing" + "github.com/spiral/roadrunner/service" + "github.com/sirupsen/logrus/hooks/test" + "github.com/sirupsen/logrus" + "encoding/json" + "github.com/stretchr/testify/assert" + "os" + "time" + "net/http" + "io/ioutil" +) + +type testCfg struct{ httpCfg string } + +func (cfg *testCfg) Get(name string) service.Config { + if name == Name { + return &testCfg{cfg.httpCfg} + } + return nil +} +func (cfg *testCfg) Unmarshal(out interface{}) error { + json.Unmarshal([]byte(cfg.httpCfg), out) + return nil +} + +func Test_Service_NoConfig(t *testing.T) { + logger, _ := test.NewNullLogger() + logger.SetLevel(logrus.DebugLevel) + + c := service.NewContainer(logger) + c.Register(Name, &Service{}) + + assert.NoError(t, c.Init(&testCfg{`{}`})) + + s, st := c.Get(Name) + assert.NotNil(t, s) + assert.Equal(t, service.StatusRegistered, st) +} + +func Test_Service_Configure_Disable(t *testing.T) { + logger, _ := test.NewNullLogger() + logger.SetLevel(logrus.DebugLevel) + + c := service.NewContainer(logger) + c.Register(Name, &Service{}) + + assert.NoError(t, c.Init(&testCfg{`{ + "enable": false, + "address": ":8070", + "maxRequest": 1024, + "uploads": { + "dir": ` + tmpDir() + `, + "forbid": [] + }, + "workers":{ + "command": "php ../../php-src/tests/http/client.php echo pipes", + "relay": "pipes", + "pool": { + "numWorkers": 1, + "allocateTimeout": 10000000, + "destroyTimeout": 10000000 + } + } + }`})) + + s, st := c.Get(Name) + assert.NotNil(t, s) + assert.Equal(t, service.StatusRegistered, st) +} + +func Test_Service_Configure_Enable(t *testing.T) { + logger, _ := test.NewNullLogger() + logger.SetLevel(logrus.DebugLevel) + + c := service.NewContainer(logger) + c.Register(Name, &Service{}) + + assert.NoError(t, c.Init(&testCfg{`{ + "enable": true, + "address": ":8070", + "maxRequest": 1024, + "uploads": { + "dir": ` + tmpDir() + `, + "forbid": [] + }, + "workers":{ + "command": "php ../../php-src/tests/http/client.php echo pipes", + "relay": "pipes", + "pool": { + "numWorkers": 1, + "allocateTimeout": 10000000, + "destroyTimeout": 10000000 + } + } + }`})) + + s, st := c.Get(Name) + assert.NotNil(t, s) + assert.Equal(t, service.StatusConfigured, st) +} + +func Test_Service_Echo(t *testing.T) { + logger, _ := test.NewNullLogger() + logger.SetLevel(logrus.DebugLevel) + + c := service.NewContainer(logger) + c.Register(Name, &Service{}) + + assert.NoError(t, c.Init(&testCfg{`{ + "enable": true, + "address": ":8070", + "maxRequest": 1024, + "uploads": { + "dir": ` + tmpDir() + `, + "forbid": [] + }, + "workers":{ + "command": "php ../../php-src/tests/http/client.php echo pipes", + "relay": "pipes", + "pool": { + "numWorkers": 1, + "allocateTimeout": 10000000, + "destroyTimeout": 10000000 + } + } + }`})) + + s, st := c.Get(Name) + assert.NotNil(t, s) + assert.Equal(t, service.StatusConfigured, st) + + go func() { c.Serve() }() + time.Sleep(time.Millisecond * 10) + defer c.Stop() + + req, err := http.NewRequest("GET", "http://localhost:8070?hello=world", nil) + assert.NoError(t, err) + + r, err := http.DefaultClient.Do(req) + assert.NoError(t, err) + defer r.Body.Close() + + b, err := ioutil.ReadAll(r.Body) + assert.NoError(t, err) + + assert.NoError(t, err) + assert.Equal(t, 201, r.StatusCode) + assert.Equal(t, "WORLD", string(b)) +} + +func tmpDir() string { + p := os.TempDir() + r, _ := json.Marshal(p) + + return string(r) +} |