2015-10-25 20:17:17 -07:00
|
|
|
package server
|
2015-10-26 10:06:45 -07:00
|
|
|
|
2015-10-25 20:17:17 -07:00
|
|
|
import (
|
2015-10-26 11:22:06 -07:00
|
|
|
"encoding/json"
|
2015-10-26 10:06:45 -07:00
|
|
|
"fmt"
|
|
|
|
"github.com/satori/go.uuid"
|
|
|
|
"golang.org/x/net/websocket"
|
|
|
|
"io/ioutil"
|
2015-10-25 20:17:17 -07:00
|
|
|
"net/http"
|
2015-10-26 10:06:45 -07:00
|
|
|
"net/http/httptest"
|
2015-10-26 11:22:06 -07:00
|
|
|
"net/url"
|
2015-10-26 10:06:45 -07:00
|
|
|
"os"
|
2015-10-25 20:17:17 -07:00
|
|
|
"sync"
|
|
|
|
"syscall"
|
2015-10-26 10:06:45 -07:00
|
|
|
"testing"
|
2015-10-25 20:17:17 -07:00
|
|
|
)
|
|
|
|
|
2015-10-26 11:22:06 -07:00
|
|
|
func TCountOpenFDs() uint64 {
|
2015-10-25 20:17:17 -07:00
|
|
|
ary, _ := ioutil.ReadDir(fmt.Sprintf("/proc/%d/fd", os.Getpid()))
|
|
|
|
return uint64(len(ary))
|
|
|
|
}
|
|
|
|
|
2015-10-26 11:22:06 -07:00
|
|
|
const IgnoreReceivedArguments = 1+2i
|
|
|
|
func TReceiveExpectedMessage(tb testing.TB, conn *websocket.Conn, messageId int, command Command, arguments interface{}) (ClientMessage, bool) {
|
|
|
|
var msg ClientMessage
|
|
|
|
var fail bool
|
|
|
|
err := FFZCodec.Receive(conn, &msg)
|
|
|
|
if err != nil {
|
|
|
|
tb.Error(err)
|
|
|
|
return msg, false
|
|
|
|
}
|
|
|
|
if msg.MessageID != messageId {
|
|
|
|
tb.Error("Message ID was wrong. Expected", messageId, ", got", msg.MessageID, ":", msg)
|
|
|
|
fail = true
|
|
|
|
}
|
|
|
|
if msg.Command != command {
|
|
|
|
tb.Error("Command was wrong. Expected", command, ", got", msg.Command, ":", msg)
|
|
|
|
fail = true
|
|
|
|
}
|
|
|
|
if arguments != IgnoreReceivedArguments {
|
|
|
|
if msg.Arguments != arguments {
|
|
|
|
tb.Error("Arguments are wrong. Expected", arguments, ", got", msg.Arguments, ":", msg)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return msg, !fail
|
|
|
|
}
|
|
|
|
|
|
|
|
func TSendMessage(tb testing.TB, conn *websocket.Conn, messageId int, command Command, arguments interface{}) bool {
|
|
|
|
err := FFZCodec.Send(conn, ClientMessage{MessageID: messageId, Command: command, Arguments: arguments})
|
|
|
|
if err != nil {
|
|
|
|
tb.Error(err)
|
|
|
|
}
|
|
|
|
return err == nil
|
|
|
|
}
|
|
|
|
|
2015-10-26 11:25:17 -07:00
|
|
|
type TURLs struct {
|
|
|
|
Websocket string
|
|
|
|
Origin string
|
|
|
|
PubMsg string
|
|
|
|
}
|
|
|
|
|
2015-10-26 11:56:03 -07:00
|
|
|
func TGetUrls(testserver *httptest.Server) TURLs {
|
2015-10-26 11:25:17 -07:00
|
|
|
addr := testserver.Listener.Addr().String()
|
|
|
|
return TURLs{
|
|
|
|
Websocket: fmt.Sprintf("ws://%s/", addr),
|
2015-10-26 11:56:03 -07:00
|
|
|
Origin: fmt.Sprintf("http://%s", addr),
|
|
|
|
PubMsg: fmt.Sprintf("http://%s/pub_msg", addr),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const TNaclKeysLocation = "/tmp/test_naclkeys.json"
|
|
|
|
|
|
|
|
func TSetup(testserver **httptest.Server, urls *TURLs) {
|
|
|
|
if backendSharedKey[0] == 0 {
|
|
|
|
GenerateKeys(TNaclKeysLocation, "2", "+ZMqOmxhaVrCV5c0OMZ09QoSGcJHuqQtJrwzRD+JOjE=")
|
|
|
|
}
|
|
|
|
DumpCache()
|
|
|
|
|
|
|
|
if testserver != nil {
|
|
|
|
conf := &Config{
|
|
|
|
UseSSL: false,
|
|
|
|
NaclKeysFile: TNaclKeysLocation,
|
|
|
|
SocketOrigin: "localhost:2002",
|
|
|
|
}
|
|
|
|
serveMux := http.NewServeMux()
|
|
|
|
SetupServerAndHandle(conf, nil, serveMux)
|
|
|
|
|
|
|
|
tserv := httptest.NewUnstartedServer(serveMux)
|
|
|
|
*testserver = tserv
|
|
|
|
tserv.Start()
|
|
|
|
if urls != nil {
|
|
|
|
*urls = TGetUrls(tserv)
|
|
|
|
}
|
2015-10-26 11:25:17 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-26 11:22:06 -07:00
|
|
|
func TestSubscriptionAndPublish(t *testing.T) {
|
|
|
|
var doneWg sync.WaitGroup
|
|
|
|
var readyWg sync.WaitGroup
|
|
|
|
|
2015-10-26 12:13:28 -07:00
|
|
|
const TestChannelName = "room.testchannel"
|
2015-10-26 11:22:06 -07:00
|
|
|
const TestCommand = "testdata"
|
|
|
|
const TestData = "123456789"
|
|
|
|
|
2015-10-26 11:56:03 -07:00
|
|
|
var server *httptest.Server
|
|
|
|
var urls TURLs
|
|
|
|
TSetup(&server, &urls)
|
|
|
|
defer unsubscribeAllClients()
|
2015-10-26 11:22:06 -07:00
|
|
|
|
2015-10-26 11:25:17 -07:00
|
|
|
conn, err := websocket.Dial(urls.Websocket, "", urls.Origin)
|
2015-10-26 11:22:06 -07:00
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
doneWg.Add(1)
|
|
|
|
readyWg.Add(1)
|
|
|
|
|
|
|
|
go func(conn *websocket.Conn) {
|
|
|
|
TSendMessage(t, conn, 1, HelloCommand, []interface{}{"ffz_0.0-test", uuid.NewV4().String()})
|
|
|
|
TReceiveExpectedMessage(t, conn, 1, SuccessCommand, IgnoreReceivedArguments)
|
|
|
|
TSendMessage(t, conn, 2, "sub", TestChannelName)
|
|
|
|
TReceiveExpectedMessage(t, conn, 2, SuccessCommand, nil)
|
|
|
|
|
|
|
|
readyWg.Done()
|
|
|
|
|
|
|
|
TReceiveExpectedMessage(t, conn, -1, TestCommand, TestData)
|
|
|
|
|
|
|
|
conn.Close()
|
|
|
|
doneWg.Done()
|
|
|
|
}(conn)
|
|
|
|
|
|
|
|
readyWg.Wait()
|
|
|
|
|
|
|
|
form := url.Values{}
|
|
|
|
form.Set("cmd", TestCommand)
|
|
|
|
argsBytes, _ := json.Marshal(TestData)
|
|
|
|
form.Set("args", string(argsBytes))
|
|
|
|
form.Set("channel", TestChannelName)
|
|
|
|
form.Set("scope", MsgTargetTypeChat.Name())
|
|
|
|
|
|
|
|
sealedForm, err := SealRequest(form)
|
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
server.CloseClientConnections()
|
|
|
|
panic("halting test")
|
|
|
|
}
|
|
|
|
|
2015-10-26 11:25:17 -07:00
|
|
|
resp, err := http.PostForm(urls.PubMsg, sealedForm)
|
2015-10-26 11:22:06 -07:00
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
server.CloseClientConnections()
|
|
|
|
panic("halting test")
|
|
|
|
}
|
|
|
|
|
|
|
|
respBytes, err := ioutil.ReadAll(resp.Body)
|
|
|
|
resp.Body.Close()
|
|
|
|
respStr := string(respBytes)
|
|
|
|
|
|
|
|
if resp.StatusCode != 200 {
|
|
|
|
t.Error("Publish failed: ", resp.StatusCode, respStr)
|
|
|
|
server.CloseClientConnections()
|
|
|
|
panic("halting test")
|
|
|
|
}
|
|
|
|
|
|
|
|
doneWg.Wait()
|
|
|
|
server.Close()
|
|
|
|
}
|
|
|
|
|
2015-10-26 11:56:03 -07:00
|
|
|
func BenchmarkUserSubscriptionSinglePublish(b *testing.B) {
|
2015-10-25 20:17:17 -07:00
|
|
|
var doneWg sync.WaitGroup
|
|
|
|
var readyWg sync.WaitGroup
|
|
|
|
|
2015-10-26 12:13:28 -07:00
|
|
|
const TestChannelName = "room.testchannel"
|
2015-10-25 20:17:17 -07:00
|
|
|
const TestCommand = "testdata"
|
2015-10-26 11:22:06 -07:00
|
|
|
const TestData = "123456789"
|
2015-10-25 20:17:17 -07:00
|
|
|
|
2015-10-26 11:22:06 -07:00
|
|
|
message := ClientMessage{MessageID: -1, Command: "testdata", Arguments: TestData}
|
2015-10-25 20:17:17 -07:00
|
|
|
|
|
|
|
fmt.Println()
|
|
|
|
fmt.Println(b.N)
|
|
|
|
|
|
|
|
var limit syscall.Rlimit
|
|
|
|
syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit)
|
|
|
|
|
2015-10-26 11:22:06 -07:00
|
|
|
limit.Cur = TCountOpenFDs() + uint64(b.N)*2 + 100
|
2015-10-25 20:17:17 -07:00
|
|
|
|
|
|
|
if limit.Cur > limit.Max {
|
|
|
|
b.Skip("Open file limit too low")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
syscall.Setrlimit(syscall.RLIMIT_NOFILE, &limit)
|
|
|
|
|
2015-10-26 11:56:03 -07:00
|
|
|
var server *httptest.Server
|
|
|
|
var urls TURLs
|
|
|
|
TSetup(&server, &urls)
|
|
|
|
defer unsubscribeAllClients()
|
|
|
|
|
2015-10-25 20:17:17 -07:00
|
|
|
b.ResetTimer()
|
|
|
|
for i := 0; i < b.N; i++ {
|
2015-10-26 11:25:17 -07:00
|
|
|
conn, err := websocket.Dial(urls.Websocket, "", urls.Origin)
|
2015-10-25 20:17:17 -07:00
|
|
|
if err != nil {
|
|
|
|
b.Error(err)
|
|
|
|
break
|
|
|
|
}
|
|
|
|
doneWg.Add(1)
|
|
|
|
readyWg.Add(1)
|
|
|
|
go func(i int, conn *websocket.Conn) {
|
2015-10-26 11:22:06 -07:00
|
|
|
TSendMessage(b, conn, 1, HelloCommand, []interface{}{"ffz_0.0-test", uuid.NewV4().String()})
|
|
|
|
TSendMessage(b, conn, 2, "sub", TestChannelName)
|
|
|
|
|
|
|
|
TReceiveExpectedMessage(b, conn, 1, SuccessCommand, IgnoreReceivedArguments)
|
|
|
|
TReceiveExpectedMessage(b, conn, 2, SuccessCommand, nil)
|
2015-10-25 20:17:17 -07:00
|
|
|
|
|
|
|
readyWg.Done()
|
|
|
|
|
2015-10-26 11:22:06 -07:00
|
|
|
TReceiveExpectedMessage(b, conn, -1, TestCommand, TestData)
|
|
|
|
|
2015-10-25 20:17:17 -07:00
|
|
|
conn.Close()
|
|
|
|
doneWg.Done()
|
|
|
|
}(i, conn)
|
|
|
|
}
|
|
|
|
|
|
|
|
readyWg.Wait()
|
|
|
|
|
|
|
|
fmt.Println("publishing...")
|
|
|
|
if PublishToChat(TestChannelName, message) != b.N {
|
|
|
|
b.Error("not enough sent")
|
2015-10-26 11:22:06 -07:00
|
|
|
server.CloseClientConnections()
|
|
|
|
panic("halting test instead of waiting")
|
2015-10-25 20:17:17 -07:00
|
|
|
}
|
|
|
|
doneWg.Wait()
|
2015-10-26 11:56:03 -07:00
|
|
|
fmt.Println("...done.")
|
2015-10-25 20:17:17 -07:00
|
|
|
|
|
|
|
b.StopTimer()
|
|
|
|
server.Close()
|
|
|
|
server.CloseClientConnections()
|
|
|
|
}
|