mirror of https://github.com/0xERR0R/blocky.git
fix: return error code on server starup failure (#1165)
This commit is contained in:
parent
e63ad3880c
commit
65ff6847ad
|
@ -19,6 +19,7 @@ import (
|
|||
var (
|
||||
done = make(chan bool, 1)
|
||||
isConfigMandatory = true
|
||||
signals = make(chan os.Signal, 1)
|
||||
)
|
||||
|
||||
func newServeCommand() *cobra.Command {
|
||||
|
@ -40,8 +41,6 @@ func startServer(_ *cobra.Command, _ []string) error {
|
|||
|
||||
log.ConfigureLogger(&cfg.Log)
|
||||
|
||||
signals := make(chan os.Signal, 1)
|
||||
|
||||
signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM)
|
||||
|
||||
srv, err := server.NewServer(cfg)
|
||||
|
@ -54,6 +53,8 @@ func startServer(_ *cobra.Command, _ []string) error {
|
|||
|
||||
srv.Start(errChan)
|
||||
|
||||
var terminationErr error
|
||||
|
||||
go func() {
|
||||
select {
|
||||
case <-signals:
|
||||
|
@ -63,6 +64,7 @@ func startServer(_ *cobra.Command, _ []string) error {
|
|||
|
||||
case err := <-errChan:
|
||||
log.Log().Error("server start failed: ", err)
|
||||
terminationErr = err
|
||||
done <- true
|
||||
}
|
||||
}()
|
||||
|
@ -70,7 +72,7 @@ func startServer(_ *cobra.Command, _ []string) error {
|
|||
evt.Bus().Publish(evt.ApplicationStarted, util.Version, util.BuildTime)
|
||||
<-done
|
||||
|
||||
return nil
|
||||
return terminationErr
|
||||
}
|
||||
|
||||
func printBanner() {
|
||||
|
|
|
@ -1,39 +1,121 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"github.com/0xERR0R/blocky/config"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/0xERR0R/blocky/helpertest"
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("Serve command", func() {
|
||||
When("Serve command is called", func() {
|
||||
It("should start DNS server", func() {
|
||||
config.GetConfig().BootstrapDNS = []config.BootstrappedUpstreamConfig{
|
||||
{
|
||||
Upstream: config.Upstream{
|
||||
Net: config.NetProtocolTcpTls,
|
||||
Host: "1.1.1.1",
|
||||
Port: 53,
|
||||
},
|
||||
},
|
||||
}
|
||||
var tmpDir *helpertest.TmpFolder
|
||||
BeforeEach(func() {
|
||||
tmpDir = helpertest.NewTmpFolder("config")
|
||||
Expect(tmpDir.Error).Should(Succeed())
|
||||
DeferCleanup(tmpDir.Clean)
|
||||
configPath = defaultConfigPath
|
||||
})
|
||||
|
||||
isConfigMandatory = false
|
||||
When("Serve command is called with valid config", func() {
|
||||
It("should start without error and terminate with signal", func() {
|
||||
By("initialize config", func() {
|
||||
cfgFile := tmpDir.CreateStringFile("config.yaml",
|
||||
"upstreams:",
|
||||
" groups:",
|
||||
" default:",
|
||||
" - 1.1.1.1",
|
||||
"ports:",
|
||||
" dns: 55555")
|
||||
Expect(cfgFile.Error).Should(Succeed())
|
||||
os.Setenv(configFileEnvVar, cfgFile.Path)
|
||||
DeferCleanup(func() { os.Unsetenv(configFileEnvVar) })
|
||||
initConfig()
|
||||
})
|
||||
|
||||
grClosure := make(chan interface{})
|
||||
errChan := make(chan error)
|
||||
By("start server", func() {
|
||||
go func() {
|
||||
// it is a blocking function, call async
|
||||
errChan <- startServer(newServeCommand(), []string{})
|
||||
}()
|
||||
})
|
||||
|
||||
go func() {
|
||||
defer GinkgoRecover()
|
||||
By("check DNS port is open", func() {
|
||||
Eventually(func(g Gomega) {
|
||||
conn, err := net.DialTimeout("tcp", "127.0.0.1:55555", 200*time.Millisecond)
|
||||
g.Expect(err).Should(Succeed())
|
||||
defer conn.Close()
|
||||
}).Should(Succeed())
|
||||
})
|
||||
|
||||
err := startServer(newServeCommand(), []string{})
|
||||
Expect(err).Should(HaveOccurred())
|
||||
By("terminate with signal", func() {
|
||||
signals <- syscall.SIGINT
|
||||
|
||||
close(grClosure)
|
||||
}()
|
||||
// no errors
|
||||
Eventually(errChan).Should(Receive(BeNil()))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Eventually(grClosure).Should(BeClosed())
|
||||
When("Serve command is called with valid config", func() {
|
||||
It("should fail if server start fails", func() {
|
||||
By("start http server on port 5555", func() {
|
||||
go func() {
|
||||
Expect(http.ListenAndServe(":55555", nil)).Should(Succeed())
|
||||
}()
|
||||
})
|
||||
By("initialize config with blocked port 55555", func() {
|
||||
cfgFile := tmpDir.CreateStringFile("config.yaml",
|
||||
"upstreams:",
|
||||
" groups:",
|
||||
" default:",
|
||||
" - 1.1.1.1",
|
||||
"ports:",
|
||||
" dns: 55555")
|
||||
Expect(cfgFile.Error).Should(Succeed())
|
||||
os.Setenv(configFileEnvVar, cfgFile.Path)
|
||||
DeferCleanup(func() { os.Unsetenv(configFileEnvVar) })
|
||||
initConfig()
|
||||
})
|
||||
|
||||
errChan := make(chan error)
|
||||
By("start server", func() {
|
||||
go func() {
|
||||
// it is a blocking function, call async
|
||||
errChan <- startServer(newServeCommand(), []string{})
|
||||
}()
|
||||
})
|
||||
|
||||
By("terminate with signal", func() {
|
||||
var startError error
|
||||
Eventually(errChan).Should(Receive(&startError))
|
||||
Expect(startError).ShouldNot(BeNil())
|
||||
Expect(startError.Error()).Should(ContainSubstring("address already in use"))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
When("Serve command is called without config", func() {
|
||||
It("should fail to start and report error", func() {
|
||||
errChan := make(chan error)
|
||||
By("start server", func() {
|
||||
go func() {
|
||||
// it is a blocking function, call async
|
||||
errChan <- startServer(newServeCommand(), []string{})
|
||||
}()
|
||||
})
|
||||
|
||||
By("server should terminate with error", func() {
|
||||
var startError error
|
||||
Eventually(errChan).Should(Receive(&startError))
|
||||
Expect(startError).ShouldNot(BeNil())
|
||||
Expect(startError.Error()).Should(ContainSubstring("unable to load configuration"))
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -24,6 +24,33 @@ var _ = Describe("Basic functional tests", func() {
|
|||
Expect(err).Should(Succeed())
|
||||
DeferCleanup(moka.Terminate)
|
||||
})
|
||||
When("wrong port configuration is provided", func() {
|
||||
BeforeEach(func() {
|
||||
blocky, err = createBlockyContainer(tmpDir,
|
||||
"upstreams:",
|
||||
" groups:",
|
||||
" default:",
|
||||
" - moka1",
|
||||
"ports:",
|
||||
" http: 4000",
|
||||
" dns: 4000",
|
||||
)
|
||||
Expect(err).Should(HaveOccurred())
|
||||
|
||||
// check container exit status
|
||||
state, err := blocky.State(context.Background())
|
||||
Expect(err).Should(Succeed())
|
||||
Expect(state.ExitCode).Should(Equal(1))
|
||||
|
||||
DeferCleanup(blocky.Terminate)
|
||||
})
|
||||
It("should fail to start", func() {
|
||||
Eventually(blocky.IsRunning, "5s", "2ms").Should(BeFalse())
|
||||
|
||||
Expect(getContainerLogs(blocky)).
|
||||
Should(ContainElement(ContainSubstring("address already in use")))
|
||||
})
|
||||
})
|
||||
When("Minimal configuration is provided", func() {
|
||||
BeforeEach(func() {
|
||||
blocky, err = createBlockyContainer(tmpDir,
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package e2e
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
. "github.com/0xERR0R/blocky/helpertest"
|
||||
"github.com/0xERR0R/blocky/util"
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
|
@ -77,6 +79,12 @@ var _ = Describe("External lists and query blocking", func() {
|
|||
)
|
||||
|
||||
Expect(err).Should(HaveOccurred())
|
||||
|
||||
// check container exit status
|
||||
state, err := blocky.State(context.Background())
|
||||
Expect(err).Should(Succeed())
|
||||
Expect(state.ExitCode).Should(Equal(1))
|
||||
|
||||
DeferCleanup(blocky.Terminate)
|
||||
})
|
||||
|
||||
|
|
Loading…
Reference in New Issue