diff options
author | Valery Piashchynski <[email protected]> | 2021-09-16 21:46:50 +0300 |
---|---|---|
committer | GitHub <[email protected]> | 2021-09-16 21:46:50 +0300 |
commit | 3581b45f237a3f7aa29591ceb2bf6f4a4642a2f5 (patch) | |
tree | e723b19ec1ac16b7ccc7b3c2da69d4a416d63d81 /tests/plugins | |
parent | 337d292dd2d6ff0a555098b1970d8194d8df8bc2 (diff) | |
parent | 823d831b57b75f70c7c3bbbee355f2016633bb3b (diff) |
[#803]: feat(plugins): move plugins to a separate repositoryv2.5.0-alpha.2
[#803]: feat(plugins): move plugins to a separate repository
Diffstat (limited to 'tests/plugins')
191 files changed, 0 insertions, 22119 deletions
diff --git a/tests/plugins/broadcast/broadcast_plugin_test.go b/tests/plugins/broadcast/broadcast_plugin_test.go deleted file mode 100644 index 5d8c9ce9..00000000 --- a/tests/plugins/broadcast/broadcast_plugin_test.go +++ /dev/null @@ -1,513 +0,0 @@ -package broadcast - -import ( - "context" - "net" - "net/rpc" - "os" - "os/signal" - "sync" - "syscall" - "testing" - "time" - - goRedis "github.com/go-redis/redis/v8" - "github.com/golang/mock/gomock" - endure "github.com/spiral/endure/pkg/container" - goridgeRpc "github.com/spiral/goridge/v3/pkg/rpc" - "github.com/spiral/roadrunner/v2/plugins/broadcast" - "github.com/spiral/roadrunner/v2/plugins/config" - httpPlugin "github.com/spiral/roadrunner/v2/plugins/http" - "github.com/spiral/roadrunner/v2/plugins/logger" - "github.com/spiral/roadrunner/v2/plugins/memory" - "github.com/spiral/roadrunner/v2/plugins/redis" - rpcPlugin "github.com/spiral/roadrunner/v2/plugins/rpc" - "github.com/spiral/roadrunner/v2/plugins/server" - "github.com/spiral/roadrunner/v2/plugins/websockets" - websocketsv1 "github.com/spiral/roadrunner/v2/proto/websockets/v1beta" - "github.com/spiral/roadrunner/v2/tests/mocks" - "github.com/spiral/roadrunner/v2/tests/plugins/broadcast/plugins" - "github.com/stretchr/testify/assert" -) - -func TestBroadcastInit(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-broadcast-init.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &broadcast.Plugin{}, - &rpcPlugin.Plugin{}, - &logger.ZapLogger{}, - &server.Plugin{}, - &redis.Plugin{}, - &websockets.Plugin{}, - &httpPlugin.Plugin{}, - &memory.Plugin{}, - ) - - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - if err != nil { - t.Fatal(err) - } - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - stopCh <- struct{}{} - - wg.Wait() -} - -func TestBroadcastConfigError(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-broadcast-config-error.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &broadcast.Plugin{}, - &rpcPlugin.Plugin{}, - &logger.ZapLogger{}, - &server.Plugin{}, - &redis.Plugin{}, - &websockets.Plugin{}, - &httpPlugin.Plugin{}, - &memory.Plugin{}, - - &plugins.Plugin1{}, - ) - - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - _, err = cont.Serve() - assert.Error(t, err) -} - -func TestBroadcastNoConfig(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-broadcast-no-config.yaml", - Prefix: "rr", - } - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - - mockLogger.EXPECT().Debug("worker destructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("Started RPC service", "address", "tcp://127.0.0.1:6001", "plugins", []string{}).MinTimes(1) - - err = cont.RegisterAll( - cfg, - &broadcast.Plugin{}, - &rpcPlugin.Plugin{}, - mockLogger, - &server.Plugin{}, - &redis.Plugin{}, - &websockets.Plugin{}, - &httpPlugin.Plugin{}, - &memory.Plugin{}, - ) - - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - // should be just disabled - _, err = cont.Serve() - assert.NoError(t, err) -} - -func TestBroadcastSameSubscriber(t *testing.T) { - t.Run("RedisFlush", redisFlushAll("127.0.0.1:6379")) - t.Run("RedisFlush", redisFlushAll("127.0.0.1:6378")) - - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel), endure.GracefulShutdownTimeout(time.Second)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-broadcast-same-section.yaml", - Prefix: "rr", - } - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - - mockLogger.EXPECT().Debug("worker destructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("Started RPC service", "address", "tcp://127.0.0.1:6002", "plugins", []string{"broadcast"}).AnyTimes() - mockLogger.EXPECT().Debug("message published", "msg", gomock.Any()).AnyTimes() - - mockLogger.EXPECT().Info(`plugin1: {foo hello}`).Times(3) - mockLogger.EXPECT().Info(`plugin1: {foo2 hello}`).Times(2) - mockLogger.EXPECT().Info(`plugin1: {foo3 hello}`).Times(3) - mockLogger.EXPECT().Info(`plugin2: {foo hello}`).Times(3) - mockLogger.EXPECT().Info(`plugin3: {foo hello}`).Times(3) - mockLogger.EXPECT().Info(`plugin4: {foo hello}`).Times(3) - mockLogger.EXPECT().Info(`plugin5: {foo hello}`).Times(3) - mockLogger.EXPECT().Info(`plugin6: {foo hello}`).Times(3) - - err = cont.RegisterAll( - cfg, - &broadcast.Plugin{}, - &rpcPlugin.Plugin{}, - mockLogger, - &server.Plugin{}, - &redis.Plugin{}, - &websockets.Plugin{}, - &httpPlugin.Plugin{}, - &memory.Plugin{}, - - // test - redis - // test2 - redis (port 6378) - // test3 - memory - // test4 - memory - &plugins.Plugin1{}, // foo, foo2, foo3 test - &plugins.Plugin2{}, // foo, test - &plugins.Plugin3{}, // foo, test2 - &plugins.Plugin4{}, // foo, test3 - &plugins.Plugin5{}, // foo, test4 - &plugins.Plugin6{}, // foo, test3 - ) - - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - if err != nil { - t.Fatal(err) - } - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 2) - - t.Run("PublishHelloFooFoo2Foo3", BroadcastPublishFooFoo2Foo3("6002")) - time.Sleep(time.Second) - t.Run("PublishHelloFoo2", BroadcastPublishFoo2("6002")) - time.Sleep(time.Second) - t.Run("PublishHelloFoo3", BroadcastPublishFoo3("6002")) - time.Sleep(time.Second) - t.Run("PublishAsyncHelloFooFoo2Foo3", BroadcastPublishAsyncFooFoo2Foo3("6002")) - - time.Sleep(time.Second * 5) - - stopCh <- struct{}{} - - wg.Wait() - - t.Run("RedisFlush", redisFlushAll("127.0.0.1:6379")) - t.Run("RedisFlush", redisFlushAll("127.0.0.1:6378")) - - time.Sleep(time.Second * 5) -} - -func TestBroadcastSameSubscriberGlobal(t *testing.T) { - t.Run("RedisFlush", redisFlushAll("127.0.0.1:6379")) - t.Run("RedisFlush", redisFlushAll("127.0.0.1:6378")) - - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel), endure.GracefulShutdownTimeout(time.Second)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-broadcast-global.yaml", - Prefix: "rr", - } - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - - mockLogger.EXPECT().Debug("worker destructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("Started RPC service", "address", "tcp://127.0.0.1:6003", "plugins", []string{"broadcast"}).AnyTimes() - mockLogger.EXPECT().Debug("message published", "msg", gomock.Any()).AnyTimes() - - mockLogger.EXPECT().Info(`plugin1: {foo hello}`).Times(3) - mockLogger.EXPECT().Info(`plugin1: {foo2 hello}`).Times(2) - mockLogger.EXPECT().Info(`plugin1: {foo3 hello}`).Times(3) - mockLogger.EXPECT().Info(`plugin2: {foo hello}`).Times(3) - mockLogger.EXPECT().Info(`plugin3: {foo hello}`).Times(3) - mockLogger.EXPECT().Info(`plugin4: {foo hello}`).Times(3) - mockLogger.EXPECT().Info(`plugin5: {foo hello}`).Times(3) - mockLogger.EXPECT().Info(`plugin6: {foo hello}`).Times(3) - - err = cont.RegisterAll( - cfg, - &broadcast.Plugin{}, - &rpcPlugin.Plugin{}, - mockLogger, - &server.Plugin{}, - &redis.Plugin{}, - &websockets.Plugin{}, - &httpPlugin.Plugin{}, - &memory.Plugin{}, - - // test - redis - // test2 - redis (port 6378) - // test3 - memory - // test4 - memory - &plugins.Plugin1{}, // foo, foo2, foo3 test - &plugins.Plugin2{}, // foo, test - &plugins.Plugin3{}, // foo, test2 - &plugins.Plugin4{}, // foo, test3 - &plugins.Plugin5{}, // foo, test4 - &plugins.Plugin6{}, // foo, test3 - ) - - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - if err != nil { - t.Fatal(err) - } - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 2) - - t.Run("PublishHelloFooFoo2Foo3", BroadcastPublishFooFoo2Foo3("6003")) - time.Sleep(time.Second) - t.Run("PublishHelloFoo2", BroadcastPublishFoo2("6003")) - time.Sleep(time.Second) - t.Run("PublishHelloFoo3", BroadcastPublishFoo3("6003")) - time.Sleep(time.Second) - t.Run("PublishAsyncHelloFooFoo2Foo3", BroadcastPublishAsyncFooFoo2Foo3("6003")) - - time.Sleep(time.Second * 4) - - stopCh <- struct{}{} - - wg.Wait() - - time.Sleep(time.Second * 5) - - t.Run("RedisFlush", redisFlushAll("127.0.0.1:6379")) - t.Run("RedisFlush", redisFlushAll("127.0.0.1:6378")) -} - -func BroadcastPublishFooFoo2Foo3(port string) func(t *testing.T) { - return func(t *testing.T) { - conn, err := net.Dial("tcp", "127.0.0.1:"+port) - if err != nil { - t.Fatal(err) - } - - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - - ret := &websocketsv1.Response{} - err = client.Call("broadcast.Publish", makeMessage([]byte("hello"), "foo", "foo2", "foo3"), ret) - if err != nil { - t.Fatal(err) - } - } -} - -func BroadcastPublishFoo2(port string) func(t *testing.T) { - return func(t *testing.T) { - conn, err := net.Dial("tcp", "127.0.0.1:"+port) - if err != nil { - t.Fatal(err) - } - - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - - ret := &websocketsv1.Response{} - err = client.Call("broadcast.Publish", makeMessage([]byte("hello"), "foo"), ret) - if err != nil { - t.Fatal(err) - } - } -} - -func BroadcastPublishFoo3(port string) func(t *testing.T) { - return func(t *testing.T) { - conn, err := net.Dial("tcp", "127.0.0.1:"+port) - if err != nil { - t.Fatal(err) - } - - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - - ret := &websocketsv1.Response{} - err = client.Call("broadcast.Publish", makeMessage([]byte("hello"), "foo3"), ret) - if err != nil { - t.Fatal(err) - } - } -} - -func BroadcastPublishAsyncFooFoo2Foo3(port string) func(t *testing.T) { - return func(t *testing.T) { - conn, err := net.Dial("tcp", "127.0.0.1:"+port) - if err != nil { - t.Fatal(err) - } - - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - - ret := &websocketsv1.Response{} - err = client.Call("broadcast.PublishAsync", makeMessage([]byte("hello"), "foo", "foo2", "foo3"), ret) - if err != nil { - t.Fatal(err) - } - } -} - -func makeMessage(payload []byte, topics ...string) *websocketsv1.Request { - m := &websocketsv1.Request{ - Messages: []*websocketsv1.Message{ - { - Topics: topics, - Payload: payload, - }, - }, - } - - return m -} - -func redisFlushAll(addr string) func(t *testing.T) { - return func(t *testing.T) { - rdb := goRedis.NewClient(&goRedis.Options{ - Addr: addr, - Password: "", // no password set - DB: 0, // use default DB - }) - - rdb.FlushAll(context.Background()) - } -} diff --git a/tests/plugins/broadcast/configs/.rr-broadcast-config-error.yaml b/tests/plugins/broadcast/configs/.rr-broadcast-config-error.yaml deleted file mode 100644 index 1474feb7..00000000 --- a/tests/plugins/broadcast/configs/.rr-broadcast-config-error.yaml +++ /dev/null @@ -1,32 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../psr-worker-bench.php" - relay: "pipes" - relay_timeout: "20s" - -http: - address: 127.0.0.1:21345 - max_request_size: 1024 - middleware: [ "websockets" ] - trusted_subnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] - pool: - num_workers: 2 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s - -# no global or local config -broadcast: - default: - driver: redis - -logs: - mode: development - level: debug - -endure: - grace_period: 120s - print_graph: false - log_level: error diff --git a/tests/plugins/broadcast/configs/.rr-broadcast-global.yaml b/tests/plugins/broadcast/configs/.rr-broadcast-global.yaml deleted file mode 100644 index a7f9c35d..00000000 --- a/tests/plugins/broadcast/configs/.rr-broadcast-global.yaml +++ /dev/null @@ -1,50 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6003 - -server: - command: "php ../../psr-worker-bench.php" - relay: "pipes" - relay_timeout: "20s" - -http: - address: 127.0.0.1:21543 - max_request_size: 1024 - middleware: ["websockets"] - trusted_subnets: - [ - "10.0.0.0/8", - "127.0.0.0/8", - "172.16.0.0/12", - "192.168.0.0/16", - "::1/128", - "fc00::/7", - "fe80::/10", - ] - pool: - num_workers: 2 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s - -test: - addrs: - - "127.0.0.1:6379" - -broadcast: - test: - driver: redis - test2: - driver: redis - config: - addrs: - - "127.0.0.1:6378" - test3: - driver: memory - config: {} - test4: - driver: memory - config: {} - -logs: - mode: development - level: info diff --git a/tests/plugins/broadcast/configs/.rr-broadcast-init.yaml b/tests/plugins/broadcast/configs/.rr-broadcast-init.yaml deleted file mode 100644 index 1cbebdd7..00000000 --- a/tests/plugins/broadcast/configs/.rr-broadcast-init.yaml +++ /dev/null @@ -1,36 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../psr-worker-bench.php" - user: "" - group: "" - relay: "pipes" - relay_timeout: "20s" - -http: - address: 127.0.0.1:21345 - max_request_size: 1024 - middleware: [ "websockets" ] - trusted_subnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] - pool: - num_workers: 2 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s - -broadcast: - default: - driver: redis - config: - addrs: - - "127.0.0.1:6379" - -logs: - mode: development - level: error - -endure: - grace_period: 120s - print_graph: false - log_level: error diff --git a/tests/plugins/broadcast/configs/.rr-broadcast-no-config.yaml b/tests/plugins/broadcast/configs/.rr-broadcast-no-config.yaml deleted file mode 100644 index 90790869..00000000 --- a/tests/plugins/broadcast/configs/.rr-broadcast-no-config.yaml +++ /dev/null @@ -1,29 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../psr-worker-bench.php" - user: "" - group: "" - relay: "pipes" - relay_timeout: "20s" - -http: - address: 127.0.0.1:21345 - max_request_size: 1024 - middleware: [ "websockets" ] - trusted_subnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] - pool: - num_workers: 2 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s - -logs: - mode: development - level: debug - -endure: - grace_period: 120s - print_graph: false - log_level: error diff --git a/tests/plugins/broadcast/configs/.rr-broadcast-same-section.yaml b/tests/plugins/broadcast/configs/.rr-broadcast-same-section.yaml deleted file mode 100644 index 85a767cb..00000000 --- a/tests/plugins/broadcast/configs/.rr-broadcast-same-section.yaml +++ /dev/null @@ -1,48 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6002 - -server: - command: "php ../../psr-worker-bench.php" - relay: "pipes" - relay_timeout: "20s" - -http: - address: 127.0.0.1:21345 - max_request_size: 1024 - middleware: ["websockets"] - trusted_subnets: - [ - "10.0.0.0/8", - "127.0.0.0/8", - "172.16.0.0/12", - "192.168.0.0/16", - "::1/128", - "fc00::/7", - "fe80::/10", - ] - pool: - num_workers: 2 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s - -broadcast: - test: - driver: redis - config: - addrs: - - "127.0.0.1:6379" - test2: - driver: redis - config: - addrs: - - "127.0.0.1:6378" - test3: - driver: memory - config: {} - test4: - driver: memory - config: {} -logs: - mode: development - level: info diff --git a/tests/plugins/broadcast/plugins/plugin1.go b/tests/plugins/broadcast/plugins/plugin1.go deleted file mode 100644 index ed5139a8..00000000 --- a/tests/plugins/broadcast/plugins/plugin1.go +++ /dev/null @@ -1,73 +0,0 @@ -package plugins - -import ( - "context" - "fmt" - - "github.com/spiral/errors" - "github.com/spiral/roadrunner/v2/common/pubsub" - "github.com/spiral/roadrunner/v2/plugins/broadcast" - "github.com/spiral/roadrunner/v2/plugins/logger" -) - -const Plugin1Name = "plugin1" - -type Plugin1 struct { - log logger.Logger - b broadcast.Broadcaster - driver pubsub.SubReader - ctx context.Context - cancel context.CancelFunc -} - -func (p *Plugin1) Init(log logger.Logger, b broadcast.Broadcaster) error { - p.log = log - p.b = b - p.ctx, p.cancel = context.WithCancel(context.Background()) - return nil -} - -func (p *Plugin1) Serve() chan error { - errCh := make(chan error, 1) - - var err error - p.driver, err = p.b.GetDriver("test") - if err != nil { - errCh <- err - return errCh - } - - err = p.driver.Subscribe("1", "foo", "foo2", "foo3") - if err != nil { - panic(err) - } - - go func() { - for { - msg, err := p.driver.Next(p.ctx) - if err != nil { - if errors.Is(errors.TimeOut, err) { - return - } - errCh <- err - return - } - - p.log.Info(fmt.Sprintf("%s: %s", Plugin1Name, *msg)) - } - }() - - return errCh -} - -func (p *Plugin1) Stop() error { - _ = p.driver.Unsubscribe("1", "foo") - _ = p.driver.Unsubscribe("1", "foo2") - _ = p.driver.Unsubscribe("1", "foo3") - p.cancel() - return nil -} - -func (p *Plugin1) Name() string { - return Plugin1Name -} diff --git a/tests/plugins/broadcast/plugins/plugin2.go b/tests/plugins/broadcast/plugins/plugin2.go deleted file mode 100644 index 20cc1b24..00000000 --- a/tests/plugins/broadcast/plugins/plugin2.go +++ /dev/null @@ -1,74 +0,0 @@ -package plugins - -import ( - "context" - "fmt" - - "github.com/spiral/errors" - "github.com/spiral/roadrunner/v2/common/pubsub" - "github.com/spiral/roadrunner/v2/plugins/broadcast" - "github.com/spiral/roadrunner/v2/plugins/logger" -) - -const Plugin2Name = "plugin2" - -type Plugin2 struct { - log logger.Logger - b broadcast.Broadcaster - driver pubsub.SubReader - ctx context.Context - cancel context.CancelFunc -} - -func (p *Plugin2) Init(log logger.Logger, b broadcast.Broadcaster) error { - p.log = log - p.b = b - p.ctx, p.cancel = context.WithCancel(context.Background()) - return nil -} - -func (p *Plugin2) Serve() chan error { - errCh := make(chan error, 1) - - var err error - p.driver, err = p.b.GetDriver("test") - if err != nil { - panic(err) - } - - err = p.driver.Subscribe("2", "foo") - if err != nil { - panic(err) - } - - go func() { - for { - msg, err := p.driver.Next(p.ctx) - if err != nil { - if errors.Is(errors.TimeOut, err) { - return - } - errCh <- err - return - } - - if msg == nil { - continue - } - - p.log.Info(fmt.Sprintf("%s: %s", Plugin2Name, *msg)) - } - }() - - return errCh -} - -func (p *Plugin2) Stop() error { - _ = p.driver.Unsubscribe("2", "foo") - p.cancel() - return nil -} - -func (p *Plugin2) Name() string { - return Plugin2Name -} diff --git a/tests/plugins/broadcast/plugins/plugin3.go b/tests/plugins/broadcast/plugins/plugin3.go deleted file mode 100644 index 2f416d2e..00000000 --- a/tests/plugins/broadcast/plugins/plugin3.go +++ /dev/null @@ -1,74 +0,0 @@ -package plugins - -import ( - "context" - "fmt" - - "github.com/spiral/errors" - "github.com/spiral/roadrunner/v2/common/pubsub" - "github.com/spiral/roadrunner/v2/plugins/broadcast" - "github.com/spiral/roadrunner/v2/plugins/logger" -) - -const Plugin3Name = "plugin3" - -type Plugin3 struct { - log logger.Logger - b broadcast.Broadcaster - driver pubsub.SubReader - ctx context.Context - cancel context.CancelFunc -} - -func (p *Plugin3) Init(log logger.Logger, b broadcast.Broadcaster) error { - p.log = log - p.b = b - p.ctx, p.cancel = context.WithCancel(context.Background()) - return nil -} - -func (p *Plugin3) Serve() chan error { - errCh := make(chan error, 1) - - var err error - p.driver, err = p.b.GetDriver("test2") - if err != nil { - panic(err) - } - - err = p.driver.Subscribe("3", "foo") - if err != nil { - panic(err) - } - - go func() { - for { - msg, err := p.driver.Next(p.ctx) - if err != nil { - if errors.Is(errors.TimeOut, err) { - return - } - errCh <- err - return - } - - if msg == nil { - continue - } - - p.log.Info(fmt.Sprintf("%s: %s", Plugin3Name, *msg)) - } - }() - - return errCh -} - -func (p *Plugin3) Stop() error { - _ = p.driver.Unsubscribe("3", "foo") - p.cancel() - return nil -} - -func (p *Plugin3) Name() string { - return Plugin3Name -} diff --git a/tests/plugins/broadcast/plugins/plugin4.go b/tests/plugins/broadcast/plugins/plugin4.go deleted file mode 100644 index e2209648..00000000 --- a/tests/plugins/broadcast/plugins/plugin4.go +++ /dev/null @@ -1,74 +0,0 @@ -package plugins - -import ( - "context" - "fmt" - - "github.com/spiral/errors" - "github.com/spiral/roadrunner/v2/common/pubsub" - "github.com/spiral/roadrunner/v2/plugins/broadcast" - "github.com/spiral/roadrunner/v2/plugins/logger" -) - -const Plugin4Name = "plugin4" - -type Plugin4 struct { - log logger.Logger - b broadcast.Broadcaster - driver pubsub.SubReader - ctx context.Context - cancel context.CancelFunc -} - -func (p *Plugin4) Init(log logger.Logger, b broadcast.Broadcaster) error { - p.log = log - p.b = b - p.ctx, p.cancel = context.WithCancel(context.Background()) - return nil -} - -func (p *Plugin4) Serve() chan error { - errCh := make(chan error, 1) - - var err error - p.driver, err = p.b.GetDriver("test3") - if err != nil { - panic(err) - } - - err = p.driver.Subscribe("4", "foo") - if err != nil { - panic(err) - } - - go func() { - for { - msg, err := p.driver.Next(p.ctx) - if err != nil { - if errors.Is(errors.TimeOut, err) { - return - } - errCh <- err - return - } - - if msg == nil { - continue - } - - p.log.Info(fmt.Sprintf("%s: %s", Plugin4Name, *msg)) - } - }() - - return errCh -} - -func (p *Plugin4) Stop() error { - _ = p.driver.Unsubscribe("4", "foo") - p.cancel() - return nil -} - -func (p *Plugin4) Name() string { - return Plugin4Name -} diff --git a/tests/plugins/broadcast/plugins/plugin5.go b/tests/plugins/broadcast/plugins/plugin5.go deleted file mode 100644 index 122046b8..00000000 --- a/tests/plugins/broadcast/plugins/plugin5.go +++ /dev/null @@ -1,74 +0,0 @@ -package plugins - -import ( - "context" - "fmt" - - "github.com/spiral/errors" - "github.com/spiral/roadrunner/v2/common/pubsub" - "github.com/spiral/roadrunner/v2/plugins/broadcast" - "github.com/spiral/roadrunner/v2/plugins/logger" -) - -const Plugin5Name = "plugin5" - -type Plugin5 struct { - log logger.Logger - b broadcast.Broadcaster - driver pubsub.SubReader - ctx context.Context - cancel context.CancelFunc -} - -func (p *Plugin5) Init(log logger.Logger, b broadcast.Broadcaster) error { - p.log = log - p.b = b - p.ctx, p.cancel = context.WithCancel(context.Background()) - return nil -} - -func (p *Plugin5) Serve() chan error { - errCh := make(chan error, 1) - - var err error - p.driver, err = p.b.GetDriver("test4") - if err != nil { - panic(err) - } - - err = p.driver.Subscribe("5", "foo") - if err != nil { - panic(err) - } - - go func() { - for { - msg, err := p.driver.Next(p.ctx) - if err != nil { - if errors.Is(errors.TimeOut, err) { - return - } - errCh <- err - return - } - - if msg == nil { - continue - } - - p.log.Info(fmt.Sprintf("%s: %s", Plugin5Name, *msg)) - } - }() - - return errCh -} - -func (p *Plugin5) Stop() error { - _ = p.driver.Unsubscribe("5", "foo") - p.cancel() - return nil -} - -func (p *Plugin5) Name() string { - return Plugin5Name -} diff --git a/tests/plugins/broadcast/plugins/plugin6.go b/tests/plugins/broadcast/plugins/plugin6.go deleted file mode 100644 index 6ace0a79..00000000 --- a/tests/plugins/broadcast/plugins/plugin6.go +++ /dev/null @@ -1,74 +0,0 @@ -package plugins - -import ( - "context" - "fmt" - - "github.com/spiral/errors" - "github.com/spiral/roadrunner/v2/common/pubsub" - "github.com/spiral/roadrunner/v2/plugins/broadcast" - "github.com/spiral/roadrunner/v2/plugins/logger" -) - -const Plugin6Name = "plugin6" - -type Plugin6 struct { - log logger.Logger - b broadcast.Broadcaster - driver pubsub.SubReader - ctx context.Context - cancel context.CancelFunc -} - -func (p *Plugin6) Init(log logger.Logger, b broadcast.Broadcaster) error { - p.log = log - p.b = b - p.ctx, p.cancel = context.WithCancel(context.Background()) - return nil -} - -func (p *Plugin6) Serve() chan error { - errCh := make(chan error, 1) - - var err error - p.driver, err = p.b.GetDriver("test") - if err != nil { - panic(err) - } - - err = p.driver.Subscribe("6", "foo") - if err != nil { - panic(err) - } - - go func() { - for { - msg, err := p.driver.Next(p.ctx) - if err != nil { - if errors.Is(errors.TimeOut, err) { - return - } - errCh <- err - return - } - - if msg == nil { - continue - } - - p.log.Info(fmt.Sprintf("%s: %s", Plugin6Name, *msg)) - } - }() - - return errCh -} - -func (p *Plugin6) Stop() error { - _ = p.driver.Unsubscribe("6", "foo") - p.cancel() - return nil -} - -func (p *Plugin6) Name() string { - return Plugin6Name -} diff --git a/tests/plugins/config/config_test.go b/tests/plugins/config/config_test.go deleted file mode 100755 index 87ab1eaa..00000000 --- a/tests/plugins/config/config_test.go +++ /dev/null @@ -1,272 +0,0 @@ -package config - -import ( - "os" - "os/signal" - "testing" - "time" - - endure "github.com/spiral/endure/pkg/container" - "github.com/spiral/roadrunner/v2/plugins/config" - "github.com/spiral/roadrunner/v2/plugins/logger" - "github.com/spiral/roadrunner/v2/plugins/rpc" - "github.com/stretchr/testify/assert" -) - -func TestViperProvider_Init(t *testing.T) { - container, err := endure.NewContainer(nil, endure.RetryOnFail(true), endure.SetLogLevel(endure.ErrorLevel)) - if err != nil { - t.Fatal(err) - } - vp := &config.Viper{} - vp.Path = "configs/.rr.yaml" - vp.Prefix = "rr" - vp.Flags = nil - - err = container.Register(vp) - if err != nil { - t.Fatal(err) - } - - err = container.Register(&Foo{}) - if err != nil { - t.Fatal(err) - } - - err = container.Init() - if err != nil { - t.Fatal(err) - } - - errCh, err := container.Serve() - if err != nil { - t.Fatal(err) - } - - // stop by CTRL+C - c := make(chan os.Signal, 1) - signal.Notify(c, os.Interrupt) - - tt := time.NewTicker(time.Second * 2) - defer tt.Stop() - - for { - select { - case e := <-errCh: - assert.NoError(t, e.Error) - assert.NoError(t, container.Stop()) - return - case <-c: - er := container.Stop() - assert.NoError(t, er) - return - case <-tt.C: - assert.NoError(t, container.Stop()) - return - } - } -} - -func TestConfigOverwriteFail(t *testing.T) { - container, err := endure.NewContainer(nil, endure.RetryOnFail(false), endure.SetLogLevel(endure.ErrorLevel)) - if err != nil { - t.Fatal(err) - } - vp := &config.Viper{} - vp.Path = "configs/.rr.yaml" - vp.Prefix = "rr" - vp.Flags = []string{"rpc.listen=tcp//not_exist"} - - err = container.RegisterAll( - &logger.ZapLogger{}, - &rpc.Plugin{}, - vp, - &Foo2{}, - ) - assert.NoError(t, err) - - err = container.Init() - assert.Error(t, err) -} - -func TestConfigOverwriteValid(t *testing.T) { - container, err := endure.NewContainer(nil, endure.RetryOnFail(false), endure.SetLogLevel(endure.ErrorLevel)) - if err != nil { - t.Fatal(err) - } - vp := &config.Viper{} - vp.Path = "configs/.rr.yaml" - vp.Prefix = "rr" - vp.Flags = []string{"rpc.listen=tcp://127.0.0.1:36643"} - - err = container.RegisterAll( - &logger.ZapLogger{}, - &rpc.Plugin{}, - vp, - &Foo2{}, - ) - assert.NoError(t, err) - - err = container.Init() - assert.NoError(t, err) - - errCh, err := container.Serve() - assert.NoError(t, err) - - // stop by CTRL+C - c := make(chan os.Signal, 1) - signal.Notify(c, os.Interrupt) - - tt := time.NewTicker(time.Second * 3) - defer tt.Stop() - - for { - select { - case e := <-errCh: - assert.NoError(t, e.Error) - assert.NoError(t, container.Stop()) - return - case <-c: - er := container.Stop() - assert.NoError(t, er) - return - case <-tt.C: - assert.NoError(t, container.Stop()) - return - } - } -} - -func TestConfigEnvVariables(t *testing.T) { - container, err := endure.NewContainer(nil, endure.RetryOnFail(false), endure.SetLogLevel(endure.ErrorLevel)) - if err != nil { - t.Fatal(err) - } - - err = os.Setenv("SUPER_RPC_ENV", "tcp://127.0.0.1:36643") - assert.NoError(t, err) - - vp := &config.Viper{} - vp.Path = "configs/.rr-env.yaml" - vp.Prefix = "rr" - - err = container.RegisterAll( - &logger.ZapLogger{}, - &rpc.Plugin{}, - vp, - &Foo2{}, - ) - assert.NoError(t, err) - - err = container.Init() - assert.NoError(t, err) - - errCh, err := container.Serve() - assert.NoError(t, err) - - // stop by CTRL+C - c := make(chan os.Signal, 1) - signal.Notify(c, os.Interrupt) - - tt := time.NewTicker(time.Second * 3) - defer tt.Stop() - - for { - select { - case e := <-errCh: - assert.NoError(t, e.Error) - assert.NoError(t, container.Stop()) - return - case <-c: - er := container.Stop() - assert.NoError(t, er) - return - case <-tt.C: - assert.NoError(t, container.Stop()) - return - } - } -} - -func TestConfigEnvVariablesFail(t *testing.T) { - container, err := endure.NewContainer(nil, endure.RetryOnFail(false), endure.SetLogLevel(endure.ErrorLevel)) - if err != nil { - t.Fatal(err) - } - - err = os.Setenv("SUPER_RPC_ENV", "tcp://127.0.0.1:6065") - assert.NoError(t, err) - - vp := &config.Viper{} - vp.Path = "configs/.rr-env.yaml" - vp.Prefix = "rr" - - err = container.RegisterAll( - &logger.ZapLogger{}, - &rpc.Plugin{}, - vp, - &Foo2{}, - ) - assert.NoError(t, err) - - err = container.Init() - assert.NoError(t, err) - - _, err = container.Serve() - assert.Error(t, err) -} - -func TestConfigProvider_GeneralSection(t *testing.T) { - container, err := endure.NewContainer(nil, endure.RetryOnFail(true), endure.SetLogLevel(endure.ErrorLevel)) - if err != nil { - t.Fatal(err) - } - vp := &config.Viper{} - vp.Path = "configs/.rr.yaml" - vp.Prefix = "rr" - vp.Flags = nil - vp.CommonConfig = &config.General{GracefulTimeout: time.Second * 10} - - err = container.Register(vp) - if err != nil { - t.Fatal(err) - } - - err = container.Register(&Foo3{}) - if err != nil { - t.Fatal(err) - } - - err = container.Init() - if err != nil { - t.Fatal(err) - } - - errCh, err := container.Serve() - if err != nil { - t.Fatal(err) - } - - // stop by CTRL+C - c := make(chan os.Signal, 1) - signal.Notify(c, os.Interrupt) - - tt := time.NewTicker(time.Second * 2) - defer tt.Stop() - - for { - select { - case e := <-errCh: - assert.NoError(t, e.Error) - assert.NoError(t, container.Stop()) - return - case <-c: - er := container.Stop() - assert.NoError(t, er) - return - case <-tt.C: - assert.NoError(t, container.Stop()) - return - } - } -} diff --git a/tests/plugins/config/configs/.rr-env.yaml b/tests/plugins/config/configs/.rr-env.yaml deleted file mode 100755 index 3cacb5d0..00000000 --- a/tests/plugins/config/configs/.rr-env.yaml +++ /dev/null @@ -1,24 +0,0 @@ -rpc: - listen: ${SUPER_RPC_ENV} - -logs: - mode: development - level: error - -reload: - interval: 1s - patterns: [ ".php" ] - services: - http: - recursive: true - ignore: [ "vendor" ] - patterns: [ ".php", ".go",".md", ] - dirs: [ "." ] - jobs: - recursive: false - ignore: [ "service/metrics" ] - dirs: [ "./jobs" ] - rpc: - recursive: true - patterns: [ ".json" ] - dirs: [ "" ] diff --git a/tests/plugins/config/configs/.rr.yaml b/tests/plugins/config/configs/.rr.yaml deleted file mode 100755 index 575cdd33..00000000 --- a/tests/plugins/config/configs/.rr.yaml +++ /dev/null @@ -1,24 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6060 - -logs: - mode: development - level: error - -reload: - interval: 1s - patterns: [".php"] - services: - http: - recursive: true - ignore: ["vendor"] - patterns: [".php", ".go",".md",] - dirs: ["."] - jobs: - recursive: false - ignore: ["service/metrics"] - dirs: ["./jobs"] - rpc: - recursive: true - patterns: [".json"] - dirs: [""] diff --git a/tests/plugins/config/plugin1.go b/tests/plugins/config/plugin1.go deleted file mode 100755 index 08a48a4f..00000000 --- a/tests/plugins/config/plugin1.go +++ /dev/null @@ -1,96 +0,0 @@ -package config - -import ( - "time" - - "github.com/spiral/errors" - "github.com/spiral/roadrunner/v2/plugins/config" -) - -type AllConfig struct { - RPC struct { - Listen string `mapstructure:"listen"` - } `mapstructure:"rpc"` - Reload struct { - Enabled bool `mapstructure:"enabled"` - Interval string `mapstructure:"interval"` - Patterns []string `mapstructure:"patterns"` - Services struct { - HTTP struct { - Recursive bool `mapstructure:"recursive"` - Ignore []string `mapstructure:"ignore"` - Patterns []string `mapstructure:"patterns"` - Dirs []string `mapstructure:"dirs"` - } `mapstructure:"http"` - Jobs struct { - Recursive bool `mapstructure:"recursive"` - Ignore []string `mapstructure:"ignore"` - Dirs []string `mapstructure:"dirs"` - } `mapstructure:"jobs"` - RPC struct { - Recursive bool `mapstructure:"recursive"` - Patterns []string `mapstructure:"patterns"` - Dirs []string `mapstructure:"dirs"` - } `mapstructure:"rpc"` - } `mapstructure:"services"` - } `mapstructure:"reload"` -} - -// ReloadConfig is a Reload configuration point. -type ReloadConfig struct { - Interval time.Duration - Patterns []string - Services map[string]ServiceConfig -} - -type ServiceConfig struct { - Enabled bool - Recursive bool - Patterns []string - Dirs []string - Ignore []string -} - -type Foo struct { - configProvider config.Configurer -} - -// Depends on S2 and DB (S3 in the current case) -func (f *Foo) Init(p config.Configurer) error { - f.configProvider = p - return nil -} - -func (f *Foo) Serve() chan error { - const op = errors.Op("foo_plugin_serve") - errCh := make(chan error, 1) - - r := &ReloadConfig{} - err := f.configProvider.UnmarshalKey("reload", r) - if err != nil { - errCh <- err - } - - if len(r.Patterns) == 0 { - errCh <- errors.E(op, errors.Str("should be at least one pattern, but got 0")) - return errCh - } - - var allCfg AllConfig - err = f.configProvider.Unmarshal(&allCfg) - if err != nil { - errCh <- errors.E(op, errors.Str("should be at least one pattern, but got 0")) - return errCh - } - - if allCfg.RPC.Listen != "tcp://127.0.0.1:6060" { - errCh <- errors.E(op, errors.Str("RPC.Listen should be parsed")) - return errCh - } - - return errCh -} - -func (f *Foo) Stop() error { - return nil -} diff --git a/tests/plugins/config/plugin2.go b/tests/plugins/config/plugin2.go deleted file mode 100755 index 8c6f36c1..00000000 --- a/tests/plugins/config/plugin2.go +++ /dev/null @@ -1,50 +0,0 @@ -package config - -import ( - "github.com/spiral/errors" - "github.com/spiral/roadrunner/v2/plugins/config" -) - -type Foo2 struct { - configProvider config.Configurer -} - -// Depends on S2 and DB (S3 in the current case) -func (f *Foo2) Init(p config.Configurer) error { - f.configProvider = p - return nil -} - -func (f *Foo2) Serve() chan error { - const op = errors.Op("foo_plugin_serve") - errCh := make(chan error, 1) - - r := &ReloadConfig{} - err := f.configProvider.UnmarshalKey("reload", r) - if err != nil { - errCh <- err - } - - if len(r.Patterns) == 0 { - errCh <- errors.E(op, errors.Str("should be at least one pattern, but got 0")) - return errCh - } - - var allCfg AllConfig - err = f.configProvider.Unmarshal(&allCfg) - if err != nil { - errCh <- errors.E(op, errors.Str("should be at least one pattern, but got 0")) - return errCh - } - - if allCfg.RPC.Listen != "tcp://127.0.0.1:36643" { - errCh <- errors.E(op, errors.Str("RPC.Listen should be overwritten")) - return errCh - } - - return errCh -} - -func (f *Foo2) Stop() error { - return nil -} diff --git a/tests/plugins/config/plugin3.go b/tests/plugins/config/plugin3.go deleted file mode 100755 index 41b79259..00000000 --- a/tests/plugins/config/plugin3.go +++ /dev/null @@ -1,34 +0,0 @@ -package config - -import ( - "time" - - "github.com/spiral/errors" - "github.com/spiral/roadrunner/v2/plugins/config" -) - -type Foo3 struct { - configProvider config.Configurer -} - -// Depends on S2 and DB (S3 in the current case) -func (f *Foo3) Init(p config.Configurer) error { - f.configProvider = p - return nil -} - -func (f *Foo3) Serve() chan error { - const op = errors.Op("foo_plugin_serve") - errCh := make(chan error, 1) - - if f.configProvider.GetCommonConfig().GracefulTimeout != time.Second*10 { - errCh <- errors.E(op, errors.Str("GracefulTimeout should be eq to 10 seconds")) - return errCh - } - - return errCh -} - -func (f *Foo3) Stop() error { - return nil -} diff --git a/tests/plugins/grpc/configs/.rr-grpc-init.yaml b/tests/plugins/grpc/configs/.rr-grpc-init.yaml deleted file mode 100644 index b743a766..00000000 --- a/tests/plugins/grpc/configs/.rr-grpc-init.yaml +++ /dev/null @@ -1,58 +0,0 @@ -rpc: - listen: "tcp://127.0.0.1:6001" - -server: - command: "php ../../psr-worker-bench.php" - relay: "pipes" - relay_timeout: "20s" - -# GRPC service configuration -grpc: - # socket to listen - listen: "tcp://localhost:9001" - - # proto root file - proto: "configs/test.proto" - - # max send limit (MB) - max_send_msg_size: 50 - - # max receive limit (MB) - max_recv_msg_size: 50 - - # MaxConnectionIdle is a duration for the amount of time after which an - # idle connection would be closed by sending a GoAway. Idleness duration is - # defined since the most recent time the number of outstanding RPCs became - # zero or the connection establishment. - max_connection_idle: 0s - - # MaxConnectionAge is a duration for the maximum amount of time a - # connection may exist before it will be closed by sending a GoAway. A - # random jitter of +/-10% will be added to MaxConnectionAge to spread out - # connection storms. - max_connection_age: 0s - - # MaxConnectionAgeGrace is an additive period after MaxConnectionAge after - # which the connection will be forcibly closed. - max_connection_age_grace: 0s - - # MaxConnectionAgeGrace is an additive period after MaxConnectionAge after - # which the connection will be forcibly closed. - max_concurrent_streams: 10 - - # After a duration of this time if the server doesn't see any activity it - # pings the client to see if the transport is still alive. - # If set below 1s, a minimum value of 1s will be used instead. - ping_time: 1s - - # After having pinged for keepalive check, the server waits for a duration - # of Timeout and if no activity is seen even after that the connection is - # closed. - timeout: 200s - - # Usual workers pool configuration - pool: - num_workers: 2 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60 diff --git a/tests/plugins/grpc/configs/external.proto b/tests/plugins/grpc/configs/external.proto deleted file mode 100644 index 2bbe806e..00000000 --- a/tests/plugins/grpc/configs/external.proto +++ /dev/null @@ -1,19 +0,0 @@ -syntax = "proto3"; -package tests; - -service External { - rpc Echo (Ping) returns (Pong) { - } - - rpc Empty (EmptyMessage) returns (EmptyMessage) { - - } -} - -message Ping { - int64 value = 1; -} - -message Pong { - int64 value = 1; -}
\ No newline at end of file diff --git a/tests/plugins/grpc/configs/test.pb.go b/tests/plugins/grpc/configs/test.pb.go deleted file mode 100644 index 5f30ceb6..00000000 --- a/tests/plugins/grpc/configs/test.pb.go +++ /dev/null @@ -1,291 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.27.1 -// protoc v3.17.3 -// source: test.proto - -package __ - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type Message struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Msg string `protobuf:"bytes,1,opt,name=msg,proto3" json:"msg,omitempty"` -} - -func (x *Message) Reset() { - *x = Message{} - if protoimpl.UnsafeEnabled { - mi := &file_test_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Message) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Message) ProtoMessage() {} - -func (x *Message) ProtoReflect() protoreflect.Message { - mi := &file_test_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Message.ProtoReflect.Descriptor instead. -func (*Message) Descriptor() ([]byte, []int) { - return file_test_proto_rawDescGZIP(), []int{0} -} - -func (x *Message) GetMsg() string { - if x != nil { - return x.Msg - } - return "" -} - -type EmptyMessage struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *EmptyMessage) Reset() { - *x = EmptyMessage{} - if protoimpl.UnsafeEnabled { - mi := &file_test_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *EmptyMessage) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*EmptyMessage) ProtoMessage() {} - -func (x *EmptyMessage) ProtoReflect() protoreflect.Message { - mi := &file_test_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use EmptyMessage.ProtoReflect.Descriptor instead. -func (*EmptyMessage) Descriptor() ([]byte, []int) { - return file_test_proto_rawDescGZIP(), []int{1} -} - -type DetailsMessageForException struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Code uint64 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` - Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` -} - -func (x *DetailsMessageForException) Reset() { - *x = DetailsMessageForException{} - if protoimpl.UnsafeEnabled { - mi := &file_test_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DetailsMessageForException) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DetailsMessageForException) ProtoMessage() {} - -func (x *DetailsMessageForException) ProtoReflect() protoreflect.Message { - mi := &file_test_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DetailsMessageForException.ProtoReflect.Descriptor instead. -func (*DetailsMessageForException) Descriptor() ([]byte, []int) { - return file_test_proto_rawDescGZIP(), []int{2} -} - -func (x *DetailsMessageForException) GetCode() uint64 { - if x != nil { - return x.Code - } - return 0 -} - -func (x *DetailsMessageForException) GetMessage() string { - if x != nil { - return x.Message - } - return "" -} - -var File_test_proto protoreflect.FileDescriptor - -var file_test_proto_rawDesc = []byte{ - 0x0a, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x73, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x22, 0x1b, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, - 0x73, 0x67, 0x22, 0x0e, 0x0a, 0x0c, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x22, 0x4a, 0x0a, 0x1a, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x4d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x46, 0x6f, 0x72, 0x45, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, - 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x32, 0xf6, - 0x01, 0x0a, 0x04, 0x54, 0x65, 0x73, 0x74, 0x12, 0x2c, 0x0a, 0x04, 0x45, 0x63, 0x68, 0x6f, 0x12, - 0x10, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x1a, 0x10, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x2d, 0x0a, 0x05, 0x54, 0x68, 0x72, 0x6f, 0x77, 0x12, 0x10, - 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x1a, 0x10, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x22, 0x00, 0x12, 0x2b, 0x0a, 0x03, 0x44, 0x69, 0x65, 0x12, 0x10, 0x2e, 0x73, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x10, 0x2e, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, - 0x00, 0x12, 0x2c, 0x0a, 0x04, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x10, 0x2e, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x10, 0x2e, 0x73, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, - 0x36, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x15, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x15, - 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x4d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x42, 0x05, 0x5a, 0x03, 0x2e, 0x2f, 0x3b, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_test_proto_rawDescOnce sync.Once - file_test_proto_rawDescData = file_test_proto_rawDesc -) - -func file_test_proto_rawDescGZIP() []byte { - file_test_proto_rawDescOnce.Do(func() { - file_test_proto_rawDescData = protoimpl.X.CompressGZIP(file_test_proto_rawDescData) - }) - return file_test_proto_rawDescData -} - -var file_test_proto_msgTypes = make([]protoimpl.MessageInfo, 3) -var file_test_proto_goTypes = []interface{}{ - (*Message)(nil), // 0: service.Message - (*EmptyMessage)(nil), // 1: service.EmptyMessage - (*DetailsMessageForException)(nil), // 2: service.DetailsMessageForException -} -var file_test_proto_depIdxs = []int32{ - 0, // 0: service.Test.Echo:input_type -> service.Message - 0, // 1: service.Test.Throw:input_type -> service.Message - 0, // 2: service.Test.Die:input_type -> service.Message - 0, // 3: service.Test.Info:input_type -> service.Message - 1, // 4: service.Test.Ping:input_type -> service.EmptyMessage - 0, // 5: service.Test.Echo:output_type -> service.Message - 0, // 6: service.Test.Throw:output_type -> service.Message - 0, // 7: service.Test.Die:output_type -> service.Message - 0, // 8: service.Test.Info:output_type -> service.Message - 1, // 9: service.Test.Ping:output_type -> service.EmptyMessage - 5, // [5:10] is the sub-list for method output_type - 0, // [0:5] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_test_proto_init() } -func file_test_proto_init() { - if File_test_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_test_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Message); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_test_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*EmptyMessage); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_test_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DetailsMessageForException); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_test_proto_rawDesc, - NumEnums: 0, - NumMessages: 3, - NumExtensions: 0, - NumServices: 1, - }, - GoTypes: file_test_proto_goTypes, - DependencyIndexes: file_test_proto_depIdxs, - MessageInfos: file_test_proto_msgTypes, - }.Build() - File_test_proto = out.File - file_test_proto_rawDesc = nil - file_test_proto_goTypes = nil - file_test_proto_depIdxs = nil -} diff --git a/tests/plugins/grpc/configs/test.proto b/tests/plugins/grpc/configs/test.proto deleted file mode 100644 index 2e1c90a9..00000000 --- a/tests/plugins/grpc/configs/test.proto +++ /dev/null @@ -1,33 +0,0 @@ -syntax = "proto3"; - -package service; -option go_package = "./;"; - -service Test { - rpc Echo (Message) returns (Message) { - } - - rpc Throw (Message) returns (Message) { - } - - rpc Die (Message) returns (Message) { - } - - rpc Info (Message) returns (Message) { - } - - rpc Ping (EmptyMessage) returns (EmptyMessage) { - } -} - -message Message { - string msg = 1; -} - -message EmptyMessage { -} - -message DetailsMessageForException { - uint64 code = 1; - string message = 2; -}
\ No newline at end of file diff --git a/tests/plugins/grpc/grpc_plugin_test.go b/tests/plugins/grpc/grpc_plugin_test.go deleted file mode 100644 index b92282f7..00000000 --- a/tests/plugins/grpc/grpc_plugin_test.go +++ /dev/null @@ -1,89 +0,0 @@ -package grpc_test - -import ( - "os" - "os/signal" - "sync" - "syscall" - "testing" - "time" - - endure "github.com/spiral/endure/pkg/container" - "github.com/spiral/roadrunner/v2/plugins/config" - "github.com/spiral/roadrunner/v2/plugins/grpc" - "github.com/spiral/roadrunner/v2/plugins/informer" - "github.com/spiral/roadrunner/v2/plugins/logger" - "github.com/spiral/roadrunner/v2/plugins/resetter" - rpcPlugin "github.com/spiral/roadrunner/v2/plugins/rpc" - "github.com/spiral/roadrunner/v2/plugins/server" - "github.com/stretchr/testify/assert" -) - -func TestGrpcInit(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-grpc-init.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &grpc.Plugin{}, - &rpcPlugin.Plugin{}, - &logger.ZapLogger{}, - &server.Plugin{}, - &informer.Plugin{}, - &resetter.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 5) - stopCh <- struct{}{} - - wg.Wait() -} diff --git a/tests/plugins/grpc/php_server/.rr.yaml b/tests/plugins/grpc/php_server/.rr.yaml deleted file mode 100644 index cc4a9300..00000000 --- a/tests/plugins/grpc/php_server/.rr.yaml +++ /dev/null @@ -1,22 +0,0 @@ -grpc: - listen: "tcp://:9001" - proto: "service.proto" - tls: - key: "server.key" - cert: "server.crt" - workers: - command: "php worker.php" - pool: - numWorkers: 4 - -metrics: - address: localhost:2112 - -limit: - interval: 1 - services: - grpc: - maxMemory: 100 - TTL: 0 - idleTTL: 0 - execTTL: 60
\ No newline at end of file diff --git a/tests/plugins/grpc/php_server/composer.json b/tests/plugins/grpc/php_server/composer.json deleted file mode 100644 index b6303291..00000000 --- a/tests/plugins/grpc/php_server/composer.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "app/example-grpc-server", - "description": "Example GRPC Server", - "repositories": [ - { - "type": "path", - "url": "../.." - } - ], - "require": { - "spiral/php-grpc": "*" - }, - "require-dev": { - "grpc/grpc": "^1.36" - }, - "autoload": { - "psr-4": { - "": "src" - } - }, - "minimum-stability": "dev", - "prefer-stable": true -} diff --git a/tests/plugins/grpc/php_server/server.crt b/tests/plugins/grpc/php_server/server.crt deleted file mode 100644 index 24d67fd7..00000000 --- a/tests/plugins/grpc/php_server/server.crt +++ /dev/null @@ -1,15 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICTTCCAdOgAwIBAgIJAOKyUd+llTRKMAoGCCqGSM49BAMCMGMxCzAJBgNVBAYT -AlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNpc2Nv -MRMwEQYDVQQKDApSb2FkUnVubmVyMRIwEAYDVQQDDAlsb2NhbGhvc3QwHhcNMTgw -OTMwMTMzNDUzWhcNMjgwOTI3MTMzNDUzWjBjMQswCQYDVQQGEwJVUzETMBEGA1UE -CAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzETMBEGA1UECgwK -Um9hZFJ1bm5lcjESMBAGA1UEAwwJbG9jYWxob3N0MHYwEAYHKoZIzj0CAQYFK4EE -ACIDYgAEVnbShsM+l5RR3wfWWmGhzuFGwNzKCk7i9xyobDIyBUxG/UUSfj7KKlUX -puDnDEtF5xXcepl744CyIAYFLOXHb5WqI4jCOzG0o9f/00QQ4bQudJOdbqV910QF -C2vb7Fxro1MwUTAdBgNVHQ4EFgQU9xUexnbB6ORKayA7Pfjzs33otsAwHwYDVR0j -BBgwFoAU9xUexnbB6ORKayA7Pfjzs33otsAwDwYDVR0TAQH/BAUwAwEB/zAKBggq -hkjOPQQDAgNoADBlAjEAue3HhR/MUhxoa9tSDBtOJT3FYbDQswrsdqBTz97CGKst -e7XeZ3HMEvEXy0hGGEMhAjAqcD/4k9vViVppgWFtkk6+NFbm+Kw/QeeAiH5FgFSj -8xQcb+b7nPwNLp3JOkXkVd4= ------END CERTIFICATE----- diff --git a/tests/plugins/grpc/php_server/server.key b/tests/plugins/grpc/php_server/server.key deleted file mode 100644 index 7501dd46..00000000 --- a/tests/plugins/grpc/php_server/server.key +++ /dev/null @@ -1,9 +0,0 @@ ------BEGIN EC PARAMETERS----- -BgUrgQQAIg== ------END EC PARAMETERS----- ------BEGIN EC PRIVATE KEY----- -MIGkAgEBBDCQP8utxNbHR6xZOLAJgUhn88r6IrPqmN0MsgGJM/jePB+T9UhkmIU8 -PMm2HeScbcugBwYFK4EEACKhZANiAARWdtKGwz6XlFHfB9ZaYaHO4UbA3MoKTuL3 -HKhsMjIFTEb9RRJ+PsoqVRem4OcMS0XnFdx6mXvjgLIgBgUs5cdvlaojiMI7MbSj -1//TRBDhtC50k51upX3XRAULa9vsXGs= ------END EC PRIVATE KEY----- diff --git a/tests/plugins/grpc/php_server/service.proto b/tests/plugins/grpc/php_server/service.proto deleted file mode 100644 index 60ff84a9..00000000 --- a/tests/plugins/grpc/php_server/service.proto +++ /dev/null @@ -1,11 +0,0 @@ -syntax = "proto3"; -package service; - -service Echo { - rpc Ping (Message) returns (Message) { - } -} - -message Message { - string msg = 1; -}
\ No newline at end of file diff --git a/tests/plugins/grpc/php_server/src/EchoService.php b/tests/plugins/grpc/php_server/src/EchoService.php deleted file mode 100644 index c2707811..00000000 --- a/tests/plugins/grpc/php_server/src/EchoService.php +++ /dev/null @@ -1,17 +0,0 @@ -<?php -/** - * Sample GRPC PHP server. - */ - -use Spiral\GRPC\ContextInterface; -use Service\EchoInterface; -use Service\Message; - -class EchoService implements EchoInterface -{ - public function Ping(ContextInterface $ctx, Message $in): Message - { - $out = new Message(); - return $out->setMsg(strtoupper($in->getMsg())); - } -}
\ No newline at end of file diff --git a/tests/plugins/grpc/php_server/src/GPBMetadata/Service.php b/tests/plugins/grpc/php_server/src/GPBMetadata/Service.php deleted file mode 100644 index c1b65b21..00000000 --- a/tests/plugins/grpc/php_server/src/GPBMetadata/Service.php +++ /dev/null @@ -1,27 +0,0 @@ -<?php -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: service.proto - -namespace GPBMetadata; - -class Service -{ - public static $is_initialized = false; - - public static function initOnce() { - $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool(); - - if (static::$is_initialized == true) { - return; - } - $pool->internalAddGeneratedFile(hex2bin( - "0a6e0a0d736572766963652e70726f746f12077365727669636522160a07" . - "4d657373616765120b0a036d736718012001280932340a044563686f122c" . - "0a0450696e6712102e736572766963652e4d6573736167651a102e736572" . - "766963652e4d6573736167652200620670726f746f33" - )); - - static::$is_initialized = true; - } -} - diff --git a/tests/plugins/grpc/php_server/src/Service/EchoInterface.php b/tests/plugins/grpc/php_server/src/Service/EchoInterface.php deleted file mode 100644 index 5f336ace..00000000 --- a/tests/plugins/grpc/php_server/src/Service/EchoInterface.php +++ /dev/null @@ -1,22 +0,0 @@ -<?php -# Generated by the protocol buffer compiler (spiral/grpc). DO NOT EDIT! -# source: service.proto - -namespace Service; - -use Spiral\GRPC; - -interface EchoInterface extends GRPC\ServiceInterface -{ - // GRPC specific service name. - public const NAME = "service.Echo"; - - /** - * @param GRPC\ContextInterface $ctx - * @param Message $in - * @return Message - * - * @throws GRPC\Exception\InvokeException - */ - public function Ping(GRPC\ContextInterface $ctx, Message $in): Message; -} diff --git a/tests/plugins/grpc/php_server/src/Service/Message.php b/tests/plugins/grpc/php_server/src/Service/Message.php deleted file mode 100644 index 6c40c879..00000000 --- a/tests/plugins/grpc/php_server/src/Service/Message.php +++ /dev/null @@ -1,58 +0,0 @@ -<?php -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: service.proto - -namespace Service; - -use Google\Protobuf\Internal\GPBType; -use Google\Protobuf\Internal\RepeatedField; -use Google\Protobuf\Internal\GPBUtil; - -/** - * Generated from protobuf message <code>service.Message</code> - */ -class Message extends \Google\Protobuf\Internal\Message -{ - /** - * Generated from protobuf field <code>string msg = 1;</code> - */ - private $msg = ''; - - /** - * Constructor. - * - * @param array $data { - * Optional. Data for populating the Message object. - * - * @type string $msg - * } - */ - public function __construct($data = NULL) { - \GPBMetadata\Service::initOnce(); - parent::__construct($data); - } - - /** - * Generated from protobuf field <code>string msg = 1;</code> - * @return string - */ - public function getMsg() - { - return $this->msg; - } - - /** - * Generated from protobuf field <code>string msg = 1;</code> - * @param string $var - * @return $this - */ - public function setMsg($var) - { - GPBUtil::checkString($var, True); - $this->msg = $var; - - return $this; - } - -} - diff --git a/tests/plugins/grpc/php_server/worker-grpc.php b/tests/plugins/grpc/php_server/worker-grpc.php deleted file mode 100644 index 683a2341..00000000 --- a/tests/plugins/grpc/php_server/worker-grpc.php +++ /dev/null @@ -1,26 +0,0 @@ -<?php -/** - * Sample GRPC PHP server. - */ - -use Service\EchoInterface; -use Spiral\Goridge\StreamRelay; -use Spiral\GRPC\Server; -use Spiral\RoadRunner\Worker; - -require __DIR__ . '/vendor/autoload.php'; - -$server = new Server(null, [ - 'debug' => false, // optional (default: false) -]); - -$server->registerService(EchoInterface::class, new EchoService()); - -$worker = \method_exists(Worker::class, 'create') - // RoadRunner >= 2.x - ? Worker::create() - // RoadRunner 1.x - : new Worker(new StreamRelay(STDIN, STDOUT)) -; - -$server->serve($worker); diff --git a/tests/plugins/grpc/plugin_test.go b/tests/plugins/grpc/plugin_test.go deleted file mode 100644 index cfbe0121..00000000 --- a/tests/plugins/grpc/plugin_test.go +++ /dev/null @@ -1,178 +0,0 @@ -package grpc - -import ( - "io/ioutil" - "os" - "os/exec" - "strings" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func init() { - err := build() - if err != nil { - panic(err) - } -} - -func build() error { - cmd := exec.Command("go", "build", "-o", "plugin", "../../../plugins/grpc/protoc_plugins/protoc-gen-php-grpc") - return cmd.Run() -} - -func protoc(t *testing.T, args []string) { - cmd := exec.Command("protoc", "--plugin=protoc-gen-php-grpc=./plugin") - cmd.Args = append(cmd.Args, args...) - out, err := cmd.CombinedOutput() - - if len(out) > 0 || err != nil { - t.Log("RUNNING: ", strings.Join(cmd.Args, " ")) - } - - if len(out) > 0 { - t.Log(string(out)) - } - - if err != nil { - t.Fatalf("protoc: %v", err) - } -} - -func Test_Simple(t *testing.T) { - workdir, _ := os.Getwd() - tmpdir, err := ioutil.TempDir("", "proto-test") - require.NoError(t, err) - - defer func() { - assert.NoError(t, os.RemoveAll(tmpdir)) - }() - - args := []string{ - "-Itestdata", - "--php-grpc_out=" + tmpdir, - "simple/simple.proto", - } - - protoc(t, args) - - assertEqualFiles( - t, - workdir+"/testdata/simple/TestSimple/SimpleServiceInterface.php", - tmpdir+"/TestSimple/SimpleServiceInterface.php", - ) -} - -func Test_PhpNamespaceOption(t *testing.T) { - workdir, _ := os.Getwd() - tmpdir, err := ioutil.TempDir("", "proto-test") - require.NoError(t, err) - - defer func() { - assert.NoError(t, os.RemoveAll(tmpdir)) - }() - - args := []string{ - "-Itestdata", - "--php-grpc_out=" + tmpdir, - "php_namespace/service.proto", - } - protoc(t, args) - - assertEqualFiles( - t, - workdir+"/testdata/php_namespace/Test/CustomNamespace/ServiceInterface.php", - tmpdir+"/Test/CustomNamespace/ServiceInterface.php", - ) -} - -func Test_UseImportedMessage(t *testing.T) { - workdir, _ := os.Getwd() - tmpdir, err := ioutil.TempDir("", "proto-test") - require.NoError(t, err) - - defer func() { - assert.NoError(t, os.RemoveAll(tmpdir)) - }() - - args := []string{ - "-Itestdata", - "--php-grpc_out=" + tmpdir, - "import/service.proto", - } - protoc(t, args) - - assertEqualFiles( - t, - workdir+"/testdata/import/Import/ServiceInterface.php", - tmpdir+"/Import/ServiceInterface.php", - ) -} - -func Test_PhpNamespaceOptionInUse(t *testing.T) { - workdir, _ := os.Getwd() - tmpdir, err := ioutil.TempDir("", "proto-test") - require.NoError(t, err) - - defer func() { - assert.NoError(t, os.RemoveAll(tmpdir)) - }() - - args := []string{ - "-Itestdata", - "--php-grpc_out=" + tmpdir, - "import_custom/service.proto", - } - protoc(t, args) - - assertEqualFiles( - t, - workdir+"/testdata/import_custom/Test/CustomImport/ServiceInterface.php", - tmpdir+"/Test/CustomImport/ServiceInterface.php", - ) -} - -func Test_UseOfGoogleEmptyMessage(t *testing.T) { - workdir, _ := os.Getwd() - tmpdir, err := ioutil.TempDir("", "proto-test") - require.NoError(t, err) - - defer func() { - assert.NoError(t, os.RemoveAll(tmpdir)) - }() - - args := []string{ - "-Itestdata", - "--php-grpc_out=" + tmpdir, - "use_empty/service.proto", - } - protoc(t, args) - - assertEqualFiles( - t, - workdir+"/testdata/use_empty/Test/ServiceInterface.php", - tmpdir+"/Test/ServiceInterface.php", - ) - - assert.NoError(t, os.RemoveAll("plugin")) -} - -func assertEqualFiles(t *testing.T, original, generated string) { - assert.FileExists(t, generated) - - originalData, err := ioutil.ReadFile(original) - if err != nil { - t.Fatal("Can't find original file for comparison") - } - - generatedData, err := ioutil.ReadFile(generated) - if err != nil { - t.Fatal("Can't find generated file for comparison") - } - - // every OS has a special boy - r := strings.NewReplacer("\r\n", "", "\n", "") - assert.Equal(t, r.Replace(string(originalData)), r.Replace(string(generatedData))) -} diff --git a/tests/plugins/grpc/testdata/import/Import/ServiceInterface.php b/tests/plugins/grpc/testdata/import/Import/ServiceInterface.php deleted file mode 100644 index 13e58daf..00000000 --- a/tests/plugins/grpc/testdata/import/Import/ServiceInterface.php +++ /dev/null @@ -1,32 +0,0 @@ -<?php -# Generated by the protocol buffer compiler (spiral/php-grpc). DO NOT EDIT! -# source: import/service.proto - -namespace Import; - -use Spiral\GRPC; -use Import\Sub; - -interface ServiceInterface extends GRPC\ServiceInterface -{ - // GRPC specific service name. - public const NAME = "import.Service"; - - /** - * @param GRPC\ContextInterface $ctx - * @param Message $in - * @return Message - * - * @throws GRPC\Exception\InvokeException - */ - public function SimpleMethod(GRPC\ContextInterface $ctx, Message $in): Message; - - /** - * @param GRPC\ContextInterface $ctx - * @param Sub\Message $in - * @return Sub\Message - * - * @throws GRPC\Exception\InvokeException - */ - public function ImportMethod(GRPC\ContextInterface $ctx, Sub\Message $in): Sub\Message; -} diff --git a/tests/plugins/grpc/testdata/import/service.proto b/tests/plugins/grpc/testdata/import/service.proto deleted file mode 100644 index 5d888f09..00000000 --- a/tests/plugins/grpc/testdata/import/service.proto +++ /dev/null @@ -1,17 +0,0 @@ -syntax = "proto3"; - -package import; - -import "import/sub/message.proto"; - -service Service { - rpc SimpleMethod (Message) returns (Message) { - } - - rpc ImportMethod (import.sub.Message) returns (import.sub.Message) { - } -} - -message Message { - int64 id = 1; -}
\ No newline at end of file diff --git a/tests/plugins/grpc/testdata/import/sub/message.proto b/tests/plugins/grpc/testdata/import/sub/message.proto deleted file mode 100644 index 1db0313b..00000000 --- a/tests/plugins/grpc/testdata/import/sub/message.proto +++ /dev/null @@ -1,7 +0,0 @@ -syntax = "proto3"; - -package import.sub; - -message Message { - int64 id = 1; -}
\ No newline at end of file diff --git a/tests/plugins/grpc/testdata/import_custom/Test/CustomImport/ServiceInterface.php b/tests/plugins/grpc/testdata/import_custom/Test/CustomImport/ServiceInterface.php deleted file mode 100644 index b010ce4f..00000000 --- a/tests/plugins/grpc/testdata/import_custom/Test/CustomImport/ServiceInterface.php +++ /dev/null @@ -1,32 +0,0 @@ -<?php -# Generated by the protocol buffer compiler (spiral/php-grpc). DO NOT EDIT! -# source: import_custom/service.proto - -namespace Test\CustomImport; - -use Spiral\GRPC; -use Test\CustomImport\Message; - -interface ServiceInterface extends GRPC\ServiceInterface -{ - // GRPC specific service name. - public const NAME = "import.Service"; - - /** - * @param GRPC\ContextInterface $ctx - * @param Message $in - * @return Message - * - * @throws GRPC\Exception\InvokeException - */ - public function SimpleMethod(GRPC\ContextInterface $ctx, Message $in): Message; - - /** - * @param GRPC\ContextInterface $ctx - * @param Message\Message $in - * @return Message\Message - * - * @throws GRPC\Exception\InvokeException - */ - public function ImportMethod(GRPC\ContextInterface $ctx, Message\Message $in): Message\Message; -} diff --git a/tests/plugins/grpc/testdata/import_custom/service.proto b/tests/plugins/grpc/testdata/import_custom/service.proto deleted file mode 100644 index 872aaae3..00000000 --- a/tests/plugins/grpc/testdata/import_custom/service.proto +++ /dev/null @@ -1,19 +0,0 @@ -syntax = "proto3"; - -package import; - -option php_namespace = "Test\\CustomImport"; - -import "import_custom/sub/message.proto"; - -service Service { - rpc SimpleMethod (Message) returns (Message) { - } - - rpc ImportMethod (import.sub.Message) returns (import.sub.Message) { - } -} - -message Message { - int64 id = 1; -}
\ No newline at end of file diff --git a/tests/plugins/grpc/testdata/import_custom/sub/message.proto b/tests/plugins/grpc/testdata/import_custom/sub/message.proto deleted file mode 100644 index 5d722ca3..00000000 --- a/tests/plugins/grpc/testdata/import_custom/sub/message.proto +++ /dev/null @@ -1,14 +0,0 @@ -syntax = "proto3"; - -package import.sub; -option php_namespace = "Test\\CustomImport\\Message"; - - -service Service { - rpc AnotherMethod (Message) returns (Message) { - } -} - -message Message { - int64 id = 1; -}
\ No newline at end of file diff --git a/tests/plugins/grpc/testdata/php_namespace/Test/CustomNamespace/ServiceInterface.php b/tests/plugins/grpc/testdata/php_namespace/Test/CustomNamespace/ServiceInterface.php deleted file mode 100644 index 2090ba97..00000000 --- a/tests/plugins/grpc/testdata/php_namespace/Test/CustomNamespace/ServiceInterface.php +++ /dev/null @@ -1,22 +0,0 @@ -<?php -# Generated by the protocol buffer compiler (spiral/php-grpc). DO NOT EDIT! -# source: php_namespace/service.proto - -namespace Test\CustomNamespace; - -use Spiral\GRPC; - -interface ServiceInterface extends GRPC\ServiceInterface -{ - // GRPC specific service name. - public const NAME = "testPhpNamespace.Service"; - - /** - * @param GRPC\ContextInterface $ctx - * @param SimpleMessage $in - * @return SimpleMessage - * - * @throws GRPC\Exception\InvokeException - */ - public function SimpleMethod(GRPC\ContextInterface $ctx, SimpleMessage $in): SimpleMessage; -} diff --git a/tests/plugins/grpc/testdata/php_namespace/service.proto b/tests/plugins/grpc/testdata/php_namespace/service.proto deleted file mode 100644 index a3bfa3c0..00000000 --- a/tests/plugins/grpc/testdata/php_namespace/service.proto +++ /dev/null @@ -1,15 +0,0 @@ -syntax = "proto3"; - -package testPhpNamespace; - -option php_namespace = "Test\\CustomNamespace"; - -service Service { - rpc SimpleMethod (SimpleMessage) returns (SimpleMessage) { - } -} - -message SimpleMessage { - int32 id = 1; - string name = 2; -}
\ No newline at end of file diff --git a/tests/plugins/grpc/testdata/simple/TestSimple/SimpleServiceInterface.php b/tests/plugins/grpc/testdata/simple/TestSimple/SimpleServiceInterface.php deleted file mode 100644 index f9e84bf7..00000000 --- a/tests/plugins/grpc/testdata/simple/TestSimple/SimpleServiceInterface.php +++ /dev/null @@ -1,22 +0,0 @@ -<?php -# Generated by the protocol buffer compiler (spiral/php-grpc). DO NOT EDIT! -# source: simple/simple.proto - -namespace TestSimple; - -use Spiral\GRPC; - -interface SimpleServiceInterface extends GRPC\ServiceInterface -{ - // GRPC specific service name. - public const NAME = "testSimple.SimpleService"; - - /** - * @param GRPC\ContextInterface $ctx - * @param SimpleMessage $in - * @return SimpleMessage - * - * @throws GRPC\Exception\InvokeException - */ - public function SimpleMethod(GRPC\ContextInterface $ctx, SimpleMessage $in): SimpleMessage; -} diff --git a/tests/plugins/grpc/testdata/simple/simple.proto b/tests/plugins/grpc/testdata/simple/simple.proto deleted file mode 100644 index aca3c1d9..00000000 --- a/tests/plugins/grpc/testdata/simple/simple.proto +++ /dev/null @@ -1,13 +0,0 @@ -syntax = "proto3"; - -package testSimple; - -service SimpleService { - rpc SimpleMethod (SimpleMessage) returns (SimpleMessage) { - } -} - -message SimpleMessage { - int32 id = 1; - string name = 2; -}
\ No newline at end of file diff --git a/tests/plugins/grpc/testdata/use_empty/Test/ServiceInterface.php b/tests/plugins/grpc/testdata/use_empty/Test/ServiceInterface.php deleted file mode 100644 index fe6d345a..00000000 --- a/tests/plugins/grpc/testdata/use_empty/Test/ServiceInterface.php +++ /dev/null @@ -1,23 +0,0 @@ -<?php -# Generated by the protocol buffer compiler (spiral/php-grpc). DO NOT EDIT! -# source: use_empty/service.proto - -namespace Test; - -use Spiral\GRPC; -use Google\Protobuf; - -interface ServiceInterface extends GRPC\ServiceInterface -{ - // GRPC specific service name. - public const NAME = "test.Service"; - - /** - * @param GRPC\ContextInterface $ctx - * @param Protobuf\GPBEmpty $in - * @return Protobuf\GPBEmpty - * - * @throws GRPC\Exception\InvokeException - */ - public function Test(GRPC\ContextInterface $ctx, Protobuf\GPBEmpty $in): Protobuf\GPBEmpty; -} diff --git a/tests/plugins/grpc/testdata/use_empty/service.proto b/tests/plugins/grpc/testdata/use_empty/service.proto deleted file mode 100644 index 8c68d8d3..00000000 --- a/tests/plugins/grpc/testdata/use_empty/service.proto +++ /dev/null @@ -1,10 +0,0 @@ -syntax = "proto3"; - -package test; - -import "google/protobuf/empty.proto"; - -service Service { - rpc Test (google.protobuf.Empty) returns (google.protobuf.Empty) { - } -}
\ No newline at end of file diff --git a/tests/plugins/gzip/configs/.rr-http-middlewareNotExist.yaml b/tests/plugins/gzip/configs/.rr-http-middlewareNotExist.yaml deleted file mode 100644 index 73e4f6e6..00000000 --- a/tests/plugins/gzip/configs/.rr-http-middlewareNotExist.yaml +++ /dev/null @@ -1,20 +0,0 @@ -server: - command: "php ../../psr-worker.php" - relay: "pipes" - relay_timeout: "20s" - -http: - address: 127.0.0.1:18103 - max_request_size: 1024 - middleware: [ "gzip", "foo" ] - uploads: - forbid: [ ".php", ".exe", ".bat" ] - trusted_subnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] - pool: - num_workers: 2 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s -logs: - mode: development - level: error diff --git a/tests/plugins/gzip/configs/.rr-http-withGzip.yaml b/tests/plugins/gzip/configs/.rr-http-withGzip.yaml deleted file mode 100644 index c67e207b..00000000 --- a/tests/plugins/gzip/configs/.rr-http-withGzip.yaml +++ /dev/null @@ -1,22 +0,0 @@ -server: - command: "php ../../psr-worker.php" - user: "" - group: "" - relay: "pipes" - relay_timeout: "20s" - -http: - address: 127.0.0.1:18953 - max_request_size: 1024 - middleware: [ "gzip" ] - uploads: - forbid: [ ".php", ".exe", ".bat" ] - trusted_subnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] - pool: - num_workers: 2 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s -logs: - mode: development - level: error
\ No newline at end of file diff --git a/tests/plugins/gzip/plugin_test.go b/tests/plugins/gzip/plugin_test.go deleted file mode 100644 index 1c6ab887..00000000 --- a/tests/plugins/gzip/plugin_test.go +++ /dev/null @@ -1,180 +0,0 @@ -package gzip - -import ( - "net/http" - "os" - "os/signal" - "sync" - "syscall" - "testing" - "time" - - "github.com/golang/mock/gomock" - endure "github.com/spiral/endure/pkg/container" - "github.com/spiral/roadrunner/v2/plugins/config" - "github.com/spiral/roadrunner/v2/plugins/gzip" - httpPlugin "github.com/spiral/roadrunner/v2/plugins/http" - "github.com/spiral/roadrunner/v2/plugins/logger" - "github.com/spiral/roadrunner/v2/plugins/server" - "github.com/spiral/roadrunner/v2/tests/mocks" - "github.com/stretchr/testify/assert" -) - -func TestGzipPlugin(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-http-withGzip.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &logger.ZapLogger{}, - &server.Plugin{}, - &httpPlugin.Plugin{}, - &gzip.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 2) - t.Run("GzipCheckHeader", headerCheck) - - stopCh <- struct{}{} - wg.Wait() -} - -func headerCheck(t *testing.T) { - req, err := http.NewRequest("GET", "http://127.0.0.1:18953", nil) - assert.NoError(t, err) - client := &http.Client{ - Transport: &http.Transport{ - DisableCompression: false, - }, - } - - r, err := client.Do(req) - assert.NoError(t, err) - assert.True(t, r.Uncompressed) - - err = r.Body.Close() - assert.NoError(t, err) -} - -func TestMiddlewareNotExist(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-http-middlewareNotExist.yaml", - Prefix: "rr", - } - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - - mockLogger.EXPECT().Warn("requested middleware does not exist", "requested", "foo").MinTimes(1) - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("worker destructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Error(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() // placeholder for the workerlogerror - - err = cont.RegisterAll( - cfg, - mockLogger, - &server.Plugin{}, - &httpPlugin.Plugin{}, - &gzip.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second) - stopCh <- struct{}{} - wg.Wait() -} diff --git a/tests/plugins/headers/configs/.rr-cors-headers.yaml b/tests/plugins/headers/configs/.rr-cors-headers.yaml deleted file mode 100644 index b4e960f1..00000000 --- a/tests/plugins/headers/configs/.rr-cors-headers.yaml +++ /dev/null @@ -1,34 +0,0 @@ -server: - command: "php ../../http/client.php headers pipes" - relay: "pipes" - relay_timeout: "20s" - -http: - address: 127.0.0.1:22855 - max_request_size: 1024 - middleware: [ "headers" ] - uploads: - forbid: [ ".php", ".exe", ".bat" ] - trusted_subnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] - # Additional HTTP headers and CORS control. - headers: - cors: - allowed_origin: "*" - allowed_headers: "*" - allowed_methods: "GET,POST,PUT,DELETE" - allow_credentials: true - exposed_headers: "Cache-Control,Content-Language,Content-Type,Expires,Last-Modified,Pragma" - max_age: 600 - request: - input: "custom-header" - response: - output: "output-header" - pool: - num_workers: 2 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s -logs: - mode: development - level: error - diff --git a/tests/plugins/headers/configs/.rr-headers-init.yaml b/tests/plugins/headers/configs/.rr-headers-init.yaml deleted file mode 100644 index b2781f2b..00000000 --- a/tests/plugins/headers/configs/.rr-headers-init.yaml +++ /dev/null @@ -1,38 +0,0 @@ -server: - command: "php ../../http/client.php echo pipes" - user: "" - group: "" - env: - "RR_HTTP": "true" - relay: "pipes" - relay_timeout: "20s" - -http: - address: 127.0.0.1:33453 - max_request_size: 1024 - middleware: [ "headers" ] - uploads: - forbid: [ ".php", ".exe", ".bat" ] - trusted_subnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] - # Additional HTTP headers and CORS control. - headers: - cors: - allowed_origin: "*" - allowed_headers: "*" - allowed_methods: "GET,POST,PUT,DELETE" - allow_credentials: true - exposed_headers: "Cache-Control,Content-Language,Content-Type,Expires,Last-Modified,Pragma" - max_age: 600 - request: - Example-Request-Header: "Value" - response: - X-Powered-By: "RoadRunner" - pool: - num_workers: 2 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s -logs: - mode: development - level: error - diff --git a/tests/plugins/headers/configs/.rr-req-headers.yaml b/tests/plugins/headers/configs/.rr-req-headers.yaml deleted file mode 100644 index a2b97171..00000000 --- a/tests/plugins/headers/configs/.rr-req-headers.yaml +++ /dev/null @@ -1,31 +0,0 @@ -server: - command: "php ../../http/client.php header pipes" - user: "" - group: "" - env: - "RR_HTTP": "true" - relay: "pipes" - relay_timeout: "20s" - -http: - address: 127.0.0.1:22655 - max_request_size: 1024 - middleware: [ "headers" ] - uploads: - forbid: [ ".php", ".exe", ".bat" ] - trusted_subnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] - # Additional HTTP headers and CORS control. - headers: - request: - input: "custom-header" - response: - output: "output-header" - pool: - num_workers: 2 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s -logs: - mode: development - level: error - diff --git a/tests/plugins/headers/configs/.rr-res-headers.yaml b/tests/plugins/headers/configs/.rr-res-headers.yaml deleted file mode 100644 index 4448343c..00000000 --- a/tests/plugins/headers/configs/.rr-res-headers.yaml +++ /dev/null @@ -1,31 +0,0 @@ -server: - command: "php ../../http/client.php header pipes" - user: "" - group: "" - env: - "RR_HTTP": "true" - relay: "pipes" - relay_timeout: "20s" - -http: - address: 127.0.0.1:22455 - max_request_size: 1024 - middleware: [ "headers" ] - uploads: - forbid: [ ".php", ".exe", ".bat" ] - trusted_subnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] - # Additional HTTP headers and CORS control. - headers: - request: - input: "custom-header" - response: - output: "output-header" - pool: - num_workers: 2 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s -logs: - mode: development - level: error - diff --git a/tests/plugins/headers/headers_plugin_test.go b/tests/plugins/headers/headers_plugin_test.go deleted file mode 100644 index a03a3c34..00000000 --- a/tests/plugins/headers/headers_plugin_test.go +++ /dev/null @@ -1,368 +0,0 @@ -package headers - -import ( - "io/ioutil" - "net/http" - "os" - "os/signal" - "sync" - "syscall" - "testing" - "time" - - endure "github.com/spiral/endure/pkg/container" - "github.com/spiral/roadrunner/v2/plugins/config" - "github.com/spiral/roadrunner/v2/plugins/headers" - httpPlugin "github.com/spiral/roadrunner/v2/plugins/http" - "github.com/spiral/roadrunner/v2/plugins/logger" - "github.com/spiral/roadrunner/v2/plugins/server" - "github.com/stretchr/testify/assert" -) - -func TestHeadersInit(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-headers-init.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &logger.ZapLogger{}, - &server.Plugin{}, - &httpPlugin.Plugin{}, - &headers.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second) - stopCh <- struct{}{} - wg.Wait() -} - -func TestRequestHeaders(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-req-headers.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &logger.ZapLogger{}, - &server.Plugin{}, - &httpPlugin.Plugin{}, - &headers.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second) - t.Run("RequestHeaders", reqHeaders) - - stopCh <- struct{}{} - wg.Wait() -} - -func reqHeaders(t *testing.T) { - req, err := http.NewRequest("GET", "http://127.0.0.1:22655?hello=value", nil) - assert.NoError(t, err) - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - - b, err := ioutil.ReadAll(r.Body) - assert.NoError(t, err) - - assert.Equal(t, 200, r.StatusCode) - assert.Equal(t, "CUSTOM-HEADER", string(b)) - - err = r.Body.Close() - assert.NoError(t, err) -} - -func TestResponseHeaders(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-res-headers.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &logger.ZapLogger{}, - &server.Plugin{}, - &httpPlugin.Plugin{}, - &headers.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second) - t.Run("ResponseHeaders", resHeaders) - - stopCh <- struct{}{} - wg.Wait() -} - -func resHeaders(t *testing.T) { - req, err := http.NewRequest("GET", "http://127.0.0.1:22455?hello=value", nil) - assert.NoError(t, err) - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - - assert.Equal(t, "output-header", r.Header.Get("output")) - - b, err := ioutil.ReadAll(r.Body) - assert.NoError(t, err) - assert.Equal(t, 200, r.StatusCode) - assert.Equal(t, "CUSTOM-HEADER", string(b)) - - err = r.Body.Close() - assert.NoError(t, err) -} - -func TestCORSHeaders(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-cors-headers.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &logger.ZapLogger{}, - &server.Plugin{}, - &httpPlugin.Plugin{}, - &headers.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second) - t.Run("CORSHeaders", corsHeaders) - t.Run("CORSHeadersPass", corsHeadersPass) - - stopCh <- struct{}{} - wg.Wait() -} - -func corsHeadersPass(t *testing.T) { - req, err := http.NewRequest("GET", "http://127.0.0.1:22855", nil) - assert.NoError(t, err) - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - - assert.Equal(t, "true", r.Header.Get("Access-Control-Allow-Credentials")) - assert.Equal(t, "*", r.Header.Get("Access-Control-Allow-Headers")) - assert.Equal(t, "*", r.Header.Get("Access-Control-Allow-Origin")) - assert.Equal(t, "true", r.Header.Get("Access-Control-Allow-Credentials")) - - _, err = ioutil.ReadAll(r.Body) - assert.NoError(t, err) - assert.Equal(t, 200, r.StatusCode) - - err = r.Body.Close() - assert.NoError(t, err) -} - -func corsHeaders(t *testing.T) { - req, err := http.NewRequest("OPTIONS", "http://127.0.0.1:22855", nil) - assert.NoError(t, err) - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - - assert.Equal(t, "true", r.Header.Get("Access-Control-Allow-Credentials")) - assert.Equal(t, "*", r.Header.Get("Access-Control-Allow-Headers")) - assert.Equal(t, "GET,POST,PUT,DELETE", r.Header.Get("Access-Control-Allow-Methods")) - assert.Equal(t, "*", r.Header.Get("Access-Control-Allow-Origin")) - assert.Equal(t, "600", r.Header.Get("Access-Control-Max-Age")) - assert.Equal(t, "true", r.Header.Get("Access-Control-Allow-Credentials")) - - _, err = ioutil.ReadAll(r.Body) - assert.NoError(t, err) - assert.Equal(t, 200, r.StatusCode) - - err = r.Body.Close() - assert.NoError(t, err) -} diff --git a/tests/plugins/http/attributes_test.go b/tests/plugins/http/attributes_test.go deleted file mode 100644 index 69200a30..00000000 --- a/tests/plugins/http/attributes_test.go +++ /dev/null @@ -1,78 +0,0 @@ -package http - -import ( - "net/http" - "testing" - - "github.com/spiral/roadrunner/v2/plugins/http/attributes" - "github.com/stretchr/testify/assert" -) - -func TestAllAttributes(t *testing.T) { - r := &http.Request{} - r = attributes.Init(r) - - err := attributes.Set(r, "key", "value") - if err != nil { - t.Errorf("error during the Set: error %v", err) - } - - assert.Equal(t, attributes.All(r), map[string]interface{}{ - "key": "value", - }) -} - -func TestAllAttributesNone(t *testing.T) { - r := &http.Request{} - r = attributes.Init(r) - - assert.Equal(t, attributes.All(r), map[string]interface{}{}) -} - -func TestAllAttributesNone2(t *testing.T) { - r := &http.Request{} - - assert.Equal(t, attributes.All(r), map[string]interface{}{}) -} - -func TestGetAttribute(t *testing.T) { - r := &http.Request{} - r = attributes.Init(r) - - err := attributes.Set(r, "key", "value") - if err != nil { - t.Errorf("error during the Set: error %v", err) - } - assert.Equal(t, attributes.Get(r, "key"), "value") -} - -func TestGetAttributeNone(t *testing.T) { - r := &http.Request{} - r = attributes.Init(r) - - assert.Equal(t, attributes.Get(r, "key"), nil) -} - -func TestGetAttributeNone2(t *testing.T) { - r := &http.Request{} - - assert.Equal(t, attributes.Get(r, "key"), nil) -} - -func TestSetAttribute(t *testing.T) { - r := &http.Request{} - r = attributes.Init(r) - - err := attributes.Set(r, "key", "value") - if err != nil { - t.Errorf("error during the Set: error %v", err) - } - assert.Equal(t, attributes.Get(r, "key"), "value") -} - -func TestSetAttributeNone(t *testing.T) { - r := &http.Request{} - err := attributes.Set(r, "key", "value") - assert.Error(t, err) - assert.Equal(t, attributes.Get(r, "key"), nil) -} diff --git a/tests/plugins/http/configs/.rr-big-req-size.yaml b/tests/plugins/http/configs/.rr-big-req-size.yaml deleted file mode 100644 index 574b3393..00000000 --- a/tests/plugins/http/configs/.rr-big-req-size.yaml +++ /dev/null @@ -1,21 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../http/client.php echo pipes" - -http: - address: 127.0.0.1:10085 - max_request_size: 1 - middleware: [ "" ] - uploads: - forbid: [ ".php", ".exe", ".bat" ] - trusted_subnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] - pool: - num_workers: 2 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s -logs: - mode: development - level: error
\ No newline at end of file diff --git a/tests/plugins/http/configs/.rr-broken-pipes.yaml b/tests/plugins/http/configs/.rr-broken-pipes.yaml deleted file mode 100644 index 703f9431..00000000 --- a/tests/plugins/http/configs/.rr-broken-pipes.yaml +++ /dev/null @@ -1,29 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../http/client.php broken pipes" - user: "" - group: "" - env: - "RR_HTTP": "true" - relay: "pipes" - relay_timeout: "20s" - -http: - address: 127.0.0.1:12384 - max_request_size: 1024 - middleware: [ "" ] - uploads: - forbid: [ ".php", ".exe", ".bat" ] - trusted_subnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] - pool: - num_workers: 2 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s -logs: - mode: development - level: error - - diff --git a/tests/plugins/http/configs/.rr-env.yaml b/tests/plugins/http/configs/.rr-env.yaml deleted file mode 100644 index 4ea8ec73..00000000 --- a/tests/plugins/http/configs/.rr-env.yaml +++ /dev/null @@ -1,27 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../http/client.php env pipes" - relay: "pipes" - relay_timeout: "20s" - -http: - address: 127.0.0.1:12084 - max_request_size: 1024 - middleware: [] - env: - "RR_HTTP": "true" - "env_key": "ENV_VALUE" - uploads: - forbid: [ ".php", ".exe", ".bat" ] - trusted_subnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] - pool: - num_workers: 2 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s -logs: - mode: development - level: error - diff --git a/tests/plugins/http/configs/.rr-fcgi-reqUri.yaml b/tests/plugins/http/configs/.rr-fcgi-reqUri.yaml deleted file mode 100644 index cbdd211e..00000000 --- a/tests/plugins/http/configs/.rr-fcgi-reqUri.yaml +++ /dev/null @@ -1,32 +0,0 @@ -server: - command: "php ../../http/client.php request-uri pipes" - relay: "pipes" - relay_timeout: "20s" - -http: - address: :8082 - max_request_size: 1024 - middleware: [ ] - uploads: - forbid: [ ".php", ".exe", ".bat" ] - trusted_subnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] - pool: - num_workers: 1 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s - - ssl: - address: :8890 - redirect: false - cert: fixtures/server.crt - key: fixtures/server.key - # root_ca: root.crt - fcgi: - address: tcp://127.0.0.1:6921 - http2: - h2c: false - maxConcurrentStreams: 128 -logs: - mode: development - level: error diff --git a/tests/plugins/http/configs/.rr-fcgi.yaml b/tests/plugins/http/configs/.rr-fcgi.yaml deleted file mode 100644 index b0060d85..00000000 --- a/tests/plugins/http/configs/.rr-fcgi.yaml +++ /dev/null @@ -1,30 +0,0 @@ -server: - command: "php ../../http/client.php echo pipes" - relay: "pipes" - relay_timeout: "20s" - -http: - address: :8081 - max_request_size: 1024 - middleware: [ "gzip" ] - static: - dir: "../../../tests" - forbid: [ "" ] - allow: [ ".txt", ".php" ] - uploads: - forbid: [ ".php", ".exe", ".bat" ] - trusted_subnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] - pool: - num_workers: 1 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s - - fcgi: - address: tcp://0.0.0.0:6920 - http2: - h2c: false - maxConcurrentStreams: 128 -logs: - mode: development - level: error diff --git a/tests/plugins/http/configs/.rr-h2c.yaml b/tests/plugins/http/configs/.rr-h2c.yaml deleted file mode 100644 index 796ad307..00000000 --- a/tests/plugins/http/configs/.rr-h2c.yaml +++ /dev/null @@ -1,28 +0,0 @@ -server: - command: "php ../../http/client.php echo pipes" - user: "" - group: "" - env: - "RR_HTTP": "true" - relay: "pipes" - relay_timeout: "20s" - -http: - address: :8083 - max_request_size: 1024 - middleware: [ "" ] - uploads: - forbid: [ ".php", ".exe", ".bat" ] - trusted_subnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] - pool: - num_workers: 1 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s - http2: - h2c: true - maxConcurrentStreams: 128 -logs: - mode: production - level: info - encoding: console
\ No newline at end of file diff --git a/tests/plugins/http/configs/.rr-http-ipv6-2.yaml b/tests/plugins/http/configs/.rr-http-ipv6-2.yaml deleted file mode 100644 index 233a22b4..00000000 --- a/tests/plugins/http/configs/.rr-http-ipv6-2.yaml +++ /dev/null @@ -1,24 +0,0 @@ -rpc: - listen: tcp://[::1]:6001 - -server: - command: "php ../../http/client.php echo pipes" - relay: "pipes" - relay_timeout: "20s" - -http: - address: "[::1]:10784" - max_request_size: 1024 - middleware: [] - uploads: - forbid: [ ".php", ".exe", ".bat" ] - trusted_subnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] - pool: - num_workers: 2 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s -logs: - mode: development - level: error - diff --git a/tests/plugins/http/configs/.rr-http-ipv6.yaml b/tests/plugins/http/configs/.rr-http-ipv6.yaml deleted file mode 100644 index cb768159..00000000 --- a/tests/plugins/http/configs/.rr-http-ipv6.yaml +++ /dev/null @@ -1,24 +0,0 @@ -rpc: - listen: tcp://[0:0:0:0:0:0:0:1]:6001 - -server: - command: "php ../../http/client.php echo pipes" - relay: "pipes" - relay_timeout: "20s" - -http: - address: "[0:0:0:0:0:0:0:1]:10684" - max_request_size: 1024 - middleware: [] - uploads: - forbid: [ ".php", ".exe", ".bat" ] - trusted_subnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] - pool: - num_workers: 2 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s -logs: - mode: development - level: debug - diff --git a/tests/plugins/http/configs/.rr-http-static-disabled.yaml b/tests/plugins/http/configs/.rr-http-static-disabled.yaml deleted file mode 100644 index d248ce48..00000000 --- a/tests/plugins/http/configs/.rr-http-static-disabled.yaml +++ /dev/null @@ -1,27 +0,0 @@ -server: - command: "php ../../http/client.php pid pipes" - user: "" - group: "" - env: - "RR_HTTP": "true" - relay: "pipes" - relay_timeout: "20s" - -http: - address: 127.0.0.1:21234 - max_request_size: 1024 - middleware: [ "gzip" ] - trusted_subnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] - uploads: - forbid: [ ".php", ".exe", ".bat" ] - static: - dir: "abc" #not exists - forbid: [ ".php", ".htaccess" ] - pool: - num_workers: 2 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s -logs: - mode: development - level: error diff --git a/tests/plugins/http/configs/.rr-http-static-etags.yaml b/tests/plugins/http/configs/.rr-http-static-etags.yaml deleted file mode 100644 index b09de0f4..00000000 --- a/tests/plugins/http/configs/.rr-http-static-etags.yaml +++ /dev/null @@ -1,34 +0,0 @@ -server: - command: "php ../../http/client.php pid pipes" - user: "" - group: "" - env: - "RR_HTTP": "true" - relay: "pipes" - relay_timeout: "20s" - -http: - address: 127.0.0.1:21603 - max_request_size: 1024 - middleware: [ "gzip" ] - trusted_subnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] - uploads: - forbid: [ ".php", ".exe", ".bat" ] - static: - dir: "../../../tests" - forbid: [ "" ] - allow: [ ".txt", ".php" ] - calculate_etag: true - weak: true - request: - "input": "custom-header" - response: - "output": "output-header" - pool: - num_workers: 2 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s -logs: - mode: development - level: error diff --git a/tests/plugins/http/configs/.rr-http-static-files-disable.yaml b/tests/plugins/http/configs/.rr-http-static-files-disable.yaml deleted file mode 100644 index 9f91d75b..00000000 --- a/tests/plugins/http/configs/.rr-http-static-files-disable.yaml +++ /dev/null @@ -1,24 +0,0 @@ -server: - command: "php ../../http/client.php echo pipes" - user: "" - group: "" - env: - "RR_HTTP": "true" - relay: "pipes" - relay_timeout: "20s" - -http: - address: 127.0.0.1:45877 - max_request_size: 1024 - middleware: [ "gzip" ] - trusted_subnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] - uploads: - forbid: [ ".php", ".exe", ".bat" ] - pool: - num_workers: 2 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s -logs: - mode: development - level: error diff --git a/tests/plugins/http/configs/.rr-http-static-files.yaml b/tests/plugins/http/configs/.rr-http-static-files.yaml deleted file mode 100644 index 18c6107d..00000000 --- a/tests/plugins/http/configs/.rr-http-static-files.yaml +++ /dev/null @@ -1,30 +0,0 @@ -server: - command: "php ../../http/client.php echo pipes" - user: "" - group: "" - env: - "RR_HTTP": "true" - relay: "pipes" - relay_timeout: "20s" - -http: - address: 127.0.0.1:34653 - max_request_size: 1024 - middleware: [ "gzip" ] - trusted_subnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] - uploads: - forbid: [ ".php", ".exe", ".bat" ] - static: - dir: "../../../tests" - allow: [ ".ico" ] - forbid: [ ".php", ".htaccess" ] - - pool: - num_workers: 2 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s - -logs: - mode: development - level: info diff --git a/tests/plugins/http/configs/.rr-http-static-security.yaml b/tests/plugins/http/configs/.rr-http-static-security.yaml deleted file mode 100644 index e2e3af2a..00000000 --- a/tests/plugins/http/configs/.rr-http-static-security.yaml +++ /dev/null @@ -1,34 +0,0 @@ -server: - command: "php ../../http/client.php pid pipes" - user: "" - group: "" - env: - "RR_HTTP": "true" - relay: "pipes" - relay_timeout: "20s" - -http: - address: 127.0.0.1:21603 - max_request_size: 1024 - middleware: [ "gzip" ] - trusted_subnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] - uploads: - forbid: [ ".php", ".exe", ".bat" ] - static: - dir: "../../../tests" - forbid: [ "" ] - allow: [ ".txt", ".php" ] - calculate_etag: true - weak: false - request: - "input": "custom-header" - response: - "output": "output-header" - pool: - num_workers: 2 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s -logs: - mode: development - level: error diff --git a/tests/plugins/http/configs/.rr-http-static.yaml b/tests/plugins/http/configs/.rr-http-static.yaml deleted file mode 100644 index 30bb5b1e..00000000 --- a/tests/plugins/http/configs/.rr-http-static.yaml +++ /dev/null @@ -1,30 +0,0 @@ -server: - command: "php ../../http/client.php pid pipes" - relay: "pipes" - relay_timeout: "20s" - -http: - address: 127.0.0.1:21603 - max_request_size: 1024 - middleware: [ "gzip" ] - trusted_subnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] - uploads: - forbid: [ ".php", ".exe", ".bat" ] - static: - dir: "../../../tests" - forbid: [ "" ] - allow: [ ".txt", ".php" ] - calculate_etag: true - weak: false - request: - "input": "custom-header" - response: - "output": "output-header" - pool: - num_workers: 2 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s -logs: - mode: development - level: error diff --git a/tests/plugins/http/configs/.rr-http-supervised-pool.yaml b/tests/plugins/http/configs/.rr-http-supervised-pool.yaml deleted file mode 100644 index 8d4d81d9..00000000 --- a/tests/plugins/http/configs/.rr-http-supervised-pool.yaml +++ /dev/null @@ -1,28 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:15432 -server: - command: "php ../../http/client.php echo pipes" - relay: "pipes" - relay_timeout: "20s" - -http: - address: 127.0.0.1:18888 - max_request_size: 1024 - middleware: [] - uploads: - forbid: [ ".php", ".exe", ".bat" ] - trusted_subnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] - pool: - num_workers: 1 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s - supervisor: - watch_tick: 1s - ttl: 0 - idle_ttl: 1s - exec_ttl: 10s - max_worker_memory: 100 -logs: - mode: development - level: error diff --git a/tests/plugins/http/configs/.rr-http.yaml b/tests/plugins/http/configs/.rr-http.yaml deleted file mode 100644 index b4910160..00000000 --- a/tests/plugins/http/configs/.rr-http.yaml +++ /dev/null @@ -1,25 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../http/client.php echo pipes" - relay: "pipes" - relay_timeout: "20s" - -http: - address: 127.0.0.1:18903 - max_request_size: 1024 - middleware: [ "pluginMiddleware", "pluginMiddleware2" ] - uploads: - forbid: [ ".php", ".exe", ".bat" ] - trusted_subnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] - pool: - num_workers: 2 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s -logs: - mode: development - level: error - - diff --git a/tests/plugins/http/configs/.rr-init.yaml b/tests/plugins/http/configs/.rr-init.yaml deleted file mode 100644 index 02cb1636..00000000 --- a/tests/plugins/http/configs/.rr-init.yaml +++ /dev/null @@ -1,36 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../http/client.php echo pipes" - relay: "pipes" - relay_timeout: "20s" - -http: - address: 127.0.0.1:15395 - max_request_size: 1024 - middleware: [ ] - uploads: - forbid: [ ".php", ".exe", ".bat" ] - trusted_subnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] - pool: - num_workers: 2 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s - - ssl: - address: :8892 - redirect: false - cert: fixtures/server.crt - key: fixtures/server.key - # root_ca: root.crt - fcgi: - address: tcp://0.0.0.0:7921 - http2: - h2c: false - maxConcurrentStreams: 128 -logs: - mode: development - level: error - diff --git a/tests/plugins/http/configs/.rr-issue659.yaml b/tests/plugins/http/configs/.rr-issue659.yaml deleted file mode 100644 index bf192fab..00000000 --- a/tests/plugins/http/configs/.rr-issue659.yaml +++ /dev/null @@ -1,23 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../issue659.php" - relay: "pipes" - relay_timeout: "20s" - -http: - address: 127.0.0.1:32552 - max_request_size: 1024 - internal_error_code: 444 - middleware: [ ] - uploads: - forbid: [ ".php", ".exe", ".bat" ] - trusted_subnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] - pool: - num_workers: 1 - -logs: - mode: development - level: debug - diff --git a/tests/plugins/http/configs/.rr-no-http.yaml b/tests/plugins/http/configs/.rr-no-http.yaml deleted file mode 100644 index a6747b5d..00000000 --- a/tests/plugins/http/configs/.rr-no-http.yaml +++ /dev/null @@ -1,16 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../http/client.php echo pipes" - user: "" - group: "" - env: - "RR_HTTP": "true" - relay: "pipes" - relay_timeout: "20s" - -logs: - mode: development - level: error - diff --git a/tests/plugins/http/configs/.rr-resetter.yaml b/tests/plugins/http/configs/.rr-resetter.yaml deleted file mode 100644 index 61b0e501..00000000 --- a/tests/plugins/http/configs/.rr-resetter.yaml +++ /dev/null @@ -1,28 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../http/client.php echo pipes" - user: "" - group: "" - env: - "RR_HTTP": "true" - relay: "pipes" - relay_timeout: "20s" - -http: - address: 127.0.0.1:10084 - max_request_size: 1024 - middleware: [ "" ] - uploads: - forbid: [ ".php", ".exe", ".bat" ] - trusted_subnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] - pool: - num_workers: 2 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s -logs: - mode: development - level: error - diff --git a/tests/plugins/http/configs/.rr-ssl-push.yaml b/tests/plugins/http/configs/.rr-ssl-push.yaml deleted file mode 100644 index 3349575e..00000000 --- a/tests/plugins/http/configs/.rr-ssl-push.yaml +++ /dev/null @@ -1,30 +0,0 @@ -server: - command: "php ../../http/client.php push pipes" - user: "" - group: "" - env: - "RR_HTTP": "true" - relay: "pipes" - relay_timeout: "20s" - -http: - address: :8086 - max_request_size: 1024 - middleware: [ "" ] - uploads: - forbid: [ ".php", ".exe", ".bat" ] - trusted_subnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] - pool: - num_workers: 1 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s - - ssl: - address: :8894 - redirect: true - cert: fixtures/server.crt - key: fixtures/server.key -logs: - mode: development - level: error
\ No newline at end of file diff --git a/tests/plugins/http/configs/.rr-ssl-redirect.yaml b/tests/plugins/http/configs/.rr-ssl-redirect.yaml deleted file mode 100644 index 1d04963e..00000000 --- a/tests/plugins/http/configs/.rr-ssl-redirect.yaml +++ /dev/null @@ -1,30 +0,0 @@ -server: - command: "php ../../http/client.php echo pipes" - user: "" - group: "" - env: - "RR_HTTP": "true" - relay: "pipes" - relay_timeout: "20s" - -http: - address: :8087 - max_request_size: 1024 - middleware: [ "" ] - uploads: - forbid: [ ".php", ".exe", ".bat" ] - trusted_subnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] - pool: - num_workers: 1 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s - - ssl: - address: :8895 - redirect: true - cert: fixtures/server.crt - key: fixtures/server.key -logs: - mode: development - level: error
\ No newline at end of file diff --git a/tests/plugins/http/configs/.rr-ssl.yaml b/tests/plugins/http/configs/.rr-ssl.yaml deleted file mode 100644 index 8a0f16b8..00000000 --- a/tests/plugins/http/configs/.rr-ssl.yaml +++ /dev/null @@ -1,32 +0,0 @@ -server: - command: "php ../../http/client.php echo pipes" - user: "" - group: "" - env: - "RR_HTTP": "true" - relay: "pipes" - relay_timeout: "20s" - -http: - address: :8085 - max_request_size: 1024 - middleware: [ "" ] - uploads: - forbid: [ ".php", ".exe", ".bat" ] - trusted_subnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] - pool: - num_workers: 1 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s - - ssl: - address: :8893 - redirect: false - cert: fixtures/server.crt - key: fixtures/server.key - fcgi: - address: tcp://0.0.0.0:16920 -logs: - mode: development - level: error
\ No newline at end of file diff --git a/tests/plugins/http/fixtures/server.crt b/tests/plugins/http/fixtures/server.crt deleted file mode 100644 index 24d67fd7..00000000 --- a/tests/plugins/http/fixtures/server.crt +++ /dev/null @@ -1,15 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICTTCCAdOgAwIBAgIJAOKyUd+llTRKMAoGCCqGSM49BAMCMGMxCzAJBgNVBAYT -AlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNpc2Nv -MRMwEQYDVQQKDApSb2FkUnVubmVyMRIwEAYDVQQDDAlsb2NhbGhvc3QwHhcNMTgw -OTMwMTMzNDUzWhcNMjgwOTI3MTMzNDUzWjBjMQswCQYDVQQGEwJVUzETMBEGA1UE -CAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzETMBEGA1UECgwK -Um9hZFJ1bm5lcjESMBAGA1UEAwwJbG9jYWxob3N0MHYwEAYHKoZIzj0CAQYFK4EE -ACIDYgAEVnbShsM+l5RR3wfWWmGhzuFGwNzKCk7i9xyobDIyBUxG/UUSfj7KKlUX -puDnDEtF5xXcepl744CyIAYFLOXHb5WqI4jCOzG0o9f/00QQ4bQudJOdbqV910QF -C2vb7Fxro1MwUTAdBgNVHQ4EFgQU9xUexnbB6ORKayA7Pfjzs33otsAwHwYDVR0j -BBgwFoAU9xUexnbB6ORKayA7Pfjzs33otsAwDwYDVR0TAQH/BAUwAwEB/zAKBggq -hkjOPQQDAgNoADBlAjEAue3HhR/MUhxoa9tSDBtOJT3FYbDQswrsdqBTz97CGKst -e7XeZ3HMEvEXy0hGGEMhAjAqcD/4k9vViVppgWFtkk6+NFbm+Kw/QeeAiH5FgFSj -8xQcb+b7nPwNLp3JOkXkVd4= ------END CERTIFICATE----- diff --git a/tests/plugins/http/fixtures/server.key b/tests/plugins/http/fixtures/server.key deleted file mode 100644 index 7501dd46..00000000 --- a/tests/plugins/http/fixtures/server.key +++ /dev/null @@ -1,9 +0,0 @@ ------BEGIN EC PARAMETERS----- -BgUrgQQAIg== ------END EC PARAMETERS----- ------BEGIN EC PRIVATE KEY----- -MIGkAgEBBDCQP8utxNbHR6xZOLAJgUhn88r6IrPqmN0MsgGJM/jePB+T9UhkmIU8 -PMm2HeScbcugBwYFK4EEACKhZANiAARWdtKGwz6XlFHfB9ZaYaHO4UbA3MoKTuL3 -HKhsMjIFTEb9RRJ+PsoqVRem4OcMS0XnFdx6mXvjgLIgBgUs5cdvlaojiMI7MbSj -1//TRBDhtC50k51upX3XRAULa9vsXGs= ------END EC PRIVATE KEY----- diff --git a/tests/plugins/http/handler_test.go b/tests/plugins/http/handler_test.go deleted file mode 100644 index c8709678..00000000 --- a/tests/plugins/http/handler_test.go +++ /dev/null @@ -1,1862 +0,0 @@ -package http - -import ( - "bytes" - "context" - "io/ioutil" - "mime/multipart" - "net/url" - "os/exec" - "runtime" - "strings" - - "github.com/spiral/roadrunner/v2/pkg/pool" - "github.com/spiral/roadrunner/v2/pkg/transport/pipe" - handler "github.com/spiral/roadrunner/v2/pkg/worker_handler" - "github.com/spiral/roadrunner/v2/plugins/http/config" - "github.com/stretchr/testify/assert" - - "net/http" - "os" - "testing" - "time" -) - -func TestHandler_Echo(t *testing.T) { - p, err := pool.Initialize(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../http/client.php", "echo", "pipes") }, - pipe.NewPipeFactory(), - &pool.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - - h, err := handler.NewHandler(1024, 500, config.Uploads{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, p) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":8177", Handler: h} - defer func() { - errS := hs.Shutdown(context.Background()) - if errS != nil { - t.Errorf("error during the shutdown: error %v", err) - } - }() - go func(server *http.Server) { - err = server.ListenAndServe() - if err != nil && err != http.ErrServerClosed { - t.Errorf("error listening the interface: error %v", err) - } - }(hs) - time.Sleep(time.Millisecond * 10) - - body, r, err := get("http://127.0.0.1:8177/?hello=world") - assert.NoError(t, err) - defer func() { - _ = r.Body.Close() - }() - assert.Equal(t, 201, r.StatusCode) - assert.Equal(t, "WORLD", body) -} - -func Test_HandlerErrors(t *testing.T) { - _, err := handler.NewHandler(1024, 500, config.Uploads{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, nil) - assert.Error(t, err) -} - -func TestHandler_Headers(t *testing.T) { - p, err := pool.Initialize(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../http/client.php", "header", "pipes") }, - pipe.NewPipeFactory(), - &pool.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - p.Destroy(context.Background()) - }() - - h, err := handler.NewHandler(1024, 500, config.Uploads{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, p) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":8078", Handler: h} - defer func() { - errS := hs.Shutdown(context.Background()) - if errS != nil { - t.Errorf("error during the shutdown: error %v", err) - } - }() - - go func() { - err = hs.ListenAndServe() - if err != nil && err != http.ErrServerClosed { - t.Errorf("error listening the interface: error %v", err) - } - }() - time.Sleep(time.Millisecond * 100) - - req, err := http.NewRequest("GET", "http://127.0.0.1:8078?hello=world", nil) - assert.NoError(t, err) - - req.Header.Add("input", "sample") - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - defer func() { - err = r.Body.Close() - if err != nil { - t.Errorf("error during the closing Body: error %v", err) - } - }() - - b, err := ioutil.ReadAll(r.Body) - assert.NoError(t, err) - - assert.NoError(t, err) - assert.Equal(t, 200, r.StatusCode) - assert.Equal(t, "world", r.Header.Get("Header")) - assert.Equal(t, "SAMPLE", string(b)) -} - -func TestHandler_Empty_User_Agent(t *testing.T) { - p, err := pool.Initialize(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../http/client.php", "user-agent", "pipes") }, - pipe.NewPipeFactory(), - &pool.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - p.Destroy(context.Background()) - }() - - h, err := handler.NewHandler(1024, 500, config.Uploads{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, p) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":19658", Handler: h} - defer func() { - errS := hs.Shutdown(context.Background()) - if errS != nil { - t.Errorf("error during the shutdown: error %v", err) - } - }() - - go func() { - err = hs.ListenAndServe() - if err != nil && err != http.ErrServerClosed { - t.Errorf("error listening the interface: error %v", err) - } - }() - time.Sleep(time.Millisecond * 10) - - req, err := http.NewRequest("GET", "http://127.0.0.1:19658?hello=world", nil) - assert.NoError(t, err) - - req.Header.Add("user-agent", "") - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - defer func() { - err = r.Body.Close() - if err != nil { - t.Errorf("error during the closing Body: error %v", err) - } - }() - - b, err := ioutil.ReadAll(r.Body) - assert.NoError(t, err) - - assert.NoError(t, err) - assert.Equal(t, 200, r.StatusCode) - assert.Equal(t, "", string(b)) -} - -func TestHandler_User_Agent(t *testing.T) { - p, err := pool.Initialize(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../http/client.php", "user-agent", "pipes") }, - pipe.NewPipeFactory(), - &pool.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - p.Destroy(context.Background()) - }() - - h, err := handler.NewHandler(1024, 500, config.Uploads{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, p) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":25688", Handler: h} - defer func() { - errS := hs.Shutdown(context.Background()) - if errS != nil { - t.Errorf("error during the shutdown: error %v", err) - } - }() - - go func() { - err = hs.ListenAndServe() - if err != nil && err != http.ErrServerClosed { - t.Errorf("error listening the interface: error %v", err) - } - }() - time.Sleep(time.Millisecond * 10) - - req, err := http.NewRequest("GET", "http://127.0.0.1:25688?hello=world", nil) - assert.NoError(t, err) - - req.Header.Add("User-Agent", "go-agent") - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - defer func() { - err = r.Body.Close() - if err != nil { - t.Errorf("error during the closing Body: error %v", err) - } - }() - - b, err := ioutil.ReadAll(r.Body) - assert.NoError(t, err) - - assert.NoError(t, err) - assert.Equal(t, 200, r.StatusCode) - assert.Equal(t, "go-agent", string(b)) -} - -func TestHandler_Cookies(t *testing.T) { - p, err := pool.Initialize(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../http/client.php", "cookie", "pipes") }, - pipe.NewPipeFactory(), - &pool.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - p.Destroy(context.Background()) - }() - - h, err := handler.NewHandler(1024, 500, config.Uploads{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, p) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":8079", Handler: h} - defer func() { - errS := hs.Shutdown(context.Background()) - if errS != nil { - t.Errorf("error during the shutdown: error %v", err) - } - }() - - go func() { - err = hs.ListenAndServe() - if err != nil && err != http.ErrServerClosed { - t.Errorf("error listening the interface: error %v", err) - } - }() - time.Sleep(time.Millisecond * 10) - - req, err := http.NewRequest("GET", "http://127.0.0.1:8079", nil) - assert.NoError(t, err) - - req.AddCookie(&http.Cookie{Name: "input", Value: "input-value"}) - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - defer func() { - err = r.Body.Close() - if err != nil { - t.Errorf("error during the closing Body: error %v", err) - } - }() - - b, err := ioutil.ReadAll(r.Body) - assert.NoError(t, err) - - assert.NoError(t, err) - assert.Equal(t, 200, r.StatusCode) - assert.Equal(t, "INPUT-VALUE", string(b)) - - for _, c := range r.Cookies() { - assert.Equal(t, "output", c.Name) - assert.Equal(t, "cookie-output", c.Value) - } -} - -func TestHandler_JsonPayload_POST(t *testing.T) { - p, err := pool.Initialize(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../http/client.php", "payload", "pipes") }, - pipe.NewPipeFactory(), - &pool.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - p.Destroy(context.Background()) - }() - - h, err := handler.NewHandler(1024, 500, config.Uploads{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, p) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":8090", Handler: h} - defer func() { - errS := hs.Shutdown(context.Background()) - if errS != nil { - t.Errorf("error during the shutdown: error %v", err) - } - }() - - go func() { - err = hs.ListenAndServe() - if err != nil && err != http.ErrServerClosed { - t.Errorf("error listening the interface: error %v", err) - } - }() - time.Sleep(time.Millisecond * 10) - - req, err := http.NewRequest( - "POST", - "http://127.0.0.1"+hs.Addr, - bytes.NewBufferString(`{"key":"value"}`), - ) - assert.NoError(t, err) - - req.Header.Add("Content-Type", "application/json") - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - defer func() { - err = r.Body.Close() - if err != nil { - t.Errorf("error during the closing Body: error %v", err) - } - }() - - b, err := ioutil.ReadAll(r.Body) - assert.NoError(t, err) - - assert.NoError(t, err) - assert.Equal(t, 200, r.StatusCode) - assert.Equal(t, `{"value":"key"}`, string(b)) -} - -func TestHandler_JsonPayload_PUT(t *testing.T) { - p, err := pool.Initialize(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../http/client.php", "payload", "pipes") }, - pipe.NewPipeFactory(), - &pool.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - p.Destroy(context.Background()) - }() - - h, err := handler.NewHandler(1024, 500, config.Uploads{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, p) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":8081", Handler: h} - defer func() { - errS := hs.Shutdown(context.Background()) - if errS != nil { - t.Errorf("error during the shutdown: error %v", err) - } - }() - - go func() { - err = hs.ListenAndServe() - if err != nil && err != http.ErrServerClosed { - t.Errorf("error listening the interface: error %v", err) - } - }() - time.Sleep(time.Millisecond * 10) - - req, err := http.NewRequest("PUT", "http://127.0.0.1"+hs.Addr, bytes.NewBufferString(`{"key":"value"}`)) - assert.NoError(t, err) - - req.Header.Add("Content-Type", "application/json") - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - defer func() { - err = r.Body.Close() - if err != nil { - t.Errorf("error during the closing Body: error %v", err) - } - }() - - b, err := ioutil.ReadAll(r.Body) - assert.NoError(t, err) - - assert.NoError(t, err) - assert.Equal(t, 200, r.StatusCode) - assert.Equal(t, `{"value":"key"}`, string(b)) -} - -func TestHandler_JsonPayload_PATCH(t *testing.T) { - p, err := pool.Initialize(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../http/client.php", "payload", "pipes") }, - pipe.NewPipeFactory(), - &pool.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - p.Destroy(context.Background()) - }() - - h, err := handler.NewHandler(1024, 500, config.Uploads{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, p) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":8082", Handler: h} - defer func() { - errS := hs.Shutdown(context.Background()) - if errS != nil { - t.Errorf("error during the shutdown: error %v", err) - } - }() - - go func() { - err = hs.ListenAndServe() - if err != nil && err != http.ErrServerClosed { - t.Errorf("error listening the interface: error %v", err) - } - }() - time.Sleep(time.Millisecond * 10) - - req, err := http.NewRequest("PATCH", "http://127.0.0.1"+hs.Addr, bytes.NewBufferString(`{"key":"value"}`)) - assert.NoError(t, err) - - req.Header.Add("Content-Type", "application/json") - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - defer func() { - err = r.Body.Close() - if err != nil { - t.Errorf("error during the closing Body: error %v", err) - } - }() - - b, err := ioutil.ReadAll(r.Body) - assert.NoError(t, err) - - assert.NoError(t, err) - assert.Equal(t, 200, r.StatusCode) - assert.Equal(t, `{"value":"key"}`, string(b)) -} - -func TestHandler_FormData_POST(t *testing.T) { - p, err := pool.Initialize(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../http/client.php", "data", "pipes") }, - pipe.NewPipeFactory(), - &pool.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - p.Destroy(context.Background()) - }() - - h, err := handler.NewHandler(1024, 500, config.Uploads{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, p) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":8083", Handler: h} - defer func() { - errS := hs.Shutdown(context.Background()) - if errS != nil { - t.Errorf("error during the shutdown: error %v", err) - } - }() - - go func() { - err = hs.ListenAndServe() - if err != nil && err != http.ErrServerClosed { - t.Errorf("error listening the interface: error %v", err) - } - }() - time.Sleep(time.Millisecond * 500) - - form := url.Values{} - - form.Add("key", "value") - form.Add("name[]", "name1") - form.Add("name[]", "name2") - form.Add("name[]", "name3") - form.Add("arr[x][y][z]", "y") - form.Add("arr[x][y][e]", "f") - form.Add("arr[c]p", "l") - form.Add("arr[c]z", "") - - req, err := http.NewRequest("POST", "http://127.0.0.1"+hs.Addr, strings.NewReader(form.Encode())) - assert.NoError(t, err) - - req.Header.Add("Content-Type", "application/x-www-form-urlencoded") - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - defer func() { - err = r.Body.Close() - if err != nil { - t.Errorf("error during the closing Body: error %v", err) - } - }() - - b, err := ioutil.ReadAll(r.Body) - assert.NoError(t, err) - - assert.NoError(t, err) - assert.Equal(t, 200, r.StatusCode) - - // Sorted - assert.Equal(t, "{\"arr\":{\"c\":{\"p\":\"l\",\"z\":\"\"},\"x\":{\"y\":{\"e\":\"f\",\"z\":\"y\"}}},\"key\":\"value\",\"name\":[\"name1\",\"name2\",\"name3\"]}", string(b)) -} - -func TestHandler_FormData_POST_Overwrite(t *testing.T) { - p, err := pool.Initialize(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../http/client.php", "data", "pipes") }, - pipe.NewPipeFactory(), - &pool.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - p.Destroy(context.Background()) - }() - - h, err := handler.NewHandler(1024, 500, config.Uploads{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, p) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":8083", Handler: h} - defer func() { - errS := hs.Shutdown(context.Background()) - if errS != nil { - t.Errorf("error during the shutdown: error %v", err) - } - }() - - go func() { - err = hs.ListenAndServe() - if err != nil && err != http.ErrServerClosed { - t.Errorf("error listening the interface: error %v", err) - } - }() - time.Sleep(time.Millisecond * 10) - - form := url.Values{} - - form.Add("key", "value") - form.Add("key", "value2") - form.Add("name[]", "name1") - form.Add("name[]", "name2") - form.Add("name[]", "name3") - form.Add("arr[x][y][z]", "y") - form.Add("arr[x][y][e]", "f") - form.Add("arr[c]p", "l") - form.Add("arr[c]z", "") - - req, err := http.NewRequest("POST", "http://127.0.0.1"+hs.Addr, strings.NewReader(form.Encode())) - assert.NoError(t, err) - - req.Header.Add("Content-Type", "application/x-www-form-urlencoded") - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - defer func() { - err = r.Body.Close() - if err != nil { - t.Errorf("error during the closing Body: error %v", err) - } - }() - - b, err := ioutil.ReadAll(r.Body) - assert.NoError(t, err) - - assert.NoError(t, err) - assert.Equal(t, 200, r.StatusCode) - - assert.Equal(t, `{"arr":{"c":{"p":"l","z":""},"x":{"y":{"e":"f","z":"y"}}},"key":"value2","name":["name1","name2","name3"]}`, string(b)) -} - -func TestHandler_FormData_POST_Form_UrlEncoded_Charset(t *testing.T) { - p, err := pool.Initialize(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../http/client.php", "data", "pipes") }, - pipe.NewPipeFactory(), - &pool.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - p.Destroy(context.Background()) - }() - - h, err := handler.NewHandler(1024, 500, config.Uploads{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, p) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":8083", Handler: h} - defer func() { - errS := hs.Shutdown(context.Background()) - if errS != nil { - t.Errorf("error during the shutdown: error %v", err) - } - }() - - go func() { - err = hs.ListenAndServe() - if err != nil && err != http.ErrServerClosed { - t.Errorf("error listening the interface: error %v", err) - } - }() - time.Sleep(time.Millisecond * 10) - - form := url.Values{} - - form.Add("key", "value") - form.Add("name[]", "name1") - form.Add("name[]", "name2") - form.Add("name[]", "name3") - form.Add("arr[x][y][z]", "y") - form.Add("arr[x][y][e]", "f") - form.Add("arr[c]p", "l") - form.Add("arr[c]z", "") - - req, err := http.NewRequest("POST", "http://127.0.0.1"+hs.Addr, strings.NewReader(form.Encode())) - assert.NoError(t, err) - - req.Header.Add("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8") - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - defer func() { - err = r.Body.Close() - if err != nil { - t.Errorf("error during the closing Body: error %v", err) - } - }() - - b, err := ioutil.ReadAll(r.Body) - assert.NoError(t, err) - - assert.NoError(t, err) - assert.Equal(t, 200, r.StatusCode) - - assert.Equal(t, `{"arr":{"c":{"p":"l","z":""},"x":{"y":{"e":"f","z":"y"}}},"key":"value","name":["name1","name2","name3"]}`, string(b)) -} - -func TestHandler_FormData_PUT(t *testing.T) { - p, err := pool.Initialize(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../http/client.php", "data", "pipes") }, - pipe.NewPipeFactory(), - &pool.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - p.Destroy(context.Background()) - }() - - h, err := handler.NewHandler(1024, 500, config.Uploads{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, p) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":17834", Handler: h} - defer func() { - errS := hs.Shutdown(context.Background()) - if errS != nil { - t.Errorf("error during the shutdown: error %v", err) - } - }() - - go func() { - err = hs.ListenAndServe() - if err != nil && err != http.ErrServerClosed { - t.Errorf("error listening the interface: error %v", err) - } - }() - time.Sleep(time.Millisecond * 500) - - form := url.Values{} - - form.Add("key", "value") - form.Add("name[]", "name1") - form.Add("name[]", "name2") - form.Add("name[]", "name3") - form.Add("arr[x][y][z]", "y") - form.Add("arr[x][y][e]", "f") - form.Add("arr[c]p", "l") - form.Add("arr[c]z", "") - - req, err := http.NewRequest("PUT", "http://127.0.0.1"+hs.Addr, strings.NewReader(form.Encode())) - assert.NoError(t, err) - - req.Header.Add("Content-Type", "application/x-www-form-urlencoded") - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - defer func() { - err = r.Body.Close() - if err != nil { - t.Errorf("error during the closing Body: error %v", err) - } - }() - - b, err := ioutil.ReadAll(r.Body) - assert.NoError(t, err) - - assert.NoError(t, err) - assert.Equal(t, 200, r.StatusCode) - - assert.Equal(t, `{"arr":{"c":{"p":"l","z":""},"x":{"y":{"e":"f","z":"y"}}},"key":"value","name":["name1","name2","name3"]}`, string(b)) -} - -func TestHandler_FormData_PATCH(t *testing.T) { - p, err := pool.Initialize(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../http/client.php", "data", "pipes") }, - pipe.NewPipeFactory(), - &pool.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - p.Destroy(context.Background()) - }() - - h, err := handler.NewHandler(1024, 500, config.Uploads{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, p) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":8085", Handler: h} - defer func() { - errS := hs.Shutdown(context.Background()) - if errS != nil { - t.Errorf("error during the shutdown: error %v", err) - } - }() - - go func() { - err = hs.ListenAndServe() - if err != nil && err != http.ErrServerClosed { - t.Errorf("error listening the interface: error %v", err) - } - }() - time.Sleep(time.Millisecond * 10) - - form := url.Values{} - - form.Add("key", "value") - form.Add("name[]", "name1") - form.Add("name[]", "name2") - form.Add("name[]", "name3") - form.Add("arr[x][y][z]", "y") - form.Add("arr[x][y][e]", "f") - form.Add("arr[c]p", "l") - form.Add("arr[c]z", "") - - req, err := http.NewRequest("PATCH", "http://127.0.0.1"+hs.Addr, strings.NewReader(form.Encode())) - assert.NoError(t, err) - - req.Header.Add("Content-Type", "application/x-www-form-urlencoded") - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - defer func() { - err = r.Body.Close() - if err != nil { - t.Errorf("error during the closing Body: error %v", err) - } - }() - - b, err := ioutil.ReadAll(r.Body) - assert.NoError(t, err) - - assert.NoError(t, err) - assert.Equal(t, 200, r.StatusCode) - - assert.Equal(t, "{\"arr\":{\"c\":{\"p\":\"l\",\"z\":\"\"},\"x\":{\"y\":{\"e\":\"f\",\"z\":\"y\"}}},\"key\":\"value\",\"name\":[\"name1\",\"name2\",\"name3\"]}", string(b)) -} - -func TestHandler_Multipart_POST(t *testing.T) { - p, err := pool.Initialize(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../http/client.php", "data", "pipes") }, - pipe.NewPipeFactory(), - &pool.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - p.Destroy(context.Background()) - }() - - h, err := handler.NewHandler(1024, 500, config.Uploads{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, p) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":8019", Handler: h} - defer func() { - errS := hs.Shutdown(context.Background()) - if errS != nil { - t.Errorf("error during the shutdown: error %v", err) - } - }() - - go func() { - err = hs.ListenAndServe() - if err != nil && err != http.ErrServerClosed { - t.Errorf("error listening the interface: error %v", err) - } - }() - time.Sleep(time.Millisecond * 10) - - var mb bytes.Buffer - w := multipart.NewWriter(&mb) - err = w.WriteField("key", "value") - if err != nil { - t.Errorf("error writing the field: error %v", err) - } - - err = w.WriteField("key", "value") - if err != nil { - t.Errorf("error writing the field: error %v", err) - } - - err = w.WriteField("name[]", "name1") - if err != nil { - t.Errorf("error writing the field: error %v", err) - } - - err = w.WriteField("name[]", "name2") - if err != nil { - t.Errorf("error writing the field: error %v", err) - } - - err = w.WriteField("name[]", "name3") - if err != nil { - t.Errorf("error writing the field: error %v", err) - } - - err = w.WriteField("arr[x][y][z]", "y") - if err != nil { - t.Errorf("error writing the field: error %v", err) - } - - err = w.WriteField("arr[x][y][e]", "f") - - if err != nil { - t.Errorf("error writing the field: error %v", err) - } - - err = w.WriteField("arr[c]p", "l") - if err != nil { - t.Errorf("error writing the field: error %v", err) - } - - err = w.WriteField("arr[c]z", "") - if err != nil { - t.Errorf("error writing the field: error %v", err) - } - - err = w.Close() - if err != nil { - t.Errorf("error closing the writer: error %v", err) - } - - req, err := http.NewRequest("POST", "http://127.0.0.1"+hs.Addr, &mb) - assert.NoError(t, err) - - req.Header.Set("Content-Type", w.FormDataContentType()) - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - defer func() { - err = r.Body.Close() - if err != nil { - t.Errorf("error during the closing Body: error %v", err) - } - }() - - b, err := ioutil.ReadAll(r.Body) - assert.NoError(t, err) - - assert.NoError(t, err) - assert.Equal(t, 200, r.StatusCode) - - assert.Equal(t, "{\"arr\":{\"c\":{\"p\":\"l\",\"z\":\"\"},\"x\":{\"y\":{\"e\":\"f\",\"z\":\"y\"}}},\"key\":\"value\",\"name\":[\"name1\",\"name2\",\"name3\"]}", string(b)) -} - -func TestHandler_Multipart_PUT(t *testing.T) { - p, err := pool.Initialize(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../http/client.php", "data", "pipes") }, - pipe.NewPipeFactory(), - &pool.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - p.Destroy(context.Background()) - }() - - h, err := handler.NewHandler(1024, 500, config.Uploads{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, p) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":8020", Handler: h} - defer func() { - errS := hs.Shutdown(context.Background()) - if errS != nil { - t.Errorf("error during the shutdown: error %v", err) - } - }() - - go func() { - err = hs.ListenAndServe() - if err != nil && err != http.ErrServerClosed { - t.Errorf("error listening the interface: error %v", err) - } - }() - time.Sleep(time.Millisecond * 500) - - var mb bytes.Buffer - w := multipart.NewWriter(&mb) - err = w.WriteField("key", "value") - if err != nil { - t.Errorf("error writing the field: error %v", err) - } - - err = w.WriteField("key", "value") - if err != nil { - t.Errorf("error writing the field: error %v", err) - } - - err = w.WriteField("name[]", "name1") - - if err != nil { - t.Errorf("error writing the field: error %v", err) - } - - err = w.WriteField("name[]", "name2") - if err != nil { - t.Errorf("error writing the field: error %v", err) - } - - err = w.WriteField("name[]", "name3") - if err != nil { - t.Errorf("error writing the field: error %v", err) - } - - err = w.WriteField("arr[x][y][z]", "y") - if err != nil { - t.Errorf("error writing the field: error %v", err) - } - - err = w.WriteField("arr[x][y][e]", "f") - if err != nil { - t.Errorf("error writing the field: error %v", err) - } - - err = w.WriteField("arr[c]p", "l") - if err != nil { - t.Errorf("error writing the field: error %v", err) - } - - err = w.WriteField("arr[c]z", "") - if err != nil { - t.Errorf("error writing the field: error %v", err) - } - - err = w.Close() - if err != nil { - t.Errorf("error closing the writer: error %v", err) - } - - req, err := http.NewRequest("PUT", "http://127.0.0.1"+hs.Addr, &mb) - assert.NoError(t, err) - - req.Header.Set("Content-Type", w.FormDataContentType()) - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - defer func() { - err = r.Body.Close() - if err != nil { - t.Errorf("error during the closing Body: error %v", err) - } - }() - - b, err := ioutil.ReadAll(r.Body) - assert.NoError(t, err) - - assert.NoError(t, err) - assert.Equal(t, 200, r.StatusCode) - - assert.Equal(t, `{"arr":{"c":{"p":"l","z":""},"x":{"y":{"e":"f","z":"y"}}},"key":"value","name":["name1","name2","name3"]}`, string(b)) -} - -func TestHandler_Multipart_PATCH(t *testing.T) { - p, err := pool.Initialize(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../http/client.php", "data", "pipes") }, - pipe.NewPipeFactory(), - &pool.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - p.Destroy(context.Background()) - }() - - h, err := handler.NewHandler(1024, 500, config.Uploads{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, p) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":8021", Handler: h} - defer func() { - errS := hs.Shutdown(context.Background()) - if errS != nil { - t.Errorf("error during the shutdown: error %v", err) - } - }() - - go func() { - err = hs.ListenAndServe() - - if err != nil && err != http.ErrServerClosed { - t.Errorf("error listening the interface: error %v", err) - } - }() - time.Sleep(time.Millisecond * 500) - - var mb bytes.Buffer - w := multipart.NewWriter(&mb) - err = w.WriteField("key", "value") - if err != nil { - t.Errorf("error writing the field: error %v", err) - } - - err = w.WriteField("key", "value") - if err != nil { - t.Errorf("error writing the field: error %v", err) - } - - err = w.WriteField("name[]", "name1") - if err != nil { - t.Errorf("error writing the field: error %v", err) - } - - err = w.WriteField("name[]", "name2") - - if err != nil { - t.Errorf("error writing the field: error %v", err) - } - - err = w.WriteField("name[]", "name3") - - if err != nil { - t.Errorf("error writing the field: error %v", err) - } - - err = w.WriteField("arr[x][y][z]", "y") - if err != nil { - t.Errorf("error writing the field: error %v", err) - } - - err = w.WriteField("arr[x][y][e]", "f") - if err != nil { - t.Errorf("error writing the field: error %v", err) - } - - err = w.WriteField("arr[c]p", "l") - if err != nil { - t.Errorf("error writing the field: error %v", err) - } - - err = w.WriteField("arr[c]z", "") - if err != nil { - t.Errorf("error writing the field: error %v", err) - } - - err = w.Close() - if err != nil { - t.Errorf("error closing the writer: error %v", err) - } - - req, err := http.NewRequest("PATCH", "http://127.0.0.1"+hs.Addr, &mb) - assert.NoError(t, err) - - req.Header.Set("Content-Type", w.FormDataContentType()) - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - defer func() { - err = r.Body.Close() - if err != nil { - t.Errorf("error during the closing Body: error %v", err) - } - }() - - b, err := ioutil.ReadAll(r.Body) - assert.NoError(t, err) - - assert.NoError(t, err) - assert.Equal(t, 200, r.StatusCode) - - assert.Equal(t, `{"arr":{"c":{"p":"l","z":""},"x":{"y":{"e":"f","z":"y"}}},"key":"value","name":["name1","name2","name3"]}`, string(b)) -} - -func TestHandler_Error(t *testing.T) { - p, err := pool.Initialize(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../http/client.php", "error", "pipes") }, - pipe.NewPipeFactory(), - &pool.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - p.Destroy(context.Background()) - }() - - h, err := handler.NewHandler(1024, 500, config.Uploads{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, p) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":8177", Handler: h} - defer func() { - errS := hs.Shutdown(context.Background()) - if errS != nil { - t.Errorf("error during the shutdown: error %v", err) - } - }() - - go func() { - err = hs.ListenAndServe() - if err != nil && err != http.ErrServerClosed { - t.Errorf("error listening the interface: error %v", err) - } - }() - time.Sleep(time.Millisecond * 10) - - _, r, err := get("http://127.0.0.1:8177/?hello=world") - assert.NoError(t, err) - defer func() { - _ = r.Body.Close() - }() - assert.Equal(t, 500, r.StatusCode) -} - -func TestHandler_Error2(t *testing.T) { - p, err := pool.Initialize(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../http/client.php", "error2", "pipes") }, - pipe.NewPipeFactory(), - &pool.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - p.Destroy(context.Background()) - }() - - h, err := handler.NewHandler(1024, 500, config.Uploads{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, p) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":8177", Handler: h} - defer func() { - errS := hs.Shutdown(context.Background()) - if errS != nil { - t.Errorf("error during the shutdown: error %v", err) - } - }() - - go func() { - err = hs.ListenAndServe() - if err != nil && err != http.ErrServerClosed { - t.Errorf("error listening the interface: error %v", err) - } - }() - time.Sleep(time.Millisecond * 10) - - _, r, err := get("http://127.0.0.1:8177/?hello=world") - assert.NoError(t, err) - defer func() { - _ = r.Body.Close() - }() - assert.Equal(t, 500, r.StatusCode) -} - -func TestHandler_Error3(t *testing.T) { - p, err := pool.Initialize(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../http/client.php", "pid", "pipes") }, - pipe.NewPipeFactory(), - &pool.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - p.Destroy(context.Background()) - }() - - h, err := handler.NewHandler(1, 500, config.Uploads{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, p) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":8177", Handler: h} - defer func() { - errS := hs.Shutdown(context.Background()) - if errS != nil { - t.Errorf("error during the shutdown: error %v", err) - } - }() - - go func() { - err = hs.ListenAndServe() - if err != nil && err != http.ErrServerClosed { - t.Errorf("error listening the interface: error %v", err) - } - }() - time.Sleep(time.Millisecond * 10) - - b2 := &bytes.Buffer{} - for i := 0; i < 1024*1024; i++ { - b2.Write([]byte(" ")) - } - - req, err := http.NewRequest("POST", "http://127.0.0.1"+hs.Addr, b2) - assert.NoError(t, err) - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - defer func() { - err = r.Body.Close() - if err != nil { - t.Errorf("error during the closing Body: error %v", err) - } - }() - - assert.NoError(t, err) - assert.Equal(t, 400, r.StatusCode) -} - -func TestHandler_ResponseDuration(t *testing.T) { - p, err := pool.Initialize(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../http/client.php", "echo", "pipes") }, - pipe.NewPipeFactory(), - &pool.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - p.Destroy(context.Background()) - }() - - h, err := handler.NewHandler(1024, 500, config.Uploads{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, p) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":8177", Handler: h} - defer func() { - errS := hs.Shutdown(context.Background()) - if errS != nil { - t.Errorf("error during the shutdown: error %v", err) - } - }() - - go func() { - err = hs.ListenAndServe() - if err != nil && err != http.ErrServerClosed { - t.Errorf("error listening the interface: error %v", err) - } - }() - time.Sleep(time.Millisecond * 10) - - gotresp := make(chan interface{}) - h.AddListener(func(event interface{}) { - switch t := event.(type) { - case handler.ResponseEvent: - if t.Elapsed() > 0 { - close(gotresp) - } - default: - } - }) - - body, r, err := get("http://127.0.0.1:8177/?hello=world") - assert.NoError(t, err) - defer func() { - _ = r.Body.Close() - }() - - <-gotresp - - assert.Equal(t, 201, r.StatusCode) - assert.Equal(t, "WORLD", body) -} - -func TestHandler_ResponseDurationDelayed(t *testing.T) { - p, err := pool.Initialize(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../http/client.php", "echoDelay", "pipes") }, - pipe.NewPipeFactory(), - &pool.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - p.Destroy(context.Background()) - }() - - h, err := handler.NewHandler(1024, 500, config.Uploads{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, p) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":8177", Handler: h} - defer func() { - errS := hs.Shutdown(context.Background()) - if errS != nil { - t.Errorf("error during the shutdown: error %v", err) - } - }() - - go func() { - err = hs.ListenAndServe() - if err != nil && err != http.ErrServerClosed { - t.Errorf("error listening the interface: error %v", err) - } - }() - time.Sleep(time.Millisecond * 10) - - gotresp := make(chan interface{}) - h.AddListener(func(event interface{}) { - switch tp := event.(type) { - case handler.ResponseEvent: - if tp.Elapsed() > time.Second { - close(gotresp) - } - default: - } - }) - - body, r, err := get("http://127.0.0.1:8177/?hello=world") - assert.NoError(t, err) - defer func() { - _ = r.Body.Close() - }() - <-gotresp - - assert.Equal(t, 201, r.StatusCode) - assert.Equal(t, "WORLD", body) -} - -func TestHandler_ErrorDuration(t *testing.T) { - p, err := pool.Initialize(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../http/client.php", "error", "pipes") }, - pipe.NewPipeFactory(), - &pool.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - p.Destroy(context.Background()) - }() - - h, err := handler.NewHandler(1024, 500, config.Uploads{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, p) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":8177", Handler: h} - defer func() { - errS := hs.Shutdown(context.Background()) - if errS != nil { - t.Errorf("error during the shutdown: error %v", err) - } - }() - - go func() { - err = hs.ListenAndServe() - if err != nil && err != http.ErrServerClosed { - t.Errorf("error listening the interface: error %v", err) - } - }() - time.Sleep(time.Millisecond * 10) - - goterr := make(chan struct{}, 10) - h.AddListener(func(event interface{}) { - switch tp := event.(type) { - case handler.ErrorEvent: - if tp.Elapsed() > 0 { - goterr <- struct{}{} - } - default: - } - }) - - _, r, err := get("http://127.0.0.1:8177/?hello=world") - assert.NoError(t, err) - defer func() { - _ = r.Body.Close() - }() - - <-goterr - <-goterr - - assert.Equal(t, 500, r.StatusCode) -} - -func TestHandler_IP(t *testing.T) { - trusted := []string{ - "10.0.0.0/8", - "127.0.0.0/8", - "172.16.0.0/12", - "192.168.0.0/16", - "::1/128", - "fc00::/7", - "fe80::/10", - } - - cidrs, err := config.ParseCIDRs(trusted) - assert.NoError(t, err) - assert.NotNil(t, cidrs) - - p, err := pool.Initialize(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../http/client.php", "ip", "pipes") }, - pipe.NewPipeFactory(), - &pool.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - p.Destroy(context.Background()) - }() - - h, err := handler.NewHandler(1024, 500, config.Uploads{ - Dir: os.TempDir(), - Forbid: []string{}, - }, cidrs, p) - assert.NoError(t, err) - - hs := &http.Server{Addr: "127.0.0.1:8177", Handler: h} - defer func() { - errS := hs.Shutdown(context.Background()) - if errS != nil { - t.Errorf("error during the shutdown: error %v", err) - } - }() - - go func() { - err = hs.ListenAndServe() - if err != nil && err != http.ErrServerClosed { - t.Errorf("error listening the interface: error %v", err) - } - }() - time.Sleep(time.Millisecond * 10) - - body, r, err := get("http://127.0.0.1:8177/") - assert.NoError(t, err) - defer func() { - _ = r.Body.Close() - }() - assert.Equal(t, 200, r.StatusCode) - assert.Equal(t, "127.0.0.1", body) -} - -func TestHandler_XRealIP(t *testing.T) { - trusted := []string{ - "10.0.0.0/8", - "127.0.0.0/8", - "172.16.0.0/12", - "192.168.0.0/16", - "::1/128", - "fc00::/7", - "fe80::/10", - } - - cidrs, err := config.ParseCIDRs(trusted) - assert.NoError(t, err) - assert.NotNil(t, cidrs) - - p, err := pool.Initialize(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../http/client.php", "ip", "pipes") }, - pipe.NewPipeFactory(), - &pool.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - p.Destroy(context.Background()) - }() - - h, err := handler.NewHandler(1024, 500, config.Uploads{ - Dir: os.TempDir(), - Forbid: []string{}, - }, cidrs, p) - assert.NoError(t, err) - - hs := &http.Server{Addr: "127.0.0.1:8179", Handler: h} - defer func() { - errS := hs.Shutdown(context.Background()) - if errS != nil { - t.Errorf("error during the shutdown: error %v", err) - } - }() - - go func() { - err = hs.ListenAndServe() - if err != nil && err != http.ErrServerClosed { - t.Errorf("error listening the interface: error %v", err) - } - }() - time.Sleep(time.Millisecond * 10) - - body, r, err := getHeader("http://127.0.0.1:8179/", map[string]string{ - "X-Real-Ip": "200.0.0.1", - }) - - assert.NoError(t, err) - defer func() { - _ = r.Body.Close() - }() - assert.Equal(t, 200, r.StatusCode) - assert.Equal(t, "200.0.0.1", body) -} - -func TestHandler_XForwardedFor(t *testing.T) { - trusted := []string{ - "10.0.0.0/8", - "127.0.0.0/8", - "172.16.0.0/12", - "192.168.0.0/16", - "100.0.0.0/16", - "200.0.0.0/16", - "::1/128", - "fc00::/7", - "fe80::/10", - } - - cidrs, err := config.ParseCIDRs(trusted) - assert.NoError(t, err) - assert.NotNil(t, cidrs) - - p, err := pool.Initialize(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../http/client.php", "ip", "pipes") }, - pipe.NewPipeFactory(), - &pool.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - p.Destroy(context.Background()) - }() - - h, err := handler.NewHandler(1024, 500, config.Uploads{ - Dir: os.TempDir(), - Forbid: []string{}, - }, cidrs, p) - assert.NoError(t, err) - - hs := &http.Server{Addr: "127.0.0.1:8177", Handler: h} - defer func() { - errS := hs.Shutdown(context.Background()) - if errS != nil { - t.Errorf("error during the shutdown: error %v", err) - } - }() - - go func() { - err = hs.ListenAndServe() - if err != nil && err != http.ErrServerClosed { - t.Errorf("error listening the interface: error %v", err) - } - }() - time.Sleep(time.Millisecond * 10) - - body, r, err := getHeader("http://127.0.0.1:8177/", map[string]string{ - "X-Forwarded-For": "100.0.0.1, 200.0.0.1, invalid, 101.0.0.1", - }) - - assert.NoError(t, err) - assert.Equal(t, 200, r.StatusCode) - assert.Equal(t, "101.0.0.1", body) - _ = r.Body.Close() - - body, r, err = getHeader("http://127.0.0.1:8177/", map[string]string{ - "X-Forwarded-For": "100.0.0.1, 200.0.0.1, 101.0.0.1, invalid", - }) - - assert.NoError(t, err) - _ = r.Body.Close() - assert.Equal(t, 200, r.StatusCode) - assert.Equal(t, "101.0.0.1", body) -} - -func TestHandler_XForwardedFor_NotTrustedRemoteIp(t *testing.T) { - trusted := []string{ - "10.0.0.0/8", - } - - cidrs, err := config.ParseCIDRs(trusted) - assert.NoError(t, err) - assert.NotNil(t, cidrs) - - p, err := pool.Initialize(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../http/client.php", "ip", "pipes") }, - pipe.NewPipeFactory(), - &pool.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - p.Destroy(context.Background()) - }() - - h, err := handler.NewHandler(1024, 500, config.Uploads{ - Dir: os.TempDir(), - Forbid: []string{}, - }, cidrs, p) - assert.NoError(t, err) - - hs := &http.Server{Addr: "127.0.0.1:8177", Handler: h} - defer func() { - errS := hs.Shutdown(context.Background()) - if errS != nil { - t.Errorf("error during the shutdown: error %v", err) - } - }() - - go func() { - err = hs.ListenAndServe() - if err != nil && err != http.ErrServerClosed { - t.Errorf("error listening the interface: error %v", err) - } - }() - time.Sleep(time.Millisecond * 10) - - body, r, err := getHeader("http://127.0.0.1:8177/", map[string]string{ - "X-Forwarded-For": "100.0.0.1, 200.0.0.1, invalid, 101.0.0.1", - }) - - assert.NoError(t, err) - _ = r.Body.Close() - assert.Equal(t, 200, r.StatusCode) - assert.Equal(t, "127.0.0.1", body) -} - -func BenchmarkHandler_Listen_Echo(b *testing.B) { - p, err := pool.Initialize(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../http/client.php", "echo", "pipes") }, - pipe.NewPipeFactory(), - &pool.Config{ - NumWorkers: uint64(runtime.NumCPU()), - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - b.Fatal(err) - } - defer func() { - p.Destroy(context.Background()) - }() - - h, err := handler.NewHandler(1024, 500, config.Uploads{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, p) - assert.NoError(b, err) - - hs := &http.Server{Addr: ":8177", Handler: h} - defer func() { - errS := hs.Shutdown(context.Background()) - if errS != nil { - b.Errorf("error during the shutdown: error %v", err) - } - }() - - go func() { - err = hs.ListenAndServe() - if err != nil && err != http.ErrServerClosed { - b.Errorf("error listening the interface: error %v", err) - } - }() - time.Sleep(time.Millisecond * 10) - - b.ResetTimer() - b.ReportAllocs() - bb := "WORLD" - for n := 0; n < b.N; n++ { - r, err := http.Get("http://127.0.0.1:8177/?hello=world") - if err != nil { - b.Fail() - } - // Response might be nil here - if r != nil { - br, err := ioutil.ReadAll(r.Body) - if err != nil { - b.Errorf("error reading Body: error %v", err) - } - if string(br) != bb { - b.Fail() - } - err = r.Body.Close() - if err != nil { - b.Errorf("error closing the Body: error %v", err) - } - } else { - b.Errorf("got nil response") - } - } -} diff --git a/tests/plugins/http/http_plugin_test.go b/tests/plugins/http/http_plugin_test.go deleted file mode 100644 index 10feff03..00000000 --- a/tests/plugins/http/http_plugin_test.go +++ /dev/null @@ -1,2516 +0,0 @@ -package http - -import ( - "bytes" - "crypto/rand" - "crypto/tls" - "fmt" - "io" - "io/ioutil" - "net" - "net/http" - "net/http/httptest" - "net/rpc" - "net/url" - "os" - "os/signal" - "sync" - "syscall" - "testing" - "time" - - "github.com/golang/mock/gomock" - endure "github.com/spiral/endure/pkg/container" - goridgeRpc "github.com/spiral/goridge/v3/pkg/rpc" - "github.com/spiral/roadrunner/v2/pkg/state/process" - "github.com/spiral/roadrunner/v2/plugins/config" - "github.com/spiral/roadrunner/v2/plugins/gzip" - "github.com/spiral/roadrunner/v2/plugins/informer" - "github.com/spiral/roadrunner/v2/plugins/logger" - "github.com/spiral/roadrunner/v2/plugins/resetter" - "github.com/spiral/roadrunner/v2/plugins/server" - "github.com/spiral/roadrunner/v2/plugins/static" - "github.com/spiral/roadrunner/v2/tests/mocks" - "github.com/stretchr/testify/require" - "github.com/yookoala/gofast" - - httpPlugin "github.com/spiral/roadrunner/v2/plugins/http" - rpcPlugin "github.com/spiral/roadrunner/v2/plugins/rpc" - "github.com/stretchr/testify/assert" -) - -var sslClient = &http.Client{ - Transport: &http.Transport{ - TLSClientConfig: &tls.Config{ - InsecureSkipVerify: true, //nolint:gosec - }, - }, -} - -func TestHTTPInit(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - rIn := makeConfig("6001", "15395", "7921", ":8892", "false", "false", "php ../../http/client.php echo pipes") - cfg := &config.Viper{ - ReadInCfg: rIn, - Type: "yaml", - } - - err = cont.RegisterAll( - cfg, - &logger.ZapLogger{}, - &server.Plugin{}, - &httpPlugin.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - stopCh <- struct{}{} - wg.Wait() -} - -func TestHTTPNoConfigSection(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-no-http.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &logger.ZapLogger{}, - &server.Plugin{}, - &httpPlugin.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 2) - stopCh <- struct{}{} - wg.Wait() -} - -func TestHTTPInformerReset(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-resetter.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &rpcPlugin.Plugin{}, - &logger.ZapLogger{}, - &server.Plugin{}, - &httpPlugin.Plugin{}, - &informer.Plugin{}, - &resetter.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 1) - t.Run("HTTPInformerTest", informerTest) - t.Run("HTTPEchoTestBefore", echoHTTP) - t.Run("HTTPResetTest", resetTest) - t.Run("HTTPEchoTestAfter", echoHTTP) - - stopCh <- struct{}{} - - wg.Wait() -} - -func TestSSL(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-ssl.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &rpcPlugin.Plugin{}, - &logger.ZapLogger{}, - &server.Plugin{}, - &httpPlugin.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 1) - t.Run("SSLEcho", sslEcho) - t.Run("SSLNoRedirect", sslNoRedirect) - t.Run("FCGEcho", fcgiEcho) - - stopCh <- struct{}{} - wg.Wait() -} - -func sslNoRedirect(t *testing.T) { - req, err := http.NewRequest("GET", "http://127.0.0.1:8085?hello=world", nil) - assert.NoError(t, err) - - r, err := sslClient.Do(req) - assert.NoError(t, err) - - assert.Nil(t, r.TLS) - - 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)) - - err2 := r.Body.Close() - if err2 != nil { - t.Errorf("fail to close the Body: error %v", err2) - } -} - -func sslEcho(t *testing.T) { - req, err := http.NewRequest("GET", "https://127.0.0.1:8893?hello=world", nil) - assert.NoError(t, err) - - r, err := sslClient.Do(req) - assert.NoError(t, err) - - 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)) - - err2 := r.Body.Close() - if err2 != nil { - t.Errorf("fail to close the Body: error %v", err2) - } -} - -func fcgiEcho(t *testing.T) { - fcgiConnFactory := gofast.SimpleConnFactory("tcp", "0.0.0.0:16920") - - fcgiHandler := gofast.NewHandler( - gofast.BasicParamsMap(gofast.BasicSession), - gofast.SimpleClientFactory(fcgiConnFactory), - ) - - w := httptest.NewRecorder() - req := httptest.NewRequest("GET", "http://site.local/?hello=world", nil) - fcgiHandler.ServeHTTP(w, req) - - body, err := ioutil.ReadAll(w.Result().Body) //nolint:bodyclose - - defer func() { - _ = w.Result().Body.Close() - w.Body.Reset() - }() - - assert.NoError(t, err) - assert.Equal(t, 201, w.Result().StatusCode) //nolint:bodyclose - assert.Equal(t, "WORLD", string(body)) -} - -func TestSSLRedirect(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-ssl-redirect.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &rpcPlugin.Plugin{}, - &logger.ZapLogger{}, - &server.Plugin{}, - &httpPlugin.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 1) - t.Run("SSLRedirect", sslRedirect) - - stopCh <- struct{}{} - wg.Wait() -} - -func sslRedirect(t *testing.T) { - req, err := http.NewRequest("GET", "http://127.0.0.1:8087?hello=world", nil) - assert.NoError(t, err) - - r, err := sslClient.Do(req) - assert.NoError(t, err) - assert.NotNil(t, r.TLS) - - 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)) - - err2 := r.Body.Close() - if err2 != nil { - t.Errorf("fail to close the Body: error %v", err2) - } -} - -func TestSSLPushPipes(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-ssl-push.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &rpcPlugin.Plugin{}, - &logger.ZapLogger{}, - &server.Plugin{}, - &httpPlugin.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 1) - t.Run("SSLPush", sslPush) - - stopCh <- struct{}{} - wg.Wait() -} - -func sslPush(t *testing.T) { - req, err := http.NewRequest("GET", "https://127.0.0.1:8894?hello=world", nil) - assert.NoError(t, err) - - r, err := sslClient.Do(req) - assert.NoError(t, err) - - assert.NotNil(t, r.TLS) - - b, err := ioutil.ReadAll(r.Body) - assert.NoError(t, err) - - assert.Equal(t, "", r.Header.Get("Http2-Release")) - - assert.NoError(t, err) - assert.Equal(t, 201, r.StatusCode) - assert.Equal(t, "WORLD", string(b)) - - err2 := r.Body.Close() - if err2 != nil { - t.Errorf("fail to close the Body: error %v", err2) - } -} - -func TestFastCGI_Echo(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-fcgi.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &logger.ZapLogger{}, - &server.Plugin{}, - &httpPlugin.Plugin{}, - &static.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 1) - t.Run("FastCGIEcho", fcgiEcho1) - - stopCh <- struct{}{} - wg.Wait() -} - -func fcgiEcho1(t *testing.T) { - time.Sleep(time.Second * 2) - fcgiConnFactory := gofast.SimpleConnFactory("tcp", "127.0.0.1:6920") - - fcgiHandler := gofast.NewHandler( - gofast.BasicParamsMap(gofast.BasicSession), - gofast.SimpleClientFactory(fcgiConnFactory), - ) - - w := httptest.NewRecorder() - req := httptest.NewRequest("GET", "http://site.local/hello-world", nil) - fcgiHandler.ServeHTTP(w, req) - - _, err := ioutil.ReadAll(w.Result().Body) //nolint:bodyclose - assert.NoError(t, err) - assert.Equal(t, 201, w.Result().StatusCode) //nolint:bodyclose -} - -func TestFastCGI_RequestUri(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-fcgi-reqUri.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &logger.ZapLogger{}, - &server.Plugin{}, - &httpPlugin.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 1) - t.Run("FastCGIServiceRequestUri", fcgiReqURI) - - stopCh <- struct{}{} - wg.Wait() -} - -func fcgiReqURI(t *testing.T) { - time.Sleep(time.Second * 2) - fcgiConnFactory := gofast.SimpleConnFactory("tcp", "127.0.0.1:6921") - - fcgiHandler := gofast.NewHandler( - gofast.BasicParamsMap(gofast.BasicSession), - gofast.SimpleClientFactory(fcgiConnFactory), - ) - - w := httptest.NewRecorder() - req := httptest.NewRequest("GET", "http://site.local/hello-world", nil) - fcgiHandler.ServeHTTP(w, req) - - body, err := ioutil.ReadAll(w.Result().Body) //nolint:bodyclose - assert.NoError(t, err) - assert.Equal(t, 200, w.Result().StatusCode) //nolint:bodyclose - assert.Equal(t, "http://site.local/hello-world", string(body)) -} - -func TestH2CUpgrade(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-h2c.yaml", - Prefix: "rr", - } - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - - mockLogger.EXPECT().Error("server internal error", "message", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).MinTimes(1) - - err = cont.RegisterAll( - cfg, - &rpcPlugin.Plugin{}, - mockLogger, - &server.Plugin{}, - &httpPlugin.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 1) - t.Run("H2cUpgrade", h2cUpgrade) - - stopCh <- struct{}{} - wg.Wait() -} - -func h2cUpgrade(t *testing.T) { - req, err := http.NewRequest("PRI", "http://127.0.0.1:8083?hello=world", nil) - if err != nil { - t.Fatal(err) - } - - req.Header.Add("Upgrade", "h2c") - req.Header.Add("Connection", "HTTP2-Settings") - req.Header.Add("HTTP2-Settings", "") - - r, err2 := http.DefaultClient.Do(req) - if err2 != nil { - t.Fatal(err) - } - - assert.Equal(t, "101 Switching Protocols", r.Status) - - err3 := r.Body.Close() - if err3 != nil { - t.Fatal(err) - } -} - -func TestH2C(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-h2c.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &rpcPlugin.Plugin{}, - &logger.ZapLogger{}, - &server.Plugin{}, - &httpPlugin.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 1) - t.Run("H2c", h2c) - - stopCh <- struct{}{} - wg.Wait() -} - -func h2c(t *testing.T) { - req, err := http.NewRequest("PRI", "http://127.0.0.1:8083?hello=world", nil) - if err != nil { - t.Fatal(err) - } - - req.Header.Add("Connection", "HTTP2-Settings") - req.Header.Add("HTTP2-Settings", "") - - r, err2 := http.DefaultClient.Do(req) - if err2 != nil { - t.Fatal(err) - } - - assert.Equal(t, "201 Created", r.Status) - - err3 := r.Body.Close() - if err3 != nil { - t.Fatal(err) - } -} - -func TestHttpMiddleware(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-http.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &rpcPlugin.Plugin{}, - &logger.ZapLogger{}, - &server.Plugin{}, - &httpPlugin.Plugin{}, - &PluginMiddleware{}, - &PluginMiddleware2{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 1) - t.Run("MiddlewareTest", middleware) - - stopCh <- struct{}{} - wg.Wait() -} - -func middleware(t *testing.T) { - req, err := http.NewRequest("GET", "http://127.0.0.1:18903?hello=world", nil) - assert.NoError(t, err) - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - - b, err := ioutil.ReadAll(r.Body) - assert.NoError(t, err) - - assert.Equal(t, 201, r.StatusCode) - assert.Equal(t, "WORLD", string(b)) - - err = r.Body.Close() - assert.NoError(t, err) - - req, err = http.NewRequest("GET", "http://127.0.0.1:18903/halt", nil) - assert.NoError(t, err) - - r, err = http.DefaultClient.Do(req) - assert.NoError(t, err) - b, err = ioutil.ReadAll(r.Body) - assert.NoError(t, err) - - assert.Equal(t, 500, r.StatusCode) - assert.Equal(t, "halted", string(b)) - - err = r.Body.Close() - assert.NoError(t, err) -} - -func TestHttpEchoErr(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - rIn := ` -rpc: - listen: tcp://127.0.0.1:6001 - disabled: false - -server: - command: "php ../../http/client.php echoerr pipes" - relay: "pipes" - relay_timeout: "20s" - -http: - debug: true - address: 127.0.0.1:34999 - max_request_size: 1024 - middleware: [ "pluginMiddleware", "pluginMiddleware2" ] - uploads: - forbid: [ "" ] - trusted_subnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] - pool: - num_workers: 2 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s - -logs: - mode: development - level: debug -` - - cfg := &config.Viper{ - Path: "", - Prefix: "", - Type: "yaml", - ReadInCfg: []byte(rIn), - } - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - - mockLogger.EXPECT().Debug(gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Debug("201 GET http://127.0.0.1:34999/?hello=world", "remote", "127.0.0.1", "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("WORLD").MinTimes(1) - mockLogger.EXPECT().Error(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() // placeholder for the workerlogerror - - err = cont.RegisterAll( - cfg, - mockLogger, - &server.Plugin{}, - &httpPlugin.Plugin{}, - &PluginMiddleware{}, - &PluginMiddleware2{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 3) - - t.Run("HttpEchoError", echoError) - - stopCh <- struct{}{} - wg.Wait() -} - -func echoError(t *testing.T) { - req, err := http.NewRequest("GET", "http://127.0.0.1:34999?hello=world", nil) - assert.NoError(t, err) - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - require.NotNil(t, r) - - b, err := ioutil.ReadAll(r.Body) - assert.NoError(t, err) - - assert.Equal(t, 201, r.StatusCode) - assert.Equal(t, "WORLD", string(b)) - err = r.Body.Close() - assert.NoError(t, err) -} - -func TestHttpEnvVariables(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-env.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &logger.ZapLogger{}, - &server.Plugin{}, - &httpPlugin.Plugin{}, - &PluginMiddleware{}, - &PluginMiddleware2{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 1) - t.Run("EnvVariablesTest", envVarsTest) - - stopCh <- struct{}{} - wg.Wait() -} - -func envVarsTest(t *testing.T) { - req, err := http.NewRequest("GET", "http://127.0.0.1:12084", nil) - assert.NoError(t, err) - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - - b, err := ioutil.ReadAll(r.Body) - assert.NoError(t, err) - - assert.Equal(t, 200, r.StatusCode) - assert.Equal(t, "ENV_VALUE", string(b)) - - err = r.Body.Close() - assert.NoError(t, err) -} - -func TestHttpBrokenPipes(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-broken-pipes.yaml", - Prefix: "rr", - Type: "yaml", - } - - err = cont.RegisterAll( - cfg, - &logger.ZapLogger{}, - &server.Plugin{}, - &httpPlugin.Plugin{}, - &PluginMiddleware{}, - &PluginMiddleware2{}, - ) - assert.NoError(t, err) - - err = cont.Init() - assert.NoError(t, err) - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - // should be error from the plugin - case e := <-ch: - assert.Error(t, e.Error) - return - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - wg.Wait() -} - -func TestHTTPSupervisedPool(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-http-supervised-pool.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &rpcPlugin.Plugin{}, - &logger.ZapLogger{}, - &server.Plugin{}, - &httpPlugin.Plugin{}, - &informer.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 1) - t.Run("HTTPEchoRunActivateWorker", echoHTTP2) - // bigger timeout to handle idle_ttl on slow systems - time.Sleep(time.Second * 10) - t.Run("HTTPInformerCompareWorkersTestBefore", informerTestBefore) - t.Run("HTTPEchoShouldBeNewWorker", echoHTTP2) - // worker should be destructed (idle_ttl) - t.Run("HTTPInformerCompareWorkersTestAfter", informerTestAfter) - - stopCh <- struct{}{} - wg.Wait() -} - -func echoHTTP2(t *testing.T) { - req, err := http.NewRequest("GET", "http://127.0.0.1:18888?hello=world", nil) - assert.NoError(t, err) - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - b, err := ioutil.ReadAll(r.Body) - assert.NoError(t, err) - assert.Equal(t, 201, r.StatusCode) - assert.Equal(t, "WORLD", string(b)) - - err = r.Body.Close() - assert.NoError(t, err) -} - -// get worker -// sleep -// supervisor destroy worker -// compare pid's -var workerPid int = 0 - -func informerTestBefore(t *testing.T) { - conn, err := net.Dial("tcp", "127.0.0.1:15432") - assert.NoError(t, err) - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - // WorkerList contains list of workers. - list := struct { - // Workers is list of workers. - Workers []process.State `json:"workers"` - }{} - - err = client.Call("informer.Workers", "http", &list) - assert.NoError(t, err) - assert.Len(t, list.Workers, 1) - // save the pid - workerPid = list.Workers[0].Pid -} - -func informerTestAfter(t *testing.T) { - conn, err := net.Dial("tcp", "127.0.0.1:15432") - assert.NoError(t, err) - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - // WorkerList contains list of workers. - list := struct { - // Workers is list of workers. - Workers []process.State `json:"workers"` - }{} - - assert.NotZero(t, workerPid) - - time.Sleep(time.Second * 5) - - err = client.Call("informer.Workers", "http", &list) - assert.NoError(t, err) - assert.Len(t, list.Workers, 1) - assert.NotEqual(t, workerPid, list.Workers[0].Pid) -} - -// get request and return body -func getHeader(url string, h map[string]string) (string, *http.Response, error) { - req, err := http.NewRequest("GET", url, bytes.NewBuffer(nil)) - if err != nil { - return "", nil, err - } - - for k, v := range h { - req.Header.Set(k, v) - } - - r, err := http.DefaultClient.Do(req) - if err != nil { - return "", nil, err - } - - b, err := ioutil.ReadAll(r.Body) - if err != nil { - return "", nil, err - } - - err = r.Body.Close() - if err != nil { - return "", nil, err - } - return string(b), r, err -} - -func makeConfig(rpcPort, httpPort, fcgiPort, sslAddress, redirect, http2Enabled, command string) []byte { - return []byte(fmt.Sprintf(` -rpc: - listen: tcp://127.0.0.1:%s - disabled: false - -server: - command: "%s" - user: "" - group: "" - relay: "pipes" - relay_timeout: "20s" - -http: - address: 127.0.0.1:%s - max_request_size: 1024 - middleware: [ "" ] - uploads: - forbid: [ ".php", ".exe", ".bat" ] - trusted_subnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] - pool: - num_workers: 2 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s - - ssl: - address: %s - redirect: %s - cert: fixtures/server.crt - key: fixtures/server.key - # rootCa: root.crt - fcgi: - address: tcp://0.0.0.0:%s - http2: - enabled: %s - h2c: false - max_concurrent_streams: 128 -logs: - mode: development - level: error -`, rpcPort, command, httpPort, sslAddress, redirect, fcgiPort, http2Enabled)) -} - -func TestHTTPBigRequestSize(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-big-req-size.yaml", - Prefix: "rr", - Type: "yaml", - } - - err = cont.RegisterAll( - cfg, - &logger.ZapLogger{}, - &server.Plugin{}, - &httpPlugin.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 2) - - t.Run("HTTPBigEcho10Mb", bigEchoHTTP) - - stopCh <- struct{}{} - wg.Wait() -} - -func bigEchoHTTP(t *testing.T) { - buf := make([]byte, 1024*1024*10) - - _, err := rand.Read(buf) - assert.NoError(t, err) - - bt := bytes.NewBuffer(buf) - - req, err := http.NewRequest("GET", "http://127.0.0.1:10085?hello=world", bt) - assert.NoError(t, err) - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - b, err := ioutil.ReadAll(r.Body) - assert.NoError(t, err) - assert.Equal(t, 400, r.StatusCode) - assert.Equal(t, "http_handler_max_size: request body max size is exceeded\n", string(b)) - - err = r.Body.Close() - assert.NoError(t, err) -} - -func TestStaticEtagPlugin(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-http-static.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &logger.ZapLogger{}, - &server.Plugin{}, - &httpPlugin.Plugin{}, - &gzip.Plugin{}, - &static.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second) - t.Run("ServeSampleEtag", serveStaticSampleEtag) - - stopCh <- struct{}{} - wg.Wait() -} - -func serveStaticSampleEtag(t *testing.T) { - // OK 200 response - b, r, err := get("http://127.0.0.1:21603/sample.txt") - assert.NoError(t, err) - assert.Equal(t, "sample\n", b) - assert.Equal(t, r.StatusCode, http.StatusOK) - etag := r.Header.Get("Etag") - - _ = r.Body.Close() - - // Should be 304 response with same etag - c := http.Client{ - Timeout: time.Second * 5, - } - - parsedURL, _ := url.Parse("http://127.0.0.1:21603/sample.txt") - - req := &http.Request{ - Method: http.MethodGet, - URL: parsedURL, - Header: map[string][]string{"If-None-Match": {etag}}, - } - - resp, err := c.Do(req) - assert.Nil(t, err) - assert.Equal(t, http.StatusNotModified, resp.StatusCode) - _ = resp.Body.Close() -} - -func TestStaticPluginSecurity(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-http-static-security.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &logger.ZapLogger{}, - &server.Plugin{}, - &httpPlugin.Plugin{}, - &gzip.Plugin{}, - &static.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second) - t.Run("ServeSampleNotAllowedPath", serveStaticSampleNotAllowedPath) - - stopCh <- struct{}{} - wg.Wait() -} - -func serveStaticSampleNotAllowedPath(t *testing.T) { - // Should be 304 response with same etag - c := http.Client{ - Timeout: time.Second * 5, - } - - parsedURL := &url.URL{ - Scheme: "http", - User: nil, - Host: "127.0.0.1:21603", - Path: "%2e%2e%/tests/", - } - - req := &http.Request{ - Method: http.MethodGet, - URL: parsedURL, - } - - resp, err := c.Do(req) - assert.Nil(t, err) - assert.Equal(t, http.StatusBadRequest, resp.StatusCode) - _ = resp.Body.Close() - - parsedURL = &url.URL{ - Scheme: "http", - User: nil, - Host: "127.0.0.1:21603", - Path: "%2e%2e%5ctests/", - } - - req = &http.Request{ - Method: http.MethodGet, - URL: parsedURL, - } - - resp, err = c.Do(req) - assert.Nil(t, err) - assert.Equal(t, http.StatusBadRequest, resp.StatusCode) - _ = resp.Body.Close() - - parsedURL = &url.URL{ - Scheme: "http", - User: nil, - Host: "127.0.0.1:21603", - Path: "..%2ftests/", - } - - req = &http.Request{ - Method: http.MethodGet, - URL: parsedURL, - } - - resp, err = c.Do(req) - assert.Nil(t, err) - assert.Equal(t, http.StatusBadRequest, resp.StatusCode) - _ = resp.Body.Close() - - parsedURL = &url.URL{ - Scheme: "http", - User: nil, - Host: "127.0.0.1:21603", - Path: "%2e%2e%2ftests/", - } - - req = &http.Request{ - Method: http.MethodGet, - URL: parsedURL, - } - - resp, err = c.Do(req) - assert.Nil(t, err) - assert.Equal(t, http.StatusBadRequest, resp.StatusCode) - _ = resp.Body.Close() - - _, r, err := get("http://127.0.0.1:21603/../../../../tests/../static/sample.txt") - assert.NoError(t, err) - assert.Equal(t, 403, r.StatusCode) - _ = r.Body.Close() -} - -func TestStaticPlugin(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-http-static.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &logger.ZapLogger{}, - &server.Plugin{}, - &httpPlugin.Plugin{}, - &gzip.Plugin{}, - &static.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second) - t.Run("ServeSample", serveStaticSample) - t.Run("StaticNotForbid", staticNotForbid) - t.Run("StaticHeaders", staticHeaders) - - stopCh <- struct{}{} - wg.Wait() -} - -func staticHeaders(t *testing.T) { - req, err := http.NewRequest("GET", "http://127.0.0.1:21603/client.php", nil) - if err != nil { - t.Fatal(err) - } - - resp, err := http.DefaultClient.Do(req) - if err != nil { - t.Fatal(err) - } - - if resp.Header.Get("Output") != "output-header" { - t.Fatal("can't find output header in response") - } - - b, err := ioutil.ReadAll(resp.Body) - if err != nil { - t.Fatal(err) - } - - defer func() { - _ = resp.Body.Close() - }() - - assert.Equal(t, all("../../../tests/client.php"), string(b)) - assert.Equal(t, all("../../../tests/client.php"), string(b)) -} - -func staticNotForbid(t *testing.T) { - b, r, err := get("http://127.0.0.1:21603/client.php") - assert.NoError(t, err) - assert.Equal(t, all("../../../tests/client.php"), b) - assert.Equal(t, all("../../../tests/client.php"), b) - _ = r.Body.Close() -} - -func serveStaticSample(t *testing.T) { - b, r, err := get("http://127.0.0.1:21603/sample.txt") - assert.NoError(t, err) - assert.Equal(t, "sample\n", b) - _ = r.Body.Close() -} - -func TestStaticDisabled_Error(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-http-static-disabled.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &logger.ZapLogger{}, - &server.Plugin{}, - &httpPlugin.Plugin{}, - &gzip.Plugin{}, - &static.Plugin{}, - ) - assert.NoError(t, err) - assert.Error(t, cont.Init()) -} - -func TestStaticFilesDisabled(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-http-static-files-disable.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &logger.ZapLogger{}, - &server.Plugin{}, - &httpPlugin.Plugin{}, - &gzip.Plugin{}, - &static.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second) - t.Run("StaticFilesDisabled", staticFilesDisabled) - - stopCh <- struct{}{} - wg.Wait() -} - -func staticFilesDisabled(t *testing.T) { - b, r, err := get("http://127.0.0.1:45877/client.php?hello=world") - if err != nil { - t.Fatal(err) - } - assert.Equal(t, "WORLD", b) - _ = r.Body.Close() -} - -func TestStaticFilesForbid(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-http-static-files.yaml", - Prefix: "rr", - } - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - - mockLogger.EXPECT().Debug("worker destructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("201 GET http://127.0.0.1:34653/http?hello=world", "remote", "127.0.0.1", "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Debug("201 GET http://127.0.0.1:34653/client.XXX?hello=world", "remote", "127.0.0.1", "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Debug("201 GET http://127.0.0.1:34653/client.php?hello=world", "remote", "127.0.0.1", "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Error("file open error", "error", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("no such file or directory", "error", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("possible path to dir provided").AnyTimes() - mockLogger.EXPECT().Debug("file extension is forbidden", gomock.Any(), gomock.Any()).AnyTimes() - mockLogger.EXPECT().Error(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() // placeholder for the workerlogerror - - err = cont.RegisterAll( - cfg, - mockLogger, - &server.Plugin{}, - &httpPlugin.Plugin{}, - &gzip.Plugin{}, - &static.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second) - t.Run("StaticTestFilesDir", staticTestFilesDir) - t.Run("StaticNotFound", staticNotFound) - t.Run("StaticFilesForbid", staticFilesForbid) - - stopCh <- struct{}{} - wg.Wait() -} - -func staticTestFilesDir(t *testing.T) { - b, r, err := get("http://127.0.0.1:34653/http?hello=world") - assert.NoError(t, err) - assert.Equal(t, "WORLD", b) - _ = r.Body.Close() -} - -func staticNotFound(t *testing.T) { - b, _, _ := get("http://127.0.0.1:34653/client.XXX?hello=world") //nolint:bodyclose - assert.Equal(t, "WORLD", b) -} - -func staticFilesForbid(t *testing.T) { - b, r, err := get("http://127.0.0.1:34653/client.php?hello=world") - if err != nil { - t.Fatal(err) - } - assert.Equal(t, "WORLD", b) - _ = r.Body.Close() -} - -func TestHTTPIssue659(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-issue659.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &rpcPlugin.Plugin{}, - &logger.ZapLogger{}, - &server.Plugin{}, - &httpPlugin.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 1) - t.Run("HTTPIssue659", echoIssue659) - - stopCh <- struct{}{} - - wg.Wait() -} - -func TestHTTPIPv6Long(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-http-ipv6.yaml", - Prefix: "rr", - } - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - mockLogger.EXPECT().Debug("worker destructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("Started RPC service", "address", "tcp://[0:0:0:0:0:0:0:1]:6001", "plugins", gomock.Any()).Times(1) - mockLogger.EXPECT().Debug("201 GET http://[0:0:0:0:0:0:0:1]:10684/?hello=world", "remote", "::1", "elapsed", gomock.Any()).Times(1) - - err = cont.RegisterAll( - cfg, - &rpcPlugin.Plugin{}, - mockLogger, - &server.Plugin{}, - &httpPlugin.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 1) - t.Run("HTTPEchoIPv6-long", echoHTTPIPv6Long) - - stopCh <- struct{}{} - - wg.Wait() -} - -func TestHTTPIPv6Short(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-http-ipv6-2.yaml", - Prefix: "rr", - } - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - mockLogger.EXPECT().Debug("worker destructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("Started RPC service", "address", "tcp://[::1]:6001", "plugins", gomock.Any()).Times(1) - mockLogger.EXPECT().Debug("201 GET http://[::1]:10784/?hello=world", "remote", "::1", "elapsed", gomock.Any()).Times(1) - - err = cont.RegisterAll( - cfg, - &rpcPlugin.Plugin{}, - mockLogger, - &server.Plugin{}, - &httpPlugin.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 1) - t.Run("HTTPEchoIPv6-short", echoHTTPIPv6Short) - - stopCh <- struct{}{} - - wg.Wait() -} - -func echoIssue659(t *testing.T) { - req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:32552", nil) - assert.NoError(t, err) - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - b, err := ioutil.ReadAll(r.Body) - assert.NoError(t, err) - assert.Empty(t, b) - assert.Equal(t, 444, r.StatusCode) - - err = r.Body.Close() - assert.NoError(t, err) -} - -func echoHTTP(t *testing.T) { - req, err := http.NewRequest("GET", "http://127.0.0.1:10084?hello=world", nil) - assert.NoError(t, err) - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - b, err := ioutil.ReadAll(r.Body) - assert.NoError(t, err) - assert.Equal(t, 201, r.StatusCode) - assert.Equal(t, "WORLD", string(b)) - - err = r.Body.Close() - assert.NoError(t, err) -} - -func echoHTTPIPv6Long(t *testing.T) { - req, err := http.NewRequest("GET", "http://[0:0:0:0:0:0:0:1]:10684?hello=world", nil) - assert.NoError(t, err) - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - b, err := ioutil.ReadAll(r.Body) - assert.NoError(t, err) - assert.Equal(t, 201, r.StatusCode) - assert.Equal(t, "WORLD", string(b)) - - err = r.Body.Close() - assert.NoError(t, err) -} - -func echoHTTPIPv6Short(t *testing.T) { - req, err := http.NewRequest("GET", "http://[::1]:10784?hello=world", nil) - assert.NoError(t, err) - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - b, err := ioutil.ReadAll(r.Body) - assert.NoError(t, err) - assert.Equal(t, 201, r.StatusCode) - assert.Equal(t, "WORLD", string(b)) - - err = r.Body.Close() - assert.NoError(t, err) -} - -func resetTest(t *testing.T) { - conn, err := net.Dial("tcp", "127.0.0.1:6001") - assert.NoError(t, err) - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - // WorkerList contains list of workers. - - var ret bool - err = client.Call("resetter.Reset", "http", &ret) - assert.NoError(t, err) - assert.True(t, ret) - ret = false - - var services []string - err = client.Call("resetter.List", nil, &services) - assert.NoError(t, err) - if services[0] != "http" { - t.Fatal("no enough services") - } -} - -func informerTest(t *testing.T) { - conn, err := net.Dial("tcp", "127.0.0.1:6001") - assert.NoError(t, err) - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - // WorkerList contains list of workers. - list := struct { - // Workers is list of workers. - Workers []process.State `json:"workers"` - }{} - - err = client.Call("informer.Workers", "http", &list) - assert.NoError(t, err) - assert.Len(t, list.Workers, 2) -} - -// HELPERS -func get(url string) (string, *http.Response, error) { - r, err := http.Get(url) //nolint:gosec - if err != nil { - return "", nil, err - } - - b, err := ioutil.ReadAll(r.Body) - if err != nil { - return "", nil, err - } - - err = r.Body.Close() - if err != nil { - return "", nil, err - } - - return string(b), r, err -} - -func all(fn string) string { - f, _ := os.Open(fn) - - b := new(bytes.Buffer) - _, err := io.Copy(b, f) - if err != nil { - return "" - } - - err = f.Close() - if err != nil { - return "" - } - - return b.String() -} diff --git a/tests/plugins/http/parse_test.go b/tests/plugins/http/parse_test.go deleted file mode 100644 index d75620f3..00000000 --- a/tests/plugins/http/parse_test.go +++ /dev/null @@ -1,54 +0,0 @@ -package http - -import ( - "testing" - - handler "github.com/spiral/roadrunner/v2/pkg/worker_handler" -) - -var samples = []struct { - in string - out []string -}{ - {"key", []string{"key"}}, - {"key[subkey]", []string{"key", "subkey"}}, - {"key[subkey]value", []string{"key", "subkey", "value"}}, - {"key[subkey][value]", []string{"key", "subkey", "value"}}, - {"key[subkey][value][]", []string{"key", "subkey", "value", ""}}, - {"key[subkey] [value][]", []string{"key", "subkey", "value", ""}}, - {"key [ subkey ] [ value ] [ ]", []string{"key", "subkey", "value", ""}}, -} - -func Test_FetchIndexes(t *testing.T) { - for i := 0; i < len(samples); i++ { - r := handler.FetchIndexes(samples[i].in) - if !same(r, samples[i].out) { - t.Errorf("got %q, want %q", r, samples[i].out) - } - } -} - -func BenchmarkConfig_FetchIndexes(b *testing.B) { - for _, tt := range samples { - for n := 0; n < b.N; n++ { - r := handler.FetchIndexes(tt.in) - if !same(r, tt.out) { - b.Fail() - } - } - } -} - -func same(in, out []string) bool { - if len(in) != len(out) { - return false - } - - for i, v := range in { - if v != out[i] { - return false - } - } - - return true -} diff --git a/tests/plugins/http/plugin1.go b/tests/plugins/http/plugin1.go deleted file mode 100644 index 0ec31211..00000000 --- a/tests/plugins/http/plugin1.go +++ /dev/null @@ -1,27 +0,0 @@ -package http - -import ( - "github.com/spiral/roadrunner/v2/plugins/config" -) - -type Plugin1 struct { - config config.Configurer -} - -func (p1 *Plugin1) Init(cfg config.Configurer) error { - p1.config = cfg - return nil -} - -func (p1 *Plugin1) Serve() chan error { - errCh := make(chan error, 1) - return errCh -} - -func (p1 *Plugin1) Stop() error { - return nil -} - -func (p1 *Plugin1) Name() string { - return "http_test.plugin1" -} diff --git a/tests/plugins/http/plugin_middleware.go b/tests/plugins/http/plugin_middleware.go deleted file mode 100644 index 9f04d6db..00000000 --- a/tests/plugins/http/plugin_middleware.go +++ /dev/null @@ -1,69 +0,0 @@ -package http - -import ( - "net/http" - - "github.com/spiral/roadrunner/v2/plugins/config" -) - -// PluginMiddleware test -type PluginMiddleware struct { - config config.Configurer -} - -// Init test -func (p *PluginMiddleware) Init(cfg config.Configurer) error { - p.config = cfg - return nil -} - -// Middleware test -func (p *PluginMiddleware) Middleware(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if r.URL.Path == "/halt" { - w.WriteHeader(500) - _, err := w.Write([]byte("halted")) - if err != nil { - panic("error writing the data to the http reply") - } - } else { - next.ServeHTTP(w, r) - } - }) -} - -// Name test -func (p *PluginMiddleware) Name() string { - return "pluginMiddleware" -} - -// PluginMiddleware2 test -type PluginMiddleware2 struct { - config config.Configurer -} - -// Init test -func (p *PluginMiddleware2) Init(cfg config.Configurer) error { - p.config = cfg - return nil -} - -// Middleware test -func (p *PluginMiddleware2) Middleware(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if r.URL.Path == "/boom" { - w.WriteHeader(555) - _, err := w.Write([]byte("boom")) - if err != nil { - panic("error writing the data to the http reply") - } - } else { - next.ServeHTTP(w, r) - } - }) -} - -// Name test -func (p *PluginMiddleware2) Name() string { - return "pluginMiddleware2" -} diff --git a/tests/plugins/http/response_test.go b/tests/plugins/http/response_test.go deleted file mode 100644 index f754429d..00000000 --- a/tests/plugins/http/response_test.go +++ /dev/null @@ -1,165 +0,0 @@ -package http - -import ( - "bytes" - "errors" - "net/http" - "testing" - - "github.com/spiral/roadrunner/v2/pkg/payload" - handler "github.com/spiral/roadrunner/v2/pkg/worker_handler" - "github.com/stretchr/testify/assert" -) - -type testWriter struct { - h http.Header - buf bytes.Buffer - wroteHeader bool - code int - err error - pushErr error - pushes []string -} - -func (tw *testWriter) Header() http.Header { return tw.h } - -func (tw *testWriter) Write(p []byte) (int, error) { - if !tw.wroteHeader { - tw.WriteHeader(http.StatusOK) - } - - n, e := tw.buf.Write(p) - if e == nil { - e = tw.err - } - - return n, e -} - -func (tw *testWriter) WriteHeader(code int) { tw.wroteHeader = true; tw.code = code } - -func (tw *testWriter) Push(target string, opts *http.PushOptions) error { - tw.pushes = append(tw.pushes, target) - - return tw.pushErr -} - -func TestNewResponse_Error(t *testing.T) { - r, err := handler.NewResponse(&payload.Payload{Context: []byte(`invalid payload`)}) - assert.Error(t, err) - assert.Nil(t, r) -} - -func TestNewResponse_Write(t *testing.T) { - r, err := handler.NewResponse(&payload.Payload{ - Context: []byte(`{"headers":{"key":["value"]},"status": 301}`), - Body: []byte(`sample body`), - }) - - assert.NoError(t, err) - assert.NotNil(t, r) - - w := &testWriter{h: http.Header(make(map[string][]string))} - assert.NoError(t, r.Write(w)) - - assert.Equal(t, 301, w.code) - assert.Equal(t, "value", w.h.Get("key")) - assert.Equal(t, "sample body", w.buf.String()) -} - -func TestNewResponse_Stream(t *testing.T) { - r, err := handler.NewResponse(&payload.Payload{ - Context: []byte(`{"headers":{"key":["value"]},"status": 301}`), - }) - - // r is pointer, so, it might be nil - if r == nil { - t.Fatal("response is nil") - return - } - - r.Body = new(bytes.Buffer) - r.Body.(*bytes.Buffer).WriteString("hello world") - - assert.NoError(t, err) - assert.NotNil(t, r) - - w := &testWriter{h: http.Header(make(map[string][]string))} - assert.NoError(t, r.Write(w)) - - assert.Equal(t, 301, w.code) - assert.Equal(t, "value", w.h.Get("key")) - assert.Equal(t, "hello world", w.buf.String()) -} - -func TestNewResponse_StreamError(t *testing.T) { - r, err := handler.NewResponse(&payload.Payload{ - Context: []byte(`{"headers":{"key":["value"]},"status": 301}`), - }) - - // r is pointer, so, it might be nil - if r == nil { - t.Fatal("response is nil") - return - } - - r.Body = &bytes.Buffer{} - r.Body.(*bytes.Buffer).WriteString("hello world") - - assert.NoError(t, err) - assert.NotNil(t, r) - - w := &testWriter{h: http.Header(make(map[string][]string)), err: errors.New("error")} - assert.Error(t, r.Write(w)) -} - -func TestWrite_HandlesPush(t *testing.T) { - r, err := handler.NewResponse(&payload.Payload{ - Context: []byte(`{"headers":{"Http2-Push":["/test.js"],"content-type":["text/html"]},"status": 200}`), - }) - - assert.NoError(t, err) - assert.NotNil(t, r) - - w := &testWriter{h: http.Header(make(map[string][]string))} - assert.NoError(t, r.Write(w)) - - assert.Nil(t, w.h["Http2-Push"]) - assert.Equal(t, []string{"/test.js"}, w.pushes) -} - -func TestWrite_HandlesTrailers(t *testing.T) { - r, err := handler.NewResponse(&payload.Payload{ - Context: []byte(`{"headers":{"Trailer":["foo, bar", "baz"],"foo":["test"],"bar":["demo"]},"status": 200}`), - }) - - assert.NoError(t, err) - assert.NotNil(t, r) - - w := &testWriter{h: http.Header(make(map[string][]string))} - assert.NoError(t, r.Write(w)) - - assert.Nil(t, w.h[handler.TrailerHeaderKey]) - assert.Nil(t, w.h["foo"]) //nolint:staticcheck - assert.Nil(t, w.h["baz"]) //nolint:staticcheck - - assert.Equal(t, "test", w.h.Get("Trailer:foo")) - assert.Equal(t, "demo", w.h.Get("Trailer:bar")) -} - -func TestWrite_HandlesHandlesWhitespacesInTrailer(t *testing.T) { - r, err := handler.NewResponse(&payload.Payload{ - Context: []byte( - `{"headers":{"Trailer":["foo\t,bar , baz"],"foo":["a"],"bar":["b"],"baz":["c"]},"status": 200}`), - }) - - assert.NoError(t, err) - assert.NotNil(t, r) - - w := &testWriter{h: http.Header(make(map[string][]string))} - assert.NoError(t, r.Write(w)) - - assert.Equal(t, "a", w.h.Get("Trailer:foo")) - assert.Equal(t, "b", w.h.Get("Trailer:bar")) - assert.Equal(t, "c", w.h.Get("Trailer:baz")) -} diff --git a/tests/plugins/http/uploads_config_test.go b/tests/plugins/http/uploads_config_test.go deleted file mode 100644 index 4f99b621..00000000 --- a/tests/plugins/http/uploads_config_test.go +++ /dev/null @@ -1,26 +0,0 @@ -package http - -import ( - "os" - "testing" - - "github.com/spiral/roadrunner/v2/plugins/http/config" - "github.com/stretchr/testify/assert" -) - -func TestFsConfig_Forbids(t *testing.T) { - cfg := config.Uploads{Forbid: []string{".php"}} - - assert.True(t, cfg.Forbids("index.php")) - assert.True(t, cfg.Forbids("index.PHP")) - assert.True(t, cfg.Forbids("phpadmin/index.bak.php")) - assert.False(t, cfg.Forbids("index.html")) -} - -func TestFsConfig_TmpFallback(t *testing.T) { - cfg := config.Uploads{Dir: "test"} - assert.Equal(t, "test", cfg.TmpDir()) - - cfg = config.Uploads{Dir: ""} - assert.Equal(t, os.TempDir(), cfg.TmpDir()) -} diff --git a/tests/plugins/http/uploads_test.go b/tests/plugins/http/uploads_test.go deleted file mode 100644 index 54f2bead..00000000 --- a/tests/plugins/http/uploads_test.go +++ /dev/null @@ -1,433 +0,0 @@ -package http - -import ( - "bytes" - "context" - "crypto/sha512" - "encoding/hex" - "fmt" - "io" - "io/ioutil" - "mime/multipart" - "net/http" - "os" - "os/exec" - "testing" - "time" - - j "github.com/json-iterator/go" - poolImpl "github.com/spiral/roadrunner/v2/pkg/pool" - "github.com/spiral/roadrunner/v2/pkg/transport/pipe" - handler "github.com/spiral/roadrunner/v2/pkg/worker_handler" - "github.com/spiral/roadrunner/v2/plugins/http/config" - "github.com/stretchr/testify/assert" -) - -var json = j.ConfigCompatibleWithStandardLibrary - -const testFile = "uploads_test.go" - -func TestHandler_Upload_File(t *testing.T) { - pool, err := poolImpl.Initialize(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../http/client.php", "upload", "pipes") }, - pipe.NewPipeFactory(), - &poolImpl.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - - h, err := handler.NewHandler(1024, 500, config.Uploads{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, pool) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":8021", Handler: h} - defer func() { - errS := hs.Shutdown(context.Background()) - if errS != nil { - t.Errorf("error during the shutdown: error %v", errS) - } - }() - - go func() { - errL := hs.ListenAndServe() - if errL != nil && errL != http.ErrServerClosed { - t.Errorf("error listening the interface: error %v", errL) - } - }() - time.Sleep(time.Millisecond * 10) - - var mb bytes.Buffer - w := multipart.NewWriter(&mb) - - f := mustOpen(testFile) - defer func() { - errC := f.Close() - if errC != nil { - t.Errorf("failed to close a file: error %v", errC) - } - }() - fw, err := w.CreateFormFile("upload", f.Name()) - assert.NotNil(t, fw) - assert.NoError(t, err) - _, err = io.Copy(fw, f) - if err != nil { - t.Errorf("error copying the file: error %v", err) - } - - err = w.Close() - if err != nil { - t.Errorf("error closing the file: error %v", err) - } - - req, err := http.NewRequest("POST", "http://127.0.0.1"+hs.Addr, &mb) - assert.NoError(t, err) - - req.Header.Set("Content-Type", w.FormDataContentType()) - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - defer func() { - errC := r.Body.Close() - if errC != nil { - t.Errorf("error closing the Body: error %v", errC) - } - }() - - b, err := ioutil.ReadAll(r.Body) - assert.NoError(t, err) - - assert.NoError(t, err) - assert.Equal(t, 200, r.StatusCode) - - fs := fileString(testFile, 0, "application/octet-stream") - - assert.Equal(t, `{"upload":`+fs+`}`, string(b)) -} - -func TestHandler_Upload_NestedFile(t *testing.T) { - pool, err := poolImpl.Initialize(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../http/client.php", "upload", "pipes") }, - pipe.NewPipeFactory(), - &poolImpl.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - - h, err := handler.NewHandler(1024, 500, config.Uploads{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, pool) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":8021", Handler: h} - defer func() { - errS := hs.Shutdown(context.Background()) - if errS != nil { - t.Errorf("error during the shutdown: error %v", errS) - } - }() - - go func() { - errL := hs.ListenAndServe() - if errL != nil && errL != http.ErrServerClosed { - t.Errorf("error listening the interface: error %v", errL) - } - }() - time.Sleep(time.Millisecond * 10) - - var mb bytes.Buffer - w := multipart.NewWriter(&mb) - - f := mustOpen(testFile) - defer func() { - errC := hs.Close() - if errC != nil { - t.Errorf("failed to close a file: error %v", errC) - } - }() - fw, err := w.CreateFormFile("upload[x][y][z][]", f.Name()) - assert.NotNil(t, fw) - assert.NoError(t, err) - _, err = io.Copy(fw, f) - if err != nil { - t.Errorf("error copying the file: error %v", err) - } - - err = w.Close() - if err != nil { - t.Errorf("error closing the file: error %v", err) - } - - req, err := http.NewRequest("POST", "http://127.0.0.1"+hs.Addr, &mb) - assert.NoError(t, err) - - req.Header.Set("Content-Type", w.FormDataContentType()) - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - defer func() { - errC := r.Body.Close() - if errC != nil { - t.Errorf("error closing the Body: error %v", errC) - } - }() - - b, err := ioutil.ReadAll(r.Body) - assert.NoError(t, err) - - assert.NoError(t, err) - assert.Equal(t, 200, r.StatusCode) - - fs := fileString(testFile, 0, "application/octet-stream") - - assert.Equal(t, `{"upload":{"x":{"y":{"z":[`+fs+`]}}}}`, string(b)) -} - -func TestHandler_Upload_File_NoTmpDir(t *testing.T) { - pool, err := poolImpl.Initialize(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../http/client.php", "upload", "pipes") }, - pipe.NewPipeFactory(), - &poolImpl.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - - h, err := handler.NewHandler(1024, 500, config.Uploads{ - Dir: "-------", - Forbid: []string{}, - }, nil, pool) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":8021", Handler: h} - defer func() { - errS := hs.Shutdown(context.Background()) - if errS != nil { - t.Errorf("error during the shutdown: error %v", err) - } - }() - - go func() { - err = hs.ListenAndServe() - if err != nil && err != http.ErrServerClosed { - t.Errorf("error listening the interface: error %v", err) - } - }() - time.Sleep(time.Millisecond * 10) - - var mb bytes.Buffer - w := multipart.NewWriter(&mb) - - f := mustOpen(testFile) - defer func() { - errC := hs.Close() - if errC != nil { - t.Errorf("failed to close a file: error %v", errC) - } - }() - fw, err := w.CreateFormFile("upload", f.Name()) - assert.NotNil(t, fw) - assert.NoError(t, err) - _, err = io.Copy(fw, f) - if err != nil { - t.Errorf("error copying the file: error %v", err) - } - - err = w.Close() - if err != nil { - t.Errorf("error closing the file: error %v", err) - } - - req, err := http.NewRequest("POST", "http://127.0.0.1"+hs.Addr, &mb) - assert.NoError(t, err) - - req.Header.Set("Content-Type", w.FormDataContentType()) - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - defer func() { - errC := r.Body.Close() - if errC != nil { - t.Errorf("error closing the Body: error %v", errC) - } - }() - - b, err := ioutil.ReadAll(r.Body) - assert.NoError(t, err) - - assert.NoError(t, err) - assert.Equal(t, 200, r.StatusCode) - - fs := fileString(testFile, 6, "application/octet-stream") - - assert.Equal(t, `{"upload":`+fs+`}`, string(b)) -} - -func TestHandler_Upload_File_Forbids(t *testing.T) { - pool, err := poolImpl.Initialize(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../http/client.php", "upload", "pipes") }, - pipe.NewPipeFactory(), - &poolImpl.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - - h, err := handler.NewHandler(1024, 500, config.Uploads{ - Dir: os.TempDir(), - Forbid: []string{".go"}, - }, nil, pool) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":8021", Handler: h} - defer func() { - errS := hs.Shutdown(context.Background()) - if errS != nil { - t.Errorf("error during the shutdown: error %v", err) - } - }() - - go func() { - err = hs.ListenAndServe() - if err != nil && err != http.ErrServerClosed { - t.Errorf("error listening the interface: error %v", err) - } - }() - time.Sleep(time.Millisecond * 10) - - var mb bytes.Buffer - w := multipart.NewWriter(&mb) - - f := mustOpen(testFile) - defer func() { - errC := hs.Close() - if errC != nil { - t.Errorf("failed to close a file: error %v", errC) - } - }() - fw, err := w.CreateFormFile("upload", f.Name()) - assert.NotNil(t, fw) - assert.NoError(t, err) - _, err = io.Copy(fw, f) - if err != nil { - t.Errorf("error copying the file: error %v", err) - } - - err = w.Close() - if err != nil { - t.Errorf("error closing the file: error %v", err) - } - - req, err := http.NewRequest("POST", "http://127.0.0.1"+hs.Addr, &mb) - assert.NoError(t, err) - - req.Header.Set("Content-Type", w.FormDataContentType()) - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - defer func() { - errC := r.Body.Close() - if errC != nil { - t.Errorf("error closing the Body: error %v", errC) - } - }() - - b, err := ioutil.ReadAll(r.Body) - assert.NoError(t, err) - - assert.NoError(t, err) - assert.Equal(t, 200, r.StatusCode) - - fs := fileString(testFile, 8, "application/octet-stream") - - assert.Equal(t, `{"upload":`+fs+`}`, string(b)) -} - -func Test_FileExists(t *testing.T) { - assert.True(t, exists(testFile)) - assert.False(t, exists("uploads_test.")) -} - -func mustOpen(f string) *os.File { - r, err := os.Open(f) - if err != nil { - panic(err) - } - return r -} - -type fInfo struct { - Name string `json:"name"` - Size int64 `json:"size"` - Mime string `json:"mime"` - Error int `json:"error"` - Sha512 string `json:"sha512,omitempty"` -} - -func fileString(f string, errNo int, mime string) string { - s, err := os.Stat(f) - if err != nil { - fmt.Println(fmt.Errorf("error stat the file, error: %v", err)) - } - - ff, err := os.Open(f) - if err != nil { - fmt.Println(fmt.Errorf("error opening the file, error: %v", err)) - } - - defer func() { - er := ff.Close() - if er != nil { - fmt.Println(fmt.Errorf("error closing the file, error: %v", er)) - } - }() - - h := sha512.New() - _, err = io.Copy(h, ff) - if err != nil { - fmt.Println(fmt.Errorf("error copying the file, error: %v", err)) - } - - v := &fInfo{ - Name: s.Name(), - Size: s.Size(), - Error: errNo, - Mime: mime, - Sha512: hex.EncodeToString(h.Sum(nil)), - } - - if errNo != 0 { - v.Sha512 = "" - v.Size = 0 - } - - r, err := json.Marshal(v) - if err != nil { - fmt.Println(fmt.Errorf("error marshaling fInfo, error: %v", err)) - } - return string(r) -} - -// exists if file exists. -func exists(path string) bool { - if _, err := os.Stat(path); os.IsNotExist(err) { - return false - } - return true -} diff --git a/tests/plugins/informer/.rr-informer.yaml b/tests/plugins/informer/.rr-informer.yaml deleted file mode 100644 index 94c9a856..00000000 --- a/tests/plugins/informer/.rr-informer.yaml +++ /dev/null @@ -1,15 +0,0 @@ -server: - command: "php ../../http/client.php echo pipes" - user: "" - group: "" - env: - - RR_CONFIG: "/some/place/on/the/C134" - - RR_CONFIG: "C138" - relay: "pipes" - relay_timeout: "20s" - -rpc: - listen: tcp://127.0.0.1:6001 -logs: - mode: development - level: error diff --git a/tests/plugins/informer/informer_test.go b/tests/plugins/informer/informer_test.go deleted file mode 100644 index c3b5c6a6..00000000 --- a/tests/plugins/informer/informer_test.go +++ /dev/null @@ -1,136 +0,0 @@ -package informer - -import ( - "net" - "net/rpc" - "os" - "os/signal" - "sync" - "syscall" - "testing" - "time" - - endure "github.com/spiral/endure/pkg/container" - goridgeRpc "github.com/spiral/goridge/v3/pkg/rpc" - "github.com/spiral/roadrunner/v2/pkg/state/process" - "github.com/spiral/roadrunner/v2/plugins/config" - "github.com/spiral/roadrunner/v2/plugins/informer" - "github.com/spiral/roadrunner/v2/plugins/logger" - rpcPlugin "github.com/spiral/roadrunner/v2/plugins/rpc" - "github.com/spiral/roadrunner/v2/plugins/server" - "github.com/stretchr/testify/assert" -) - -func TestInformerInit(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - if err != nil { - t.Fatal(err) - } - - cfg := &config.Viper{ - Path: ".rr-informer.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &server.Plugin{}, - &logger.ZapLogger{}, - &informer.Plugin{}, - &rpcPlugin.Plugin{}, - &Plugin1{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - stopCh := make(chan struct{}, 1) - - wg := &sync.WaitGroup{} - wg.Add(1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - return - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second) - t.Run("InformerWorkersRpcTest", informerWorkersRPCTest) - t.Run("InformerListRpcTest", informerListRPCTest) - t.Run("InformerPluginWithoutWorkersRpcTest", informerPluginWOWorkersRPCTest) - - stopCh <- struct{}{} - wg.Wait() -} - -func informerPluginWOWorkersRPCTest(t *testing.T) { - conn, err := net.Dial("tcp", "127.0.0.1:6001") - assert.NoError(t, err) - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - // WorkerList contains list of workers. - list := struct { - // Workers is list of workers. - Workers []process.State `json:"workers"` - }{} - - err = client.Call("informer.Workers", "informer.config", &list) - assert.NoError(t, err) - assert.Len(t, list.Workers, 0) -} - -func informerWorkersRPCTest(t *testing.T) { - conn, err := net.Dial("tcp", "127.0.0.1:6001") - assert.NoError(t, err) - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - // WorkerList contains list of workers. - list := struct { - // Workers is list of workers. - Workers []process.State `json:"workers"` - }{} - - err = client.Call("informer.Workers", "informer.plugin1", &list) - assert.NoError(t, err) - assert.Len(t, list.Workers, 10) -} - -func informerListRPCTest(t *testing.T) { - conn, err := net.Dial("tcp", "127.0.0.1:6001") - assert.NoError(t, err) - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - // WorkerList contains list of workers. - list := make([]string, 0, 5) - // Plugins which are expected to be in the list - expected := []string{"rpc", "logs", "informer.plugin1", "config", "server"} - - err = client.Call("informer.List", true, &list) - assert.NoError(t, err) - assert.ElementsMatch(t, list, expected) -} diff --git a/tests/plugins/informer/test_plugin.go b/tests/plugins/informer/test_plugin.go deleted file mode 100644 index 21897f40..00000000 --- a/tests/plugins/informer/test_plugin.go +++ /dev/null @@ -1,71 +0,0 @@ -package informer - -import ( - "context" - "time" - - "github.com/spiral/roadrunner/v2/pkg/pool" - "github.com/spiral/roadrunner/v2/pkg/state/process" - "github.com/spiral/roadrunner/v2/plugins/config" - "github.com/spiral/roadrunner/v2/plugins/server" -) - -var testPoolConfig = &pool.Config{ - NumWorkers: 10, - MaxJobs: 100, - AllocateTimeout: time.Second * 10, - DestroyTimeout: time.Second * 10, - Supervisor: &pool.SupervisorConfig{ - WatchTick: 60 * time.Second, - TTL: 1000 * time.Second, - IdleTTL: 10 * time.Second, - ExecTTL: 10 * time.Second, - MaxWorkerMemory: 1000, - }, -} - -// Gauge ////////////// -type Plugin1 struct { - config config.Configurer - server server.Server -} - -func (p1 *Plugin1) Init(cfg config.Configurer, server server.Server) error { - p1.config = cfg - p1.server = server - return nil -} - -func (p1 *Plugin1) Serve() chan error { - errCh := make(chan error, 1) - return errCh -} - -func (p1 *Plugin1) Stop() error { - return nil -} - -func (p1 *Plugin1) Name() string { - return "informer.plugin1" -} - -func (p1 *Plugin1) Available() {} - -func (p1 *Plugin1) Workers() []*process.State { - p, err := p1.server.NewWorkerPool(context.Background(), testPoolConfig, nil) - if err != nil { - panic(err) - } - - ps := make([]*process.State, 0, len(p.Workers())) - workers := p.Workers() - for i := 0; i < len(workers); i++ { - state, err := process.WorkerProcessState(workers[i]) - if err != nil { - return nil - } - ps = append(ps, state) - } - - return ps -} diff --git a/tests/plugins/jobs/amqp/.rr-amqp-declare.yaml b/tests/plugins/jobs/amqp/.rr-amqp-declare.yaml deleted file mode 100644 index f9a7308b..00000000 --- a/tests/plugins/jobs/amqp/.rr-amqp-declare.yaml +++ /dev/null @@ -1,24 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../jobs_ok.php" - relay: "pipes" - relay_timeout: "20s" - -amqp: - addr: amqp://guest:[email protected]:5672/ - -logs: - level: debug - encoding: console - mode: development - -jobs: - num_pollers: 10 - pipeline_size: 100000 - pool: - num_workers: 10 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s diff --git a/tests/plugins/jobs/amqp/.rr-amqp-init.yaml b/tests/plugins/jobs/amqp/.rr-amqp-init.yaml deleted file mode 100644 index 43840545..00000000 --- a/tests/plugins/jobs/amqp/.rr-amqp-init.yaml +++ /dev/null @@ -1,55 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../jobs_ok.php" - relay: "pipes" - relay_timeout: "20s" - -amqp: - addr: amqp://guest:[email protected]:5672/ - -logs: - level: debug - encoding: console - mode: development - -jobs: - num_pollers: 1 - pipeline_size: 100000 - timeout: 1 - pool: - num_workers: 10 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s - - pipelines: - test-1: - driver: amqp - prefetch: 100 - queue: test-1-queue - priority: 1 - exchange: default - exchange_type: direct - routing_key: test-1 - exclusive: false - multiple_ack: false - requeue_on_fail: false - - test-2: - driver: amqp - prefetch: 100 - queue: test-2-queue - priority: 2 - exchange: default - exchange_type: direct - routing_key: test-2 - exclusive: false - multiple_ack: false - requeue_on_fail: false - - - # list of pipelines to be consumed by the server, keep empty if you want to start consuming manually - consume: [ "test-1", "test-2" ] - diff --git a/tests/plugins/jobs/amqp/.rr-amqp-jobs-err.yaml b/tests/plugins/jobs/amqp/.rr-amqp-jobs-err.yaml deleted file mode 100644 index 79493d96..00000000 --- a/tests/plugins/jobs/amqp/.rr-amqp-jobs-err.yaml +++ /dev/null @@ -1,24 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../jobs_err.php" - relay: "pipes" - relay_timeout: "20s" - -amqp: - addr: amqp://guest:[email protected]:5672/ - -logs: - level: debug - encoding: console - mode: development - -jobs: - num_pollers: 1 - pipeline_size: 100000 - pool: - num_workers: 10 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s diff --git a/tests/plugins/jobs/amqp/.rr-no-global.yaml b/tests/plugins/jobs/amqp/.rr-no-global.yaml deleted file mode 100644 index 1b01eb73..00000000 --- a/tests/plugins/jobs/amqp/.rr-no-global.yaml +++ /dev/null @@ -1,47 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../client.php echo pipes" - relay: "pipes" - relay_timeout: "20s" - -logs: - level: error - mode: development - -jobs: - # num logical cores by default - num_pollers: 10 - # 1mi by default - pipeline_size: 100000 - # worker pool configuration - pool: - num_workers: 10 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s - - # list of broker pipelines associated with endpoints - pipelines: - test-1: - driver: amqp - priority: 1 - pipeline_size: 100 - queue: test-1-queue - exchange: default - exchange_type: direct - routing_key: test - - test-2: - driver: amqp - priority: 2 - pipeline_size: 100 - queue: test-2-queue - exchange: default - exchange_type: direct - routing_key: test-2 - - # list of pipelines to be consumed by the server, keep empty if you want to start consuming manually - consume: [ "test-1", "test-2" ] - diff --git a/tests/plugins/jobs/beanstalk/.rr-beanstalk-declare.yaml b/tests/plugins/jobs/beanstalk/.rr-beanstalk-declare.yaml deleted file mode 100644 index 3555ef96..00000000 --- a/tests/plugins/jobs/beanstalk/.rr-beanstalk-declare.yaml +++ /dev/null @@ -1,27 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../jobs_ok.php" - relay: "pipes" - relay_timeout: "20s" - -beanstalk: - # beanstalk address - addr: tcp://127.0.0.1:11300 - # connect timeout - timeout: 10s - -logs: - level: debug - encoding: console - mode: development - -jobs: - num_pollers: 10 - pipeline_size: 100000 - pool: - num_workers: 10 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s diff --git a/tests/plugins/jobs/beanstalk/.rr-beanstalk-init.yaml b/tests/plugins/jobs/beanstalk/.rr-beanstalk-init.yaml deleted file mode 100644 index cf9069a8..00000000 --- a/tests/plugins/jobs/beanstalk/.rr-beanstalk-init.yaml +++ /dev/null @@ -1,45 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../jobs_ok.php" - relay: "pipes" - relay_timeout: "20s" - -beanstalk: - addr: tcp://127.0.0.1:11300 - timeout: 10s - -logs: - level: info - encoding: console - mode: development - -jobs: - num_pollers: 10 - pipeline_size: 100000 - pool: - num_workers: 10 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s - - pipelines: - test-1: - driver: beanstalk - priority: 11 - tube_priority: 1 - tube: default-1 - reserve_timeout: 10s - - test-2: - driver: beanstalk - priority: 11 - tube_priority: 3 - tube: default-2 - reserve_timeout: 10s - - - # list of pipelines to be consumed by the server, keep empty if you want to start consuming manually - consume: [ "test-1", "test-2" ] - diff --git a/tests/plugins/jobs/beanstalk/.rr-beanstalk-jobs-err.yaml b/tests/plugins/jobs/beanstalk/.rr-beanstalk-jobs-err.yaml deleted file mode 100644 index 71b51dce..00000000 --- a/tests/plugins/jobs/beanstalk/.rr-beanstalk-jobs-err.yaml +++ /dev/null @@ -1,25 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../jobs_err.php" - relay: "pipes" - relay_timeout: "20s" - -beanstalk: - addr: tcp://127.0.0.1:11300 - timeout: 10s - -logs: - level: debug - encoding: console - mode: development - -jobs: - num_pollers: 10 - pipeline_size: 100000 - pool: - num_workers: 10 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s diff --git a/tests/plugins/jobs/beanstalk/.rr-no-global.yaml b/tests/plugins/jobs/beanstalk/.rr-no-global.yaml deleted file mode 100644 index 92d090d4..00000000 --- a/tests/plugins/jobs/beanstalk/.rr-no-global.yaml +++ /dev/null @@ -1,34 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../jobs_ok.php" - relay: "pipes" - relay_timeout: "20s" - -logs: - level: error - mode: development - -jobs: - num_pollers: 10 - pipeline_size: 100000 - pool: - num_workers: 10 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s - - # list of broker pipelines associated with endpoints - pipelines: - test-1: - driver: beanstalk - priority: 11 - tube_priority: 1 - tube: default-1 - reserve_timeout: 10s - - consume: [ "test-1" ] - -endure: - log_level: debug diff --git a/tests/plugins/jobs/boltdb/.rr-boltdb-declare.yaml b/tests/plugins/jobs/boltdb/.rr-boltdb-declare.yaml deleted file mode 100644 index cdc2655f..00000000 --- a/tests/plugins/jobs/boltdb/.rr-boltdb-declare.yaml +++ /dev/null @@ -1,24 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../jobs_ok.php" - relay: "pipes" - relay_timeout: "20s" - -boltdb: - permissions: 0777 - -logs: - level: debug - encoding: console - mode: development - -jobs: - num_pollers: 10 - pipeline_size: 100000 - pool: - num_workers: 10 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s diff --git a/tests/plugins/jobs/boltdb/.rr-boltdb-init.yaml b/tests/plugins/jobs/boltdb/.rr-boltdb-init.yaml deleted file mode 100644 index 804db543..00000000 --- a/tests/plugins/jobs/boltdb/.rr-boltdb-init.yaml +++ /dev/null @@ -1,43 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../jobs_ok.php" - relay: "pipes" - relay_timeout: "20s" - -boltdb: - permissions: 0777 - -logs: - level: debug - encoding: console - mode: development - -jobs: - num_pollers: 1 - pipeline_size: 100000 - timeout: 1 - pool: - num_workers: 10 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s - - pipelines: - test-1: - driver: boltdb - prefetch: 100 - file: "rr1.db" - priority: 1 - - test-2: - driver: boltdb - prefetch: 100 - file: "rr2.db" - priority: 2 - - - # list of pipelines to be consumed by the server, keep empty if you want to start consuming manually - consume: [ "test-1", "test-2" ] - diff --git a/tests/plugins/jobs/boltdb/.rr-boltdb-jobs-err.yaml b/tests/plugins/jobs/boltdb/.rr-boltdb-jobs-err.yaml deleted file mode 100644 index d375a9a5..00000000 --- a/tests/plugins/jobs/boltdb/.rr-boltdb-jobs-err.yaml +++ /dev/null @@ -1,24 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../jobs_err.php" - relay: "pipes" - relay_timeout: "20s" - -boltdb: - permissions: 0777 - -logs: - level: debug - encoding: console - mode: development - -jobs: - num_pollers: 1 - pipeline_size: 100000 - pool: - num_workers: 10 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s diff --git a/tests/plugins/jobs/boltdb/.rr-no-global.yaml b/tests/plugins/jobs/boltdb/.rr-no-global.yaml deleted file mode 100644 index 54aaf3c6..00000000 --- a/tests/plugins/jobs/boltdb/.rr-no-global.yaml +++ /dev/null @@ -1,41 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../client.php echo pipes" - relay: "pipes" - relay_timeout: "20s" - -logs: - level: error - mode: development - -jobs: - # num logical cores by default - num_pollers: 10 - # 1mi by default - pipeline_size: 100000 - # worker pool configuration - pool: - num_workers: 10 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s - - # list of broker pipelines associated with endpoints - pipelines: - test-1: - driver: boltdb - prefetch: 100 - file: "rr1.db" - priority: 1 - - test-2: - driver: boltdb - prefetch: 100 - file: "rr2.db" - priority: 1 - - # list of pipelines to be consumed by the server, keep empty if you want to start consuming manually - consume: [ "test-1", "test-2" ] - diff --git a/tests/plugins/jobs/configs/.rr-jobs-init.yaml b/tests/plugins/jobs/configs/.rr-jobs-init.yaml deleted file mode 100644 index 9813344e..00000000 --- a/tests/plugins/jobs/configs/.rr-jobs-init.yaml +++ /dev/null @@ -1,112 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../client.php echo pipes" - relay: "pipes" - relay_timeout: "20s" - -amqp: - addr: amqp://guest:[email protected]:5672/ - -# beanstalk configuration -# -beanstalk: - # beanstalk address - addr: tcp://127.0.0.1:11300 - # connect timeout - timeout: 10s - -# amazon sqs configuration -# General section -sqs: - key: api-key - secret: api-secret - region: us-west-1 - endpoint: http://127.0.0.1:9324 - -logs: - level: info - encoding: console - mode: development - -jobs: - # num logical cores by default - num_pollers: 10 - # 1mi by default - pipeline_size: 100000 - # worker pool configuration - pool: - num_workers: 10 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s - - # list of broker pipelines associated with endpoints - pipelines: - test-local: - driver: memory - priority: 10 - prefetch: 10000 - - test-local-2: - driver: memory - priority: 1 - prefetch: 10000 - - test-local-3: - driver: memory - priority: 2 - prefetch: 10000 - - test-1: - driver: amqp - # QoS - prefetch: 1000000 - # Queue name - queue: test-1-queue - # Pipeline jobs priority, 1 - highest - priority: 1 - # Exchange - exchange: default - # Exchange type: direct, topic, fanout - exchange_type: direct - # Routing key for the queue - routing_key: test - # Declare a queue exclusive at the exchange - exclusive: false - # When multiple is true, this delivery and all prior unacknowledged deliveries - # on the same channel will be acknowledged. This is useful for batch processing - # of deliveries - multiple_ack: false - # When multiple is true, this delivery and all prior unacknowledged deliveries - # on the same channel will be acknowledged. This is useful for batch processing - # of deliveries - requeue_on_fail: false - - test-2-amqp: - driver: amqp - priority: 2 - prefetch: 1000000 - queue: test-2-queue - exchange: default - exchange_type: direct - routing_key: test-2 - - test-2: - driver: beanstalk - priority: 11 - tube: default - - test-3: - driver: sqs - prefetch: 1000000 - queue: default - attributes: - MessageRetentionPeriod: 86400 - tags: - test: "tag" - - # list of pipelines to be consumed by the server, keep empty if you want to start consuming manually - consume: [ "test-local", "test-local-2", "test-local-3", "test-1", "test-2-amqp", "test-3" ] - diff --git a/tests/plugins/jobs/configs/.rr-jobs-metrics.yaml b/tests/plugins/jobs/configs/.rr-jobs-metrics.yaml deleted file mode 100644 index 4db9a676..00000000 --- a/tests/plugins/jobs/configs/.rr-jobs-metrics.yaml +++ /dev/null @@ -1,27 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../client.php echo pipes" - relay: "pipes" - relay_timeout: "20s" - -metrics: - address: 127.0.0.1:2112 - -logs: - level: info - encoding: console - mode: development - -jobs: - # num logical cores by default - num_pollers: 10 - # 1mi by default - pipeline_size: 100000 - # worker pool configuration - pool: - num_workers: 1 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s diff --git a/tests/plugins/jobs/durability/.rr-amqp-durability-redial.yaml b/tests/plugins/jobs/durability/.rr-amqp-durability-redial.yaml deleted file mode 100644 index 2c4709ba..00000000 --- a/tests/plugins/jobs/durability/.rr-amqp-durability-redial.yaml +++ /dev/null @@ -1,55 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../jobs_ok.php" - relay: "pipes" - relay_timeout: "20s" - -amqp: - addr: amqp://guest:[email protected]:23679/ - -logs: - level: debug - encoding: console - mode: development - -jobs: - num_pollers: 10 - pipeline_size: 100000 - timeout: 1 - pool: - num_workers: 10 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s - - pipelines: - test-1: - driver: amqp - prefetch: 100 - queue: test-1-queue - priority: 1 - exchange: default - exchange_type: direct - routing_key: test-1 - exclusive: false - multiple_ack: false - requeue_on_fail: false - - test-2: - driver: amqp - prefetch: 100 - queue: test-2-queue - priority: 2 - exchange: default - exchange_type: direct - routing_key: test-2 - exclusive: false - multiple_ack: false - requeue_on_fail: false - - - # list of pipelines to be consumed by the server, keep empty if you want to start consuming manually - consume: [ "test-1", "test-2" ] - diff --git a/tests/plugins/jobs/durability/.rr-beanstalk-durability-redial.yaml b/tests/plugins/jobs/durability/.rr-beanstalk-durability-redial.yaml deleted file mode 100644 index 57d8ad2d..00000000 --- a/tests/plugins/jobs/durability/.rr-beanstalk-durability-redial.yaml +++ /dev/null @@ -1,44 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../client.php echo pipes" - relay: "pipes" - relay_timeout: "20s" - -beanstalk: - addr: tcp://127.0.0.1:11400 - timeout: 10s - -logs: - level: debug - encoding: console - mode: development - -jobs: - num_pollers: 10 - pipeline_size: 100000 - pool: - num_workers: 10 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s - - pipelines: - test-1: - driver: beanstalk - priority: 11 - tube_priority: 1 - tube: default-1 - reserve_timeout: 10s - - test-2: - driver: beanstalk - priority: 11 - tube_priority: 3 - tube: default-2 - reserve_timeout: 10s - - # list of pipelines to be consumed by the server, keep empty if you want to start consuming manually - consume: [ "test-1", "test-2" ] - diff --git a/tests/plugins/jobs/durability/.rr-sqs-durability-redial.yaml b/tests/plugins/jobs/durability/.rr-sqs-durability-redial.yaml deleted file mode 100644 index b6ba83a4..00000000 --- a/tests/plugins/jobs/durability/.rr-sqs-durability-redial.yaml +++ /dev/null @@ -1,60 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../client.php echo pipes" - relay: "pipes" - relay_timeout: "20s" - -sqs: - key: api-key - secret: api-secret - region: us-west-1 - endpoint: http://127.0.0.1:19324 - -logs: - level: debug - encoding: console - mode: development - -jobs: - num_pollers: 10 - pipeline_size: 100000 - pool: - num_workers: 10 - timeout: 20 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s - - pipelines: - test-1: - driver: sqs - prefetch: 10 - visibility_timeout: 0 - wait_time_seconds: 1 - queue: default - # https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SetQueueAttributes.html - attributes: - DelaySeconds: 0 - MaximumMessageSize: 262144 - MessageRetentionPeriod: 345600 - ReceiveMessageWaitTimeSeconds: 0 - VisibilityTimeout: 0 - tags: - test: "tag" - - test-2: - driver: sqs - prefetch: 10 - queue: default-2 - wait_time_seconds: 1 - attributes: - MessageRetentionPeriod: 86400 - tags: - test: "tag" - - - # list of pipelines to be consumed by the server, keep empty if you want to start consuming manually - consume: [ "test-1", "test-2" ] - diff --git a/tests/plugins/jobs/helpers.go b/tests/plugins/jobs/helpers.go deleted file mode 100644 index 6c2d05ca..00000000 --- a/tests/plugins/jobs/helpers.go +++ /dev/null @@ -1,234 +0,0 @@ -package jobs - -import ( - "bytes" - "net" - "net/http" - "net/rpc" - "testing" - - goridgeRpc "github.com/spiral/goridge/v3/pkg/rpc" - jobState "github.com/spiral/roadrunner/v2/pkg/state/job" - jobsv1beta "github.com/spiral/roadrunner/v2/proto/jobs/v1beta" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -const ( - push string = "jobs.Push" - pause string = "jobs.Pause" - destroy string = "jobs.Destroy" - resume string = "jobs.Resume" - stat string = "jobs.Stat" -) - -func resumePipes(pipes ...string) func(t *testing.T) { - return func(t *testing.T) { - conn, err := net.Dial("tcp", "127.0.0.1:6001") - assert.NoError(t, err) - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - - pipe := &jobsv1beta.Pipelines{Pipelines: make([]string, len(pipes))} - - for i := 0; i < len(pipes); i++ { - pipe.GetPipelines()[i] = pipes[i] - } - - er := &jobsv1beta.Empty{} - err = client.Call(resume, pipe, er) - assert.NoError(t, err) - } -} - -func pushToDisabledPipe(pipeline string) func(t *testing.T) { - return func(t *testing.T) { - conn, err := net.Dial("tcp", "127.0.0.1:6001") - assert.NoError(t, err) - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - - req := &jobsv1beta.PushRequest{Job: &jobsv1beta.Job{ - Job: "some/php/namespace", - Id: "1", - Payload: `{"hello":"world"}`, - Headers: nil, - Options: &jobsv1beta.Options{ - Priority: 1, - Pipeline: pipeline, - }, - }} - - er := &jobsv1beta.Empty{} - err = client.Call(push, req, er) - assert.NoError(t, err) - } -} - -func pushToPipe(pipeline string) func(t *testing.T) { - return func(t *testing.T) { - conn, err := net.Dial("tcp", "127.0.0.1:6001") - assert.NoError(t, err) - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - - req := &jobsv1beta.PushRequest{Job: &jobsv1beta.Job{ - Job: "some/php/namespace", - Id: "1", - Payload: `{"hello":"world"}`, - Headers: map[string]*jobsv1beta.HeaderValue{"test": {Value: []string{"test2"}}}, - Options: &jobsv1beta.Options{ - Priority: 1, - Pipeline: pipeline, - Delay: 0, - }, - }} - - er := &jobsv1beta.Empty{} - err = client.Call(push, req, er) - assert.NoError(t, err) - } -} - -func pushToPipeDelayed(pipeline string, delay int64) func(t *testing.T) { - return func(t *testing.T) { - conn, err := net.Dial("tcp", "127.0.0.1:6001") - assert.NoError(t, err) - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - - req := &jobsv1beta.PushRequest{Job: &jobsv1beta.Job{ - Job: "some/php/namespace", - Id: "2", - Payload: `{"hello":"world"}`, - Headers: map[string]*jobsv1beta.HeaderValue{"test": {Value: []string{"test2"}}}, - Options: &jobsv1beta.Options{ - Priority: 1, - Pipeline: pipeline, - Delay: delay, - }, - }} - - er := &jobsv1beta.Empty{} - err = client.Call(push, req, er) - assert.NoError(t, err) - } -} - -func pushToPipeErr(pipeline string) func(t *testing.T) { - return func(t *testing.T) { - conn, err := net.Dial("tcp", "127.0.0.1:6001") - require.NoError(t, err) - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - - req := &jobsv1beta.PushRequest{Job: &jobsv1beta.Job{ - Job: "some/php/namespace", - Id: "1", - Payload: `{"hello":"world"}`, - Headers: map[string]*jobsv1beta.HeaderValue{"test": {Value: []string{"test2"}}}, - Options: &jobsv1beta.Options{ - Priority: 1, - Pipeline: pipeline, - Delay: 0, - }, - }} - - er := &jobsv1beta.Empty{} - err = client.Call(push, req, er) - require.Error(t, err) - } -} -func pausePipelines(pipes ...string) func(t *testing.T) { - return func(t *testing.T) { - conn, err := net.Dial("tcp", "127.0.0.1:6001") - assert.NoError(t, err) - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - - pipe := &jobsv1beta.Pipelines{Pipelines: make([]string, len(pipes))} - - for i := 0; i < len(pipes); i++ { - pipe.GetPipelines()[i] = pipes[i] - } - - er := &jobsv1beta.Empty{} - err = client.Call(pause, pipe, er) - assert.NoError(t, err) - } -} - -func destroyPipelines(pipes ...string) func(t *testing.T) { - return func(t *testing.T) { - conn, err := net.Dial("tcp", "127.0.0.1:6001") - assert.NoError(t, err) - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - - pipe := &jobsv1beta.Pipelines{Pipelines: make([]string, len(pipes))} - - for i := 0; i < len(pipes); i++ { - pipe.GetPipelines()[i] = pipes[i] - } - - er := &jobsv1beta.Empty{} - err = client.Call(destroy, pipe, er) - assert.NoError(t, err) - } -} - -func enableProxy(name string, t *testing.T) { - buf := new(bytes.Buffer) - buf.WriteString(`{"enabled":true}`) - - resp, err := http.Post("http://127.0.0.1:8474/proxies/"+name, "application/json", buf) //nolint:noctx - require.NoError(t, err) - require.Equal(t, 200, resp.StatusCode) - if resp.Body != nil { - _ = resp.Body.Close() - } -} - -func disableProxy(name string, t *testing.T) { - buf := new(bytes.Buffer) - buf.WriteString(`{"enabled":false}`) - - resp, err := http.Post("http://127.0.0.1:8474/proxies/"+name, "application/json", buf) //nolint:noctx - require.NoError(t, err) - require.Equal(t, 200, resp.StatusCode) - if resp.Body != nil { - _ = resp.Body.Close() - } -} - -func deleteProxy(name string, t *testing.T) { - client := &http.Client{} - - req, err := http.NewRequest(http.MethodDelete, "http://127.0.0.1:8474/proxies/"+name, nil) //nolint:noctx - require.NoError(t, err) - - resp, err := client.Do(req) - require.NoError(t, err) - - require.NoError(t, err) - require.Equal(t, 204, resp.StatusCode) - if resp.Body != nil { - _ = resp.Body.Close() - } -} - -func stats(state *jobState.State) func(t *testing.T) { - return func(t *testing.T) { - conn, err := net.Dial("tcp", "127.0.0.1:6001") - assert.NoError(t, err) - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - - st := &jobsv1beta.Stats{} - er := &jobsv1beta.Empty{} - - err = client.Call(stat, er, st) - require.NoError(t, err) - require.NotNil(t, st) - - state.Queue = st.Stats[0].Queue - state.Pipeline = st.Stats[0].Pipeline - state.Driver = st.Stats[0].Driver - state.Active = st.Stats[0].Active - state.Delayed = st.Stats[0].Delayed - state.Reserved = st.Stats[0].Reserved - state.Ready = st.Stats[0].Ready - } -} diff --git a/tests/plugins/jobs/jobs_amqp_test.go b/tests/plugins/jobs/jobs_amqp_test.go deleted file mode 100644 index 949698ec..00000000 --- a/tests/plugins/jobs/jobs_amqp_test.go +++ /dev/null @@ -1,499 +0,0 @@ -package jobs - -import ( - "net" - "net/rpc" - "os" - "os/signal" - "sync" - "syscall" - "testing" - "time" - - "github.com/golang/mock/gomock" - endure "github.com/spiral/endure/pkg/container" - goridgeRpc "github.com/spiral/goridge/v3/pkg/rpc" - jobState "github.com/spiral/roadrunner/v2/pkg/state/job" - "github.com/spiral/roadrunner/v2/plugins/amqp" - "github.com/spiral/roadrunner/v2/plugins/config" - "github.com/spiral/roadrunner/v2/plugins/informer" - "github.com/spiral/roadrunner/v2/plugins/jobs" - "github.com/spiral/roadrunner/v2/plugins/logger" - "github.com/spiral/roadrunner/v2/plugins/resetter" - rpcPlugin "github.com/spiral/roadrunner/v2/plugins/rpc" - "github.com/spiral/roadrunner/v2/plugins/server" - jobsv1beta "github.com/spiral/roadrunner/v2/proto/jobs/v1beta" - "github.com/spiral/roadrunner/v2/tests/mocks" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestAMQPInit(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "amqp/.rr-amqp-init.yaml", - Prefix: "rr", - } - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - - // general - mockLogger.EXPECT().Debug("worker destructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("Started RPC service", "address", "tcp://127.0.0.1:6001", "plugins", gomock.Any()).Times(1) - mockLogger.EXPECT().Error(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() - - mockLogger.EXPECT().Info("pipeline active", "pipeline", "test-2", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Info("pipeline active", "pipeline", "test-1", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - - mockLogger.EXPECT().Warn("pipeline stopped", "pipeline", "test-1", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Warn("pipeline stopped", "pipeline", "test-2", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - - mockLogger.EXPECT().Info("delivery channel closed, leaving the rabbit listener").Times(2) - - err = cont.RegisterAll( - cfg, - &server.Plugin{}, - &rpcPlugin.Plugin{}, - mockLogger, - &jobs.Plugin{}, - &resetter.Plugin{}, - &informer.Plugin{}, - &amqp.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - if err != nil { - t.Fatal(err) - } - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 3) - stopCh <- struct{}{} - wg.Wait() -} - -func TestAMQPDeclare(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "amqp/.rr-amqp-declare.yaml", - Prefix: "rr", - } - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - - // general - mockLogger.EXPECT().Debug("worker destructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("Started RPC service", "address", "tcp://127.0.0.1:6001", "plugins", gomock.Any()).Times(1) - mockLogger.EXPECT().Error(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() - - mockLogger.EXPECT().Info("job pushed to the queue", "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("job processed without errors", "ID", gomock.Any(), "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("job processing started", "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - - mockLogger.EXPECT().Info("pipeline active", "pipeline", "test-3", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Info("pipeline paused", "pipeline", "test-3", "driver", "amqp", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Warn("pipeline stopped", "pipeline", "test-3", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Info("delivery channel closed, leaving the rabbit listener").Times(1) - - err = cont.RegisterAll( - cfg, - &server.Plugin{}, - &rpcPlugin.Plugin{}, - mockLogger, - &jobs.Plugin{}, - &resetter.Plugin{}, - &informer.Plugin{}, - &amqp.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - if err != nil { - t.Fatal(err) - } - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 3) - - t.Run("DeclareAMQPPipeline", declareAMQPPipe) - t.Run("ConsumeAMQPPipeline", resumePipes("test-3")) - t.Run("PushAMQPPipeline", pushToPipe("test-3")) - time.Sleep(time.Second) - t.Run("PauseAMQPPipeline", pausePipelines("test-3")) - time.Sleep(time.Second) - t.Run("DestroyAMQPPipeline", destroyPipelines("test-3")) - - time.Sleep(time.Second * 5) - stopCh <- struct{}{} - wg.Wait() -} - -func TestAMQPJobsError(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "amqp/.rr-amqp-jobs-err.yaml", - Prefix: "rr", - } - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - - // general - mockLogger.EXPECT().Debug("worker destructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("Started RPC service", "address", "tcp://127.0.0.1:6001", "plugins", gomock.Any()).Times(1) - mockLogger.EXPECT().Error(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() - - mockLogger.EXPECT().Info("job pushed to the queue", "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("job processed without errors", "ID", gomock.Any(), "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("job processing started", "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - - mockLogger.EXPECT().Info("pipeline active", "pipeline", "test-3", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Info("pipeline paused", "pipeline", "test-3", "driver", "amqp", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Error("jobs protocol error", "error", "error", "delay", gomock.Any(), "requeue", gomock.Any()).Times(3) - mockLogger.EXPECT().Warn("pipeline stopped", "pipeline", "test-3", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Info("delivery channel closed, leaving the rabbit listener").Times(1) - - err = cont.RegisterAll( - cfg, - &server.Plugin{}, - &rpcPlugin.Plugin{}, - mockLogger, - &jobs.Plugin{}, - &resetter.Plugin{}, - &informer.Plugin{}, - &amqp.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - if err != nil { - t.Fatal(err) - } - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 3) - - t.Run("DeclareAMQPPipeline", declareAMQPPipe) - t.Run("ConsumeAMQPPipeline", resumePipes("test-3")) - t.Run("PushAMQPPipeline", pushToPipe("test-3")) - time.Sleep(time.Second * 25) - t.Run("PauseAMQPPipeline", pausePipelines("test-3")) - t.Run("DestroyAMQPPipeline", destroyPipelines("test-3")) - - time.Sleep(time.Second * 5) - stopCh <- struct{}{} - wg.Wait() -} - -func TestAMQPNoGlobalSection(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "amqp/.rr-no-global.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &server.Plugin{}, - &rpcPlugin.Plugin{}, - &logger.ZapLogger{}, - &jobs.Plugin{}, - &resetter.Plugin{}, - &informer.Plugin{}, - &amqp.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - _, err = cont.Serve() - require.Error(t, err) -} - -func TestAMQPStats(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "amqp/.rr-amqp-declare.yaml", - Prefix: "rr", - } - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - - // general - mockLogger.EXPECT().Debug("worker destructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("Started RPC service", "address", "tcp://127.0.0.1:6001", "plugins", gomock.Any()).Times(1) - mockLogger.EXPECT().Error(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() - - mockLogger.EXPECT().Info("job pushed to the queue", "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("pipeline active", "pipeline", "test-3", "start", gomock.Any(), "elapsed", gomock.Any()).Times(2) - mockLogger.EXPECT().Info("pipeline paused", "pipeline", "test-3", "driver", "amqp", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Info("job processed without errors", "ID", gomock.Any(), "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("job processing started", "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Warn("pipeline stopped", "pipeline", "test-3", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Info("delivery channel closed, leaving the rabbit listener").AnyTimes() - - err = cont.RegisterAll( - cfg, - &server.Plugin{}, - &rpcPlugin.Plugin{}, - mockLogger, - &jobs.Plugin{}, - &resetter.Plugin{}, - &informer.Plugin{}, - &amqp.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - if err != nil { - t.Fatal(err) - } - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 3) - - t.Run("DeclareAMQPPipeline", declareAMQPPipe) - t.Run("ConsumeAMQPPipeline", resumePipes("test-3")) - t.Run("PushAMQPPipeline", pushToPipe("test-3")) - time.Sleep(time.Second * 2) - t.Run("PauseAMQPPipeline", pausePipelines("test-3")) - time.Sleep(time.Second * 2) - t.Run("PushAMQPPipeline", pushToPipe("test-3")) - t.Run("PushPipelineDelayed", pushToPipeDelayed("test-3", 5)) - - out := &jobState.State{} - t.Run("Stats", stats(out)) - - assert.Equal(t, out.Pipeline, "test-3") - assert.Equal(t, out.Driver, "amqp") - assert.Equal(t, out.Queue, "default") - - assert.Equal(t, int64(1), out.Active) - assert.Equal(t, int64(1), out.Delayed) - assert.Equal(t, int64(0), out.Reserved) - assert.Equal(t, false, out.Ready) - - time.Sleep(time.Second) - t.Run("ResumePipeline", resumePipes("test-3")) - time.Sleep(time.Second * 7) - - out = &jobState.State{} - t.Run("Stats", stats(out)) - - assert.Equal(t, out.Pipeline, "test-3") - assert.Equal(t, out.Driver, "amqp") - assert.Equal(t, out.Queue, "default") - - assert.Equal(t, int64(0), out.Active) - assert.Equal(t, int64(0), out.Delayed) - assert.Equal(t, int64(0), out.Reserved) - assert.Equal(t, true, out.Ready) - - time.Sleep(time.Second) - t.Run("DestroyAMQPPipeline", destroyPipelines("test-3")) - - time.Sleep(time.Second * 5) - stopCh <- struct{}{} - wg.Wait() -} - -func declareAMQPPipe(t *testing.T) { - conn, err := net.Dial("tcp", "127.0.0.1:6001") - assert.NoError(t, err) - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - - pipe := &jobsv1beta.DeclareRequest{Pipeline: map[string]string{ - "driver": "amqp", - "name": "test-3", - "routing_key": "test-3", - "queue": "default", - "exchange_type": "direct", - "exchange": "amqp.default", - "prefetch": "100", - "priority": "3", - "exclusive": "true", - "multiple_ask": "true", - "requeue_on_fail": "true", - }} - - er := &jobsv1beta.Empty{} - err = client.Call("jobs.Declare", pipe, er) - assert.NoError(t, err) -} diff --git a/tests/plugins/jobs/jobs_beanstalk_test.go b/tests/plugins/jobs/jobs_beanstalk_test.go deleted file mode 100644 index 9f4d37ec..00000000 --- a/tests/plugins/jobs/jobs_beanstalk_test.go +++ /dev/null @@ -1,515 +0,0 @@ -package jobs - -import ( - "net" - "net/rpc" - "os" - "os/signal" - "sync" - "syscall" - "testing" - "time" - - "github.com/golang/mock/gomock" - endure "github.com/spiral/endure/pkg/container" - goridgeRpc "github.com/spiral/goridge/v3/pkg/rpc" - jobState "github.com/spiral/roadrunner/v2/pkg/state/job" - "github.com/spiral/roadrunner/v2/plugins/beanstalk" - "github.com/spiral/roadrunner/v2/plugins/config" - "github.com/spiral/roadrunner/v2/plugins/informer" - "github.com/spiral/roadrunner/v2/plugins/jobs" - "github.com/spiral/roadrunner/v2/plugins/logger" - "github.com/spiral/roadrunner/v2/plugins/resetter" - rpcPlugin "github.com/spiral/roadrunner/v2/plugins/rpc" - "github.com/spiral/roadrunner/v2/plugins/server" - jobsv1beta "github.com/spiral/roadrunner/v2/proto/jobs/v1beta" - "github.com/spiral/roadrunner/v2/tests/mocks" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestBeanstalkInit(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "beanstalk/.rr-beanstalk-init.yaml", - Prefix: "rr", - } - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - - // general - mockLogger.EXPECT().Debug("worker destructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("Started RPC service", "address", "tcp://127.0.0.1:6001", "plugins", gomock.Any()).Times(1) - mockLogger.EXPECT().Error(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() - - mockLogger.EXPECT().Info("pipeline active", "pipeline", "test-2", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Info("pipeline active", "pipeline", "test-1", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - - mockLogger.EXPECT().Info("beanstalk reserve timeout", "warn", "reserve-with-timeout").AnyTimes() - - mockLogger.EXPECT().Warn("pipeline stopped", "pipeline", "test-1", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Warn("pipeline stopped", "pipeline", "test-2", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Warn("beanstalk listener stopped").AnyTimes() - - err = cont.RegisterAll( - cfg, - &server.Plugin{}, - &rpcPlugin.Plugin{}, - mockLogger, - &jobs.Plugin{}, - &resetter.Plugin{}, - &informer.Plugin{}, - &beanstalk.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - if err != nil { - t.Fatal(err) - } - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 3) - stopCh <- struct{}{} - wg.Wait() -} - -func TestBeanstalkDeclare(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "beanstalk/.rr-beanstalk-declare.yaml", - Prefix: "rr", - } - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - - // general - mockLogger.EXPECT().Debug("worker destructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("Started RPC service", "address", "tcp://127.0.0.1:6001", "plugins", gomock.Any()).Times(1) - mockLogger.EXPECT().Error(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() - - mockLogger.EXPECT().Info("job pushed to the queue", "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("job processing started", "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("job processed without errors", "ID", gomock.Any(), "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - - mockLogger.EXPECT().Info("pipeline active", "pipeline", "test-3", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Info("pipeline paused", "pipeline", "test-3", "driver", "beanstalk", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Info("beanstalk reserve timeout", "warn", "reserve-with-timeout").AnyTimes() - - mockLogger.EXPECT().Warn("pipeline stopped", "pipeline", "test-3", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Warn("beanstalk listener stopped").AnyTimes() - - err = cont.RegisterAll( - cfg, - &server.Plugin{}, - &rpcPlugin.Plugin{}, - mockLogger, - &jobs.Plugin{}, - &resetter.Plugin{}, - &informer.Plugin{}, - &beanstalk.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - if err != nil { - t.Fatal(err) - } - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 3) - - t.Run("DeclareBeanstalkPipeline", declareBeanstalkPipe) - t.Run("ConsumeBeanstalkPipeline", resumePipes("test-3")) - t.Run("PushBeanstalkPipeline", pushToPipe("test-3")) - time.Sleep(time.Second) - t.Run("PauseBeanstalkPipeline", pausePipelines("test-3")) - time.Sleep(time.Second) - t.Run("DestroyBeanstalkPipeline", destroyPipelines("test-3")) - - time.Sleep(time.Second * 5) - stopCh <- struct{}{} - wg.Wait() -} - -func TestBeanstalkJobsError(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "beanstalk/.rr-beanstalk-jobs-err.yaml", - Prefix: "rr", - } - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - - // general - mockLogger.EXPECT().Debug("worker destructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("Started RPC service", "address", "tcp://127.0.0.1:6001", "plugins", gomock.Any()).Times(1) - mockLogger.EXPECT().Error(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() - - mockLogger.EXPECT().Info("pipeline active", "pipeline", "test-3", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Info("pipeline paused", "pipeline", "test-3", "driver", "beanstalk", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Info("beanstalk reserve timeout", "warn", "reserve-with-timeout").AnyTimes() - - mockLogger.EXPECT().Info("job pushed to the queue", "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("job processing started", "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("job processed without errors", "ID", gomock.Any(), "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - - mockLogger.EXPECT().Warn("pipeline stopped", "pipeline", "test-3", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Warn("beanstalk listener stopped").AnyTimes() - - mockLogger.EXPECT().Error("jobs protocol error", "error", "error", "delay", gomock.Any(), "requeue", gomock.Any()).Times(3) - - err = cont.RegisterAll( - cfg, - &server.Plugin{}, - &rpcPlugin.Plugin{}, - mockLogger, - &jobs.Plugin{}, - &resetter.Plugin{}, - &informer.Plugin{}, - &beanstalk.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - if err != nil { - t.Fatal(err) - } - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 3) - - t.Run("DeclareBeanstalkPipeline", declareBeanstalkPipe) - t.Run("ConsumeBeanstalkPipeline", resumePipes("test-3")) - t.Run("PushBeanstalkPipeline", pushToPipe("test-3")) - time.Sleep(time.Second * 25) - t.Run("PauseBeanstalkPipeline", pausePipelines("test-3")) - time.Sleep(time.Second) - t.Run("DestroyBeanstalkPipeline", destroyPipelines("test-3")) - - time.Sleep(time.Second * 5) - stopCh <- struct{}{} - wg.Wait() -} - -func TestBeanstalkStats(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "beanstalk/.rr-beanstalk-declare.yaml", - Prefix: "rr", - } - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - - // general - mockLogger.EXPECT().Debug("worker destructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("Started RPC service", "address", "tcp://127.0.0.1:6001", "plugins", gomock.Any()).Times(1) - mockLogger.EXPECT().Error(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() - - mockLogger.EXPECT().Info("pipeline active", "pipeline", "test-3", "start", gomock.Any(), "elapsed", gomock.Any()).Times(2) - mockLogger.EXPECT().Info("pipeline paused", "pipeline", "test-3", "driver", "beanstalk", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Info("beanstalk reserve timeout", "warn", "reserve-with-timeout").AnyTimes() - - mockLogger.EXPECT().Info("job pushed to the queue", "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("job processing started", "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("job processed without errors", "ID", gomock.Any(), "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - - mockLogger.EXPECT().Warn("pipeline stopped", "pipeline", "test-3", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Warn("beanstalk listener stopped").AnyTimes() - - err = cont.RegisterAll( - cfg, - &server.Plugin{}, - &rpcPlugin.Plugin{}, - mockLogger, - &jobs.Plugin{}, - &resetter.Plugin{}, - &informer.Plugin{}, - &beanstalk.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - if err != nil { - t.Fatal(err) - } - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 3) - - t.Run("DeclarePipeline", declareBeanstalkPipe) - t.Run("ConsumePipeline", resumePipes("test-3")) - t.Run("PushPipeline", pushToPipe("test-3")) - time.Sleep(time.Second * 2) - t.Run("PausePipeline", pausePipelines("test-3")) - time.Sleep(time.Second * 3) - t.Run("PushPipelineDelayed", pushToPipeDelayed("test-3", 5)) - t.Run("PushPipeline", pushToPipe("test-3")) - time.Sleep(time.Second) - - out := &jobState.State{} - t.Run("Stats", stats(out)) - - assert.Equal(t, out.Pipeline, "test-3") - assert.Equal(t, out.Driver, "beanstalk") - assert.Equal(t, out.Queue, "default") - - // try 5 times - if out.Active == 0 { - for i := 0; i < 5; i++ { - time.Sleep(time.Second) - out = &jobState.State{} - t.Run("Stats", stats(out)) - if out.Active == 1 { - break - } - } - } - - assert.Equal(t, int64(1), out.Active) - assert.Equal(t, int64(1), out.Delayed) - assert.Equal(t, int64(0), out.Reserved) - - time.Sleep(time.Second) - t.Run("ResumePipeline", resumePipes("test-3")) - time.Sleep(time.Second * 15) - - out = &jobState.State{} - t.Run("Stats", stats(out)) - - assert.Equal(t, out.Pipeline, "test-3") - assert.Equal(t, out.Driver, "beanstalk") - assert.Equal(t, out.Queue, "default") - - assert.Equal(t, int64(0), out.Active) - assert.Equal(t, int64(0), out.Delayed) - assert.Equal(t, int64(0), out.Reserved) - - time.Sleep(time.Second) - t.Run("DestroyPipeline", destroyPipelines("test-3")) - - time.Sleep(time.Second) - stopCh <- struct{}{} - wg.Wait() -} - -func TestBeanstalkNoGlobalSection(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "beanstalk/.rr-no-global.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &server.Plugin{}, - &rpcPlugin.Plugin{}, - &logger.ZapLogger{}, - &jobs.Plugin{}, - &resetter.Plugin{}, - &informer.Plugin{}, - &beanstalk.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - _, err = cont.Serve() - require.Error(t, err) -} - -func declareBeanstalkPipe(t *testing.T) { - conn, err := net.Dial("tcp", "127.0.0.1:6001") - assert.NoError(t, err) - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - - pipe := &jobsv1beta.DeclareRequest{Pipeline: map[string]string{ - "driver": "beanstalk", - "name": "test-3", - "tube": "default", - "reserve_timeout": "1", - "priority": "3", - "tube_priority": "10", - }} - - er := &jobsv1beta.Empty{} - err = client.Call("jobs.Declare", pipe, er) - assert.NoError(t, err) -} diff --git a/tests/plugins/jobs/jobs_boltdb_test.go b/tests/plugins/jobs/jobs_boltdb_test.go deleted file mode 100644 index ab36ffa4..00000000 --- a/tests/plugins/jobs/jobs_boltdb_test.go +++ /dev/null @@ -1,506 +0,0 @@ -package jobs - -import ( - "net" - "net/rpc" - "os" - "os/signal" - "sync" - "syscall" - "testing" - "time" - - "github.com/golang/mock/gomock" - endure "github.com/spiral/endure/pkg/container" - goridgeRpc "github.com/spiral/goridge/v3/pkg/rpc" - jobState "github.com/spiral/roadrunner/v2/pkg/state/job" - "github.com/spiral/roadrunner/v2/plugins/boltdb" - "github.com/spiral/roadrunner/v2/plugins/config" - "github.com/spiral/roadrunner/v2/plugins/informer" - "github.com/spiral/roadrunner/v2/plugins/jobs" - "github.com/spiral/roadrunner/v2/plugins/logger" - "github.com/spiral/roadrunner/v2/plugins/resetter" - rpcPlugin "github.com/spiral/roadrunner/v2/plugins/rpc" - "github.com/spiral/roadrunner/v2/plugins/server" - jobsv1beta "github.com/spiral/roadrunner/v2/proto/jobs/v1beta" - "github.com/spiral/roadrunner/v2/tests/mocks" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -const ( - rr1db string = "rr1.db" - rr2db string = "rr2.db" -) - -func TestBoltDBInit(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "boltdb/.rr-boltdb-init.yaml", - Prefix: "rr", - } - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - - // general - mockLogger.EXPECT().Debug("worker destructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("Started RPC service", "address", "tcp://127.0.0.1:6001", "plugins", gomock.Any()).Times(1) - mockLogger.EXPECT().Error(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() - - mockLogger.EXPECT().Info("pipeline active", "pipeline", "test-2", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Info("pipeline active", "pipeline", "test-1", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - - mockLogger.EXPECT().Warn("pipeline stopped", "pipeline", "test-1", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Warn("pipeline stopped", "pipeline", "test-2", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - - mockLogger.EXPECT().Info("boltdb listener stopped").Times(4) - - err = cont.RegisterAll( - cfg, - &server.Plugin{}, - &rpcPlugin.Plugin{}, - mockLogger, - &jobs.Plugin{}, - &resetter.Plugin{}, - &informer.Plugin{}, - &boltdb.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - if err != nil { - t.Fatal(err) - } - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 3) - stopCh <- struct{}{} - wg.Wait() - - assert.NoError(t, os.Remove(rr1db)) - assert.NoError(t, os.Remove(rr2db)) -} - -func TestBoltDBDeclare(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "boltdb/.rr-boltdb-declare.yaml", - Prefix: "rr", - } - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - - // general - mockLogger.EXPECT().Debug("worker destructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("Started RPC service", "address", "tcp://127.0.0.1:6001", "plugins", gomock.Any()).Times(1) - mockLogger.EXPECT().Error(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() - - mockLogger.EXPECT().Info("job pushed to the queue", "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("job processed without errors", "ID", gomock.Any(), "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("job processing started", "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - - mockLogger.EXPECT().Info("pipeline active", "pipeline", "test-3", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Info("pipeline paused", "pipeline", "test-3", "driver", "boltdb", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Warn("pipeline stopped", "pipeline", "test-3", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Info("boltdb listener stopped").Times(2) - - err = cont.RegisterAll( - cfg, - &server.Plugin{}, - &rpcPlugin.Plugin{}, - mockLogger, - &jobs.Plugin{}, - &resetter.Plugin{}, - &informer.Plugin{}, - &boltdb.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - if err != nil { - t.Fatal(err) - } - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 3) - - t.Run("DeclarePipeline", declareBoltDBPipe(rr1db)) - t.Run("ConsumePipeline", resumePipes("test-3")) - t.Run("PushPipeline", pushToPipe("test-3")) - time.Sleep(time.Second) - t.Run("PausePipeline", pausePipelines("test-3")) - time.Sleep(time.Second) - t.Run("DestroyPipeline", destroyPipelines("test-3")) - - time.Sleep(time.Second * 5) - stopCh <- struct{}{} - wg.Wait() - assert.NoError(t, os.Remove(rr1db)) -} - -func TestBoltDBJobsError(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "boltdb/.rr-boltdb-jobs-err.yaml", - Prefix: "rr", - } - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - - // general - mockLogger.EXPECT().Debug("worker destructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("Started RPC service", "address", "tcp://127.0.0.1:6001", "plugins", gomock.Any()).Times(1) - mockLogger.EXPECT().Error(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() - - mockLogger.EXPECT().Info("job pushed to the queue", "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("job processed without errors", "ID", gomock.Any(), "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("job processing started", "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - - mockLogger.EXPECT().Info("pipeline active", "pipeline", "test-3", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Info("pipeline paused", "pipeline", "test-3", "driver", "boltdb", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Error("jobs protocol error", "error", "error", "delay", gomock.Any(), "requeue", gomock.Any()).Times(3) - mockLogger.EXPECT().Warn("pipeline stopped", "pipeline", "test-3", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Info("boltdb listener stopped").Times(2) - - err = cont.RegisterAll( - cfg, - &server.Plugin{}, - &rpcPlugin.Plugin{}, - mockLogger, - &jobs.Plugin{}, - &resetter.Plugin{}, - &informer.Plugin{}, - &boltdb.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - if err != nil { - t.Fatal(err) - } - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 3) - - t.Run("DeclarePipeline", declareBoltDBPipe(rr1db)) - t.Run("ConsumePipeline", resumePipes("test-3")) - t.Run("PushPipeline", pushToPipe("test-3")) - time.Sleep(time.Second * 25) - t.Run("PausePipeline", pausePipelines("test-3")) - t.Run("DestroyPipeline", destroyPipelines("test-3")) - - time.Sleep(time.Second * 5) - stopCh <- struct{}{} - wg.Wait() - assert.NoError(t, os.Remove(rr1db)) -} - -func TestBoltDBNoGlobalSection(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "boltdb/.rr-no-global.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &server.Plugin{}, - &rpcPlugin.Plugin{}, - &logger.ZapLogger{}, - &jobs.Plugin{}, - &resetter.Plugin{}, - &informer.Plugin{}, - &boltdb.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - _, err = cont.Serve() - require.Error(t, err) -} - -func TestBoltDBStats(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "boltdb/.rr-boltdb-declare.yaml", - Prefix: "rr", - } - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - - // general - mockLogger.EXPECT().Debug("worker destructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("Started RPC service", "address", "tcp://127.0.0.1:6001", "plugins", gomock.Any()).Times(1) - mockLogger.EXPECT().Error(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() - - mockLogger.EXPECT().Info("job pushed to the queue", "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("pipeline active", "pipeline", "test-3", "start", gomock.Any(), "elapsed", gomock.Any()).Times(2) - mockLogger.EXPECT().Info("pipeline paused", "pipeline", "test-3", "driver", "boltdb", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Info("job processed without errors", "ID", gomock.Any(), "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("job processing started", "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Warn("pipeline stopped", "pipeline", "test-3", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Info("boltdb listener stopped").AnyTimes() - - err = cont.RegisterAll( - cfg, - &server.Plugin{}, - &rpcPlugin.Plugin{}, - mockLogger, - &jobs.Plugin{}, - &resetter.Plugin{}, - &informer.Plugin{}, - &boltdb.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - if err != nil { - t.Fatal(err) - } - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 3) - - t.Run("DeclarePipeline", declareBoltDBPipe(rr1db)) - t.Run("ConsumePipeline", resumePipes("test-3")) - t.Run("PushPipeline", pushToPipe("test-3")) - time.Sleep(time.Second * 2) - t.Run("PausePipeline", pausePipelines("test-3")) - time.Sleep(time.Second * 2) - t.Run("PushPipeline", pushToPipe("test-3")) - t.Run("PushPipelineDelayed", pushToPipeDelayed("test-3", 5)) - - out := &jobState.State{} - t.Run("Stats", stats(out)) - - assert.Equal(t, "test-3", out.Pipeline) - assert.Equal(t, "boltdb", out.Driver) - assert.Equal(t, "push", out.Queue) - - assert.Equal(t, int64(1), out.Active) - assert.Equal(t, int64(1), out.Delayed) - assert.Equal(t, int64(0), out.Reserved) - assert.Equal(t, false, out.Ready) - - time.Sleep(time.Second) - t.Run("ResumePipeline", resumePipes("test-3")) - time.Sleep(time.Second * 7) - - out = &jobState.State{} - t.Run("Stats", stats(out)) - - assert.Equal(t, "test-3", out.Pipeline) - assert.Equal(t, "boltdb", out.Driver) - assert.Equal(t, "push", out.Queue) - - assert.Equal(t, int64(0), out.Active) - assert.Equal(t, int64(0), out.Delayed) - assert.Equal(t, int64(0), out.Reserved) - assert.Equal(t, true, out.Ready) - - time.Sleep(time.Second) - t.Run("DestroyPipeline", destroyPipelines("test-3")) - - time.Sleep(time.Second * 5) - stopCh <- struct{}{} - wg.Wait() - assert.NoError(t, os.Remove(rr1db)) -} - -func declareBoltDBPipe(file string) func(t *testing.T) { - return func(t *testing.T) { - conn, err := net.Dial("tcp", "127.0.0.1:6001") - assert.NoError(t, err) - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - - pipe := &jobsv1beta.DeclareRequest{Pipeline: map[string]string{ - "driver": "boltdb", - "name": "test-3", - "prefetch": "100", - "priority": "3", - "file": file, - }} - - er := &jobsv1beta.Empty{} - err = client.Call("jobs.Declare", pipe, er) - assert.NoError(t, err) - } -} diff --git a/tests/plugins/jobs/jobs_general_test.go b/tests/plugins/jobs/jobs_general_test.go deleted file mode 100644 index 5c521c2b..00000000 --- a/tests/plugins/jobs/jobs_general_test.go +++ /dev/null @@ -1,249 +0,0 @@ -package jobs - -import ( - "io/ioutil" - "net/http" - "os" - "os/signal" - "sync" - "syscall" - "testing" - "time" - - "github.com/golang/mock/gomock" - endure "github.com/spiral/endure/pkg/container" - "github.com/spiral/roadrunner/v2/plugins/amqp" - "github.com/spiral/roadrunner/v2/plugins/config" - "github.com/spiral/roadrunner/v2/plugins/informer" - "github.com/spiral/roadrunner/v2/plugins/jobs" - "github.com/spiral/roadrunner/v2/plugins/memory" - "github.com/spiral/roadrunner/v2/plugins/metrics" - "github.com/spiral/roadrunner/v2/plugins/resetter" - rpcPlugin "github.com/spiral/roadrunner/v2/plugins/rpc" - "github.com/spiral/roadrunner/v2/plugins/server" - "github.com/spiral/roadrunner/v2/tests/mocks" - "github.com/stretchr/testify/assert" -) - -func TestJobsInit(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-jobs-init.yaml", - Prefix: "rr", - } - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - - // general - mockLogger.EXPECT().Debug("worker destructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("Started RPC service", "address", "tcp://127.0.0.1:6001", "plugins", gomock.Any()).Times(1) - mockLogger.EXPECT().Error(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() - - mockLogger.EXPECT().Info("driver ready", "pipeline", "test-2", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Info("driver ready", "pipeline", "test-3", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - - mockLogger.EXPECT().Info("pipeline active", "pipeline", "test-local-2", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Info("pipeline active", "pipeline", "test-1", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Info("pipeline active", "pipeline", "test-2-amqp", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Info("pipeline active", "pipeline", "test-local", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Info("pipeline active", "pipeline", "test-local-3", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - - mockLogger.EXPECT().Warn("pipeline stopped", "pipeline", "test-local-3", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Warn("pipeline stopped", "pipeline", "test-local-2", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Warn("pipeline stopped", "pipeline", "test-1", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Warn("pipeline stopped", "pipeline", "test-2-amqp", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Warn("pipeline stopped", "pipeline", "test-local", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - - mockLogger.EXPECT().Info("delivery channel closed, leaving the rabbit listener").Times(2) - - err = cont.RegisterAll( - cfg, - &server.Plugin{}, - &rpcPlugin.Plugin{}, - mockLogger, - &jobs.Plugin{}, - &resetter.Plugin{}, - &informer.Plugin{}, - &memory.Plugin{}, - &amqp.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - if err != nil { - t.Fatal(err) - } - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 5) - stopCh <- struct{}{} - wg.Wait() -} - -func TestJOBSMetrics(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - if err != nil { - t.Fatal(err) - } - - cfg := &config.Viper{} - cfg.Prefix = "rr" - cfg.Path = "configs/.rr-jobs-metrics.yaml" - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - - mockLogger.EXPECT().Debug("worker destructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("Started RPC service", "address", "tcp://127.0.0.1:6001", "plugins", gomock.Any()).Times(1) - mockLogger.EXPECT().Error(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() - - mockLogger.EXPECT().Info("job processing started", "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("job processed without errors", "ID", gomock.Any(), "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("job pushed to the queue", "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - - mockLogger.EXPECT().Info("pipeline active", "pipeline", "test-3", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Warn("pipeline stopped", "pipeline", "test-3", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - - err = cont.RegisterAll( - cfg, - &rpcPlugin.Plugin{}, - &server.Plugin{}, - &jobs.Plugin{}, - &metrics.Plugin{}, - &memory.Plugin{}, - mockLogger, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - tt := time.NewTimer(time.Minute * 3) - wg := &sync.WaitGroup{} - wg.Add(1) - - go func() { - defer tt.Stop() - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-tt.C: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 2) - - t.Run("DeclareEphemeralPipeline", declareMemoryPipe) - t.Run("ConsumeEphemeralPipeline", consumeMemoryPipe) - t.Run("PushEphemeralPipeline", pushToPipe("test-3")) - time.Sleep(time.Second) - t.Run("PushEphemeralPipeline", pushToPipeDelayed("test-3", 5)) - time.Sleep(time.Second) - t.Run("PushEphemeralPipeline", pushToPipe("test-3")) - time.Sleep(time.Second * 5) - - genericOut, err := get() - assert.NoError(t, err) - - assert.Contains(t, genericOut, `rr_jobs_jobs_err 0`) - assert.Contains(t, genericOut, `rr_jobs_jobs_ok 3`) - assert.Contains(t, genericOut, `rr_jobs_push_err 0`) - assert.Contains(t, genericOut, `rr_jobs_push_ok 3`) - assert.Contains(t, genericOut, "workers_memory_bytes") - - close(sig) - wg.Wait() -} - -const getAddr = "http://127.0.0.1:2112/metrics" - -// get request and return body -func get() (string, error) { - r, err := http.Get(getAddr) - if err != nil { - return "", err - } - - b, err := ioutil.ReadAll(r.Body) - if err != nil { - return "", err - } - - err = r.Body.Close() - if err != nil { - return "", err - } - // unsafe - return string(b), err -} diff --git a/tests/plugins/jobs/jobs_memory_test.go b/tests/plugins/jobs/jobs_memory_test.go deleted file mode 100644 index 7e39c556..00000000 --- a/tests/plugins/jobs/jobs_memory_test.go +++ /dev/null @@ -1,570 +0,0 @@ -package jobs - -import ( - "net" - "net/rpc" - "os" - "os/signal" - "sync" - "syscall" - "testing" - "time" - - "github.com/golang/mock/gomock" - endure "github.com/spiral/endure/pkg/container" - goridgeRpc "github.com/spiral/goridge/v3/pkg/rpc" - jobState "github.com/spiral/roadrunner/v2/pkg/state/job" - "github.com/spiral/roadrunner/v2/plugins/config" - "github.com/spiral/roadrunner/v2/plugins/informer" - "github.com/spiral/roadrunner/v2/plugins/jobs" - "github.com/spiral/roadrunner/v2/plugins/memory" - "github.com/spiral/roadrunner/v2/plugins/resetter" - rpcPlugin "github.com/spiral/roadrunner/v2/plugins/rpc" - "github.com/spiral/roadrunner/v2/plugins/server" - jobsv1beta "github.com/spiral/roadrunner/v2/proto/jobs/v1beta" - "github.com/spiral/roadrunner/v2/tests/mocks" - "github.com/stretchr/testify/assert" -) - -func TestMemoryInit(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "memory/.rr-memory-init.yaml", - Prefix: "rr", - } - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - - // general - mockLogger.EXPECT().Debug("worker destructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("Started RPC service", "address", "tcp://127.0.0.1:6001", "plugins", gomock.Any()).Times(1) - mockLogger.EXPECT().Error(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() - - mockLogger.EXPECT().Info("pipeline active", "pipeline", "test-1", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Info("pipeline active", "pipeline", "test-2", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - - mockLogger.EXPECT().Warn("pipeline stopped", "pipeline", "test-1", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Warn("pipeline stopped", "pipeline", "test-2", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - - err = cont.RegisterAll( - cfg, - &server.Plugin{}, - &rpcPlugin.Plugin{}, - mockLogger, - &jobs.Plugin{}, - &resetter.Plugin{}, - &informer.Plugin{}, - &memory.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - if err != nil { - t.Fatal(err) - } - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 1) - stopCh <- struct{}{} - wg.Wait() -} - -func TestMemoryDeclare(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "memory/.rr-memory-declare.yaml", - Prefix: "rr", - } - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - - // general - mockLogger.EXPECT().Debug("worker destructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("Started RPC service", "address", "tcp://127.0.0.1:6001", "plugins", gomock.Any()).Times(1) - mockLogger.EXPECT().Error(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() - - mockLogger.EXPECT().Info("job pushed to the queue", "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("job processing started", "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("job processed without errors", "ID", gomock.Any(), "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - - mockLogger.EXPECT().Info("pipeline active", "pipeline", "test-3", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Info("pipeline paused", "pipeline", "test-3", "driver", "memory", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Warn("pipeline stopped", "pipeline", "test-3", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - - err = cont.RegisterAll( - cfg, - &server.Plugin{}, - &rpcPlugin.Plugin{}, - mockLogger, - &jobs.Plugin{}, - &resetter.Plugin{}, - &informer.Plugin{}, - &memory.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - if err != nil { - t.Fatal(err) - } - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 3) - - t.Run("DeclarePipeline", declareMemoryPipe) - t.Run("ConsumePipeline", consumeMemoryPipe) - t.Run("PushPipeline", pushToPipe("test-3")) - time.Sleep(time.Second) - t.Run("PausePipeline", pausePipelines("test-3")) - time.Sleep(time.Second) - t.Run("DestroyPipeline", destroyPipelines("test-3")) - - time.Sleep(time.Second * 5) - stopCh <- struct{}{} - wg.Wait() -} - -func TestMemoryPauseResume(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "memory/.rr-memory-pause-resume.yaml", - Prefix: "rr", - } - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - - // general - mockLogger.EXPECT().Debug("worker destructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("Started RPC service", "address", "tcp://127.0.0.1:6001", "plugins", gomock.Any()).Times(1) - mockLogger.EXPECT().Error(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() - - mockLogger.EXPECT().Info("pipeline active", "pipeline", "test-local-2", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Info("pipeline active", "pipeline", "test-local", "start", gomock.Any(), "elapsed", gomock.Any()).Times(2) - - mockLogger.EXPECT().Info("pipeline paused", "pipeline", "test-local", "driver", "memory", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - - mockLogger.EXPECT().Info("job pushed to the queue", "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("job processing started", "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("job processed without errors", "ID", gomock.Any(), "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - - mockLogger.EXPECT().Warn("pipeline stopped", "pipeline", "test-local-3", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Warn("pipeline stopped", "pipeline", "test-local-2", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Warn("pipeline stopped", "pipeline", "test-local", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - - err = cont.RegisterAll( - cfg, - &server.Plugin{}, - &rpcPlugin.Plugin{}, - mockLogger, - &jobs.Plugin{}, - &resetter.Plugin{}, - &informer.Plugin{}, - &memory.Plugin{}, - ) - - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - if err != nil { - t.Fatal(err) - } - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 3) - - t.Run("Pause", pausePipelines("test-local")) - t.Run("pushToDisabledPipe", pushToDisabledPipe("test-local")) - t.Run("Resume", resumePipes("test-local")) - t.Run("pushToEnabledPipe", pushToPipe("test-local")) - time.Sleep(time.Second * 1) - - stopCh <- struct{}{} - time.Sleep(time.Second) - wg.Wait() -} - -func TestMemoryJobsError(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "memory/.rr-memory-jobs-err.yaml", - Prefix: "rr", - } - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - - // general - mockLogger.EXPECT().Debug("worker destructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("Started RPC service", "address", "tcp://127.0.0.1:6001", "plugins", gomock.Any()).Times(1) - mockLogger.EXPECT().Error(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() - - mockLogger.EXPECT().Info("job pushed to the queue", "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("job processing started", "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("job processed without errors", "ID", gomock.Any(), "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - - mockLogger.EXPECT().Info("pipeline active", "pipeline", "test-3", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Info("pipeline paused", "pipeline", "test-3", "driver", "memory", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Error("jobs protocol error", "error", "error", "delay", gomock.Any(), "requeue", gomock.Any()).Times(3) - mockLogger.EXPECT().Warn("pipeline stopped", "pipeline", "test-3", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - - err = cont.RegisterAll( - cfg, - &server.Plugin{}, - &rpcPlugin.Plugin{}, - mockLogger, - &jobs.Plugin{}, - &resetter.Plugin{}, - &informer.Plugin{}, - &memory.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - if err != nil { - t.Fatal(err) - } - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 3) - - t.Run("DeclarePipeline", declareMemoryPipe) - t.Run("ConsumePipeline", resumePipes("test-3")) - t.Run("PushPipeline", pushToPipe("test-3")) - time.Sleep(time.Second * 25) - t.Run("PausePipeline", pausePipelines("test-3")) - time.Sleep(time.Second) - t.Run("DestroyPipeline", destroyPipelines("test-3")) - - time.Sleep(time.Second * 5) - stopCh <- struct{}{} - wg.Wait() -} - -func TestMemoryStats(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "memory/.rr-memory-declare.yaml", - Prefix: "rr", - } - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - - // general - mockLogger.EXPECT().Debug("worker destructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("Started RPC service", "address", "tcp://127.0.0.1:6001", "plugins", gomock.Any()).Times(1) - mockLogger.EXPECT().Error(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() - - mockLogger.EXPECT().Info("job pushed to the queue", "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("job processing started", "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("job processed without errors", "ID", gomock.Any(), "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - - mockLogger.EXPECT().Info("pipeline active", "pipeline", "test-3", "start", gomock.Any(), "elapsed", gomock.Any()).Times(2) - mockLogger.EXPECT().Info("pipeline paused", "pipeline", "test-3", "driver", "memory", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Warn("pipeline stopped", "pipeline", "test-3", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - - err = cont.RegisterAll( - cfg, - &server.Plugin{}, - &rpcPlugin.Plugin{}, - mockLogger, - &jobs.Plugin{}, - &resetter.Plugin{}, - &informer.Plugin{}, - &memory.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - if err != nil { - t.Fatal(err) - } - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 3) - - t.Run("DeclarePipeline", declareMemoryPipe) - t.Run("ConsumePipeline", consumeMemoryPipe) - t.Run("PushPipeline", pushToPipe("test-3")) - time.Sleep(time.Second) - t.Run("PausePipeline", pausePipelines("test-3")) - time.Sleep(time.Second) - - t.Run("PushPipeline", pushToPipeDelayed("test-3", 5)) - t.Run("PushPipeline", pushToPipe("test-3")) - - time.Sleep(time.Second) - out := &jobState.State{} - t.Run("Stats", stats(out)) - - assert.Equal(t, out.Pipeline, "test-3") - assert.Equal(t, out.Driver, "memory") - assert.Equal(t, out.Queue, "test-3") - - assert.Equal(t, out.Active, int64(1)) - assert.Equal(t, out.Delayed, int64(1)) - assert.Equal(t, out.Reserved, int64(0)) - - time.Sleep(time.Second) - t.Run("ConsumePipeline", consumeMemoryPipe) - time.Sleep(time.Second * 7) - - out = &jobState.State{} - t.Run("Stats", stats(out)) - - assert.Equal(t, out.Pipeline, "test-3") - assert.Equal(t, out.Driver, "memory") - assert.Equal(t, out.Queue, "test-3") - - assert.Equal(t, out.Active, int64(0)) - assert.Equal(t, out.Delayed, int64(0)) - assert.Equal(t, out.Reserved, int64(0)) - - t.Run("DestroyEphemeralPipeline", destroyPipelines("test-3")) - - time.Sleep(time.Second * 5) - stopCh <- struct{}{} - wg.Wait() -} - -func declareMemoryPipe(t *testing.T) { - conn, err := net.Dial("tcp", "127.0.0.1:6001") - assert.NoError(t, err) - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - - pipe := &jobsv1beta.DeclareRequest{Pipeline: map[string]string{ - "driver": "memory", - "name": "test-3", - "prefetch": "10000", - }} - - er := &jobsv1beta.Empty{} - err = client.Call("jobs.Declare", pipe, er) - assert.NoError(t, err) -} - -func consumeMemoryPipe(t *testing.T) { - conn, err := net.Dial("tcp", "127.0.0.1:6001") - assert.NoError(t, err) - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - - pipe := &jobsv1beta.Pipelines{Pipelines: make([]string, 1)} - pipe.GetPipelines()[0] = "test-3" - - er := &jobsv1beta.Empty{} - err = client.Call("jobs.Resume", pipe, er) - assert.NoError(t, err) -} diff --git a/tests/plugins/jobs/jobs_sqs_test.go b/tests/plugins/jobs/jobs_sqs_test.go deleted file mode 100644 index 2dd2c8db..00000000 --- a/tests/plugins/jobs/jobs_sqs_test.go +++ /dev/null @@ -1,503 +0,0 @@ -package jobs - -import ( - "net" - "net/rpc" - "os" - "os/signal" - "sync" - "syscall" - "testing" - "time" - - "github.com/golang/mock/gomock" - endure "github.com/spiral/endure/pkg/container" - goridgeRpc "github.com/spiral/goridge/v3/pkg/rpc" - jobState "github.com/spiral/roadrunner/v2/pkg/state/job" - "github.com/spiral/roadrunner/v2/plugins/config" - "github.com/spiral/roadrunner/v2/plugins/informer" - "github.com/spiral/roadrunner/v2/plugins/jobs" - "github.com/spiral/roadrunner/v2/plugins/logger" - "github.com/spiral/roadrunner/v2/plugins/resetter" - rpcPlugin "github.com/spiral/roadrunner/v2/plugins/rpc" - "github.com/spiral/roadrunner/v2/plugins/server" - "github.com/spiral/roadrunner/v2/plugins/sqs" - jobsv1beta "github.com/spiral/roadrunner/v2/proto/jobs/v1beta" - "github.com/spiral/roadrunner/v2/tests/mocks" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestSQSInit(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "sqs/.rr-sqs-init.yaml", - Prefix: "rr", - } - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - - // general - mockLogger.EXPECT().Debug("worker destructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("Started RPC service", "address", "tcp://127.0.0.1:6001", "plugins", gomock.Any()).Times(1) - mockLogger.EXPECT().Error(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() - - mockLogger.EXPECT().Info("pipeline active", "pipeline", "test-1", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Info("pipeline active", "pipeline", "test-2", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - - mockLogger.EXPECT().Warn("pipeline stopped", "pipeline", "test-1", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Warn("pipeline stopped", "pipeline", "test-2", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - - mockLogger.EXPECT().Warn("sqs listener stopped").AnyTimes() - mockLogger.EXPECT().Info("------> job poller stopped <------").AnyTimes() - - err = cont.RegisterAll( - cfg, - &server.Plugin{}, - &rpcPlugin.Plugin{}, - mockLogger, - &jobs.Plugin{}, - &resetter.Plugin{}, - &informer.Plugin{}, - &sqs.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - if err != nil { - t.Fatal(err) - } - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 3) - stopCh <- struct{}{} - wg.Wait() -} - -func TestSQSDeclare(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "sqs/.rr-sqs-declare.yaml", - Prefix: "rr", - } - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - - // general - mockLogger.EXPECT().Debug("worker destructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("Started RPC service", "address", "tcp://127.0.0.1:6001", "plugins", gomock.Any()).Times(1) - mockLogger.EXPECT().Error(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() - - mockLogger.EXPECT().Info("job pushed to the queue", "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("job processing started", "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("job processed without errors", "ID", gomock.Any(), "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - - mockLogger.EXPECT().Info("pipeline active", "pipeline", "test-3", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Info("pipeline paused", "pipeline", "test-3", "driver", "sqs", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Warn("pipeline stopped", "pipeline", "test-3", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Warn("sqs listener stopped").AnyTimes() - mockLogger.EXPECT().Info("------> job poller stopped <------").AnyTimes() - - err = cont.RegisterAll( - cfg, - &server.Plugin{}, - &rpcPlugin.Plugin{}, - mockLogger, - &jobs.Plugin{}, - &resetter.Plugin{}, - &informer.Plugin{}, - &sqs.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - if err != nil { - t.Fatal(err) - } - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 3) - - t.Run("DeclareSQSPipeline", declareSQSPipe) - t.Run("ConsumeSQSPipeline", resumePipes("test-3")) - t.Run("PushSQSPipeline", pushToPipe("test-3")) - time.Sleep(time.Second) - t.Run("PauseSQSPipeline", pausePipelines("test-3")) - time.Sleep(time.Second) - t.Run("DestroySQSPipeline", destroyPipelines("test-3")) - - time.Sleep(time.Second * 5) - stopCh <- struct{}{} - wg.Wait() -} - -func TestSQSJobsError(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "sqs/.rr-sqs-jobs-err.yaml", - Prefix: "rr", - } - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - - // general - mockLogger.EXPECT().Debug("worker destructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("Started RPC service", "address", "tcp://127.0.0.1:6001", "plugins", gomock.Any()).Times(1) - mockLogger.EXPECT().Error(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() - - mockLogger.EXPECT().Info("pipeline active", "pipeline", "test-3", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Error("jobs protocol error", "error", "error", "delay", gomock.Any(), "requeue", gomock.Any()).Times(3) - - mockLogger.EXPECT().Info("job pushed to the queue", "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("job processing started", "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("job processed without errors", "ID", gomock.Any(), "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - - mockLogger.EXPECT().Info("pipeline paused", "pipeline", "test-3", "driver", "sqs", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Warn("pipeline stopped", "pipeline", "test-3", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Warn("sqs listener stopped").AnyTimes() - mockLogger.EXPECT().Info("------> job poller stopped <------").AnyTimes() - - err = cont.RegisterAll( - cfg, - &server.Plugin{}, - &rpcPlugin.Plugin{}, - mockLogger, - &jobs.Plugin{}, - &resetter.Plugin{}, - &informer.Plugin{}, - &sqs.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - if err != nil { - t.Fatal(err) - } - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 3) - - t.Run("DeclareSQSPipeline", declareSQSPipe) - t.Run("ConsumeSQSPipeline", resumePipes("test-3")) - t.Run("PushSQSPipeline", pushToPipe("test-3")) - time.Sleep(time.Second * 25) - t.Run("PauseSQSPipeline", pausePipelines("test-3")) - time.Sleep(time.Second) - t.Run("DestroySQSPipeline", destroyPipelines("test-3")) - - time.Sleep(time.Second * 5) - stopCh <- struct{}{} - wg.Wait() - - time.Sleep(time.Second * 5) -} - -func TestSQSNoGlobalSection(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "sqs/.rr-no-global.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &server.Plugin{}, - &rpcPlugin.Plugin{}, - &logger.ZapLogger{}, - &jobs.Plugin{}, - &resetter.Plugin{}, - &informer.Plugin{}, - &sqs.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - _, err = cont.Serve() - require.Error(t, err) -} - -func TestSQSStat(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "sqs/.rr-sqs-declare.yaml", - Prefix: "rr", - } - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - - // general - mockLogger.EXPECT().Debug("worker destructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("Started RPC service", "address", "tcp://127.0.0.1:6001", "plugins", gomock.Any()).Times(1) - mockLogger.EXPECT().Error(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() - - mockLogger.EXPECT().Info("job pushed to the queue", "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("job processing started", "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("pipeline active", "pipeline", "test-3", "start", gomock.Any(), "elapsed", gomock.Any()).Times(2) - mockLogger.EXPECT().Info("pipeline paused", "pipeline", "test-3", "driver", "sqs", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Warn("pipeline stopped", "pipeline", "test-3", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Info("job processed without errors", "ID", gomock.Any(), "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Warn("sqs listener stopped").AnyTimes() - mockLogger.EXPECT().Info("------> job poller stopped <------").AnyTimes() - - err = cont.RegisterAll( - cfg, - &server.Plugin{}, - &rpcPlugin.Plugin{}, - mockLogger, - &jobs.Plugin{}, - &resetter.Plugin{}, - &informer.Plugin{}, - &sqs.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - if err != nil { - t.Fatal(err) - } - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 3) - - t.Run("DeclarePipeline", declareSQSPipe) - t.Run("ConsumePipeline", resumePipes("test-3")) - t.Run("PushPipeline", pushToPipe("test-3")) - time.Sleep(time.Second) - t.Run("PausePipeline", pausePipelines("test-3")) - time.Sleep(time.Second) - - t.Run("PushPipelineDelayed", pushToPipeDelayed("test-3", 5)) - t.Run("PushPipeline", pushToPipe("test-3")) - time.Sleep(time.Second) - - out := &jobState.State{} - t.Run("Stats", stats(out)) - - assert.Equal(t, out.Pipeline, "test-3") - assert.Equal(t, out.Driver, "sqs") - assert.Equal(t, out.Queue, "http://127.0.0.1:9324/000000000000/default") - - assert.Equal(t, int64(1), out.Active) - assert.Equal(t, int64(1), out.Delayed) - assert.Equal(t, int64(0), out.Reserved) - - time.Sleep(time.Second) - t.Run("ResumePipeline", resumePipes("test-3")) - time.Sleep(time.Second * 7) - - out = &jobState.State{} - t.Run("Stats", stats(out)) - - assert.Equal(t, out.Pipeline, "test-3") - assert.Equal(t, out.Driver, "sqs") - assert.Equal(t, out.Queue, "http://127.0.0.1:9324/000000000000/default") - - assert.Equal(t, int64(0), out.Active) - assert.Equal(t, int64(0), out.Delayed) - assert.Equal(t, int64(0), out.Reserved) - - t.Run("DestroyPipeline", destroyPipelines("test-3")) - - time.Sleep(time.Second * 5) - stopCh <- struct{}{} - wg.Wait() -} - -func declareSQSPipe(t *testing.T) { - conn, err := net.Dial("tcp", "127.0.0.1:6001") - assert.NoError(t, err) - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - - pipe := &jobsv1beta.DeclareRequest{Pipeline: map[string]string{ - "driver": "sqs", - "name": "test-3", - "queue": "default", - "prefetch": "10", - "priority": "3", - "visibility_timeout": "0", - "wait_time_seconds": "3", - "tags": `{"key":"value"}`, - }} - - er := &jobsv1beta.Empty{} - err = client.Call("jobs.Declare", pipe, er) - assert.NoError(t, err) -} diff --git a/tests/plugins/jobs/jobs_with_toxics_test.go b/tests/plugins/jobs/jobs_with_toxics_test.go deleted file mode 100644 index 84fbec48..00000000 --- a/tests/plugins/jobs/jobs_with_toxics_test.go +++ /dev/null @@ -1,400 +0,0 @@ -package jobs - -import ( - "os" - "os/signal" - "sync" - "syscall" - "testing" - "time" - - toxiproxy "github.com/Shopify/toxiproxy/client" - "github.com/golang/mock/gomock" - endure "github.com/spiral/endure/pkg/container" - "github.com/spiral/roadrunner/v2/plugins/amqp" - "github.com/spiral/roadrunner/v2/plugins/beanstalk" - "github.com/spiral/roadrunner/v2/plugins/config" - "github.com/spiral/roadrunner/v2/plugins/informer" - "github.com/spiral/roadrunner/v2/plugins/jobs" - "github.com/spiral/roadrunner/v2/plugins/resetter" - rpcPlugin "github.com/spiral/roadrunner/v2/plugins/rpc" - "github.com/spiral/roadrunner/v2/plugins/server" - "github.com/spiral/roadrunner/v2/plugins/sqs" - "github.com/spiral/roadrunner/v2/tests/mocks" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestDurabilityAMQP(t *testing.T) { - client := toxiproxy.NewClient("127.0.0.1:8474") - proxies, err := client.Proxies() - require.NoError(t, err) - - for p := range proxies { - _ = proxies[p].Delete() - } - - proxy, err := client.CreateProxy("redial", "127.0.0.1:23679", "127.0.0.1:5672") - require.NoError(t, err) - defer func() { - _ = proxy.Delete() - }() - - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - require.NoError(t, err) - - cfg := &config.Viper{ - Path: "durability/.rr-amqp-durability-redial.yaml", - Prefix: "rr", - } - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - - // general - mockLogger.EXPECT().Debug("worker destructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("Started RPC service", "address", "tcp://127.0.0.1:6001", "plugins", gomock.Any()).Times(1) - - mockLogger.EXPECT().Info("pipeline active", "pipeline", "test-1", "start", gomock.Any(), "elapsed", gomock.Any()).Times(2) - mockLogger.EXPECT().Info("pipeline active", "pipeline", "test-2", "start", gomock.Any(), "elapsed", gomock.Any()).Times(2) - - mockLogger.EXPECT().Error(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() - - mockLogger.EXPECT().Warn("pipeline stopped", "pipeline", "test-1", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Warn("pipeline stopped", "pipeline", "test-2", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - - mockLogger.EXPECT().Info("job pushed to the queue", "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("job processing started", "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("job processed without errors", "ID", gomock.Any(), "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Error("job push error, job might be lost", "error", gomock.Any(), "pipeline", "test-1", "ID", gomock.Any(), "driver", "amqp", "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Error("job push error, job might be lost", "error", gomock.Any(), "pipeline", "test-2", "ID", gomock.Any(), "driver", "amqp", "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - - mockLogger.EXPECT().Info("delivery channel closed, leaving the rabbit listener").Times(4) - - // redial errors - mockLogger.EXPECT().Warn("rabbitmq reconnecting, caused by", "error", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Error("pipeline error", "pipeline", "test-1", "error", gomock.Any(), "start", gomock.Any(), "elapsed", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Error("pipeline error", "pipeline", "test-2", "error", gomock.Any(), "start", gomock.Any(), "elapsed", gomock.Any()).AnyTimes() - - mockLogger.EXPECT().Info("rabbitmq dial succeed. trying to redeclare queues and subscribers").AnyTimes() - mockLogger.EXPECT().Info("queues and subscribers redeclared successfully").AnyTimes() - - err = cont.RegisterAll( - cfg, - &server.Plugin{}, - &rpcPlugin.Plugin{}, - mockLogger, - &jobs.Plugin{}, - &resetter.Plugin{}, - &informer.Plugin{}, - &amqp.Plugin{}, - ) - require.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - if err != nil { - t.Fatal(err) - } - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 3) - disableProxy("redial", t) - time.Sleep(time.Second * 3) - - go func() { - time.Sleep(time.Second * 5) - enableProxy("redial", t) - }() - - t.Run("PushPipelineWhileRedialing-1", pushToPipeErr("test-1")) - t.Run("PushPipelineWhileRedialing-2", pushToPipeErr("test-2")) - - time.Sleep(time.Second * 15) - t.Run("PushPipelineWhileRedialing-1", pushToPipe("test-1")) - t.Run("PushPipelineWhileRedialing-2", pushToPipe("test-2")) - - time.Sleep(time.Second * 5) - - stopCh <- struct{}{} - wg.Wait() -} - -func TestDurabilitySQS(t *testing.T) { - client := toxiproxy.NewClient("127.0.0.1:8474") - - _, err := client.CreateProxy("redial", "127.0.0.1:19324", "127.0.0.1:9324") - require.NoError(t, err) - defer deleteProxy("redial", t) - - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - require.NoError(t, err) - - cfg := &config.Viper{ - Path: "durability/.rr-sqs-durability-redial.yaml", - Prefix: "rr", - } - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - - // general - mockLogger.EXPECT().Debug("worker destructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("Started RPC service", "address", "tcp://127.0.0.1:6001", "plugins", gomock.Any()).Times(1) - - mockLogger.EXPECT().Info("pipeline active", "pipeline", "test-1", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Info("pipeline active", "pipeline", "test-2", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - - mockLogger.EXPECT().Error(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() - - mockLogger.EXPECT().Warn("pipeline stopped", "pipeline", "test-1", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Warn("pipeline stopped", "pipeline", "test-2", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - - mockLogger.EXPECT().Info("job pushed to the queue", "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("job processing started", "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("job processed without errors", "ID", gomock.Any(), "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - // redial errors - mockLogger.EXPECT().Error("pipeline error", "pipeline", "test-1", "error", gomock.Any(), "start", gomock.Any(), "elapsed", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Error("pipeline error", "pipeline", "test-2", "error", gomock.Any(), "start", gomock.Any(), "elapsed", gomock.Any()).AnyTimes() - - // stop - mockLogger.EXPECT().Warn("sqs listener stopped").AnyTimes() - mockLogger.EXPECT().Info("------> job poller stopped <------").AnyTimes() - - err = cont.RegisterAll( - cfg, - &server.Plugin{}, - &rpcPlugin.Plugin{}, - mockLogger, - &jobs.Plugin{}, - &resetter.Plugin{}, - &informer.Plugin{}, - &sqs.Plugin{}, - ) - require.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - if err != nil { - t.Fatal(err) - } - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 3) - disableProxy("redial", t) - time.Sleep(time.Second * 3) - - go func() { - time.Sleep(time.Second) - t.Run("PushPipelineWhileRedialing-1", pushToPipe("test-1")) - time.Sleep(time.Second) - t.Run("PushPipelineWhileRedialing-2", pushToPipe("test-2")) - }() - - time.Sleep(time.Second * 5) - enableProxy("redial", t) - - t.Run("PushPipelineWhileRedialing-1", pushToPipe("test-1")) - t.Run("PushPipelineWhileRedialing-2", pushToPipe("test-2")) - - time.Sleep(time.Second * 10) - - stopCh <- struct{}{} - wg.Wait() -} - -func TestDurabilityBeanstalk(t *testing.T) { - client := toxiproxy.NewClient("127.0.0.1:8474") - - _, err := client.CreateProxy("redial", "127.0.0.1:11400", "127.0.0.1:11300") - require.NoError(t, err) - defer deleteProxy("redial", t) - - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - require.NoError(t, err) - - cfg := &config.Viper{ - Path: "durability/.rr-beanstalk-durability-redial.yaml", - Prefix: "rr", - } - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - - // general - mockLogger.EXPECT().Debug("worker destructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("Started RPC service", "address", "tcp://127.0.0.1:6001", "plugins", gomock.Any()).Times(1) - - mockLogger.EXPECT().Info("pipeline active", "pipeline", "test-1", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Info("pipeline active", "pipeline", "test-2", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - - mockLogger.EXPECT().Error(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() - - mockLogger.EXPECT().Info("job pushed to the queue", "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Warn("pipeline stopped", "pipeline", "test-1", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - mockLogger.EXPECT().Warn("pipeline stopped", "pipeline", "test-2", "start", gomock.Any(), "elapsed", gomock.Any()).Times(1) - - mockLogger.EXPECT().Info("job processing started", "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("job processed without errors", "ID", gomock.Any(), "start", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - // redial errors - mockLogger.EXPECT().Info("beanstalk redial was successful").MinTimes(2) - mockLogger.EXPECT().Error("pipeline error", "pipeline", "test-1", "error", gomock.Any(), "start", gomock.Any(), "elapsed", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Error("pipeline error", "pipeline", "test-2", "error", gomock.Any(), "start", gomock.Any(), "elapsed", gomock.Any()).AnyTimes() - - err = cont.RegisterAll( - cfg, - &server.Plugin{}, - &rpcPlugin.Plugin{}, - mockLogger, - &jobs.Plugin{}, - &resetter.Plugin{}, - &informer.Plugin{}, - &beanstalk.Plugin{}, - ) - require.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - if err != nil { - t.Fatal(err) - } - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 3) - disableProxy("redial", t) - time.Sleep(time.Second * 3) - - go func() { - time.Sleep(time.Second * 2) - t.Run("PushPipelineWhileRedialing-1", pushToPipe("test-1")) - t.Run("PushPipelineWhileRedialing-2", pushToPipe("test-2")) - }() - - time.Sleep(time.Second * 5) - enableProxy("redial", t) - - t.Run("PushPipelineWhileRedialing-1", pushToPipe("test-1")) - t.Run("PushPipelineWhileRedialing-2", pushToPipe("test-2")) - - time.Sleep(time.Second * 10) - - stopCh <- struct{}{} - wg.Wait() -} diff --git a/tests/plugins/jobs/memory/.rr-memory-declare.yaml b/tests/plugins/jobs/memory/.rr-memory-declare.yaml deleted file mode 100644 index 726c24ac..00000000 --- a/tests/plugins/jobs/memory/.rr-memory-declare.yaml +++ /dev/null @@ -1,21 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../jobs_ok.php" - relay: "pipes" - relay_timeout: "20s" - -logs: - level: debug - encoding: console - mode: development - -jobs: - num_pollers: 10 - pipeline_size: 100000 - pool: - num_workers: 10 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s diff --git a/tests/plugins/jobs/memory/.rr-memory-init.yaml b/tests/plugins/jobs/memory/.rr-memory-init.yaml deleted file mode 100644 index 9ee8afc2..00000000 --- a/tests/plugins/jobs/memory/.rr-memory-init.yaml +++ /dev/null @@ -1,37 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../jobs_ok.php" - relay: "pipes" - relay_timeout: "20s" - -logs: - level: debug - encoding: console - mode: development - -jobs: - num_pollers: 10 - pipeline_size: 100000 - pool: - num_workers: 10 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s - - pipelines: - test-1: - driver: memory - priority: 10 - prefetch: 10000 - - test-2: - driver: memory - priority: 10 - prefetch: 10000 - - - # list of pipelines to be consumed by the server, keep empty if you want to start consuming manually - consume: [ "test-1", "test-2" ] - diff --git a/tests/plugins/jobs/memory/.rr-memory-jobs-err.yaml b/tests/plugins/jobs/memory/.rr-memory-jobs-err.yaml deleted file mode 100644 index 05dc3ffa..00000000 --- a/tests/plugins/jobs/memory/.rr-memory-jobs-err.yaml +++ /dev/null @@ -1,21 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../jobs_err.php" - relay: "pipes" - relay_timeout: "20s" - -logs: - level: debug - encoding: console - mode: development - -jobs: - num_pollers: 10 - pipeline_size: 100000 - pool: - num_workers: 10 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s diff --git a/tests/plugins/jobs/memory/.rr-memory-pause-resume.yaml b/tests/plugins/jobs/memory/.rr-memory-pause-resume.yaml deleted file mode 100644 index 1ad48237..00000000 --- a/tests/plugins/jobs/memory/.rr-memory-pause-resume.yaml +++ /dev/null @@ -1,44 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../jobs_ok.php" - relay: "pipes" - relay_timeout: "20s" - -logs: - level: debug - mode: development - -jobs: - # num logical cores by default - num_pollers: 10 - # 1mi by default - pipeline_size: 100000 - # worker pool configuration - pool: - num_workers: 10 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s - - # list of broker pipelines associated with endpoints - pipelines: - test-local: - driver: memory - priority: 10 - pipeline_size: 10000 - - test-local-2: - driver: memory - priority: 1 - pipeline_size: 10000 - - test-local-3: - driver: memory - priority: 2 - pipeline_size: 10000 - - # list of pipelines to be consumed by the server, keep empty if you want to start consuming manually - consume: [ "test-local", "test-local-2" ] - diff --git a/tests/plugins/jobs/sqs/.rr-no-global.yaml b/tests/plugins/jobs/sqs/.rr-no-global.yaml deleted file mode 100644 index 2c97a37e..00000000 --- a/tests/plugins/jobs/sqs/.rr-no-global.yaml +++ /dev/null @@ -1,39 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../jobs_ok.php" - relay: "pipes" - relay_timeout: "20s" - -logs: - level: error - mode: development - -jobs: - num_pollers: 10 - pipeline_size: 100000 - pool: - num_workers: 10 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s - - pipelines: - test-1: - driver: sqs - prefetch: 1000 - visibility_timeout: 0 - wait_time_seconds: 0 - queue: default - attributes: - DelaySeconds: 0 - MaximumMessageSize: 262144 - MessageRetentionPeriod: 345600 - ReceiveMessageWaitTimeSeconds: 0 - VisibilityTimeout: 30 - tags: - test: "tag" - - consume: [ "test-1" ] - diff --git a/tests/plugins/jobs/sqs/.rr-sqs-declare.yaml b/tests/plugins/jobs/sqs/.rr-sqs-declare.yaml deleted file mode 100644 index 21209cbb..00000000 --- a/tests/plugins/jobs/sqs/.rr-sqs-declare.yaml +++ /dev/null @@ -1,29 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../jobs_ok.php" - relay: "pipes" - relay_timeout: "20s" - -# amazon sqs configuration -# General section -sqs: - key: api-key - secret: api-secret - region: us-west-1 - endpoint: http://127.0.0.1:9324 - -logs: - level: debug - encoding: console - mode: development - -jobs: - num_pollers: 1 - pipeline_size: 100000 - pool: - num_workers: 10 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s diff --git a/tests/plugins/jobs/sqs/.rr-sqs-init.yaml b/tests/plugins/jobs/sqs/.rr-sqs-init.yaml deleted file mode 100644 index ffdec1fd..00000000 --- a/tests/plugins/jobs/sqs/.rr-sqs-init.yaml +++ /dev/null @@ -1,54 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../client.php echo pipes" - relay: "pipes" - relay_timeout: "20s" - -sqs: - key: api-key - secret: api-secret - region: us-west-1 - endpoint: http://127.0.0.1:9324 - -logs: - level: debug - encoding: console - mode: development - -jobs: - num_pollers: 10 - pipeline_size: 100000 - pool: - num_workers: 10 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s - - pipelines: - test-1: - driver: sqs - prefetch: 1000 - visibility_timeout: 0 - wait_time_seconds: 0 - queue: default - attributes: - DelaySeconds: 0 - MaximumMessageSize: 262144 - MessageRetentionPeriod: 345600 - ReceiveMessageWaitTimeSeconds: 0 - VisibilityTimeout: 30 - tags: - test: "tag" - - test-2: - driver: sqs - prefetch: 1000 - queue: default-2 - attributes: - MessageRetentionPeriod: 86400 - tags: - test: "tag" - consume: [ "test-1", "test-2" ] - diff --git a/tests/plugins/jobs/sqs/.rr-sqs-jobs-err.yaml b/tests/plugins/jobs/sqs/.rr-sqs-jobs-err.yaml deleted file mode 100644 index b518d433..00000000 --- a/tests/plugins/jobs/sqs/.rr-sqs-jobs-err.yaml +++ /dev/null @@ -1,28 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../jobs_err.php" - relay: "pipes" - relay_timeout: "20s" - -sqs: - key: api-key - secret: api-secret - region: us-west-1 - endpoint: http://127.0.0.1:9324 - -logs: - level: debug - encoding: console - mode: development - -jobs: - num_pollers: 10 - timeout: 60 - pipeline_size: 100000 - pool: - num_workers: 10 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s diff --git a/tests/plugins/kv/configs/.rr-boltdb.yaml b/tests/plugins/kv/configs/.rr-boltdb.yaml deleted file mode 100644 index 7a8aee4e..00000000 --- a/tests/plugins/kv/configs/.rr-boltdb.yaml +++ /dev/null @@ -1,16 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -logs: - mode: development - level: error - -kv: - boltdb-rr: - driver: boltdb - config: - dir: "." - file: "rr.db" - bucket: "test" - permissions: 0666 - interval: 1 # seconds diff --git a/tests/plugins/kv/configs/.rr-in-memory.yaml b/tests/plugins/kv/configs/.rr-in-memory.yaml deleted file mode 100644 index 0452d8bc..00000000 --- a/tests/plugins/kv/configs/.rr-in-memory.yaml +++ /dev/null @@ -1,12 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -logs: - mode: development - level: error - -kv: - memory-rr: - driver: memory - config: - interval: 1 diff --git a/tests/plugins/kv/configs/.rr-kv-bolt-no-interval.yaml b/tests/plugins/kv/configs/.rr-kv-bolt-no-interval.yaml deleted file mode 100644 index 476369c5..00000000 --- a/tests/plugins/kv/configs/.rr-kv-bolt-no-interval.yaml +++ /dev/null @@ -1,19 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -logs: - mode: development - level: error - -kv: - boltdb-south: - driver: boltdb - config: - file: "rr.db" - permissions: 755 - - boltdb-africa: - driver: boltdb - config: - file: "africa.db" - permissions: 755 diff --git a/tests/plugins/kv/configs/.rr-kv-bolt-perms.yaml b/tests/plugins/kv/configs/.rr-kv-bolt-perms.yaml deleted file mode 100644 index e7728972..00000000 --- a/tests/plugins/kv/configs/.rr-kv-bolt-perms.yaml +++ /dev/null @@ -1,18 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -logs: - mode: development - level: error - -kv: - boltdb-south: - driver: boltdb - config: - file: "rr.db" - - boltdb-africa: - driver: boltdb - config: - file: "africa.db" - permissions: 0777 diff --git a/tests/plugins/kv/configs/.rr-kv-init.yaml b/tests/plugins/kv/configs/.rr-kv-init.yaml deleted file mode 100644 index 10cf6491..00000000 --- a/tests/plugins/kv/configs/.rr-kv-init.yaml +++ /dev/null @@ -1,35 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -logs: - mode: development - level: error - -kv: - default: - driver: memory - config: - interval: 60 - - boltdb-south: - driver: boltdb - config: - dir: "." - file: "rr.db" - bucket: "rr" - permissions: 0666 - interval: 1 - - boltdb-africa: - driver: boltdb - config: - dir: "." - file: "africa.db" - bucket: "rr" - permissions: 0666 - interval: 1 - - memcached: - driver: memcached - config: - addr: ["127.0.0.1:11211"] diff --git a/tests/plugins/kv/configs/.rr-memcached.yaml b/tests/plugins/kv/configs/.rr-memcached.yaml deleted file mode 100644 index ef8de2ab..00000000 --- a/tests/plugins/kv/configs/.rr-memcached.yaml +++ /dev/null @@ -1,13 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -logs: - mode: development - level: error - -kv: - memcached-rr: - driver: memcached - config: - addr: - - "127.0.0.1:11211" diff --git a/tests/plugins/kv/configs/.rr-redis-global.yaml b/tests/plugins/kv/configs/.rr-redis-global.yaml deleted file mode 100644 index 27377835..00000000 --- a/tests/plugins/kv/configs/.rr-redis-global.yaml +++ /dev/null @@ -1,14 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -logs: - mode: development - level: error - -redis-rr: - addrs: - - "127.0.0.1:6379" - -kv: - redis-rr: - driver: redis diff --git a/tests/plugins/kv/configs/.rr-redis-no-config.yaml b/tests/plugins/kv/configs/.rr-redis-no-config.yaml deleted file mode 100644 index 56113f13..00000000 --- a/tests/plugins/kv/configs/.rr-redis-no-config.yaml +++ /dev/null @@ -1,10 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -logs: - mode: development - level: error - -kv: - redis-rr: - driver: redis diff --git a/tests/plugins/kv/configs/.rr-redis.yaml b/tests/plugins/kv/configs/.rr-redis.yaml deleted file mode 100644 index f9b967d5..00000000 --- a/tests/plugins/kv/configs/.rr-redis.yaml +++ /dev/null @@ -1,13 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -logs: - mode: development - level: error - -kv: - redis-rr: - driver: redis - config: - addrs: - - "127.0.0.1:6379" diff --git a/tests/plugins/kv/storage_plugin_test.go b/tests/plugins/kv/storage_plugin_test.go deleted file mode 100644 index c10e4726..00000000 --- a/tests/plugins/kv/storage_plugin_test.go +++ /dev/null @@ -1,1517 +0,0 @@ -package kv - -import ( - "net" - "net/rpc" - "os" - "os/signal" - "sync" - "syscall" - "testing" - "time" - - "github.com/golang/mock/gomock" - endure "github.com/spiral/endure/pkg/container" - goridgeRpc "github.com/spiral/goridge/v3/pkg/rpc" - "github.com/spiral/roadrunner/v2/plugins/boltdb" - "github.com/spiral/roadrunner/v2/plugins/config" - "github.com/spiral/roadrunner/v2/plugins/kv" - "github.com/spiral/roadrunner/v2/plugins/logger" - "github.com/spiral/roadrunner/v2/plugins/memcached" - "github.com/spiral/roadrunner/v2/plugins/memory" - "github.com/spiral/roadrunner/v2/plugins/redis" - rpcPlugin "github.com/spiral/roadrunner/v2/plugins/rpc" - payload "github.com/spiral/roadrunner/v2/proto/kv/v1beta" - "github.com/spiral/roadrunner/v2/tests/mocks" - "github.com/stretchr/testify/assert" -) - -func TestKVInit(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-kv-init.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &memory.Plugin{}, - &boltdb.Plugin{}, - &memcached.Plugin{}, - &redis.Plugin{}, - &rpcPlugin.Plugin{}, - &logger.ZapLogger{}, - &kv.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - if err != nil { - t.Fatal(err) - } - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 1) - t.Run("KvSetTest", kvSetTest) - t.Run("KvHasTest", kvHasTest) - - stopCh <- struct{}{} - - wg.Wait() - - _ = os.RemoveAll("rr.db") - _ = os.RemoveAll("africa.db") -} - -func TestKVNoInterval(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-kv-bolt-no-interval.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &boltdb.Plugin{}, - &rpcPlugin.Plugin{}, - &logger.ZapLogger{}, - &kv.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - if err != nil { - t.Fatal(err) - } - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 1) - t.Run("KvSetTest", kvSetTest) - t.Run("KvHasTest", kvHasTest) - - stopCh <- struct{}{} - - wg.Wait() - - _ = os.RemoveAll("rr.db") - _ = os.RemoveAll("africa.db") -} - -func TestKVCreateToReopenWithPerms(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-kv-bolt-perms.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &boltdb.Plugin{}, - &rpcPlugin.Plugin{}, - &logger.ZapLogger{}, - &kv.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - if err != nil { - t.Fatal(err) - } - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 1) - stopCh <- struct{}{} - wg.Wait() -} - -func TestKVCreateToReopenWithPerms2(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-kv-bolt-perms.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &boltdb.Plugin{}, - &rpcPlugin.Plugin{}, - &logger.ZapLogger{}, - &kv.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - if err != nil { - t.Fatal(err) - } - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 1) - t.Run("KvSetTest", kvSetTest) - t.Run("KvHasTest", kvHasTest) - - stopCh <- struct{}{} - - wg.Wait() - - _ = os.RemoveAll("rr.db") - _ = os.RemoveAll("africa.db") -} - -func kvSetTest(t *testing.T) { - conn, err := net.Dial("tcp", "127.0.0.1:6001") - assert.NoError(t, err) - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - // WorkerList contains list of workers. - p := &payload.Request{ - Storage: "boltdb-south", - Items: []*payload.Item{ - { - Key: "key", - Value: []byte("val"), - }, - }, - } - - resp := &payload.Response{} - err = client.Call("kv.Set", p, resp) - assert.NoError(t, err) -} - -func kvHasTest(t *testing.T) { - conn, err := net.Dial("tcp", "127.0.0.1:6001") - assert.NoError(t, err) - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - // WorkerList contains list of workers. - p := &payload.Request{ - Storage: "boltdb-south", - Items: []*payload.Item{ - { - Key: "key", - Value: []byte("val"), - }, - }, - } - - ret := &payload.Response{} - err = client.Call("kv.Has", p, ret) - assert.NoError(t, err) - assert.Len(t, ret.GetItems(), 1) -} - -func TestBoltDb(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-boltdb.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &kv.Plugin{}, - &boltdb.Plugin{}, - &rpcPlugin.Plugin{}, - &logger.ZapLogger{}, - &memory.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 1) - t.Run("BOLTDB", testRPCMethods) - stopCh <- struct{}{} - wg.Wait() - - _ = os.Remove("rr.db") -} - -func testRPCMethods(t *testing.T) { - conn, err := net.Dial("tcp", "127.0.0.1:6001") - assert.NoError(t, err) - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - - // add 5 second ttl - tt := time.Now().Add(time.Second * 5).Format(time.RFC3339) - keys := &payload.Request{ - Storage: "boltdb-rr", - Items: []*payload.Item{ - { - Key: "a", - }, - { - Key: "b", - }, - { - Key: "c", - }, - }, - } - - data := &payload.Request{ - Storage: "boltdb-rr", - Items: []*payload.Item{ - { - Key: "a", - Value: []byte("aa"), - }, - { - Key: "b", - Value: []byte("bb"), - }, - { - Key: "c", - Value: []byte("cc"), - Timeout: tt, - }, - { - Key: "d", - Value: []byte("dd"), - }, - { - Key: "e", - Value: []byte("ee"), - }, - }, - } - - ret := &payload.Response{} - // Register 3 keys with values - err = client.Call("kv.Set", data, ret) - assert.NoError(t, err) - - ret = &payload.Response{} - err = client.Call("kv.Has", keys, ret) - assert.NoError(t, err) - assert.Len(t, ret.GetItems(), 3) // should be 3 - - // key "c" should be deleted - time.Sleep(time.Second * 7) - - ret = &payload.Response{} - err = client.Call("kv.Has", keys, ret) - assert.NoError(t, err) - assert.Len(t, ret.GetItems(), 2) // should be 2 - - ret = &payload.Response{} - err = client.Call("kv.MGet", keys, ret) - assert.NoError(t, err) - assert.Len(t, ret.GetItems(), 2) // c is expired - - tt2 := time.Now().Add(time.Second * 10).Format(time.RFC3339) - - data2 := &payload.Request{ - Storage: "boltdb-rr", - Items: []*payload.Item{ - { - Key: "a", - Timeout: tt2, - }, - { - Key: "b", - Timeout: tt2, - }, - { - Key: "d", - Timeout: tt2, - }, - }, - } - - // MEXPIRE - ret = &payload.Response{} - err = client.Call("kv.MExpire", data2, ret) - assert.NoError(t, err) - - // TTL - keys2 := &payload.Request{ - Storage: "boltdb-rr", - Items: []*payload.Item{ - { - Key: "a", - }, - { - Key: "b", - }, - { - Key: "d", - }, - }, - } - - ret = &payload.Response{} - err = client.Call("kv.TTL", keys2, ret) - assert.NoError(t, err) - assert.Len(t, ret.GetItems(), 3) - - // HAS AFTER TTL - time.Sleep(time.Second * 15) - ret = &payload.Response{} - err = client.Call("kv.Has", keys2, ret) - assert.NoError(t, err) - assert.Len(t, ret.GetItems(), 0) - - // DELETE - keysDel := &payload.Request{ - Storage: "boltdb-rr", - Items: []*payload.Item{ - { - Key: "e", - }, - }, - } - - ret = &payload.Response{} - err = client.Call("kv.Delete", keysDel, ret) - assert.NoError(t, err) - - // HAS AFTER DELETE - ret = &payload.Response{} - err = client.Call("kv.Has", keysDel, ret) - assert.NoError(t, err) - assert.Len(t, ret.GetItems(), 0) - - dataClear := &payload.Request{ - Storage: "boltdb-rr", - Items: []*payload.Item{ - { - Key: "a", - Value: []byte("aa"), - }, - { - Key: "b", - Value: []byte("bb"), - }, - { - Key: "c", - Value: []byte("cc"), - }, - { - Key: "d", - Value: []byte("dd"), - }, - { - Key: "e", - Value: []byte("ee"), - }, - }, - } - - clear := &payload.Request{Storage: "boltdb-rr"} - - ret = &payload.Response{} - // Register 3 keys with values - err = client.Call("kv.Set", dataClear, ret) - assert.NoError(t, err) - - ret = &payload.Response{} - err = client.Call("kv.Has", dataClear, ret) - assert.NoError(t, err) - assert.Len(t, ret.GetItems(), 5) // should be 5 - - ret = &payload.Response{} - err = client.Call("kv.Clear", clear, ret) - assert.NoError(t, err) - - ret = &payload.Response{} - err = client.Call("kv.Has", dataClear, ret) - assert.NoError(t, err) - assert.Len(t, ret.GetItems(), 0) // should be 5 -} - -func TestMemcached(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-memcached.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &kv.Plugin{}, - &memcached.Plugin{}, - &rpcPlugin.Plugin{}, - &logger.ZapLogger{}, - &memory.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 1) - t.Run("MEMCACHED", testRPCMethodsMemcached) - stopCh <- struct{}{} - wg.Wait() -} - -func testRPCMethodsMemcached(t *testing.T) { - conn, err := net.Dial("tcp", "127.0.0.1:6001") - assert.NoError(t, err) - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - - // add 5 second ttl - tt := time.Now().Add(time.Second * 5).Format(time.RFC3339) - - keys := &payload.Request{ - Storage: "memcached-rr", - Items: []*payload.Item{ - { - Key: "a", - }, - { - Key: "b", - }, - { - Key: "c", - }, - }, - } - - data := &payload.Request{ - Storage: "memcached-rr", - Items: []*payload.Item{ - { - Key: "a", - Value: []byte("aa"), - }, - { - Key: "b", - Value: []byte("bb"), - }, - { - Key: "c", - Value: []byte("cc"), - Timeout: tt, - }, - { - Key: "d", - Value: []byte("dd"), - }, - { - Key: "e", - Value: []byte("ee"), - }, - }, - } - - ret := &payload.Response{} - // Register 3 keys with values - err = client.Call("kv.Set", data, ret) - assert.NoError(t, err) - - ret = &payload.Response{} - err = client.Call("kv.Has", keys, ret) - assert.NoError(t, err) - assert.Len(t, ret.GetItems(), 3) // should be 3 - - // key "c" should be deleted - time.Sleep(time.Second * 7) - - ret = &payload.Response{} - err = client.Call("kv.Has", keys, ret) - assert.NoError(t, err) - assert.Len(t, ret.GetItems(), 2) // should be 2 - - ret = &payload.Response{} - err = client.Call("kv.MGet", keys, ret) - assert.NoError(t, err) - assert.Len(t, ret.GetItems(), 2) // c is expired - - tt2 := time.Now().Add(time.Second * 10).Format(time.RFC3339) - - data2 := &payload.Request{ - Storage: "memcached-rr", - Items: []*payload.Item{ - { - Key: "a", - Timeout: tt2, - }, - { - Key: "b", - Timeout: tt2, - }, - { - Key: "d", - Timeout: tt2, - }, - }, - } - - // MEXPIRE - ret = &payload.Response{} - err = client.Call("kv.MExpire", data2, ret) - assert.NoError(t, err) - - // TTL call is not supported for the memcached driver - keys2 := &payload.Request{ - Storage: "memcached-rr", - Items: []*payload.Item{ - { - Key: "a", - }, - { - Key: "b", - }, - { - Key: "d", - }, - }, - } - - ret = &payload.Response{} - err = client.Call("kv.TTL", keys2, ret) - assert.Error(t, err) - assert.Len(t, ret.GetItems(), 0) - - // HAS AFTER TTL - time.Sleep(time.Second * 15) - ret = &payload.Response{} - err = client.Call("kv.Has", keys2, ret) - assert.NoError(t, err) - assert.Len(t, ret.GetItems(), 0) - - // DELETE - keysDel := &payload.Request{ - Storage: "memcached-rr", - Items: []*payload.Item{ - { - Key: "e", - }, - }, - } - - ret = &payload.Response{} - err = client.Call("kv.Delete", keysDel, ret) - assert.NoError(t, err) - - // HAS AFTER DELETE - ret = &payload.Response{} - err = client.Call("kv.Has", keysDel, ret) - assert.NoError(t, err) - assert.Len(t, ret.GetItems(), 0) - - dataClear := &payload.Request{ - Storage: "memcached-rr", - Items: []*payload.Item{ - { - Key: "a", - Value: []byte("aa"), - }, - { - Key: "b", - Value: []byte("bb"), - }, - { - Key: "c", - Value: []byte("cc"), - }, - { - Key: "d", - Value: []byte("dd"), - }, - { - Key: "e", - Value: []byte("ee"), - }, - }, - } - - clear := &payload.Request{Storage: "memcached-rr"} - - ret = &payload.Response{} - // Register 3 keys with values - err = client.Call("kv.Set", dataClear, ret) - assert.NoError(t, err) - - ret = &payload.Response{} - err = client.Call("kv.Has", dataClear, ret) - assert.NoError(t, err) - assert.Len(t, ret.GetItems(), 5) // should be 5 - - ret = &payload.Response{} - err = client.Call("kv.Clear", clear, ret) - assert.NoError(t, err) - - time.Sleep(time.Second * 2) - ret = &payload.Response{} - err = client.Call("kv.Has", dataClear, ret) - assert.NoError(t, err) - assert.Len(t, ret.GetItems(), 0) // should be 5 -} - -func TestInMemory(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-in-memory.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &kv.Plugin{}, - &memory.Plugin{}, - &rpcPlugin.Plugin{}, - &logger.ZapLogger{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 1) - t.Run("INMEMORY", testRPCMethodsInMemory) - stopCh <- struct{}{} - wg.Wait() -} - -func testRPCMethodsInMemory(t *testing.T) { - conn, err := net.Dial("tcp", "127.0.0.1:6001") - assert.NoError(t, err) - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - - // add 5 second ttl - - tt := time.Now().Add(time.Second * 5).Format(time.RFC3339) - keys := &payload.Request{ - Storage: "memory-rr", - Items: []*payload.Item{ - { - Key: "a", - }, - { - Key: "b", - }, - { - Key: "c", - }, - }, - } - - data := &payload.Request{ - Storage: "memory-rr", - Items: []*payload.Item{ - { - Key: "a", - Value: []byte("aa"), - }, - { - Key: "b", - Value: []byte("bb"), - }, - { - Key: "c", - Value: []byte("cc"), - Timeout: tt, - }, - { - Key: "d", - Value: []byte("dd"), - }, - { - Key: "e", - Value: []byte("ee"), - }, - }, - } - - ret := &payload.Response{} - // Register 3 keys with values - err = client.Call("kv.Set", data, ret) - assert.NoError(t, err) - - ret = &payload.Response{} - err = client.Call("kv.Has", keys, ret) - assert.NoError(t, err) - assert.Len(t, ret.GetItems(), 3) // should be 3 - - // key "c" should be deleted - time.Sleep(time.Second * 7) - - ret = &payload.Response{} - err = client.Call("kv.Has", keys, ret) - assert.NoError(t, err) - assert.Len(t, ret.GetItems(), 2) // should be 2 - - ret = &payload.Response{} - err = client.Call("kv.MGet", keys, ret) - assert.NoError(t, err) - assert.Len(t, ret.GetItems(), 2) // c is expired - - tt2 := time.Now().Add(time.Second * 10).Format(time.RFC3339) - - data2 := &payload.Request{ - Storage: "memory-rr", - Items: []*payload.Item{ - { - Key: "a", - Timeout: tt2, - }, - { - Key: "b", - Timeout: tt2, - }, - { - Key: "d", - Timeout: tt2, - }, - }, - } - - // MEXPIRE - ret = &payload.Response{} - err = client.Call("kv.MExpire", data2, ret) - assert.NoError(t, err) - - // TTL - keys2 := &payload.Request{ - Storage: "memory-rr", - Items: []*payload.Item{ - { - Key: "a", - }, - { - Key: "b", - }, - { - Key: "d", - }, - }, - } - - ret = &payload.Response{} - err = client.Call("kv.TTL", keys2, ret) - assert.NoError(t, err) - assert.Len(t, ret.GetItems(), 3) - - // HAS AFTER TTL - time.Sleep(time.Second * 15) - ret = &payload.Response{} - err = client.Call("kv.Has", keys2, ret) - assert.NoError(t, err) - assert.Len(t, ret.GetItems(), 0) - - // DELETE - keysDel := &payload.Request{ - Storage: "memory-rr", - Items: []*payload.Item{ - { - Key: "e", - }, - }, - } - - ret = &payload.Response{} - err = client.Call("kv.Delete", keysDel, ret) - assert.NoError(t, err) - - // HAS AFTER DELETE - ret = &payload.Response{} - err = client.Call("kv.Has", keysDel, ret) - assert.NoError(t, err) - assert.Len(t, ret.GetItems(), 0) - - dataClear := &payload.Request{ - Storage: "memory-rr", - Items: []*payload.Item{ - { - Key: "a", - Value: []byte("aa"), - }, - { - Key: "b", - Value: []byte("bb"), - }, - { - Key: "c", - Value: []byte("cc"), - }, - { - Key: "d", - Value: []byte("dd"), - }, - { - Key: "e", - Value: []byte("ee"), - }, - }, - } - - clear := &payload.Request{Storage: "memory-rr"} - - ret = &payload.Response{} - // Register 3 keys with values - err = client.Call("kv.Set", dataClear, ret) - assert.NoError(t, err) - - ret = &payload.Response{} - err = client.Call("kv.Has", dataClear, ret) - assert.NoError(t, err) - assert.Len(t, ret.GetItems(), 5) // should be 5 - - ret = &payload.Response{} - err = client.Call("kv.Clear", clear, ret) - assert.NoError(t, err) - - ret = &payload.Response{} - err = client.Call("kv.Has", dataClear, ret) - assert.NoError(t, err) - assert.Len(t, ret.GetItems(), 0) // should be 5 -} - -func TestRedis(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-redis.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &kv.Plugin{}, - &redis.Plugin{}, - &rpcPlugin.Plugin{}, - &logger.ZapLogger{}, - &memory.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 1) - t.Run("REDIS", testRPCMethodsRedis) - stopCh <- struct{}{} - wg.Wait() -} - -func TestRedisGlobalSection(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-redis-global.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &kv.Plugin{}, - &redis.Plugin{}, - &rpcPlugin.Plugin{}, - &logger.ZapLogger{}, - &memory.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 1) - t.Run("REDIS", testRPCMethodsRedis) - stopCh <- struct{}{} - wg.Wait() -} - -func TestRedisNoConfig(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-redis-no-config.yaml", // should be used default - Prefix: "rr", - } - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - - mockLogger.EXPECT().Debug("worker destructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("Started RPC service", "address", "tcp://127.0.0.1:6001", "plugins", []string{"kv"}).AnyTimes() - - mockLogger.EXPECT().Error(`can't find local or global configuration, this section will be skipped`, "local: ", "kv.redis-rr.config", "global: ", "redis-rr").Times(1) - - err = cont.RegisterAll( - cfg, - &kv.Plugin{}, - &redis.Plugin{}, - &rpcPlugin.Plugin{}, - mockLogger, - &memory.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - _, err = cont.Serve() - assert.NoError(t, err) -} - -func testRPCMethodsRedis(t *testing.T) { - conn, err := net.Dial("tcp", "127.0.0.1:6001") - assert.NoError(t, err) - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - - // add 5 second ttl - tt := time.Now().Add(time.Second * 5).Format(time.RFC3339) - keys := &payload.Request{ - Storage: "redis-rr", - Items: []*payload.Item{ - { - Key: "a", - }, - { - Key: "b", - }, - { - Key: "c", - }, - }, - } - - data := &payload.Request{ - Storage: "redis-rr", - Items: []*payload.Item{ - { - Key: "a", - Value: []byte("aa"), - }, - { - Key: "b", - Value: []byte("bb"), - }, - { - Key: "c", - Value: []byte("cc"), - Timeout: tt, - }, - { - Key: "d", - Value: []byte("dd"), - }, - { - Key: "e", - Value: []byte("ee"), - }, - }, - } - - ret := &payload.Response{} - // Register 3 keys with values - err = client.Call("kv.Set", data, ret) - assert.NoError(t, err) - - ret = &payload.Response{} - err = client.Call("kv.Has", keys, ret) - assert.NoError(t, err) - assert.Len(t, ret.GetItems(), 3) // should be 3 - - // key "c" should be deleted - time.Sleep(time.Second * 7) - - ret = &payload.Response{} - err = client.Call("kv.Has", keys, ret) - assert.NoError(t, err) - assert.Len(t, ret.GetItems(), 2) // should be 2 - - ret = &payload.Response{} - err = client.Call("kv.MGet", keys, ret) - assert.NoError(t, err) - assert.Len(t, ret.GetItems(), 2) // c is expired - - tt2 := time.Now().Add(time.Second * 10).Format(time.RFC3339) - - data2 := &payload.Request{ - Storage: "redis-rr", - Items: []*payload.Item{ - { - Key: "a", - Timeout: tt2, - }, - { - Key: "b", - Timeout: tt2, - }, - { - Key: "d", - Timeout: tt2, - }, - }, - } - - // MEXPIRE - ret = &payload.Response{} - err = client.Call("kv.MExpire", data2, ret) - assert.NoError(t, err) - - // TTL - keys2 := &payload.Request{ - Storage: "redis-rr", - Items: []*payload.Item{ - { - Key: "a", - }, - { - Key: "b", - }, - { - Key: "d", - }, - }, - } - - ret = &payload.Response{} - err = client.Call("kv.TTL", keys2, ret) - assert.NoError(t, err) - assert.Len(t, ret.GetItems(), 3) - - // HAS AFTER TTL - time.Sleep(time.Second * 15) - ret = &payload.Response{} - err = client.Call("kv.Has", keys2, ret) - assert.NoError(t, err) - assert.Len(t, ret.GetItems(), 0) - - // DELETE - keysDel := &payload.Request{ - Storage: "redis-rr", - Items: []*payload.Item{ - { - Key: "e", - }, - }, - } - - ret = &payload.Response{} - err = client.Call("kv.Delete", keysDel, ret) - assert.NoError(t, err) - - // HAS AFTER DELETE - ret = &payload.Response{} - err = client.Call("kv.Has", keysDel, ret) - assert.NoError(t, err) - assert.Len(t, ret.GetItems(), 0) - - dataClear := &payload.Request{ - Storage: "redis-rr", - Items: []*payload.Item{ - { - Key: "a", - Value: []byte("aa"), - }, - { - Key: "b", - Value: []byte("bb"), - }, - { - Key: "c", - Value: []byte("cc"), - }, - { - Key: "d", - Value: []byte("dd"), - }, - { - Key: "e", - Value: []byte("ee"), - }, - }, - } - - clear := &payload.Request{Storage: "redis-rr"} - - ret = &payload.Response{} - // Register 3 keys with values - err = client.Call("kv.Set", dataClear, ret) - assert.NoError(t, err) - - ret = &payload.Response{} - err = client.Call("kv.Has", dataClear, ret) - assert.NoError(t, err) - assert.Len(t, ret.GetItems(), 5) // should be 5 - - ret = &payload.Response{} - err = client.Call("kv.Clear", clear, ret) - assert.NoError(t, err) - - ret = &payload.Response{} - err = client.Call("kv.Has", dataClear, ret) - assert.NoError(t, err) - assert.Len(t, ret.GetItems(), 0) // should be 5 -} diff --git a/tests/plugins/logger/configs/.rr-file-logger.yaml b/tests/plugins/logger/configs/.rr-file-logger.yaml deleted file mode 100644 index 49c30d02..00000000 --- a/tests/plugins/logger/configs/.rr-file-logger.yaml +++ /dev/null @@ -1,23 +0,0 @@ -server: - command: "php ../../http/client.php echo pipes" - relay: "pipes" - relay_timeout: "20s" - -http: - address: 127.0.0.1:54224 - max_request_size: 1024 - middleware: [ ] - uploads: - forbid: [ ".php", ".exe", ".bat" ] - trusted_subnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] - pool: - num_workers: 2 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s - -logs: - mode: development - level: debug - file_logger_options: - log_output: "test.log" diff --git a/tests/plugins/logger/configs/.rr-no-logger.yaml b/tests/plugins/logger/configs/.rr-no-logger.yaml deleted file mode 100644 index e69de29b..00000000 --- a/tests/plugins/logger/configs/.rr-no-logger.yaml +++ /dev/null diff --git a/tests/plugins/logger/configs/.rr-no-logger2.yaml b/tests/plugins/logger/configs/.rr-no-logger2.yaml deleted file mode 100644 index 810ea88f..00000000 --- a/tests/plugins/logger/configs/.rr-no-logger2.yaml +++ /dev/null @@ -1,16 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../http/client.php echo pipes" - relay: "pipes" - relay_timeout: "20s" - -http: - address: 127.0.0.1:18945 - max_request_size: 1024 - pool: - num_workers: 2 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s diff --git a/tests/plugins/logger/configs/.rr-raw-mode.yaml b/tests/plugins/logger/configs/.rr-raw-mode.yaml deleted file mode 100644 index fba25945..00000000 --- a/tests/plugins/logger/configs/.rr-raw-mode.yaml +++ /dev/null @@ -1,15 +0,0 @@ -server: - command: "php ../../raw-error.php" - relay: "pipes" - -http: - address: 127.0.0.1:34999 - max_requestSize: 1024 - pool: - num_workers: 1 - max_jobs: 0 - allocate_timeout: 10s - destroy_timeout: 10s - -logs: - mode: raw diff --git a/tests/plugins/logger/configs/.rr.yaml b/tests/plugins/logger/configs/.rr.yaml deleted file mode 100644 index 5ab359d3..00000000 --- a/tests/plugins/logger/configs/.rr.yaml +++ /dev/null @@ -1,3 +0,0 @@ -logs: - mode: development - level: error
\ No newline at end of file diff --git a/tests/plugins/logger/logger_test.go b/tests/plugins/logger/logger_test.go deleted file mode 100644 index e077f0bc..00000000 --- a/tests/plugins/logger/logger_test.go +++ /dev/null @@ -1,430 +0,0 @@ -package logger - -import ( - "net/http" - "os" - "os/signal" - "strings" - "sync" - "syscall" - "testing" - "time" - - "github.com/golang/mock/gomock" - endure "github.com/spiral/endure/pkg/container" - "github.com/spiral/roadrunner/v2/plugins/config" - httpPlugin "github.com/spiral/roadrunner/v2/plugins/http" - "github.com/spiral/roadrunner/v2/plugins/logger" - "github.com/spiral/roadrunner/v2/plugins/rpc" - "github.com/spiral/roadrunner/v2/plugins/server" - "github.com/spiral/roadrunner/v2/tests/mocks" - "github.com/stretchr/testify/assert" -) - -func TestLogger(t *testing.T) { - container, err := endure.NewContainer(nil, endure.RetryOnFail(false), endure.SetLogLevel(endure.ErrorLevel)) - if err != nil { - t.Fatal(err) - } - // config plugin - vp := &config.Viper{} - vp.Path = "configs/.rr.yaml" - vp.Prefix = "rr" - - err = container.RegisterAll( - vp, - &Plugin{}, - &logger.ZapLogger{}, - ) - assert.NoError(t, err) - - err = container.Init() - if err != nil { - t.Fatal(err) - } - - errCh, err := container.Serve() - if err != nil { - t.Fatal(err) - } - - // stop by CTRL+C - c := make(chan os.Signal, 1) - signal.Notify(c, os.Interrupt) - - stopCh := make(chan struct{}, 1) - - wg := &sync.WaitGroup{} - wg.Add(1) - - go func() { - defer wg.Done() - for { - select { - case e := <-errCh: - assert.NoError(t, e.Error) - assert.NoError(t, container.Stop()) - return - case <-c: - err = container.Stop() - assert.NoError(t, err) - return - case <-stopCh: - assert.NoError(t, container.Stop()) - return - } - } - }() - - stopCh <- struct{}{} - wg.Wait() -} - -func TestLoggerRawErr(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - // config plugin - cfg := &config.Viper{} - cfg.Path = "configs/.rr-raw-mode.yaml" - cfg.Prefix = "rr" - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - - mockLogger.EXPECT().Debug("worker destructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Info("{\"field\": \"value\"}").MinTimes(1) - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).MinTimes(1) - - err = cont.RegisterAll( - cfg, - mockLogger, - &server.Plugin{}, - &httpPlugin.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - stopCh <- struct{}{} - wg.Wait() -} - -func TestLoggerNoConfig(t *testing.T) { - container, err := endure.NewContainer(nil, endure.RetryOnFail(true), endure.SetLogLevel(endure.ErrorLevel)) - if err != nil { - t.Fatal(err) - } - // config plugin - vp := &config.Viper{} - vp.Path = "configs/.rr-no-logger.yaml" - vp.Prefix = "rr" - - err = container.RegisterAll( - vp, - &Plugin{}, - &logger.ZapLogger{}, - ) - assert.NoError(t, err) - - err = container.Init() - if err != nil { - t.Fatal(err) - } - - errCh, err := container.Serve() - if err != nil { - t.Fatal(err) - } - - // stop by CTRL+C - c := make(chan os.Signal, 1) - signal.Notify(c, os.Interrupt) - - stopCh := make(chan struct{}, 1) - - wg := &sync.WaitGroup{} - wg.Add(1) - - go func() { - defer wg.Done() - for { - select { - case e := <-errCh: - assert.NoError(t, e.Error) - assert.NoError(t, container.Stop()) - return - case <-c: - err = container.Stop() - assert.NoError(t, err) - return - case <-stopCh: - assert.NoError(t, container.Stop()) - return - } - } - }() - - stopCh <- struct{}{} - wg.Wait() -} - -// Should no panic -func TestLoggerNoConfig2(t *testing.T) { - container, err := endure.NewContainer(nil, endure.RetryOnFail(true), endure.SetLogLevel(endure.ErrorLevel)) - if err != nil { - t.Fatal(err) - } - // config plugin - vp := &config.Viper{} - vp.Path = "configs/.rr-no-logger2.yaml" - vp.Prefix = "rr" - - err = container.RegisterAll( - vp, - &rpc.Plugin{}, - &logger.ZapLogger{}, - &httpPlugin.Plugin{}, - &server.Plugin{}, - ) - assert.NoError(t, err) - - err = container.Init() - if err != nil { - t.Fatal(err) - } - - errCh, err := container.Serve() - if err != nil { - t.Fatal(err) - } - - // stop by CTRL+C - c := make(chan os.Signal, 1) - signal.Notify(c, os.Interrupt) - - stopCh := make(chan struct{}, 1) - - wg := &sync.WaitGroup{} - wg.Add(1) - - go func() { - defer wg.Done() - for { - select { - case e := <-errCh: - assert.NoError(t, e.Error) - assert.NoError(t, container.Stop()) - return - case <-c: - err = container.Stop() - assert.NoError(t, err) - return - case <-stopCh: - assert.NoError(t, container.Stop()) - return - } - } - }() - - stopCh <- struct{}{} - wg.Wait() -} - -func TestFileLogger(t *testing.T) { - container, err := endure.NewContainer(nil, endure.RetryOnFail(true), endure.SetLogLevel(endure.ErrorLevel)) - if err != nil { - t.Fatal(err) - } - // config plugin - vp := &config.Viper{} - vp.Path = "configs/.rr-file-logger.yaml" - vp.Prefix = "rr" - - err = container.RegisterAll( - vp, - &rpc.Plugin{}, - &logger.ZapLogger{}, - &httpPlugin.Plugin{}, - &server.Plugin{}, - ) - assert.NoError(t, err) - - err = container.Init() - if err != nil { - t.Fatal(err) - } - - errCh, err := container.Serve() - if err != nil { - t.Fatal(err) - } - - // stop by CTRL+C - c := make(chan os.Signal, 1) - signal.Notify(c, os.Interrupt) - - stopCh := make(chan struct{}, 1) - - wg := &sync.WaitGroup{} - wg.Add(1) - - go func() { - defer wg.Done() - for { - select { - case e := <-errCh: - assert.NoError(t, e.Error) - assert.NoError(t, container.Stop()) - return - case <-c: - err = container.Stop() - assert.NoError(t, err) - return - case <-stopCh: - assert.NoError(t, container.Stop()) - return - } - } - }() - - time.Sleep(time.Second * 2) - t.Run("HTTPEchoReq", httpEcho) - - f, err := os.ReadFile("test.log") - if err != nil { - t.Fatal(err) - } - - strings.Contains(string(f), "worker constructed") - strings.Contains(string(f), "201 GET") - - _ = os.Remove("test.log") - - stopCh <- struct{}{} - wg.Wait() -} - -func TestMarshalObjectLogging(t *testing.T) { - container, err := endure.NewContainer(nil, endure.RetryOnFail(true), endure.SetLogLevel(endure.ErrorLevel)) - if err != nil { - t.Fatal(err) - } - // config plugin - vp := &config.Viper{} - vp.Path = "configs/.rr-file-logger.yaml" - vp.Prefix = "rr" - - err = container.RegisterAll( - vp, - &Plugin{}, - &logger.ZapLogger{}, - ) - assert.NoError(t, err) - - err = container.Init() - if err != nil { - t.Fatal(err) - } - - errCh, err := container.Serve() - if err != nil { - t.Fatal(err) - } - - // stop by CTRL+C - c := make(chan os.Signal, 1) - signal.Notify(c, os.Interrupt) - - stopCh := make(chan struct{}, 1) - - wg := &sync.WaitGroup{} - wg.Add(1) - - go func() { - defer wg.Done() - for { - select { - case e := <-errCh: - assert.NoError(t, e.Error) - assert.NoError(t, container.Stop()) - return - case <-c: - err = container.Stop() - assert.NoError(t, err) - return - case <-stopCh: - assert.NoError(t, container.Stop()) - return - } - } - }() - - time.Sleep(time.Second * 2) - - f, err := os.ReadFile("test.log") - if err != nil { - t.Fatal(err) - } - - assert.Contains(t, string(f), "Example marshaller error") - assert.Equal(t, 4, strings.Count(string(f), "Example marshaller error")) - - _ = os.Remove("test.log") - - stopCh <- struct{}{} - wg.Wait() -} - -func httpEcho(t *testing.T) { - req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:54224?hello=world", nil) - assert.NoError(t, err) - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - assert.Equal(t, http.StatusCreated, r.StatusCode) - - err = r.Body.Close() - assert.NoError(t, err) -} diff --git a/tests/plugins/logger/plugin.go b/tests/plugins/logger/plugin.go deleted file mode 100644 index 54e78d7b..00000000 --- a/tests/plugins/logger/plugin.go +++ /dev/null @@ -1,71 +0,0 @@ -package logger - -import ( - "strings" - - "github.com/spiral/errors" - "github.com/spiral/roadrunner/v2/plugins/config" - "github.com/spiral/roadrunner/v2/plugins/logger" - "go.uber.org/zap" - core "go.uber.org/zap/zapcore" -) - -type Plugin struct { - config config.Configurer - log logger.Logger -} - -type Loggable struct { -} - -func (l *Loggable) MarshalLogObject(encoder core.ObjectEncoder) error { - encoder.AddString("error", "Example marshaller error") - return nil -} - -func (p1 *Plugin) Init(cfg config.Configurer, log logger.Logger) error { - p1.config = cfg - p1.log = log - return nil -} - -func (p1 *Plugin) Serve() chan error { - errCh := make(chan error, 1) - p1.log.Error("error", "test", errors.E(errors.Str("test"))) - p1.log.Info("error", "test", errors.E(errors.Str("test"))) - p1.log.Debug("error", "test", errors.E(errors.Str("test"))) - p1.log.Warn("error", "test", errors.E(errors.Str("test"))) - - field := zap.String("error", "Example field error") - - p1.log.Error("error", field) - p1.log.Info("error", field) - p1.log.Debug("error", field) - p1.log.Warn("error", field) - - marshalledObject := &Loggable{} - - p1.log.Error("error", marshalledObject) - p1.log.Info("error", marshalledObject) - p1.log.Debug("error", marshalledObject) - p1.log.Warn("error", marshalledObject) - - p1.log.Error("error", "test") - p1.log.Info("error", "test") - p1.log.Debug("error", "test") - p1.log.Warn("error", "test") - - // test the `raw` mode - messageJSON := []byte(`{"field": "value"}`) - p1.log.Debug(strings.TrimRight(string(messageJSON), " \n\t")) - - return errCh -} - -func (p1 *Plugin) Stop() error { - return nil -} - -func (p1 *Plugin) Name() string { - return "logger_plugin" -} diff --git a/tests/plugins/metrics/configs/.rr-http-metrics.yaml b/tests/plugins/metrics/configs/.rr-http-metrics.yaml deleted file mode 100644 index 3e92a88c..00000000 --- a/tests/plugins/metrics/configs/.rr-http-metrics.yaml +++ /dev/null @@ -1,20 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../psr-worker-bench.php" - relay: "pipes" - -http: - address: 127.0.0.1:13223 - max_request_size: 1024 - middleware: [ ] - pool: - num_workers: 1 - -metrics: - address: 127.0.0.1:2112 - -logs: - mode: development - level: debug diff --git a/tests/plugins/metrics/configs/.rr-issue-571.yaml b/tests/plugins/metrics/configs/.rr-issue-571.yaml deleted file mode 100644 index 872f777a..00000000 --- a/tests/plugins/metrics/configs/.rr-issue-571.yaml +++ /dev/null @@ -1,13 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../metrics-issue-571.php" - -http: - address: "0.0.0.0:56444" - pool: - num_workers: 5 - -metrics: - address: "0.0.0.0:23557" diff --git a/tests/plugins/metrics/configs/.rr-test.yaml b/tests/plugins/metrics/configs/.rr-test.yaml deleted file mode 100644 index d6f529f5..00000000 --- a/tests/plugins/metrics/configs/.rr-test.yaml +++ /dev/null @@ -1,18 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -metrics: - # prometheus client address (path /metrics added automatically) - address: "[::1]:2112" - collect: - app_metric: - type: histogram - help: "Custom application metric" - labels: [ "type" ] - buckets: [ 0.1, 0.2, 0.3, 1.0 ] - app_metric_counter: - type: counter - help: "Custom application counter." -logs: - mode: development - level: error diff --git a/tests/plugins/metrics/metrics_test.go b/tests/plugins/metrics/metrics_test.go deleted file mode 100644 index c590ab2e..00000000 --- a/tests/plugins/metrics/metrics_test.go +++ /dev/null @@ -1,1091 +0,0 @@ -package metrics - -import ( - "io/ioutil" - "net" - "net/http" - "net/rpc" - "os" - "os/signal" - "sync" - "syscall" - "testing" - "time" - - "github.com/golang/mock/gomock" - endure "github.com/spiral/endure/pkg/container" - goridgeRpc "github.com/spiral/goridge/v3/pkg/rpc" - "github.com/spiral/roadrunner/v2/plugins/config" - httpPlugin "github.com/spiral/roadrunner/v2/plugins/http" - "github.com/spiral/roadrunner/v2/plugins/logger" - "github.com/spiral/roadrunner/v2/plugins/metrics" - rpcPlugin "github.com/spiral/roadrunner/v2/plugins/rpc" - "github.com/spiral/roadrunner/v2/plugins/server" - "github.com/spiral/roadrunner/v2/tests/mocks" - "github.com/stretchr/testify/assert" -) - -const dialAddr = "127.0.0.1:6001" -const dialNetwork = "tcp" -const getAddr = "http://127.0.0.1:2112/metrics" -const getIPV6Addr = "http://[::1]:2112/metrics" - -func TestMetricsInit(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - if err != nil { - t.Fatal(err) - } - - cfg := &config.Viper{} - cfg.Prefix = "rr" - cfg.Path = "configs/.rr-test.yaml" - - err = cont.RegisterAll( - cfg, - &metrics.Plugin{}, - &rpcPlugin.Plugin{}, - &logger.ZapLogger{}, - &Plugin1{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - tt := time.NewTimer(time.Second * 5) - defer tt.Stop() - - time.Sleep(time.Second * 2) - out, err := getIPV6() - assert.NoError(t, err) - - assert.Contains(t, out, "go_gc_duration_seconds") - assert.Contains(t, out, "app_metric_counter") - - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-tt.C: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } -} - -func TestMetricsIssue571(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - if err != nil { - t.Fatal(err) - } - - cfg := &config.Viper{} - cfg.Prefix = "rr" - cfg.Path = "configs/.rr-issue-571.yaml" - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - - mockLogger.EXPECT().Debug("worker destructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("Started RPC service", "address", "tcp://127.0.0.1:6001", "plugins", []string{"metrics"}).MinTimes(1) - mockLogger.EXPECT().Debug("200 GET http://127.0.0.1:56444/", "remote", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("declaring new metric", "name", "test", "type", gomock.Any(), "namespace", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("metric successfully added", "name", "test", "type", gomock.Any(), "namespace", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("metric successfully added", "name", "test", "labels", []string{}, "value", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("adding metric", "name", "test", "value", gomock.Any(), "labels", []string{}).MinTimes(1) - mockLogger.EXPECT().Error("metric with provided name already exist", "name", "test", "type", gomock.Any(), "namespace", gomock.Any()).MinTimes(3) - mockLogger.EXPECT().Info("scan command", gomock.Any()).AnyTimes() - - err = cont.RegisterAll( - cfg, - &metrics.Plugin{}, - &rpcPlugin.Plugin{}, - &server.Plugin{}, - mockLogger, - &httpPlugin.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - // give some time to wait http - time.Sleep(time.Second * 2) - _, err = issue571Http() - assert.NoError(t, err) - - out, err := issue571Metrics() - assert.NoError(t, err) - - assert.Contains(t, out, "HELP test Test counter") - assert.Contains(t, out, "TYPE test counter") - - stopCh := make(chan struct{}, 1) - - wg := &sync.WaitGroup{} - wg.Add(1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 2) - stopCh <- struct{}{} - wg.Wait() -} - -// get request and return body -func issue571Http() (string, error) { - r, err := http.Get("http://127.0.0.1:56444") - if err != nil { - return "", err - } - - b, err := ioutil.ReadAll(r.Body) - if err != nil { - return "", err - } - - err = r.Body.Close() - if err != nil { - return "", err - } - // unsafe - return string(b), err -} - -// get request and return body -func issue571Metrics() (string, error) { - r, err := http.Get("http://127.0.0.1:23557") - if err != nil { - return "", err - } - - b, err := ioutil.ReadAll(r.Body) - if err != nil { - return "", err - } - - err = r.Body.Close() - if err != nil { - return "", err - } - // unsafe - return string(b), err -} - -func TestMetricsGaugeCollector(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - if err != nil { - t.Fatal(err) - } - - cfg := &config.Viper{} - cfg.Prefix = "rr" - cfg.Path = "configs/.rr-test.yaml" - - err = cont.RegisterAll( - cfg, - &metrics.Plugin{}, - &rpcPlugin.Plugin{}, - &logger.ZapLogger{}, - &Plugin1{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - time.Sleep(time.Second) - tt := time.NewTimer(time.Second * 5) - defer tt.Stop() - - time.Sleep(time.Second * 2) - out, err := getIPV6() - assert.NoError(t, err) - assert.Contains(t, out, "my_gauge 100") - assert.Contains(t, out, "my_gauge2 100") - - out, err = getIPV6() - assert.NoError(t, err) - assert.Contains(t, out, "go_gc_duration_seconds") - - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-tt.C: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } -} - -func TestMetricsDifferentRPCCalls(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - if err != nil { - t.Fatal(err) - } - - cfg := &config.Viper{} - cfg.Prefix = "rr" - cfg.Path = "configs/.rr-test.yaml" - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - - mockLogger.EXPECT().Debug("worker destructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("Started RPC service", "address", "tcp://127.0.0.1:6001", "plugins", []string{"metrics"}).MinTimes(1) - - mockLogger.EXPECT().Info("adding metric", "name", "counter_CounterMetric", "value", gomock.Any(), "labels", []string{"type2", "section2"}).MinTimes(1) - mockLogger.EXPECT().Info("adding metric", "name", "histogram_registerHistogram", "value", gomock.Any(), "labels", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("adding metric", "name", "sub_gauge_subVector", "value", gomock.Any(), "labels", []string{"core", "first"}).MinTimes(1) - mockLogger.EXPECT().Info("adding metric", "name", "sub_gauge_subMetric", "value", gomock.Any(), "labels", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("adding metric", "name", "test_metrics_named_collector", "value", gomock.Any(), "labels", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("adding metric", "name", "app_metric_counter", "value", gomock.Any(), "labels", gomock.Any()).MinTimes(1) - - mockLogger.EXPECT().Info("metric successfully added", "name", "observe_observeMetricNotEnoughLabels", "type", gomock.Any(), "namespace", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("metric successfully added", "name", "observe_observeMetric", "type", gomock.Any(), "namespace", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("metric successfully added", "name", "counter_CounterMetric", "labels", []string{"type2", "section2"}, "value", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("metric successfully added", "name", "counter_CounterMetric", "type", gomock.Any(), "namespace", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("metric successfully added", "name", "histogram_registerHistogram", "type", gomock.Any(), "namespace", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("metric successfully added", "name", "sub_gauge_subVector", "labels", []string{"core", "first"}, "value", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("metric successfully added", "name", "sub_gauge_subVector", "type", gomock.Any(), "namespace", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("metric successfully added", "name", "sub_gauge_subMetric", "type", gomock.Any(), "namespace", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("metric successfully added", "name", "sub_gauge_subMetric", "labels", gomock.Any(), "value", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("metric successfully added", "name", "histogram_setOnHistogram", "type", gomock.Any(), "namespace", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("metric successfully added", "name", "gauge_setWithoutLabels", "type", gomock.Any(), "namespace", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("metric successfully added", "name", "gauge_missing_section_collector", "type", gomock.Any(), "namespace", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("metric successfully added", "name", "gauge_2_collector", "type", gomock.Any(), "namespace", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("metric successfully added", "name", "test_metrics_named_collector", "type", gomock.Any(), "namespace", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("metric successfully added", "name", "test_metrics_named_collector", "labels", gomock.Any(), "value", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("metric successfully added", "name", "user_gauge_collector", "type", gomock.Any(), "namespace", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("metric successfully added", "name", "app_metric_counter", "labels", gomock.Any(), "value", gomock.Any()).MinTimes(1) - - mockLogger.EXPECT().Info("declaring new metric", "name", "observe_observeMetricNotEnoughLabels", "type", gomock.Any(), "namespace", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("declaring new metric", "name", "observe_observeMetric", "type", gomock.Any(), "namespace", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("declaring new metric", "name", "counter_CounterMetric", "type", gomock.Any(), "namespace", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("declaring new metric", "name", "histogram_registerHistogram", "type", gomock.Any(), "namespace", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("declaring new metric", "name", "sub_gauge_subVector", "type", gomock.Any(), "namespace", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("declaring new metric", "name", "sub_gauge_subMetric", "type", gomock.Any(), "namespace", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("declaring new metric", "name", "histogram_setOnHistogram", "type", gomock.Any(), "namespace", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("declaring new metric", "name", "gauge_setWithoutLabels", "type", gomock.Any(), "namespace", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("declaring new metric", "name", "gauge_missing_section_collector", "type", gomock.Any(), "namespace", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("declaring new metric", "name", "test_metrics_named_collector", "type", gomock.Any(), "namespace", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("declaring new metric", "name", "gauge_2_collector", "type", gomock.Any(), "namespace", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("declaring new metric", "name", "user_gauge_collector", "type", gomock.Any(), "namespace", gomock.Any()).MinTimes(1) - - mockLogger.EXPECT().Info("observing metric", "name", "observe_observeMetric", "value", gomock.Any(), "labels", []string{"test"}).MinTimes(1) - mockLogger.EXPECT().Info("observing metric", "name", "observe_observeMetric", "value", gomock.Any(), "labels", []string{"test", "test2"}).MinTimes(1) - mockLogger.EXPECT().Info("observing metric", "name", "gauge_setOnHistogram", "value", gomock.Any(), "labels", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("observing metric", "name", "gauge_setWithoutLabels", "value", gomock.Any(), "labels", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("observing metric", "name", "gauge_missing_section_collector", "value", gomock.Any(), "labels", []string{"missing"}).MinTimes(1) - mockLogger.EXPECT().Info("observing metric", "name", "user_gauge_collector", "value", gomock.Any(), "labels", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("observing metric", "name", "gauge_2_collector", "value", gomock.Any(), "labels", []string{"core", "first"}).MinTimes(1) - - mockLogger.EXPECT().Info("observe operation finished successfully", "name", "observe_observeMetric", "labels", []string{"test", "test2"}, "value", gomock.Any()).MinTimes(1) - - mockLogger.EXPECT().Info("set operation finished successfully", "name", "gauge_2_collector", "labels", []string{"core", "first"}, "value", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("set operation finished successfully", "name", "user_gauge_collector", "labels", gomock.Any(), "value", gomock.Any()).MinTimes(1) - - mockLogger.EXPECT().Info("subtracting value from metric", "name", "sub_gauge_subVector", "value", gomock.Any(), "labels", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("subtracting value from metric", "name", "sub_gauge_subMetric", "value", gomock.Any(), "labels", gomock.Any()).MinTimes(1) - - mockLogger.EXPECT().Info("subtracting operation finished successfully", "name", "sub_gauge_subVector", "labels", gomock.Any(), "value", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("subtracting operation finished successfully", "name", "sub_gauge_subMetric", "labels", gomock.Any(), "value", gomock.Any()).MinTimes(1) - - mockLogger.EXPECT().Error("failed to get metrics with label values", "collector", "gauge_missing_section_collector", "labels", []string{"missing"}).MinTimes(1) - mockLogger.EXPECT().Error("required labels for collector", "collector", "gauge_setWithoutLabels").MinTimes(1) - mockLogger.EXPECT().Error("failed to get metrics with label values", "collector", "observe_observeMetric", "labels", []string{"test"}).MinTimes(1) - - err = cont.RegisterAll( - cfg, - &metrics.Plugin{}, - &rpcPlugin.Plugin{}, - mockLogger, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - tt := time.NewTimer(time.Minute * 3) - defer tt.Stop() - - go func() { - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-tt.C: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 2) - t.Run("DeclareMetric", declareMetricsTest) - genericOut, err := getIPV6() - assert.NoError(t, err) - assert.Contains(t, genericOut, "test_metrics_named_collector") - - t.Run("AddMetric", addMetricsTest) - genericOut, err = getIPV6() - assert.NoError(t, err) - assert.Contains(t, genericOut, "test_metrics_named_collector 10000") - - t.Run("SetMetric", setMetric) - genericOut, err = getIPV6() - assert.NoError(t, err) - assert.Contains(t, genericOut, "user_gauge_collector 100") - - t.Run("VectorMetric", vectorMetric) - genericOut, err = getIPV6() - assert.NoError(t, err) - assert.Contains(t, genericOut, "gauge_2_collector{section=\"first\",type=\"core\"} 100") - - t.Run("MissingSection", missingSection) - t.Run("SetWithoutLabels", setWithoutLabels) - t.Run("SetOnHistogram", setOnHistogram) - t.Run("MetricSub", subMetric) - genericOut, err = getIPV6() - assert.NoError(t, err) - assert.Contains(t, genericOut, "sub_gauge_subMetric 1") - - t.Run("SubVector", subVector) - genericOut, err = getIPV6() - assert.NoError(t, err) - assert.Contains(t, genericOut, "sub_gauge_subVector{section=\"first\",type=\"core\"} 1") - - t.Run("RegisterHistogram", registerHistogram) - - genericOut, err = getIPV6() - assert.NoError(t, err) - assert.Contains(t, genericOut, `TYPE histogram_registerHistogram`) - - // check buckets - assert.Contains(t, genericOut, `histogram_registerHistogram_bucket{le="0.1"} 0`) - assert.Contains(t, genericOut, `histogram_registerHistogram_bucket{le="0.2"} 0`) - assert.Contains(t, genericOut, `histogram_registerHistogram_bucket{le="0.5"} 0`) - assert.Contains(t, genericOut, `histogram_registerHistogram_bucket{le="+Inf"} 0`) - assert.Contains(t, genericOut, `histogram_registerHistogram_sum 0`) - assert.Contains(t, genericOut, `histogram_registerHistogram_count 0`) - - t.Run("CounterMetric", counterMetric) - genericOut, err = getIPV6() - assert.NoError(t, err) - assert.Contains(t, genericOut, "HELP default_default_counter_CounterMetric test_counter") - assert.Contains(t, genericOut, `default_default_counter_CounterMetric{section="section2",type="type2"}`) - - t.Run("ObserveMetric", observeMetric) - genericOut, err = getIPV6() - assert.NoError(t, err) - assert.Contains(t, genericOut, "observe_observeMetric") - - t.Run("ObserveMetricNotEnoughLabels", observeMetricNotEnoughLabels) - - t.Run("ConfiguredCounterMetric", configuredCounterMetric) - genericOut, err = getIPV6() - assert.NoError(t, err) - assert.Contains(t, genericOut, "HELP app_metric_counter Custom application counter.") - assert.Contains(t, genericOut, `app_metric_counter 100`) - - close(sig) -} - -func configuredCounterMetric(t *testing.T) { - conn, err := net.Dial(dialNetwork, dialAddr) - assert.NoError(t, err) - defer func() { - _ = conn.Close() - }() - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - var ret bool - - assert.NoError(t, client.Call("metrics.Add", metrics.Metric{ - Name: "app_metric_counter", - Value: 100.0, - }, &ret)) - assert.True(t, ret) -} - -func observeMetricNotEnoughLabels(t *testing.T) { - conn, err := net.Dial(dialNetwork, dialAddr) - assert.NoError(t, err) - defer func() { - _ = conn.Close() - }() - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - var ret bool - - nc := metrics.NamedCollector{ - Name: "observe_observeMetricNotEnoughLabels", - Collector: metrics.Collector{ - Namespace: "default", - Subsystem: "default", - Help: "test_observe", - Type: metrics.Histogram, - Labels: []string{"type", "section"}, - }, - } - - err = client.Call("metrics.Declare", nc, &ret) - assert.NoError(t, err) - assert.True(t, ret) - ret = false - - assert.Error(t, client.Call("metrics.Observe", metrics.Metric{ - Name: "observe_observeMetric", - Value: 100.0, - Labels: []string{"test"}, - }, &ret)) - assert.False(t, ret) -} - -func observeMetric(t *testing.T) { - conn, err := net.Dial(dialNetwork, dialAddr) - assert.NoError(t, err) - defer func() { - _ = conn.Close() - }() - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - var ret bool - - nc := metrics.NamedCollector{ - Name: "observe_observeMetric", - Collector: metrics.Collector{ - Namespace: "default", - Subsystem: "default", - Help: "test_observe", - Type: metrics.Histogram, - Labels: []string{"type", "section"}, - }, - } - - err = client.Call("metrics.Declare", nc, &ret) - assert.NoError(t, err) - assert.True(t, ret) - ret = false - - assert.NoError(t, client.Call("metrics.Observe", metrics.Metric{ - Name: "observe_observeMetric", - Value: 100.0, - Labels: []string{"test", "test2"}, - }, &ret)) - assert.True(t, ret) -} - -func counterMetric(t *testing.T) { - conn, err := net.Dial(dialNetwork, dialAddr) - assert.NoError(t, err) - defer func() { - _ = conn.Close() - }() - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - var ret bool - - nc := metrics.NamedCollector{ - Name: "counter_CounterMetric", - Collector: metrics.Collector{ - Namespace: "default", - Subsystem: "default", - Help: "test_counter", - Type: metrics.Counter, - Labels: []string{"type", "section"}, - }, - } - - err = client.Call("metrics.Declare", nc, &ret) - assert.NoError(t, err) - assert.True(t, ret) - - ret = false - - assert.NoError(t, client.Call("metrics.Add", metrics.Metric{ - Name: "counter_CounterMetric", - Value: 100.0, - Labels: []string{"type2", "section2"}, - }, &ret)) - assert.True(t, ret) -} - -func registerHistogram(t *testing.T) { - conn, err := net.Dial(dialNetwork, dialAddr) - assert.NoError(t, err) - defer func() { - _ = conn.Close() - }() - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - var ret bool - - nc := metrics.NamedCollector{ - Name: "histogram_registerHistogram", - Collector: metrics.Collector{ - Help: "test_histogram", - Type: metrics.Histogram, - Buckets: []float64{0.1, 0.2, 0.5}, - }, - } - - err = client.Call("metrics.Declare", nc, &ret) - assert.NoError(t, err) - assert.True(t, ret) - - ret = false - - m := metrics.Metric{ - Name: "histogram_registerHistogram", - Value: 10000, - Labels: nil, - } - - err = client.Call("metrics.Add", m, &ret) - assert.Error(t, err) - assert.False(t, ret) -} - -func subVector(t *testing.T) { - conn, err := net.Dial(dialNetwork, dialAddr) - assert.NoError(t, err) - defer func() { - _ = conn.Close() - }() - - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - var ret bool - - nc := metrics.NamedCollector{ - Name: "sub_gauge_subVector", - Collector: metrics.Collector{ - Namespace: "default", - Subsystem: "default", - Type: metrics.Gauge, - Labels: []string{"type", "section"}, - }, - } - - err = client.Call("metrics.Declare", nc, &ret) - assert.NoError(t, err) - assert.True(t, ret) - ret = false - - m := metrics.Metric{ - Name: "sub_gauge_subVector", - Value: 100000, - Labels: []string{"core", "first"}, - } - - err = client.Call("metrics.Add", m, &ret) - assert.NoError(t, err) - assert.True(t, ret) - ret = false - - m = metrics.Metric{ - Name: "sub_gauge_subVector", - Value: 99999, - Labels: []string{"core", "first"}, - } - - err = client.Call("metrics.Sub", m, &ret) - assert.NoError(t, err) - assert.True(t, ret) -} - -func subMetric(t *testing.T) { - conn, err := net.Dial(dialNetwork, dialAddr) - assert.NoError(t, err) - defer func() { - _ = conn.Close() - }() - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - var ret bool - - nc := metrics.NamedCollector{ - Name: "sub_gauge_subMetric", - Collector: metrics.Collector{ - Namespace: "default", - Subsystem: "default", - Type: metrics.Gauge, - }, - } - - err = client.Call("metrics.Declare", nc, &ret) - assert.NoError(t, err) - assert.True(t, ret) - ret = false - - m := metrics.Metric{ - Name: "sub_gauge_subMetric", - Value: 100000, - } - - err = client.Call("metrics.Add", m, &ret) - assert.NoError(t, err) - assert.True(t, ret) - ret = false - - m = metrics.Metric{ - Name: "sub_gauge_subMetric", - Value: 99999, - } - - err = client.Call("metrics.Sub", m, &ret) - assert.NoError(t, err) - assert.True(t, ret) -} - -func setOnHistogram(t *testing.T) { - conn, err := net.Dial(dialNetwork, dialAddr) - assert.NoError(t, err) - defer func() { - _ = conn.Close() - }() - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - var ret bool - - nc := metrics.NamedCollector{ - Name: "histogram_setOnHistogram", - Collector: metrics.Collector{ - Namespace: "default", - Subsystem: "default", - Type: metrics.Histogram, - Labels: []string{"type", "section"}, - }, - } - - err = client.Call("metrics.Declare", nc, &ret) - assert.NoError(t, err) - assert.True(t, ret) - - ret = false - - m := metrics.Metric{ - Name: "gauge_setOnHistogram", - Value: 100.0, - } - - err = client.Call("metrics.Set", m, &ret) // expected 2 label values but got 1 in []string{"missing"} - assert.Error(t, err) - assert.False(t, ret) -} - -func setWithoutLabels(t *testing.T) { - conn, err := net.Dial(dialNetwork, dialAddr) - assert.NoError(t, err) - defer func() { - _ = conn.Close() - }() - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - var ret bool - - nc := metrics.NamedCollector{ - Name: "gauge_setWithoutLabels", - Collector: metrics.Collector{ - Namespace: "default", - Subsystem: "default", - Type: metrics.Gauge, - Labels: []string{"type", "section"}, - }, - } - - err = client.Call("metrics.Declare", nc, &ret) - assert.NoError(t, err) - assert.True(t, ret) - - ret = false - - m := metrics.Metric{ - Name: "gauge_setWithoutLabels", - Value: 100.0, - } - - err = client.Call("metrics.Set", m, &ret) // expected 2 label values but got 1 in []string{"missing"} - assert.Error(t, err) - assert.False(t, ret) -} - -func missingSection(t *testing.T) { - conn, err := net.Dial(dialNetwork, dialAddr) - assert.NoError(t, err) - defer func() { - _ = conn.Close() - }() - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - var ret bool - - nc := metrics.NamedCollector{ - Name: "gauge_missing_section_collector", - Collector: metrics.Collector{ - Namespace: "default", - Subsystem: "default", - Type: metrics.Gauge, - Labels: []string{"type", "section"}, - }, - } - - err = client.Call("metrics.Declare", nc, &ret) - assert.NoError(t, err) - assert.True(t, ret) - - ret = false - - m := metrics.Metric{ - Name: "gauge_missing_section_collector", - Value: 100.0, - Labels: []string{"missing"}, - } - - err = client.Call("metrics.Set", m, &ret) // expected 2 label values but got 1 in []string{"missing"} - assert.Error(t, err) - assert.False(t, ret) -} - -func vectorMetric(t *testing.T) { - conn, err := net.Dial(dialNetwork, dialAddr) - assert.NoError(t, err) - defer func() { - _ = conn.Close() - }() - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - var ret bool - - nc := metrics.NamedCollector{ - Name: "gauge_2_collector", - Collector: metrics.Collector{ - Namespace: "default", - Subsystem: "default", - Type: metrics.Gauge, - Labels: []string{"type", "section"}, - }, - } - - err = client.Call("metrics.Declare", nc, &ret) - assert.NoError(t, err) - assert.True(t, ret) - - ret = false - - m := metrics.Metric{ - Name: "gauge_2_collector", - Value: 100.0, - Labels: []string{"core", "first"}, - } - - err = client.Call("metrics.Set", m, &ret) - assert.NoError(t, err) - assert.True(t, ret) -} - -func setMetric(t *testing.T) { - conn, err := net.Dial(dialNetwork, dialAddr) - assert.NoError(t, err) - defer func() { - _ = conn.Close() - }() - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - var ret bool - - nc := metrics.NamedCollector{ - Name: "user_gauge_collector", - Collector: metrics.Collector{ - Namespace: "default", - Subsystem: "default", - Type: metrics.Gauge, - }, - } - - err = client.Call("metrics.Declare", nc, &ret) - assert.NoError(t, err) - assert.True(t, ret) - ret = false - - m := metrics.Metric{ - Name: "user_gauge_collector", - Value: 100.0, - } - - err = client.Call("metrics.Set", m, &ret) - assert.NoError(t, err) - assert.True(t, ret) -} - -func addMetricsTest(t *testing.T) { - conn, err := net.Dial(dialNetwork, dialAddr) - assert.NoError(t, err) - defer func() { - _ = conn.Close() - }() - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - var ret bool - - m := metrics.Metric{ - Name: "test_metrics_named_collector", - Value: 10000, - Labels: nil, - } - - err = client.Call("metrics.Add", m, &ret) - assert.NoError(t, err) - assert.True(t, ret) -} - -func declareMetricsTest(t *testing.T) { - conn, err := net.Dial(dialNetwork, dialAddr) - assert.NoError(t, err) - defer func() { - _ = conn.Close() - }() - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - var ret bool - - nc := metrics.NamedCollector{ - Name: "test_metrics_named_collector", - Collector: metrics.Collector{ - Namespace: "default", - Subsystem: "default", - Type: metrics.Counter, - Help: "NO HELP!", - Labels: nil, - Buckets: nil, - }, - } - - err = client.Call("metrics.Declare", nc, &ret) - assert.NoError(t, err) - assert.True(t, ret) -} - -func TestHTTPMetrics(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - if err != nil { - t.Fatal(err) - } - - cfg := &config.Viper{} - cfg.Prefix = "rr" - cfg.Path = "configs/.rr-http-metrics.yaml" - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - - mockLogger.EXPECT().Debug("worker destructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("200 GET http://127.0.0.1:13223/", "remote", gomock.Any(), "elapsed", gomock.Any()).MinTimes(1) - - err = cont.RegisterAll( - cfg, - &metrics.Plugin{}, - &server.Plugin{}, - &httpPlugin.Plugin{}, - mockLogger, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - tt := time.NewTimer(time.Minute * 3) - - go func() { - defer tt.Stop() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-tt.C: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 2) - t.Run("req1", echoHTTP) - t.Run("req2", echoHTTP) - - genericOut, err := get() - assert.NoError(t, err) - assert.Contains(t, genericOut, `rr_http_request_duration_seconds_bucket`) - assert.Contains(t, genericOut, `rr_http_request_duration_seconds_sum{status="200"}`) - assert.Contains(t, genericOut, `rr_http_request_duration_seconds_count{status="200"} 2`) - assert.Contains(t, genericOut, `rr_http_request_total{status="200"} 2`) - assert.Contains(t, genericOut, "rr_http_workers_memory_bytes") - - close(sig) -} - -func echoHTTP(t *testing.T) { - req, err := http.NewRequest("GET", "http://127.0.0.1:13223", nil) - assert.NoError(t, err) - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - _, err = ioutil.ReadAll(r.Body) - assert.NoError(t, err) - assert.Equal(t, 200, r.StatusCode) - - err = r.Body.Close() - assert.NoError(t, err) -} - -// get request and return body -func get() (string, error) { - r, err := http.Get(getAddr) - if err != nil { - return "", err - } - - b, err := ioutil.ReadAll(r.Body) - if err != nil { - return "", err - } - - err = r.Body.Close() - if err != nil { - return "", err - } - // unsafe - return string(b), err -} - -// get request and return body -func getIPV6() (string, error) { - r, err := http.Get(getIPV6Addr) - if err != nil { - return "", err - } - - b, err := ioutil.ReadAll(r.Body) - if err != nil { - return "", err - } - - err = r.Body.Close() - if err != nil { - return "", err - } - // unsafe - return string(b), err -} diff --git a/tests/plugins/metrics/plugin1.go b/tests/plugins/metrics/plugin1.go deleted file mode 100644 index ae024a8a..00000000 --- a/tests/plugins/metrics/plugin1.go +++ /dev/null @@ -1,46 +0,0 @@ -package metrics - -import ( - "github.com/prometheus/client_golang/prometheus" - "github.com/spiral/roadrunner/v2/plugins/config" -) - -// Gauge ////////////// -type Plugin1 struct { - config config.Configurer -} - -func (p1 *Plugin1) Init(cfg config.Configurer) error { - p1.config = cfg - return nil -} - -func (p1 *Plugin1) Serve() chan error { - errCh := make(chan error, 1) - return errCh -} - -func (p1 *Plugin1) Stop() error { - return nil -} - -func (p1 *Plugin1) Name() string { - return "metrics_test.plugin1" -} - -func (p1 *Plugin1) MetricsCollector() []prometheus.Collector { - collector := prometheus.NewGauge(prometheus.GaugeOpts{ - Name: "my_gauge", - Help: "My gauge value", - }) - - collector.Set(100) - - collector2 := prometheus.NewGauge(prometheus.GaugeOpts{ - Name: "my_gauge2", - Help: "My gauge2 value", - }) - - collector2.Set(100) - return []prometheus.Collector{collector, collector2} -} diff --git a/tests/plugins/reload/config_test.go b/tests/plugins/reload/config_test.go deleted file mode 100644 index 72c11070..00000000 --- a/tests/plugins/reload/config_test.go +++ /dev/null @@ -1,63 +0,0 @@ -package reload - -import ( - "testing" - "time" - - "github.com/spiral/roadrunner/v2/plugins/reload" - "github.com/stretchr/testify/assert" -) - -func Test_Config_Valid(t *testing.T) { - services := make(map[string]reload.ServiceConfig) - services["test"] = reload.ServiceConfig{ - Recursive: false, - Patterns: nil, - Dirs: nil, - Ignore: nil, - } - - cfg := &reload.Config{ - Interval: time.Second, - Patterns: nil, - Services: services, - } - assert.NoError(t, cfg.Valid()) -} - -func Test_Fake_ServiceConfig(t *testing.T) { - services := make(map[string]reload.ServiceConfig) - cfg := &reload.Config{ - Interval: time.Microsecond, - Patterns: nil, - Services: services, - } - assert.Error(t, cfg.Valid()) -} - -func Test_Interval(t *testing.T) { - services := make(map[string]reload.ServiceConfig) - services["test"] = reload.ServiceConfig{ - Enabled: false, - Recursive: false, - Patterns: nil, - Dirs: nil, - Ignore: nil, - } - - cfg := &reload.Config{ - Interval: time.Millisecond, // should crash here - Patterns: nil, - Services: services, - } - assert.Error(t, cfg.Valid()) -} - -func Test_NoServiceConfig(t *testing.T) { - cfg := &reload.Config{ - Interval: time.Second, - Patterns: nil, - Services: nil, - } - assert.Error(t, cfg.Valid()) -} diff --git a/tests/plugins/reload/configs/.rr-reload-2.yaml b/tests/plugins/reload/configs/.rr-reload-2.yaml deleted file mode 100644 index 6a9d7582..00000000 --- a/tests/plugins/reload/configs/.rr-reload-2.yaml +++ /dev/null @@ -1,37 +0,0 @@ -server: - command: php ../../psr-worker-bench.php - relay: pipes - relay_timeout: 20s -http: - address: '127.0.0.1:27388' - max_request_size: 1024 - uploads: - forbid: - - .php - - .exe - - .bat - trusted_subnets: - - 10.0.0.0/8 - - 127.0.0.0/8 - - 172.16.0.0/12 - - 192.168.0.0/16 - - '::1/128' - - 'fc00::/7' - - 'fe80::/10' - pool: - num_workers: 2 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s -logs: - mode: development - level: debug -reload: - interval: 1s - patterns: - - .txt - services: - http: - dirs: - - './unit_tests' - recursive: true diff --git a/tests/plugins/reload/configs/.rr-reload-3.yaml b/tests/plugins/reload/configs/.rr-reload-3.yaml deleted file mode 100644 index 36af2693..00000000 --- a/tests/plugins/reload/configs/.rr-reload-3.yaml +++ /dev/null @@ -1,39 +0,0 @@ -server: - command: php ../../psr-worker-bench.php - relay: pipes - relay_timeout: 20s -http: - address: '127.0.0.1:37388' - max_request_size: 1024 - uploads: - forbid: - - .php - - .exe - - .bat - trusted_subnets: - - 10.0.0.0/8 - - 127.0.0.0/8 - - 172.16.0.0/12 - - 192.168.0.0/16 - - '::1/128' - - 'fc00::/7' - - 'fe80::/10' - pool: - num_workers: 2 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s -logs: - mode: development - level: debug -reload: - interval: 1s - patterns: - - .txt - services: - http: - dirs: - - './unit_tests' - - './unit_tests_copied' - - './dir1' - recursive: true diff --git a/tests/plugins/reload/configs/.rr-reload-4.yaml b/tests/plugins/reload/configs/.rr-reload-4.yaml deleted file mode 100644 index ceec11c4..00000000 --- a/tests/plugins/reload/configs/.rr-reload-4.yaml +++ /dev/null @@ -1,40 +0,0 @@ -server: - command: php ../../psr-worker-bench.php - relay: pipes - relay_timeout: 20s -http: - address: '127.0.0.1:22766' - max_request_size: 1024 - uploads: - forbid: - - .php - - .exe - - .bat - trusted_subnets: - - 10.0.0.0/8 - - 127.0.0.0/8 - - 172.16.0.0/12 - - 192.168.0.0/16 - - '::1/128' - - 'fc00::/7' - - 'fe80::/10' - pool: - num_workers: 2 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s -logs: - mode: development - level: debug - -reload: - interval: 1s - patterns: - - .aaa - services: - http: - dirs: - - './unit_tests' - - './unit_tests_copied' - - './dir1' - recursive: false diff --git a/tests/plugins/reload/configs/.rr-reload.yaml b/tests/plugins/reload/configs/.rr-reload.yaml deleted file mode 100644 index 5048ddda..00000000 --- a/tests/plugins/reload/configs/.rr-reload.yaml +++ /dev/null @@ -1,37 +0,0 @@ -server: - command: php ../../psr-worker-bench.php - relay: pipes - relay_timeout: 20s -http: - address: '127.0.0.1:22388' - max_request_size: 1024 - uploads: - forbid: - - .php - - .exe - - .bat - trusted_subnets: - - 10.0.0.0/8 - - 127.0.0.0/8 - - 172.16.0.0/12 - - 192.168.0.0/16 - - '::1/128' - - 'fc00::/7' - - 'fe80::/10' - pool: - num_workers: 2 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s -logs: - mode: development - level: debug -reload: - interval: 1s - patterns: - - .txt - services: - http: - dirs: - - './unit_tests' - recursive: true diff --git a/tests/plugins/reload/reload_plugin_test.go b/tests/plugins/reload/reload_plugin_test.go deleted file mode 100644 index 21c27e49..00000000 --- a/tests/plugins/reload/reload_plugin_test.go +++ /dev/null @@ -1,852 +0,0 @@ -package reload - -import ( - "io" - "io/ioutil" - "math/rand" - "os" - "os/signal" - "path/filepath" - "strconv" - "sync" - "syscall" - "testing" - "time" - - "github.com/golang/mock/gomock" - endure "github.com/spiral/endure/pkg/container" - "github.com/spiral/errors" - "github.com/spiral/roadrunner/v2/plugins/config" - httpPlugin "github.com/spiral/roadrunner/v2/plugins/http" - "github.com/spiral/roadrunner/v2/plugins/reload" - "github.com/spiral/roadrunner/v2/plugins/resetter" - "github.com/spiral/roadrunner/v2/plugins/server" - "github.com/spiral/roadrunner/v2/tests/mocks" - "github.com/stretchr/testify/assert" -) - -const testDir string = "unit_tests" -const testCopyToDir string = "unit_tests_copied" -const dir1 string = "dir1" -const hugeNumberOfFiles uint = 500 - -func TestReloadInit(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-reload.yaml", - Prefix: "rr", - } - - // try to remove, skip error - assert.NoError(t, freeResources(testDir)) - err = os.Mkdir(testDir, 0755) - assert.NoError(t, err) - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - - mockLogger.EXPECT().Debug("worker destructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("file was created", "path", gomock.Any(), "name", "file.txt", "size", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Debug("file was added to watcher", "path", gomock.Any(), "name", "file.txt", "size", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("HTTP plugin got restart request. Restarting...").MinTimes(1) - mockLogger.EXPECT().Info("HTTP workers Pool successfully restarted").MinTimes(1) - mockLogger.EXPECT().Info("HTTP handler listeners successfully re-added").MinTimes(1) - mockLogger.EXPECT().Info("HTTP plugin successfully restarted").MinTimes(1) - mockLogger.EXPECT().Error(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() // placeholder for the workerlogerror - - err = cont.RegisterAll( - cfg, - mockLogger, - &server.Plugin{}, - &httpPlugin.Plugin{}, - &reload.Plugin{}, - &resetter.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - assert.NoError(t, err) - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 3) - t.Run("ReloadTestInit", reloadTestInit) - time.Sleep(time.Second * 3) - stopCh <- struct{}{} - wg.Wait() - - assert.NoError(t, freeResources(testDir)) -} - -func reloadTestInit(t *testing.T) { - err := ioutil.WriteFile(filepath.Join(testDir, "file.txt"), //nolint:gosec - []byte{}, 0755) - assert.NoError(t, err) -} - -func TestReloadHugeNumberOfFiles(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-reload.yaml", - Prefix: "rr", - } - - // try to remove, skip error - assert.NoError(t, freeResources(testDir)) - assert.NoError(t, freeResources(testCopyToDir)) - - assert.NoError(t, os.Mkdir(testDir, 0755)) - assert.NoError(t, os.Mkdir(testCopyToDir, 0755)) - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - - mockLogger.EXPECT().Debug("worker destructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("file added to the list of removed files", "path", gomock.Any(), "name", gomock.Any(), "size", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("file was created", "path", gomock.Any(), "name", gomock.Any(), "size", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Debug("file was updated", "path", gomock.Any(), "name", gomock.Any(), "size", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Debug("file was added to watcher", "path", gomock.Any(), "name", gomock.Any(), "size", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("HTTP plugin got restart request. Restarting...").MinTimes(1) - mockLogger.EXPECT().Info("HTTP workers Pool successfully restarted").MinTimes(1) - mockLogger.EXPECT().Info("HTTP handler listeners successfully re-added").MinTimes(1) - mockLogger.EXPECT().Info("HTTP plugin successfully restarted").MinTimes(1) - mockLogger.EXPECT().Error(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() // placeholder for the workerlogerror - - err = cont.RegisterAll( - cfg, - mockLogger, - &server.Plugin{}, - &httpPlugin.Plugin{}, - &reload.Plugin{}, - &resetter.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - assert.NoError(t, err) - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 3) - t.Run("ReloadTestHugeNumberOfFiles", reloadHugeNumberOfFiles) - t.Run("ReloadRandomlyChangeFile", randomlyChangeFile) - time.Sleep(time.Second * 10) - - stopCh <- struct{}{} - wg.Wait() - - assert.NoError(t, freeResources(testDir)) - assert.NoError(t, freeResources(testCopyToDir)) -} - -func randomlyChangeFile(t *testing.T) { - // we know, that directory contains 500 files (0-499) - // let's try to randomly change it - for i := 0; i < 10; i++ { - // rand sleep - rSleep := rand.Int63n(500) //nolint:gosec - time.Sleep(time.Millisecond * time.Duration(rSleep)) - rNum := rand.Int63n(int64(hugeNumberOfFiles)) //nolint:gosec - err := ioutil.WriteFile(filepath.Join(testDir, "file_"+strconv.Itoa(int(rNum))+".txt"), []byte("Hello, Gophers!"), 0755) //nolint:gosec - assert.NoError(t, err) - } -} - -func reloadHugeNumberOfFiles(t *testing.T) { - for i := uint(0); i < hugeNumberOfFiles; i++ { - assert.NoError(t, makeFile("file_"+strconv.Itoa(int(i))+".txt")) - } -} - -// Should be events only about creating files with txt ext -func TestReloadFilterFileExt(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-reload-2.yaml", - Prefix: "rr", - } - - // try to remove, skip error - assert.NoError(t, freeResources(testDir)) - assert.NoError(t, os.Mkdir(testDir, 0755)) - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - - mockLogger.EXPECT().Debug("worker destructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("file was created", "path", gomock.Any(), "name", gomock.Any(), "size", gomock.Any()).MinTimes(100) - mockLogger.EXPECT().Debug("file was added to watcher", "path", gomock.Any(), "name", gomock.Any(), "size", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Debug("file added to the list of removed files", "path", gomock.Any(), "name", gomock.Any(), "size", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Info("HTTP plugin got restart request. Restarting...").MinTimes(1) - mockLogger.EXPECT().Info("HTTP workers Pool successfully restarted").MinTimes(1) - mockLogger.EXPECT().Info("HTTP handler listeners successfully re-added").MinTimes(1) - mockLogger.EXPECT().Info("HTTP plugin successfully restarted").MinTimes(1) - mockLogger.EXPECT().Error(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() // placeholder for the workerlogerror - - err = cont.RegisterAll( - cfg, - mockLogger, - &server.Plugin{}, - &httpPlugin.Plugin{}, - &reload.Plugin{}, - &resetter.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - assert.NoError(t, err) - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 3) - t.Run("ReloadMakeFiles", reloadMakeFiles) - time.Sleep(time.Second * 2) - t.Run("ReloadFilteredExt", reloadFilteredExt) - time.Sleep(time.Second * 10) - - stopCh <- struct{}{} - wg.Wait() - - assert.NoError(t, freeResources(testDir)) -} - -func reloadMakeFiles(t *testing.T) { - for i := uint(0); i < 100; i++ { - assert.NoError(t, makeFile("file_"+strconv.Itoa(int(i))+".txt")) - } - for i := uint(0); i < 100; i++ { - assert.NoError(t, makeFile("file_"+strconv.Itoa(int(i))+".abc")) - } - for i := uint(0); i < 100; i++ { - assert.NoError(t, makeFile("file_"+strconv.Itoa(int(i))+".def")) - } -} - -func reloadFilteredExt(t *testing.T) { - // change files with abc extension - for i := 0; i < 10; i++ { - // rand sleep - rSleep := rand.Int63n(1000) //nolint:gosec - time.Sleep(time.Millisecond * time.Duration(rSleep)) - rNum := rand.Int63n(int64(hugeNumberOfFiles)) //nolint:gosec - err := ioutil.WriteFile(filepath.Join(testDir, "file_"+strconv.Itoa(int(rNum))+".abc"), []byte("Hello, Gophers!"), 0755) //nolint:gosec - assert.NoError(t, err) - } - - // change files with def extension - for i := 0; i < 10; i++ { - // rand sleep - rSleep := rand.Int63n(1000) //nolint:gosec - time.Sleep(time.Millisecond * time.Duration(rSleep)) - rNum := rand.Int63n(int64(hugeNumberOfFiles)) //nolint:gosec - err := ioutil.WriteFile(filepath.Join(testDir, "file_"+strconv.Itoa(int(rNum))+".def"), []byte("Hello, Gophers!"), 0755) //nolint:gosec - assert.NoError(t, err) - } -} - -// Should be events only about creating files with txt ext -func TestReloadCopy100(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-reload-3.yaml", - Prefix: "rr", - } - - // try to remove, skip error - assert.NoError(t, freeResources(testDir)) - assert.NoError(t, freeResources(testCopyToDir)) - assert.NoError(t, freeResources(dir1)) - - assert.NoError(t, os.Mkdir(testDir, 0755)) - assert.NoError(t, os.Mkdir(testCopyToDir, 0755)) - assert.NoError(t, os.Mkdir(dir1, 0755)) - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - // - mockLogger.EXPECT().Debug("worker destructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("file was created", "path", gomock.Any(), "name", gomock.Any(), "size", gomock.Any()).MinTimes(50) - mockLogger.EXPECT().Debug("file was added to watcher", "path", gomock.Any(), "name", gomock.Any(), "size", gomock.Any()).MinTimes(50) - mockLogger.EXPECT().Debug("file added to the list of removed files", "path", gomock.Any(), "name", gomock.Any(), "size", gomock.Any()).MinTimes(50) - mockLogger.EXPECT().Debug("file was removed from watcher", "path", gomock.Any(), "name", gomock.Any(), "size", gomock.Any()).MinTimes(50) - mockLogger.EXPECT().Debug("file was updated", "path", gomock.Any(), "name", gomock.Any(), "size", gomock.Any()).MinTimes(50) - mockLogger.EXPECT().Info("HTTP plugin got restart request. Restarting...").AnyTimes() - mockLogger.EXPECT().Info("HTTP workers Pool successfully restarted").MinTimes(1) - mockLogger.EXPECT().Info("HTTP handler listeners successfully re-added").MinTimes(1) - mockLogger.EXPECT().Info("HTTP plugin successfully restarted").MinTimes(1) - mockLogger.EXPECT().Error(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() // placeholder for the workerlogerror - - err = cont.RegisterAll( - cfg, - mockLogger, - &server.Plugin{}, - &httpPlugin.Plugin{}, - &reload.Plugin{}, - &resetter.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - assert.NoError(t, err) - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - // Scenario - // 1 - // Create 100 files with txt, abc, def extensions - // Copy files to the unit_tests_copy dir - // 2 - // Delete both dirs, recreate - // Create 100 files with txt, abc, def extensions - // Move files to the unit_tests_copy dir - // 3 - // Recursive - - time.Sleep(time.Second * 3) - t.Run("ReloadMake100Files", reloadMake100Files) - time.Sleep(time.Second * 2) - t.Run("ReloadCopyFiles", reloadCopyFiles) - time.Sleep(time.Second * 2) - t.Run("ReloadRecursiveDirsSupport", copyFilesRecursive) - time.Sleep(time.Second * 2) - t.Run("RandomChangesInRecursiveDirs", randomChangesInRecursiveDirs) - time.Sleep(time.Second * 2) - t.Run("RemoveFilesSupport", removeFilesSupport) - time.Sleep(time.Second * 2) - t.Run("ReloadMoveSupport", reloadMoveSupport) - time.Sleep(time.Second * 10) - - assert.NoError(t, freeResources(testDir)) - assert.NoError(t, freeResources(testCopyToDir)) - assert.NoError(t, freeResources(dir1)) - - time.Sleep(time.Second * 3) - - stopCh <- struct{}{} - wg.Wait() -} - -func reloadMoveSupport(t *testing.T) { - t.Run("MoveSupportCopy", copyFilesRecursive) - // move some files - for i := 0; i < 10; i++ { - // rand sleep - rSleep := rand.Int63n(500) //nolint:gosec - time.Sleep(time.Millisecond * time.Duration(rSleep)) - rNum := rand.Int63n(int64(33)) //nolint:gosec - rDir := rand.Int63n(9) //nolint:gosec - rExt := rand.Int63n(3) //nolint:gosec - - ext := []string{ - ".txt", - ".abc", - ".def", - } - - // change files with def extension - dirs := []string{ - "dir1", - "dir1/dir2", - "dir1/dir2/dir3", - "dir1/dir2/dir3/dir4", - "dir1/dir2/dir3/dir4/dir5", - "dir1/dir2/dir3/dir4/dir5/dir6", - "dir1/dir2/dir3/dir4/dir5/dir6/dir7", - "dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8", - "dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9", - "dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dir10", - } - - // move file - err := os.Rename(filepath.Join(dirs[rDir], "file_"+strconv.Itoa(int(rNum))+ext[rExt]), filepath.Join(dirs[rDir+1], "file_"+strconv.Itoa(int(rNum))+ext[rExt])) - assert.NoError(t, err) - } -} - -func removeFilesSupport(t *testing.T) { - // remove some files - for i := 0; i < 10; i++ { - // rand sleep - rSleep := rand.Int63n(500) //nolint:gosec - time.Sleep(time.Millisecond * time.Duration(rSleep)) - rNum := rand.Int63n(int64(100)) //nolint:gosec - rDir := rand.Int63n(10) //nolint:gosec - rExt := rand.Int63n(3) //nolint:gosec - - ext := []string{ - ".txt", - ".abc", - ".def", - } - - // change files with def extension - dirs := []string{ - "dir1", - "dir1/dir2", - "dir1/dir2/dir3", - "dir1/dir2/dir3/dir4", - "dir1/dir2/dir3/dir4/dir5", - "dir1/dir2/dir3/dir4/dir5/dir6", - "dir1/dir2/dir3/dir4/dir5/dir6/dir7", - "dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8", - "dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9", - "dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dir10", - } - // here can be a situation, when file already deleted - _ = os.Remove(filepath.Join(dirs[rDir], "file_"+strconv.Itoa(int(rNum))+ext[rExt])) - } -} - -func randomChangesInRecursiveDirs(t *testing.T) { - // change files with def extension - dirs := []string{ - "dir1", - "dir1/dir2", - "dir1/dir2/dir3", - "dir1/dir2/dir3/dir4", - "dir1/dir2/dir3/dir4/dir5", - "dir1/dir2/dir3/dir4/dir5/dir6", - "dir1/dir2/dir3/dir4/dir5/dir6/dir7", - "dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8", - "dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9", - "dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dir10", - } - - ext := []string{ - ".txt", - ".abc", - ".def", - } - - filenames := []string{ - "file_", // should be update - "foo_", // should be created - "bar_", // should be created - } - for i := 0; i < 10; i++ { - // rand sleep - rSleep := rand.Int63n(100) //nolint:gosec - time.Sleep(time.Millisecond * time.Duration(rSleep)) - rNum := rand.Int63n(int64(100)) //nolint:gosec - rDir := rand.Int63n(10) //nolint:gosec - rExt := rand.Int63n(3) //nolint:gosec - rName := rand.Int63n(3) //nolint:gosec - - err := ioutil.WriteFile(filepath.Join(dirs[rDir], filenames[rName]+strconv.Itoa(int(rNum))+ext[rExt]), []byte("Hello, Gophers!"), 0755) //nolint:gosec - assert.NoError(t, err) - } -} - -func copyFilesRecursive(t *testing.T) { - err := copyDir(testDir, "dir1") - assert.NoError(t, err) - err = copyDir(testDir, "dir1/dir2") - assert.NoError(t, err) - err = copyDir(testDir, "dir1/dir2/dir3") - assert.NoError(t, err) - err = copyDir(testDir, "dir1/dir2/dir3/dir4") - assert.NoError(t, err) - err = copyDir(testDir, "dir1/dir2/dir3/dir4/dir5") - assert.NoError(t, err) - err = copyDir(testDir, "dir1/dir2/dir3/dir4/dir5/dir6") - assert.NoError(t, err) - err = copyDir(testDir, "dir1/dir2/dir3/dir4/dir5/dir6/dir7") - assert.NoError(t, err) - err = copyDir(testDir, "dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8") - assert.NoError(t, err) - err = copyDir(testDir, "dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9") - assert.NoError(t, err) - err = copyDir(testDir, "dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dir10") - assert.NoError(t, err) -} - -func reloadCopyFiles(t *testing.T) { - err := copyDir(testDir, testCopyToDir) - assert.NoError(t, err) - - assert.NoError(t, freeResources(testDir)) - assert.NoError(t, freeResources(testCopyToDir)) - - assert.NoError(t, os.Mkdir(testDir, 0755)) - assert.NoError(t, os.Mkdir(testCopyToDir, 0755)) - - // recreate files - for i := uint(0); i < 33; i++ { - assert.NoError(t, makeFile("file_"+strconv.Itoa(int(i))+".txt")) - } - for i := uint(0); i < 33; i++ { - assert.NoError(t, makeFile("file_"+strconv.Itoa(int(i))+".abc")) - } - for i := uint(0); i < 34; i++ { - assert.NoError(t, makeFile("file_"+strconv.Itoa(int(i))+".def")) - } - - err = copyDir(testDir, testCopyToDir) - assert.NoError(t, err) -} - -func reloadMake100Files(t *testing.T) { - for i := uint(0); i < 33; i++ { - assert.NoError(t, makeFile("file_"+strconv.Itoa(int(i))+".txt")) - } - for i := uint(0); i < 33; i++ { - assert.NoError(t, makeFile("file_"+strconv.Itoa(int(i))+".abc")) - } - for i := uint(0); i < 34; i++ { - assert.NoError(t, makeFile("file_"+strconv.Itoa(int(i))+".def")) - } -} - -func TestReloadNoRecursion(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-reload-4.yaml", - Prefix: "rr", - } - - // try to remove, skip error - assert.NoError(t, freeResources(testDir)) - assert.NoError(t, freeResources(testCopyToDir)) - assert.NoError(t, freeResources(dir1)) - - assert.NoError(t, os.Mkdir(testDir, 0755)) - assert.NoError(t, os.Mkdir(dir1, 0755)) - assert.NoError(t, os.Mkdir(testCopyToDir, 0755)) - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - - // http server should not be restarted. all event from wrong file extensions should be skipped - mockLogger.EXPECT().Debug("worker destructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("file was removed from watcher", "path", gomock.Any(), "name", gomock.Any(), "size", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Debug("file added to the list of removed files", "path", gomock.Any(), "name", gomock.Any(), "size", gomock.Any()).MinTimes(1) - mockLogger.EXPECT().Info("HTTP plugin got restart request. Restarting...").MinTimes(1) - mockLogger.EXPECT().Info("HTTP workers Pool successfully restarted").MinTimes(1) - mockLogger.EXPECT().Info("HTTP handler listeners successfully re-added").MinTimes(1) - mockLogger.EXPECT().Info("HTTP plugin successfully restarted").MinTimes(1) - mockLogger.EXPECT().Error(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() // placeholder for the workerlogerror - - err = cont.RegisterAll( - cfg, - mockLogger, - &server.Plugin{}, - &httpPlugin.Plugin{}, - &reload.Plugin{}, - &resetter.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - assert.NoError(t, err) - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 3) - t.Run("ReloadMakeFiles", reloadMakeFiles) // make files in the testDir - time.Sleep(time.Second * 2) - t.Run("ReloadCopyFilesRecursive", reloadCopyFiles) - time.Sleep(time.Second * 3) - assert.NoError(t, freeResources(testDir)) - time.Sleep(time.Second * 10) - - stopCh <- struct{}{} - wg.Wait() - - assert.NoError(t, freeResources(testCopyToDir)) - assert.NoError(t, freeResources(dir1)) -} - -// ======================================================================== - -func freeResources(path string) error { - return os.RemoveAll(path) -} - -func makeFile(filename string) error { - return ioutil.WriteFile(filepath.Join(testDir, filename), []byte{}, 0755) //nolint:gosec -} - -func copyDir(src string, dst string) error { - src = filepath.Clean(src) - dst = filepath.Clean(dst) - - si, err := os.Stat(src) - if err != nil { - return err - } - if !si.IsDir() { - return errors.E(errors.Str("source is not a directory")) - } - - _, err = os.Stat(dst) - if err != nil && !os.IsNotExist(err) { - return err - } - - err = os.MkdirAll(dst, si.Mode()) - if err != nil { - return err - } - - entries, err := ioutil.ReadDir(src) - if err != nil { - return err - } - - for _, entry := range entries { - srcPath := filepath.Join(src, entry.Name()) - dstPath := filepath.Join(dst, entry.Name()) - - if entry.IsDir() { - err = copyDir(srcPath, dstPath) - if err != nil { - return err - } - } else { - // Skip symlinks. - if entry.Mode()&os.ModeSymlink != 0 { - continue - } - - err = copyFile(srcPath, dstPath) - if err != nil { - return err - } - } - } - return nil -} - -func copyFile(src, dst string) error { - in, err := os.Open(src) - if err != nil { - return errors.E(err) - } - defer func() { - _ = in.Close() - }() - - out, err := os.Create(dst) - if err != nil { - return errors.E(err) - } - defer func() { - _ = out.Close() - }() - - _, err = io.Copy(out, in) - if err != nil { - return errors.E(err) - } - - err = out.Sync() - if err != nil { - return errors.E(err) - } - - si, err := os.Stat(src) - if err != nil { - return errors.E(err) - } - err = os.Chmod(dst, si.Mode()) - if err != nil { - return errors.E(err) - } - return nil -} diff --git a/tests/plugins/resetter/.rr-resetter.yaml b/tests/plugins/resetter/.rr-resetter.yaml deleted file mode 100644 index 623ba142..00000000 --- a/tests/plugins/resetter/.rr-resetter.yaml +++ /dev/null @@ -1,15 +0,0 @@ -server: - command: "php ../../http/client.php echo pipes" - user: "" - group: "" - env: - "RR_CONFIG": "/some/place/on/the/C134" - "RR_CONFIG2": "C138" - relay: "pipes" - relay_timeout: "20s" - -rpc: - listen: tcp://127.0.0.1:6001 -logs: - mode: development - level: debug
\ No newline at end of file diff --git a/tests/plugins/resetter/resetter_test.go b/tests/plugins/resetter/resetter_test.go deleted file mode 100644 index e0fb020d..00000000 --- a/tests/plugins/resetter/resetter_test.go +++ /dev/null @@ -1,125 +0,0 @@ -package resetter - -import ( - "net" - "net/rpc" - "os" - "os/signal" - "sync" - "syscall" - "testing" - "time" - - "github.com/golang/mock/gomock" - endure "github.com/spiral/endure/pkg/container" - goridgeRpc "github.com/spiral/goridge/v3/pkg/rpc" - "github.com/spiral/roadrunner/v2/plugins/config" - "github.com/spiral/roadrunner/v2/plugins/resetter" - rpcPlugin "github.com/spiral/roadrunner/v2/plugins/rpc" - "github.com/spiral/roadrunner/v2/plugins/server" - "github.com/spiral/roadrunner/v2/tests/mocks" - "github.com/stretchr/testify/assert" -) - -func TestResetterInit(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - if err != nil { - t.Fatal(err) - } - - cfg := &config.Viper{ - Path: ".rr-resetter.yaml", - Prefix: "rr", - } - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - - mockLogger.EXPECT().Debug("worker destructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("Started RPC service", "address", "tcp://127.0.0.1:6001", "plugins", []string{"resetter"}).MinTimes(1) - - mockLogger.EXPECT().Error(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() - - mockLogger.EXPECT().Warn("listener accept error, connection closed", "error", gomock.Any()).AnyTimes() - - err = cont.RegisterAll( - cfg, - &server.Plugin{}, - mockLogger, - &resetter.Plugin{}, - &rpcPlugin.Plugin{}, - &Plugin1{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - stopCh := make(chan struct{}, 1) - - wg := &sync.WaitGroup{} - wg.Add(1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second) - - t.Run("ResetterRpcTest", resetterRPCTest) - stopCh <- struct{}{} - wg.Wait() -} - -func resetterRPCTest(t *testing.T) { - conn, err := net.Dial("tcp", "127.0.0.1:6001") - assert.NoError(t, err) - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - // WorkerList contains list of workers. - - var ret bool - err = client.Call("resetter.Reset", "resetter.plugin1", &ret) - assert.NoError(t, err) - assert.True(t, ret) - ret = false - - var services []string - err = client.Call("resetter.List", nil, &services) - assert.NotNil(t, services) - assert.NoError(t, err) - if services[0] != "resetter.plugin1" { - t.Fatal("no enough services") - } -} diff --git a/tests/plugins/resetter/test_plugin.go b/tests/plugins/resetter/test_plugin.go deleted file mode 100644 index 5c26cbd0..00000000 --- a/tests/plugins/resetter/test_plugin.go +++ /dev/null @@ -1,66 +0,0 @@ -package resetter - -import ( - "context" - "time" - - poolImpl "github.com/spiral/roadrunner/v2/pkg/pool" - "github.com/spiral/roadrunner/v2/plugins/config" - "github.com/spiral/roadrunner/v2/plugins/server" -) - -var testPoolConfig = &poolImpl.Config{ - NumWorkers: 10, - MaxJobs: 100, - AllocateTimeout: time.Second * 10, - DestroyTimeout: time.Second * 10, - Supervisor: &poolImpl.SupervisorConfig{ - WatchTick: 60 * time.Second, - TTL: 1000 * time.Second, - IdleTTL: 10 * time.Second, - ExecTTL: 10 * time.Second, - MaxWorkerMemory: 1000, - }, -} - -// Gauge ////////////// -type Plugin1 struct { - config config.Configurer - server server.Server -} - -func (p1 *Plugin1) Init(cfg config.Configurer, server server.Server) error { - p1.config = cfg - p1.server = server - return nil -} - -func (p1 *Plugin1) Serve() chan error { - errCh := make(chan error, 1) - return errCh -} - -func (p1 *Plugin1) Stop() error { - return nil -} - -func (p1 *Plugin1) Name() string { - return "resetter.plugin1" -} - -func (p1 *Plugin1) Reset() error { - pool, err := p1.server.NewWorkerPool(context.Background(), testPoolConfig, nil) - if err != nil { - panic(err) - } - pool.Destroy(context.Background()) - - pool, err = p1.server.NewWorkerPool(context.Background(), testPoolConfig, nil) - if err != nil { - panic(err) - } - - _ = pool - - return nil -} diff --git a/tests/plugins/rpc/config_test.go b/tests/plugins/rpc/config_test.go deleted file mode 100755 index 0645050d..00000000 --- a/tests/plugins/rpc/config_test.go +++ /dev/null @@ -1,163 +0,0 @@ -package rpc - -import ( - "testing" - - "github.com/spiral/roadrunner/v2/plugins/rpc" - "github.com/stretchr/testify/assert" -) - -func TestConfig_Listener(t *testing.T) { - cfg := &rpc.Config{Listen: "tcp://:18001"} - - ln, err := cfg.Listener() - assert.NoError(t, err) - assert.NotNil(t, ln) - defer func() { - err := ln.Close() - if err != nil { - t.Errorf("error closing the listener: error %v", err) - } - }() - - assert.Equal(t, "tcp", ln.Addr().Network()) - assert.Equal(t, "0.0.0.0:18001", ln.Addr().String()) -} - -func TestConfig_Listener2(t *testing.T) { - cfg := &rpc.Config{Listen: ":18001"} - - ln, err := cfg.Listener() - assert.NoError(t, err) - assert.NotNil(t, ln) - defer func() { - err := ln.Close() - if err != nil { - t.Errorf("error closing the listener: error %v", err) - } - }() - - assert.Equal(t, "tcp", ln.Addr().Network()) - assert.Equal(t, "0.0.0.0:18001", ln.Addr().String()) -} - -func TestConfig_ListenerIPV6(t *testing.T) { - cfg := &rpc.Config{Listen: "tcp://[::]:18001"} - - ln, err := cfg.Listener() - assert.NoError(t, err) - assert.NotNil(t, ln) - defer func() { - err := ln.Close() - if err != nil { - t.Errorf("error closing the listener: error %v", err) - } - }() - - assert.Equal(t, "tcp", ln.Addr().Network()) - assert.Equal(t, "[::]:18001", ln.Addr().String()) -} - -func TestConfig_ListenerUnix(t *testing.T) { - cfg := &rpc.Config{Listen: "unix://file.sock"} - - ln, err := cfg.Listener() - assert.NoError(t, err) - assert.NotNil(t, ln) - defer func() { - err := ln.Close() - if err != nil { - t.Errorf("error closing the listener: error %v", err) - } - }() - - assert.Equal(t, "unix", ln.Addr().Network()) - assert.Equal(t, "file.sock", ln.Addr().String()) -} - -func Test_Config_Error(t *testing.T) { - cfg := &rpc.Config{Listen: "uni:unix.sock"} - ln, err := cfg.Listener() - assert.Nil(t, ln) - assert.Error(t, err) -} - -func Test_Config_ErrorMethod(t *testing.T) { - cfg := &rpc.Config{Listen: "xinu://unix.sock"} - - ln, err := cfg.Listener() - assert.Nil(t, ln) - assert.Error(t, err) -} - -func TestConfig_Dialer(t *testing.T) { - cfg := &rpc.Config{Listen: "tcp://:18001"} - - ln, _ := cfg.Listener() - defer func() { - err := ln.Close() - if err != nil { - t.Errorf("error closing the listener: error %v", err) - } - }() - - conn, err := cfg.Dialer() - assert.NoError(t, err) - assert.NotNil(t, conn) - defer func() { - err := conn.Close() - if err != nil { - t.Errorf("error closing the connection: error %v", err) - } - }() - - assert.Equal(t, "tcp", conn.RemoteAddr().Network()) - assert.Equal(t, "127.0.0.1:18001", conn.RemoteAddr().String()) -} - -func TestConfig_DialerUnix(t *testing.T) { - cfg := &rpc.Config{Listen: "unix://file.sock"} - - ln, _ := cfg.Listener() - defer func() { - err := ln.Close() - if err != nil { - t.Errorf("error closing the listener: error %v", err) - } - }() - - conn, err := cfg.Dialer() - assert.NoError(t, err) - assert.NotNil(t, conn) - defer func() { - err := conn.Close() - if err != nil { - t.Errorf("error closing the connection: error %v", err) - } - }() - - assert.Equal(t, "unix", conn.RemoteAddr().Network()) - assert.Equal(t, "file.sock", conn.RemoteAddr().String()) -} - -func Test_Config_DialerError(t *testing.T) { - cfg := &rpc.Config{Listen: "uni:unix.sock"} - ln, err := cfg.Dialer() - assert.Nil(t, ln) - assert.Error(t, err) - assert.Equal(t, "invalid socket DSN (tcp://:6001, unix://file.sock)", err.Error()) -} - -func Test_Config_DialerErrorMethod(t *testing.T) { - cfg := &rpc.Config{Listen: "xinu://unix.sock"} - - ln, err := cfg.Dialer() - assert.Nil(t, ln) - assert.Error(t, err) -} - -func Test_Config_Defaults(t *testing.T) { - c := &rpc.Config{} - c.InitDefaults() - assert.Equal(t, "tcp://127.0.0.1:6001", c.Listen) -} diff --git a/tests/plugins/rpc/configs/.rr-rpc-disabled.yaml b/tests/plugins/rpc/configs/.rr-rpc-disabled.yaml deleted file mode 100644 index d256aad7..00000000 --- a/tests/plugins/rpc/configs/.rr-rpc-disabled.yaml +++ /dev/null @@ -1,8 +0,0 @@ -logs: - mode: development - level: panic - -endure: - grace_period: 120s - print_graph: false - log_level: panic diff --git a/tests/plugins/rpc/configs/.rr.yaml b/tests/plugins/rpc/configs/.rr.yaml deleted file mode 100644 index d6aaa7c6..00000000 --- a/tests/plugins/rpc/configs/.rr.yaml +++ /dev/null @@ -1,11 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -logs: - mode: development - level: panic - -endure: - grace_period: 120s - print_graph: false - log_level: panic diff --git a/tests/plugins/rpc/plugin1.go b/tests/plugins/rpc/plugin1.go deleted file mode 100644 index 6843b396..00000000 --- a/tests/plugins/rpc/plugin1.go +++ /dev/null @@ -1,42 +0,0 @@ -package rpc - -import ( - "fmt" - - "github.com/spiral/roadrunner/v2/plugins/config" -) - -type Plugin1 struct { - config config.Configurer -} - -func (p1 *Plugin1) Init(cfg config.Configurer) error { - p1.config = cfg - return nil -} - -func (p1 *Plugin1) Serve() chan error { - errCh := make(chan error, 1) - return errCh -} - -func (p1 *Plugin1) Stop() error { - return nil -} - -func (p1 *Plugin1) Name() string { - return "rpc_test.plugin1" -} - -func (p1 *Plugin1) RPC() interface{} { - return &PluginRPC{srv: p1} -} - -type PluginRPC struct { - srv *Plugin1 -} - -func (r *PluginRPC) Hello(in string, out *string) error { - *out = fmt.Sprintf("Hello, username: %s", in) - return nil -} diff --git a/tests/plugins/rpc/plugin2.go b/tests/plugins/rpc/plugin2.go deleted file mode 100644 index 2c47158f..00000000 --- a/tests/plugins/rpc/plugin2.go +++ /dev/null @@ -1,53 +0,0 @@ -package rpc - -import ( - "net" - "net/rpc" - "time" - - "github.com/spiral/errors" - goridgeRpc "github.com/spiral/goridge/v3/pkg/rpc" -) - -// plugin2 makes a call to the plugin1 via RPC -// this is just a simulation of external call FOR TEST -// you don't need to do such things :) -type Plugin2 struct { -} - -func (p2 *Plugin2) Init() error { - return nil -} - -func (p2 *Plugin2) Serve() chan error { - errCh := make(chan error, 1) - - go func() { - time.Sleep(time.Second * 3) - - conn, err := net.Dial("tcp", "127.0.0.1:6001") - if err != nil { - errCh <- errors.E(errors.Serve, err) - return - } - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - var ret string - err = client.Call("rpc_test.plugin1.Hello", "Valery", &ret) - if err != nil { - errCh <- err - return - } - if ret != "Hello, username: Valery" { - errCh <- errors.E("wrong response") - return - } - // to stop exec - errCh <- errors.E(errors.Disabled) - }() - - return errCh -} - -func (p2 *Plugin2) Stop() error { - return nil -} diff --git a/tests/plugins/rpc/rpc_test.go b/tests/plugins/rpc/rpc_test.go deleted file mode 100644 index 49d3b3f1..00000000 --- a/tests/plugins/rpc/rpc_test.go +++ /dev/null @@ -1,188 +0,0 @@ -package rpc - -import ( - "os" - "os/signal" - "sync" - "syscall" - "testing" - "time" - - endure "github.com/spiral/endure/pkg/container" - "github.com/spiral/errors" - "github.com/spiral/roadrunner/v2/plugins/config" - "github.com/spiral/roadrunner/v2/plugins/logger" - "github.com/spiral/roadrunner/v2/plugins/rpc" - "github.com/stretchr/testify/assert" -) - -// graph https://bit.ly/3ensdNb -func TestRpcInit(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - if err != nil { - t.Fatal(err) - } - - err = cont.Register(&Plugin1{}) - if err != nil { - t.Fatal(err) - } - - err = cont.Register(&Plugin2{}) - if err != nil { - t.Fatal(err) - } - - v := &config.Viper{} - v.Path = "configs/.rr.yaml" - v.Prefix = "rr" - err = cont.Register(v) - if err != nil { - t.Fatal(err) - } - - err = cont.Register(&rpc.Plugin{}) - if err != nil { - t.Fatal(err) - } - - err = cont.Register(&logger.ZapLogger{}) - if err != nil { - t.Fatal(err) - } - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - if err != nil { - t.Fatal(err) - } - - sig := make(chan os.Signal, 1) - - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - wg := &sync.WaitGroup{} - wg.Add(1) - - tt := time.NewTimer(time.Second * 10) - - go func() { - defer wg.Done() - defer tt.Stop() - for { - select { - case e := <-ch: - // just stop, this is ok - if errors.Is(errors.Disabled, e.Error) { - return - } - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-tt.C: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - assert.Fail(t, "timeout") - } - } - }() - - wg.Wait() -} - -// graph https://bit.ly/3ensdNb -func TestRpcDisabled(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - if err != nil { - t.Fatal(err) - } - - err = cont.Register(&Plugin1{}) - if err != nil { - t.Fatal(err) - } - - err = cont.Register(&Plugin2{}) - if err != nil { - t.Fatal(err) - } - - v := &config.Viper{} - v.Path = "configs/.rr-rpc-disabled.yaml" - v.Prefix = "rr" - err = cont.Register(v) - if err != nil { - t.Fatal(err) - } - - err = cont.Register(&rpc.Plugin{}) - if err != nil { - t.Fatal(err) - } - - err = cont.Register(&logger.ZapLogger{}) - if err != nil { - t.Fatal(err) - } - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - if err != nil { - t.Fatal(err) - } - - sig := make(chan os.Signal, 1) - - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - tt := time.NewTimer(time.Second * 20) - - wg := &sync.WaitGroup{} - wg.Add(1) - - go func() { - defer wg.Done() - defer tt.Stop() - for { - select { - case e := <-ch: - // RPC is turned off, should be and dial error - if errors.Is(errors.Disabled, e.Error) { - assert.FailNow(t, "should not be disabled error") - } - assert.Error(t, e.Error) - err = cont.Stop() - assert.Error(t, err) - return - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-tt.C: - // timeout - return - } - } - }() - - wg.Wait() -} diff --git a/tests/plugins/server/configs/.rr-no-app-section.yaml b/tests/plugins/server/configs/.rr-no-app-section.yaml deleted file mode 100644 index d28265d5..00000000 --- a/tests/plugins/server/configs/.rr-no-app-section.yaml +++ /dev/null @@ -1,12 +0,0 @@ -server: - command: "php ../../client.php echo pipes" - user: "" - group: "" - env: - - RR_CONFIG: "/some/place/on/the/C134" - - RR_CONFIG2: "C138" - relay: "pipes" - relay_timeout: "20s" -logs: - mode: development - level: error diff --git a/tests/plugins/server/configs/.rr-sockets.yaml b/tests/plugins/server/configs/.rr-sockets.yaml deleted file mode 100644 index 4c57f36f..00000000 --- a/tests/plugins/server/configs/.rr-sockets.yaml +++ /dev/null @@ -1,12 +0,0 @@ -server: - command: "php socket.php" - user: "" - group: "" - env: - - RR_CONFIG: "/some/place/on/the/C134" - - RR_CONFIG2: "C138" - relay: "unix://unix.sock" - relay_timeout: "20s" -logs: - mode: development - level: error diff --git a/tests/plugins/server/configs/.rr-tcp.yaml b/tests/plugins/server/configs/.rr-tcp.yaml deleted file mode 100644 index 6b9c9ddb..00000000 --- a/tests/plugins/server/configs/.rr-tcp.yaml +++ /dev/null @@ -1,12 +0,0 @@ -server: - command: "php tcp.php" - user: "" - group: "" - env: - - RR_CONFIG: "/some/place/on/the/C134" - - RR_CONFIG2: "C138" - relay: "tcp://127.0.0.1:9999" - relay_timeout: "20s" -logs: - mode: development - level: error diff --git a/tests/plugins/server/configs/.rr-wrong-command.yaml b/tests/plugins/server/configs/.rr-wrong-command.yaml deleted file mode 100644 index 9d105d90..00000000 --- a/tests/plugins/server/configs/.rr-wrong-command.yaml +++ /dev/null @@ -1,12 +0,0 @@ -server: - command: "php some_absent_file.php" - user: "" - group: "" - env: - - RR_CONFIG: "/some/place/on/the/C134" - - RR_CONFIG2: "C138" - relay: "pipes" - relay_timeout: "20s" -logs: - mode: development - level: error diff --git a/tests/plugins/server/configs/.rr-wrong-relay.yaml b/tests/plugins/server/configs/.rr-wrong-relay.yaml deleted file mode 100644 index c4d1edb0..00000000 --- a/tests/plugins/server/configs/.rr-wrong-relay.yaml +++ /dev/null @@ -1,12 +0,0 @@ -server: - command: "php ../../client.php echo pipes" - user: "" - group: "" - env: - - RR_CONFIG: "/some/place/on/the/C134" - - RR_CONFIG2: "C138" - relay: "pupes" - relay_timeout: "20s" -logs: - mode: development - level: error diff --git a/tests/plugins/server/configs/.rr.yaml b/tests/plugins/server/configs/.rr.yaml deleted file mode 100644 index a1484c02..00000000 --- a/tests/plugins/server/configs/.rr.yaml +++ /dev/null @@ -1,12 +0,0 @@ -server: - command: "php ../../client.php echo pipes" - user: "" - group: "" - env: - - RR_CONFIG: "/some/place/on/the/C134" - - RR_CONFIG2: "C138" - relay: "pipes" - relay_timeout: "20s" -logs: - mode: development - level: info diff --git a/tests/plugins/server/plugin_pipes.go b/tests/plugins/server/plugin_pipes.go deleted file mode 100644 index d136da1e..00000000 --- a/tests/plugins/server/plugin_pipes.go +++ /dev/null @@ -1,128 +0,0 @@ -package server - -import ( - "context" - "time" - - "github.com/spiral/errors" - "github.com/spiral/roadrunner/v2/pkg/payload" - "github.com/spiral/roadrunner/v2/pkg/pool" - "github.com/spiral/roadrunner/v2/pkg/worker" - "github.com/spiral/roadrunner/v2/plugins/config" - "github.com/spiral/roadrunner/v2/plugins/server" -) - -const ConfigSection = "server" -const Response = "test" - -var testPoolConfig = &pool.Config{ - NumWorkers: 10, - MaxJobs: 100, - AllocateTimeout: time.Second * 10, - DestroyTimeout: time.Second * 10, - Supervisor: &pool.SupervisorConfig{ - WatchTick: 60 * time.Second, - TTL: 1000 * time.Second, - IdleTTL: 10 * time.Second, - ExecTTL: 10 * time.Second, - MaxWorkerMemory: 1000, - }, -} - -type Foo struct { - configProvider config.Configurer - wf server.Server - pool pool.Pool -} - -func (f *Foo) Init(p config.Configurer, workerFactory server.Server) error { - f.configProvider = p - f.wf = workerFactory - return nil -} - -func (f *Foo) Serve() chan error { - const op = errors.Op("serve") - - // test payload for echo - r := &payload.Payload{ - Context: nil, - Body: []byte(Response), - } - - errCh := make(chan error, 1) - - conf := &server.Config{} - var err error - err = f.configProvider.UnmarshalKey(ConfigSection, conf) - if err != nil { - errCh <- err - return errCh - } - - // test CMDFactory - cmd, err := f.wf.CmdFactory(nil) - if err != nil { - errCh <- err - return errCh - } - if cmd == nil { - errCh <- errors.E(op, errors.Str("command is nil")) - return errCh - } - - // test worker creation - w, err := f.wf.NewWorker(context.Background(), nil) - if err != nil { - errCh <- err - return errCh - } - - // test that our worker is functional - sw := worker.From(w) - - rsp, err := sw.Exec(r) - if err != nil { - errCh <- err - return errCh - } - - if string(rsp.Body) != Response { - errCh <- errors.E("response from worker is wrong", errors.Errorf("response: %s", rsp.Body)) - return errCh - } - - // should not be errors - err = sw.Stop() - if err != nil { - errCh <- err - return errCh - } - - // test pool - f.pool, err = f.wf.NewWorkerPool(context.Background(), testPoolConfig, nil) - if err != nil { - errCh <- err - return errCh - } - - // test pool execution - rsp, err = f.pool.Exec(r) - if err != nil { - errCh <- err - return errCh - } - - // echo of the "test" should be -> test - if string(rsp.Body) != Response { - errCh <- errors.E("response from worker is wrong", errors.Errorf("response: %s", rsp.Body)) - return errCh - } - - return errCh -} - -func (f *Foo) Stop() error { - f.pool.Destroy(context.Background()) - return nil -} diff --git a/tests/plugins/server/plugin_sockets.go b/tests/plugins/server/plugin_sockets.go deleted file mode 100644 index 143a604c..00000000 --- a/tests/plugins/server/plugin_sockets.go +++ /dev/null @@ -1,109 +0,0 @@ -package server - -import ( - "context" - - "github.com/spiral/errors" - "github.com/spiral/roadrunner/v2/pkg/payload" - "github.com/spiral/roadrunner/v2/pkg/pool" - "github.com/spiral/roadrunner/v2/pkg/worker" - "github.com/spiral/roadrunner/v2/plugins/config" - "github.com/spiral/roadrunner/v2/plugins/server" -) - -type Foo2 struct { - configProvider config.Configurer - wf server.Server - pool pool.Pool -} - -func (f *Foo2) Init(p config.Configurer, workerFactory server.Server) error { - f.configProvider = p - f.wf = workerFactory - return nil -} - -func (f *Foo2) Serve() chan error { - const op = errors.Op("serve") - var err error - errCh := make(chan error, 1) - conf := &server.Config{} - - // test payload for echo - r := &payload.Payload{ - Context: nil, - Body: []byte(Response), - } - - err = f.configProvider.UnmarshalKey(ConfigSection, conf) - if err != nil { - errCh <- err - return errCh - } - - // test CMDFactory - cmd, err := f.wf.CmdFactory(nil) - if err != nil { - errCh <- err - return errCh - } - if cmd == nil { - errCh <- errors.E(op, "command is nil") - return errCh - } - - // test worker creation - w, err := f.wf.NewWorker(context.Background(), nil) - if err != nil { - errCh <- err - return errCh - } - - // test that our worker is functional - sw := worker.From(w) - - rsp, err := sw.Exec(r) - if err != nil { - errCh <- err - return errCh - } - - if string(rsp.Body) != Response { - errCh <- errors.E("response from worker is wrong", errors.Errorf("response: %s", rsp.Body)) - return errCh - } - - // should not be errors - err = sw.Stop() - if err != nil { - errCh <- err - return errCh - } - - // test pool - f.pool, err = f.wf.NewWorkerPool(context.Background(), testPoolConfig, nil) - if err != nil { - errCh <- err - return errCh - } - - // test pool execution - rsp, err = f.pool.Exec(r) - if err != nil { - errCh <- err - return errCh - } - - // echo of the "test" should be -> test - if string(rsp.Body) != Response { - errCh <- errors.E("response from worker is wrong", errors.Errorf("response: %s", rsp.Body)) - return errCh - } - - return errCh -} - -func (f *Foo2) Stop() error { - f.pool.Destroy(context.Background()) - return nil -} diff --git a/tests/plugins/server/plugin_tcp.go b/tests/plugins/server/plugin_tcp.go deleted file mode 100644 index 57a2e6ea..00000000 --- a/tests/plugins/server/plugin_tcp.go +++ /dev/null @@ -1,109 +0,0 @@ -package server - -import ( - "context" - - "github.com/spiral/errors" - "github.com/spiral/roadrunner/v2/pkg/payload" - "github.com/spiral/roadrunner/v2/pkg/pool" - "github.com/spiral/roadrunner/v2/pkg/worker" - "github.com/spiral/roadrunner/v2/plugins/config" - "github.com/spiral/roadrunner/v2/plugins/server" -) - -type Foo3 struct { - configProvider config.Configurer - wf server.Server - pool pool.Pool -} - -func (f *Foo3) Init(p config.Configurer, workerFactory server.Server) error { - f.configProvider = p - f.wf = workerFactory - return nil -} - -func (f *Foo3) Serve() chan error { - const op = errors.Op("serve") - var err error - errCh := make(chan error, 1) - conf := &server.Config{} - - // test payload for echo - r := &payload.Payload{ - Context: nil, - Body: []byte(Response), - } - - err = f.configProvider.UnmarshalKey(ConfigSection, conf) - if err != nil { - errCh <- err - return errCh - } - - // test CMDFactory - cmd, err := f.wf.CmdFactory(nil) - if err != nil { - errCh <- err - return errCh - } - if cmd == nil { - errCh <- errors.E(op, "command is nil") - return errCh - } - - // test worker creation - w, err := f.wf.NewWorker(context.Background(), nil) - if err != nil { - errCh <- err - return errCh - } - - // test that our worker is functional - sw := worker.From(w) - - rsp, err := sw.Exec(r) - if err != nil { - errCh <- err - return errCh - } - - if string(rsp.Body) != Response { - errCh <- errors.E("response from worker is wrong", errors.Errorf("response: %s", rsp.Body)) - return errCh - } - - // should not be errors - err = sw.Stop() - if err != nil { - errCh <- err - return errCh - } - - // test pool - f.pool, err = f.wf.NewWorkerPool(context.Background(), testPoolConfig, nil) - if err != nil { - errCh <- err - return errCh - } - - // test pool execution - rsp, err = f.pool.Exec(r) - if err != nil { - errCh <- err - return errCh - } - - // echo of the "test" should be -> test - if string(rsp.Body) != Response { - errCh <- errors.E("response from worker is wrong", errors.Errorf("response: %s", rsp.Body)) - return errCh - } - - return errCh -} - -func (f *Foo3) Stop() error { - f.pool.Destroy(context.Background()) - return nil -} diff --git a/tests/plugins/server/server_plugin_test.go b/tests/plugins/server/server_plugin_test.go deleted file mode 100644 index 06c9eb50..00000000 --- a/tests/plugins/server/server_plugin_test.go +++ /dev/null @@ -1,352 +0,0 @@ -package server - -import ( - "os" - "os/signal" - "sync" - "testing" - "time" - - endure "github.com/spiral/endure/pkg/container" - "github.com/spiral/roadrunner/v2/plugins/config" - "github.com/spiral/roadrunner/v2/plugins/logger" - "github.com/spiral/roadrunner/v2/plugins/server" - "github.com/stretchr/testify/assert" -) - -func TestAppPipes(t *testing.T) { - container, err := endure.NewContainer(nil, endure.RetryOnFail(true), endure.SetLogLevel(endure.ErrorLevel)) - if err != nil { - t.Fatal(err) - } - // config plugin - vp := &config.Viper{} - vp.Path = "configs/.rr.yaml" - vp.Prefix = "rr" - - err = container.RegisterAll( - vp, - &server.Plugin{}, - &Foo{}, - &logger.ZapLogger{}, - ) - if err != nil { - t.Fatal(err) - } - - err = container.Init() - if err != nil { - t.Fatal(err) - } - - errCh, err := container.Serve() - if err != nil { - t.Fatal(err) - } - - // stop by CTRL+C - c := make(chan os.Signal, 1) - signal.Notify(c, os.Interrupt) - - tt := time.NewTimer(time.Second * 10) - wg := &sync.WaitGroup{} - wg.Add(1) - - go func() { - defer wg.Done() - defer tt.Stop() - for { - select { - case e := <-errCh: - assert.NoError(t, e.Error) - assert.NoError(t, container.Stop()) - return - case <-c: - er := container.Stop() - assert.NoError(t, er) - return - case <-tt.C: - assert.NoError(t, container.Stop()) - return - } - } - }() - - wg.Wait() -} - -func TestAppSockets(t *testing.T) { - container, err := endure.NewContainer(nil, endure.RetryOnFail(true), endure.SetLogLevel(endure.ErrorLevel)) - if err != nil { - t.Fatal(err) - } - // config plugin - vp := &config.Viper{} - vp.Path = "configs/.rr-sockets.yaml" - vp.Prefix = "rr" - err = container.Register(vp) - if err != nil { - t.Fatal(err) - } - - err = container.Register(&server.Plugin{}) - if err != nil { - t.Fatal(err) - } - - err = container.Register(&Foo2{}) - if err != nil { - t.Fatal(err) - } - - err = container.Register(&logger.ZapLogger{}) - if err != nil { - t.Fatal(err) - } - - err = container.Init() - if err != nil { - t.Fatal(err) - } - - errCh, err := container.Serve() - if err != nil { - t.Fatal(err) - } - - // stop by CTRL+C - c := make(chan os.Signal, 1) - signal.Notify(c, os.Interrupt) - - // stop after 10 seconds - tt := time.NewTicker(time.Second * 10) - - for { - select { - case e := <-errCh: - assert.NoError(t, e.Error) - assert.NoError(t, container.Stop()) - return - case <-c: - er := container.Stop() - if er != nil { - panic(er) - } - return - case <-tt.C: - tt.Stop() - assert.NoError(t, container.Stop()) - return - } - } -} - -func TestAppTCP(t *testing.T) { - container, err := endure.NewContainer(nil, endure.RetryOnFail(true), endure.SetLogLevel(endure.ErrorLevel)) - if err != nil { - t.Fatal(err) - } - // config plugin - vp := &config.Viper{} - vp.Path = "configs/.rr-tcp.yaml" - vp.Prefix = "rr" - err = container.Register(vp) - if err != nil { - t.Fatal(err) - } - - err = container.Register(&server.Plugin{}) - if err != nil { - t.Fatal(err) - } - - err = container.Register(&Foo3{}) - if err != nil { - t.Fatal(err) - } - - err = container.Register(&logger.ZapLogger{}) - if err != nil { - t.Fatal(err) - } - - err = container.Init() - if err != nil { - t.Fatal(err) - } - - errCh, err := container.Serve() - if err != nil { - t.Fatal(err) - } - - // stop by CTRL+C - c := make(chan os.Signal, 1) - signal.Notify(c, os.Interrupt) - - // stop after 10 seconds - tt := time.NewTicker(time.Second * 10) - - for { - select { - case e := <-errCh: - assert.NoError(t, e.Error) - assert.NoError(t, container.Stop()) - return - case <-c: - er := container.Stop() - if er != nil { - panic(er) - } - return - case <-tt.C: - tt.Stop() - assert.NoError(t, container.Stop()) - return - } - } -} - -func TestAppWrongConfig(t *testing.T) { - container, err := endure.NewContainer(nil, endure.RetryOnFail(true), endure.SetLogLevel(endure.ErrorLevel)) - if err != nil { - t.Fatal(err) - } - // config plugin - vp := &config.Viper{} - vp.Path = "configs/.rrrrrrrrrr.yaml" - vp.Prefix = "rr" - err = container.Register(vp) - if err != nil { - t.Fatal(err) - } - - err = container.Register(&server.Plugin{}) - if err != nil { - t.Fatal(err) - } - - err = container.Register(&Foo3{}) - if err != nil { - t.Fatal(err) - } - - err = container.Register(&logger.ZapLogger{}) - if err != nil { - t.Fatal(err) - } - - assert.Error(t, container.Init()) -} - -func TestAppWrongRelay(t *testing.T) { - container, err := endure.NewContainer(nil, endure.RetryOnFail(true), endure.SetLogLevel(endure.ErrorLevel)) - if err != nil { - t.Fatal(err) - } - // config plugin - vp := &config.Viper{} - vp.Path = "configs/.rr-wrong-relay.yaml" - vp.Prefix = "rr" - err = container.Register(vp) - if err != nil { - t.Fatal(err) - } - - err = container.Register(&server.Plugin{}) - if err != nil { - t.Fatal(err) - } - - err = container.Register(&Foo3{}) - if err != nil { - t.Fatal(err) - } - - err = container.Register(&logger.ZapLogger{}) - if err != nil { - t.Fatal(err) - } - - err = container.Init() - assert.NoError(t, err) - - _, err = container.Serve() - assert.Error(t, err) -} - -func TestAppWrongCommand(t *testing.T) { - container, err := endure.NewContainer(nil, endure.RetryOnFail(true), endure.SetLogLevel(endure.ErrorLevel)) - if err != nil { - t.Fatal(err) - } - // config plugin - vp := &config.Viper{} - vp.Path = "configs/.rr-wrong-command.yaml" - vp.Prefix = "rr" - err = container.Register(vp) - if err != nil { - t.Fatal(err) - } - - err = container.Register(&server.Plugin{}) - if err != nil { - t.Fatal(err) - } - - err = container.Register(&Foo3{}) - if err != nil { - t.Fatal(err) - } - - err = container.Register(&logger.ZapLogger{}) - if err != nil { - t.Fatal(err) - } - - err = container.Init() - if err != nil { - t.Fatal(err) - } - - _, err = container.Serve() - assert.Error(t, err) -} - -func TestAppNoAppSectionInConfig(t *testing.T) { - container, err := endure.NewContainer(nil, endure.RetryOnFail(true), endure.SetLogLevel(endure.ErrorLevel)) - if err != nil { - t.Fatal(err) - } - // config plugin - vp := &config.Viper{} - vp.Path = "configs/.rr-wrong-command.yaml" - vp.Prefix = "rr" - err = container.Register(vp) - if err != nil { - t.Fatal(err) - } - - err = container.Register(&server.Plugin{}) - if err != nil { - t.Fatal(err) - } - - err = container.Register(&Foo3{}) - if err != nil { - t.Fatal(err) - } - - err = container.Register(&logger.ZapLogger{}) - if err != nil { - t.Fatal(err) - } - - err = container.Init() - if err != nil { - t.Fatal(err) - } - - _, err = container.Serve() - assert.Error(t, err) -} diff --git a/tests/plugins/server/socket.php b/tests/plugins/server/socket.php deleted file mode 100644 index f90dda6f..00000000 --- a/tests/plugins/server/socket.php +++ /dev/null @@ -1,25 +0,0 @@ -<?php -/** - * @var Goridge\RelayInterface $relay - */ - -use Spiral\Goridge; -use Spiral\RoadRunner; - -require dirname(__DIR__) . "/../vendor/autoload.php"; - -$relay = new Goridge\SocketRelay( - "unix.sock", - null, - Goridge\SocketRelay::SOCK_UNIX - ); - -$rr = new RoadRunner\Worker($relay); - -while ($in = $rr->waitPayload()) { - try { - $rr->respond(new RoadRunner\Payload((string)$in->body)); - } catch (\Throwable $e) { - $rr->error((string)$e); - } -} diff --git a/tests/plugins/server/tcp.php b/tests/plugins/server/tcp.php deleted file mode 100644 index acc1e1a5..00000000 --- a/tests/plugins/server/tcp.php +++ /dev/null @@ -1,20 +0,0 @@ -<?php -/** - * @var Goridge\RelayInterface $relay - */ - -use Spiral\Goridge; -use Spiral\RoadRunner; - -require dirname(__DIR__) . "/../vendor/autoload.php"; - -$relay = new Goridge\SocketRelay("127.0.0.1", 9999); -$rr = new RoadRunner\Worker($relay); - -while ($in = $rr->waitPayload()) { - try { - $rr->respond(new RoadRunner\Payload((string)$in->body)); - } catch (\Throwable $e) { - $rr->error((string)$e); - } -} diff --git a/tests/plugins/service/configs/.rr-service-error.yaml b/tests/plugins/service/configs/.rr-service-error.yaml deleted file mode 100644 index 3b0f1eb9..00000000 --- a/tests/plugins/service/configs/.rr-service-error.yaml +++ /dev/null @@ -1,16 +0,0 @@ -service: - some_service_1: - command: "php test_files/loopo.php" - process_num: 1 - exec_timeout: 5s # s,m,h (seconds, minutes, hours) - remain_after_exit: true - restart_sec: 1 - -logs: - level: info - mode: raw - -endure: - grace_period: 120s - print_graph: false - log_level: error diff --git a/tests/plugins/service/configs/.rr-service-init.yaml b/tests/plugins/service/configs/.rr-service-init.yaml deleted file mode 100644 index e32f2eda..00000000 --- a/tests/plugins/service/configs/.rr-service-init.yaml +++ /dev/null @@ -1,22 +0,0 @@ -service: - some_service_1: - command: "php test_files/loop.php" - process_num: 1 - exec_timeout: 5s # s,m,h (seconds, minutes, hours) - remain_after_exit: true - restart_sec: 1 - some_service_2: - command: "test_files/test_binary" - process_num: 1 - remain_after_exit: true - restart_delay: 1s - exec_timeout: 5s - -logs: - level: info - mode: raw - -endure: - grace_period: 120s - print_graph: false - log_level: error diff --git a/tests/plugins/service/configs/.rr-service-restarts.yaml b/tests/plugins/service/configs/.rr-service-restarts.yaml deleted file mode 100644 index f08d5720..00000000 --- a/tests/plugins/service/configs/.rr-service-restarts.yaml +++ /dev/null @@ -1,16 +0,0 @@ -service: - some_service_2: - command: "test_files/test_binary" - process_num: 1 - remain_after_exit: true - restart_delay: 1s - exec_timeout: 2s - -logs: - level: debug - mode: raw - -endure: - grace_period: 120s - print_graph: false - log_level: error diff --git a/tests/plugins/service/service_plugin_test.go b/tests/plugins/service/service_plugin_test.go deleted file mode 100644 index ddf54520..00000000 --- a/tests/plugins/service/service_plugin_test.go +++ /dev/null @@ -1,254 +0,0 @@ -//go:build linux -// +build linux - -package service - -import ( - "os" - "os/signal" - "sync" - "syscall" - "testing" - "time" - - "github.com/golang/mock/gomock" - endure "github.com/spiral/endure/pkg/container" - "github.com/spiral/roadrunner/v2/plugins/config" - "github.com/spiral/roadrunner/v2/plugins/service" - "github.com/spiral/roadrunner/v2/tests/mocks" - "github.com/stretchr/testify/assert" -) - -func TestServiceInit(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-service-init.yaml", - Prefix: "rr", - } - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - - mockLogger.EXPECT().Debug("worker destructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Info("The number is: 0\n").MinTimes(1) - mockLogger.EXPECT().Info("The number is: 1\n").MinTimes(1) - mockLogger.EXPECT().Info("The number is: 2\n").MinTimes(1) - mockLogger.EXPECT().Info("The number is: 3\n").MinTimes(1) - mockLogger.EXPECT().Info("The number is: 4\n").AnyTimes() - - // process interrupt error - mockLogger.EXPECT().Error("process wait error", gomock.Any()).MinTimes(2) - - mockLogger.EXPECT().Info("Hello 0").MinTimes(1) - mockLogger.EXPECT().Info("Hello 1").MinTimes(1) - mockLogger.EXPECT().Info("Hello 2").MinTimes(1) - mockLogger.EXPECT().Info("Hello 3").MinTimes(1) - mockLogger.EXPECT().Info("Hello 4").AnyTimes() - - err = cont.RegisterAll( - cfg, - mockLogger, - &service.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 10) - stopCh <- struct{}{} - wg.Wait() -} - -func TestServiceError(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-service-error.yaml", - Prefix: "rr", - } - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - - mockLogger.EXPECT().Debug("worker destructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).AnyTimes() - - // process interrupt error - mockLogger.EXPECT().Error("process wait error", gomock.Any()).MinTimes(2) - - err = cont.RegisterAll( - cfg, - mockLogger, - &service.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - assert.NoError(t, err) - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 10) - stopCh <- struct{}{} - wg.Wait() -} - -func TestServiceRestarts(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-service-restarts.yaml", - Prefix: "rr", - } - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - - mockLogger.EXPECT().Debug("worker destructed", "pid", gomock.Any()).AnyTimes() - mockLogger.EXPECT().Debug("worker constructed", "pid", gomock.Any()).AnyTimes() - - // process interrupt error - mockLogger.EXPECT().Error("process wait error", gomock.Any()).MinTimes(1) - - // should not be more than Hello 0, because of restarts - mockLogger.EXPECT().Info("Hello 0").MinTimes(1) - mockLogger.EXPECT().Info("Hello 1").AnyTimes() - - err = cont.RegisterAll( - cfg, - mockLogger, - &service.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 10) - stopCh <- struct{}{} - wg.Wait() -} diff --git a/tests/plugins/service/test_files/loop.php b/tests/plugins/service/test_files/loop.php deleted file mode 100644 index 6ba488ef..00000000 --- a/tests/plugins/service/test_files/loop.php +++ /dev/null @@ -1,6 +0,0 @@ -<?php -for ($x = 0; $x <= 1000; $x++) { - sleep(1); - error_log("The number is: $x", 0); -} -?> diff --git a/tests/plugins/service/test_files/test_binary b/tests/plugins/service/test_files/test_binary Binary files differdeleted file mode 100755 index 480fb7e2..00000000 --- a/tests/plugins/service/test_files/test_binary +++ /dev/null diff --git a/tests/plugins/status/configs/.rr-ready-init.yaml b/tests/plugins/status/configs/.rr-ready-init.yaml deleted file mode 100755 index da9e84c3..00000000 --- a/tests/plugins/status/configs/.rr-ready-init.yaml +++ /dev/null @@ -1,28 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6007 - -server: - command: "php ../../sleep.php" - user: "" - group: "" - relay: "pipes" - relay_timeout: "20s" - -status: - address: "127.0.0.1:34334" - -logs: - mode: development - level: error -http: - address: 127.0.0.1:11933 - max_request_size: 1024 - middleware: [ "" ] - uploads: - forbid: [ ".php", ".exe", ".bat" ] - trusted_subnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] - pool: - num_workers: 1 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s diff --git a/tests/plugins/status/configs/.rr-status-init.yaml b/tests/plugins/status/configs/.rr-status-init.yaml deleted file mode 100755 index c791c10f..00000000 --- a/tests/plugins/status/configs/.rr-status-init.yaml +++ /dev/null @@ -1,28 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6005 - -server: - command: "php ../../http/client.php echo pipes" - user: "" - group: "" - relay: "pipes" - relay_timeout: "20s" - -status: - address: "127.0.0.1:34333" - -logs: - mode: development - level: error -http: - address: 127.0.0.1:11933 - max_request_size: 1024 - middleware: [ "" ] - uploads: - forbid: [ ".php", ".exe", ".bat" ] - trusted_subnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] - pool: - num_workers: 2 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s
\ No newline at end of file diff --git a/tests/plugins/status/plugin_test.go b/tests/plugins/status/plugin_test.go deleted file mode 100644 index 227cfd46..00000000 --- a/tests/plugins/status/plugin_test.go +++ /dev/null @@ -1,388 +0,0 @@ -package status - -import ( - "io/ioutil" - "net" - "net/http" - "net/rpc" - "os" - "os/signal" - "sync" - "syscall" - "testing" - "time" - - endure "github.com/spiral/endure/pkg/container" - goridgeRpc "github.com/spiral/goridge/v3/pkg/rpc" - "github.com/spiral/roadrunner/v2/plugins/config" - httpPlugin "github.com/spiral/roadrunner/v2/plugins/http" - "github.com/spiral/roadrunner/v2/plugins/logger" - rpcPlugin "github.com/spiral/roadrunner/v2/plugins/rpc" - "github.com/spiral/roadrunner/v2/plugins/server" - "github.com/spiral/roadrunner/v2/plugins/status" - "github.com/stretchr/testify/assert" -) - -func TestStatusHttp(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-status-init.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &logger.ZapLogger{}, - &server.Plugin{}, - &httpPlugin.Plugin{}, - &status.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second) - t.Run("CheckerGetStatus", checkHTTPStatus) - - stopCh <- struct{}{} - wg.Wait() -} - -const resp = `Service: http: Status: 200 -Service: rpc not found` - -func checkHTTPStatus(t *testing.T) { - req, err := http.NewRequest("GET", "http://127.0.0.1:34333/health?plugin=http&plugin=rpc", nil) - assert.NoError(t, err) - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - b, err := ioutil.ReadAll(r.Body) - assert.NoError(t, err) - assert.Equal(t, 200, r.StatusCode) - assert.Equal(t, resp, string(b)) - - err = r.Body.Close() - assert.NoError(t, err) -} - -func TestStatusRPC(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-status-init.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &rpcPlugin.Plugin{}, - &logger.ZapLogger{}, - &server.Plugin{}, - &httpPlugin.Plugin{}, - &status.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second) - t.Run("CheckerGetStatusRpc", checkRPCStatus) - stopCh <- struct{}{} - wg.Wait() -} - -func checkRPCStatus(t *testing.T) { - conn, err := net.Dial("tcp", "127.0.0.1:6005") - assert.NoError(t, err) - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - - st := &status.Status{} - - err = client.Call("status.Status", "http", &st) - assert.NoError(t, err) - assert.Equal(t, st.Code, 200) -} - -func TestReadyHttp(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-status-init.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &logger.ZapLogger{}, - &server.Plugin{}, - &httpPlugin.Plugin{}, - &status.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second) - t.Run("CheckerGetReadiness", checkHTTPReadiness) - - stopCh <- struct{}{} - wg.Wait() -} - -const resp2 = `Service: http: Status: 204 -Service: rpc not found` - -func checkHTTPReadiness(t *testing.T) { - req, err := http.NewRequest("GET", "http://127.0.0.1:34333/ready?plugin=http&plugin=rpc", nil) - assert.NoError(t, err) - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - b, err := ioutil.ReadAll(r.Body) - assert.NoError(t, err) - assert.Equal(t, 200, r.StatusCode) - assert.Equal(t, resp, string(b)) - - err = r.Body.Close() - assert.NoError(t, err) -} - -func TestReadinessRPCWorkerNotReady(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel), endure.GracefulShutdownTimeout(time.Second*2)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-ready-init.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &rpcPlugin.Plugin{}, - &logger.ZapLogger{}, - &server.Plugin{}, - &httpPlugin.Plugin{}, - &status.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout, error here is OK, because in the PHP we are sleeping for the 300s - _ = cont.Stop() - return - } - } - }() - - time.Sleep(time.Second) - t.Run("DoHttpReq", doHTTPReq) - time.Sleep(time.Second * 5) - t.Run("CheckerGetReadiness2", checkHTTPReadiness2) - t.Run("CheckerGetRpcReadiness", checkRPCReadiness) - stopCh <- struct{}{} - wg.Wait() -} - -func doHTTPReq(t *testing.T) { - go func() { - req, err := http.NewRequest("GET", "http://127.0.0.1:11933", nil) - assert.NoError(t, err) - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - b, err := ioutil.ReadAll(r.Body) - assert.NoError(t, err) - assert.Equal(t, 200, r.StatusCode) - assert.Equal(t, resp2, string(b)) - - err = r.Body.Close() - assert.NoError(t, err) - }() -} - -func checkHTTPReadiness2(t *testing.T) { - req, err := http.NewRequest("GET", "http://127.0.0.1:34334/ready?plugin=http&plugin=rpc", nil) - assert.NoError(t, err) - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - b, err := ioutil.ReadAll(r.Body) - assert.NoError(t, err) - assert.Equal(t, 503, r.StatusCode) - assert.Equal(t, "", string(b)) - - err = r.Body.Close() - assert.NoError(t, err) -} - -func checkRPCReadiness(t *testing.T) { - conn, err := net.Dial("tcp", "127.0.0.1:6007") - assert.NoError(t, err) - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - - st := &status.Status{} - - err = client.Call("status.Ready", "http", &st) - assert.NoError(t, err) - assert.Equal(t, st.Code, 503) -} diff --git a/tests/plugins/websockets/configs/.rr-websockets-allow.yaml b/tests/plugins/websockets/configs/.rr-websockets-allow.yaml deleted file mode 100644 index 3d0268d4..00000000 --- a/tests/plugins/websockets/configs/.rr-websockets-allow.yaml +++ /dev/null @@ -1,52 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../worker-ok.php" - user: "" - group: "" - relay: "pipes" - relay_timeout: "20s" - -http: - address: 127.0.0.1:41278 - max_request_size: 1024 - middleware: ["websockets"] - trusted_subnets: - [ - "10.0.0.0/8", - "127.0.0.0/8", - "172.16.0.0/12", - "192.168.0.0/16", - "::1/128", - "fc00::/7", - "fe80::/10", - ] - pool: - num_workers: 2 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s - -redis: - addrs: - - "127.0.0.1:6379" - -broadcast: - test: - driver: memory - config: {} - -websockets: - broker: test - allowed_origin: "*" - path: "/ws" - -logs: - mode: development - level: error - -endure: - grace_period: 120s - print_graph: false - log_level: error diff --git a/tests/plugins/websockets/configs/.rr-websockets-allow2.yaml b/tests/plugins/websockets/configs/.rr-websockets-allow2.yaml deleted file mode 100644 index f8e36136..00000000 --- a/tests/plugins/websockets/configs/.rr-websockets-allow2.yaml +++ /dev/null @@ -1,54 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../worker-ok.php" - user: "" - group: "" - relay: "pipes" - relay_timeout: "20s" - -http: - address: 127.0.0.1:41270 - max_request_size: 1024 - middleware: ["websockets"] - trusted_subnets: - [ - "10.0.0.0/8", - "127.0.0.0/8", - "172.16.0.0/12", - "192.168.0.0/16", - "::1/128", - "fc00::/7", - "fe80::/10", - ] - pool: - num_workers: 2 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s - -test: - addrs: - - "127.0.0.1:6379" - -broadcast: - test: - driver: redis - config: - addrs: - - "127.0.0.1:6379" - -websockets: - broker: test - allowed_origin: "*" - path: "/ws" - -logs: - mode: development - level: error - -endure: - grace_period: 120s - print_graph: false - log_level: error diff --git a/tests/plugins/websockets/configs/.rr-websockets-broker-no-section.yaml b/tests/plugins/websockets/configs/.rr-websockets-broker-no-section.yaml deleted file mode 100644 index c72e1f15..00000000 --- a/tests/plugins/websockets/configs/.rr-websockets-broker-no-section.yaml +++ /dev/null @@ -1,48 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../psr-worker-bench.php" - user: "" - group: "" - relay: "pipes" - relay_timeout: "20s" - -http: - address: 127.0.0.1:13235 - max_request_size: 1024 - middleware: ["websockets"] - trusted_subnets: - [ - "10.0.0.0/8", - "127.0.0.0/8", - "172.16.0.0/12", - "192.168.0.0/16", - "::1/128", - "fc00::/7", - "fe80::/10", - ] - pool: - num_workers: 2 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s - -broadcast: - test1: - driver: no - config: - -websockets: - broker: test - allowed_origin: "*" - path: "/ws" - -logs: - mode: development - level: error - -endure: - grace_period: 120s - print_graph: false - log_level: error diff --git a/tests/plugins/websockets/configs/.rr-websockets-deny.yaml b/tests/plugins/websockets/configs/.rr-websockets-deny.yaml deleted file mode 100644 index 61265c4b..00000000 --- a/tests/plugins/websockets/configs/.rr-websockets-deny.yaml +++ /dev/null @@ -1,48 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../worker-deny.php" - user: "" - group: "" - relay: "pipes" - relay_timeout: "20s" - -http: - address: 127.0.0.1:15587 - max_request_size: 1024 - middleware: ["websockets"] - trusted_subnets: - [ - "10.0.0.0/8", - "127.0.0.0/8", - "172.16.0.0/12", - "192.168.0.0/16", - "::1/128", - "fc00::/7", - "fe80::/10", - ] - pool: - num_workers: 2 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s - -broadcast: - test: - driver: memory - config: {} - -websockets: - broker: test - allowed_origin: "*" - path: "/ws" - -logs: - mode: development - level: error - -endure: - grace_period: 120s - print_graph: false - log_level: error diff --git a/tests/plugins/websockets/configs/.rr-websockets-deny2.yaml b/tests/plugins/websockets/configs/.rr-websockets-deny2.yaml deleted file mode 100644 index b99a3571..00000000 --- a/tests/plugins/websockets/configs/.rr-websockets-deny2.yaml +++ /dev/null @@ -1,50 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../worker-deny.php" - user: "" - group: "" - relay: "pipes" - relay_timeout: "20s" - -http: - address: 127.0.0.1:15588 - max_request_size: 1024 - middleware: ["websockets"] - trusted_subnets: - [ - "10.0.0.0/8", - "127.0.0.0/8", - "172.16.0.0/12", - "192.168.0.0/16", - "::1/128", - "fc00::/7", - "fe80::/10", - ] - pool: - num_workers: 2 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s - -broadcast: - test: - driver: redis - config: - addrs: - - "127.0.0.1:6379" - -websockets: - broker: test - allowed_origin: "*" - path: "/ws" - -logs: - mode: development - level: error - -endure: - grace_period: 120s - print_graph: false - log_level: error diff --git a/tests/plugins/websockets/configs/.rr-websockets-init.yaml b/tests/plugins/websockets/configs/.rr-websockets-init.yaml deleted file mode 100644 index 3120f146..00000000 --- a/tests/plugins/websockets/configs/.rr-websockets-init.yaml +++ /dev/null @@ -1,48 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../psr-worker-bench.php" - user: "" - group: "" - relay: "pipes" - relay_timeout: "20s" - -http: - address: 127.0.0.1:11111 - max_request_size: 1024 - middleware: ["websockets"] - trusted_subnets: - [ - "10.0.0.0/8", - "127.0.0.0/8", - "172.16.0.0/12", - "192.168.0.0/16", - "::1/128", - "fc00::/7", - "fe80::/10", - ] - pool: - num_workers: 2 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s - -broadcast: - default: - driver: memory - config: {} - -websockets: - broker: default - allowed_origin: "*" - path: "/ws" - -logs: - mode: development - level: error - -endure: - grace_period: 120s - print_graph: false - log_level: error diff --git a/tests/plugins/websockets/configs/.rr-websockets-redis.yaml b/tests/plugins/websockets/configs/.rr-websockets-redis.yaml deleted file mode 100644 index fc01e0b1..00000000 --- a/tests/plugins/websockets/configs/.rr-websockets-redis.yaml +++ /dev/null @@ -1,51 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../psr-worker-bench.php" - user: "" - group: "" - relay: "pipes" - relay_timeout: "20s" - -http: - address: 127.0.0.1:13235 - max_request_size: 1024 - middleware: ["websockets"] - trusted_subnets: - [ - "10.0.0.0/8", - "127.0.0.0/8", - "172.16.0.0/12", - "192.168.0.0/16", - "::1/128", - "fc00::/7", - "fe80::/10", - ] - pool: - num_workers: 2 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s - -test: - addrs: - - "127.0.0.1:6379" - -broadcast: - test: - driver: redis - -websockets: - broker: test - allowed_origin: "*" - path: "/ws" - -logs: - mode: development - level: error - -endure: - grace_period: 120s - print_graph: false - log_level: error diff --git a/tests/plugins/websockets/configs/.rr-websockets-stop.yaml b/tests/plugins/websockets/configs/.rr-websockets-stop.yaml deleted file mode 100644 index 35529e9e..00000000 --- a/tests/plugins/websockets/configs/.rr-websockets-stop.yaml +++ /dev/null @@ -1,48 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - -server: - command: "php ../../worker-stop.php" - user: "" - group: "" - relay: "pipes" - relay_timeout: "20s" - -http: - address: 127.0.0.1:11114 - max_request_size: 1024 - middleware: ["websockets"] - trusted_subnets: - [ - "10.0.0.0/8", - "127.0.0.0/8", - "172.16.0.0/12", - "192.168.0.0/16", - "::1/128", - "fc00::/7", - "fe80::/10", - ] - pool: - num_workers: 2 - max_jobs: 0 - allocate_timeout: 60s - destroy_timeout: 60s - -broadcast: - test: - driver: memory - config: {} - -websockets: - broker: test - allowed_origin: "*" - path: "/ws" - -logs: - mode: development - level: error - -endure: - grace_period: 120s - print_graph: false - log_level: error diff --git a/tests/plugins/websockets/websocket_plugin_test.go b/tests/plugins/websockets/websocket_plugin_test.go deleted file mode 100644 index 3e74ca59..00000000 --- a/tests/plugins/websockets/websocket_plugin_test.go +++ /dev/null @@ -1,918 +0,0 @@ -package websockets - -import ( - "net" - "net/http" - "net/rpc" - "net/url" - "os" - "os/signal" - "sync" - "syscall" - "testing" - "time" - - "github.com/fasthttp/websocket" - json "github.com/json-iterator/go" - endure "github.com/spiral/endure/pkg/container" - goridgeRpc "github.com/spiral/goridge/v3/pkg/rpc" - "github.com/spiral/roadrunner/v2/plugins/broadcast" - "github.com/spiral/roadrunner/v2/plugins/config" - httpPlugin "github.com/spiral/roadrunner/v2/plugins/http" - "github.com/spiral/roadrunner/v2/plugins/logger" - "github.com/spiral/roadrunner/v2/plugins/memory" - "github.com/spiral/roadrunner/v2/plugins/redis" - rpcPlugin "github.com/spiral/roadrunner/v2/plugins/rpc" - "github.com/spiral/roadrunner/v2/plugins/server" - "github.com/spiral/roadrunner/v2/plugins/websockets" - websocketsv1 "github.com/spiral/roadrunner/v2/proto/websockets/v1beta" - "github.com/spiral/roadrunner/v2/utils" - "github.com/stretchr/testify/assert" -) - -func TestWebsocketsInit(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-websockets-init.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &rpcPlugin.Plugin{}, - &logger.ZapLogger{}, - &server.Plugin{}, - &redis.Plugin{}, - &websockets.Plugin{}, - &httpPlugin.Plugin{}, - &memory.Plugin{}, - &broadcast.Plugin{}, - ) - - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - if err != nil { - t.Fatal(err) - } - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 1) - t.Run("TestWSInit", wsInit) - t.Run("RPCWsMemoryPubAsync", RPCWsPubAsync("11111")) - t.Run("RPCWsMemory", RPCWsPub("11111")) - - stopCh <- struct{}{} - - wg.Wait() -} - -func TestWSRedis(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-websockets-redis.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &rpcPlugin.Plugin{}, - &logger.ZapLogger{}, - &server.Plugin{}, - &redis.Plugin{}, - &websockets.Plugin{}, - &httpPlugin.Plugin{}, - &broadcast.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - if err != nil { - t.Fatal(err) - } - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 1) - t.Run("RPCWsRedisPubAsync", RPCWsPubAsync("13235")) - t.Run("RPCWsRedisPub", RPCWsPub("13235")) - - stopCh <- struct{}{} - - wg.Wait() -} - -func TestWSRedisNoSection(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-websockets-broker-no-section.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &rpcPlugin.Plugin{}, - &logger.ZapLogger{}, - &server.Plugin{}, - &redis.Plugin{}, - &websockets.Plugin{}, - &httpPlugin.Plugin{}, - &broadcast.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - _, err = cont.Serve() - assert.Error(t, err) -} - -func TestWSDeny(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-websockets-deny.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &rpcPlugin.Plugin{}, - &logger.ZapLogger{}, - &server.Plugin{}, - &websockets.Plugin{}, - &httpPlugin.Plugin{}, - &memory.Plugin{}, - &broadcast.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - if err != nil { - t.Fatal(err) - } - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 1) - t.Run("RPCWsMemoryDeny", RPCWsDeny("15587")) - - stopCh <- struct{}{} - - wg.Wait() -} - -func TestWSDeny2(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-websockets-deny2.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &rpcPlugin.Plugin{}, - &logger.ZapLogger{}, - &server.Plugin{}, - &websockets.Plugin{}, - &httpPlugin.Plugin{}, - &redis.Plugin{}, - &broadcast.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - if err != nil { - t.Fatal(err) - } - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 1) - t.Run("RPCWsRedisDeny", RPCWsDeny("15588")) - - stopCh <- struct{}{} - - wg.Wait() -} - -func TestWSStop(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-websockets-stop.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &rpcPlugin.Plugin{}, - &logger.ZapLogger{}, - &server.Plugin{}, - &redis.Plugin{}, - &websockets.Plugin{}, - &httpPlugin.Plugin{}, - &memory.Plugin{}, - &broadcast.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - if err != nil { - t.Fatal(err) - } - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 1) - t.Run("RPCWsStop", RPCWsMemoryStop("11114")) - - stopCh <- struct{}{} - - wg.Wait() -} - -func RPCWsMemoryStop(port string) func(t *testing.T) { - return func(t *testing.T) { - da := websocket.Dialer{ - Proxy: http.ProxyFromEnvironment, - HandshakeTimeout: time.Second * 20, - } - - connURL := url.URL{Scheme: "ws", Host: "127.0.0.1:" + port, Path: "/ws"} - - c, resp, err := da.Dial(connURL.String(), nil) - assert.NotNil(t, resp) - assert.Error(t, err) - assert.Nil(t, c) - assert.Equal(t, http.StatusUnauthorized, resp.StatusCode) //nolint:staticcheck - assert.Equal(t, resp.Header.Get("Stop"), "we-dont-like-you") //nolint:staticcheck - if resp != nil && resp.Body != nil { //nolint:staticcheck - _ = resp.Body.Close() - } - } -} - -func TestWSAllow(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-websockets-allow.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &rpcPlugin.Plugin{}, - &logger.ZapLogger{}, - &server.Plugin{}, - &redis.Plugin{}, - &websockets.Plugin{}, - &httpPlugin.Plugin{}, - &memory.Plugin{}, - &broadcast.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - if err != nil { - t.Fatal(err) - } - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 1) - t.Run("RPCWsMemoryAllow", RPCWsPub("41278")) - - stopCh <- struct{}{} - - wg.Wait() -} - -func TestWSAllow2(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-websockets-allow2.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &rpcPlugin.Plugin{}, - &logger.ZapLogger{}, - &server.Plugin{}, - &redis.Plugin{}, - &websockets.Plugin{}, - &httpPlugin.Plugin{}, - &memory.Plugin{}, - &broadcast.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - if err != nil { - t.Fatal(err) - } - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - stopCh := make(chan struct{}, 1) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-stopCh: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 1) - t.Run("RPCWsMemoryAllow", RPCWsPub("41270")) - - stopCh <- struct{}{} - - wg.Wait() -} - -func wsInit(t *testing.T) { - da := websocket.Dialer{ - Proxy: http.ProxyFromEnvironment, - HandshakeTimeout: time.Second * 20, - } - - connURL := url.URL{Scheme: "ws", Host: "127.0.0.1:11111", Path: "/ws"} - - c, resp, err := da.Dial(connURL.String(), nil) - assert.NoError(t, err) - - defer func() { - _ = resp.Body.Close() - }() - - d, err := json.Marshal(messageWS("join", []byte("hello websockets"), "foo", "foo2")) - if err != nil { - panic(err) - } - - err = c.WriteMessage(websocket.BinaryMessage, d) - assert.NoError(t, err) - - _, msg, err := c.ReadMessage() - retMsg := utils.AsString(msg) - assert.NoError(t, err) - - // subscription done - assert.Equal(t, `{"topic":"@join","payload":["foo","foo2"]}`, retMsg) - - err = c.WriteControl(websocket.CloseMessage, nil, time.Time{}) - assert.NoError(t, err) -} - -func RPCWsPubAsync(port string) func(t *testing.T) { - return func(t *testing.T) { - da := websocket.Dialer{ - Proxy: http.ProxyFromEnvironment, - HandshakeTimeout: time.Second * 20, - } - - connURL := url.URL{Scheme: "ws", Host: "127.0.0.1:" + port, Path: "/ws"} - - c, resp, err := da.Dial(connURL.String(), nil) - assert.NoError(t, err) - - defer func() { - if resp != nil && resp.Body != nil { - _ = resp.Body.Close() - } - }() - - go func() { - messagesToVerify := make([]string, 0, 4) - messagesToVerify = append(messagesToVerify, `{"topic":"@join","payload":["foo","foo2"]}`) - messagesToVerify = append(messagesToVerify, `{"topic":"foo","payload":"hello, PHP"}`) - messagesToVerify = append(messagesToVerify, `{"topic":"@leave","payload":["foo"]}`) - messagesToVerify = append(messagesToVerify, `{"topic":"foo2","payload":"hello, PHP2"}`) - i := 0 - for { - _, msg, err2 := c.ReadMessage() - retMsg := utils.AsString(msg) - assert.NoError(t, err2) - assert.Equal(t, messagesToVerify[i], retMsg) - i++ - if i == 3 { - return - } - } - }() - - time.Sleep(time.Second) - - d, err := json.Marshal(messageWS("join", []byte("hello websockets"), "foo", "foo2")) - if err != nil { - panic(err) - } - - err = c.WriteMessage(websocket.BinaryMessage, d) - assert.NoError(t, err) - - time.Sleep(time.Second) - - publishAsync(t, "foo") - - time.Sleep(time.Second) - - // //// LEAVE foo ///////// - d, err = json.Marshal(messageWS("leave", []byte("hello websockets"), "foo")) - if err != nil { - panic(err) - } - - err = c.WriteMessage(websocket.BinaryMessage, d) - assert.NoError(t, err) - - time.Sleep(time.Second) - - // TRY TO PUBLISH TO UNSUBSCRIBED TOPIC - publishAsync(t, "foo") - - go func() { - time.Sleep(time.Second * 5) - publishAsync(t, "foo2") - }() - - err = c.WriteControl(websocket.CloseMessage, nil, time.Time{}) - assert.NoError(t, err) - } -} - -func RPCWsPub(port string) func(t *testing.T) { - return func(t *testing.T) { - da := websocket.Dialer{ - Proxy: http.ProxyFromEnvironment, - HandshakeTimeout: time.Second * 20, - } - - connURL := url.URL{Scheme: "ws", Host: "127.0.0.1:" + port, Path: "/ws"} - - c, resp, err := da.Dial(connURL.String(), nil) - assert.NoError(t, err) - - defer func() { - if resp != nil && resp.Body != nil { - _ = resp.Body.Close() - } - }() - - go func() { - messagesToVerify := make([]string, 0, 10) - messagesToVerify = append(messagesToVerify, `{"topic":"@join","payload":["foo","foo2"]}`) - messagesToVerify = append(messagesToVerify, `{"topic":"foo","payload":"hello, PHP"}`) - messagesToVerify = append(messagesToVerify, `{"topic":"@leave","payload":["foo"]}`) - messagesToVerify = append(messagesToVerify, `{"topic":"foo2","payload":"hello, PHP2"}`) - i := 0 - for { - _, msg, err2 := c.ReadMessage() - retMsg := utils.AsString(msg) - assert.NoError(t, err2) - assert.Equal(t, messagesToVerify[i], retMsg) - i++ - if i == 3 { - return - } - } - }() - - time.Sleep(time.Second) - - d, err := json.Marshal(messageWS("join", []byte("hello websockets"), "foo", "foo2")) - if err != nil { - panic(err) - } - - err = c.WriteMessage(websocket.BinaryMessage, d) - assert.NoError(t, err) - - time.Sleep(time.Second) - - publish("", "foo") - - time.Sleep(time.Second) - - // //// LEAVE foo ///////// - d, err = json.Marshal(messageWS("leave", []byte("hello websockets"), "foo")) - if err != nil { - panic(err) - } - - err = c.WriteMessage(websocket.BinaryMessage, d) - assert.NoError(t, err) - - time.Sleep(time.Second) - - // TRY TO PUBLISH TO UNSUBSCRIBED TOPIC - publish("", "foo") - - go func() { - time.Sleep(time.Second * 5) - publish2(t, "", "foo2") - }() - - err = c.WriteControl(websocket.CloseMessage, nil, time.Time{}) - assert.NoError(t, err) - } -} - -func RPCWsDeny(port string) func(t *testing.T) { - return func(t *testing.T) { - da := websocket.Dialer{ - Proxy: http.ProxyFromEnvironment, - HandshakeTimeout: time.Second * 20, - } - - connURL := url.URL{Scheme: "ws", Host: "127.0.0.1:" + port, Path: "/ws"} - - c, resp, err := da.Dial(connURL.String(), nil) - assert.NoError(t, err) - assert.NotNil(t, c) - assert.Equal(t, http.StatusSwitchingProtocols, resp.StatusCode) - - defer func() { - if resp != nil && resp.Body != nil { - _ = resp.Body.Close() - } - }() - - d, err := json.Marshal(messageWS("join", []byte("hello websockets"), "foo", "foo2")) - if err != nil { - panic(err) - } - - err = c.WriteMessage(websocket.BinaryMessage, d) - assert.NoError(t, err) - - _, msg, err := c.ReadMessage() - retMsg := utils.AsString(msg) - assert.NoError(t, err) - - // subscription done - assert.Equal(t, `{"topic":"#join","payload":["foo","foo2"]}`, retMsg) - - // //// LEAVE foo, foo2 ///////// - d, err = json.Marshal(messageWS("leave", []byte("hello websockets"), "foo")) - if err != nil { - panic(err) - } - - err = c.WriteMessage(websocket.BinaryMessage, d) - assert.NoError(t, err) - - _, msg, err = c.ReadMessage() - retMsg = utils.AsString(msg) - assert.NoError(t, err) - - // subscription done - assert.Equal(t, `{"topic":"@leave","payload":["foo"]}`, retMsg) - - err = c.WriteControl(websocket.CloseMessage, nil, time.Time{}) - assert.NoError(t, err) - } -} - -// --------------------------------------------------------------------------------------------------- - -func publish(topics ...string) { - conn, err := net.Dial("tcp", "127.0.0.1:6001") - if err != nil { - panic(err) - } - - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - - ret := &websocketsv1.Response{} - err = client.Call("broadcast.Publish", makeMessage([]byte("hello, PHP"), topics...), ret) - if err != nil { - panic(err) - } -} - -func publishAsync(t *testing.T, topics ...string) { - conn, err := net.Dial("tcp", "127.0.0.1:6001") - if err != nil { - panic(err) - } - - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - - ret := &websocketsv1.Response{} - err = client.Call("broadcast.PublishAsync", makeMessage([]byte("hello, PHP"), topics...), ret) - assert.NoError(t, err) - assert.True(t, ret.Ok) -} - -func publish2(t *testing.T, topics ...string) { - conn, err := net.Dial("tcp", "127.0.0.1:6001") - if err != nil { - panic(err) - } - - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - - ret := &websocketsv1.Response{} - err = client.Call("broadcast.Publish", makeMessage([]byte("hello, PHP2"), topics...), ret) - assert.NoError(t, err) - assert.True(t, ret.Ok) -} - -func messageWS(command string, payload []byte, topics ...string) *websocketsv1.Message { - return &websocketsv1.Message{ - Topics: topics, - Command: command, - Payload: payload, - } -} - -func makeMessage(payload []byte, topics ...string) *websocketsv1.Request { - m := &websocketsv1.Request{ - Messages: []*websocketsv1.Message{ - { - Topics: topics, - Payload: payload, - }, - }, - } - - return m -} |