diff options
author | Valery Piashchynski <[email protected]> | 2022-07-15 17:16:57 +0200 |
---|---|---|
committer | GitHub <[email protected]> | 2022-07-15 17:16:57 +0200 |
commit | ee688b78be4c756d26470f36c0fbf32f99a325a2 (patch) | |
tree | 552930e2790ad15d1f890f9abfac217a01c0be06 | |
parent | bb4a2bf33fc53728f438550fad6118c3bf4ff95c (diff) | |
parent | 867b8d1e443b7cb32d8276518fe9e49918a5fda2 (diff) |
[#1214]: feat: make RR embeddable in other programs
-rw-r--r-- | CHANGELOG.md | 7 | ||||
-rw-r--r-- | container/config.go (renamed from internal/container/config.go) | 0 | ||||
-rw-r--r-- | container/config_test.go (renamed from internal/container/config_test.go) | 2 | ||||
-rw-r--r-- | container/container.go (renamed from internal/container/container.go) | 0 | ||||
-rw-r--r-- | container/container_test.go (renamed from internal/container/container_test.go) | 3 | ||||
-rw-r--r-- | container/plugins.go (renamed from internal/container/plugins.go) | 0 | ||||
-rw-r--r-- | container/plugins_test.go (renamed from internal/container/plugins_test.go) | 0 | ||||
-rw-r--r-- | container/test/endure_ok.yaml (renamed from internal/container/test/endure_ok.yaml) | 0 | ||||
-rw-r--r-- | container/test/endure_ok_debug.yaml (renamed from internal/container/test/endure_ok_debug.yaml) | 0 | ||||
-rw-r--r-- | container/test/endure_ok_fatal.yaml (renamed from internal/container/test/endure_ok_fatal.yaml) | 0 | ||||
-rw-r--r-- | container/test/endure_ok_foobar.yaml (renamed from internal/container/test/endure_ok_foobar.yaml) | 0 | ||||
-rw-r--r-- | container/test/endure_ok_info.yaml (renamed from internal/container/test/endure_ok_info.yaml) | 0 | ||||
-rw-r--r-- | container/test/endure_ok_panic.yaml (renamed from internal/container/test/endure_ok_panic.yaml) | 0 | ||||
-rw-r--r-- | container/test/endure_ok_warn.yaml (renamed from internal/container/test/endure_ok_warn.yaml) | 0 | ||||
-rw-r--r-- | container/test/without_endure_ok.yaml (renamed from internal/container/test/without_endure_ok.yaml) | 0 | ||||
-rw-r--r-- | go.mod | 10 | ||||
-rw-r--r-- | go.sum | 20 | ||||
-rw-r--r-- | internal/cli/serve/command.go | 17 | ||||
-rw-r--r-- | lib/roadrunner.go | 111 | ||||
-rw-r--r-- | lib/roadrunner_test.go | 83 |
20 files changed, 224 insertions, 29 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ba5e6d8..41b94e2f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # CHANGELOG +## v2.11.0 (??.??.????) + +## 👀 New: + +- ✏️ **RoadRunner**: Can now be embedded in other go programs + + ## v2.10.7 (14.07.2022) ## 👀 New: diff --git a/internal/container/config.go b/container/config.go index fb5b028e..fb5b028e 100644 --- a/internal/container/config.go +++ b/container/config.go diff --git a/internal/container/config_test.go b/container/config_test.go index ec07225a..d07a80d4 100644 --- a/internal/container/config_test.go +++ b/container/config_test.go @@ -6,7 +6,7 @@ import ( "github.com/roadrunner-server/config/v2" endure "github.com/roadrunner-server/endure/pkg/container" - "github.com/roadrunner-server/roadrunner/v2/internal/container" + "github.com/roadrunner-server/roadrunner/v2/container" "github.com/stretchr/testify/assert" ) diff --git a/internal/container/container.go b/container/container.go index 610fdbf9..610fdbf9 100644 --- a/internal/container/container.go +++ b/container/container.go diff --git a/internal/container/container_test.go b/container/container_test.go index 210409d4..ed080d38 100644 --- a/internal/container/container_test.go +++ b/container/container_test.go @@ -4,9 +4,8 @@ import ( "testing" "time" - "github.com/roadrunner-server/roadrunner/v2/internal/container" - endure "github.com/roadrunner-server/endure/pkg/container" + "github.com/roadrunner-server/roadrunner/v2/container" "github.com/stretchr/testify/assert" ) diff --git a/internal/container/plugins.go b/container/plugins.go index 3ee8cdc7..3ee8cdc7 100644 --- a/internal/container/plugins.go +++ b/container/plugins.go diff --git a/internal/container/plugins_test.go b/container/plugins_test.go index b857f09a..b857f09a 100644 --- a/internal/container/plugins_test.go +++ b/container/plugins_test.go diff --git a/internal/container/test/endure_ok.yaml b/container/test/endure_ok.yaml index 03db7c23..03db7c23 100644 --- a/internal/container/test/endure_ok.yaml +++ b/container/test/endure_ok.yaml diff --git a/internal/container/test/endure_ok_debug.yaml b/container/test/endure_ok_debug.yaml index 5953c4de..5953c4de 100644 --- a/internal/container/test/endure_ok_debug.yaml +++ b/container/test/endure_ok_debug.yaml diff --git a/internal/container/test/endure_ok_fatal.yaml b/container/test/endure_ok_fatal.yaml index 69e16467..69e16467 100644 --- a/internal/container/test/endure_ok_fatal.yaml +++ b/container/test/endure_ok_fatal.yaml diff --git a/internal/container/test/endure_ok_foobar.yaml b/container/test/endure_ok_foobar.yaml index 90728d2c..90728d2c 100644 --- a/internal/container/test/endure_ok_foobar.yaml +++ b/container/test/endure_ok_foobar.yaml diff --git a/internal/container/test/endure_ok_info.yaml b/container/test/endure_ok_info.yaml index 7ad62861..7ad62861 100644 --- a/internal/container/test/endure_ok_info.yaml +++ b/container/test/endure_ok_info.yaml diff --git a/internal/container/test/endure_ok_panic.yaml b/container/test/endure_ok_panic.yaml index 5ac4dc9e..5ac4dc9e 100644 --- a/internal/container/test/endure_ok_panic.yaml +++ b/container/test/endure_ok_panic.yaml diff --git a/internal/container/test/endure_ok_warn.yaml b/container/test/endure_ok_warn.yaml index 03db7c23..03db7c23 100644 --- a/internal/container/test/endure_ok_warn.yaml +++ b/container/test/endure_ok_warn.yaml diff --git a/internal/container/test/without_endure_ok.yaml b/container/test/without_endure_ok.yaml index e69de29b..e69de29b 100644 --- a/internal/container/test/without_endure_ok.yaml +++ b/container/test/without_endure_ok.yaml @@ -86,7 +86,7 @@ require ( github.com/gobwas/httphead v0.1.0 // indirect github.com/gobwas/pool v0.2.1 // indirect github.com/gobwas/ws v1.1.0 // indirect - github.com/goccy/go-json v0.9.8 // indirect + github.com/goccy/go-json v0.9.10 // indirect github.com/gofiber/fiber/v2 v2.35.0 // indirect github.com/gogo/googleapis v1.4.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect @@ -124,7 +124,7 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_golang v1.12.2 // indirect github.com/prometheus/client_model v0.2.0 // indirect - github.com/prometheus/common v0.36.0 // indirect + github.com/prometheus/common v0.37.0 // indirect github.com/prometheus/procfs v0.7.3 // indirect github.com/rabbitmq/amqp091-go v1.3.4 // indirect github.com/rivo/uniseg v0.2.0 // indirect @@ -132,7 +132,7 @@ require ( github.com/roadrunner-server/tcplisten v1.1.2 // indirect github.com/robfig/cron v1.2.0 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect - github.com/spf13/afero v1.8.2 // indirect + github.com/spf13/afero v1.9.0 // indirect github.com/spf13/cast v1.5.0 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect @@ -148,7 +148,7 @@ require ( github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect github.com/yusufpapurcu/wmi v1.2.2 // indirect - go.buf.build/protocolbuffers/go/roadrunner-server/api v1.2.6 // indirect + go.buf.build/protocolbuffers/go/roadrunner-server/api v1.2.7 // indirect go.etcd.io/bbolt v1.3.6 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.33.0 // indirect go.opentelemetry.io/contrib/propagators/jaeger v1.8.0 // indirect @@ -178,7 +178,7 @@ require ( golang.org/x/text v0.3.7 // indirect golang.org/x/time v0.0.0-20220609170525-579cf78fd858 // indirect golang.org/x/tools v0.1.11 // indirect - google.golang.org/genproto v0.0.0-20220713161829-9c7dac0a6568 // indirect + google.golang.org/genproto v0.0.0-20220714211235-042d03aeabc9 // indirect google.golang.org/grpc v1.48.0 // indirect google.golang.org/protobuf v1.28.0 // indirect gopkg.in/ini.v1 v1.66.6 // indirect @@ -175,8 +175,8 @@ github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og= github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.1.0 h1:7RFti/xnNkMJnrK7D1yQ/iCIB5OrrY/54/H930kIbHA= github.com/gobwas/ws v1.1.0/go.mod h1:nzvNcVha5eUziGrbxFCo6qFIojQHjJV5cLYIbezhfL0= -github.com/goccy/go-json v0.9.8 h1:DxXB6MLd6yyel7CLph8EwNIonUtVZd3Ue5iRcL4DQCE= -github.com/goccy/go-json v0.9.8/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/goccy/go-json v0.9.10 h1:hCeNmprSNLB8B8vQKWl6DpuH0t60oEs+TAk9a7CScKc= +github.com/goccy/go-json v0.9.10/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/gofiber/fiber/v2 v2.35.0 h1:ct+jKw8Qb24WEIZx3VV3zz9VXyBZL7mcEjNaqj3g0h0= github.com/gofiber/fiber/v2 v2.35.0/go.mod h1:tgCr+lierLwLoVHHO/jn3Niannv34WRkQETU8wiL9fQ= github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= @@ -407,8 +407,8 @@ github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.36.0 h1:78hJTing+BLYLjhXE+Z2BubeEymH5Lr0/Mt8FKkxxYo= -github.com/prometheus/common v0.36.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= +github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= +github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= @@ -518,8 +518,8 @@ github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6Mwd github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo= -github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo= +github.com/spf13/afero v1.9.0 h1:sFSLUHgxdnN32Qy38hK3QkYBFXZj9DKjVjCUCtD7juY= +github.com/spf13/afero v1.9.0/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU= @@ -582,8 +582,8 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1 github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= -go.buf.build/protocolbuffers/go/roadrunner-server/api v1.2.6 h1:Phc8G4A+b1ll4enKMweDE87XPdj5+CtTQ1/QKWvoYWA= -go.buf.build/protocolbuffers/go/roadrunner-server/api v1.2.6/go.mod h1:iGiZ72YpQLUTuxA0Ynq5SQ9gcseK0Ny1bbVbA0sHdvU= +go.buf.build/protocolbuffers/go/roadrunner-server/api v1.2.7 h1:DWLaC/bjsfPJSICJjPcB+DFvFoHdLMnNJkyqkRtI4x8= +go.buf.build/protocolbuffers/go/roadrunner-server/api v1.2.7/go.mod h1:iGiZ72YpQLUTuxA0Ynq5SQ9gcseK0Ny1bbVbA0sHdvU= go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= @@ -986,8 +986,8 @@ google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220602131408-e326c6e8e9c8/go.mod h1:yKyY4AMRwFiC8yMMNaMi+RkCnjZJt9LoWuvhXjMs+To= -google.golang.org/genproto v0.0.0-20220713161829-9c7dac0a6568 h1:iKx0VcikTdB4xj9Ho1Opn9AKzWFknYDE7oW/KBWZf9g= -google.golang.org/genproto v0.0.0-20220713161829-9c7dac0a6568/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220714211235-042d03aeabc9 h1:zfXhTgBfGlIh3jMXN06W8qbhFGsh6MJNJiYEuhTddOI= +google.golang.org/genproto v0.0.0-20220714211235-042d03aeabc9/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE= google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= diff --git a/internal/cli/serve/command.go b/internal/cli/serve/command.go index 73b54c3c..eaf6260f 100644 --- a/internal/cli/serve/command.go +++ b/internal/cli/serve/command.go @@ -6,7 +6,7 @@ import ( "os/signal" "syscall" - "github.com/roadrunner-server/roadrunner/v2/internal/container" + "github.com/roadrunner-server/roadrunner/v2/container" "github.com/roadrunner-server/roadrunner/v2/internal/meta" configImpl "github.com/roadrunner-server/config/v2" @@ -50,20 +50,15 @@ func NewCommand(override *[]string, cfgFile *string, silent *bool) *cobra.Comman return errors.E(op, err) } - // register config plugin - if err = endureContainer.Register(cfg); err != nil { + // register plugins + err = endureContainer.RegisterAll(append(container.Plugins(), cfg)...) + if err != nil { return errors.E(op, err) } - // register another container plugins - for i, plugins := 0, container.Plugins(); i < len(plugins); i++ { - if err = endureContainer.Register(plugins[i]); err != nil { - return errors.E(op, err) - } - } - // init container and all services - if err = endureContainer.Init(); err != nil { + err = endureContainer.Init() + if err != nil { return errors.E(op, err) } diff --git a/lib/roadrunner.go b/lib/roadrunner.go new file mode 100644 index 00000000..cbbb7414 --- /dev/null +++ b/lib/roadrunner.go @@ -0,0 +1,111 @@ +package lib + +import ( + "fmt" + "runtime/debug" + + configImpl "github.com/roadrunner-server/config/v2" + endure "github.com/roadrunner-server/endure/pkg/container" + "github.com/roadrunner-server/endure/pkg/fsm" + "github.com/roadrunner-server/roadrunner/v2/container" +) + +const ( + rrPrefix string = "rr" + rrModule string = "github.com/roadrunner-server/roadrunner/v2" +) + +type RR struct { + container *endure.Endure + stop chan struct{} + Version string +} + +// NewRR creates a new RR instance that can then be started or stopped by the caller +func NewRR(cfgFile string, override []string, pluginList []interface{}) (*RR, error) { + // create endure container config + containerCfg, err := container.NewConfig(cfgFile) + if err != nil { + return nil, err + } + + cfg := &configImpl.Plugin{ + Path: cfgFile, + Prefix: rrPrefix, + Timeout: containerCfg.GracePeriod, + Flags: override, + Version: getRRVersion(), + } + + // create endure container + endureContainer, err := container.NewContainer(*containerCfg) + if err != nil { + return nil, err + } + + // register another container plugins + err = endureContainer.RegisterAll(append(pluginList, cfg)...) + if err != nil { + return nil, err + } + + // init container and all services + err = endureContainer.Init() + if err != nil { + return nil, err + } + + return &RR{ + container: endureContainer, + stop: make(chan struct{}, 1), + Version: cfg.Version, + }, nil +} + +// Serve starts RR and starts listening for requests. +// This is a blocking call that will return an error if / when one occurs in a plugin +func (rr *RR) Serve() error { + // start serving the graph + errCh, err := rr.container.Serve() + if err != nil { + return err + } + + select { + case e := <-errCh: + return fmt.Errorf("error: %w\nplugin: %s", e.Error, e.VertexID) + case <-rr.stop: + return rr.container.Stop() + } +} + +func (rr *RR) CurrentState() fsm.State { + return rr.container.CurrentState() +} + +// Stop stops roadrunner +func (rr *RR) Stop() { + rr.stop <- struct{}{} +} + +// DefaultPluginsList returns all the plugins that RR can run with and are included by default +func DefaultPluginsList() []interface{} { + return container.Plugins() +} + +// Tries to find the version info for a given module's path +// empty string if not found +func getRRVersion() string { + bi, ok := debug.ReadBuildInfo() + if !ok { + return "" + } + + for i := 0; i < len(bi.Deps); i++ { + if bi.Deps[i].Path == rrModule { + return bi.Deps[i].Version + } + } + + return "" +} diff --git a/lib/roadrunner_test.go b/lib/roadrunner_test.go new file mode 100644 index 00000000..9406b7bf --- /dev/null +++ b/lib/roadrunner_test.go @@ -0,0 +1,83 @@ +package lib_test + +import ( + "os" + "testing" + "time" + + "github.com/roadrunner-server/endure/pkg/fsm" + "github.com/roadrunner-server/informer/v2" + "github.com/roadrunner-server/resetter/v2" + "github.com/roadrunner-server/roadrunner/v2/lib" + "github.com/stretchr/testify/assert" +) + +func TestNewFailsOnMissingConfig(t *testing.T) { + _, err := lib.NewRR("config/file/does/not/exist/.rr.yaml", []string{}, lib.DefaultPluginsList()) + assert.NotNil(t, err) +} + +const testConfig = ` +server: + command: "php src/index.php" + relay: "pipes" + +endure: + grace_period: 1s +` + +func makeConfig(t *testing.T, configYaml string) string { + cfgFile := os.TempDir() + "/.rr.yaml" + err := os.WriteFile(cfgFile, []byte(configYaml), 0600) + assert.Nil(t, err) + + return cfgFile +} + +func TestNewWithConfig(t *testing.T) { + cfgFile := makeConfig(t, testConfig) + rr, err := lib.NewRR(cfgFile, []string{}, lib.DefaultPluginsList()) + assert.Nil(t, err) + + assert.Equal(t, "2", string(rr.Version[0])) + assert.Equal(t, fsm.Initialized, rr.CurrentState()) + + t.Cleanup(func() { + _ = os.Remove(cfgFile) + }) +} + +func TestServeStop(t *testing.T) { + cfgFile := makeConfig(t, testConfig) + plugins := []interface{}{ + &informer.Plugin{}, + &resetter.Plugin{}, + } + rr, err := lib.NewRR(cfgFile, []string{}, plugins) + assert.Nil(t, err) + + errchan := make(chan error, 1) + stopchan := make(chan struct{}, 1) + + go func() { + errchan <- rr.Serve() + stopchan <- struct{}{} + }() + + assert.Equal(t, rr.CurrentState(), fsm.Initialized) + + for rr.CurrentState() != fsm.Started { + time.Sleep(20 * time.Millisecond) + } + + rr.Stop() + time.Sleep(time.Second * 2) + + assert.Equal(t, fsm.Stopped, rr.CurrentState()) + assert.Equal(t, struct{}{}, <-stopchan) + assert.Nil(t, <-errchan) + + t.Cleanup(func() { + _ = os.Remove(cfgFile) + }) +} |