Test cases often run HTTP server without specifying a port number, in order for the server to listen on any available port. Afterwards, the test case author peeks into the listener structure to find out the actual port number, using code similar to:
echoSrv.Listener.(*net.TCPListener).Addr().(*net.TCPAddr).Port
However, the method will not work with echo because the listener is a private extension of TCPListener, therefore it is impossible to find out actual port number being listened on. Consequently, it becomes difficult to run parallel tests against an echo HTTP server.
Therefore, please consider exporting the private TCPListener extension, or make a function dedicated to finding out the listener's port number.
master at https://github.com/labstack/echo/commit/e9f67801e3e2ab81e5ff5540395301255ef5532c
@alexaandru do you want to have a look at it?
@HouzuoGuo @vishr Not sure I understand what the problem is. Especially the "run HTTP server without specifying a port number in order to listen on any" part - could you please provide an example of such a test?
As far as I see, you cannot even run echo without a port https://github.com/labstack/echo/blob/master/echo.go#L590 in the 1st place and if you run net/http.Server without an address (with an empty one) it defaults to port 80 (http) NOT to "all available ports": https://golang.org/pkg/net/http/#Server
I really should have said "specify port number 0" instead of not specifying a port number.
Here is an example of starting an HTTP server on the next available port, and then inspects the listener to find out actual port number:
I also should've been more clear about the example I asked for @HouzuoGuo :) - could you please provide an example of a test case where you need to find out this port dynamically? Just trying to understand what is it that you're trying to test that you cannot simply run echo with a known port and instead need to dynamically allocate it and then dynamically find it. Being testing, I'd imagine you'd have more control over the settings/context and be able to control it, no?
Oh, it's just a habit of making less assumption about the host system in regards to which ports might be free during test run, and when two or more echo servers need to be tested from independent packages, using randomly assigned port number saves the hassle of tracking which package uses which port.
Thank you @HouzuoGuo that makes sense now, I can see how this can be useful. I will look into this. Cheers!
@HouzuoGuo Sorry, I'm still not able to replicate the issue you're facing:
Given:
package main
import (
"fmt"
"net"
"time"
"github.com/labstack/echo"
)
func main() {
e := echo.New()
go e.Start(":0")
time.Sleep(1 * time.Second)
fmt.Println("Port is:", e.Listener.Addr().(*net.TCPAddr).Port)
}
I get:
$ go run x.go
____ __
/ __/___/ / ___
/ _// __/ _ \/ _ \
/___/\__/_//_/\___/ v3.2.6
High performance, minimalist Go web framework
https://echo.labstack.com
____________________________________O/_______
O\
⇨ http server started on [::]:41687
Port is: 41687
Seems to work as expected, no?
Thanks very much Alexandru, you're absolutely right. I should not have used type casting on the listener itself.
You're most welcome @HouzuoGuo :) Cheers!
Most helpful comment
@HouzuoGuo Sorry, I'm still not able to replicate the issue you're facing:
Given:
I get:
Seems to work as expected, no?