113 lines
2.7 KiB
Go
113 lines
2.7 KiB
Go
package testenv
|
|
|
|
import (
|
|
"net"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/gomodule/redigo/redis"
|
|
"github.com/mna/redisc"
|
|
"github.com/mna/redisc/redistest"
|
|
"github.com/stretchr/testify/require"
|
|
"src.dualinventive.com/go/websocketserver/internal/mtiwss"
|
|
mtiep "src.dualinventive.com/go/websocketserver/internal/mtiwss/testutil"
|
|
wsclnt "src.dualinventive.com/go/websocketserver/internal/wsconn/testutil"
|
|
"src.dualinventive.com/go/websocketserver/internal/wss"
|
|
)
|
|
|
|
// TestEnv holds a redis cluster, redis client, websocket client and an MTI WSS HTTP server
|
|
type TestEnv struct {
|
|
wsclnt *wsclnt.Client
|
|
mti *mtiep.Server
|
|
srv *wss.Server
|
|
rc *redisc.Cluster
|
|
rcClose func()
|
|
}
|
|
|
|
// MtiWss returns the instance to the MTI WSS HTTP endpoint test server
|
|
func (t *TestEnv) MtiWss() *mtiep.Server {
|
|
return t.mti
|
|
}
|
|
|
|
// Ws returns the instance to the Websocket client
|
|
func (t *TestEnv) Ws() *wsclnt.Client {
|
|
return t.wsclnt
|
|
}
|
|
|
|
// RedisDo executes a redis command on the cluster
|
|
func (t *TestEnv) RedisDo(cmd string, args ...interface{}) (interface{}, error) {
|
|
conn := t.rc.Get()
|
|
c, err := redisc.RetryConn(conn, 3, 10*time.Second)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer c.Close()
|
|
return c.Do(cmd, args...)
|
|
}
|
|
|
|
// New create a new testing environment with a Redis cluster, redis client and a MTI WSS HTTP endpoint
|
|
func New(t *testing.T) *TestEnv {
|
|
addr := getFreeAddr(t)
|
|
|
|
tenv := &TestEnv{}
|
|
// Setup, spawn MTI Wss stub endpoint and redis server
|
|
mti := mtiep.New(mtiwss.Endpoint)
|
|
|
|
// Start redis cluster
|
|
clusterClose, clusterPorts := redistest.StartCluster(t, nil)
|
|
|
|
// Create new websocket server
|
|
srv, err := wss.NewServer([]string{":" + clusterPorts[0]}, addr, mti.URL())
|
|
require.Nil(t, err)
|
|
require.NotNil(t, srv)
|
|
|
|
// Start the wss server in the background
|
|
go srv.ListenAndServe()
|
|
|
|
// Create redis cluster client
|
|
rc := redisc.Cluster{
|
|
StartupNodes: []string{":" + clusterPorts[0]},
|
|
DialOptions: []redis.DialOption{redis.DialConnectTimeout(10 * time.Second)},
|
|
}
|
|
require.Nil(t, rc.Refresh())
|
|
|
|
// Create websocket client
|
|
clnt, err := wsclnt.NewClient("ws://" + addr)
|
|
require.Nil(t, err)
|
|
|
|
// Attach to TestEnv context
|
|
tenv.mti = mti
|
|
tenv.rcClose = clusterClose
|
|
tenv.srv = srv
|
|
tenv.rc = &rc
|
|
tenv.wsclnt = clnt
|
|
|
|
return tenv
|
|
}
|
|
|
|
// Close closes all the connections and waits fo stopping the servers
|
|
func (t *TestEnv) Close() error {
|
|
err := t.rc.Close()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = t.srv.Close()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = t.mti.Close()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
t.rcClose()
|
|
return nil
|
|
}
|
|
|
|
// getFreeAddr gets a free TCP port from the kernel
|
|
func getFreeAddr(t *testing.T) string {
|
|
l, err := net.Listen("tcp", "127.0.0.1:0")
|
|
require.NoError(t, err, "listen on port 0")
|
|
defer l.Close()
|
|
return l.Addr().String()
|
|
}
|