diff --git a/config/server.go b/config/server.go index b580fce5..089ced10 100644 --- a/config/server.go +++ b/config/server.go @@ -37,6 +37,8 @@ type Server struct { // // example: https://github.com/iris-contrib/examples/tree/master/multiserver_listening2 RedirectTo string + // Virtual If this server is not really listens to a real host, it mostly used in order to achieve testing without system modifications + Virtual bool } // DefaultServer returns the default configs for the server diff --git a/http.go b/http.go index 6d72aaa5..c3ff9e57 100644 --- a/http.go +++ b/http.go @@ -431,10 +431,15 @@ func (s *Server) Open() error { } } + if s.Config.Virtual { + return nil + } + if s.Config.Mode > 0 { return s.listenUNIX() } return s.listen() + } // Close terminates the server diff --git a/initiatory.go b/initiatory.go index ec3f3186..2c6fa358 100644 --- a/initiatory.go +++ b/initiatory.go @@ -179,6 +179,7 @@ func (s *Framework) openServer() (err error) { // set the server's handler now, in order to give the chance to the plugins to add their own middlewares and routes to this station s.HTTPServer.SetHandler(s.mux) if err = s.HTTPServer.Open(); err == nil { + // print the banner if !s.Config.DisableBanner { s.Logger.PrintBanner(banner, @@ -186,10 +187,16 @@ func (s *Framework) openServer() (err error) { s.HTTPServer.Host())) } s.Plugins.DoPostListen(s) - s.Available <- true - ch := make(chan os.Signal) - <-ch - s.Close() + go func() { + s.Available <- true + }() + + if !s.Config.Server.Virtual { + ch := make(chan os.Signal) + <-ch + s.Close() + } + } return } @@ -201,25 +208,6 @@ func (s *Framework) closeServer() error { return s.HTTPServer.Close() } -// justServe initializes the whole framework but server doesn't listens to a specific net.Listener -func (s *Framework) justServe(optionalAddr ...string) *Server { - s.HTTPServer.Config = &s.Config.Server - - if len(optionalAddr) > 0 { - s.HTTPServer.Config.ListeningAddr = optionalAddr[0] - } - - s.initialize() - s.Plugins.DoPreListen(s) - s.HTTPServer.SetHandler(s.mux) - s.Plugins.DoPostListen(s) - go func() { - s.Available <- true - }() - - return s.HTTPServer -} - // tester returns the test framework func (s *Framework) tester(t *testing.T) *httpexpect.Expect { if s.testFramework == nil { diff --git a/iris.go b/iris.go index fc1352e2..f4d783c1 100644 --- a/iris.go +++ b/iris.go @@ -94,6 +94,7 @@ type ( ListenUNIX(string, os.FileMode) SecondaryListen(config.Server) *Server NoListen(...string) *Server + ListenVirtual(cfg ...config.Server) *Server Close() // global middleware prepending, registers to all subdomains, to all parties, you can call it at the last also MustUse(...Handler) @@ -328,9 +329,11 @@ func (s *Framework) SecondaryListen(cfg config.Server) *Server { go func() { // goroutine in order to not block any runtime post listeners srv.Handler = s.HTTPServer.Handler if err := srv.Open(); err == nil { - ch := make(chan os.Signal) - <-ch - srv.Close() + if !cfg.Virtual { + ch := make(chan os.Signal) + <-ch + srv.Close() + } } }() })) @@ -346,7 +349,31 @@ func NoListen(optionalAddr ...string) *Server { // NoListen is useful only when you want to test Iris, it doesn't starts the server but it configures and returns it // initializes the whole framework but server doesn't listens to a specific net.Listener func (s *Framework) NoListen(optionalAddr ...string) *Server { - return s.justServe(optionalAddr...) + if len(optionalAddr) > 0 { + s.Config.Server.ListeningAddr = optionalAddr[0] + } + return s.ListenVirtual() +} + +// ListenVirtual is useful only when you want to test Iris, it doesn't starts the server but it configures and returns it +// initializes the whole framework but server doesn't listens to a specific net.Listener +// same as NoListen +func ListenVirtual(cfg ...config.Server) *Server { + return Default.ListenVirtual(cfg...) +} + +// ListenVirtual is useful only when you want to test Iris, it doesn't starts the server but it configures and returns it +// initializes the whole framework but server doesn't listens to a specific net.Listener +// same as NoListen +func (s *Framework) ListenVirtual(cfg ...config.Server) *Server { + if len(cfg) > 0 { + s.Config.Server = cfg[0] + } + s.Config.DisableBanner = true + s.Config.Server.Virtual = true + + s.Must(s.openServer()) + return s.HTTPServer } // CloseWithErr terminates the server and returns an error if any @@ -609,7 +636,7 @@ func (s *Framework) TemplateString(templateFile string, pageContext interface{}, func NewTester(api *Framework, t *testing.T) *httpexpect.Expect { api.Config.DisableBanner = true if !api.HTTPServer.IsListening() { // maybe the user called this after .Listen/ListenTLS/ListenUNIX, the tester can be used as standalone (with no running iris instance) or inside a running instance/app - api.NoListen() + api.ListenVirtual() if ok := <-api.Available; !ok { t.Fatal("Unexpected error: server cannot start, please report this as bug!!") } diff --git a/server_test.go b/server_test.go index 15720145..e4276769 100644 --- a/server_test.go +++ b/server_test.go @@ -15,6 +15,7 @@ Linux: */ import ( + "io/ioutil" "net/http" "os" "testing" @@ -22,6 +23,7 @@ import ( "github.com/gavv/httpexpect" "github.com/kataras/iris/config" + "github.com/kataras/iris/utils" ) const ( @@ -84,12 +86,13 @@ func TestMultiRunningServers(t *testing.T) { host := "mydomain.com:443" // you have to add it to your hosts file( for windows, as 127.0.0.1 mydomain.com) // create the key and cert files on the fly, and delete them when this test finished - certFile, ferr := os.Create(testCertFilename) + certFile, ferr := ioutil.TempFile(utils.AssetsDirectory, "_iris") + if ferr != nil { t.Fatal(ferr.Error()) } - keyFile, ferr := os.Create(testKeyFilename) + keyFile, ferr := ioutil.TempFile(utils.AssetsDirectory, "_iris") if ferr != nil { t.Fatal(ferr.Error()) } @@ -100,11 +103,11 @@ func TestMultiRunningServers(t *testing.T) { defer func() { certFile.Close() time.Sleep(350 * time.Millisecond) - os.Remove(testCertFilename) + os.Remove(certFile.Name()) keyFile.Close() time.Sleep(350 * time.Millisecond) - os.Remove(testKeyFilename) + os.Remove(keyFile.Name()) }() initDefault() @@ -114,14 +117,9 @@ func TestMultiRunningServers(t *testing.T) { ctx.Write("Hello from %s", ctx.HostString()) }) - secondary := SecondaryListen(config.Server{ListeningAddr: ":80", RedirectTo: "https://" + host}) // start one secondary server + secondary := SecondaryListen(config.Server{ListeningAddr: ":80", RedirectTo: "https://" + host, Virtual: true}) // start one secondary server // start the main server - go func() { - err := ListenTLSWithErr(host, testCertFilename, testKeyFilename) - if err != nil { - t.Fatalf("Error on server_test ListenTLSWithErr: %s", err.Error()) - } - }() + go ListenVirtual(config.Server{ListeningAddr: host, CertFile: certFile.Name(), KeyFile: keyFile.Name()}) defer func() { go secondary.Close()