Add virtual listen same as NoListen- some changes in order the server_test no need any system modification

This commit is contained in:
Makis Maropoulos 2016-07-05 14:29:32 +02:00
parent 93dc7c7e48
commit afa5b57dc7
5 changed files with 59 additions and 39 deletions

View File

@ -37,6 +37,8 @@ type Server struct {
// //
// example: https://github.com/iris-contrib/examples/tree/master/multiserver_listening2 // example: https://github.com/iris-contrib/examples/tree/master/multiserver_listening2
RedirectTo string 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 // DefaultServer returns the default configs for the server

View File

@ -431,10 +431,15 @@ func (s *Server) Open() error {
} }
} }
if s.Config.Virtual {
return nil
}
if s.Config.Mode > 0 { if s.Config.Mode > 0 {
return s.listenUNIX() return s.listenUNIX()
} }
return s.listen() return s.listen()
} }
// Close terminates the server // Close terminates the server

View File

@ -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 // 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) s.HTTPServer.SetHandler(s.mux)
if err = s.HTTPServer.Open(); err == nil { if err = s.HTTPServer.Open(); err == nil {
// print the banner // print the banner
if !s.Config.DisableBanner { if !s.Config.DisableBanner {
s.Logger.PrintBanner(banner, s.Logger.PrintBanner(banner,
@ -186,10 +187,16 @@ func (s *Framework) openServer() (err error) {
s.HTTPServer.Host())) s.HTTPServer.Host()))
} }
s.Plugins.DoPostListen(s) s.Plugins.DoPostListen(s)
s.Available <- true go func() {
ch := make(chan os.Signal) s.Available <- true
<-ch }()
s.Close()
if !s.Config.Server.Virtual {
ch := make(chan os.Signal)
<-ch
s.Close()
}
} }
return return
} }
@ -201,25 +208,6 @@ func (s *Framework) closeServer() error {
return s.HTTPServer.Close() 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 // tester returns the test framework
func (s *Framework) tester(t *testing.T) *httpexpect.Expect { func (s *Framework) tester(t *testing.T) *httpexpect.Expect {
if s.testFramework == nil { if s.testFramework == nil {

37
iris.go
View File

@ -94,6 +94,7 @@ type (
ListenUNIX(string, os.FileMode) ListenUNIX(string, os.FileMode)
SecondaryListen(config.Server) *Server SecondaryListen(config.Server) *Server
NoListen(...string) *Server NoListen(...string) *Server
ListenVirtual(cfg ...config.Server) *Server
Close() Close()
// global middleware prepending, registers to all subdomains, to all parties, you can call it at the last also // global middleware prepending, registers to all subdomains, to all parties, you can call it at the last also
MustUse(...Handler) 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 go func() { // goroutine in order to not block any runtime post listeners
srv.Handler = s.HTTPServer.Handler srv.Handler = s.HTTPServer.Handler
if err := srv.Open(); err == nil { if err := srv.Open(); err == nil {
ch := make(chan os.Signal) if !cfg.Virtual {
<-ch ch := make(chan os.Signal)
srv.Close() <-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 // 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 // initializes the whole framework but server doesn't listens to a specific net.Listener
func (s *Framework) NoListen(optionalAddr ...string) *Server { 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 // 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 { func NewTester(api *Framework, t *testing.T) *httpexpect.Expect {
api.Config.DisableBanner = true 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 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 { if ok := <-api.Available; !ok {
t.Fatal("Unexpected error: server cannot start, please report this as bug!!") t.Fatal("Unexpected error: server cannot start, please report this as bug!!")
} }

View File

@ -15,6 +15,7 @@ Linux:
*/ */
import ( import (
"io/ioutil"
"net/http" "net/http"
"os" "os"
"testing" "testing"
@ -22,6 +23,7 @@ import (
"github.com/gavv/httpexpect" "github.com/gavv/httpexpect"
"github.com/kataras/iris/config" "github.com/kataras/iris/config"
"github.com/kataras/iris/utils"
) )
const ( 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) 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 // 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 { if ferr != nil {
t.Fatal(ferr.Error()) t.Fatal(ferr.Error())
} }
keyFile, ferr := os.Create(testKeyFilename) keyFile, ferr := ioutil.TempFile(utils.AssetsDirectory, "_iris")
if ferr != nil { if ferr != nil {
t.Fatal(ferr.Error()) t.Fatal(ferr.Error())
} }
@ -100,11 +103,11 @@ func TestMultiRunningServers(t *testing.T) {
defer func() { defer func() {
certFile.Close() certFile.Close()
time.Sleep(350 * time.Millisecond) time.Sleep(350 * time.Millisecond)
os.Remove(testCertFilename) os.Remove(certFile.Name())
keyFile.Close() keyFile.Close()
time.Sleep(350 * time.Millisecond) time.Sleep(350 * time.Millisecond)
os.Remove(testKeyFilename) os.Remove(keyFile.Name())
}() }()
initDefault() initDefault()
@ -114,14 +117,9 @@ func TestMultiRunningServers(t *testing.T) {
ctx.Write("Hello from %s", ctx.HostString()) 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 // start the main server
go func() { go ListenVirtual(config.Server{ListeningAddr: host, CertFile: certFile.Name(), KeyFile: keyFile.Name()})
err := ListenTLSWithErr(host, testCertFilename, testKeyFilename)
if err != nil {
t.Fatalf("Error on server_test ListenTLSWithErr: %s", err.Error())
}
}()
defer func() { defer func() {
go secondary.Close() go secondary.Close()