mirror of
https://github.com/openfaas/faas.git
synced 2025-06-18 03:56:37 +00:00
Merge master into breakout_swarm
Signed-off-by: Alex Ellis <alexellis2@gmail.com>
This commit is contained in:
223
gateway/vendor/github.com/nats-io/go-nats/test/auth_test.go
generated
vendored
Normal file
223
gateway/vendor/github.com/nats-io/go-nats/test/auth_test.go
generated
vendored
Normal file
@ -0,0 +1,223 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/nats-io/gnatsd/server"
|
||||
"github.com/nats-io/gnatsd/test"
|
||||
"github.com/nats-io/go-nats"
|
||||
)
|
||||
|
||||
func TestAuth(t *testing.T) {
|
||||
opts := test.DefaultTestOptions
|
||||
opts.Port = 8232
|
||||
opts.Username = "derek"
|
||||
opts.Password = "foo"
|
||||
s := RunServerWithOptions(opts)
|
||||
defer s.Shutdown()
|
||||
|
||||
_, err := nats.Connect("nats://localhost:8232")
|
||||
if err == nil {
|
||||
t.Fatal("Should have received an error while trying to connect")
|
||||
}
|
||||
|
||||
// This test may be a bit too strict for the future, but for now makes
|
||||
// sure that we correctly process the -ERR content on connect.
|
||||
if err.Error() != nats.ErrAuthorization.Error() {
|
||||
t.Fatalf("Expected error '%v', got '%v'", nats.ErrAuthorization, err)
|
||||
}
|
||||
|
||||
nc, err := nats.Connect("nats://derek:foo@localhost:8232")
|
||||
if err != nil {
|
||||
t.Fatal("Should have connected successfully with a token")
|
||||
}
|
||||
nc.Close()
|
||||
|
||||
// Use Options
|
||||
nc, err = nats.Connect("nats://localhost:8232", nats.UserInfo("derek", "foo"))
|
||||
if err != nil {
|
||||
t.Fatalf("Should have connected successfully with a token: %v", err)
|
||||
}
|
||||
nc.Close()
|
||||
// Verify that credentials in URL take precedence.
|
||||
nc, err = nats.Connect("nats://derek:foo@localhost:8232", nats.UserInfo("foo", "bar"))
|
||||
if err != nil {
|
||||
t.Fatalf("Should have connected successfully with a token: %v", err)
|
||||
}
|
||||
nc.Close()
|
||||
}
|
||||
|
||||
func TestAuthFailNoDisconnectCB(t *testing.T) {
|
||||
opts := test.DefaultTestOptions
|
||||
opts.Port = 8232
|
||||
opts.Username = "derek"
|
||||
opts.Password = "foo"
|
||||
s := RunServerWithOptions(opts)
|
||||
defer s.Shutdown()
|
||||
|
||||
copts := nats.GetDefaultOptions()
|
||||
copts.Url = "nats://localhost:8232"
|
||||
receivedDisconnectCB := int32(0)
|
||||
copts.DisconnectedCB = func(nc *nats.Conn) {
|
||||
atomic.AddInt32(&receivedDisconnectCB, 1)
|
||||
}
|
||||
|
||||
_, err := copts.Connect()
|
||||
if err == nil {
|
||||
t.Fatal("Should have received an error while trying to connect")
|
||||
}
|
||||
if atomic.LoadInt32(&receivedDisconnectCB) > 0 {
|
||||
t.Fatal("Should not have received a disconnect callback on auth failure")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAuthFailAllowReconnect(t *testing.T) {
|
||||
ts := RunServerOnPort(23232)
|
||||
defer ts.Shutdown()
|
||||
|
||||
var servers = []string{
|
||||
"nats://localhost:23232",
|
||||
"nats://localhost:23233",
|
||||
"nats://localhost:23234",
|
||||
}
|
||||
|
||||
ots2 := test.DefaultTestOptions
|
||||
ots2.Port = 23233
|
||||
ots2.Username = "ivan"
|
||||
ots2.Password = "foo"
|
||||
ts2 := RunServerWithOptions(ots2)
|
||||
defer ts2.Shutdown()
|
||||
|
||||
ts3 := RunServerOnPort(23234)
|
||||
defer ts3.Shutdown()
|
||||
|
||||
reconnectch := make(chan bool)
|
||||
|
||||
opts := nats.GetDefaultOptions()
|
||||
opts.Servers = servers
|
||||
opts.AllowReconnect = true
|
||||
opts.NoRandomize = true
|
||||
opts.MaxReconnect = 10
|
||||
opts.ReconnectWait = 100 * time.Millisecond
|
||||
|
||||
opts.ReconnectedCB = func(_ *nats.Conn) {
|
||||
reconnectch <- true
|
||||
}
|
||||
|
||||
// Connect
|
||||
nc, err := opts.Connect()
|
||||
if err != nil {
|
||||
t.Fatalf("Should have connected ok: %v", err)
|
||||
}
|
||||
defer nc.Close()
|
||||
|
||||
// Stop the server
|
||||
ts.Shutdown()
|
||||
|
||||
// The client will try to connect to the second server, and that
|
||||
// should fail. It should then try to connect to the third and succeed.
|
||||
|
||||
// Wait for the reconnect CB.
|
||||
if e := Wait(reconnectch); e != nil {
|
||||
t.Fatal("Reconnect callback should have been triggered")
|
||||
}
|
||||
|
||||
if nc.IsClosed() {
|
||||
t.Fatal("Should have reconnected")
|
||||
}
|
||||
|
||||
if nc.ConnectedUrl() != servers[2] {
|
||||
t.Fatalf("Should have reconnected to %s, reconnected to %s instead", servers[2], nc.ConnectedUrl())
|
||||
}
|
||||
}
|
||||
|
||||
func TestTokenAuth(t *testing.T) {
|
||||
opts := test.DefaultTestOptions
|
||||
opts.Port = 8232
|
||||
secret := "S3Cr3T0k3n!"
|
||||
opts.Authorization = secret
|
||||
s := RunServerWithOptions(opts)
|
||||
defer s.Shutdown()
|
||||
|
||||
_, err := nats.Connect("nats://localhost:8232")
|
||||
if err == nil {
|
||||
t.Fatal("Should have received an error while trying to connect")
|
||||
}
|
||||
|
||||
tokenURL := fmt.Sprintf("nats://%s@localhost:8232", secret)
|
||||
nc, err := nats.Connect(tokenURL)
|
||||
if err != nil {
|
||||
t.Fatal("Should have connected successfully")
|
||||
}
|
||||
nc.Close()
|
||||
|
||||
// Use Options
|
||||
nc, err = nats.Connect("nats://localhost:8232", nats.Token(secret))
|
||||
if err != nil {
|
||||
t.Fatalf("Should have connected successfully: %v", err)
|
||||
}
|
||||
nc.Close()
|
||||
// Verify that token in the URL takes precedence.
|
||||
nc, err = nats.Connect(tokenURL, nats.Token("badtoken"))
|
||||
if err != nil {
|
||||
t.Fatalf("Should have connected successfully: %v", err)
|
||||
}
|
||||
nc.Close()
|
||||
}
|
||||
|
||||
func TestPermViolation(t *testing.T) {
|
||||
opts := test.DefaultTestOptions
|
||||
opts.Port = 8232
|
||||
opts.Users = []*server.User{
|
||||
&server.User{
|
||||
Username: "ivan",
|
||||
Password: "pwd",
|
||||
Permissions: &server.Permissions{
|
||||
Publish: []string{"foo"},
|
||||
Subscribe: []string{"bar"},
|
||||
},
|
||||
},
|
||||
}
|
||||
s := RunServerWithOptions(opts)
|
||||
defer s.Shutdown()
|
||||
|
||||
errCh := make(chan error, 2)
|
||||
errCB := func(_ *nats.Conn, _ *nats.Subscription, err error) {
|
||||
errCh <- err
|
||||
}
|
||||
nc, err := nats.Connect(
|
||||
fmt.Sprintf("nats://ivan:pwd@localhost:%d", opts.Port),
|
||||
nats.ErrorHandler(errCB))
|
||||
if err != nil {
|
||||
t.Fatalf("Error on connect: %v", err)
|
||||
}
|
||||
defer nc.Close()
|
||||
|
||||
// Cause a publish error
|
||||
nc.Publish("bar", []byte("fail"))
|
||||
// Cause a subscribe error
|
||||
nc.Subscribe("foo", func(_ *nats.Msg) {})
|
||||
|
||||
expectedErrorTypes := []string{"publish", "subscription"}
|
||||
for _, expectedErr := range expectedErrorTypes {
|
||||
select {
|
||||
case e := <-errCh:
|
||||
if !strings.Contains(e.Error(), nats.PERMISSIONS_ERR) {
|
||||
t.Fatalf("Did not receive error about permissions")
|
||||
}
|
||||
if !strings.Contains(e.Error(), expectedErr) {
|
||||
t.Fatalf("Did not receive error about %q, got %v", expectedErr, e.Error())
|
||||
}
|
||||
case <-time.After(2 * time.Second):
|
||||
t.Fatalf("Did not get the permission error")
|
||||
}
|
||||
}
|
||||
// Make sure connection has not been closed
|
||||
if nc.IsClosed() {
|
||||
t.Fatal("Connection should be not be closed")
|
||||
}
|
||||
}
|
885
gateway/vendor/github.com/nats-io/go-nats/test/basic_test.go
generated
vendored
Normal file
885
gateway/vendor/github.com/nats-io/go-nats/test/basic_test.go
generated
vendored
Normal file
@ -0,0 +1,885 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"math"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/nats-io/go-nats"
|
||||
)
|
||||
|
||||
func TestCloseLeakingGoRoutines(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
|
||||
// Give time for things to settle before capturing the number of
|
||||
// go routines
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
|
||||
base := runtime.NumGoroutine()
|
||||
|
||||
nc := NewDefaultConnection(t)
|
||||
|
||||
nc.Flush()
|
||||
nc.Close()
|
||||
|
||||
// Give time for things to settle before capturing the number of
|
||||
// go routines
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
|
||||
delta := (runtime.NumGoroutine() - base)
|
||||
if delta > 0 {
|
||||
t.Fatalf("%d Go routines still exist post Close()", delta)
|
||||
}
|
||||
// Make sure we can call Close() multiple times
|
||||
nc.Close()
|
||||
}
|
||||
|
||||
func TestLeakingGoRoutinesOnFailedConnect(t *testing.T) {
|
||||
// Give time for things to settle before capturing the number of
|
||||
// go routines
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
|
||||
base := runtime.NumGoroutine()
|
||||
|
||||
nc, err := nats.Connect(nats.DefaultURL)
|
||||
if err == nil {
|
||||
nc.Close()
|
||||
t.Fatalf("Expected failure to connect")
|
||||
}
|
||||
|
||||
// Give time for things to settle before capturing the number of
|
||||
// go routines
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
|
||||
delta := (runtime.NumGoroutine() - base)
|
||||
if delta > 0 {
|
||||
t.Fatalf("%d Go routines still exist post Close()", delta)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConnectedServer(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
|
||||
nc := NewDefaultConnection(t)
|
||||
defer nc.Close()
|
||||
|
||||
u := nc.ConnectedUrl()
|
||||
if u == "" || u != nats.DefaultURL {
|
||||
t.Fatalf("Unexpected connected URL of %s\n", u)
|
||||
}
|
||||
srv := nc.ConnectedServerId()
|
||||
if srv == "" {
|
||||
t.Fatal("Expected a connected server id")
|
||||
}
|
||||
nc.Close()
|
||||
u = nc.ConnectedUrl()
|
||||
if u != "" {
|
||||
t.Fatalf("Expected a nil connected URL, got %s\n", u)
|
||||
}
|
||||
srv = nc.ConnectedServerId()
|
||||
if srv != "" {
|
||||
t.Fatalf("Expected a nil connect server, got %s\n", srv)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMultipleClose(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
nc := NewDefaultConnection(t)
|
||||
|
||||
var wg sync.WaitGroup
|
||||
for i := 0; i < 10; i++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
nc.Close()
|
||||
wg.Done()
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func TestBadOptionTimeoutConnect(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
|
||||
opts := nats.GetDefaultOptions()
|
||||
opts.Timeout = -1
|
||||
opts.Url = "nats://localhost:4222"
|
||||
|
||||
_, err := opts.Connect()
|
||||
if err == nil {
|
||||
t.Fatal("Expected an error")
|
||||
}
|
||||
if err != nats.ErrNoServers {
|
||||
t.Fatalf("Expected a ErrNoServers error: Got %v\n", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSimplePublish(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
nc := NewDefaultConnection(t)
|
||||
defer nc.Close()
|
||||
|
||||
if err := nc.Publish("foo", []byte("Hello World")); err != nil {
|
||||
t.Fatal("Failed to publish string message: ", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSimplePublishNoData(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
nc := NewDefaultConnection(t)
|
||||
defer nc.Close()
|
||||
|
||||
if err := nc.Publish("foo", nil); err != nil {
|
||||
t.Fatal("Failed to publish empty message: ", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPublishDoesNotFailOnSlowConsumer(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
nc := NewDefaultConnection(t)
|
||||
defer nc.Close()
|
||||
|
||||
sub, err := nc.SubscribeSync("foo")
|
||||
if err != nil {
|
||||
t.Fatalf("Unable to create subscription: %v", err)
|
||||
}
|
||||
|
||||
if err := sub.SetPendingLimits(1, 1000); err != nil {
|
||||
t.Fatalf("Unable to set pending limits: %v", err)
|
||||
}
|
||||
|
||||
var pubErr error
|
||||
|
||||
msg := []byte("Hello")
|
||||
for i := 0; i < 10; i++ {
|
||||
pubErr = nc.Publish("foo", msg)
|
||||
if pubErr != nil {
|
||||
break
|
||||
}
|
||||
nc.Flush()
|
||||
}
|
||||
|
||||
if pubErr != nil {
|
||||
t.Fatalf("Publish() should not fail because of slow consumer. Got '%v'", pubErr)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAsyncSubscribe(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
nc := NewDefaultConnection(t)
|
||||
defer nc.Close()
|
||||
|
||||
omsg := []byte("Hello World")
|
||||
ch := make(chan bool)
|
||||
|
||||
// Callback is mandatory
|
||||
if _, err := nc.Subscribe("foo", nil); err == nil {
|
||||
t.Fatal("Creating subscription without callback should have failed")
|
||||
}
|
||||
|
||||
_, err := nc.Subscribe("foo", func(m *nats.Msg) {
|
||||
if !bytes.Equal(m.Data, omsg) {
|
||||
t.Fatal("Message received does not match")
|
||||
}
|
||||
if m.Sub == nil {
|
||||
t.Fatal("Callback does not have a valid Subscription")
|
||||
}
|
||||
ch <- true
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal("Failed to subscribe: ", err)
|
||||
}
|
||||
nc.Publish("foo", omsg)
|
||||
if e := Wait(ch); e != nil {
|
||||
t.Fatal("Message not received for subscription")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAsyncSubscribeRoutineLeakOnUnsubscribe(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
|
||||
nc := NewDefaultConnection(t)
|
||||
defer nc.Close()
|
||||
|
||||
ch := make(chan bool)
|
||||
|
||||
// Give time for things to settle before capturing the number of
|
||||
// go routines
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
|
||||
// Take the base once the connection is established, but before
|
||||
// the subscriber is created.
|
||||
base := runtime.NumGoroutine()
|
||||
|
||||
sub, err := nc.Subscribe("foo", func(m *nats.Msg) { ch <- true })
|
||||
if err != nil {
|
||||
t.Fatal("Failed to subscribe: ", err)
|
||||
}
|
||||
|
||||
// Send to ourself
|
||||
nc.Publish("foo", []byte("hello"))
|
||||
|
||||
// This ensures that the async delivery routine is up and running.
|
||||
if err := Wait(ch); err != nil {
|
||||
t.Fatal("Failed to receive message")
|
||||
}
|
||||
|
||||
// Make sure to give it time to go back into wait
|
||||
time.Sleep(200 * time.Millisecond)
|
||||
|
||||
// Explicit unsubscribe
|
||||
sub.Unsubscribe()
|
||||
|
||||
// Give time for things to settle before capturing the number of
|
||||
// go routines
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
|
||||
delta := (runtime.NumGoroutine() - base)
|
||||
if delta > 0 {
|
||||
t.Fatalf("%d Go routines still exist post Unsubscribe()", delta)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAsyncSubscribeRoutineLeakOnClose(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
|
||||
ch := make(chan bool)
|
||||
|
||||
// Give time for things to settle before capturing the number of
|
||||
// go routines
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
|
||||
// Take the base before creating the connection, since we are going
|
||||
// to close it before taking the delta.
|
||||
base := runtime.NumGoroutine()
|
||||
|
||||
nc := NewDefaultConnection(t)
|
||||
defer nc.Close()
|
||||
|
||||
_, err := nc.Subscribe("foo", func(m *nats.Msg) { ch <- true })
|
||||
if err != nil {
|
||||
t.Fatal("Failed to subscribe: ", err)
|
||||
}
|
||||
|
||||
// Send to ourself
|
||||
nc.Publish("foo", []byte("hello"))
|
||||
|
||||
// This ensures that the async delivery routine is up and running.
|
||||
if err := Wait(ch); err != nil {
|
||||
t.Fatal("Failed to receive message")
|
||||
}
|
||||
|
||||
// Make sure to give it time to go back into wait
|
||||
time.Sleep(200 * time.Millisecond)
|
||||
|
||||
// Close connection without explicit unsubscribe
|
||||
nc.Close()
|
||||
|
||||
// Give time for things to settle before capturing the number of
|
||||
// go routines
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
|
||||
delta := (runtime.NumGoroutine() - base)
|
||||
if delta > 0 {
|
||||
t.Fatalf("%d Go routines still exist post Close()", delta)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSyncSubscribe(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
nc := NewDefaultConnection(t)
|
||||
defer nc.Close()
|
||||
|
||||
sub, err := nc.SubscribeSync("foo")
|
||||
if err != nil {
|
||||
t.Fatal("Failed to subscribe: ", err)
|
||||
}
|
||||
omsg := []byte("Hello World")
|
||||
nc.Publish("foo", omsg)
|
||||
msg, err := sub.NextMsg(1 * time.Second)
|
||||
if err != nil || !bytes.Equal(msg.Data, omsg) {
|
||||
t.Fatal("Message received does not match")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPubSubWithReply(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
nc := NewDefaultConnection(t)
|
||||
defer nc.Close()
|
||||
|
||||
sub, err := nc.SubscribeSync("foo")
|
||||
if err != nil {
|
||||
t.Fatal("Failed to subscribe: ", err)
|
||||
}
|
||||
omsg := []byte("Hello World")
|
||||
nc.PublishMsg(&nats.Msg{Subject: "foo", Reply: "bar", Data: omsg})
|
||||
msg, err := sub.NextMsg(10 * time.Second)
|
||||
if err != nil || !bytes.Equal(msg.Data, omsg) {
|
||||
t.Fatal("Message received does not match")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFlush(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
nc := NewDefaultConnection(t)
|
||||
defer nc.Close()
|
||||
|
||||
omsg := []byte("Hello World")
|
||||
for i := 0; i < 10000; i++ {
|
||||
nc.Publish("flush", omsg)
|
||||
}
|
||||
if err := nc.FlushTimeout(0); err == nil {
|
||||
t.Fatal("Calling FlushTimeout() with invalid timeout should fail")
|
||||
}
|
||||
if err := nc.Flush(); err != nil {
|
||||
t.Fatalf("Received error from flush: %s\n", err)
|
||||
}
|
||||
if nb, _ := nc.Buffered(); nb > 0 {
|
||||
t.Fatalf("Outbound buffer not empty: %d bytes\n", nb)
|
||||
}
|
||||
|
||||
nc.Close()
|
||||
if _, err := nc.Buffered(); err == nil {
|
||||
t.Fatal("Calling Buffered() on closed connection should fail")
|
||||
}
|
||||
}
|
||||
|
||||
func TestQueueSubscriber(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
nc := NewDefaultConnection(t)
|
||||
defer nc.Close()
|
||||
|
||||
s1, _ := nc.QueueSubscribeSync("foo", "bar")
|
||||
s2, _ := nc.QueueSubscribeSync("foo", "bar")
|
||||
omsg := []byte("Hello World")
|
||||
nc.Publish("foo", omsg)
|
||||
nc.Flush()
|
||||
r1, _ := s1.QueuedMsgs()
|
||||
r2, _ := s2.QueuedMsgs()
|
||||
if (r1 + r2) != 1 {
|
||||
t.Fatal("Received too many messages for multiple queue subscribers")
|
||||
}
|
||||
// Drain messages
|
||||
s1.NextMsg(time.Second)
|
||||
s2.NextMsg(time.Second)
|
||||
|
||||
total := 1000
|
||||
for i := 0; i < total; i++ {
|
||||
nc.Publish("foo", omsg)
|
||||
}
|
||||
nc.Flush()
|
||||
v := uint(float32(total) * 0.15)
|
||||
r1, _ = s1.QueuedMsgs()
|
||||
r2, _ = s2.QueuedMsgs()
|
||||
if r1+r2 != total {
|
||||
t.Fatalf("Incorrect number of messages: %d vs %d", (r1 + r2), total)
|
||||
}
|
||||
expected := total / 2
|
||||
d1 := uint(math.Abs(float64(expected - r1)))
|
||||
d2 := uint(math.Abs(float64(expected - r2)))
|
||||
if d1 > v || d2 > v {
|
||||
t.Fatalf("Too much variance in totals: %d, %d > %d", d1, d2, v)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReplyArg(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
nc := NewDefaultConnection(t)
|
||||
defer nc.Close()
|
||||
|
||||
ch := make(chan bool)
|
||||
replyExpected := "bar"
|
||||
|
||||
nc.Subscribe("foo", func(m *nats.Msg) {
|
||||
if m.Reply != replyExpected {
|
||||
t.Fatalf("Did not receive correct reply arg in callback: "+
|
||||
"('%s' vs '%s')", m.Reply, replyExpected)
|
||||
}
|
||||
ch <- true
|
||||
})
|
||||
nc.PublishMsg(&nats.Msg{Subject: "foo", Reply: replyExpected, Data: []byte("Hello")})
|
||||
if e := Wait(ch); e != nil {
|
||||
t.Fatal("Did not receive callback")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSyncReplyArg(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
nc := NewDefaultConnection(t)
|
||||
defer nc.Close()
|
||||
|
||||
replyExpected := "bar"
|
||||
sub, _ := nc.SubscribeSync("foo")
|
||||
nc.PublishMsg(&nats.Msg{Subject: "foo", Reply: replyExpected, Data: []byte("Hello")})
|
||||
msg, err := sub.NextMsg(1 * time.Second)
|
||||
if err != nil {
|
||||
t.Fatal("Received an err on NextMsg()")
|
||||
}
|
||||
if msg.Reply != replyExpected {
|
||||
t.Fatalf("Did not receive correct reply arg in callback: "+
|
||||
"('%s' vs '%s')", msg.Reply, replyExpected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnsubscribe(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
nc := NewDefaultConnection(t)
|
||||
defer nc.Close()
|
||||
|
||||
received := int32(0)
|
||||
max := int32(10)
|
||||
ch := make(chan bool)
|
||||
nc.Subscribe("foo", func(m *nats.Msg) {
|
||||
atomic.AddInt32(&received, 1)
|
||||
if received == max {
|
||||
err := m.Sub.Unsubscribe()
|
||||
if err != nil {
|
||||
t.Fatal("Unsubscribe failed with err:", err)
|
||||
}
|
||||
ch <- true
|
||||
}
|
||||
})
|
||||
send := 20
|
||||
for i := 0; i < send; i++ {
|
||||
nc.Publish("foo", []byte("hello"))
|
||||
}
|
||||
nc.Flush()
|
||||
<-ch
|
||||
|
||||
r := atomic.LoadInt32(&received)
|
||||
if r != max {
|
||||
t.Fatalf("Received wrong # of messages after unsubscribe: %d vs %d",
|
||||
r, max)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDoubleUnsubscribe(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
nc := NewDefaultConnection(t)
|
||||
defer nc.Close()
|
||||
|
||||
sub, err := nc.SubscribeSync("foo")
|
||||
if err != nil {
|
||||
t.Fatal("Failed to subscribe: ", err)
|
||||
}
|
||||
if err = sub.Unsubscribe(); err != nil {
|
||||
t.Fatal("Unsubscribe failed with err:", err)
|
||||
}
|
||||
if err = sub.Unsubscribe(); err == nil {
|
||||
t.Fatal("Unsubscribe should have reported an error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRequestTimeout(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
nc := NewDefaultConnection(t)
|
||||
defer nc.Close()
|
||||
|
||||
if _, err := nc.Request("foo", []byte("help"), 10*time.Millisecond); err == nil {
|
||||
t.Fatalf("Expected to receive a timeout error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestOldRequest(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
|
||||
nc, err := nats.Connect(nats.DefaultURL, nats.UseOldRequestStyle())
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to connect: %v", err)
|
||||
}
|
||||
defer nc.Close()
|
||||
|
||||
response := []byte("I will help you")
|
||||
nc.Subscribe("foo", func(m *nats.Msg) {
|
||||
nc.Publish(m.Reply, response)
|
||||
})
|
||||
msg, err := nc.Request("foo", []byte("help"), 500*time.Millisecond)
|
||||
if err != nil {
|
||||
t.Fatalf("Received an error on Request test: %s", err)
|
||||
}
|
||||
if !bytes.Equal(msg.Data, response) {
|
||||
t.Fatalf("Received invalid response")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRequest(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
nc := NewDefaultConnection(t)
|
||||
defer nc.Close()
|
||||
|
||||
response := []byte("I will help you")
|
||||
nc.Subscribe("foo", func(m *nats.Msg) {
|
||||
nc.Publish(m.Reply, response)
|
||||
})
|
||||
msg, err := nc.Request("foo", []byte("help"), 500*time.Millisecond)
|
||||
if err != nil {
|
||||
t.Fatalf("Received an error on Request test: %s", err)
|
||||
}
|
||||
if !bytes.Equal(msg.Data, response) {
|
||||
t.Fatalf("Received invalid response")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRequestNoBody(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
nc := NewDefaultConnection(t)
|
||||
defer nc.Close()
|
||||
|
||||
response := []byte("I will help you")
|
||||
nc.Subscribe("foo", func(m *nats.Msg) {
|
||||
nc.Publish(m.Reply, response)
|
||||
})
|
||||
msg, err := nc.Request("foo", nil, 500*time.Millisecond)
|
||||
if err != nil {
|
||||
t.Fatalf("Received an error on Request test: %s", err)
|
||||
}
|
||||
if !bytes.Equal(msg.Data, response) {
|
||||
t.Fatalf("Received invalid response")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSimultaneousRequests(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
nc := NewDefaultConnection(t)
|
||||
defer nc.Close()
|
||||
|
||||
response := []byte("I will help you")
|
||||
nc.Subscribe("foo", func(m *nats.Msg) {
|
||||
nc.Publish(m.Reply, response)
|
||||
})
|
||||
|
||||
var wg sync.WaitGroup
|
||||
for i := 0; i < 50; i++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
if _, err := nc.Request("foo", nil, 2*time.Second); err != nil {
|
||||
t.Fatalf("Expected to receive a timeout error")
|
||||
} else {
|
||||
wg.Done()
|
||||
}
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func TestRequestClose(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
|
||||
nc := NewDefaultConnection(t)
|
||||
defer nc.Close()
|
||||
|
||||
wg := &sync.WaitGroup{}
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
nc.Close()
|
||||
}()
|
||||
if _, err := nc.Request("foo", []byte("help"), 2*time.Second); err != nats.ErrInvalidConnection && err != nats.ErrConnectionClosed {
|
||||
t.Fatalf("Expected connection error: got %v", err)
|
||||
}
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func TestRequestCloseTimeout(t *testing.T) {
|
||||
// Make sure we return a timeout when we close
|
||||
// the connection even if response is queued.
|
||||
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
|
||||
nc := NewDefaultConnection(t)
|
||||
defer nc.Close()
|
||||
|
||||
response := []byte("I will help you")
|
||||
nc.Subscribe("foo", func(m *nats.Msg) {
|
||||
nc.Publish(m.Reply, response)
|
||||
nc.Close()
|
||||
})
|
||||
if _, err := nc.Request("foo", nil, 1*time.Second); err == nil {
|
||||
t.Fatalf("Expected to receive a timeout error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFlushInCB(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
nc := NewDefaultConnection(t)
|
||||
defer nc.Close()
|
||||
|
||||
ch := make(chan bool)
|
||||
|
||||
nc.Subscribe("foo", func(_ *nats.Msg) {
|
||||
nc.Flush()
|
||||
ch <- true
|
||||
})
|
||||
nc.Publish("foo", []byte("Hello"))
|
||||
if e := Wait(ch); e != nil {
|
||||
t.Fatal("Flush did not return properly in callback")
|
||||
}
|
||||
}
|
||||
|
||||
func TestReleaseFlush(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
nc := NewDefaultConnection(t)
|
||||
|
||||
for i := 0; i < 1000; i++ {
|
||||
nc.Publish("foo", []byte("Hello"))
|
||||
}
|
||||
go nc.Close()
|
||||
nc.Flush()
|
||||
}
|
||||
|
||||
func TestInbox(t *testing.T) {
|
||||
inbox := nats.NewInbox()
|
||||
if matched, _ := regexp.Match(`_INBOX.\S`, []byte(inbox)); !matched {
|
||||
t.Fatal("Bad INBOX format")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStats(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
nc := NewDefaultConnection(t)
|
||||
defer nc.Close()
|
||||
|
||||
data := []byte("The quick brown fox jumped over the lazy dog")
|
||||
iter := 10
|
||||
|
||||
for i := 0; i < iter; i++ {
|
||||
nc.Publish("foo", data)
|
||||
}
|
||||
|
||||
if nc.OutMsgs != uint64(iter) {
|
||||
t.Fatalf("Not properly tracking OutMsgs: received %d, wanted %d\n", nc.OutMsgs, iter)
|
||||
}
|
||||
obb := uint64(iter * len(data))
|
||||
if nc.OutBytes != obb {
|
||||
t.Fatalf("Not properly tracking OutBytes: received %d, wanted %d\n", nc.OutBytes, obb)
|
||||
}
|
||||
|
||||
// Clear outbound
|
||||
nc.OutMsgs, nc.OutBytes = 0, 0
|
||||
|
||||
// Test both sync and async versions of subscribe.
|
||||
nc.Subscribe("foo", func(_ *nats.Msg) {})
|
||||
nc.SubscribeSync("foo")
|
||||
|
||||
for i := 0; i < iter; i++ {
|
||||
nc.Publish("foo", data)
|
||||
}
|
||||
nc.Flush()
|
||||
|
||||
if nc.InMsgs != uint64(2*iter) {
|
||||
t.Fatalf("Not properly tracking InMsgs: received %d, wanted %d\n", nc.InMsgs, 2*iter)
|
||||
}
|
||||
|
||||
ibb := 2 * obb
|
||||
if nc.InBytes != ibb {
|
||||
t.Fatalf("Not properly tracking InBytes: received %d, wanted %d\n", nc.InBytes, ibb)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRaceSafeStats(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
nc := NewDefaultConnection(t)
|
||||
defer nc.Close()
|
||||
|
||||
go nc.Publish("foo", []byte("Hello World"))
|
||||
time.Sleep(200 * time.Millisecond)
|
||||
|
||||
stats := nc.Stats()
|
||||
|
||||
if stats.OutMsgs != uint64(1) {
|
||||
t.Fatalf("Not properly tracking OutMsgs: received %d, wanted %d\n", nc.OutMsgs, 1)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBadSubject(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
nc := NewDefaultConnection(t)
|
||||
defer nc.Close()
|
||||
|
||||
err := nc.Publish("", []byte("Hello World"))
|
||||
if err == nil {
|
||||
t.Fatalf("Expected an error on bad subject to publish")
|
||||
}
|
||||
if err != nats.ErrBadSubject {
|
||||
t.Fatalf("Expected a ErrBadSubject error: Got %v\n", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestOptions(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
|
||||
nc, err := nats.Connect(nats.DefaultURL, nats.Name("myName"), nats.MaxReconnects(2), nats.ReconnectWait(50*time.Millisecond))
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to connect: %v", err)
|
||||
}
|
||||
defer nc.Close()
|
||||
|
||||
rch := make(chan bool)
|
||||
cch := make(chan bool)
|
||||
|
||||
nc.SetReconnectHandler(func(_ *nats.Conn) { rch <- true })
|
||||
nc.SetClosedHandler(func(_ *nats.Conn) { cch <- true })
|
||||
|
||||
s.Shutdown()
|
||||
|
||||
s = RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
|
||||
if err := Wait(rch); err != nil {
|
||||
t.Fatal("Failed getting reconnected cb")
|
||||
}
|
||||
|
||||
nc.Close()
|
||||
|
||||
if err := Wait(cch); err != nil {
|
||||
t.Fatal("Failed getting closed cb")
|
||||
}
|
||||
|
||||
nc, err = nats.Connect(nats.DefaultURL, nats.NoReconnect())
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to connect: %v", err)
|
||||
}
|
||||
defer nc.Close()
|
||||
|
||||
nc.SetReconnectHandler(func(_ *nats.Conn) { rch <- true })
|
||||
nc.SetClosedHandler(func(_ *nats.Conn) { cch <- true })
|
||||
|
||||
s.Shutdown()
|
||||
|
||||
// We should not get a reconnect cb this time
|
||||
if err := WaitTime(rch, time.Second); err == nil {
|
||||
t.Fatal("Unexpected reconnect cb")
|
||||
}
|
||||
|
||||
nc.Close()
|
||||
|
||||
if err := Wait(cch); err != nil {
|
||||
t.Fatal("Failed getting closed cb")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNilConnection(t *testing.T) {
|
||||
var nc *nats.Conn
|
||||
data := []byte("ok")
|
||||
|
||||
// Publish
|
||||
if err := nc.Publish("foo", data); err == nil || err != nats.ErrInvalidConnection {
|
||||
t.Fatalf("Expected ErrInvalidConnection error, got %v\n", err)
|
||||
}
|
||||
if err := nc.PublishMsg(nil); err == nil || err != nats.ErrInvalidMsg {
|
||||
t.Fatalf("Expected ErrInvalidMsg error, got %v\n", err)
|
||||
}
|
||||
if err := nc.PublishMsg(&nats.Msg{}); err == nil || err != nats.ErrInvalidConnection {
|
||||
t.Fatalf("Expected ErrInvalidConnection error, got %v\n", err)
|
||||
}
|
||||
if err := nc.PublishRequest("foo", "reply", data); err == nil || err != nats.ErrInvalidConnection {
|
||||
t.Fatalf("Expected ErrInvalidConnection error, got %v\n", err)
|
||||
}
|
||||
|
||||
// Subscribe
|
||||
if _, err := nc.Subscribe("foo", nil); err == nil || err != nats.ErrInvalidConnection {
|
||||
t.Fatalf("Expected ErrInvalidConnection error, got %v\n", err)
|
||||
}
|
||||
if _, err := nc.SubscribeSync("foo"); err == nil || err != nats.ErrInvalidConnection {
|
||||
t.Fatalf("Expected ErrInvalidConnection error, got %v\n", err)
|
||||
}
|
||||
if _, err := nc.QueueSubscribe("foo", "bar", nil); err == nil || err != nats.ErrInvalidConnection {
|
||||
t.Fatalf("Expected ErrInvalidConnection error, got %v\n", err)
|
||||
}
|
||||
ch := make(chan *nats.Msg)
|
||||
if _, err := nc.ChanSubscribe("foo", ch); err == nil || err != nats.ErrInvalidConnection {
|
||||
t.Fatalf("Expected ErrInvalidConnection error, got %v\n", err)
|
||||
}
|
||||
if _, err := nc.ChanQueueSubscribe("foo", "bar", ch); err == nil || err != nats.ErrInvalidConnection {
|
||||
t.Fatalf("Expected ErrInvalidConnection error, got %v\n", err)
|
||||
}
|
||||
if _, err := nc.QueueSubscribeSyncWithChan("foo", "bar", ch); err == nil || err != nats.ErrInvalidConnection {
|
||||
t.Fatalf("Expected ErrInvalidConnection error, got %v\n", err)
|
||||
}
|
||||
|
||||
// Flush
|
||||
if err := nc.Flush(); err == nil || err != nats.ErrInvalidConnection {
|
||||
t.Fatalf("Expected ErrInvalidConnection error, got %v\n", err)
|
||||
}
|
||||
if err := nc.FlushTimeout(time.Millisecond); err == nil || err != nats.ErrInvalidConnection {
|
||||
t.Fatalf("Expected ErrInvalidConnection error, got %v\n", err)
|
||||
}
|
||||
|
||||
// Nil Subscribers
|
||||
var sub *nats.Subscription
|
||||
if sub.Type() != nats.NilSubscription {
|
||||
t.Fatalf("Got wrong type for nil subscription, %v\n", sub.Type())
|
||||
}
|
||||
if sub.IsValid() {
|
||||
t.Fatalf("Expected IsValid() to return false")
|
||||
}
|
||||
if err := sub.Unsubscribe(); err == nil || err != nats.ErrBadSubscription {
|
||||
t.Fatalf("Expected Unsubscribe to return proper error, got %v\n", err)
|
||||
}
|
||||
if err := sub.AutoUnsubscribe(1); err == nil || err != nats.ErrBadSubscription {
|
||||
t.Fatalf("Expected ErrBadSubscription error, got %v\n", err)
|
||||
}
|
||||
if _, err := sub.NextMsg(time.Millisecond); err == nil || err != nats.ErrBadSubscription {
|
||||
t.Fatalf("Expected ErrBadSubscription error, got %v\n", err)
|
||||
}
|
||||
if _, err := sub.QueuedMsgs(); err == nil || err != nats.ErrBadSubscription {
|
||||
t.Fatalf("Expected ErrBadSubscription error, got %v\n", err)
|
||||
}
|
||||
if _, _, err := sub.Pending(); err == nil || err != nats.ErrBadSubscription {
|
||||
t.Fatalf("Expected ErrBadSubscription error, got %v\n", err)
|
||||
}
|
||||
if _, _, err := sub.MaxPending(); err == nil || err != nats.ErrBadSubscription {
|
||||
t.Fatalf("Expected ErrBadSubscription error, got %v\n", err)
|
||||
}
|
||||
if err := sub.ClearMaxPending(); err == nil || err != nats.ErrBadSubscription {
|
||||
t.Fatalf("Expected ErrBadSubscription error, got %v\n", err)
|
||||
}
|
||||
if _, _, err := sub.PendingLimits(); err == nil || err != nats.ErrBadSubscription {
|
||||
t.Fatalf("Expected ErrBadSubscription error, got %v\n", err)
|
||||
}
|
||||
if err := sub.SetPendingLimits(1, 1); err == nil || err != nats.ErrBadSubscription {
|
||||
t.Fatalf("Expected ErrBadSubscription error, got %v\n", err)
|
||||
}
|
||||
if _, err := sub.Delivered(); err == nil || err != nats.ErrBadSubscription {
|
||||
t.Fatalf("Expected ErrBadSubscription error, got %v\n", err)
|
||||
}
|
||||
if _, err := sub.Dropped(); err == nil || err != nats.ErrBadSubscription {
|
||||
t.Fatalf("Expected ErrBadSubscription error, got %v\n", err)
|
||||
}
|
||||
}
|
153
gateway/vendor/github.com/nats-io/go-nats/test/bench_test.go
generated
vendored
Normal file
153
gateway/vendor/github.com/nats-io/go-nats/test/bench_test.go
generated
vendored
Normal file
@ -0,0 +1,153 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/nats-io/go-nats"
|
||||
)
|
||||
|
||||
func BenchmarkPublishSpeed(b *testing.B) {
|
||||
b.StopTimer()
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
nc := NewDefaultConnection(b)
|
||||
defer nc.Close()
|
||||
b.StartTimer()
|
||||
|
||||
msg := []byte("Hello World")
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
if err := nc.Publish("foo", msg); err != nil {
|
||||
b.Fatalf("Error in benchmark during Publish: %v\n", err)
|
||||
}
|
||||
}
|
||||
// Make sure they are all processed.
|
||||
nc.Flush()
|
||||
b.StopTimer()
|
||||
}
|
||||
|
||||
func BenchmarkPubSubSpeed(b *testing.B) {
|
||||
b.StopTimer()
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
nc := NewDefaultConnection(b)
|
||||
defer nc.Close()
|
||||
|
||||
ch := make(chan bool)
|
||||
|
||||
nc.SetErrorHandler(func(nc *nats.Conn, s *nats.Subscription, err error) {
|
||||
b.Fatalf("Error : %v\n", err)
|
||||
})
|
||||
|
||||
received := int32(0)
|
||||
|
||||
nc.Subscribe("foo", func(m *nats.Msg) {
|
||||
if nr := atomic.AddInt32(&received, 1); nr >= int32(b.N) {
|
||||
ch <- true
|
||||
}
|
||||
})
|
||||
|
||||
msg := []byte("Hello World")
|
||||
|
||||
b.StartTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
if err := nc.Publish("foo", msg); err != nil {
|
||||
b.Fatalf("Error in benchmark during Publish: %v\n", err)
|
||||
}
|
||||
// Don't overrun ourselves and be a slow consumer, server will cut us off
|
||||
if int32(i)-atomic.LoadInt32(&received) > 32768 {
|
||||
time.Sleep(100 * time.Nanosecond)
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure they are all processed.
|
||||
err := WaitTime(ch, 10*time.Second)
|
||||
if err != nil {
|
||||
b.Fatal("Timed out waiting for messages")
|
||||
} else if atomic.LoadInt32(&received) != int32(b.N) {
|
||||
b.Fatalf("Received: %d, err:%v", received, nc.LastError())
|
||||
}
|
||||
b.StopTimer()
|
||||
}
|
||||
|
||||
func BenchmarkAsyncSubscriptionCreationSpeed(b *testing.B) {
|
||||
b.StopTimer()
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
nc := NewDefaultConnection(b)
|
||||
defer nc.Close()
|
||||
b.StartTimer()
|
||||
b.ReportAllocs()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
nc.Subscribe("foo", func(m *nats.Msg) {})
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkSyncSubscriptionCreationSpeed(b *testing.B) {
|
||||
b.StopTimer()
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
nc := NewDefaultConnection(b)
|
||||
defer nc.Close()
|
||||
b.StartTimer()
|
||||
b.ReportAllocs()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
nc.SubscribeSync("foo")
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkInboxCreation(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
nats.NewInbox()
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkRequest(b *testing.B) {
|
||||
b.StopTimer()
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
nc := NewDefaultConnection(b)
|
||||
defer nc.Close()
|
||||
ok := []byte("ok")
|
||||
nc.Subscribe("req", func(m *nats.Msg) {
|
||||
nc.Publish(m.Reply, ok)
|
||||
})
|
||||
b.StartTimer()
|
||||
b.ReportAllocs()
|
||||
q := []byte("q")
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, err := nc.Request("req", q, 1*time.Second)
|
||||
if err != nil {
|
||||
b.Fatalf("Err %v\n", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkOldRequest(b *testing.B) {
|
||||
b.StopTimer()
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
nc, err := nats.Connect(nats.DefaultURL, nats.UseOldRequestStyle())
|
||||
if err != nil {
|
||||
b.Fatalf("Failed to connect: %v", err)
|
||||
}
|
||||
defer nc.Close()
|
||||
ok := []byte("ok")
|
||||
nc.Subscribe("req", func(m *nats.Msg) {
|
||||
nc.Publish(m.Reply, ok)
|
||||
})
|
||||
b.StartTimer()
|
||||
b.ReportAllocs()
|
||||
q := []byte("q")
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, err := nc.Request("req", q, 1*time.Second)
|
||||
if err != nil {
|
||||
b.Fatalf("Err %v\n", err)
|
||||
}
|
||||
}
|
||||
}
|
606
gateway/vendor/github.com/nats-io/go-nats/test/cluster_test.go
generated
vendored
Normal file
606
gateway/vendor/github.com/nats-io/go-nats/test/cluster_test.go
generated
vendored
Normal file
@ -0,0 +1,606 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"math"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/nats-io/gnatsd/test"
|
||||
"github.com/nats-io/go-nats"
|
||||
)
|
||||
|
||||
var testServers = []string{
|
||||
"nats://localhost:1222",
|
||||
"nats://localhost:1223",
|
||||
"nats://localhost:1224",
|
||||
"nats://localhost:1225",
|
||||
"nats://localhost:1226",
|
||||
"nats://localhost:1227",
|
||||
"nats://localhost:1228",
|
||||
}
|
||||
|
||||
var servers = strings.Join(testServers, ",")
|
||||
|
||||
func TestServersOption(t *testing.T) {
|
||||
opts := nats.GetDefaultOptions()
|
||||
opts.NoRandomize = true
|
||||
|
||||
_, err := opts.Connect()
|
||||
if err != nats.ErrNoServers {
|
||||
t.Fatalf("Wrong error: '%v'\n", err)
|
||||
}
|
||||
opts.Servers = testServers
|
||||
_, err = opts.Connect()
|
||||
if err == nil || err != nats.ErrNoServers {
|
||||
t.Fatalf("Did not receive proper error: %v\n", err)
|
||||
}
|
||||
|
||||
// Make sure we can connect to first server if running
|
||||
s1 := RunServerOnPort(1222)
|
||||
// Do this in case some failure occurs before explicit shutdown
|
||||
defer s1.Shutdown()
|
||||
|
||||
nc, err := opts.Connect()
|
||||
if err != nil {
|
||||
t.Fatalf("Could not connect: %v\n", err)
|
||||
}
|
||||
if nc.ConnectedUrl() != "nats://localhost:1222" {
|
||||
nc.Close()
|
||||
t.Fatalf("Does not report correct connection: %s\n",
|
||||
nc.ConnectedUrl())
|
||||
}
|
||||
nc.Close()
|
||||
s1.Shutdown()
|
||||
|
||||
// Make sure we can connect to a non first server if running
|
||||
s2 := RunServerOnPort(1223)
|
||||
// Do this in case some failure occurs before explicit shutdown
|
||||
defer s2.Shutdown()
|
||||
|
||||
nc, err = opts.Connect()
|
||||
if err != nil {
|
||||
t.Fatalf("Could not connect: %v\n", err)
|
||||
}
|
||||
defer nc.Close()
|
||||
if nc.ConnectedUrl() != "nats://localhost:1223" {
|
||||
t.Fatalf("Does not report correct connection: %s\n",
|
||||
nc.ConnectedUrl())
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewStyleServersOption(t *testing.T) {
|
||||
_, err := nats.Connect(nats.DefaultURL, nats.DontRandomize())
|
||||
if err != nats.ErrNoServers {
|
||||
t.Fatalf("Wrong error: '%v'\n", err)
|
||||
}
|
||||
servers := strings.Join(testServers, ",")
|
||||
|
||||
_, err = nats.Connect(servers, nats.DontRandomize())
|
||||
if err == nil || err != nats.ErrNoServers {
|
||||
t.Fatalf("Did not receive proper error: %v\n", err)
|
||||
}
|
||||
|
||||
// Make sure we can connect to first server if running
|
||||
s1 := RunServerOnPort(1222)
|
||||
// Do this in case some failure occurs before explicit shutdown
|
||||
defer s1.Shutdown()
|
||||
|
||||
nc, err := nats.Connect(servers, nats.DontRandomize())
|
||||
if err != nil {
|
||||
t.Fatalf("Could not connect: %v\n", err)
|
||||
}
|
||||
if nc.ConnectedUrl() != "nats://localhost:1222" {
|
||||
nc.Close()
|
||||
t.Fatalf("Does not report correct connection: %s\n",
|
||||
nc.ConnectedUrl())
|
||||
}
|
||||
nc.Close()
|
||||
s1.Shutdown()
|
||||
|
||||
// Make sure we can connect to a non-first server if running
|
||||
s2 := RunServerOnPort(1223)
|
||||
// Do this in case some failure occurs before explicit shutdown
|
||||
defer s2.Shutdown()
|
||||
|
||||
nc, err = nats.Connect(servers, nats.DontRandomize())
|
||||
if err != nil {
|
||||
t.Fatalf("Could not connect: %v\n", err)
|
||||
}
|
||||
defer nc.Close()
|
||||
if nc.ConnectedUrl() != "nats://localhost:1223" {
|
||||
t.Fatalf("Does not report correct connection: %s\n",
|
||||
nc.ConnectedUrl())
|
||||
}
|
||||
}
|
||||
|
||||
func TestAuthServers(t *testing.T) {
|
||||
var plainServers = []string{
|
||||
"nats://localhost:1222",
|
||||
"nats://localhost:1224",
|
||||
}
|
||||
|
||||
opts := test.DefaultTestOptions
|
||||
opts.Username = "derek"
|
||||
opts.Password = "foo"
|
||||
|
||||
opts.Port = 1222
|
||||
as1 := RunServerWithOptions(opts)
|
||||
defer as1.Shutdown()
|
||||
opts.Port = 1224
|
||||
as2 := RunServerWithOptions(opts)
|
||||
defer as2.Shutdown()
|
||||
|
||||
pservers := strings.Join(plainServers, ",")
|
||||
nc, err := nats.Connect(pservers, nats.DontRandomize(), nats.Timeout(5*time.Second))
|
||||
if err == nil {
|
||||
nc.Close()
|
||||
t.Fatalf("Expect Auth failure, got no error\n")
|
||||
}
|
||||
|
||||
if matched, _ := regexp.Match(`authorization`, []byte(err.Error())); !matched {
|
||||
t.Fatalf("Wrong error, wanted Auth failure, got '%s'\n", err)
|
||||
}
|
||||
|
||||
// Test that we can connect to a subsequent correct server.
|
||||
var authServers = []string{
|
||||
"nats://localhost:1222",
|
||||
"nats://derek:foo@localhost:1224",
|
||||
}
|
||||
aservers := strings.Join(authServers, ",")
|
||||
nc, err = nats.Connect(aservers, nats.DontRandomize(), nats.Timeout(5*time.Second))
|
||||
if err != nil {
|
||||
t.Fatalf("Expected to connect properly: %v\n", err)
|
||||
}
|
||||
defer nc.Close()
|
||||
if nc.ConnectedUrl() != authServers[1] {
|
||||
t.Fatalf("Does not report correct connection: %s\n",
|
||||
nc.ConnectedUrl())
|
||||
}
|
||||
}
|
||||
|
||||
func TestBasicClusterReconnect(t *testing.T) {
|
||||
s1 := RunServerOnPort(1222)
|
||||
defer s1.Shutdown()
|
||||
s2 := RunServerOnPort(1224)
|
||||
defer s2.Shutdown()
|
||||
|
||||
dch := make(chan bool)
|
||||
rch := make(chan bool)
|
||||
|
||||
dcbCalled := false
|
||||
|
||||
opts := []nats.Option{nats.DontRandomize(),
|
||||
nats.DisconnectHandler(func(nc *nats.Conn) {
|
||||
// Suppress any additional callbacks
|
||||
if dcbCalled {
|
||||
return
|
||||
}
|
||||
dcbCalled = true
|
||||
dch <- true
|
||||
}),
|
||||
nats.ReconnectHandler(func(_ *nats.Conn) { rch <- true }),
|
||||
}
|
||||
|
||||
nc, err := nats.Connect(servers, opts...)
|
||||
if err != nil {
|
||||
t.Fatalf("Expected to connect, got err: %v\n", err)
|
||||
}
|
||||
defer nc.Close()
|
||||
|
||||
s1.Shutdown()
|
||||
|
||||
// wait for disconnect
|
||||
if e := WaitTime(dch, 2*time.Second); e != nil {
|
||||
t.Fatal("Did not receive a disconnect callback message")
|
||||
}
|
||||
|
||||
reconnectTimeStart := time.Now()
|
||||
|
||||
// wait for reconnect
|
||||
if e := WaitTime(rch, 2*time.Second); e != nil {
|
||||
t.Fatal("Did not receive a reconnect callback message")
|
||||
}
|
||||
|
||||
if nc.ConnectedUrl() != testServers[2] {
|
||||
t.Fatalf("Does not report correct connection: %s\n",
|
||||
nc.ConnectedUrl())
|
||||
}
|
||||
|
||||
// Make sure we did not wait on reconnect for default time.
|
||||
// Reconnect should be fast since it will be a switch to the
|
||||
// second server and not be dependent on server restart time.
|
||||
|
||||
// On Windows, a failed connect takes more than a second, so
|
||||
// account for that.
|
||||
maxDuration := 100 * time.Millisecond
|
||||
if runtime.GOOS == "windows" {
|
||||
maxDuration = 1100 * time.Millisecond
|
||||
}
|
||||
reconnectTime := time.Since(reconnectTimeStart)
|
||||
if reconnectTime > maxDuration {
|
||||
t.Fatalf("Took longer than expected to reconnect: %v\n", reconnectTime)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHotSpotReconnect(t *testing.T) {
|
||||
s1 := RunServerOnPort(1222)
|
||||
defer s1.Shutdown()
|
||||
|
||||
var srvrs string
|
||||
if runtime.GOOS == "windows" {
|
||||
srvrs = strings.Join(testServers[:5], ",")
|
||||
} else {
|
||||
srvrs = servers
|
||||
}
|
||||
|
||||
numClients := 32
|
||||
clients := []*nats.Conn{}
|
||||
|
||||
wg := &sync.WaitGroup{}
|
||||
wg.Add(numClients)
|
||||
|
||||
opts := []nats.Option{
|
||||
nats.ReconnectWait(50 * time.Millisecond),
|
||||
nats.ReconnectHandler(func(_ *nats.Conn) { wg.Done() }),
|
||||
}
|
||||
|
||||
for i := 0; i < numClients; i++ {
|
||||
nc, err := nats.Connect(srvrs, opts...)
|
||||
if err != nil {
|
||||
t.Fatalf("Expected to connect, got err: %v\n", err)
|
||||
}
|
||||
defer nc.Close()
|
||||
if nc.ConnectedUrl() != testServers[0] {
|
||||
t.Fatalf("Connected to incorrect server: %v\n", nc.ConnectedUrl())
|
||||
}
|
||||
clients = append(clients, nc)
|
||||
}
|
||||
|
||||
s2 := RunServerOnPort(1224)
|
||||
defer s2.Shutdown()
|
||||
s3 := RunServerOnPort(1226)
|
||||
defer s3.Shutdown()
|
||||
|
||||
s1.Shutdown()
|
||||
|
||||
numServers := 2
|
||||
|
||||
// Wait on all reconnects
|
||||
wg.Wait()
|
||||
|
||||
// Walk the clients and calculate how many of each..
|
||||
cs := make(map[string]int)
|
||||
for _, nc := range clients {
|
||||
cs[nc.ConnectedUrl()]++
|
||||
nc.Close()
|
||||
}
|
||||
if len(cs) != numServers {
|
||||
t.Fatalf("Wrong number of reported servers: %d vs %d\n", len(cs), numServers)
|
||||
}
|
||||
expected := numClients / numServers
|
||||
v := uint(float32(expected) * 0.40)
|
||||
|
||||
// Check that each item is within acceptable range
|
||||
for s, total := range cs {
|
||||
delta := uint(math.Abs(float64(expected - total)))
|
||||
if delta > v {
|
||||
t.Fatalf("Connected clients to server: %s out of range: %d\n", s, total)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestProperReconnectDelay(t *testing.T) {
|
||||
s1 := RunServerOnPort(1222)
|
||||
defer s1.Shutdown()
|
||||
|
||||
var srvs string
|
||||
opts := nats.GetDefaultOptions()
|
||||
if runtime.GOOS == "windows" {
|
||||
srvs = strings.Join(testServers[:2], ",")
|
||||
} else {
|
||||
srvs = strings.Join(testServers, ",")
|
||||
}
|
||||
opts.NoRandomize = true
|
||||
|
||||
dcbCalled := false
|
||||
closedCbCalled := false
|
||||
dch := make(chan bool)
|
||||
|
||||
dcb := func(nc *nats.Conn) {
|
||||
// Suppress any additional calls
|
||||
if dcbCalled {
|
||||
return
|
||||
}
|
||||
dcbCalled = true
|
||||
dch <- true
|
||||
}
|
||||
|
||||
ccb := func(_ *nats.Conn) {
|
||||
closedCbCalled = true
|
||||
}
|
||||
|
||||
nc, err := nats.Connect(srvs, nats.DontRandomize(), nats.DisconnectHandler(dcb), nats.ClosedHandler(ccb))
|
||||
if err != nil {
|
||||
t.Fatalf("Expected to connect, got err: %v\n", err)
|
||||
}
|
||||
defer nc.Close()
|
||||
|
||||
s1.Shutdown()
|
||||
|
||||
// wait for disconnect
|
||||
if e := WaitTime(dch, 2*time.Second); e != nil {
|
||||
t.Fatal("Did not receive a disconnect callback message")
|
||||
}
|
||||
|
||||
// Wait, want to make sure we don't spin on reconnect to non-existent servers.
|
||||
time.Sleep(1 * time.Second)
|
||||
|
||||
// Make sure we are still reconnecting..
|
||||
if closedCbCalled {
|
||||
t.Fatal("Closed CB was triggered, should not have been.")
|
||||
}
|
||||
if status := nc.Status(); status != nats.RECONNECTING {
|
||||
t.Fatalf("Wrong status: %d\n", status)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProperFalloutAfterMaxAttempts(t *testing.T) {
|
||||
s1 := RunServerOnPort(1222)
|
||||
defer s1.Shutdown()
|
||||
|
||||
opts := nats.GetDefaultOptions()
|
||||
// Reduce the list of servers for Windows tests
|
||||
if runtime.GOOS == "windows" {
|
||||
opts.Servers = testServers[:2]
|
||||
opts.MaxReconnect = 2
|
||||
} else {
|
||||
opts.Servers = testServers
|
||||
opts.MaxReconnect = 5
|
||||
}
|
||||
opts.NoRandomize = true
|
||||
opts.ReconnectWait = (25 * time.Millisecond)
|
||||
|
||||
dch := make(chan bool)
|
||||
opts.DisconnectedCB = func(_ *nats.Conn) {
|
||||
dch <- true
|
||||
}
|
||||
|
||||
closedCbCalled := false
|
||||
cch := make(chan bool)
|
||||
|
||||
opts.ClosedCB = func(_ *nats.Conn) {
|
||||
closedCbCalled = true
|
||||
cch <- true
|
||||
}
|
||||
|
||||
nc, err := opts.Connect()
|
||||
if err != nil {
|
||||
t.Fatalf("Expected to connect, got err: %v\n", err)
|
||||
}
|
||||
defer nc.Close()
|
||||
|
||||
s1.Shutdown()
|
||||
|
||||
// On Windows, creating a TCP connection to a server not running takes more than
|
||||
// a second. So be generous with the WaitTime.
|
||||
|
||||
// wait for disconnect
|
||||
if e := WaitTime(dch, 5*time.Second); e != nil {
|
||||
t.Fatal("Did not receive a disconnect callback message")
|
||||
}
|
||||
|
||||
// Wait for ClosedCB
|
||||
if e := WaitTime(cch, 5*time.Second); e != nil {
|
||||
t.Fatal("Did not receive a closed callback message")
|
||||
}
|
||||
|
||||
// Make sure we are not still reconnecting..
|
||||
if !closedCbCalled {
|
||||
t.Logf("%+v\n", nc)
|
||||
t.Fatal("Closed CB was not triggered, should have been.")
|
||||
}
|
||||
|
||||
// Expect connection to be closed...
|
||||
if !nc.IsClosed() {
|
||||
t.Fatalf("Wrong status: %d\n", nc.Status())
|
||||
}
|
||||
}
|
||||
|
||||
func TestProperFalloutAfterMaxAttemptsWithAuthMismatch(t *testing.T) {
|
||||
var myServers = []string{
|
||||
"nats://localhost:1222",
|
||||
"nats://localhost:4443",
|
||||
}
|
||||
s1 := RunServerOnPort(1222)
|
||||
defer s1.Shutdown()
|
||||
|
||||
s2, _ := RunServerWithConfig("./configs/tlsverify.conf")
|
||||
defer s2.Shutdown()
|
||||
|
||||
opts := nats.GetDefaultOptions()
|
||||
opts.Servers = myServers
|
||||
opts.NoRandomize = true
|
||||
if runtime.GOOS == "windows" {
|
||||
opts.MaxReconnect = 2
|
||||
} else {
|
||||
opts.MaxReconnect = 5
|
||||
}
|
||||
opts.ReconnectWait = (25 * time.Millisecond)
|
||||
|
||||
dch := make(chan bool)
|
||||
opts.DisconnectedCB = func(_ *nats.Conn) {
|
||||
dch <- true
|
||||
}
|
||||
|
||||
closedCbCalled := false
|
||||
cch := make(chan bool)
|
||||
|
||||
opts.ClosedCB = func(_ *nats.Conn) {
|
||||
closedCbCalled = true
|
||||
cch <- true
|
||||
}
|
||||
|
||||
nc, err := opts.Connect()
|
||||
if err != nil {
|
||||
t.Fatalf("Expected to connect, got err: %v\n", err)
|
||||
}
|
||||
defer nc.Close()
|
||||
|
||||
s1.Shutdown()
|
||||
|
||||
// On Windows, creating a TCP connection to a server not running takes more than
|
||||
// a second. So be generous with the WaitTime.
|
||||
|
||||
// wait for disconnect
|
||||
if e := WaitTime(dch, 5*time.Second); e != nil {
|
||||
t.Fatal("Did not receive a disconnect callback message")
|
||||
}
|
||||
|
||||
// Wait for ClosedCB
|
||||
if e := WaitTime(cch, 5*time.Second); e != nil {
|
||||
reconnects := nc.Stats().Reconnects
|
||||
t.Fatalf("Did not receive a closed callback message, #reconnects: %v", reconnects)
|
||||
}
|
||||
|
||||
// Make sure we have not exceeded MaxReconnect
|
||||
reconnects := nc.Stats().Reconnects
|
||||
if reconnects != uint64(opts.MaxReconnect) {
|
||||
t.Fatalf("Num reconnects was %v, expected %v", reconnects, opts.MaxReconnect)
|
||||
}
|
||||
|
||||
// Make sure we are not still reconnecting..
|
||||
if !closedCbCalled {
|
||||
t.Logf("%+v\n", nc)
|
||||
t.Fatal("Closed CB was not triggered, should have been.")
|
||||
}
|
||||
|
||||
// Expect connection to be closed...
|
||||
if !nc.IsClosed() {
|
||||
t.Fatalf("Wrong status: %d\n", nc.Status())
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimeoutOnNoServers(t *testing.T) {
|
||||
s1 := RunServerOnPort(1222)
|
||||
defer s1.Shutdown()
|
||||
|
||||
opts := nats.GetDefaultOptions()
|
||||
if runtime.GOOS == "windows" {
|
||||
opts.Servers = testServers[:2]
|
||||
opts.MaxReconnect = 2
|
||||
opts.ReconnectWait = (100 * time.Millisecond)
|
||||
} else {
|
||||
opts.Servers = testServers
|
||||
// 1 second total time wait
|
||||
opts.MaxReconnect = 10
|
||||
opts.ReconnectWait = (100 * time.Millisecond)
|
||||
}
|
||||
opts.NoRandomize = true
|
||||
|
||||
dch := make(chan bool)
|
||||
opts.DisconnectedCB = func(nc *nats.Conn) {
|
||||
// Suppress any additional calls
|
||||
nc.SetDisconnectHandler(nil)
|
||||
dch <- true
|
||||
}
|
||||
|
||||
cch := make(chan bool)
|
||||
opts.ClosedCB = func(_ *nats.Conn) {
|
||||
cch <- true
|
||||
}
|
||||
|
||||
nc, err := opts.Connect()
|
||||
if err != nil {
|
||||
t.Fatalf("Expected to connect, got err: %v\n", err)
|
||||
}
|
||||
defer nc.Close()
|
||||
|
||||
s1.Shutdown()
|
||||
|
||||
// On Windows, creating a connection to a non-running server takes
|
||||
// more than a second. So be generous with WaitTime
|
||||
|
||||
// wait for disconnect
|
||||
if e := WaitTime(dch, 5*time.Second); e != nil {
|
||||
t.Fatal("Did not receive a disconnect callback message")
|
||||
}
|
||||
|
||||
startWait := time.Now()
|
||||
|
||||
// Wait for ClosedCB
|
||||
if e := WaitTime(cch, 5*time.Second); e != nil {
|
||||
t.Fatal("Did not receive a closed callback message")
|
||||
}
|
||||
|
||||
if runtime.GOOS != "windows" {
|
||||
timeWait := time.Since(startWait)
|
||||
|
||||
// Use 500ms as variable time delta
|
||||
variable := (500 * time.Millisecond)
|
||||
expected := (time.Duration(opts.MaxReconnect) * opts.ReconnectWait)
|
||||
|
||||
if timeWait > (expected + variable) {
|
||||
t.Fatalf("Waited too long for Closed state: %d\n", timeWait/time.Millisecond)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPingReconnect(t *testing.T) {
|
||||
RECONNECTS := 4
|
||||
s1 := RunServerOnPort(1222)
|
||||
defer s1.Shutdown()
|
||||
|
||||
opts := nats.GetDefaultOptions()
|
||||
opts.Servers = testServers
|
||||
opts.NoRandomize = true
|
||||
opts.ReconnectWait = 200 * time.Millisecond
|
||||
opts.PingInterval = 50 * time.Millisecond
|
||||
opts.MaxPingsOut = -1
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
rch := make(chan time.Time, RECONNECTS)
|
||||
dch := make(chan time.Time, RECONNECTS)
|
||||
|
||||
opts.DisconnectedCB = func(_ *nats.Conn) {
|
||||
d := dch
|
||||
select {
|
||||
case d <- time.Now():
|
||||
default:
|
||||
d = nil
|
||||
}
|
||||
}
|
||||
|
||||
opts.ReconnectedCB = func(c *nats.Conn) {
|
||||
r := rch
|
||||
select {
|
||||
case r <- time.Now():
|
||||
default:
|
||||
r = nil
|
||||
wg.Done()
|
||||
}
|
||||
}
|
||||
|
||||
nc, err := opts.Connect()
|
||||
if err != nil {
|
||||
t.Fatalf("Expected to connect, got err: %v\n", err)
|
||||
}
|
||||
defer nc.Close()
|
||||
|
||||
wg.Wait()
|
||||
s1.Shutdown()
|
||||
|
||||
<-dch
|
||||
for i := 0; i < RECONNECTS-1; i++ {
|
||||
disconnectedAt := <-dch
|
||||
reconnectAt := <-rch
|
||||
pingCycle := disconnectedAt.Sub(reconnectAt)
|
||||
if pingCycle > 2*opts.PingInterval {
|
||||
t.Fatalf("Reconnect due to ping took %s", pingCycle.String())
|
||||
}
|
||||
}
|
||||
}
|
38
gateway/vendor/github.com/nats-io/go-nats/test/configs/certs/ca.pem
generated
vendored
Normal file
38
gateway/vendor/github.com/nats-io/go-nats/test/configs/certs/ca.pem
generated
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
+Svp
|
||||
-----END CERTIFICATE-----
|
30
gateway/vendor/github.com/nats-io/go-nats/test/configs/certs/client-cert.pem
generated
vendored
Normal file
30
gateway/vendor/github.com/nats-io/go-nats/test/configs/certs/client-cert.pem
generated
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
-----END CERTIFICATE-----
|
51
gateway/vendor/github.com/nats-io/go-nats/test/configs/certs/client-key.pem
generated
vendored
Normal file
51
gateway/vendor/github.com/nats-io/go-nats/test/configs/certs/client-key.pem
generated
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
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
|
||||
-----END RSA PRIVATE KEY-----
|
51
gateway/vendor/github.com/nats-io/go-nats/test/configs/certs/key.pem
generated
vendored
Normal file
51
gateway/vendor/github.com/nats-io/go-nats/test/configs/certs/key.pem
generated
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
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
|
||||
-----END RSA PRIVATE KEY-----
|
31
gateway/vendor/github.com/nats-io/go-nats/test/configs/certs/server.pem
generated
vendored
Normal file
31
gateway/vendor/github.com/nats-io/go-nats/test/configs/certs/server.pem
generated
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
NiZPnqA=
|
||||
-----END CERTIFICATE-----
|
17
gateway/vendor/github.com/nats-io/go-nats/test/configs/tls.conf
generated
vendored
Normal file
17
gateway/vendor/github.com/nats-io/go-nats/test/configs/tls.conf
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
|
||||
# Simple TLS config file
|
||||
|
||||
port: 4443
|
||||
net: localhost # net interface
|
||||
|
||||
tls {
|
||||
cert_file: "./configs/certs/server.pem"
|
||||
key_file: "./configs/certs/key.pem"
|
||||
timeout: 2
|
||||
}
|
||||
|
||||
authorization {
|
||||
user: derek
|
||||
password: buckley
|
||||
timeout: 1
|
||||
}
|
17
gateway/vendor/github.com/nats-io/go-nats/test/configs/tlsverify.conf
generated
vendored
Normal file
17
gateway/vendor/github.com/nats-io/go-nats/test/configs/tlsverify.conf
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
|
||||
# Simple TLS config file
|
||||
|
||||
port: 4443
|
||||
net: localhost
|
||||
|
||||
tls {
|
||||
cert_file: "./configs/certs/server.pem"
|
||||
key_file: "./configs/certs/key.pem"
|
||||
timeout: 2
|
||||
|
||||
# Optional certificate authority for clients
|
||||
ca_file: "./configs/certs/ca.pem"
|
||||
|
||||
# Require a client certificate
|
||||
verify: true
|
||||
}
|
1545
gateway/vendor/github.com/nats-io/go-nats/test/conn_test.go
generated
vendored
Normal file
1545
gateway/vendor/github.com/nats-io/go-nats/test/conn_test.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
999
gateway/vendor/github.com/nats-io/go-nats/test/context_test.go
generated
vendored
Normal file
999
gateway/vendor/github.com/nats-io/go-nats/test/context_test.go
generated
vendored
Normal file
@ -0,0 +1,999 @@
|
||||
// Copyright 2012-2017 Apcera Inc. All rights reserved.
|
||||
|
||||
// +build go1.7
|
||||
|
||||
package test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/nats-io/go-nats"
|
||||
)
|
||||
|
||||
func TestContextRequestWithNilConnection(t *testing.T) {
|
||||
var nc *nats.Conn
|
||||
|
||||
ctx, cancelCB := context.WithTimeout(context.Background(), 100*time.Millisecond)
|
||||
defer cancelCB() // should always be called, not discarded, to prevent context leak
|
||||
|
||||
_, err := nc.RequestWithContext(ctx, "fast", []byte(""))
|
||||
if err == nil {
|
||||
t.Fatalf("Expected request with context and nil connection to fail\n")
|
||||
}
|
||||
if err != nats.ErrInvalidConnection {
|
||||
t.Fatalf("Expected nats.ErrInvalidConnection, got %v\n", err)
|
||||
}
|
||||
}
|
||||
|
||||
func testContextRequestWithTimeout(t *testing.T, nc *nats.Conn) {
|
||||
nc.Subscribe("slow", func(m *nats.Msg) {
|
||||
// Simulates latency into the client so that timeout is hit.
|
||||
time.Sleep(200 * time.Millisecond)
|
||||
nc.Publish(m.Reply, []byte("NG"))
|
||||
})
|
||||
nc.Subscribe("fast", func(m *nats.Msg) {
|
||||
nc.Publish(m.Reply, []byte("OK"))
|
||||
})
|
||||
|
||||
ctx, cancelCB := context.WithTimeout(context.Background(), 100*time.Millisecond)
|
||||
defer cancelCB() // should always be called, not discarded, to prevent context leak
|
||||
|
||||
// Fast request should not fail at this point.
|
||||
resp, err := nc.RequestWithContext(ctx, "fast", []byte(""))
|
||||
if err != nil {
|
||||
t.Fatalf("Expected request with context to not fail on fast response: %s", err)
|
||||
}
|
||||
got := string(resp.Data)
|
||||
expected := "OK"
|
||||
if got != expected {
|
||||
t.Errorf("Expected to receive %s, got: %s", expected, got)
|
||||
}
|
||||
|
||||
// Slow request hits timeout so expected to fail.
|
||||
_, err = nc.RequestWithContext(ctx, "slow", []byte("world"))
|
||||
if err == nil {
|
||||
t.Fatalf("Expected request with timeout context to fail: %s", err)
|
||||
}
|
||||
|
||||
// Reported error is "context deadline exceeded" from Context package,
|
||||
// which implements net.Error interface.
|
||||
type timeoutError interface {
|
||||
Timeout() bool
|
||||
}
|
||||
timeoutErr, ok := err.(timeoutError)
|
||||
if !ok || !timeoutErr.Timeout() {
|
||||
t.Errorf("Expected to have a timeout error")
|
||||
}
|
||||
expected = `context deadline exceeded`
|
||||
if !strings.Contains(err.Error(), expected) {
|
||||
t.Errorf("Expected %q error, got: %q", expected, err.Error())
|
||||
}
|
||||
|
||||
// 2nd request should fail again even if they would be fast because context
|
||||
// has already timed out.
|
||||
_, err = nc.RequestWithContext(ctx, "fast", []byte("world"))
|
||||
if err == nil {
|
||||
t.Fatalf("Expected request with context to fail: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestContextRequestWithTimeout(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
|
||||
nc := NewDefaultConnection(t)
|
||||
defer nc.Close()
|
||||
|
||||
testContextRequestWithTimeout(t, nc)
|
||||
}
|
||||
|
||||
func TestOldContextRequestWithTimeout(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
|
||||
nc, err := nats.Connect(nats.DefaultURL, nats.UseOldRequestStyle())
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to connect: %v", err)
|
||||
}
|
||||
defer nc.Close()
|
||||
|
||||
testContextRequestWithTimeout(t, nc)
|
||||
}
|
||||
|
||||
func testContextRequestWithTimeoutCanceled(t *testing.T, nc *nats.Conn) {
|
||||
ctx, cancelCB := context.WithTimeout(context.Background(), 100*time.Millisecond)
|
||||
defer cancelCB()
|
||||
|
||||
nc.Subscribe("fast", func(m *nats.Msg) {
|
||||
nc.Publish(m.Reply, []byte("OK"))
|
||||
})
|
||||
|
||||
// Fast request should not fail
|
||||
resp, err := nc.RequestWithContext(ctx, "fast", []byte(""))
|
||||
if err != nil {
|
||||
t.Fatalf("Expected request with context to not fail on fast response: %s", err)
|
||||
}
|
||||
got := string(resp.Data)
|
||||
expected := "OK"
|
||||
if got != expected {
|
||||
t.Errorf("Expected to receive %s, got: %s", expected, got)
|
||||
}
|
||||
|
||||
// Cancel the context already so that rest of requests fail.
|
||||
cancelCB()
|
||||
|
||||
_, err = nc.RequestWithContext(ctx, "fast", []byte("world"))
|
||||
if err == nil {
|
||||
t.Fatalf("Expected request with timeout context to fail: %s", err)
|
||||
}
|
||||
|
||||
// Reported error is "context canceled" from Context package,
|
||||
// which is not a timeout error.
|
||||
type timeoutError interface {
|
||||
Timeout() bool
|
||||
}
|
||||
if _, ok := err.(timeoutError); ok {
|
||||
t.Errorf("Expected to not have a timeout error")
|
||||
}
|
||||
expected = `context canceled`
|
||||
if !strings.Contains(err.Error(), expected) {
|
||||
t.Errorf("Expected %q error, got: %q", expected, err.Error())
|
||||
}
|
||||
|
||||
// 2nd request should fail again even if fast because context has already been canceled
|
||||
_, err = nc.RequestWithContext(ctx, "fast", []byte("world"))
|
||||
if err == nil {
|
||||
t.Fatalf("Expected request with context to fail: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestContextRequestWithTimeoutCanceled(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
|
||||
nc := NewDefaultConnection(t)
|
||||
defer nc.Close()
|
||||
|
||||
testContextRequestWithTimeoutCanceled(t, nc)
|
||||
}
|
||||
|
||||
func TestOldContextRequestWithTimeoutCanceled(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
|
||||
nc, err := nats.Connect(nats.DefaultURL, nats.UseOldRequestStyle())
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to connect: %v", err)
|
||||
}
|
||||
defer nc.Close()
|
||||
|
||||
testContextRequestWithTimeoutCanceled(t, nc)
|
||||
}
|
||||
|
||||
func testContextRequestWithCancel(t *testing.T, nc *nats.Conn) {
|
||||
ctx, cancelCB := context.WithCancel(context.Background())
|
||||
defer cancelCB() // should always be called, not discarded, to prevent context leak
|
||||
|
||||
// timer which cancels the context though can also be arbitrarily extended
|
||||
expirationTimer := time.AfterFunc(100*time.Millisecond, func() {
|
||||
cancelCB()
|
||||
})
|
||||
|
||||
nc.Subscribe("slow", func(m *nats.Msg) {
|
||||
// simulates latency into the client so that timeout is hit.
|
||||
time.Sleep(40 * time.Millisecond)
|
||||
nc.Publish(m.Reply, []byte("OK"))
|
||||
})
|
||||
nc.Subscribe("slower", func(m *nats.Msg) {
|
||||
// we know this request will take longer so extend the timeout
|
||||
expirationTimer.Reset(100 * time.Millisecond)
|
||||
|
||||
// slower reply which would have hit original timeout
|
||||
time.Sleep(90 * time.Millisecond)
|
||||
|
||||
nc.Publish(m.Reply, []byte("Also OK"))
|
||||
})
|
||||
|
||||
for i := 0; i < 2; i++ {
|
||||
resp, err := nc.RequestWithContext(ctx, "slow", []byte(""))
|
||||
if err != nil {
|
||||
t.Fatalf("Expected request with context to not fail: %s", err)
|
||||
}
|
||||
got := string(resp.Data)
|
||||
expected := "OK"
|
||||
if got != expected {
|
||||
t.Errorf("Expected to receive %s, got: %s", expected, got)
|
||||
}
|
||||
}
|
||||
|
||||
// A third request with latency would make the context
|
||||
// get canceled, but these reset the timer so deadline
|
||||
// gets extended:
|
||||
for i := 0; i < 10; i++ {
|
||||
resp, err := nc.RequestWithContext(ctx, "slower", []byte(""))
|
||||
if err != nil {
|
||||
t.Fatalf("Expected request with context to not fail: %s", err)
|
||||
}
|
||||
got := string(resp.Data)
|
||||
expected := "Also OK"
|
||||
if got != expected {
|
||||
t.Errorf("Expected to receive %s, got: %s", expected, got)
|
||||
}
|
||||
}
|
||||
|
||||
// One more slow request will expire the timer and cause an error...
|
||||
_, err := nc.RequestWithContext(ctx, "slow", []byte(""))
|
||||
if err == nil {
|
||||
t.Fatalf("Expected request with cancellation context to fail: %s", err)
|
||||
}
|
||||
|
||||
// ...though reported error is "context canceled" from Context package,
|
||||
// which is not a timeout error.
|
||||
type timeoutError interface {
|
||||
Timeout() bool
|
||||
}
|
||||
if _, ok := err.(timeoutError); ok {
|
||||
t.Errorf("Expected to not have a timeout error")
|
||||
}
|
||||
expected := `context canceled`
|
||||
if !strings.Contains(err.Error(), expected) {
|
||||
t.Errorf("Expected %q error, got: %q", expected, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func TestContextRequestWithCancel(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
|
||||
nc := NewDefaultConnection(t)
|
||||
defer nc.Close()
|
||||
|
||||
testContextRequestWithCancel(t, nc)
|
||||
}
|
||||
|
||||
func TestOldContextRequestWithCancel(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
|
||||
nc, err := nats.Connect(nats.DefaultURL, nats.UseOldRequestStyle())
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to connect: %v", err)
|
||||
}
|
||||
defer nc.Close()
|
||||
|
||||
testContextRequestWithCancel(t, nc)
|
||||
}
|
||||
|
||||
func testContextRequestWithDeadline(t *testing.T, nc *nats.Conn) {
|
||||
deadline := time.Now().Add(100 * time.Millisecond)
|
||||
ctx, cancelCB := context.WithDeadline(context.Background(), deadline)
|
||||
defer cancelCB() // should always be called, not discarded, to prevent context leak
|
||||
|
||||
nc.Subscribe("slow", func(m *nats.Msg) {
|
||||
// simulates latency into the client so that timeout is hit.
|
||||
time.Sleep(40 * time.Millisecond)
|
||||
nc.Publish(m.Reply, []byte("OK"))
|
||||
})
|
||||
|
||||
for i := 0; i < 2; i++ {
|
||||
resp, err := nc.RequestWithContext(ctx, "slow", []byte(""))
|
||||
if err != nil {
|
||||
t.Fatalf("Expected request with context to not fail: %s", err)
|
||||
}
|
||||
got := string(resp.Data)
|
||||
expected := "OK"
|
||||
if got != expected {
|
||||
t.Errorf("Expected to receive %s, got: %s", expected, got)
|
||||
}
|
||||
}
|
||||
|
||||
// A third request with latency would make the context
|
||||
// reach the deadline.
|
||||
_, err := nc.RequestWithContext(ctx, "slow", []byte(""))
|
||||
if err == nil {
|
||||
t.Fatalf("Expected request with context to reach deadline: %s", err)
|
||||
}
|
||||
|
||||
// Reported error is "context deadline exceeded" from Context package,
|
||||
// which implements net.Error Timeout interface.
|
||||
type timeoutError interface {
|
||||
Timeout() bool
|
||||
}
|
||||
timeoutErr, ok := err.(timeoutError)
|
||||
if !ok || !timeoutErr.Timeout() {
|
||||
t.Errorf("Expected to have a timeout error")
|
||||
}
|
||||
expected := `context deadline exceeded`
|
||||
if !strings.Contains(err.Error(), expected) {
|
||||
t.Errorf("Expected %q error, got: %q", expected, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func TestContextRequestWithDeadline(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
|
||||
nc := NewDefaultConnection(t)
|
||||
defer nc.Close()
|
||||
|
||||
testContextRequestWithDeadline(t, nc)
|
||||
}
|
||||
|
||||
func TestOldContextRequestWithDeadline(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
|
||||
nc, err := nats.Connect(nats.DefaultURL, nats.UseOldRequestStyle())
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to connect: %v", err)
|
||||
}
|
||||
defer nc.Close()
|
||||
|
||||
testContextRequestWithDeadline(t, nc)
|
||||
}
|
||||
|
||||
func TestContextSubNextMsgWithTimeout(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
|
||||
nc := NewDefaultConnection(t)
|
||||
defer nc.Close()
|
||||
|
||||
ctx, cancelCB := context.WithTimeout(context.Background(), 100*time.Millisecond)
|
||||
defer cancelCB() // should always be called, not discarded, to prevent context leak
|
||||
|
||||
sub, err := nc.SubscribeSync("slow")
|
||||
if err != nil {
|
||||
t.Fatalf("Expected to be able to subscribe: %s", err)
|
||||
}
|
||||
|
||||
for i := 0; i < 2; i++ {
|
||||
err := nc.Publish("slow", []byte("OK"))
|
||||
if err != nil {
|
||||
t.Fatalf("Expected publish to not fail: %s", err)
|
||||
}
|
||||
// Enough time to get a couple of messages
|
||||
time.Sleep(40 * time.Millisecond)
|
||||
|
||||
msg, err := sub.NextMsgWithContext(ctx)
|
||||
if err != nil {
|
||||
t.Fatalf("Expected to receive message: %s", err)
|
||||
}
|
||||
got := string(msg.Data)
|
||||
expected := "OK"
|
||||
if got != expected {
|
||||
t.Errorf("Expected to receive %s, got: %s", expected, got)
|
||||
}
|
||||
}
|
||||
|
||||
// Third message will fail because the context will be canceled by now
|
||||
_, err = sub.NextMsgWithContext(ctx)
|
||||
if err == nil {
|
||||
t.Fatalf("Expected to fail receiving a message: %s", err)
|
||||
}
|
||||
|
||||
// Reported error is "context deadline exceeded" from Context package,
|
||||
// which implements net.Error Timeout interface.
|
||||
type timeoutError interface {
|
||||
Timeout() bool
|
||||
}
|
||||
timeoutErr, ok := err.(timeoutError)
|
||||
if !ok || !timeoutErr.Timeout() {
|
||||
t.Errorf("Expected to have a timeout error")
|
||||
}
|
||||
expected := `context deadline exceeded`
|
||||
if !strings.Contains(err.Error(), expected) {
|
||||
t.Errorf("Expected %q error, got: %q", expected, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func TestContextSubNextMsgWithTimeoutCanceled(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
|
||||
nc := NewDefaultConnection(t)
|
||||
defer nc.Close()
|
||||
|
||||
ctx, cancelCB := context.WithTimeout(context.Background(), 100*time.Millisecond)
|
||||
defer cancelCB() // should always be called, not discarded, to prevent context leak
|
||||
|
||||
sub, err := nc.SubscribeSync("fast")
|
||||
if err != nil {
|
||||
t.Fatalf("Expected to be able to subscribe: %s", err)
|
||||
}
|
||||
|
||||
for i := 0; i < 2; i++ {
|
||||
err := nc.Publish("fast", []byte("OK"))
|
||||
if err != nil {
|
||||
t.Fatalf("Expected publish to not fail: %s", err)
|
||||
}
|
||||
// Enough time to get a couple of messages
|
||||
time.Sleep(40 * time.Millisecond)
|
||||
|
||||
msg, err := sub.NextMsgWithContext(ctx)
|
||||
if err != nil {
|
||||
t.Fatalf("Expected to receive message: %s", err)
|
||||
}
|
||||
got := string(msg.Data)
|
||||
expected := "OK"
|
||||
if got != expected {
|
||||
t.Errorf("Expected to receive %s, got: %s", expected, got)
|
||||
}
|
||||
}
|
||||
|
||||
// Cancel the context already so that rest of NextMsg calls fail.
|
||||
cancelCB()
|
||||
|
||||
_, err = sub.NextMsgWithContext(ctx)
|
||||
if err == nil {
|
||||
t.Fatalf("Expected request with timeout context to fail: %s", err)
|
||||
}
|
||||
|
||||
// Reported error is "context canceled" from Context package,
|
||||
// which is not a timeout error.
|
||||
type timeoutError interface {
|
||||
Timeout() bool
|
||||
}
|
||||
if _, ok := err.(timeoutError); ok {
|
||||
t.Errorf("Expected to not have a timeout error")
|
||||
}
|
||||
expected := `context canceled`
|
||||
if !strings.Contains(err.Error(), expected) {
|
||||
t.Errorf("Expected %q error, got: %q", expected, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func TestContextSubNextMsgWithCancel(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
|
||||
nc := NewDefaultConnection(t)
|
||||
defer nc.Close()
|
||||
|
||||
ctx, cancelCB := context.WithCancel(context.Background())
|
||||
defer cancelCB() // should always be called, not discarded, to prevent context leak
|
||||
|
||||
// timer which cancels the context though can also be arbitrarily extended
|
||||
time.AfterFunc(100*time.Millisecond, func() {
|
||||
cancelCB()
|
||||
})
|
||||
|
||||
sub1, err := nc.SubscribeSync("foo")
|
||||
if err != nil {
|
||||
t.Fatalf("Expected to be able to subscribe: %s", err)
|
||||
}
|
||||
sub2, err := nc.SubscribeSync("bar")
|
||||
if err != nil {
|
||||
t.Fatalf("Expected to be able to subscribe: %s", err)
|
||||
}
|
||||
|
||||
for i := 0; i < 2; i++ {
|
||||
err := nc.Publish("foo", []byte("OK"))
|
||||
if err != nil {
|
||||
t.Fatalf("Expected publish to not fail: %s", err)
|
||||
}
|
||||
resp, err := sub1.NextMsgWithContext(ctx)
|
||||
if err != nil {
|
||||
t.Fatalf("Expected request with context to not fail: %s", err)
|
||||
}
|
||||
got := string(resp.Data)
|
||||
expected := "OK"
|
||||
if got != expected {
|
||||
t.Errorf("Expected to receive %s, got: %s", expected, got)
|
||||
}
|
||||
}
|
||||
err = nc.Publish("bar", []byte("Also OK"))
|
||||
if err != nil {
|
||||
t.Fatalf("Expected publish to not fail: %s", err)
|
||||
}
|
||||
|
||||
resp, err := sub2.NextMsgWithContext(ctx)
|
||||
if err != nil {
|
||||
t.Fatalf("Expected request with context to not fail: %s", err)
|
||||
}
|
||||
got := string(resp.Data)
|
||||
expected := "Also OK"
|
||||
if got != expected {
|
||||
t.Errorf("Expected to receive %s, got: %s", expected, got)
|
||||
}
|
||||
|
||||
// We do not have another message pending so timer will
|
||||
// cancel the context.
|
||||
_, err = sub2.NextMsgWithContext(ctx)
|
||||
if err == nil {
|
||||
t.Fatalf("Expected request with context to fail: %s", err)
|
||||
}
|
||||
|
||||
// Reported error is "context canceled" from Context package,
|
||||
// which is not a timeout error.
|
||||
type timeoutError interface {
|
||||
Timeout() bool
|
||||
}
|
||||
if _, ok := err.(timeoutError); ok {
|
||||
t.Errorf("Expected to not have a timeout error")
|
||||
}
|
||||
expected = `context canceled`
|
||||
if !strings.Contains(err.Error(), expected) {
|
||||
t.Errorf("Expected %q error, got: %q", expected, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func TestContextSubNextMsgWithDeadline(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
|
||||
nc := NewDefaultConnection(t)
|
||||
defer nc.Close()
|
||||
|
||||
deadline := time.Now().Add(100 * time.Millisecond)
|
||||
ctx, cancelCB := context.WithDeadline(context.Background(), deadline)
|
||||
defer cancelCB() // should always be called, not discarded, to prevent context leak
|
||||
|
||||
sub, err := nc.SubscribeSync("slow")
|
||||
if err != nil {
|
||||
t.Fatalf("Expected to be able to subscribe: %s", err)
|
||||
}
|
||||
|
||||
for i := 0; i < 2; i++ {
|
||||
err := nc.Publish("slow", []byte("OK"))
|
||||
if err != nil {
|
||||
t.Fatalf("Expected publish to not fail: %s", err)
|
||||
}
|
||||
// Enough time to get a couple of messages
|
||||
time.Sleep(40 * time.Millisecond)
|
||||
|
||||
msg, err := sub.NextMsgWithContext(ctx)
|
||||
if err != nil {
|
||||
t.Fatalf("Expected to receive message: %s", err)
|
||||
}
|
||||
got := string(msg.Data)
|
||||
expected := "OK"
|
||||
if got != expected {
|
||||
t.Errorf("Expected to receive %s, got: %s", expected, got)
|
||||
}
|
||||
}
|
||||
|
||||
// Third message will fail because the context will be canceled by now
|
||||
_, err = sub.NextMsgWithContext(ctx)
|
||||
if err == nil {
|
||||
t.Fatalf("Expected to fail receiving a message: %s", err)
|
||||
}
|
||||
|
||||
// Reported error is "context deadline exceeded" from Context package,
|
||||
// which implements net.Error Timeout interface.
|
||||
type timeoutError interface {
|
||||
Timeout() bool
|
||||
}
|
||||
timeoutErr, ok := err.(timeoutError)
|
||||
if !ok || !timeoutErr.Timeout() {
|
||||
t.Errorf("Expected to have a timeout error")
|
||||
}
|
||||
expected := `context deadline exceeded`
|
||||
if !strings.Contains(err.Error(), expected) {
|
||||
t.Errorf("Expected %q error, got: %q", expected, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func TestContextEncodedRequestWithTimeout(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
|
||||
nc := NewDefaultConnection(t)
|
||||
c, err := nats.NewEncodedConn(nc, nats.JSON_ENCODER)
|
||||
if err != nil {
|
||||
t.Fatalf("Unable to create encoded connection: %v", err)
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
deadline := time.Now().Add(100 * time.Millisecond)
|
||||
ctx, cancelCB := context.WithDeadline(context.Background(), deadline)
|
||||
defer cancelCB() // should always be called, not discarded, to prevent context leak
|
||||
|
||||
type request struct {
|
||||
Message string `json:"message"`
|
||||
}
|
||||
type response struct {
|
||||
Code int `json:"code"`
|
||||
}
|
||||
c.Subscribe("slow", func(_, reply string, req *request) {
|
||||
got := req.Message
|
||||
expected := "Hello"
|
||||
if got != expected {
|
||||
t.Errorf("Expected to receive request with %q, got %q", got, expected)
|
||||
}
|
||||
|
||||
// simulates latency into the client so that timeout is hit.
|
||||
time.Sleep(40 * time.Millisecond)
|
||||
c.Publish(reply, &response{Code: 200})
|
||||
})
|
||||
|
||||
for i := 0; i < 2; i++ {
|
||||
req := &request{Message: "Hello"}
|
||||
resp := &response{}
|
||||
err := c.RequestWithContext(ctx, "slow", req, resp)
|
||||
if err != nil {
|
||||
t.Fatalf("Expected encoded request with context to not fail: %s", err)
|
||||
}
|
||||
got := resp.Code
|
||||
expected := 200
|
||||
if got != expected {
|
||||
t.Errorf("Expected to receive %v, got: %v", expected, got)
|
||||
}
|
||||
}
|
||||
|
||||
// A third request with latency would make the context
|
||||
// reach the deadline.
|
||||
req := &request{Message: "Hello"}
|
||||
resp := &response{}
|
||||
err = c.RequestWithContext(ctx, "slow", req, resp)
|
||||
if err == nil {
|
||||
t.Fatalf("Expected request with context to reach deadline: %s", err)
|
||||
}
|
||||
|
||||
// Reported error is "context deadline exceeded" from Context package,
|
||||
// which implements net.Error Timeout interface.
|
||||
type timeoutError interface {
|
||||
Timeout() bool
|
||||
}
|
||||
timeoutErr, ok := err.(timeoutError)
|
||||
if !ok || !timeoutErr.Timeout() {
|
||||
t.Errorf("Expected to have a timeout error")
|
||||
}
|
||||
expected := `context deadline exceeded`
|
||||
if !strings.Contains(err.Error(), expected) {
|
||||
t.Errorf("Expected %q error, got: %q", expected, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func TestContextEncodedRequestWithTimeoutCanceled(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
|
||||
nc := NewDefaultConnection(t)
|
||||
c, err := nats.NewEncodedConn(nc, nats.JSON_ENCODER)
|
||||
if err != nil {
|
||||
t.Fatalf("Unable to create encoded connection: %v", err)
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
ctx, cancelCB := context.WithTimeout(context.Background(), 100*time.Millisecond)
|
||||
defer cancelCB() // should always be called, not discarded, to prevent context leak
|
||||
|
||||
type request struct {
|
||||
Message string `json:"message"`
|
||||
}
|
||||
type response struct {
|
||||
Code int `json:"code"`
|
||||
}
|
||||
|
||||
c.Subscribe("fast", func(_, reply string, req *request) {
|
||||
got := req.Message
|
||||
expected := "Hello"
|
||||
if got != expected {
|
||||
t.Errorf("Expected to receive request with %q, got %q", got, expected)
|
||||
}
|
||||
|
||||
// simulates latency into the client so that timeout is hit.
|
||||
time.Sleep(40 * time.Millisecond)
|
||||
|
||||
c.Publish(reply, &response{Code: 200})
|
||||
})
|
||||
|
||||
// Fast request should not fail
|
||||
req := &request{Message: "Hello"}
|
||||
resp := &response{}
|
||||
c.RequestWithContext(ctx, "fast", req, resp)
|
||||
expectedCode := 200
|
||||
if resp.Code != expectedCode {
|
||||
t.Errorf("Expected to receive %d, got: %d", expectedCode, resp.Code)
|
||||
}
|
||||
|
||||
// Cancel the context already so that rest of requests fail.
|
||||
cancelCB()
|
||||
|
||||
err = c.RequestWithContext(ctx, "fast", req, resp)
|
||||
if err == nil {
|
||||
t.Fatalf("Expected request with timeout context to fail: %s", err)
|
||||
}
|
||||
|
||||
// Reported error is "context canceled" from Context package,
|
||||
// which is not a timeout error.
|
||||
type timeoutError interface {
|
||||
Timeout() bool
|
||||
}
|
||||
if _, ok := err.(timeoutError); ok {
|
||||
t.Errorf("Expected to not have a timeout error")
|
||||
}
|
||||
expected := `context canceled`
|
||||
if !strings.Contains(err.Error(), expected) {
|
||||
t.Errorf("Expected %q error, got: %q", expected, err.Error())
|
||||
}
|
||||
|
||||
// 2nd request should fail again even if fast because context has already been canceled
|
||||
err = c.RequestWithContext(ctx, "fast", req, resp)
|
||||
if err == nil {
|
||||
t.Fatalf("Expected request with timeout context to fail: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestContextEncodedRequestWithCancel(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
|
||||
nc := NewDefaultConnection(t)
|
||||
c, err := nats.NewEncodedConn(nc, nats.JSON_ENCODER)
|
||||
if err != nil {
|
||||
t.Fatalf("Unable to create encoded connection: %v", err)
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
ctx, cancelCB := context.WithCancel(context.Background())
|
||||
defer cancelCB() // should always be called, not discarded, to prevent context leak
|
||||
|
||||
// timer which cancels the context though can also be arbitrarily extended
|
||||
expirationTimer := time.AfterFunc(100*time.Millisecond, func() {
|
||||
cancelCB()
|
||||
})
|
||||
|
||||
type request struct {
|
||||
Message string `json:"message"`
|
||||
}
|
||||
type response struct {
|
||||
Code int `json:"code"`
|
||||
}
|
||||
c.Subscribe("slow", func(_, reply string, req *request) {
|
||||
got := req.Message
|
||||
expected := "Hello"
|
||||
if got != expected {
|
||||
t.Errorf("Expected to receive request with %q, got %q", got, expected)
|
||||
}
|
||||
|
||||
// simulates latency into the client so that timeout is hit.
|
||||
time.Sleep(40 * time.Millisecond)
|
||||
c.Publish(reply, &response{Code: 200})
|
||||
})
|
||||
c.Subscribe("slower", func(_, reply string, req *request) {
|
||||
got := req.Message
|
||||
expected := "World"
|
||||
if got != expected {
|
||||
t.Errorf("Expected to receive request with %q, got %q", got, expected)
|
||||
}
|
||||
|
||||
// we know this request will take longer so extend the timeout
|
||||
expirationTimer.Reset(100 * time.Millisecond)
|
||||
|
||||
// slower reply which would have hit original timeout
|
||||
time.Sleep(90 * time.Millisecond)
|
||||
c.Publish(reply, &response{Code: 200})
|
||||
})
|
||||
|
||||
for i := 0; i < 2; i++ {
|
||||
req := &request{Message: "Hello"}
|
||||
resp := &response{}
|
||||
err := c.RequestWithContext(ctx, "slow", req, resp)
|
||||
if err != nil {
|
||||
t.Fatalf("Expected encoded request with context to not fail: %s", err)
|
||||
}
|
||||
got := resp.Code
|
||||
expected := 200
|
||||
if got != expected {
|
||||
t.Errorf("Expected to receive %v, got: %v", expected, got)
|
||||
}
|
||||
}
|
||||
|
||||
// A third request with latency would make the context
|
||||
// get canceled, but these reset the timer so deadline
|
||||
// gets extended:
|
||||
for i := 0; i < 10; i++ {
|
||||
req := &request{Message: "World"}
|
||||
resp := &response{}
|
||||
err := c.RequestWithContext(ctx, "slower", req, resp)
|
||||
if err != nil {
|
||||
t.Fatalf("Expected request with context to not fail: %s", err)
|
||||
}
|
||||
got := resp.Code
|
||||
expected := 200
|
||||
if got != expected {
|
||||
t.Errorf("Expected to receive %d, got: %d", expected, got)
|
||||
}
|
||||
}
|
||||
|
||||
req := &request{Message: "Hello"}
|
||||
resp := &response{}
|
||||
|
||||
// One more slow request will expire the timer and cause an error...
|
||||
err = c.RequestWithContext(ctx, "slow", req, resp)
|
||||
if err == nil {
|
||||
t.Fatalf("Expected request with cancellation context to fail: %s", err)
|
||||
}
|
||||
|
||||
// ...though reported error is "context canceled" from Context package,
|
||||
// which is not a timeout error.
|
||||
type timeoutError interface {
|
||||
Timeout() bool
|
||||
}
|
||||
if _, ok := err.(timeoutError); ok {
|
||||
t.Errorf("Expected to not have a timeout error")
|
||||
}
|
||||
expected := `context canceled`
|
||||
if !strings.Contains(err.Error(), expected) {
|
||||
t.Errorf("Expected %q error, got: %q", expected, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func TestContextEncodedRequestWithDeadline(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
|
||||
nc := NewDefaultConnection(t)
|
||||
c, err := nats.NewEncodedConn(nc, nats.JSON_ENCODER)
|
||||
if err != nil {
|
||||
t.Fatalf("Unable to create encoded connection: %v", err)
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
deadline := time.Now().Add(100 * time.Millisecond)
|
||||
ctx, cancelCB := context.WithDeadline(context.Background(), deadline)
|
||||
defer cancelCB() // should always be called, not discarded, to prevent context leak
|
||||
|
||||
type request struct {
|
||||
Message string `json:"message"`
|
||||
}
|
||||
type response struct {
|
||||
Code int `json:"code"`
|
||||
}
|
||||
c.Subscribe("slow", func(_, reply string, req *request) {
|
||||
got := req.Message
|
||||
expected := "Hello"
|
||||
if got != expected {
|
||||
t.Errorf("Expected to receive request with %q, got %q", got, expected)
|
||||
}
|
||||
|
||||
// simulates latency into the client so that timeout is hit.
|
||||
time.Sleep(40 * time.Millisecond)
|
||||
c.Publish(reply, &response{Code: 200})
|
||||
})
|
||||
|
||||
for i := 0; i < 2; i++ {
|
||||
req := &request{Message: "Hello"}
|
||||
resp := &response{}
|
||||
err := c.RequestWithContext(ctx, "slow", req, resp)
|
||||
if err != nil {
|
||||
t.Fatalf("Expected encoded request with context to not fail: %s", err)
|
||||
}
|
||||
got := resp.Code
|
||||
expected := 200
|
||||
if got != expected {
|
||||
t.Errorf("Expected to receive %v, got: %v", expected, got)
|
||||
}
|
||||
}
|
||||
|
||||
// A third request with latency would make the context
|
||||
// reach the deadline.
|
||||
req := &request{Message: "Hello"}
|
||||
resp := &response{}
|
||||
err = c.RequestWithContext(ctx, "slow", req, resp)
|
||||
if err == nil {
|
||||
t.Fatalf("Expected request with context to reach deadline: %s", err)
|
||||
}
|
||||
|
||||
// Reported error is "context deadline exceeded" from Context package,
|
||||
// which implements net.Error Timeout interface.
|
||||
type timeoutError interface {
|
||||
Timeout() bool
|
||||
}
|
||||
timeoutErr, ok := err.(timeoutError)
|
||||
if !ok || !timeoutErr.Timeout() {
|
||||
t.Errorf("Expected to have a timeout error")
|
||||
}
|
||||
expected := `context deadline exceeded`
|
||||
if !strings.Contains(err.Error(), expected) {
|
||||
t.Errorf("Expected %q error, got: %q", expected, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func TestContextRequestConnClosed(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
|
||||
nc := NewDefaultConnection(t)
|
||||
ctx, cancelCB := context.WithCancel(context.Background())
|
||||
defer cancelCB()
|
||||
|
||||
time.AfterFunc(100*time.Millisecond, func() {
|
||||
cancelCB()
|
||||
})
|
||||
|
||||
nc.Close()
|
||||
_, err := nc.RequestWithContext(ctx, "foo", []byte(""))
|
||||
if err == nil {
|
||||
t.Fatalf("Expected request to fail with error")
|
||||
}
|
||||
if err != nats.ErrConnectionClosed {
|
||||
t.Errorf("Expected request to fail with connection closed error: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestContextBadSubscription(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
|
||||
nc := NewDefaultConnection(t)
|
||||
defer nc.Close()
|
||||
ctx, cancelCB := context.WithCancel(context.Background())
|
||||
defer cancelCB()
|
||||
time.AfterFunc(100*time.Millisecond, func() {
|
||||
cancelCB()
|
||||
})
|
||||
|
||||
sub, err := nc.Subscribe("foo", func(_ *nats.Msg) {})
|
||||
if err != nil {
|
||||
t.Fatalf("Expected to be able to subscribe: %s", err)
|
||||
}
|
||||
|
||||
err = sub.Unsubscribe()
|
||||
if err != nil {
|
||||
t.Fatalf("Expected to be able to unsubscribe: %s", err)
|
||||
}
|
||||
|
||||
_, err = sub.NextMsgWithContext(ctx)
|
||||
if err == nil {
|
||||
t.Fatalf("Expected to fail getting next message with context")
|
||||
}
|
||||
|
||||
if err != nats.ErrBadSubscription {
|
||||
t.Errorf("Expected request to fail with connection closed error: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestContextInvalid(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
|
||||
nc := NewDefaultConnection(t)
|
||||
c, err := nats.NewEncodedConn(nc, nats.JSON_ENCODER)
|
||||
if err != nil {
|
||||
t.Fatalf("Unable to create encoded connection: %v", err)
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
_, err = nc.RequestWithContext(nil, "foo", []byte(""))
|
||||
if err == nil {
|
||||
t.Fatalf("Expected request to fail with error")
|
||||
}
|
||||
if err != nats.ErrInvalidContext {
|
||||
t.Errorf("Expected request to fail with connection closed error: %s", err)
|
||||
}
|
||||
|
||||
sub, err := nc.Subscribe("foo", func(_ *nats.Msg) {})
|
||||
if err != nil {
|
||||
t.Fatalf("Expected to be able to subscribe: %s", err)
|
||||
}
|
||||
|
||||
_, err = sub.NextMsgWithContext(nil)
|
||||
if err == nil {
|
||||
t.Fatalf("Expected request to fail with error")
|
||||
}
|
||||
if err != nats.ErrInvalidContext {
|
||||
t.Errorf("Expected request to fail with connection closed error: %s", err)
|
||||
}
|
||||
|
||||
type request struct {
|
||||
Message string `json:"message"`
|
||||
}
|
||||
type response struct {
|
||||
Code int `json:"code"`
|
||||
}
|
||||
req := &request{Message: "Hello"}
|
||||
resp := &response{}
|
||||
err = c.RequestWithContext(nil, "slow", req, resp)
|
||||
if err == nil {
|
||||
t.Fatalf("Expected request with context to reach deadline: %s", err)
|
||||
}
|
||||
if err != nats.ErrInvalidContext {
|
||||
t.Errorf("Expected request to fail with connection closed error: %s", err)
|
||||
}
|
||||
}
|
448
gateway/vendor/github.com/nats-io/go-nats/test/enc_test.go
generated
vendored
Normal file
448
gateway/vendor/github.com/nats-io/go-nats/test/enc_test.go
generated
vendored
Normal file
@ -0,0 +1,448 @@
|
||||
// Copyright 2012-2017 Apcera Inc. All rights reserved.
|
||||
|
||||
package test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/nats-io/go-nats"
|
||||
"github.com/nats-io/go-nats/encoders/builtin"
|
||||
)
|
||||
|
||||
const TEST_PORT = 8168
|
||||
|
||||
func NewDefaultEConn(t *testing.T) *nats.EncodedConn {
|
||||
ec, err := nats.NewEncodedConn(NewConnection(t, TEST_PORT), nats.DEFAULT_ENCODER)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create an encoded connection: %v\n", err)
|
||||
}
|
||||
return ec
|
||||
}
|
||||
|
||||
func TestEncBuiltinConstructorErrs(t *testing.T) {
|
||||
s := RunServerOnPort(TEST_PORT)
|
||||
defer s.Shutdown()
|
||||
|
||||
c := NewConnection(t, TEST_PORT)
|
||||
_, err := nats.NewEncodedConn(nil, "default")
|
||||
if err == nil {
|
||||
t.Fatal("Expected err for nil connection")
|
||||
}
|
||||
_, err = nats.NewEncodedConn(c, "foo22")
|
||||
if err == nil {
|
||||
t.Fatal("Expected err for bad encoder")
|
||||
}
|
||||
c.Close()
|
||||
_, err = nats.NewEncodedConn(c, "default")
|
||||
if err == nil {
|
||||
t.Fatal("Expected err for closed connection")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestEncBuiltinMarshalString(t *testing.T) {
|
||||
s := RunServerOnPort(TEST_PORT)
|
||||
defer s.Shutdown()
|
||||
|
||||
ec := NewDefaultEConn(t)
|
||||
defer ec.Close()
|
||||
ch := make(chan bool)
|
||||
|
||||
testString := "Hello World!"
|
||||
|
||||
ec.Subscribe("enc_string", func(s string) {
|
||||
if s != testString {
|
||||
t.Fatalf("Received test string of '%s', wanted '%s'\n", s, testString)
|
||||
}
|
||||
ch <- true
|
||||
})
|
||||
ec.Publish("enc_string", testString)
|
||||
if e := Wait(ch); e != nil {
|
||||
if ec.LastError() != nil {
|
||||
e = ec.LastError()
|
||||
}
|
||||
t.Fatalf("Did not receive the message: %s", e)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncBuiltinMarshalBytes(t *testing.T) {
|
||||
s := RunServerOnPort(TEST_PORT)
|
||||
defer s.Shutdown()
|
||||
|
||||
ec := NewDefaultEConn(t)
|
||||
defer ec.Close()
|
||||
ch := make(chan bool)
|
||||
|
||||
testBytes := []byte("Hello World!")
|
||||
|
||||
ec.Subscribe("enc_bytes", func(b []byte) {
|
||||
if !bytes.Equal(b, testBytes) {
|
||||
t.Fatalf("Received test bytes of '%s', wanted '%s'\n", b, testBytes)
|
||||
}
|
||||
ch <- true
|
||||
})
|
||||
ec.Publish("enc_bytes", testBytes)
|
||||
if e := Wait(ch); e != nil {
|
||||
if ec.LastError() != nil {
|
||||
e = ec.LastError()
|
||||
}
|
||||
t.Fatalf("Did not receive the message: %s", e)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncBuiltinMarshalInt(t *testing.T) {
|
||||
s := RunServerOnPort(TEST_PORT)
|
||||
defer s.Shutdown()
|
||||
|
||||
ec := NewDefaultEConn(t)
|
||||
defer ec.Close()
|
||||
ch := make(chan bool)
|
||||
|
||||
testN := 22
|
||||
|
||||
ec.Subscribe("enc_int", func(n int) {
|
||||
if n != testN {
|
||||
t.Fatalf("Received test number of %d, wanted %d\n", n, testN)
|
||||
}
|
||||
ch <- true
|
||||
})
|
||||
ec.Publish("enc_int", testN)
|
||||
if e := Wait(ch); e != nil {
|
||||
if ec.LastError() != nil {
|
||||
e = ec.LastError()
|
||||
}
|
||||
t.Fatalf("Did not receive the message: %s", e)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncBuiltinMarshalInt32(t *testing.T) {
|
||||
s := RunServerOnPort(TEST_PORT)
|
||||
defer s.Shutdown()
|
||||
|
||||
ec := NewDefaultEConn(t)
|
||||
defer ec.Close()
|
||||
ch := make(chan bool)
|
||||
|
||||
testN := 22
|
||||
|
||||
ec.Subscribe("enc_int", func(n int32) {
|
||||
if n != int32(testN) {
|
||||
t.Fatalf("Received test number of %d, wanted %d\n", n, testN)
|
||||
}
|
||||
ch <- true
|
||||
})
|
||||
ec.Publish("enc_int", testN)
|
||||
if e := Wait(ch); e != nil {
|
||||
if ec.LastError() != nil {
|
||||
e = ec.LastError()
|
||||
}
|
||||
t.Fatalf("Did not receive the message: %s", e)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncBuiltinMarshalInt64(t *testing.T) {
|
||||
s := RunServerOnPort(TEST_PORT)
|
||||
defer s.Shutdown()
|
||||
|
||||
ec := NewDefaultEConn(t)
|
||||
defer ec.Close()
|
||||
ch := make(chan bool)
|
||||
|
||||
testN := 22
|
||||
|
||||
ec.Subscribe("enc_int", func(n int64) {
|
||||
if n != int64(testN) {
|
||||
t.Fatalf("Received test number of %d, wanted %d\n", n, testN)
|
||||
}
|
||||
ch <- true
|
||||
})
|
||||
ec.Publish("enc_int", testN)
|
||||
if e := Wait(ch); e != nil {
|
||||
if ec.LastError() != nil {
|
||||
e = ec.LastError()
|
||||
}
|
||||
t.Fatalf("Did not receive the message: %s", e)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncBuiltinMarshalFloat32(t *testing.T) {
|
||||
s := RunServerOnPort(TEST_PORT)
|
||||
defer s.Shutdown()
|
||||
|
||||
ec := NewDefaultEConn(t)
|
||||
defer ec.Close()
|
||||
ch := make(chan bool)
|
||||
|
||||
testN := float32(22)
|
||||
|
||||
ec.Subscribe("enc_float", func(n float32) {
|
||||
if n != testN {
|
||||
t.Fatalf("Received test number of %f, wanted %f\n", n, testN)
|
||||
}
|
||||
ch <- true
|
||||
})
|
||||
ec.Publish("enc_float", testN)
|
||||
if e := Wait(ch); e != nil {
|
||||
if ec.LastError() != nil {
|
||||
e = ec.LastError()
|
||||
}
|
||||
t.Fatalf("Did not receive the message: %s", e)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncBuiltinMarshalFloat64(t *testing.T) {
|
||||
s := RunServerOnPort(TEST_PORT)
|
||||
defer s.Shutdown()
|
||||
|
||||
ec := NewDefaultEConn(t)
|
||||
defer ec.Close()
|
||||
ch := make(chan bool)
|
||||
|
||||
testN := float64(22.22)
|
||||
|
||||
ec.Subscribe("enc_float", func(n float64) {
|
||||
if n != testN {
|
||||
t.Fatalf("Received test number of %f, wanted %f\n", n, testN)
|
||||
}
|
||||
ch <- true
|
||||
})
|
||||
ec.Publish("enc_float", testN)
|
||||
if e := Wait(ch); e != nil {
|
||||
if ec.LastError() != nil {
|
||||
e = ec.LastError()
|
||||
}
|
||||
t.Fatalf("Did not receive the message: %s", e)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncBuiltinMarshalBool(t *testing.T) {
|
||||
s := RunServerOnPort(TEST_PORT)
|
||||
defer s.Shutdown()
|
||||
|
||||
ec := NewDefaultEConn(t)
|
||||
defer ec.Close()
|
||||
ch := make(chan bool)
|
||||
expected := make(chan bool, 1)
|
||||
|
||||
ec.Subscribe("enc_bool", func(b bool) {
|
||||
val := <-expected
|
||||
if b != val {
|
||||
t.Fatal("Boolean values did not match")
|
||||
}
|
||||
ch <- true
|
||||
})
|
||||
|
||||
expected <- false
|
||||
ec.Publish("enc_bool", false)
|
||||
if e := Wait(ch); e != nil {
|
||||
if ec.LastError() != nil {
|
||||
e = ec.LastError()
|
||||
}
|
||||
t.Fatalf("Did not receive the message: %s", e)
|
||||
}
|
||||
|
||||
expected <- true
|
||||
ec.Publish("enc_bool", true)
|
||||
if e := Wait(ch); e != nil {
|
||||
if ec.LastError() != nil {
|
||||
e = ec.LastError()
|
||||
}
|
||||
t.Fatalf("Did not receive the message: %s", e)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncBuiltinExtendedSubscribeCB(t *testing.T) {
|
||||
s := RunServerOnPort(TEST_PORT)
|
||||
defer s.Shutdown()
|
||||
|
||||
ec := NewDefaultEConn(t)
|
||||
defer ec.Close()
|
||||
|
||||
ch := make(chan bool)
|
||||
|
||||
testString := "Hello World!"
|
||||
subject := "cb_args"
|
||||
|
||||
ec.Subscribe(subject, func(subj, s string) {
|
||||
if s != testString {
|
||||
t.Fatalf("Received test string of '%s', wanted '%s'\n", s, testString)
|
||||
}
|
||||
if subj != subject {
|
||||
t.Fatalf("Received subject of '%s', wanted '%s'\n", subj, subject)
|
||||
}
|
||||
ch <- true
|
||||
})
|
||||
ec.Publish(subject, testString)
|
||||
if e := Wait(ch); e != nil {
|
||||
if ec.LastError() != nil {
|
||||
e = ec.LastError()
|
||||
}
|
||||
t.Fatalf("Did not receive the message: %s", e)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncBuiltinExtendedSubscribeCB2(t *testing.T) {
|
||||
s := RunServerOnPort(TEST_PORT)
|
||||
defer s.Shutdown()
|
||||
|
||||
ec := NewDefaultEConn(t)
|
||||
defer ec.Close()
|
||||
|
||||
ch := make(chan bool)
|
||||
|
||||
testString := "Hello World!"
|
||||
oSubj := "cb_args"
|
||||
oReply := "foobar"
|
||||
|
||||
ec.Subscribe(oSubj, func(subj, reply, s string) {
|
||||
if s != testString {
|
||||
t.Fatalf("Received test string of '%s', wanted '%s'\n", s, testString)
|
||||
}
|
||||
if subj != oSubj {
|
||||
t.Fatalf("Received subject of '%s', wanted '%s'\n", subj, oSubj)
|
||||
}
|
||||
if reply != oReply {
|
||||
t.Fatalf("Received reply of '%s', wanted '%s'\n", reply, oReply)
|
||||
}
|
||||
ch <- true
|
||||
})
|
||||
ec.PublishRequest(oSubj, oReply, testString)
|
||||
if e := Wait(ch); e != nil {
|
||||
if ec.LastError() != nil {
|
||||
e = ec.LastError()
|
||||
}
|
||||
t.Fatalf("Did not receive the message: %s", e)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncBuiltinRawMsgSubscribeCB(t *testing.T) {
|
||||
s := RunServerOnPort(TEST_PORT)
|
||||
defer s.Shutdown()
|
||||
|
||||
ec := NewDefaultEConn(t)
|
||||
defer ec.Close()
|
||||
|
||||
ch := make(chan bool)
|
||||
|
||||
testString := "Hello World!"
|
||||
oSubj := "cb_args"
|
||||
oReply := "foobar"
|
||||
|
||||
ec.Subscribe(oSubj, func(m *nats.Msg) {
|
||||
s := string(m.Data)
|
||||
if s != testString {
|
||||
t.Fatalf("Received test string of '%s', wanted '%s'\n", s, testString)
|
||||
}
|
||||
if m.Subject != oSubj {
|
||||
t.Fatalf("Received subject of '%s', wanted '%s'\n", m.Subject, oSubj)
|
||||
}
|
||||
if m.Reply != oReply {
|
||||
t.Fatalf("Received reply of '%s', wanted '%s'\n", m.Reply, oReply)
|
||||
}
|
||||
ch <- true
|
||||
})
|
||||
ec.PublishRequest(oSubj, oReply, testString)
|
||||
if e := Wait(ch); e != nil {
|
||||
if ec.LastError() != nil {
|
||||
e = ec.LastError()
|
||||
}
|
||||
t.Fatalf("Did not receive the message: %s", e)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncBuiltinRequest(t *testing.T) {
|
||||
s := RunServerOnPort(TEST_PORT)
|
||||
defer s.Shutdown()
|
||||
|
||||
ec := NewDefaultEConn(t)
|
||||
defer ec.Close()
|
||||
|
||||
expectedResp := "I can help!"
|
||||
|
||||
ec.Subscribe("help", func(subj, reply, req string) {
|
||||
ec.Publish(reply, expectedResp)
|
||||
})
|
||||
|
||||
var resp string
|
||||
|
||||
err := ec.Request("help", "help me", &resp, 1*time.Second)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed at receiving proper response: %v\n", err)
|
||||
}
|
||||
if resp != expectedResp {
|
||||
t.Fatalf("Received reply '%s', wanted '%s'\n", resp, expectedResp)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncBuiltinRequestReceivesMsg(t *testing.T) {
|
||||
s := RunServerOnPort(TEST_PORT)
|
||||
defer s.Shutdown()
|
||||
|
||||
ec := NewDefaultEConn(t)
|
||||
defer ec.Close()
|
||||
|
||||
expectedResp := "I can help!"
|
||||
|
||||
ec.Subscribe("help", func(subj, reply, req string) {
|
||||
ec.Publish(reply, expectedResp)
|
||||
})
|
||||
|
||||
var resp nats.Msg
|
||||
|
||||
err := ec.Request("help", "help me", &resp, 1*time.Second)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed at receiving proper response: %v\n", err)
|
||||
}
|
||||
if string(resp.Data) != expectedResp {
|
||||
t.Fatalf("Received reply '%s', wanted '%s'\n", string(resp.Data), expectedResp)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncBuiltinAsyncMarshalErr(t *testing.T) {
|
||||
s := RunServerOnPort(TEST_PORT)
|
||||
defer s.Shutdown()
|
||||
|
||||
ec := NewDefaultEConn(t)
|
||||
defer ec.Close()
|
||||
|
||||
ch := make(chan bool)
|
||||
|
||||
testString := "Hello World!"
|
||||
subject := "err_marshall"
|
||||
|
||||
ec.Subscribe(subject, func(subj, num int) {
|
||||
// This will never get called.
|
||||
})
|
||||
|
||||
ec.Conn.Opts.AsyncErrorCB = func(c *nats.Conn, s *nats.Subscription, err error) {
|
||||
ch <- true
|
||||
}
|
||||
|
||||
ec.Publish(subject, testString)
|
||||
if e := Wait(ch); e != nil {
|
||||
t.Fatalf("Did not receive the message: %s", e)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncBuiltinEncodeNil(t *testing.T) {
|
||||
de := &builtin.DefaultEncoder{}
|
||||
_, err := de.Encode("foo", nil)
|
||||
if err != nil {
|
||||
t.Fatalf("Expected no error encoding nil: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncBuiltinDecodeDefault(t *testing.T) {
|
||||
de := &builtin.DefaultEncoder{}
|
||||
b, err := de.Encode("foo", 22)
|
||||
if err != nil {
|
||||
t.Fatalf("Expected no error encoding number: %v", err)
|
||||
}
|
||||
var c chan bool
|
||||
err = de.Decode("foo", b, &c)
|
||||
if err == nil {
|
||||
t.Fatalf("Expected an error decoding")
|
||||
}
|
||||
}
|
128
gateway/vendor/github.com/nats-io/go-nats/test/gob_test.go
generated
vendored
Normal file
128
gateway/vendor/github.com/nats-io/go-nats/test/gob_test.go
generated
vendored
Normal file
@ -0,0 +1,128 @@
|
||||
// Copyright 2012-2017 Apcera Inc. All rights reserved.
|
||||
|
||||
package test
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/nats-io/go-nats"
|
||||
)
|
||||
|
||||
func NewGobEncodedConn(tl TestLogger) *nats.EncodedConn {
|
||||
ec, err := nats.NewEncodedConn(NewConnection(tl, TEST_PORT), nats.GOB_ENCODER)
|
||||
if err != nil {
|
||||
tl.Fatalf("Failed to create an encoded connection: %v\n", err)
|
||||
}
|
||||
return ec
|
||||
}
|
||||
|
||||
func TestEncBuiltinGobMarshalString(t *testing.T) {
|
||||
s := RunServerOnPort(TEST_PORT)
|
||||
defer s.Shutdown()
|
||||
|
||||
ec := NewGobEncodedConn(t)
|
||||
defer ec.Close()
|
||||
ch := make(chan bool)
|
||||
|
||||
testString := "Hello World!"
|
||||
|
||||
ec.Subscribe("gob_string", func(s string) {
|
||||
if s != testString {
|
||||
t.Fatalf("Received test string of '%s', wanted '%s'\n", s, testString)
|
||||
}
|
||||
ch <- true
|
||||
})
|
||||
ec.Publish("gob_string", testString)
|
||||
if e := Wait(ch); e != nil {
|
||||
t.Fatal("Did not receive the message")
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncBuiltinGobMarshalInt(t *testing.T) {
|
||||
s := RunServerOnPort(TEST_PORT)
|
||||
defer s.Shutdown()
|
||||
|
||||
ec := NewGobEncodedConn(t)
|
||||
defer ec.Close()
|
||||
ch := make(chan bool)
|
||||
|
||||
testN := 22
|
||||
|
||||
ec.Subscribe("gob_int", func(n int) {
|
||||
if n != testN {
|
||||
t.Fatalf("Received test int of '%d', wanted '%d'\n", n, testN)
|
||||
}
|
||||
ch <- true
|
||||
})
|
||||
ec.Publish("gob_int", testN)
|
||||
if e := Wait(ch); e != nil {
|
||||
t.Fatal("Did not receive the message")
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncBuiltinGobMarshalStruct(t *testing.T) {
|
||||
s := RunServerOnPort(TEST_PORT)
|
||||
defer s.Shutdown()
|
||||
|
||||
ec := NewGobEncodedConn(t)
|
||||
defer ec.Close()
|
||||
ch := make(chan bool)
|
||||
|
||||
me := &person{Name: "derek", Age: 22, Address: "140 New Montgomery St"}
|
||||
me.Children = make(map[string]*person)
|
||||
|
||||
me.Children["sam"] = &person{Name: "sam", Age: 19, Address: "140 New Montgomery St"}
|
||||
me.Children["meg"] = &person{Name: "meg", Age: 17, Address: "140 New Montgomery St"}
|
||||
|
||||
me.Assets = make(map[string]uint)
|
||||
me.Assets["house"] = 1000
|
||||
me.Assets["car"] = 100
|
||||
|
||||
ec.Subscribe("gob_struct", func(p *person) {
|
||||
if !reflect.DeepEqual(p, me) {
|
||||
t.Fatalf("Did not receive the correct struct response")
|
||||
}
|
||||
ch <- true
|
||||
})
|
||||
|
||||
ec.Publish("gob_struct", me)
|
||||
if e := Wait(ch); e != nil {
|
||||
t.Fatal("Did not receive the message")
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkPublishGobStruct(b *testing.B) {
|
||||
// stop benchmark for set-up
|
||||
b.StopTimer()
|
||||
|
||||
s := RunServerOnPort(TEST_PORT)
|
||||
defer s.Shutdown()
|
||||
|
||||
ec := NewGobEncodedConn(b)
|
||||
defer ec.Close()
|
||||
ch := make(chan bool)
|
||||
|
||||
me := &person{Name: "derek", Age: 22, Address: "140 New Montgomery St"}
|
||||
me.Children = make(map[string]*person)
|
||||
|
||||
me.Children["sam"] = &person{Name: "sam", Age: 19, Address: "140 New Montgomery St"}
|
||||
me.Children["meg"] = &person{Name: "meg", Age: 17, Address: "140 New Montgomery St"}
|
||||
|
||||
ec.Subscribe("gob_struct", func(p *person) {
|
||||
if !reflect.DeepEqual(p, me) {
|
||||
b.Fatalf("Did not receive the correct struct response")
|
||||
}
|
||||
ch <- true
|
||||
})
|
||||
|
||||
// resume benchmark
|
||||
b.StartTimer()
|
||||
|
||||
for n := 0; n < b.N; n++ {
|
||||
ec.Publish("gob_struct", me)
|
||||
if e := Wait(ch); e != nil {
|
||||
b.Fatal("Did not receive the message")
|
||||
}
|
||||
}
|
||||
}
|
93
gateway/vendor/github.com/nats-io/go-nats/test/helper_test.go
generated
vendored
Normal file
93
gateway/vendor/github.com/nats-io/go-nats/test/helper_test.go
generated
vendored
Normal file
@ -0,0 +1,93 @@
|
||||
// Copyright 2015 Apcera Inc. All rights reserved.
|
||||
|
||||
package test
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/nats-io/gnatsd/server"
|
||||
"github.com/nats-io/go-nats"
|
||||
|
||||
gnatsd "github.com/nats-io/gnatsd/test"
|
||||
)
|
||||
|
||||
// So that we can pass tests and benchmarks...
|
||||
type tLogger interface {
|
||||
Fatalf(format string, args ...interface{})
|
||||
Errorf(format string, args ...interface{})
|
||||
}
|
||||
|
||||
// TestLogger
|
||||
type TestLogger tLogger
|
||||
|
||||
// Dumb wait program to sync on callbacks, etc... Will timeout
|
||||
func Wait(ch chan bool) error {
|
||||
return WaitTime(ch, 5*time.Second)
|
||||
}
|
||||
|
||||
// Wait for a chan with a timeout.
|
||||
func WaitTime(ch chan bool, timeout time.Duration) error {
|
||||
select {
|
||||
case <-ch:
|
||||
return nil
|
||||
case <-time.After(timeout):
|
||||
}
|
||||
return errors.New("timeout")
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Creating client connections
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// NewDefaultConnection
|
||||
func NewDefaultConnection(t tLogger) *nats.Conn {
|
||||
return NewConnection(t, nats.DefaultPort)
|
||||
}
|
||||
|
||||
// NewConnection forms connection on a given port.
|
||||
func NewConnection(t tLogger, port int) *nats.Conn {
|
||||
url := fmt.Sprintf("nats://localhost:%d", port)
|
||||
nc, err := nats.Connect(url)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create default connection: %v\n", err)
|
||||
return nil
|
||||
}
|
||||
return nc
|
||||
}
|
||||
|
||||
// NewEConn
|
||||
func NewEConn(t tLogger) *nats.EncodedConn {
|
||||
ec, err := nats.NewEncodedConn(NewDefaultConnection(t), nats.DEFAULT_ENCODER)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create an encoded connection: %v\n", err)
|
||||
}
|
||||
return ec
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Running gnatsd server in separate Go routines
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// RunDefaultServer will run a server on the default port.
|
||||
func RunDefaultServer() *server.Server {
|
||||
return RunServerOnPort(nats.DefaultPort)
|
||||
}
|
||||
|
||||
// RunServerOnPort will run a server on the given port.
|
||||
func RunServerOnPort(port int) *server.Server {
|
||||
opts := gnatsd.DefaultTestOptions
|
||||
opts.Port = port
|
||||
return RunServerWithOptions(opts)
|
||||
}
|
||||
|
||||
// RunServerWithOptions will run a server with the given options.
|
||||
func RunServerWithOptions(opts server.Options) *server.Server {
|
||||
return gnatsd.RunServer(&opts)
|
||||
}
|
||||
|
||||
// RunServerWithConfig will run a server with the given configuration file.
|
||||
func RunServerWithConfig(configFile string) (*server.Server, *server.Options) {
|
||||
return gnatsd.RunServerWithConfig(configFile)
|
||||
}
|
209
gateway/vendor/github.com/nats-io/go-nats/test/json_test.go
generated
vendored
Normal file
209
gateway/vendor/github.com/nats-io/go-nats/test/json_test.go
generated
vendored
Normal file
@ -0,0 +1,209 @@
|
||||
// Copyright 2012-2017 Apcera Inc. All rights reserved.
|
||||
|
||||
package test
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/nats-io/go-nats"
|
||||
"github.com/nats-io/go-nats/encoders/builtin"
|
||||
)
|
||||
|
||||
func NewJsonEncodedConn(tl TestLogger) *nats.EncodedConn {
|
||||
ec, err := nats.NewEncodedConn(NewConnection(tl, TEST_PORT), nats.JSON_ENCODER)
|
||||
if err != nil {
|
||||
tl.Fatalf("Failed to create an encoded connection: %v\n", err)
|
||||
}
|
||||
return ec
|
||||
}
|
||||
|
||||
func TestEncBuiltinJsonMarshalString(t *testing.T) {
|
||||
s := RunServerOnPort(TEST_PORT)
|
||||
defer s.Shutdown()
|
||||
|
||||
ec := NewJsonEncodedConn(t)
|
||||
defer ec.Close()
|
||||
ch := make(chan bool)
|
||||
|
||||
testString := "Hello World!"
|
||||
|
||||
ec.Subscribe("json_string", func(s string) {
|
||||
if s != testString {
|
||||
t.Fatalf("Received test string of '%s', wanted '%s'\n", s, testString)
|
||||
}
|
||||
ch <- true
|
||||
})
|
||||
ec.Publish("json_string", testString)
|
||||
if e := Wait(ch); e != nil {
|
||||
t.Fatal("Did not receive the message")
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncBuiltinJsonMarshalInt(t *testing.T) {
|
||||
s := RunServerOnPort(TEST_PORT)
|
||||
defer s.Shutdown()
|
||||
|
||||
ec := NewJsonEncodedConn(t)
|
||||
defer ec.Close()
|
||||
ch := make(chan bool)
|
||||
|
||||
testN := 22
|
||||
|
||||
ec.Subscribe("json_int", func(n int) {
|
||||
if n != testN {
|
||||
t.Fatalf("Received test int of '%d', wanted '%d'\n", n, testN)
|
||||
}
|
||||
ch <- true
|
||||
})
|
||||
ec.Publish("json_int", testN)
|
||||
if e := Wait(ch); e != nil {
|
||||
t.Fatal("Did not receive the message")
|
||||
}
|
||||
}
|
||||
|
||||
type person struct {
|
||||
Name string
|
||||
Address string
|
||||
Age int
|
||||
Children map[string]*person
|
||||
Assets map[string]uint
|
||||
}
|
||||
|
||||
func TestEncBuiltinJsonMarshalStruct(t *testing.T) {
|
||||
s := RunServerOnPort(TEST_PORT)
|
||||
defer s.Shutdown()
|
||||
|
||||
ec := NewJsonEncodedConn(t)
|
||||
defer ec.Close()
|
||||
ch := make(chan bool)
|
||||
|
||||
me := &person{Name: "derek", Age: 22, Address: "140 New Montgomery St"}
|
||||
me.Children = make(map[string]*person)
|
||||
|
||||
me.Children["sam"] = &person{Name: "sam", Age: 19, Address: "140 New Montgomery St"}
|
||||
me.Children["meg"] = &person{Name: "meg", Age: 17, Address: "140 New Montgomery St"}
|
||||
|
||||
me.Assets = make(map[string]uint)
|
||||
me.Assets["house"] = 1000
|
||||
me.Assets["car"] = 100
|
||||
|
||||
ec.Subscribe("json_struct", func(p *person) {
|
||||
if !reflect.DeepEqual(p, me) {
|
||||
t.Fatal("Did not receive the correct struct response")
|
||||
}
|
||||
ch <- true
|
||||
})
|
||||
|
||||
ec.Publish("json_struct", me)
|
||||
if e := Wait(ch); e != nil {
|
||||
t.Fatal("Did not receive the message")
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkJsonMarshalStruct(b *testing.B) {
|
||||
me := &person{Name: "derek", Age: 22, Address: "140 New Montgomery St"}
|
||||
me.Children = make(map[string]*person)
|
||||
|
||||
me.Children["sam"] = &person{Name: "sam", Age: 19, Address: "140 New Montgomery St"}
|
||||
me.Children["meg"] = &person{Name: "meg", Age: 17, Address: "140 New Montgomery St"}
|
||||
|
||||
encoder := &builtin.JsonEncoder{}
|
||||
for n := 0; n < b.N; n++ {
|
||||
if _, err := encoder.Encode("protobuf_test", me); err != nil {
|
||||
b.Fatal("Couldn't serialize object", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkPublishJsonStruct(b *testing.B) {
|
||||
// stop benchmark for set-up
|
||||
b.StopTimer()
|
||||
|
||||
s := RunServerOnPort(TEST_PORT)
|
||||
defer s.Shutdown()
|
||||
|
||||
ec := NewJsonEncodedConn(b)
|
||||
defer ec.Close()
|
||||
ch := make(chan bool)
|
||||
|
||||
me := &person{Name: "derek", Age: 22, Address: "140 New Montgomery St"}
|
||||
me.Children = make(map[string]*person)
|
||||
|
||||
me.Children["sam"] = &person{Name: "sam", Age: 19, Address: "140 New Montgomery St"}
|
||||
me.Children["meg"] = &person{Name: "meg", Age: 17, Address: "140 New Montgomery St"}
|
||||
|
||||
ec.Subscribe("json_struct", func(p *person) {
|
||||
if !reflect.DeepEqual(p, me) {
|
||||
b.Fatalf("Did not receive the correct struct response")
|
||||
}
|
||||
ch <- true
|
||||
})
|
||||
|
||||
// resume benchmark
|
||||
b.StartTimer()
|
||||
|
||||
for n := 0; n < b.N; n++ {
|
||||
ec.Publish("json_struct", me)
|
||||
if e := Wait(ch); e != nil {
|
||||
b.Fatal("Did not receive the message")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestEncBuiltinNotMarshableToJson(t *testing.T) {
|
||||
je := &builtin.JsonEncoder{}
|
||||
ch := make(chan bool)
|
||||
_, err := je.Encode("foo", ch)
|
||||
if err == nil {
|
||||
t.Fatal("Expected an error when failing encoding")
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncBuiltinFailedEncodedPublish(t *testing.T) {
|
||||
s := RunServerOnPort(TEST_PORT)
|
||||
defer s.Shutdown()
|
||||
|
||||
ec := NewJsonEncodedConn(t)
|
||||
defer ec.Close()
|
||||
|
||||
ch := make(chan bool)
|
||||
err := ec.Publish("foo", ch)
|
||||
if err == nil {
|
||||
t.Fatal("Expected an error trying to publish a channel")
|
||||
}
|
||||
err = ec.PublishRequest("foo", "bar", ch)
|
||||
if err == nil {
|
||||
t.Fatal("Expected an error trying to publish a channel")
|
||||
}
|
||||
var cr chan bool
|
||||
err = ec.Request("foo", ch, &cr, 1*time.Second)
|
||||
if err == nil {
|
||||
t.Fatal("Expected an error trying to publish a channel")
|
||||
}
|
||||
err = ec.LastError()
|
||||
if err != nil {
|
||||
t.Fatalf("Expected LastError to be nil: %q ", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncBuiltinDecodeConditionals(t *testing.T) {
|
||||
je := &builtin.JsonEncoder{}
|
||||
|
||||
b, err := je.Encode("foo", 22)
|
||||
if err != nil {
|
||||
t.Fatalf("Expected no error when encoding, got %v\n", err)
|
||||
}
|
||||
var foo string
|
||||
var bar []byte
|
||||
err = je.Decode("foo", b, &foo)
|
||||
if err != nil {
|
||||
t.Fatalf("Expected no error when decoding, got %v\n", err)
|
||||
}
|
||||
err = je.Decode("foo", b, &bar)
|
||||
if err != nil {
|
||||
t.Fatalf("Expected no error when decoding, got %v\n", err)
|
||||
}
|
||||
}
|
14
gateway/vendor/github.com/nats-io/go-nats/test/main.go
generated
vendored
Normal file
14
gateway/vendor/github.com/nats-io/go-nats/test/main.go
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
// Copyright 2017 Apcera Inc. All rights reserved.
|
||||
|
||||
package test
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// TestMain runs all tests. Added since tests were moved to a separate package.
|
||||
func TestMain(m *testing.M) {
|
||||
// call flag.Parse() here if TestMain uses flags
|
||||
os.Exit(m.Run())
|
||||
}
|
355
gateway/vendor/github.com/nats-io/go-nats/test/netchan_test.go
generated
vendored
Normal file
355
gateway/vendor/github.com/nats-io/go-nats/test/netchan_test.go
generated
vendored
Normal file
@ -0,0 +1,355 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/nats-io/go-nats"
|
||||
)
|
||||
|
||||
func TestBadChan(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
|
||||
ec := NewEConn(t)
|
||||
defer ec.Close()
|
||||
|
||||
if err := ec.BindSendChan("foo", "not a chan"); err == nil {
|
||||
t.Fatalf("Expected an Error when sending a non-channel\n")
|
||||
}
|
||||
|
||||
if _, err := ec.BindRecvChan("foo", "not a chan"); err == nil {
|
||||
t.Fatalf("Expected an Error when sending a non-channel\n")
|
||||
}
|
||||
|
||||
if err := ec.BindSendChan("foo", "not a chan"); err != nats.ErrChanArg {
|
||||
t.Fatalf("Expected an ErrChanArg when sending a non-channel\n")
|
||||
}
|
||||
|
||||
if _, err := ec.BindRecvChan("foo", "not a chan"); err != nats.ErrChanArg {
|
||||
t.Fatalf("Expected an ErrChanArg when sending a non-channel\n")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSimpleSendChan(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
|
||||
ec := NewEConn(t)
|
||||
defer ec.Close()
|
||||
|
||||
recv := make(chan bool)
|
||||
|
||||
numSent := int32(22)
|
||||
ch := make(chan int32)
|
||||
|
||||
if err := ec.BindSendChan("foo", ch); err != nil {
|
||||
t.Fatalf("Failed to bind to a send channel: %v\n", err)
|
||||
}
|
||||
|
||||
ec.Subscribe("foo", func(num int32) {
|
||||
if num != numSent {
|
||||
t.Fatalf("Failed to receive correct value: %d vs %d\n", num, numSent)
|
||||
}
|
||||
recv <- true
|
||||
})
|
||||
|
||||
// Send to 'foo'
|
||||
ch <- numSent
|
||||
|
||||
if e := Wait(recv); e != nil {
|
||||
if ec.LastError() != nil {
|
||||
e = ec.LastError()
|
||||
}
|
||||
t.Fatalf("Did not receive the message: %s", e)
|
||||
}
|
||||
close(ch)
|
||||
}
|
||||
|
||||
func TestFailedChannelSend(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
|
||||
ec := NewEConn(t)
|
||||
defer ec.Close()
|
||||
|
||||
nc := ec.Conn
|
||||
ch := make(chan bool)
|
||||
wch := make(chan bool)
|
||||
|
||||
nc.Opts.AsyncErrorCB = func(c *nats.Conn, s *nats.Subscription, e error) {
|
||||
wch <- true
|
||||
}
|
||||
|
||||
if err := ec.BindSendChan("foo", ch); err != nil {
|
||||
t.Fatalf("Failed to bind to a receive channel: %v\n", err)
|
||||
}
|
||||
|
||||
nc.Flush()
|
||||
|
||||
go func() {
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
nc.Close()
|
||||
}()
|
||||
|
||||
func() {
|
||||
for {
|
||||
select {
|
||||
case ch <- true:
|
||||
case <-wch:
|
||||
return
|
||||
case <-time.After(time.Second):
|
||||
t.Fatal("Failed to get async error cb")
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
ec = NewEConn(t)
|
||||
defer ec.Close()
|
||||
|
||||
nc = ec.Conn
|
||||
bch := make(chan []byte)
|
||||
|
||||
nc.Opts.AsyncErrorCB = func(c *nats.Conn, s *nats.Subscription, e error) {
|
||||
wch <- true
|
||||
}
|
||||
|
||||
if err := ec.BindSendChan("foo", bch); err != nil {
|
||||
t.Fatalf("Failed to bind to a receive channel: %v\n", err)
|
||||
}
|
||||
|
||||
buf := make([]byte, 2*1024*1024)
|
||||
bch <- buf
|
||||
|
||||
if e := Wait(wch); e != nil {
|
||||
t.Fatal("Failed to call async err handler")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSimpleRecvChan(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
|
||||
ec := NewEConn(t)
|
||||
defer ec.Close()
|
||||
|
||||
numSent := int32(22)
|
||||
ch := make(chan int32)
|
||||
|
||||
if _, err := ec.BindRecvChan("foo", ch); err != nil {
|
||||
t.Fatalf("Failed to bind to a receive channel: %v\n", err)
|
||||
}
|
||||
|
||||
ec.Publish("foo", numSent)
|
||||
|
||||
// Receive from 'foo'
|
||||
select {
|
||||
case num := <-ch:
|
||||
if num != numSent {
|
||||
t.Fatalf("Failed to receive correct value: %d vs %d\n", num, numSent)
|
||||
}
|
||||
case <-time.After(1 * time.Second):
|
||||
t.Fatalf("Failed to receive a value, timed-out\n")
|
||||
}
|
||||
close(ch)
|
||||
}
|
||||
|
||||
func TestQueueRecvChan(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
|
||||
ec := NewEConn(t)
|
||||
defer ec.Close()
|
||||
|
||||
numSent := int32(22)
|
||||
ch := make(chan int32)
|
||||
|
||||
if _, err := ec.BindRecvQueueChan("foo", "bar", ch); err != nil {
|
||||
t.Fatalf("Failed to bind to a queue receive channel: %v\n", err)
|
||||
}
|
||||
|
||||
ec.Publish("foo", numSent)
|
||||
|
||||
// Receive from 'foo'
|
||||
select {
|
||||
case num := <-ch:
|
||||
if num != numSent {
|
||||
t.Fatalf("Failed to receive correct value: %d vs %d\n", num, numSent)
|
||||
}
|
||||
case <-time.After(1 * time.Second):
|
||||
t.Fatalf("Failed to receive a value, timed-out\n")
|
||||
}
|
||||
close(ch)
|
||||
}
|
||||
|
||||
func TestDecoderErrRecvChan(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
|
||||
ec := NewEConn(t)
|
||||
defer ec.Close()
|
||||
nc := ec.Conn
|
||||
wch := make(chan bool)
|
||||
|
||||
nc.Opts.AsyncErrorCB = func(c *nats.Conn, s *nats.Subscription, e error) {
|
||||
wch <- true
|
||||
}
|
||||
|
||||
ch := make(chan *int32)
|
||||
|
||||
if _, err := ec.BindRecvChan("foo", ch); err != nil {
|
||||
t.Fatalf("Failed to bind to a send channel: %v\n", err)
|
||||
}
|
||||
|
||||
ec.Publish("foo", "Hello World")
|
||||
|
||||
if e := Wait(wch); e != nil {
|
||||
t.Fatal("Failed to call async err handler")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRecvChanPanicOnClosedChan(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
|
||||
ec := NewEConn(t)
|
||||
defer ec.Close()
|
||||
|
||||
ch := make(chan int)
|
||||
|
||||
if _, err := ec.BindRecvChan("foo", ch); err != nil {
|
||||
t.Fatalf("Failed to bind to a send channel: %v\n", err)
|
||||
}
|
||||
|
||||
close(ch)
|
||||
ec.Publish("foo", 22)
|
||||
ec.Flush()
|
||||
}
|
||||
|
||||
func TestRecvChanAsyncLeakGoRoutines(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
|
||||
ec := NewEConn(t)
|
||||
defer ec.Close()
|
||||
|
||||
// Call this to make sure that we have everything setup connection wise
|
||||
ec.Flush()
|
||||
|
||||
before := runtime.NumGoroutine()
|
||||
|
||||
ch := make(chan int)
|
||||
|
||||
if _, err := ec.BindRecvChan("foo", ch); err != nil {
|
||||
t.Fatalf("Failed to bind to a send channel: %v\n", err)
|
||||
}
|
||||
|
||||
// Close the receive Channel
|
||||
close(ch)
|
||||
|
||||
// The publish will trigger the close and shutdown of the Go routines
|
||||
ec.Publish("foo", 22)
|
||||
ec.Flush()
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
delta := (runtime.NumGoroutine() - before)
|
||||
|
||||
if delta > 0 {
|
||||
t.Fatalf("Leaked Go routine(s) : %d, closing channel should have closed them\n", delta)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRecvChanLeakGoRoutines(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
|
||||
ec := NewEConn(t)
|
||||
defer ec.Close()
|
||||
|
||||
// Call this to make sure that we have everything setup connection wise
|
||||
ec.Flush()
|
||||
|
||||
before := runtime.NumGoroutine()
|
||||
|
||||
ch := make(chan int)
|
||||
|
||||
sub, err := ec.BindRecvChan("foo", ch)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to bind to a send channel: %v\n", err)
|
||||
}
|
||||
sub.Unsubscribe()
|
||||
|
||||
// Sleep a bit to wait for the Go routine to exit.
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
|
||||
delta := (runtime.NumGoroutine() - before)
|
||||
|
||||
if delta > 0 {
|
||||
t.Fatalf("Leaked Go routine(s) : %d, closing channel should have closed them\n", delta)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRecvChanMultipleMessages(t *testing.T) {
|
||||
// Make sure we can receive more than one message.
|
||||
// In response to #25, which is a bug from fixing #22.
|
||||
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
|
||||
ec := NewEConn(t)
|
||||
defer ec.Close()
|
||||
|
||||
// Num to send, should == len of messages queued.
|
||||
size := 10
|
||||
|
||||
ch := make(chan int, size)
|
||||
|
||||
if _, err := ec.BindRecvChan("foo", ch); err != nil {
|
||||
t.Fatalf("Failed to bind to a send channel: %v\n", err)
|
||||
}
|
||||
|
||||
for i := 0; i < size; i++ {
|
||||
ec.Publish("foo", 22)
|
||||
}
|
||||
ec.Flush()
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
|
||||
if lch := len(ch); lch != size {
|
||||
t.Fatalf("Expected %d messages queued, got %d.", size, lch)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkPublishSpeedViaChan(b *testing.B) {
|
||||
b.StopTimer()
|
||||
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
|
||||
nc, err := nats.Connect(nats.DefaultURL)
|
||||
if err != nil {
|
||||
b.Fatalf("Could not connect: %v\n", err)
|
||||
}
|
||||
ec, err := nats.NewEncodedConn(nc, nats.DEFAULT_ENCODER)
|
||||
if err != nil {
|
||||
b.Fatalf("Failed creating encoded connection: %v\n", err)
|
||||
}
|
||||
defer ec.Close()
|
||||
|
||||
ch := make(chan int32, 1024)
|
||||
if err := ec.BindSendChan("foo", ch); err != nil {
|
||||
b.Fatalf("Failed to bind to a send channel: %v\n", err)
|
||||
}
|
||||
|
||||
b.StartTimer()
|
||||
|
||||
num := int32(22)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
ch <- num
|
||||
}
|
||||
// Make sure they are all processed.
|
||||
nc.Flush()
|
||||
b.StopTimer()
|
||||
}
|
126
gateway/vendor/github.com/nats-io/go-nats/test/protobuf_test.go
generated
vendored
Normal file
126
gateway/vendor/github.com/nats-io/go-nats/test/protobuf_test.go
generated
vendored
Normal file
@ -0,0 +1,126 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/nats-io/go-nats"
|
||||
|
||||
"github.com/nats-io/go-nats/encoders/protobuf"
|
||||
pb "github.com/nats-io/go-nats/encoders/protobuf/testdata"
|
||||
)
|
||||
|
||||
func NewProtoEncodedConn(tl TestLogger) *nats.EncodedConn {
|
||||
ec, err := nats.NewEncodedConn(NewConnection(tl, TEST_PORT), protobuf.PROTOBUF_ENCODER)
|
||||
if err != nil {
|
||||
tl.Fatalf("Failed to create an encoded connection: %v\n", err)
|
||||
}
|
||||
return ec
|
||||
}
|
||||
|
||||
func TestEncProtoMarshalStruct(t *testing.T) {
|
||||
s := RunServerOnPort(TEST_PORT)
|
||||
defer s.Shutdown()
|
||||
|
||||
ec := NewProtoEncodedConn(t)
|
||||
defer ec.Close()
|
||||
ch := make(chan bool)
|
||||
|
||||
me := &pb.Person{Name: "derek", Age: 22, Address: "140 New Montgomery St"}
|
||||
me.Children = make(map[string]*pb.Person)
|
||||
|
||||
me.Children["sam"] = &pb.Person{Name: "sam", Age: 19, Address: "140 New Montgomery St"}
|
||||
me.Children["meg"] = &pb.Person{Name: "meg", Age: 17, Address: "140 New Montgomery St"}
|
||||
|
||||
ec.Subscribe("protobuf_test", func(p *pb.Person) {
|
||||
if !reflect.DeepEqual(p, me) {
|
||||
t.Fatal("Did not receive the correct protobuf response")
|
||||
}
|
||||
ch <- true
|
||||
})
|
||||
|
||||
ec.Publish("protobuf_test", me)
|
||||
if e := Wait(ch); e != nil {
|
||||
t.Fatal("Did not receive the message")
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncProtoNilRequest(t *testing.T) {
|
||||
s := RunServerOnPort(TEST_PORT)
|
||||
defer s.Shutdown()
|
||||
|
||||
ec := NewProtoEncodedConn(t)
|
||||
defer ec.Close()
|
||||
|
||||
testPerson := &pb.Person{Name: "Anatolii", Age: 25, Address: "Ukraine, Nikolaev"}
|
||||
|
||||
//Subscribe with empty interface shouldn't failed on empty message
|
||||
ec.Subscribe("nil_test", func(_, reply string, _ interface{}) {
|
||||
ec.Publish(reply, testPerson)
|
||||
})
|
||||
|
||||
resp := new(pb.Person)
|
||||
|
||||
//Request with nil argument shouldn't failed with nil argument
|
||||
err := ec.Request("nil_test", nil, resp, 100*time.Millisecond)
|
||||
ec.Flush()
|
||||
|
||||
if err != nil {
|
||||
t.Error("Fail to send empty message via encoded proto connection")
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(testPerson, resp) {
|
||||
t.Error("Fail to receive encoded response")
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkProtobufMarshalStruct(b *testing.B) {
|
||||
me := &pb.Person{Name: "derek", Age: 22, Address: "140 New Montgomery St"}
|
||||
me.Children = make(map[string]*pb.Person)
|
||||
|
||||
me.Children["sam"] = &pb.Person{Name: "sam", Age: 19, Address: "140 New Montgomery St"}
|
||||
me.Children["meg"] = &pb.Person{Name: "meg", Age: 17, Address: "140 New Montgomery St"}
|
||||
|
||||
encoder := &protobuf.ProtobufEncoder{}
|
||||
for n := 0; n < b.N; n++ {
|
||||
if _, err := encoder.Encode("protobuf_test", me); err != nil {
|
||||
b.Fatal("Couldn't serialize object", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkPublishProtobufStruct(b *testing.B) {
|
||||
// stop benchmark for set-up
|
||||
b.StopTimer()
|
||||
|
||||
s := RunServerOnPort(TEST_PORT)
|
||||
defer s.Shutdown()
|
||||
|
||||
ec := NewProtoEncodedConn(b)
|
||||
defer ec.Close()
|
||||
ch := make(chan bool)
|
||||
|
||||
me := &pb.Person{Name: "derek", Age: 22, Address: "140 New Montgomery St"}
|
||||
me.Children = make(map[string]*pb.Person)
|
||||
|
||||
me.Children["sam"] = &pb.Person{Name: "sam", Age: 19, Address: "140 New Montgomery St"}
|
||||
me.Children["meg"] = &pb.Person{Name: "meg", Age: 17, Address: "140 New Montgomery St"}
|
||||
|
||||
ec.Subscribe("protobuf_test", func(p *pb.Person) {
|
||||
if !reflect.DeepEqual(p, me) {
|
||||
b.Fatalf("Did not receive the correct protobuf response")
|
||||
}
|
||||
ch <- true
|
||||
})
|
||||
|
||||
// resume benchmark
|
||||
b.StartTimer()
|
||||
|
||||
for n := 0; n < b.N; n++ {
|
||||
ec.Publish("protobuf_test", me)
|
||||
if e := Wait(ch); e != nil {
|
||||
b.Fatal("Did not receive the message")
|
||||
}
|
||||
}
|
||||
}
|
623
gateway/vendor/github.com/nats-io/go-nats/test/reconnect_test.go
generated
vendored
Normal file
623
gateway/vendor/github.com/nats-io/go-nats/test/reconnect_test.go
generated
vendored
Normal file
@ -0,0 +1,623 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/nats-io/gnatsd/server"
|
||||
"github.com/nats-io/go-nats"
|
||||
)
|
||||
|
||||
func startReconnectServer(t *testing.T) *server.Server {
|
||||
return RunServerOnPort(22222)
|
||||
}
|
||||
|
||||
func TestReconnectTotalTime(t *testing.T) {
|
||||
opts := nats.GetDefaultOptions()
|
||||
totalReconnectTime := time.Duration(opts.MaxReconnect) * opts.ReconnectWait
|
||||
if totalReconnectTime < (2 * time.Minute) {
|
||||
t.Fatalf("Total reconnect time should be at least 2 mins: Currently %v\n",
|
||||
totalReconnectTime)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReconnectDisallowedFlags(t *testing.T) {
|
||||
ts := startReconnectServer(t)
|
||||
defer ts.Shutdown()
|
||||
|
||||
ch := make(chan bool)
|
||||
opts := nats.GetDefaultOptions()
|
||||
opts.Url = "nats://localhost:22222"
|
||||
opts.AllowReconnect = false
|
||||
opts.ClosedCB = func(_ *nats.Conn) {
|
||||
ch <- true
|
||||
}
|
||||
nc, err := opts.Connect()
|
||||
if err != nil {
|
||||
t.Fatalf("Should have connected ok: %v", err)
|
||||
}
|
||||
defer nc.Close()
|
||||
|
||||
ts.Shutdown()
|
||||
|
||||
if e := Wait(ch); e != nil {
|
||||
t.Fatal("Did not trigger ClosedCB correctly")
|
||||
}
|
||||
}
|
||||
|
||||
func TestReconnectAllowedFlags(t *testing.T) {
|
||||
ts := startReconnectServer(t)
|
||||
defer ts.Shutdown()
|
||||
ch := make(chan bool)
|
||||
dch := make(chan bool)
|
||||
opts := nats.GetDefaultOptions()
|
||||
opts.Url = "nats://localhost:22222"
|
||||
opts.AllowReconnect = true
|
||||
opts.MaxReconnect = 2
|
||||
opts.ReconnectWait = 1 * time.Second
|
||||
|
||||
opts.ClosedCB = func(_ *nats.Conn) {
|
||||
ch <- true
|
||||
}
|
||||
opts.DisconnectedCB = func(_ *nats.Conn) {
|
||||
dch <- true
|
||||
}
|
||||
nc, err := opts.Connect()
|
||||
if err != nil {
|
||||
t.Fatalf("Should have connected ok: %v", err)
|
||||
}
|
||||
defer nc.Close()
|
||||
|
||||
ts.Shutdown()
|
||||
|
||||
// We want wait to timeout here, and the connection
|
||||
// should not trigger the Close CB.
|
||||
if e := WaitTime(ch, 500*time.Millisecond); e == nil {
|
||||
t.Fatal("Triggered ClosedCB incorrectly")
|
||||
}
|
||||
|
||||
// We should wait to get the disconnected callback to ensure
|
||||
// that we are in the process of reconnecting.
|
||||
if e := Wait(dch); e != nil {
|
||||
t.Fatal("DisconnectedCB should have been triggered")
|
||||
}
|
||||
|
||||
if !nc.IsReconnecting() {
|
||||
t.Fatal("Expected to be in a reconnecting state")
|
||||
}
|
||||
|
||||
// clear the CloseCB since ch will block
|
||||
nc.Opts.ClosedCB = nil
|
||||
}
|
||||
|
||||
var reconnectOpts = nats.Options{
|
||||
Url: "nats://localhost:22222",
|
||||
AllowReconnect: true,
|
||||
MaxReconnect: 10,
|
||||
ReconnectWait: 100 * time.Millisecond,
|
||||
Timeout: nats.DefaultTimeout,
|
||||
}
|
||||
|
||||
func TestConnCloseBreaksReconnectLoop(t *testing.T) {
|
||||
ts := startReconnectServer(t)
|
||||
defer ts.Shutdown()
|
||||
|
||||
cch := make(chan bool)
|
||||
|
||||
opts := reconnectOpts
|
||||
// Bump the max reconnect attempts
|
||||
opts.MaxReconnect = 100
|
||||
opts.ClosedCB = func(_ *nats.Conn) {
|
||||
cch <- true
|
||||
}
|
||||
nc, err := opts.Connect()
|
||||
if err != nil {
|
||||
t.Fatalf("Should have connected ok: %v", err)
|
||||
}
|
||||
defer nc.Close()
|
||||
nc.Flush()
|
||||
|
||||
// Shutdown the server
|
||||
ts.Shutdown()
|
||||
|
||||
// Wait a second, then close the connection
|
||||
time.Sleep(time.Second)
|
||||
|
||||
// Close the connection, this should break the reconnect loop.
|
||||
// Do this in a go routine since the issue was that Close()
|
||||
// would block until the reconnect loop is done.
|
||||
go nc.Close()
|
||||
|
||||
// Even on Windows (where a createConn takes more than a second)
|
||||
// we should be able to break the reconnect loop with the following
|
||||
// timeout.
|
||||
if err := WaitTime(cch, 3*time.Second); err != nil {
|
||||
t.Fatal("Did not get a closed callback")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBasicReconnectFunctionality(t *testing.T) {
|
||||
ts := startReconnectServer(t)
|
||||
defer ts.Shutdown()
|
||||
|
||||
ch := make(chan bool)
|
||||
dch := make(chan bool)
|
||||
|
||||
opts := reconnectOpts
|
||||
|
||||
opts.DisconnectedCB = func(_ *nats.Conn) {
|
||||
dch <- true
|
||||
}
|
||||
|
||||
nc, err := opts.Connect()
|
||||
if err != nil {
|
||||
t.Fatalf("Should have connected ok: %v\n", err)
|
||||
}
|
||||
defer nc.Close()
|
||||
ec, err := nats.NewEncodedConn(nc, nats.DEFAULT_ENCODER)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create an encoded connection: %v\n", err)
|
||||
}
|
||||
|
||||
testString := "bar"
|
||||
ec.Subscribe("foo", func(s string) {
|
||||
if s != testString {
|
||||
t.Fatal("String doesn't match")
|
||||
}
|
||||
ch <- true
|
||||
})
|
||||
ec.Flush()
|
||||
|
||||
ts.Shutdown()
|
||||
// server is stopped here...
|
||||
|
||||
if err := Wait(dch); err != nil {
|
||||
t.Fatalf("Did not get the disconnected callback on time\n")
|
||||
}
|
||||
|
||||
if err := ec.Publish("foo", testString); err != nil {
|
||||
t.Fatalf("Failed to publish message: %v\n", err)
|
||||
}
|
||||
|
||||
ts = startReconnectServer(t)
|
||||
defer ts.Shutdown()
|
||||
|
||||
if err := ec.FlushTimeout(5 * time.Second); err != nil {
|
||||
t.Fatalf("Error on Flush: %v", err)
|
||||
}
|
||||
|
||||
if e := Wait(ch); e != nil {
|
||||
t.Fatal("Did not receive our message")
|
||||
}
|
||||
|
||||
expectedReconnectCount := uint64(1)
|
||||
reconnectCount := ec.Conn.Stats().Reconnects
|
||||
|
||||
if reconnectCount != expectedReconnectCount {
|
||||
t.Fatalf("Reconnect count incorrect: %d vs %d\n",
|
||||
reconnectCount, expectedReconnectCount)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExtendedReconnectFunctionality(t *testing.T) {
|
||||
ts := startReconnectServer(t)
|
||||
defer ts.Shutdown()
|
||||
|
||||
opts := reconnectOpts
|
||||
dch := make(chan bool)
|
||||
opts.DisconnectedCB = func(_ *nats.Conn) {
|
||||
dch <- true
|
||||
}
|
||||
rch := make(chan bool)
|
||||
opts.ReconnectedCB = func(_ *nats.Conn) {
|
||||
rch <- true
|
||||
}
|
||||
nc, err := opts.Connect()
|
||||
if err != nil {
|
||||
t.Fatalf("Should have connected ok: %v", err)
|
||||
}
|
||||
defer nc.Close()
|
||||
ec, err := nats.NewEncodedConn(nc, nats.DEFAULT_ENCODER)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create an encoded connection: %v\n", err)
|
||||
}
|
||||
testString := "bar"
|
||||
received := int32(0)
|
||||
|
||||
ec.Subscribe("foo", func(s string) {
|
||||
atomic.AddInt32(&received, 1)
|
||||
})
|
||||
|
||||
sub, _ := ec.Subscribe("foobar", func(s string) {
|
||||
atomic.AddInt32(&received, 1)
|
||||
})
|
||||
|
||||
ec.Publish("foo", testString)
|
||||
ec.Flush()
|
||||
|
||||
ts.Shutdown()
|
||||
// server is stopped here..
|
||||
|
||||
// wait for disconnect
|
||||
if e := WaitTime(dch, 2*time.Second); e != nil {
|
||||
t.Fatal("Did not receive a disconnect callback message")
|
||||
}
|
||||
|
||||
// Sub while disconnected
|
||||
ec.Subscribe("bar", func(s string) {
|
||||
atomic.AddInt32(&received, 1)
|
||||
})
|
||||
|
||||
// Unsub foobar while disconnected
|
||||
sub.Unsubscribe()
|
||||
|
||||
if err = ec.Publish("foo", testString); err != nil {
|
||||
t.Fatalf("Received an error after disconnect: %v\n", err)
|
||||
}
|
||||
|
||||
if err = ec.Publish("bar", testString); err != nil {
|
||||
t.Fatalf("Received an error after disconnect: %v\n", err)
|
||||
}
|
||||
|
||||
ts = startReconnectServer(t)
|
||||
defer ts.Shutdown()
|
||||
|
||||
// server is restarted here..
|
||||
// wait for reconnect
|
||||
if e := WaitTime(rch, 2*time.Second); e != nil {
|
||||
t.Fatal("Did not receive a reconnect callback message")
|
||||
}
|
||||
|
||||
if err = ec.Publish("foobar", testString); err != nil {
|
||||
t.Fatalf("Received an error after server restarted: %v\n", err)
|
||||
}
|
||||
|
||||
if err = ec.Publish("foo", testString); err != nil {
|
||||
t.Fatalf("Received an error after server restarted: %v\n", err)
|
||||
}
|
||||
|
||||
ch := make(chan bool)
|
||||
ec.Subscribe("done", func(b bool) {
|
||||
ch <- true
|
||||
})
|
||||
ec.Publish("done", true)
|
||||
|
||||
if e := Wait(ch); e != nil {
|
||||
t.Fatal("Did not receive our message")
|
||||
}
|
||||
|
||||
// Sleep a bit to guarantee scheduler runs and process all subs.
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
|
||||
if atomic.LoadInt32(&received) != 4 {
|
||||
t.Fatalf("Received != %d, equals %d\n", 4, received)
|
||||
}
|
||||
}
|
||||
|
||||
func TestQueueSubsOnReconnect(t *testing.T) {
|
||||
ts := startReconnectServer(t)
|
||||
defer ts.Shutdown()
|
||||
|
||||
opts := reconnectOpts
|
||||
|
||||
// Allow us to block on reconnect complete.
|
||||
reconnectsDone := make(chan bool)
|
||||
opts.ReconnectedCB = func(nc *nats.Conn) {
|
||||
reconnectsDone <- true
|
||||
}
|
||||
|
||||
// Create connection
|
||||
nc, err := opts.Connect()
|
||||
if err != nil {
|
||||
t.Fatalf("Should have connected ok: %v\n", err)
|
||||
}
|
||||
defer nc.Close()
|
||||
|
||||
ec, err := nats.NewEncodedConn(nc, nats.JSON_ENCODER)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create an encoded connection: %v\n", err)
|
||||
}
|
||||
|
||||
// To hold results.
|
||||
results := make(map[int]int)
|
||||
var mu sync.Mutex
|
||||
|
||||
// Make sure we got what we needed, 1 msg only and all seqnos accounted for..
|
||||
checkResults := func(numSent int) {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
|
||||
for i := 0; i < numSent; i++ {
|
||||
if results[i] != 1 {
|
||||
t.Fatalf("Received incorrect number of messages, [%d] for seq: %d\n", results[i], i)
|
||||
}
|
||||
}
|
||||
|
||||
// Auto reset results map
|
||||
results = make(map[int]int)
|
||||
}
|
||||
|
||||
subj := "foo.bar"
|
||||
qgroup := "workers"
|
||||
|
||||
cb := func(seqno int) {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
results[seqno] = results[seqno] + 1
|
||||
}
|
||||
|
||||
// Create Queue Subscribers
|
||||
ec.QueueSubscribe(subj, qgroup, cb)
|
||||
ec.QueueSubscribe(subj, qgroup, cb)
|
||||
|
||||
ec.Flush()
|
||||
|
||||
// Helper function to send messages and check results.
|
||||
sendAndCheckMsgs := func(numToSend int) {
|
||||
for i := 0; i < numToSend; i++ {
|
||||
ec.Publish(subj, i)
|
||||
}
|
||||
// Wait for processing.
|
||||
ec.Flush()
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
|
||||
// Check Results
|
||||
checkResults(numToSend)
|
||||
}
|
||||
|
||||
// Base Test
|
||||
sendAndCheckMsgs(10)
|
||||
|
||||
// Stop and restart server
|
||||
ts.Shutdown()
|
||||
ts = startReconnectServer(t)
|
||||
defer ts.Shutdown()
|
||||
|
||||
if err := Wait(reconnectsDone); err != nil {
|
||||
t.Fatal("Did not get the ReconnectedCB!")
|
||||
}
|
||||
|
||||
// Reconnect Base Test
|
||||
sendAndCheckMsgs(10)
|
||||
}
|
||||
|
||||
func TestIsClosed(t *testing.T) {
|
||||
ts := startReconnectServer(t)
|
||||
defer ts.Shutdown()
|
||||
|
||||
nc := NewConnection(t, 22222)
|
||||
defer nc.Close()
|
||||
|
||||
if nc.IsClosed() {
|
||||
t.Fatalf("IsClosed returned true when the connection is still open.")
|
||||
}
|
||||
ts.Shutdown()
|
||||
if nc.IsClosed() {
|
||||
t.Fatalf("IsClosed returned true when the connection is still open.")
|
||||
}
|
||||
ts = startReconnectServer(t)
|
||||
defer ts.Shutdown()
|
||||
if nc.IsClosed() {
|
||||
t.Fatalf("IsClosed returned true when the connection is still open.")
|
||||
}
|
||||
nc.Close()
|
||||
if !nc.IsClosed() {
|
||||
t.Fatalf("IsClosed returned false after Close() was called.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsReconnectingAndStatus(t *testing.T) {
|
||||
ts := startReconnectServer(t)
|
||||
defer ts.Shutdown()
|
||||
|
||||
disconnectedch := make(chan bool)
|
||||
reconnectch := make(chan bool)
|
||||
opts := nats.GetDefaultOptions()
|
||||
opts.Url = "nats://localhost:22222"
|
||||
opts.AllowReconnect = true
|
||||
opts.MaxReconnect = 10000
|
||||
opts.ReconnectWait = 100 * time.Millisecond
|
||||
|
||||
opts.DisconnectedCB = func(_ *nats.Conn) {
|
||||
disconnectedch <- true
|
||||
}
|
||||
opts.ReconnectedCB = func(_ *nats.Conn) {
|
||||
reconnectch <- true
|
||||
}
|
||||
|
||||
// Connect, verify initial reconnecting state check, then stop the server
|
||||
nc, err := opts.Connect()
|
||||
if err != nil {
|
||||
t.Fatalf("Should have connected ok: %v", err)
|
||||
}
|
||||
defer nc.Close()
|
||||
|
||||
if nc.IsReconnecting() {
|
||||
t.Fatalf("IsReconnecting returned true when the connection is still open.")
|
||||
}
|
||||
if status := nc.Status(); status != nats.CONNECTED {
|
||||
t.Fatalf("Status returned %d when connected instead of CONNECTED", status)
|
||||
}
|
||||
ts.Shutdown()
|
||||
|
||||
// Wait until we get the disconnected callback
|
||||
if e := Wait(disconnectedch); e != nil {
|
||||
t.Fatalf("Disconnect callback wasn't triggered: %v", e)
|
||||
}
|
||||
if !nc.IsReconnecting() {
|
||||
t.Fatalf("IsReconnecting returned false when the client is reconnecting.")
|
||||
}
|
||||
if status := nc.Status(); status != nats.RECONNECTING {
|
||||
t.Fatalf("Status returned %d when reconnecting instead of CONNECTED", status)
|
||||
}
|
||||
|
||||
ts = startReconnectServer(t)
|
||||
defer ts.Shutdown()
|
||||
|
||||
// Wait until we get the reconnect callback
|
||||
if e := Wait(reconnectch); e != nil {
|
||||
t.Fatalf("Reconnect callback wasn't triggered: %v", e)
|
||||
}
|
||||
if nc.IsReconnecting() {
|
||||
t.Fatalf("IsReconnecting returned true after the connection was reconnected.")
|
||||
}
|
||||
if status := nc.Status(); status != nats.CONNECTED {
|
||||
t.Fatalf("Status returned %d when reconnected instead of CONNECTED", status)
|
||||
}
|
||||
|
||||
// Close the connection, reconnecting should still be false
|
||||
nc.Close()
|
||||
if nc.IsReconnecting() {
|
||||
t.Fatalf("IsReconnecting returned true after Close() was called.")
|
||||
}
|
||||
if status := nc.Status(); status != nats.CLOSED {
|
||||
t.Fatalf("Status returned %d after Close() was called instead of CLOSED", status)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFullFlushChanDuringReconnect(t *testing.T) {
|
||||
ts := startReconnectServer(t)
|
||||
defer ts.Shutdown()
|
||||
|
||||
reconnectch := make(chan bool)
|
||||
|
||||
opts := nats.GetDefaultOptions()
|
||||
opts.Url = "nats://localhost:22222"
|
||||
opts.AllowReconnect = true
|
||||
opts.MaxReconnect = 10000
|
||||
opts.ReconnectWait = 100 * time.Millisecond
|
||||
|
||||
opts.ReconnectedCB = func(_ *nats.Conn) {
|
||||
reconnectch <- true
|
||||
}
|
||||
|
||||
// Connect
|
||||
nc, err := opts.Connect()
|
||||
if err != nil {
|
||||
t.Fatalf("Should have connected ok: %v", err)
|
||||
}
|
||||
defer nc.Close()
|
||||
|
||||
// Channel used to make the go routine sending messages to stop.
|
||||
stop := make(chan bool)
|
||||
|
||||
// While connected, publish as fast as we can
|
||||
go func() {
|
||||
for i := 0; ; i++ {
|
||||
_ = nc.Publish("foo", []byte("hello"))
|
||||
|
||||
// Make sure we are sending at least flushChanSize (1024) messages
|
||||
// before potentially pausing.
|
||||
if i%2000 == 0 {
|
||||
select {
|
||||
case <-stop:
|
||||
return
|
||||
default:
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
// Send a bit...
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
|
||||
// Shut down the server
|
||||
ts.Shutdown()
|
||||
|
||||
// Continue sending while we are disconnected
|
||||
time.Sleep(time.Second)
|
||||
|
||||
// Restart the server
|
||||
ts = startReconnectServer(t)
|
||||
defer ts.Shutdown()
|
||||
|
||||
// Wait for the reconnect CB to be invoked (but not for too long)
|
||||
if e := WaitTime(reconnectch, 5*time.Second); e != nil {
|
||||
t.Fatalf("Reconnect callback wasn't triggered: %v", e)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReconnectVerbose(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
|
||||
o := nats.GetDefaultOptions()
|
||||
o.Verbose = true
|
||||
rch := make(chan bool)
|
||||
o.ReconnectedCB = func(_ *nats.Conn) {
|
||||
rch <- true
|
||||
}
|
||||
|
||||
nc, err := o.Connect()
|
||||
if err != nil {
|
||||
t.Fatalf("Should have connected ok: %v", err)
|
||||
}
|
||||
defer nc.Close()
|
||||
|
||||
err = nc.Flush()
|
||||
if err != nil {
|
||||
t.Fatalf("Error during flush: %v", err)
|
||||
}
|
||||
|
||||
s.Shutdown()
|
||||
s = RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
|
||||
if e := Wait(rch); e != nil {
|
||||
t.Fatal("Should have reconnected ok")
|
||||
}
|
||||
|
||||
err = nc.Flush()
|
||||
if err != nil {
|
||||
t.Fatalf("Error during flush: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReconnectBufSize(t *testing.T) {
|
||||
s := RunDefaultServer()
|
||||
defer s.Shutdown()
|
||||
|
||||
o := nats.GetDefaultOptions()
|
||||
o.ReconnectBufSize = 32 // 32 bytes
|
||||
|
||||
dch := make(chan bool)
|
||||
o.DisconnectedCB = func(_ *nats.Conn) {
|
||||
dch <- true
|
||||
}
|
||||
|
||||
nc, err := o.Connect()
|
||||
if err != nil {
|
||||
t.Fatalf("Should have connected ok: %v", err)
|
||||
}
|
||||
defer nc.Close()
|
||||
|
||||
err = nc.Flush()
|
||||
if err != nil {
|
||||
t.Fatalf("Error during flush: %v", err)
|
||||
}
|
||||
|
||||
// Force disconnected state.
|
||||
s.Shutdown()
|
||||
|
||||
if e := Wait(dch); e != nil {
|
||||
t.Fatal("DisconnectedCB should have been triggered")
|
||||
}
|
||||
|
||||
msg := []byte("food") // 4 bytes paylaod, total proto is 16 bytes
|
||||
// These should work, 2X16 = 32
|
||||
if err := nc.Publish("foo", msg); err != nil {
|
||||
t.Fatalf("Failed to publish message: %v\n", err)
|
||||
}
|
||||
if err := nc.Publish("foo", msg); err != nil {
|
||||
t.Fatalf("Failed to publish message: %v\n", err)
|
||||
}
|
||||
|
||||
// This should fail since we have exhausted the backing buffer.
|
||||
if err := nc.Publish("foo", msg); err == nil {
|
||||
t.Fatalf("Expected to fail to publish message: got no error\n")
|
||||
}
|
||||
nc.Buffered()
|
||||
}
|
1479
gateway/vendor/github.com/nats-io/go-nats/test/sub_test.go
generated
vendored
Normal file
1479
gateway/vendor/github.com/nats-io/go-nats/test/sub_test.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user