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:
28
gateway/vendor/github.com/nats-io/go-nats-streaming/.gitignore
generated
vendored
Normal file
28
gateway/vendor/github.com/nats-io/go-nats-streaming/.gitignore
generated
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
*.test
|
||||
*.prof
|
||||
|
||||
# Eclipse stuff
|
||||
.project
|
||||
.settings/
|
22
gateway/vendor/github.com/nats-io/go-nats-streaming/.travis.yml
generated
vendored
Normal file
22
gateway/vendor/github.com/nats-io/go-nats-streaming/.travis.yml
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
language: go
|
||||
sudo: false
|
||||
go:
|
||||
- 1.6.4
|
||||
- 1.7.4
|
||||
install:
|
||||
- go get -t ./...
|
||||
- go get github.com/nats-io/nats-streaming-server
|
||||
- go get github.com/mattn/goveralls
|
||||
- go get github.com/wadey/gocovmerge
|
||||
- go get honnef.co/go/staticcheck/cmd/staticcheck
|
||||
script:
|
||||
- go fmt ./...
|
||||
- go vet ./...
|
||||
- go test -i -race ./...
|
||||
- go test -v -race ./...
|
||||
- staticcheck ./...
|
||||
after_success:
|
||||
- if [ "$TRAVIS_GO_VERSION" \> "1.7." ]; then ./scripts/cov.sh TRAVIS; fi
|
||||
env:
|
||||
global:
|
||||
secure: OoCemKSHHH/SkkamHLWd0qh9qgQDx4/3fGuykYuzW/gjUhLlL0ThyUXOr3HOandoh3wTU8Ntj184WU6Sjh1oXzdDAYcI/ryNQXSmJ/DyGC6ffoj4Je/Rwj3sbwpaFTl1imawL8Lv6+5Dkb2JSbbbqapjbO3BhrrNfqLuQulqrLJKVaOyS5nOByiGFYsgjf/ac7Qrr9AnHhlkWRXoR+q8GlGG7qcKtLlmG5OqxifqfgQ+pcVtyeleT6zGPI0LUyr9gWHRZtMK9nYfxXuQK2d7V+SW4NBW1jdDKBHZbeJRxZ8N8rU8Nk3ka54YHXC2PeD8EloiAr5HkALuHbIdzyy40Y3rJyHfxyY6EYBcZEy+ZCRoqkVJ4NN4R46YE588BpYhT48YHK+lptM7YxrPtf08X+Cugc206X0hk/YFqqsaaNIwMfiTPbapuHxa8S4kgT2vDn3OTI53ZTrDiLVY3ZDp+EdUO1hiYFR6cpu5el/EQN5G0iW6sI69gOv26UmGI369D3fezbYPFPHHDao8xq7s8HdYUZleDNL0oCWK1MgL2g/Irbt5Kr6JjT/tpQOiiagqeR5dlV9mAiOZFr88gg7aqwOuSqmlULWVB4qYncQ6IBoednIHtrLW6H+2RfrZU01cI6tGSrXD+VoFnQ7aZwLxLc71VyN5khYPk0gGvyQhZxk=
|
11
gateway/vendor/github.com/nats-io/go-nats-streaming/README.md
generated
vendored
11
gateway/vendor/github.com/nats-io/go-nats-streaming/README.md
generated
vendored
@ -2,7 +2,7 @@
|
||||
|
||||
NATS Streaming is an extremely performant, lightweight reliable streaming platform powered by [NATS](https://nats.io).
|
||||
|
||||
[](http://opensource.org/licenses/MIT)
|
||||
[](http://opensource.org/licenses/MIT)
|
||||
[](http://travis-ci.org/nats-io/go-nats-streaming)
|
||||
[](https://coveralls.io/r/nats-io/go-nats-streaming?branch=master)
|
||||
|
||||
@ -17,6 +17,9 @@ NATS Streaming provides the following high-level feature set:
|
||||
|
||||
- Please raise questions/issues via the [Issue Tracker](https://github.com/nats-io/go-nats-streaming/issues).
|
||||
|
||||
## Known Issues
|
||||
- Time- and sequence-based subscriptions are exact. Requesting a time or seqno before the earliest stored message for a subject will result in an error (in SubscriptionRequest.Error)
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
@ -181,7 +184,7 @@ that is, the start position will take effect and delivery will start from there.
|
||||
|
||||
### Durable Queue Groups
|
||||
|
||||
As described above, for non durable queue subscribers, when the last member leaves the group,
|
||||
As described above, for non durable queue subsribers, when the last member leaves the group,
|
||||
that group is removed. A durable queue group allows you to have all members leave but still
|
||||
maintain state. When a member re-joins, it starts at the last position in that group.
|
||||
|
||||
@ -217,7 +220,7 @@ The rules for non-durable queue subscribers apply to durable subscribers.
|
||||
|
||||
As for non-durable queue subscribers, if a member's connection is closed, or if
|
||||
`Unsubscribe` its called, the member leaves the group. Any unacknowledged message
|
||||
is transferred to remaining members. See *Closing the Group* for important difference
|
||||
is transfered to remaining members. See *Closing the Group* for important difference
|
||||
with non-durable queue subscribers.
|
||||
|
||||
#### Closing the Group
|
||||
@ -298,7 +301,7 @@ ah := func(nuid string, err error) {
|
||||
}
|
||||
|
||||
for i := 1; i < 1000; i++ {
|
||||
// If the server is unable to keep up with the publisher, the number of outstanding acks will eventually
|
||||
// If the server is unable to keep up with the publisher, the number of oustanding acks will eventually
|
||||
// reach the max and this call will block
|
||||
guid, _ := sc.PublishAsync("foo", []byte("Hello World"), ah)
|
||||
}
|
||||
|
15
gateway/vendor/github.com/nats-io/go-nats-streaming/TODO.md
generated
vendored
Normal file
15
gateway/vendor/github.com/nats-io/go-nats-streaming/TODO.md
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
|
||||
- [ ] Retry limits?
|
||||
- [ ] Server Store Limits (time, msgs, byte)
|
||||
- [X] Change time to deltas
|
||||
- [X] Server heartbeat, release dead clients.
|
||||
- [X] Require clientID for published messages, error if not registered.
|
||||
- [X] Check for need of ackMap (out of order re-delivery to queue subscribers).
|
||||
- [X] Redelivered Flag for Msg.
|
||||
- [X] Queue Subscribers
|
||||
- [X] Durable Subscribers (survive reconnect, etc)
|
||||
- [X] Start Positions on Subscribers
|
||||
- [X] Ack for delivered just Reply? No need on ConnectedResponse?
|
||||
- [X] PublishWithReply, or option.
|
||||
- [X] Data Races in Server.
|
||||
- [X] Manual Ack?
|
245
gateway/vendor/github.com/nats-io/go-nats-streaming/benchmark_test.go
generated
vendored
Normal file
245
gateway/vendor/github.com/nats-io/go-nats-streaming/benchmark_test.go
generated
vendored
Normal file
@ -0,0 +1,245 @@
|
||||
package stan
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Benchmarks
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func BenchmarkPublish(b *testing.B) {
|
||||
b.StopTimer()
|
||||
|
||||
// Run a NATS Streaming server
|
||||
s := RunServer(clusterName)
|
||||
defer s.Shutdown()
|
||||
sc := NewDefaultConnection(b)
|
||||
defer sc.Close()
|
||||
|
||||
hw := []byte("Hello World")
|
||||
|
||||
b.StartTimer()
|
||||
b.ReportAllocs()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
if err := sc.Publish("foo", hw); err != nil {
|
||||
b.Fatalf("Got error on publish: %v\n", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkPublishAsync(b *testing.B) {
|
||||
b.StopTimer()
|
||||
|
||||
// Run a NATS Streaming server
|
||||
s := RunServer(clusterName)
|
||||
defer s.Shutdown()
|
||||
sc := NewDefaultConnection(b)
|
||||
defer sc.Close()
|
||||
|
||||
hw := []byte("Hello World")
|
||||
|
||||
ch := make(chan bool)
|
||||
received := int32(0)
|
||||
|
||||
ah := func(guid string, err error) {
|
||||
if err != nil {
|
||||
b.Fatalf("Received an error in ack callback: %v\n", err)
|
||||
}
|
||||
if nr := atomic.AddInt32(&received, 1); nr >= int32(b.N) {
|
||||
ch <- true
|
||||
}
|
||||
}
|
||||
b.StartTimer()
|
||||
b.ReportAllocs()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
if _, err := sc.PublishAsync("foo", hw, ah); err != nil {
|
||||
//fmt.Printf("Client status %v, Server status %v\n", s.nc.Status(), (sc.(*conn)).nc.Status())
|
||||
fmt.Printf("len(ackmap) = %d\n", len(sc.(*conn).pubAckMap))
|
||||
|
||||
b.Fatalf("Error from PublishAsync: %v\n", err)
|
||||
}
|
||||
}
|
||||
|
||||
err := WaitTime(ch, 10*time.Second)
|
||||
if err != nil {
|
||||
fmt.Printf("sc error is %v\n", sc.(*conn).nc.LastError())
|
||||
b.Fatal("Timed out waiting for ack messages")
|
||||
} else if atomic.LoadInt32(&received) != int32(b.N) {
|
||||
b.Fatalf("Received: %d", received)
|
||||
}
|
||||
|
||||
// msgs, bytes, _ := sc.(*conn).ackSubscription.MaxPending()
|
||||
// fmt.Printf("max pending msgs:%d bytes:%d\n", msgs, bytes)
|
||||
}
|
||||
|
||||
func BenchmarkSubscribe(b *testing.B) {
|
||||
b.StopTimer()
|
||||
|
||||
// Run a NATS Streaming server
|
||||
s := RunServer(clusterName)
|
||||
defer s.Shutdown()
|
||||
sc := NewDefaultConnection(b)
|
||||
defer sc.Close()
|
||||
|
||||
hw := []byte("Hello World")
|
||||
pch := make(chan bool)
|
||||
|
||||
// Queue up all the messages. Keep this outside of the timing.
|
||||
for i := 0; i < b.N; i++ {
|
||||
if i == b.N-1 {
|
||||
// last one
|
||||
sc.PublishAsync("foo", hw, func(lguid string, err error) {
|
||||
if err != nil {
|
||||
b.Fatalf("Got an error from ack handler, %v", err)
|
||||
}
|
||||
pch <- true
|
||||
})
|
||||
} else {
|
||||
sc.PublishAsync("foo", hw, nil)
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for published to finish
|
||||
if err := WaitTime(pch, 10*time.Second); err != nil {
|
||||
b.Fatalf("Error waiting for publish to finish\n")
|
||||
}
|
||||
|
||||
ch := make(chan bool)
|
||||
received := int32(0)
|
||||
|
||||
b.StartTimer()
|
||||
b.ReportAllocs()
|
||||
|
||||
sc.Subscribe("foo", func(m *Msg) {
|
||||
if nr := atomic.AddInt32(&received, 1); nr >= int32(b.N) {
|
||||
ch <- true
|
||||
}
|
||||
}, DeliverAllAvailable())
|
||||
|
||||
err := WaitTime(ch, 10*time.Second)
|
||||
nr := atomic.LoadInt32(&received)
|
||||
if err != nil {
|
||||
b.Fatalf("Timed out waiting for messages, received only %d of %d\n", nr, b.N)
|
||||
} else if nr != int32(b.N) {
|
||||
b.Fatalf("Only Received: %d of %d", received, b.N)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkQueueSubscribe(b *testing.B) {
|
||||
b.StopTimer()
|
||||
|
||||
// Run a NATS Streaming server
|
||||
s := RunServer(clusterName)
|
||||
defer s.Shutdown()
|
||||
sc := NewDefaultConnection(b)
|
||||
defer sc.Close()
|
||||
|
||||
hw := []byte("Hello World")
|
||||
pch := make(chan bool)
|
||||
|
||||
// Queue up all the messages. Keep this outside of the timing.
|
||||
for i := 0; i < b.N; i++ {
|
||||
if i == b.N-1 {
|
||||
// last one
|
||||
sc.PublishAsync("foo", hw, func(lguid string, err error) {
|
||||
if err != nil {
|
||||
b.Fatalf("Got an error from ack handler, %v", err)
|
||||
}
|
||||
pch <- true
|
||||
})
|
||||
} else {
|
||||
sc.PublishAsync("foo", hw, nil)
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for published to finish
|
||||
if err := WaitTime(pch, 10*time.Second); err != nil {
|
||||
b.Fatalf("Error waiting for publish to finish\n")
|
||||
}
|
||||
|
||||
ch := make(chan bool)
|
||||
received := int32(0)
|
||||
|
||||
b.StartTimer()
|
||||
b.ReportAllocs()
|
||||
|
||||
mcb := func(m *Msg) {
|
||||
if nr := atomic.AddInt32(&received, 1); nr >= int32(b.N) {
|
||||
ch <- true
|
||||
}
|
||||
}
|
||||
|
||||
sc.QueueSubscribe("foo", "bar", mcb, DeliverAllAvailable())
|
||||
sc.QueueSubscribe("foo", "bar", mcb, DeliverAllAvailable())
|
||||
sc.QueueSubscribe("foo", "bar", mcb, DeliverAllAvailable())
|
||||
sc.QueueSubscribe("foo", "bar", mcb, DeliverAllAvailable())
|
||||
|
||||
err := WaitTime(ch, 20*time.Second)
|
||||
nr := atomic.LoadInt32(&received)
|
||||
if err != nil {
|
||||
b.Fatalf("Timed out waiting for messages, received only %d of %d\n", nr, b.N)
|
||||
} else if nr != int32(b.N) {
|
||||
b.Fatalf("Only Received: %d of %d", received, b.N)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkPublishSubscribe(b *testing.B) {
|
||||
b.StopTimer()
|
||||
|
||||
// Run a NATS Streaming server
|
||||
s := RunServer(clusterName)
|
||||
defer s.Shutdown()
|
||||
sc := NewDefaultConnection(b)
|
||||
defer sc.Close()
|
||||
|
||||
hw := []byte("Hello World")
|
||||
|
||||
ch := make(chan bool)
|
||||
received := int32(0)
|
||||
|
||||
// Subscribe callback, counts msgs received.
|
||||
_, err := sc.Subscribe("foo", func(m *Msg) {
|
||||
if nr := atomic.AddInt32(&received, 1); nr >= int32(b.N) {
|
||||
ch <- true
|
||||
}
|
||||
}, DeliverAllAvailable())
|
||||
|
||||
if err != nil {
|
||||
b.Fatalf("Error subscribing, %v", err)
|
||||
}
|
||||
|
||||
b.StartTimer()
|
||||
b.ReportAllocs()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, err := sc.PublishAsync("foo", hw, func(guid string, err error) {
|
||||
if err != nil {
|
||||
b.Fatalf("Received an error in publish ack callback: %v\n", err)
|
||||
}
|
||||
})
|
||||
if err != nil {
|
||||
b.Fatalf("Error publishing %v\n", err)
|
||||
}
|
||||
}
|
||||
|
||||
err = WaitTime(ch, 30*time.Second)
|
||||
nr := atomic.LoadInt32(&received)
|
||||
if err != nil {
|
||||
b.Fatalf("Timed out waiting for messages, received only %d of %d\n", nr, b.N)
|
||||
} else if nr != int32(b.N) {
|
||||
b.Fatalf("Only Received: %d of %d", received, b.N)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkTimeNow(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
now := time.Now()
|
||||
now.Add(10 * time.Nanosecond)
|
||||
}
|
||||
}
|
194
gateway/vendor/github.com/nats-io/go-nats-streaming/examples/stan-bench.go
generated
vendored
Normal file
194
gateway/vendor/github.com/nats-io/go-nats-streaming/examples/stan-bench.go
generated
vendored
Normal file
@ -0,0 +1,194 @@
|
||||
// Copyright 2015 Apcera Inc. All rights reserved.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/nats-io/go-nats"
|
||||
"github.com/nats-io/go-nats-streaming"
|
||||
"github.com/nats-io/go-nats/bench"
|
||||
)
|
||||
|
||||
// Some sane defaults
|
||||
const (
|
||||
DefaultNumMsgs = 100000
|
||||
DefaultNumPubs = 1
|
||||
DefaultNumSubs = 0
|
||||
DefaultAsync = false
|
||||
DefaultMessageSize = 128
|
||||
DefaultIgnoreOld = false
|
||||
DefaultMaxPubAcksInflight = 1000
|
||||
DefaultClientID = "benchmark"
|
||||
)
|
||||
|
||||
func usage() {
|
||||
log.Fatalf("Usage: nats-bench [-s server (%s)] [--tls] [-id CLIENT_ID] [-np NUM_PUBLISHERS] [-ns NUM_SUBSCRIBERS] [-n NUM_MSGS] [-ms MESSAGE_SIZE] [-csv csvfile] [-mpa MAX_NUMBER_OF_PUBLISHED_ACKS_INFLIGHT] [-io] [-a] <subject>\n", nats.DefaultURL)
|
||||
}
|
||||
|
||||
var benchmark *bench.Benchmark
|
||||
|
||||
func main() {
|
||||
var urls = flag.String("s", nats.DefaultURL, "The NATS server URLs (separated by comma")
|
||||
var tls = flag.Bool("tls", false, "Use TLS secure sonnection")
|
||||
var numPubs = flag.Int("np", DefaultNumPubs, "Number of concurrent publishers")
|
||||
var numSubs = flag.Int("ns", DefaultNumSubs, "Number of concurrent subscribers")
|
||||
var numMsgs = flag.Int("n", DefaultNumMsgs, "Number of messages to publish")
|
||||
var async = flag.Bool("a", DefaultAsync, "Async message publishing")
|
||||
var messageSize = flag.Int("ms", DefaultMessageSize, "Message size in bytes.")
|
||||
var ignoreOld = flag.Bool("io", DefaultIgnoreOld, "Subscribers ignore old messages")
|
||||
var maxPubAcks = flag.Int("mpa", DefaultMaxPubAcksInflight, "Max number of published acks in flight")
|
||||
var clientID = flag.String("id", DefaultClientID, "Benchmark process base client ID")
|
||||
var csvFile = flag.String("csv", "", "Save bench data to csv file")
|
||||
|
||||
log.SetFlags(0)
|
||||
flag.Usage = usage
|
||||
flag.Parse()
|
||||
|
||||
args := flag.Args()
|
||||
if len(args) != 1 {
|
||||
usage()
|
||||
}
|
||||
|
||||
// Setup the option block
|
||||
opts := nats.DefaultOptions
|
||||
opts.Servers = strings.Split(*urls, ",")
|
||||
for i, s := range opts.Servers {
|
||||
opts.Servers[i] = strings.Trim(s, " ")
|
||||
}
|
||||
|
||||
opts.Secure = *tls
|
||||
|
||||
benchmark = bench.NewBenchmark("NATS Streaming", *numSubs, *numPubs)
|
||||
|
||||
var startwg sync.WaitGroup
|
||||
var donewg sync.WaitGroup
|
||||
|
||||
donewg.Add(*numPubs + *numSubs)
|
||||
|
||||
// Run Subscribers first
|
||||
startwg.Add(*numSubs)
|
||||
for i := 0; i < *numSubs; i++ {
|
||||
subID := fmt.Sprintf("%s-sub-%d", *clientID, i)
|
||||
go runSubscriber(&startwg, &donewg, opts, *numMsgs, *messageSize, *ignoreOld, subID)
|
||||
}
|
||||
startwg.Wait()
|
||||
|
||||
// Now Publishers
|
||||
startwg.Add(*numPubs)
|
||||
pubCounts := bench.MsgsPerClient(*numMsgs, *numPubs)
|
||||
for i := 0; i < *numPubs; i++ {
|
||||
pubID := fmt.Sprintf("%s-pub-%d", *clientID, i)
|
||||
go runPublisher(&startwg, &donewg, opts, pubCounts[i], *messageSize, *async, pubID, *maxPubAcks)
|
||||
}
|
||||
|
||||
log.Printf("Starting benchmark [msgs=%d, msgsize=%d, pubs=%d, subs=%d]\n", *numMsgs, *messageSize, *numPubs, *numSubs)
|
||||
|
||||
startwg.Wait()
|
||||
donewg.Wait()
|
||||
|
||||
benchmark.Close()
|
||||
fmt.Print(benchmark.Report())
|
||||
|
||||
if len(*csvFile) > 0 {
|
||||
csv := benchmark.CSV()
|
||||
ioutil.WriteFile(*csvFile, []byte(csv), 0644)
|
||||
fmt.Printf("Saved metric data in csv file %s\n", *csvFile)
|
||||
}
|
||||
}
|
||||
|
||||
func runPublisher(startwg, donewg *sync.WaitGroup, opts nats.Options, numMsgs int, msgSize int, async bool, pubID string, maxPubAcksInflight int) {
|
||||
nc, err := opts.Connect()
|
||||
if err != nil {
|
||||
log.Fatalf("Publisher %s can't connect: %v\n", pubID, err)
|
||||
}
|
||||
snc, err := stan.Connect("test-cluster", pubID, stan.MaxPubAcksInflight(maxPubAcksInflight), stan.NatsConn(nc))
|
||||
if err != nil {
|
||||
log.Fatalf("Publisher %s can't connect: %v\n", pubID, err)
|
||||
}
|
||||
|
||||
startwg.Done()
|
||||
|
||||
args := flag.Args()
|
||||
|
||||
subj := args[0]
|
||||
var msg []byte
|
||||
if msgSize > 0 {
|
||||
msg = make([]byte, msgSize)
|
||||
}
|
||||
published := 0
|
||||
start := time.Now()
|
||||
|
||||
if async {
|
||||
ch := make(chan bool)
|
||||
acb := func(lguid string, err error) {
|
||||
published++
|
||||
if published >= numMsgs {
|
||||
ch <- true
|
||||
}
|
||||
}
|
||||
for i := 0; i < numMsgs; i++ {
|
||||
_, err := snc.PublishAsync(subj, msg, acb)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
<-ch
|
||||
} else {
|
||||
for i := 0; i < numMsgs; i++ {
|
||||
err := snc.Publish(subj, msg)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
published++
|
||||
}
|
||||
}
|
||||
|
||||
benchmark.AddPubSample(bench.NewSample(numMsgs, msgSize, start, time.Now(), snc.NatsConn()))
|
||||
snc.Close()
|
||||
nc.Close()
|
||||
donewg.Done()
|
||||
}
|
||||
|
||||
func runSubscriber(startwg, donewg *sync.WaitGroup, opts nats.Options, numMsgs int, msgSize int, ignoreOld bool, subID string) {
|
||||
nc, err := opts.Connect()
|
||||
if err != nil {
|
||||
log.Fatalf("Subscriber %s can't connect: %v\n", subID, err)
|
||||
}
|
||||
snc, err := stan.Connect("test-cluster", subID, stan.NatsConn(nc))
|
||||
if err != nil {
|
||||
log.Fatalf("Subscriber %s can't connect: %v\n", subID, err)
|
||||
}
|
||||
|
||||
args := flag.Args()
|
||||
subj := args[0]
|
||||
ch := make(chan bool)
|
||||
start := time.Now()
|
||||
|
||||
received := 0
|
||||
mcb := func(msg *stan.Msg) {
|
||||
received++
|
||||
if received >= numMsgs {
|
||||
ch <- true
|
||||
}
|
||||
}
|
||||
|
||||
if ignoreOld {
|
||||
snc.Subscribe(subj, mcb)
|
||||
} else {
|
||||
snc.Subscribe(subj, mcb, stan.DeliverAllAvailable())
|
||||
}
|
||||
startwg.Done()
|
||||
|
||||
<-ch
|
||||
benchmark.AddSubSample(bench.NewSample(numMsgs, msgSize, start, time.Now(), snc.NatsConn()))
|
||||
snc.Close()
|
||||
nc.Close()
|
||||
donewg.Done()
|
||||
}
|
108
gateway/vendor/github.com/nats-io/go-nats-streaming/examples/stan-pub.go
generated
vendored
Normal file
108
gateway/vendor/github.com/nats-io/go-nats-streaming/examples/stan-pub.go
generated
vendored
Normal file
@ -0,0 +1,108 @@
|
||||
// Copyright 2012-2016 Apcera Inc. All rights reserved.
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/nats-io/go-nats-streaming"
|
||||
)
|
||||
|
||||
var usageStr = `
|
||||
Usage: stan-pub [options] <subject> <message>
|
||||
|
||||
Options:
|
||||
-s, --server <url> NATS Streaming server URL(s)
|
||||
-c, --cluster <cluster name> NATS Streaming cluster name
|
||||
-id,--clientid <client ID> NATS Streaming client ID
|
||||
-a, --async Asynchronous publish mode
|
||||
`
|
||||
|
||||
// NOTE: Use tls scheme for TLS, e.g. stan-pub -s tls://demo.nats.io:4443 foo hello
|
||||
func usage() {
|
||||
fmt.Printf("%s\n", usageStr)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
func main() {
|
||||
var clusterID string
|
||||
var clientID string
|
||||
var async bool
|
||||
var URL string
|
||||
|
||||
flag.StringVar(&URL, "s", stan.DefaultNatsURL, "The nats server URLs (separated by comma)")
|
||||
flag.StringVar(&URL, "server", stan.DefaultNatsURL, "The nats server URLs (separated by comma)")
|
||||
flag.StringVar(&clusterID, "c", "test-cluster", "The NATS Streaming cluster ID")
|
||||
flag.StringVar(&clusterID, "cluster", "test-cluster", "The NATS Streaming cluster ID")
|
||||
flag.StringVar(&clientID, "id", "stan-pub", "The NATS Streaming client ID to connect with")
|
||||
flag.StringVar(&clientID, "clientid", "stan-pub", "The NATS Streaming client ID to connect with")
|
||||
flag.BoolVar(&async, "a", false, "Publish asynchronously")
|
||||
flag.BoolVar(&async, "async", false, "Publish asynchronously")
|
||||
|
||||
log.SetFlags(0)
|
||||
flag.Usage = usage
|
||||
flag.Parse()
|
||||
|
||||
args := flag.Args()
|
||||
|
||||
if len(args) < 1 {
|
||||
usage()
|
||||
}
|
||||
|
||||
sc, err := stan.Connect(clusterID, clientID, stan.NatsURL(URL))
|
||||
if err != nil {
|
||||
log.Fatalf("Can't connect: %v.\nMake sure a NATS Streaming Server is running at: %s", err, URL)
|
||||
}
|
||||
defer sc.Close()
|
||||
|
||||
subj, msg := args[0], []byte(args[1])
|
||||
|
||||
ch := make(chan bool)
|
||||
var glock sync.Mutex
|
||||
var guid string
|
||||
acb := func(lguid string, err error) {
|
||||
glock.Lock()
|
||||
log.Printf("Received ACK for guid %s\n", lguid)
|
||||
defer glock.Unlock()
|
||||
if err != nil {
|
||||
log.Fatalf("Error in server ack for guid %s: %v\n", lguid, err)
|
||||
}
|
||||
if lguid != guid {
|
||||
log.Fatalf("Expected a matching guid in ack callback, got %s vs %s\n", lguid, guid)
|
||||
}
|
||||
ch <- true
|
||||
}
|
||||
|
||||
if async != true {
|
||||
err = sc.Publish(subj, msg)
|
||||
if err != nil {
|
||||
log.Fatalf("Error during publish: %v\n", err)
|
||||
}
|
||||
log.Printf("Published [%s] : '%s'\n", subj, msg)
|
||||
} else {
|
||||
glock.Lock()
|
||||
guid, err = sc.PublishAsync(subj, msg, acb)
|
||||
if err != nil {
|
||||
log.Fatalf("Error during async publish: %v\n", err)
|
||||
}
|
||||
glock.Unlock()
|
||||
if guid == "" {
|
||||
log.Fatal("Expected non-empty guid to be returned.")
|
||||
}
|
||||
log.Printf("Published [%s] : '%s' [guid: %s]\n", subj, msg, guid)
|
||||
|
||||
select {
|
||||
case <-ch:
|
||||
break
|
||||
case <-time.After(5 * time.Second):
|
||||
log.Fatal("timeout")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
152
gateway/vendor/github.com/nats-io/go-nats-streaming/examples/stan-sub.go
generated
vendored
Normal file
152
gateway/vendor/github.com/nats-io/go-nats-streaming/examples/stan-sub.go
generated
vendored
Normal file
@ -0,0 +1,152 @@
|
||||
// Copyright 2012-2016 Apcera Inc. All rights reserved.
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"time"
|
||||
|
||||
"github.com/nats-io/go-nats-streaming"
|
||||
"github.com/nats-io/go-nats-streaming/pb"
|
||||
)
|
||||
|
||||
var usageStr = `
|
||||
Usage: stan-sub [options] <subject>
|
||||
|
||||
Options:
|
||||
-s, --server <url> NATS Streaming server URL(s)
|
||||
-c, --cluster <cluster name> NATS Streaming cluster name
|
||||
-id,--clientid <client ID> NATS Streaming client ID
|
||||
|
||||
Subscription Options:
|
||||
--qgroup <name> Queue group
|
||||
--seq <seqno> Start at seqno
|
||||
--all Deliver all available messages
|
||||
--last Deliver starting with last published message
|
||||
--since <duration> Deliver messages in last interval (e.g. 1s, 1hr)
|
||||
(for more information: https://golang.org/pkg/time/#ParseDuration)
|
||||
--durable <name> Durable subscriber name
|
||||
--unsubscribe Unsubscribe the durable on exit
|
||||
`
|
||||
|
||||
// NOTE: Use tls scheme for TLS, e.g. stan-sub -s tls://demo.nats.io:4443 foo
|
||||
func usage() {
|
||||
log.Fatalf(usageStr)
|
||||
}
|
||||
|
||||
func printMsg(m *stan.Msg, i int) {
|
||||
log.Printf("[#%d] Received on [%s]: '%s'\n", i, m.Subject, m)
|
||||
}
|
||||
|
||||
func main() {
|
||||
var clusterID string
|
||||
var clientID string
|
||||
var showTime bool
|
||||
var startSeq uint64
|
||||
var startDelta string
|
||||
var deliverAll bool
|
||||
var deliverLast bool
|
||||
var durable string
|
||||
var qgroup string
|
||||
var unsubscribe bool
|
||||
var URL string
|
||||
|
||||
// defaultID := fmt.Sprintf("client.%s", nuid.Next())
|
||||
|
||||
flag.StringVar(&URL, "s", stan.DefaultNatsURL, "The nats server URLs (separated by comma)")
|
||||
flag.StringVar(&URL, "server", stan.DefaultNatsURL, "The nats server URLs (separated by comma)")
|
||||
flag.StringVar(&clusterID, "c", "test-cluster", "The NATS Streaming cluster ID")
|
||||
flag.StringVar(&clusterID, "cluster", "test-cluster", "The NATS Streaming cluster ID")
|
||||
flag.StringVar(&clientID, "id", "", "The NATS Streaming client ID to connect with")
|
||||
flag.StringVar(&clientID, "clientid", "", "The NATS Streaming client ID to connect with")
|
||||
flag.BoolVar(&showTime, "t", false, "Display timestamps")
|
||||
// Subscription options
|
||||
flag.Uint64Var(&startSeq, "seq", 0, "Start at sequence no.")
|
||||
flag.BoolVar(&deliverAll, "all", false, "Deliver all")
|
||||
flag.BoolVar(&deliverLast, "last", false, "Start with last value")
|
||||
flag.StringVar(&startDelta, "since", "", "Deliver messages since specified time offset")
|
||||
flag.StringVar(&durable, "durable", "", "Durable subscriber name")
|
||||
flag.StringVar(&qgroup, "qgroup", "", "Queue group name")
|
||||
flag.BoolVar(&unsubscribe, "unsubscribe", false, "Unsubscribe the durable on exit")
|
||||
|
||||
log.SetFlags(0)
|
||||
flag.Usage = usage
|
||||
flag.Parse()
|
||||
|
||||
args := flag.Args()
|
||||
|
||||
if clientID == "" {
|
||||
log.Printf("Error: A unique client ID must be specified.")
|
||||
usage()
|
||||
}
|
||||
if len(args) < 1 {
|
||||
log.Printf("Error: A subject must be specified.")
|
||||
usage()
|
||||
}
|
||||
|
||||
sc, err := stan.Connect(clusterID, clientID, stan.NatsURL(URL))
|
||||
if err != nil {
|
||||
log.Fatalf("Can't connect: %v.\nMake sure a NATS Streaming Server is running at: %s", err, URL)
|
||||
}
|
||||
log.Printf("Connected to %s clusterID: [%s] clientID: [%s]\n", URL, clusterID, clientID)
|
||||
|
||||
subj, i := args[0], 0
|
||||
|
||||
mcb := func(msg *stan.Msg) {
|
||||
i++
|
||||
printMsg(msg, i)
|
||||
}
|
||||
|
||||
startOpt := stan.StartAt(pb.StartPosition_NewOnly)
|
||||
|
||||
if startSeq != 0 {
|
||||
startOpt = stan.StartAtSequence(startSeq)
|
||||
} else if deliverLast == true {
|
||||
startOpt = stan.StartWithLastReceived()
|
||||
} else if deliverAll == true {
|
||||
log.Print("subscribing with DeliverAllAvailable")
|
||||
startOpt = stan.DeliverAllAvailable()
|
||||
} else if startDelta != "" {
|
||||
ago, err := time.ParseDuration(startDelta)
|
||||
if err != nil {
|
||||
sc.Close()
|
||||
log.Fatal(err)
|
||||
}
|
||||
startOpt = stan.StartAtTimeDelta(ago)
|
||||
}
|
||||
|
||||
sub, err := sc.QueueSubscribe(subj, qgroup, mcb, startOpt, stan.DurableName(durable))
|
||||
if err != nil {
|
||||
sc.Close()
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
log.Printf("Listening on [%s], clientID=[%s], qgroup=[%s] durable=[%s]\n", subj, clientID, qgroup, durable)
|
||||
|
||||
if showTime {
|
||||
log.SetFlags(log.LstdFlags)
|
||||
}
|
||||
|
||||
// Wait for a SIGINT (perhaps triggered by user with CTRL-C)
|
||||
// Run cleanup when signal is received
|
||||
signalChan := make(chan os.Signal, 1)
|
||||
cleanupDone := make(chan bool)
|
||||
signal.Notify(signalChan, os.Interrupt)
|
||||
go func() {
|
||||
for _ = range signalChan {
|
||||
fmt.Printf("\nReceived an interrupt, unsubscribing and closing connection...\n\n")
|
||||
// Do not unsubscribe a durable on exit, except if asked to.
|
||||
if durable == "" || unsubscribe {
|
||||
sub.Unsubscribe()
|
||||
}
|
||||
sc.Close()
|
||||
cleanupDone <- true
|
||||
}
|
||||
}()
|
||||
<-cleanupDone
|
||||
}
|
16
gateway/vendor/github.com/nats-io/go-nats-streaming/scripts/cov.sh
generated
vendored
Executable file
16
gateway/vendor/github.com/nats-io/go-nats-streaming/scripts/cov.sh
generated
vendored
Executable file
@ -0,0 +1,16 @@
|
||||
#!/bin/bash -e
|
||||
# Run from directory above via ./scripts/cov.sh
|
||||
|
||||
rm -rf ./cov
|
||||
mkdir cov
|
||||
go test -v -covermode=atomic -coverprofile=./cov/stan.out
|
||||
gocovmerge ./cov/*.out > acc.out
|
||||
rm -rf ./cov
|
||||
|
||||
# If we have an arg, assume travis run and push to coveralls. Otherwise launch browser results
|
||||
if [[ -n $1 ]]; then
|
||||
$HOME/gopath/bin/goveralls -coverprofile=acc.out
|
||||
rm -rf ./acc.out
|
||||
else
|
||||
go tool cover -html=acc.out
|
||||
fi
|
36
gateway/vendor/github.com/nats-io/go-nats-streaming/stan.go
generated
vendored
36
gateway/vendor/github.com/nats-io/go-nats-streaming/stan.go
generated
vendored
@ -71,7 +71,7 @@ var (
|
||||
)
|
||||
|
||||
// AckHandler is used for Async Publishing to provide status of the ack.
|
||||
// The func will be passed the GUID and any error state. No error means the
|
||||
// The func will be passed teh GUID and any error state. No error means the
|
||||
// message was successfully received by NATS Streaming.
|
||||
type AckHandler func(string, error)
|
||||
|
||||
@ -144,6 +144,7 @@ func NatsConn(nc *nats.Conn) Option {
|
||||
type conn struct {
|
||||
sync.RWMutex
|
||||
clientID string
|
||||
serverID string
|
||||
pubPrefix string // Publish prefix set by stan, append our subject.
|
||||
subRequests string // Subject to send subscription requests.
|
||||
unsubRequests string // Subject to send unsubscribe requests.
|
||||
@ -168,7 +169,6 @@ type ack struct {
|
||||
}
|
||||
|
||||
// Connect will form a connection to the NATS Streaming subsystem.
|
||||
// Note that clientID can contain only alphanumeric and `-` or `_` characters.
|
||||
func Connect(stanClusterID, clientID string, options ...Option) (Conn, error) {
|
||||
// Process Options
|
||||
c := conn{clientID: clientID, opts: DefaultOptions}
|
||||
@ -181,7 +181,7 @@ func Connect(stanClusterID, clientID string, options ...Option) (Conn, error) {
|
||||
c.nc = c.opts.NatsConn
|
||||
// Create a NATS connection if it doesn't exist.
|
||||
if c.nc == nil {
|
||||
nc, err := nats.Connect(c.opts.NatsURL, nats.Name(clientID))
|
||||
nc, err := nats.Connect(c.opts.NatsURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -253,6 +253,10 @@ func Connect(stanClusterID, clientID string, options ...Option) (Conn, error) {
|
||||
|
||||
// Close a connection to the stan system.
|
||||
func (sc *conn) Close() error {
|
||||
if sc == nil {
|
||||
return ErrBadConnection
|
||||
}
|
||||
|
||||
sc.Lock()
|
||||
defer sc.Unlock()
|
||||
|
||||
@ -318,7 +322,9 @@ func (sc *conn) processAck(m *nats.Msg) {
|
||||
pa := &pb.PubAck{}
|
||||
err := pa.Unmarshal(m.Data)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("Error during ack unmarshal: %v", err))
|
||||
// FIXME, make closure to have context?
|
||||
fmt.Printf("Error processing unmarshal\n")
|
||||
return
|
||||
}
|
||||
|
||||
// Remove
|
||||
@ -389,16 +395,11 @@ func (sc *conn) publishAsync(subject string, data []byte, ah AckHandler, ch chan
|
||||
// Setup the timer for expiration.
|
||||
sc.Lock()
|
||||
a.t = time.AfterFunc(ackTimeout, func() {
|
||||
pubAck := sc.removeAck(peGUID)
|
||||
// processAck could get here before and handle the ack.
|
||||
// If that's the case, we would get nil here and simply return.
|
||||
if pubAck == nil {
|
||||
return
|
||||
}
|
||||
if pubAck.ah != nil {
|
||||
pubAck.ah(peGUID, ErrTimeout)
|
||||
sc.removeAck(peGUID)
|
||||
if a.ah != nil {
|
||||
ah(peGUID, ErrTimeout)
|
||||
} else if a.ch != nil {
|
||||
pubAck.ch <- ErrTimeout
|
||||
a.ch <- ErrTimeout
|
||||
}
|
||||
})
|
||||
sc.Unlock()
|
||||
@ -435,7 +436,7 @@ func (sc *conn) processMsg(raw *nats.Msg) {
|
||||
msg := &Msg{}
|
||||
err := msg.Unmarshal(raw.Data)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("Error processing unmarshal for msg: %v", err))
|
||||
panic("Error processing unmarshal for msg")
|
||||
}
|
||||
// Lookup the subscription
|
||||
sc.RLock()
|
||||
@ -464,11 +465,12 @@ func (sc *conn) processMsg(raw *nats.Msg) {
|
||||
cb(msg)
|
||||
}
|
||||
|
||||
// Process auto-ack
|
||||
// Proces auto-ack
|
||||
if !isManualAck && nc != nil {
|
||||
ack := &pb.Ack{Subject: msg.Subject, Sequence: msg.Sequence}
|
||||
b, _ := ack.Marshal()
|
||||
// FIXME(dlc) - Async error handler? Retry?
|
||||
nc.Publish(ackSubject, b)
|
||||
if err := nc.Publish(ackSubject, b); err != nil {
|
||||
// FIXME(dlc) - Async error handler? Retry?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
2053
gateway/vendor/github.com/nats-io/go-nats-streaming/stan_test.go
generated
vendored
Normal file
2053
gateway/vendor/github.com/nats-io/go-nats-streaming/stan_test.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
115
gateway/vendor/github.com/nats-io/go-nats-streaming/sub.go
generated
vendored
115
gateway/vendor/github.com/nats-io/go-nats-streaming/sub.go
generated
vendored
@ -30,14 +30,6 @@ type Msg struct {
|
||||
// Subscription represents a subscription within the NATS Streaming cluster. Subscriptions
|
||||
// will be rate matched and follow at-least delivery semantics.
|
||||
type Subscription interface {
|
||||
ClearMaxPending() error
|
||||
Delivered() (int64, error)
|
||||
Dropped() (int, error)
|
||||
IsValid() bool
|
||||
MaxPending() (int, int, error)
|
||||
Pending() (int, int, error)
|
||||
PendingLimits() (int, int, error)
|
||||
SetPendingLimits(msgLimit, bytesLimit int) error
|
||||
// Unsubscribe removes interest in the subscription.
|
||||
// For durables, it means that the durable interest is also removed from
|
||||
// the server. Restarting a durable with the same name will not resume
|
||||
@ -264,97 +256,12 @@ func (sc *conn) subscribe(subject, qgroup string, cb MsgHandler, options ...Subs
|
||||
return sub, nil
|
||||
}
|
||||
|
||||
// ClearMaxPending resets the maximums seen so far.
|
||||
func (sub *subscription) ClearMaxPending() error {
|
||||
sub.Lock()
|
||||
defer sub.Unlock()
|
||||
if sub.inboxSub == nil {
|
||||
return ErrBadSubscription
|
||||
}
|
||||
return sub.inboxSub.ClearMaxPending()
|
||||
}
|
||||
|
||||
// Delivered returns the number of delivered messages for this subscription.
|
||||
func (sub *subscription) Delivered() (int64, error) {
|
||||
sub.Lock()
|
||||
defer sub.Unlock()
|
||||
if sub.inboxSub == nil {
|
||||
return -1, ErrBadSubscription
|
||||
}
|
||||
return sub.inboxSub.Delivered()
|
||||
}
|
||||
|
||||
// Dropped returns the number of known dropped messages for this subscription.
|
||||
// This will correspond to messages dropped by violations of PendingLimits. If
|
||||
// the server declares the connection a SlowConsumer, this number may not be
|
||||
// valid.
|
||||
func (sub *subscription) Dropped() (int, error) {
|
||||
sub.Lock()
|
||||
defer sub.Unlock()
|
||||
if sub.inboxSub == nil {
|
||||
return -1, ErrBadSubscription
|
||||
}
|
||||
return sub.inboxSub.Dropped()
|
||||
}
|
||||
|
||||
// IsValid returns a boolean indicating whether the subscription
|
||||
// is still active. This will return false if the subscription has
|
||||
// already been closed.
|
||||
func (sub *subscription) IsValid() bool {
|
||||
sub.Lock()
|
||||
defer sub.Unlock()
|
||||
if sub.inboxSub == nil {
|
||||
return false
|
||||
}
|
||||
return sub.inboxSub.IsValid()
|
||||
}
|
||||
|
||||
// MaxPending returns the maximum number of queued messages and queued bytes seen so far.
|
||||
func (sub *subscription) MaxPending() (int, int, error) {
|
||||
sub.Lock()
|
||||
defer sub.Unlock()
|
||||
if sub.inboxSub == nil {
|
||||
return -1, -1, ErrBadSubscription
|
||||
}
|
||||
return sub.inboxSub.MaxPending()
|
||||
}
|
||||
|
||||
// Pending returns the number of queued messages and queued bytes in the client for this subscription.
|
||||
func (sub *subscription) Pending() (int, int, error) {
|
||||
sub.Lock()
|
||||
defer sub.Unlock()
|
||||
if sub.inboxSub == nil {
|
||||
return -1, -1, ErrBadSubscription
|
||||
}
|
||||
return sub.inboxSub.Pending()
|
||||
}
|
||||
|
||||
// PendingLimits returns the current limits for this subscription.
|
||||
// If no error is returned, a negative value indicates that the
|
||||
// given metric is not limited.
|
||||
func (sub *subscription) PendingLimits() (int, int, error) {
|
||||
sub.Lock()
|
||||
defer sub.Unlock()
|
||||
if sub.inboxSub == nil {
|
||||
return -1, -1, ErrBadSubscription
|
||||
}
|
||||
return sub.inboxSub.PendingLimits()
|
||||
}
|
||||
|
||||
// SetPendingLimits sets the limits for pending msgs and bytes for this subscription.
|
||||
// Zero is not allowed. Any negative value means that the given metric is not limited.
|
||||
func (sub *subscription) SetPendingLimits(msgLimit, bytesLimit int) error {
|
||||
sub.Lock()
|
||||
defer sub.Unlock()
|
||||
if sub.inboxSub == nil {
|
||||
return ErrBadSubscription
|
||||
}
|
||||
return sub.inboxSub.SetPendingLimits(msgLimit, bytesLimit)
|
||||
}
|
||||
|
||||
// closeOrUnsubscribe performs either close or unsubsribe based on
|
||||
// given boolean.
|
||||
func (sub *subscription) closeOrUnsubscribe(doClose bool) error {
|
||||
if sub == nil {
|
||||
return ErrBadSubscription
|
||||
}
|
||||
sub.Lock()
|
||||
sc := sub.sc
|
||||
if sc == nil {
|
||||
@ -367,6 +274,10 @@ func (sub *subscription) closeOrUnsubscribe(doClose bool) error {
|
||||
sub.inboxSub = nil
|
||||
sub.Unlock()
|
||||
|
||||
if sc == nil {
|
||||
return ErrBadSubscription
|
||||
}
|
||||
|
||||
sc.Lock()
|
||||
if sc.nc == nil {
|
||||
sc.Unlock()
|
||||
@ -431,8 +342,12 @@ func (msg *Msg) Ack() error {
|
||||
if msg == nil {
|
||||
return ErrNilMsg
|
||||
}
|
||||
// Look up subscription (cannot be nil)
|
||||
// Look up subscription
|
||||
sub := msg.Sub.(*subscription)
|
||||
if sub == nil {
|
||||
return ErrBadSubscription
|
||||
}
|
||||
|
||||
sub.RLock()
|
||||
ackSubject := sub.ackInbox
|
||||
isManualAck := sub.opts.ManualAcks
|
||||
@ -440,9 +355,6 @@ func (msg *Msg) Ack() error {
|
||||
sub.RUnlock()
|
||||
|
||||
// Check for error conditions.
|
||||
if !isManualAck {
|
||||
return ErrManualAck
|
||||
}
|
||||
if sc == nil {
|
||||
return ErrBadSubscription
|
||||
}
|
||||
@ -453,6 +365,9 @@ func (msg *Msg) Ack() error {
|
||||
if nc == nil {
|
||||
return ErrBadConnection
|
||||
}
|
||||
if !isManualAck {
|
||||
return ErrManualAck
|
||||
}
|
||||
|
||||
// Ack here.
|
||||
ack := &pb.Ack{Subject: msg.Subject, Sequence: msg.Sequence}
|
||||
|
39
gateway/vendor/github.com/nats-io/go-nats/.gitignore
generated
vendored
Normal file
39
gateway/vendor/github.com/nats-io/go-nats/.gitignore
generated
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
|
||||
# Emacs
|
||||
*~
|
||||
\#*\#
|
||||
.\#*
|
||||
|
||||
# vi/vim
|
||||
.??*.swp
|
||||
|
||||
# Mac
|
||||
.DS_Store
|
||||
|
||||
# Eclipse
|
||||
.project
|
||||
.settings/
|
||||
|
||||
# bin
|
21
gateway/vendor/github.com/nats-io/go-nats/.travis.yml
generated
vendored
Normal file
21
gateway/vendor/github.com/nats-io/go-nats/.travis.yml
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
language: go
|
||||
sudo: false
|
||||
go:
|
||||
- 1.9.x
|
||||
- 1.8.x
|
||||
- 1.7.x
|
||||
install:
|
||||
- go get -t ./...
|
||||
- go get github.com/nats-io/gnatsd
|
||||
- go get github.com/mattn/goveralls
|
||||
- go get github.com/wadey/gocovmerge
|
||||
- go get -u honnef.co/go/tools/cmd/megacheck
|
||||
- go get -u github.com/client9/misspell/cmd/misspell
|
||||
before_script:
|
||||
- $(exit $(go fmt ./... | wc -l))
|
||||
- go vet ./...
|
||||
- misspell -error -locale US .
|
||||
- megacheck -ignore "$(cat staticcheck.ignore)" ./...
|
||||
script:
|
||||
- go test -i -race ./...
|
||||
- if [[ "$TRAVIS_GO_VERSION" == 1.7.* ]]; then ./scripts/cov.sh TRAVIS; else go test -v -race ./...; fi
|
2
gateway/vendor/github.com/nats-io/go-nats/LICENSE
generated
vendored
2
gateway/vendor/github.com/nats-io/go-nats/LICENSE
generated
vendored
@ -1,6 +1,6 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2012-2016 Apcera Inc.
|
||||
Copyright (c) 2012-2017 Apcera Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
|
26
gateway/vendor/github.com/nats-io/go-nats/TODO.md
generated
vendored
Normal file
26
gateway/vendor/github.com/nats-io/go-nats/TODO.md
generated
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
|
||||
- [ ] Better constructors, options handling
|
||||
- [ ] Functions for callback settings after connection created.
|
||||
- [ ] Better options for subscriptions. Slow Consumer state settable, Go routines vs Inline.
|
||||
- [ ] Move off of channels for subscribers, use syncPool linkedLists, etc with highwater.
|
||||
- [ ] Test for valid subjects on publish and subscribe?
|
||||
- [ ] SyncSubscriber and Next for EncodedConn
|
||||
- [ ] Fast Publisher?
|
||||
- [ ] pooling for structs used? leaky bucket?
|
||||
- [ ] Timeout 0 should work as no timeout
|
||||
- [x] Ping timer
|
||||
- [x] Name in Connect for gnatsd
|
||||
- [x] Asynchronous error handling
|
||||
- [x] Parser rewrite
|
||||
- [x] Reconnect
|
||||
- [x] Hide Lock
|
||||
- [x] Easier encoder interface
|
||||
- [x] QueueSubscribeSync
|
||||
- [x] Make nats specific errors prefixed with 'nats:'
|
||||
- [x] API test for closed connection
|
||||
- [x] TLS/SSL
|
||||
- [x] Stats collection
|
||||
- [x] Disconnect detection
|
||||
- [x] Optimized Publish (coalescing)
|
||||
- [x] Do Examples via Go style
|
||||
- [x] Standardized Errors
|
354
gateway/vendor/github.com/nats-io/go-nats/bench/bench.go
generated
vendored
Normal file
354
gateway/vendor/github.com/nats-io/go-nats/bench/bench.go
generated
vendored
Normal file
@ -0,0 +1,354 @@
|
||||
// Copyright 2016 Apcera Inc. All rights reserved.
|
||||
|
||||
package bench
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/csv"
|
||||
"fmt"
|
||||
"log"
|
||||
"math"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/nats-io/go-nats"
|
||||
"github.com/nats-io/nuid"
|
||||
)
|
||||
|
||||
// A Sample for a particular client
|
||||
type Sample struct {
|
||||
JobMsgCnt int
|
||||
MsgCnt uint64
|
||||
MsgBytes uint64
|
||||
IOBytes uint64
|
||||
Start time.Time
|
||||
End time.Time
|
||||
}
|
||||
|
||||
// SampleGroup for a number of samples, the group is a Sample itself agregating the values the Samples
|
||||
type SampleGroup struct {
|
||||
Sample
|
||||
Samples []*Sample
|
||||
}
|
||||
|
||||
// Benchmark to hold the various Samples organized by publishers and subscribers
|
||||
type Benchmark struct {
|
||||
Sample
|
||||
Name string
|
||||
RunID string
|
||||
Pubs *SampleGroup
|
||||
Subs *SampleGroup
|
||||
subChannel chan *Sample
|
||||
pubChannel chan *Sample
|
||||
}
|
||||
|
||||
// NewBenchmark initializes a Benchmark. After creating a bench call AddSubSample/AddPubSample.
|
||||
// When done collecting samples, call EndBenchmark
|
||||
func NewBenchmark(name string, subCnt, pubCnt int) *Benchmark {
|
||||
bm := Benchmark{Name: name, RunID: nuid.Next()}
|
||||
bm.Subs = NewSampleGroup()
|
||||
bm.Pubs = NewSampleGroup()
|
||||
bm.subChannel = make(chan *Sample, subCnt)
|
||||
bm.pubChannel = make(chan *Sample, pubCnt)
|
||||
return &bm
|
||||
}
|
||||
|
||||
// Close organizes collected Samples and calculates aggregates. After Close(), no more samples can be added.
|
||||
func (bm *Benchmark) Close() {
|
||||
close(bm.subChannel)
|
||||
close(bm.pubChannel)
|
||||
|
||||
for s := range bm.subChannel {
|
||||
bm.Subs.AddSample(s)
|
||||
}
|
||||
for s := range bm.pubChannel {
|
||||
bm.Pubs.AddSample(s)
|
||||
}
|
||||
|
||||
if bm.Subs.HasSamples() {
|
||||
bm.Start = bm.Subs.Start
|
||||
bm.End = bm.Subs.End
|
||||
} else {
|
||||
bm.Start = bm.Pubs.Start
|
||||
bm.End = bm.Pubs.End
|
||||
}
|
||||
|
||||
if bm.Subs.HasSamples() && bm.Pubs.HasSamples() {
|
||||
if bm.Start.After(bm.Subs.Start) {
|
||||
bm.Start = bm.Subs.Start
|
||||
}
|
||||
if bm.Start.After(bm.Pubs.Start) {
|
||||
bm.Start = bm.Pubs.Start
|
||||
}
|
||||
|
||||
if bm.End.Before(bm.Subs.End) {
|
||||
bm.End = bm.Subs.End
|
||||
}
|
||||
if bm.End.Before(bm.Pubs.End) {
|
||||
bm.End = bm.Pubs.End
|
||||
}
|
||||
}
|
||||
|
||||
bm.MsgBytes = bm.Pubs.MsgBytes + bm.Subs.MsgBytes
|
||||
bm.IOBytes = bm.Pubs.IOBytes + bm.Subs.IOBytes
|
||||
bm.MsgCnt = bm.Pubs.MsgCnt + bm.Subs.MsgCnt
|
||||
bm.JobMsgCnt = bm.Pubs.JobMsgCnt + bm.Subs.JobMsgCnt
|
||||
}
|
||||
|
||||
// AddSubSample to the benchmark
|
||||
func (bm *Benchmark) AddSubSample(s *Sample) {
|
||||
bm.subChannel <- s
|
||||
}
|
||||
|
||||
// AddPubSample to the benchmark
|
||||
func (bm *Benchmark) AddPubSample(s *Sample) {
|
||||
bm.pubChannel <- s
|
||||
}
|
||||
|
||||
// CSV generates a csv report of all the samples collected
|
||||
func (bm *Benchmark) CSV() string {
|
||||
var buffer bytes.Buffer
|
||||
writer := csv.NewWriter(&buffer)
|
||||
headers := []string{"#RunID", "ClientID", "MsgCount", "MsgBytes", "MsgsPerSec", "BytesPerSec", "DurationSecs"}
|
||||
if err := writer.Write(headers); err != nil {
|
||||
log.Fatalf("Error while serializing headers %q: %v", headers, err)
|
||||
}
|
||||
groups := []*SampleGroup{bm.Subs, bm.Pubs}
|
||||
pre := "S"
|
||||
for i, g := range groups {
|
||||
if i == 1 {
|
||||
pre = "P"
|
||||
}
|
||||
for j, c := range g.Samples {
|
||||
r := []string{bm.RunID, fmt.Sprintf("%s%d", pre, j), fmt.Sprintf("%d", c.MsgCnt), fmt.Sprintf("%d", c.MsgBytes), fmt.Sprintf("%d", c.Rate()), fmt.Sprintf("%f", c.Throughput()), fmt.Sprintf("%f", c.Duration().Seconds())}
|
||||
if err := writer.Write(r); err != nil {
|
||||
log.Fatalf("Error while serializing %v: %v", c, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
writer.Flush()
|
||||
return buffer.String()
|
||||
}
|
||||
|
||||
// NewSample creates a new Sample initialized to the provided values. The nats.Conn information captured
|
||||
func NewSample(jobCount int, msgSize int, start, end time.Time, nc *nats.Conn) *Sample {
|
||||
s := Sample{JobMsgCnt: jobCount, Start: start, End: end}
|
||||
s.MsgBytes = uint64(msgSize * jobCount)
|
||||
s.MsgCnt = nc.OutMsgs + nc.InMsgs
|
||||
s.IOBytes = nc.OutBytes + nc.InBytes
|
||||
return &s
|
||||
}
|
||||
|
||||
// Throughput of bytes per second
|
||||
func (s *Sample) Throughput() float64 {
|
||||
return float64(s.MsgBytes) / s.Duration().Seconds()
|
||||
}
|
||||
|
||||
// Rate of meessages in the job per second
|
||||
func (s *Sample) Rate() int64 {
|
||||
return int64(float64(s.JobMsgCnt) / s.Duration().Seconds())
|
||||
}
|
||||
|
||||
func (s *Sample) String() string {
|
||||
rate := commaFormat(s.Rate())
|
||||
throughput := HumanBytes(s.Throughput(), false)
|
||||
return fmt.Sprintf("%s msgs/sec ~ %s/sec", rate, throughput)
|
||||
}
|
||||
|
||||
// Duration that the sample was active
|
||||
func (s *Sample) Duration() time.Duration {
|
||||
return s.End.Sub(s.Start)
|
||||
}
|
||||
|
||||
// Seconds that the sample or samples were active
|
||||
func (s *Sample) Seconds() float64 {
|
||||
return s.Duration().Seconds()
|
||||
}
|
||||
|
||||
// NewSampleGroup initializer
|
||||
func NewSampleGroup() *SampleGroup {
|
||||
s := new(SampleGroup)
|
||||
s.Samples = make([]*Sample, 0)
|
||||
return s
|
||||
}
|
||||
|
||||
// Statistics information of the sample group (min, average, max and standard deviation)
|
||||
func (sg *SampleGroup) Statistics() string {
|
||||
return fmt.Sprintf("min %s | avg %s | max %s | stddev %s msgs", commaFormat(sg.MinRate()), commaFormat(sg.AvgRate()), commaFormat(sg.MaxRate()), commaFormat(int64(sg.StdDev())))
|
||||
}
|
||||
|
||||
// MinRate returns the smallest message rate in the SampleGroup
|
||||
func (sg *SampleGroup) MinRate() int64 {
|
||||
m := int64(0)
|
||||
for i, s := range sg.Samples {
|
||||
if i == 0 {
|
||||
m = s.Rate()
|
||||
}
|
||||
m = min(m, s.Rate())
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// MaxRate returns the largest message rate in the SampleGroup
|
||||
func (sg *SampleGroup) MaxRate() int64 {
|
||||
m := int64(0)
|
||||
for i, s := range sg.Samples {
|
||||
if i == 0 {
|
||||
m = s.Rate()
|
||||
}
|
||||
m = max(m, s.Rate())
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// AvgRate returns the average of all the message rates in the SampleGroup
|
||||
func (sg *SampleGroup) AvgRate() int64 {
|
||||
sum := uint64(0)
|
||||
for _, s := range sg.Samples {
|
||||
sum += uint64(s.Rate())
|
||||
}
|
||||
return int64(sum / uint64(len(sg.Samples)))
|
||||
}
|
||||
|
||||
// StdDev returns the standard deviation the message rates in the SampleGroup
|
||||
func (sg *SampleGroup) StdDev() float64 {
|
||||
avg := float64(sg.AvgRate())
|
||||
sum := float64(0)
|
||||
for _, c := range sg.Samples {
|
||||
sum += math.Pow(float64(c.Rate())-avg, 2)
|
||||
}
|
||||
variance := sum / float64(len(sg.Samples))
|
||||
return math.Sqrt(variance)
|
||||
}
|
||||
|
||||
// AddSample adds a Sample to the SampleGroup. After adding a Sample it shouldn't be modified.
|
||||
func (sg *SampleGroup) AddSample(e *Sample) {
|
||||
sg.Samples = append(sg.Samples, e)
|
||||
|
||||
if len(sg.Samples) == 1 {
|
||||
sg.Start = e.Start
|
||||
sg.End = e.End
|
||||
}
|
||||
sg.IOBytes += e.IOBytes
|
||||
sg.JobMsgCnt += e.JobMsgCnt
|
||||
sg.MsgCnt += e.MsgCnt
|
||||
sg.MsgBytes += e.MsgBytes
|
||||
|
||||
if e.Start.Before(sg.Start) {
|
||||
sg.Start = e.Start
|
||||
}
|
||||
|
||||
if e.End.After(sg.End) {
|
||||
sg.End = e.End
|
||||
}
|
||||
}
|
||||
|
||||
// HasSamples returns true if the group has samples
|
||||
func (sg *SampleGroup) HasSamples() bool {
|
||||
return len(sg.Samples) > 0
|
||||
}
|
||||
|
||||
// Report returns a human readable report of the samples taken in the Benchmark
|
||||
func (bm *Benchmark) Report() string {
|
||||
var buffer bytes.Buffer
|
||||
|
||||
indent := ""
|
||||
if !bm.Pubs.HasSamples() && !bm.Subs.HasSamples() {
|
||||
return "No publisher or subscribers. Nothing to report."
|
||||
}
|
||||
|
||||
if bm.Pubs.HasSamples() && bm.Subs.HasSamples() {
|
||||
buffer.WriteString(fmt.Sprintf("%s Pub/Sub stats: %s\n", bm.Name, bm))
|
||||
indent += " "
|
||||
}
|
||||
if bm.Pubs.HasSamples() {
|
||||
buffer.WriteString(fmt.Sprintf("%sPub stats: %s\n", indent, bm.Pubs))
|
||||
if len(bm.Pubs.Samples) > 1 {
|
||||
for i, stat := range bm.Pubs.Samples {
|
||||
buffer.WriteString(fmt.Sprintf("%s [%d] %v (%d msgs)\n", indent, i+1, stat, stat.JobMsgCnt))
|
||||
}
|
||||
buffer.WriteString(fmt.Sprintf("%s %s\n", indent, bm.Pubs.Statistics()))
|
||||
}
|
||||
}
|
||||
|
||||
if bm.Subs.HasSamples() {
|
||||
buffer.WriteString(fmt.Sprintf("%sSub stats: %s\n", indent, bm.Subs))
|
||||
if len(bm.Subs.Samples) > 1 {
|
||||
for i, stat := range bm.Subs.Samples {
|
||||
buffer.WriteString(fmt.Sprintf("%s [%d] %v (%d msgs)\n", indent, i+1, stat, stat.JobMsgCnt))
|
||||
}
|
||||
buffer.WriteString(fmt.Sprintf("%s %s\n", indent, bm.Subs.Statistics()))
|
||||
}
|
||||
}
|
||||
return buffer.String()
|
||||
}
|
||||
|
||||
func commaFormat(n int64) string {
|
||||
in := strconv.FormatInt(n, 10)
|
||||
out := make([]byte, len(in)+(len(in)-2+int(in[0]/'0'))/3)
|
||||
if in[0] == '-' {
|
||||
in, out[0] = in[1:], '-'
|
||||
}
|
||||
for i, j, k := len(in)-1, len(out)-1, 0; ; i, j = i-1, j-1 {
|
||||
out[j] = in[i]
|
||||
if i == 0 {
|
||||
return string(out)
|
||||
}
|
||||
if k++; k == 3 {
|
||||
j, k = j-1, 0
|
||||
out[j] = ','
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// HumanBytes formats bytes as a human readable string
|
||||
func HumanBytes(bytes float64, si bool) string {
|
||||
var base = 1024
|
||||
pre := []string{"K", "M", "G", "T", "P", "E"}
|
||||
var post = "B"
|
||||
if si {
|
||||
base = 1000
|
||||
pre = []string{"k", "M", "G", "T", "P", "E"}
|
||||
post = "iB"
|
||||
}
|
||||
if bytes < float64(base) {
|
||||
return fmt.Sprintf("%.2f B", bytes)
|
||||
}
|
||||
exp := int(math.Log(bytes) / math.Log(float64(base)))
|
||||
index := exp - 1
|
||||
units := pre[index] + post
|
||||
return fmt.Sprintf("%.2f %s", bytes/math.Pow(float64(base), float64(exp)), units)
|
||||
}
|
||||
|
||||
func min(x, y int64) int64 {
|
||||
if x < y {
|
||||
return x
|
||||
}
|
||||
return y
|
||||
}
|
||||
|
||||
func max(x, y int64) int64 {
|
||||
if x > y {
|
||||
return x
|
||||
}
|
||||
return y
|
||||
}
|
||||
|
||||
// MsgsPerClient divides the number of messages by the number of clients and tries to distribute them as evenly as possible
|
||||
func MsgsPerClient(numMsgs, numClients int) []int {
|
||||
var counts []int
|
||||
if numClients == 0 || numMsgs == 0 {
|
||||
return counts
|
||||
}
|
||||
counts = make([]int, numClients)
|
||||
mc := numMsgs / numClients
|
||||
for i := 0; i < numClients; i++ {
|
||||
counts[i] = mc
|
||||
}
|
||||
extra := numMsgs % numClients
|
||||
for i := 0; i < extra; i++ {
|
||||
counts[i]++
|
||||
}
|
||||
return counts
|
||||
}
|
226
gateway/vendor/github.com/nats-io/go-nats/bench/benchlib_test.go
generated
vendored
Normal file
226
gateway/vendor/github.com/nats-io/go-nats/bench/benchlib_test.go
generated
vendored
Normal file
@ -0,0 +1,226 @@
|
||||
package bench
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/nats-io/go-nats"
|
||||
)
|
||||
|
||||
const (
|
||||
MsgSize = 8
|
||||
Million = 1000 * 1000
|
||||
)
|
||||
|
||||
var baseTime = time.Now()
|
||||
|
||||
func millionMessagesSecondSample(seconds int) *Sample {
|
||||
messages := Million * seconds
|
||||
start := baseTime
|
||||
end := start.Add(time.Second * time.Duration(seconds))
|
||||
nc := new(nats.Conn)
|
||||
|
||||
s := NewSample(messages, MsgSize, start, end, nc)
|
||||
s.MsgCnt = uint64(messages)
|
||||
s.MsgBytes = uint64(messages * MsgSize)
|
||||
s.IOBytes = s.MsgBytes
|
||||
return s
|
||||
}
|
||||
|
||||
func TestDuration(t *testing.T) {
|
||||
s := millionMessagesSecondSample(1)
|
||||
duration := s.End.Sub(s.Start)
|
||||
if duration != s.Duration() || duration != time.Second {
|
||||
t.Fatal("Expected sample duration to be 1 second")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSeconds(t *testing.T) {
|
||||
s := millionMessagesSecondSample(1)
|
||||
seconds := s.End.Sub(s.Start).Seconds()
|
||||
if seconds != s.Seconds() || seconds != 1.0 {
|
||||
t.Fatal("Expected sample seconds to be 1 second")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRate(t *testing.T) {
|
||||
s := millionMessagesSecondSample(60)
|
||||
if s.Rate() != Million {
|
||||
t.Fatal("Expected rate at 1 million msgs")
|
||||
}
|
||||
}
|
||||
|
||||
func TestThoughput(t *testing.T) {
|
||||
s := millionMessagesSecondSample(60)
|
||||
if s.Throughput() != Million*MsgSize {
|
||||
t.Fatalf("Expected throughput at %d million bytes/sec", MsgSize)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStrings(t *testing.T) {
|
||||
s := millionMessagesSecondSample(60)
|
||||
if len(s.String()) == 0 {
|
||||
t.Fatal("Sample didn't provide a String")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGroupDuration(t *testing.T) {
|
||||
sg := NewSampleGroup()
|
||||
sg.AddSample(millionMessagesSecondSample(1))
|
||||
sg.AddSample(millionMessagesSecondSample(2))
|
||||
duration := sg.End.Sub(sg.Start)
|
||||
if duration != sg.Duration() || duration != time.Duration(2)*time.Second {
|
||||
t.Fatal("Expected aggregate duration to be 2.0 seconds")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGroupSeconds(t *testing.T) {
|
||||
sg := NewSampleGroup()
|
||||
sg.AddSample(millionMessagesSecondSample(1))
|
||||
sg.AddSample(millionMessagesSecondSample(2))
|
||||
sg.AddSample(millionMessagesSecondSample(3))
|
||||
seconds := sg.End.Sub(sg.Start).Seconds()
|
||||
if seconds != sg.Seconds() || seconds != 3.0 {
|
||||
t.Fatal("Expected aggregate seconds to be 3.0 seconds")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGroupRate(t *testing.T) {
|
||||
sg := NewSampleGroup()
|
||||
sg.AddSample(millionMessagesSecondSample(1))
|
||||
sg.AddSample(millionMessagesSecondSample(2))
|
||||
sg.AddSample(millionMessagesSecondSample(3))
|
||||
if sg.Rate() != Million*2 {
|
||||
t.Fatal("Expected MsgRate at 2 million msg/sec")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGroupThoughput(t *testing.T) {
|
||||
sg := NewSampleGroup()
|
||||
sg.AddSample(millionMessagesSecondSample(1))
|
||||
sg.AddSample(millionMessagesSecondSample(2))
|
||||
sg.AddSample(millionMessagesSecondSample(3))
|
||||
if sg.Throughput() != 2*Million*MsgSize {
|
||||
t.Fatalf("Expected througput at %d million bytes/sec", 2*MsgSize)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMinMaxRate(t *testing.T) {
|
||||
sg := NewSampleGroup()
|
||||
sg.AddSample(millionMessagesSecondSample(1))
|
||||
sg.AddSample(millionMessagesSecondSample(2))
|
||||
sg.AddSample(millionMessagesSecondSample(3))
|
||||
if sg.MinRate() != sg.MaxRate() {
|
||||
t.Fatal("Expected MinRate == MaxRate")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAvgRate(t *testing.T) {
|
||||
sg := NewSampleGroup()
|
||||
sg.AddSample(millionMessagesSecondSample(1))
|
||||
sg.AddSample(millionMessagesSecondSample(2))
|
||||
sg.AddSample(millionMessagesSecondSample(3))
|
||||
if sg.MinRate() != sg.AvgRate() {
|
||||
t.Fatal("Expected MinRate == AvgRate")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStdDev(t *testing.T) {
|
||||
sg := NewSampleGroup()
|
||||
sg.AddSample(millionMessagesSecondSample(1))
|
||||
sg.AddSample(millionMessagesSecondSample(2))
|
||||
sg.AddSample(millionMessagesSecondSample(3))
|
||||
if sg.StdDev() != 0.0 {
|
||||
t.Fatal("Expected stddev to be zero")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBenchSetup(t *testing.T) {
|
||||
bench := NewBenchmark("test", 1, 1)
|
||||
bench.AddSubSample(millionMessagesSecondSample(1))
|
||||
bench.AddPubSample(millionMessagesSecondSample(1))
|
||||
bench.Close()
|
||||
if len(bench.RunID) == 0 {
|
||||
t.Fatal("Bench doesn't have a RunID")
|
||||
}
|
||||
if len(bench.Pubs.Samples) != 1 {
|
||||
t.Fatal("Expected one publisher")
|
||||
}
|
||||
if len(bench.Subs.Samples) != 1 {
|
||||
t.Fatal("Expected one subscriber")
|
||||
}
|
||||
if bench.MsgCnt != 2*Million {
|
||||
t.Fatal("Expected 2 million msgs")
|
||||
}
|
||||
if bench.IOBytes != 2*Million*MsgSize {
|
||||
t.Fatalf("Expected %d million bytes", 2*MsgSize)
|
||||
}
|
||||
if bench.Duration() != time.Second {
|
||||
t.Fatal("Expected duration to be 1 second")
|
||||
}
|
||||
}
|
||||
|
||||
func makeBench(subs, pubs int) *Benchmark {
|
||||
bench := NewBenchmark("test", subs, pubs)
|
||||
for i := 0; i < subs; i++ {
|
||||
bench.AddSubSample(millionMessagesSecondSample(1))
|
||||
}
|
||||
for i := 0; i < pubs; i++ {
|
||||
bench.AddPubSample(millionMessagesSecondSample(1))
|
||||
}
|
||||
bench.Close()
|
||||
return bench
|
||||
}
|
||||
|
||||
func TestCsv(t *testing.T) {
|
||||
bench := makeBench(1, 1)
|
||||
csv := bench.CSV()
|
||||
lines := strings.Split(csv, "\n")
|
||||
if len(lines) != 4 {
|
||||
t.Fatal("Expected 4 lines of output from the CSV string")
|
||||
}
|
||||
|
||||
fields := strings.Split(lines[1], ",")
|
||||
if len(fields) != 7 {
|
||||
t.Fatal("Expected 7 fields")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBenchStrings(t *testing.T) {
|
||||
bench := makeBench(1, 1)
|
||||
s := bench.Report()
|
||||
lines := strings.Split(s, "\n")
|
||||
if len(lines) != 4 {
|
||||
t.Fatal("Expected 3 lines of output: header, pub, sub, empty")
|
||||
}
|
||||
|
||||
bench = makeBench(2, 2)
|
||||
s = bench.Report()
|
||||
lines = strings.Split(s, "\n")
|
||||
if len(lines) != 10 {
|
||||
fmt.Printf("%q\n", s)
|
||||
|
||||
t.Fatal("Expected 11 lines of output: header, pub header, pub x 2, stats, sub headers, sub x 2, stats, empty")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMsgsPerClient(t *testing.T) {
|
||||
zero := MsgsPerClient(0, 0)
|
||||
if len(zero) != 0 {
|
||||
t.Fatal("Expected 0 length for 0 clients")
|
||||
}
|
||||
onetwo := MsgsPerClient(1, 2)
|
||||
if len(onetwo) != 2 || onetwo[0] != 1 || onetwo[1] != 0 {
|
||||
t.Fatal("Expected uneven distribution")
|
||||
}
|
||||
twotwo := MsgsPerClient(2, 2)
|
||||
if len(twotwo) != 2 || twotwo[0] != 1 || twotwo[1] != 1 {
|
||||
t.Fatal("Expected even distribution")
|
||||
}
|
||||
threetwo := MsgsPerClient(3, 2)
|
||||
if len(threetwo) != 2 || threetwo[0] != 2 || threetwo[1] != 1 {
|
||||
t.Fatal("Expected uneven distribution")
|
||||
}
|
||||
}
|
257
gateway/vendor/github.com/nats-io/go-nats/enc_test.go
generated
vendored
Normal file
257
gateway/vendor/github.com/nats-io/go-nats/enc_test.go
generated
vendored
Normal file
@ -0,0 +1,257 @@
|
||||
package nats_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
. "github.com/nats-io/go-nats"
|
||||
"github.com/nats-io/go-nats/encoders/protobuf"
|
||||
"github.com/nats-io/go-nats/encoders/protobuf/testdata"
|
||||
)
|
||||
|
||||
// Since we import above nats packages, we need to have a different
|
||||
// const name than TEST_PORT that we used on the other packages.
|
||||
const ENC_TEST_PORT = 8268
|
||||
|
||||
var options = Options{
|
||||
Url: fmt.Sprintf("nats://localhost:%d", ENC_TEST_PORT),
|
||||
AllowReconnect: true,
|
||||
MaxReconnect: 10,
|
||||
ReconnectWait: 100 * time.Millisecond,
|
||||
Timeout: DefaultTimeout,
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Encoded connection tests
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
func TestPublishErrorAfterSubscribeDecodeError(t *testing.T) {
|
||||
ts := RunServerOnPort(ENC_TEST_PORT)
|
||||
defer ts.Shutdown()
|
||||
opts := options
|
||||
nc, _ := opts.Connect()
|
||||
defer nc.Close()
|
||||
c, _ := NewEncodedConn(nc, JSON_ENCODER)
|
||||
|
||||
//Test message type
|
||||
type Message struct {
|
||||
Message string
|
||||
}
|
||||
const testSubj = "test"
|
||||
|
||||
c.Subscribe(testSubj, func(msg *Message) {})
|
||||
|
||||
//Publish invalid json to catch decode error in subscription callback
|
||||
c.Publish(testSubj, `foo`)
|
||||
c.Flush()
|
||||
|
||||
//Next publish should be successful
|
||||
if err := c.Publish(testSubj, Message{"2"}); err != nil {
|
||||
t.Error("Fail to send correct json message after decode error in subscription")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPublishErrorAfterInvalidPublishMessage(t *testing.T) {
|
||||
ts := RunServerOnPort(ENC_TEST_PORT)
|
||||
defer ts.Shutdown()
|
||||
opts := options
|
||||
nc, _ := opts.Connect()
|
||||
defer nc.Close()
|
||||
c, _ := NewEncodedConn(nc, protobuf.PROTOBUF_ENCODER)
|
||||
const testSubj = "test"
|
||||
|
||||
c.Publish(testSubj, &testdata.Person{Name: "Anatolii"})
|
||||
|
||||
//Publish invalid protobuff message to catch decode error
|
||||
c.Publish(testSubj, "foo")
|
||||
|
||||
//Next publish with valid protobuf message should be successful
|
||||
if err := c.Publish(testSubj, &testdata.Person{Name: "Anatolii"}); err != nil {
|
||||
t.Error("Fail to send correct protobuf message after invalid message publishing", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVariousFailureConditions(t *testing.T) {
|
||||
ts := RunServerOnPort(ENC_TEST_PORT)
|
||||
defer ts.Shutdown()
|
||||
|
||||
dch := make(chan bool)
|
||||
|
||||
opts := options
|
||||
opts.AsyncErrorCB = func(_ *Conn, _ *Subscription, e error) {
|
||||
dch <- true
|
||||
}
|
||||
nc, _ := opts.Connect()
|
||||
nc.Close()
|
||||
|
||||
if _, err := NewEncodedConn(nil, protobuf.PROTOBUF_ENCODER); err == nil {
|
||||
t.Fatal("Expected an error")
|
||||
}
|
||||
|
||||
if _, err := NewEncodedConn(nc, protobuf.PROTOBUF_ENCODER); err == nil || err != ErrConnectionClosed {
|
||||
t.Fatalf("Wrong error: %v instead of %v", err, ErrConnectionClosed)
|
||||
}
|
||||
|
||||
nc, _ = opts.Connect()
|
||||
defer nc.Close()
|
||||
|
||||
if _, err := NewEncodedConn(nc, "foo"); err == nil {
|
||||
t.Fatal("Expected an error")
|
||||
}
|
||||
|
||||
c, err := NewEncodedConn(nc, protobuf.PROTOBUF_ENCODER)
|
||||
if err != nil {
|
||||
t.Fatalf("Unable to create encoded connection: %v", err)
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
if _, err := c.Subscribe("bar", func(subj, obj string) {}); err != nil {
|
||||
t.Fatalf("Unable to create subscription: %v", err)
|
||||
}
|
||||
|
||||
if err := c.Publish("bar", &testdata.Person{Name: "Ivan"}); err != nil {
|
||||
t.Fatalf("Unable to publish: %v", err)
|
||||
}
|
||||
|
||||
if err := Wait(dch); err != nil {
|
||||
t.Fatal("Did not get the async error callback")
|
||||
}
|
||||
|
||||
if err := c.PublishRequest("foo", "bar", "foo"); err == nil {
|
||||
t.Fatal("Expected an error")
|
||||
}
|
||||
|
||||
if err := c.Request("foo", "foo", nil, 2*time.Second); err == nil {
|
||||
t.Fatal("Expected an error")
|
||||
}
|
||||
|
||||
nc.Close()
|
||||
|
||||
if err := c.PublishRequest("foo", "bar", &testdata.Person{Name: "Ivan"}); err == nil {
|
||||
t.Fatal("Expected an error")
|
||||
}
|
||||
|
||||
resp := &testdata.Person{}
|
||||
if err := c.Request("foo", &testdata.Person{Name: "Ivan"}, resp, 2*time.Second); err == nil {
|
||||
t.Fatal("Expected an error")
|
||||
}
|
||||
|
||||
if _, err := c.Subscribe("foo", nil); err == nil {
|
||||
t.Fatal("Expected an error")
|
||||
}
|
||||
|
||||
if _, err := c.Subscribe("foo", func() {}); err == nil {
|
||||
t.Fatal("Expected an error")
|
||||
}
|
||||
|
||||
func() {
|
||||
defer func() {
|
||||
if r := recover(); r == nil {
|
||||
t.Fatal("Expected an error")
|
||||
}
|
||||
}()
|
||||
if _, err := c.Subscribe("foo", "bar"); err == nil {
|
||||
t.Fatal("Expected an error")
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func TestRequest(t *testing.T) {
|
||||
ts := RunServerOnPort(ENC_TEST_PORT)
|
||||
defer ts.Shutdown()
|
||||
|
||||
dch := make(chan bool)
|
||||
|
||||
opts := options
|
||||
nc, _ := opts.Connect()
|
||||
defer nc.Close()
|
||||
|
||||
c, err := NewEncodedConn(nc, protobuf.PROTOBUF_ENCODER)
|
||||
if err != nil {
|
||||
t.Fatalf("Unable to create encoded connection: %v", err)
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
sentName := "Ivan"
|
||||
recvName := "Kozlovic"
|
||||
|
||||
if _, err := c.Subscribe("foo", func(_, reply string, p *testdata.Person) {
|
||||
if p.Name != sentName {
|
||||
t.Fatalf("Got wrong name: %v instead of %v", p.Name, sentName)
|
||||
}
|
||||
c.Publish(reply, &testdata.Person{Name: recvName})
|
||||
dch <- true
|
||||
}); err != nil {
|
||||
t.Fatalf("Unable to create subscription: %v", err)
|
||||
}
|
||||
if _, err := c.Subscribe("foo", func(_ string, p *testdata.Person) {
|
||||
if p.Name != sentName {
|
||||
t.Fatalf("Got wrong name: %v instead of %v", p.Name, sentName)
|
||||
}
|
||||
dch <- true
|
||||
}); err != nil {
|
||||
t.Fatalf("Unable to create subscription: %v", err)
|
||||
}
|
||||
|
||||
if err := c.Publish("foo", &testdata.Person{Name: sentName}); err != nil {
|
||||
t.Fatalf("Unable to publish: %v", err)
|
||||
}
|
||||
|
||||
if err := Wait(dch); err != nil {
|
||||
t.Fatal("Did not get message")
|
||||
}
|
||||
if err := Wait(dch); err != nil {
|
||||
t.Fatal("Did not get message")
|
||||
}
|
||||
|
||||
response := &testdata.Person{}
|
||||
if err := c.Request("foo", &testdata.Person{Name: sentName}, response, 2*time.Second); err != nil {
|
||||
t.Fatalf("Unable to publish: %v", err)
|
||||
}
|
||||
if response == nil {
|
||||
t.Fatal("No response received")
|
||||
} else if response.Name != recvName {
|
||||
t.Fatalf("Wrong response: %v instead of %v", response.Name, recvName)
|
||||
}
|
||||
|
||||
if err := Wait(dch); err != nil {
|
||||
t.Fatal("Did not get message")
|
||||
}
|
||||
if err := Wait(dch); err != nil {
|
||||
t.Fatal("Did not get message")
|
||||
}
|
||||
|
||||
c2, err := NewEncodedConn(nc, GOB_ENCODER)
|
||||
if err != nil {
|
||||
t.Fatalf("Unable to create encoded connection: %v", err)
|
||||
}
|
||||
defer c2.Close()
|
||||
|
||||
if _, err := c2.QueueSubscribe("bar", "baz", func(m *Msg) {
|
||||
response := &Msg{Subject: m.Reply, Data: []byte(recvName)}
|
||||
c2.Conn.PublishMsg(response)
|
||||
dch <- true
|
||||
}); err != nil {
|
||||
t.Fatalf("Unable to create subscription: %v", err)
|
||||
}
|
||||
|
||||
mReply := Msg{}
|
||||
if err := c2.Request("bar", &Msg{Data: []byte(sentName)}, &mReply, 2*time.Second); err != nil {
|
||||
t.Fatalf("Unable to send request: %v", err)
|
||||
}
|
||||
if string(mReply.Data) != recvName {
|
||||
t.Fatalf("Wrong reply: %v instead of %v", string(mReply.Data), recvName)
|
||||
}
|
||||
|
||||
if err := Wait(dch); err != nil {
|
||||
t.Fatal("Did not get message")
|
||||
}
|
||||
|
||||
if c.LastError() != nil {
|
||||
t.Fatalf("Unexpected connection error: %v", c.LastError())
|
||||
}
|
||||
if c2.LastError() != nil {
|
||||
t.Fatalf("Unexpected connection error: %v", c2.LastError())
|
||||
}
|
||||
}
|
62
gateway/vendor/github.com/nats-io/go-nats/encoders/protobuf/protobuf_enc.go
generated
vendored
Normal file
62
gateway/vendor/github.com/nats-io/go-nats/encoders/protobuf/protobuf_enc.go
generated
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
// Copyright 2015 Apcera Inc. All rights reserved.
|
||||
|
||||
package protobuf
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/nats-io/go-nats"
|
||||
)
|
||||
|
||||
// Additional index for registered Encoders.
|
||||
const (
|
||||
PROTOBUF_ENCODER = "protobuf"
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Register protobuf encoder
|
||||
nats.RegisterEncoder(PROTOBUF_ENCODER, &ProtobufEncoder{})
|
||||
}
|
||||
|
||||
// ProtobufEncoder is a protobuf implementation for EncodedConn
|
||||
// This encoder will use the builtin protobuf lib to Marshal
|
||||
// and Unmarshal structs.
|
||||
type ProtobufEncoder struct {
|
||||
// Empty
|
||||
}
|
||||
|
||||
var (
|
||||
ErrInvalidProtoMsgEncode = errors.New("nats: Invalid protobuf proto.Message object passed to encode")
|
||||
ErrInvalidProtoMsgDecode = errors.New("nats: Invalid protobuf proto.Message object passed to decode")
|
||||
)
|
||||
|
||||
// Encode
|
||||
func (pb *ProtobufEncoder) Encode(subject string, v interface{}) ([]byte, error) {
|
||||
if v == nil {
|
||||
return nil, nil
|
||||
}
|
||||
i, found := v.(proto.Message)
|
||||
if !found {
|
||||
return nil, ErrInvalidProtoMsgEncode
|
||||
}
|
||||
|
||||
b, err := proto.Marshal(i)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
// Decode
|
||||
func (pb *ProtobufEncoder) Decode(subject string, data []byte, vPtr interface{}) error {
|
||||
if _, ok := vPtr.(*interface{}); ok {
|
||||
return nil
|
||||
}
|
||||
i, found := vPtr.(proto.Message)
|
||||
if !found {
|
||||
return ErrInvalidProtoMsgDecode
|
||||
}
|
||||
|
||||
return proto.Unmarshal(data, i)
|
||||
}
|
40
gateway/vendor/github.com/nats-io/go-nats/encoders/protobuf/testdata/pbtest.pb.go
generated
vendored
Normal file
40
gateway/vendor/github.com/nats-io/go-nats/encoders/protobuf/testdata/pbtest.pb.go
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
// Code generated by protoc-gen-go.
|
||||
// source: pbtest.proto
|
||||
// DO NOT EDIT!
|
||||
|
||||
/*
|
||||
Package testdata is a generated protocol buffer package.
|
||||
|
||||
It is generated from these files:
|
||||
pbtest.proto
|
||||
|
||||
It has these top-level messages:
|
||||
Person
|
||||
*/
|
||||
package testdata
|
||||
|
||||
import proto "github.com/golang/protobuf/proto"
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
|
||||
type Person struct {
|
||||
Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
|
||||
Age int32 `protobuf:"varint,2,opt,name=age" json:"age,omitempty"`
|
||||
Address string `protobuf:"bytes,3,opt,name=address" json:"address,omitempty"`
|
||||
Children map[string]*Person `protobuf:"bytes,10,rep,name=children" json:"children,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
|
||||
}
|
||||
|
||||
func (m *Person) Reset() { *m = Person{} }
|
||||
func (m *Person) String() string { return proto.CompactTextString(m) }
|
||||
func (*Person) ProtoMessage() {}
|
||||
|
||||
func (m *Person) GetChildren() map[string]*Person {
|
||||
if m != nil {
|
||||
return m.Children
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
}
|
11
gateway/vendor/github.com/nats-io/go-nats/encoders/protobuf/testdata/pbtest.proto
generated
vendored
Normal file
11
gateway/vendor/github.com/nats-io/go-nats/encoders/protobuf/testdata/pbtest.proto
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package testdata;
|
||||
|
||||
message Person {
|
||||
string name = 1;
|
||||
int32 age = 2;
|
||||
string address = 3;
|
||||
|
||||
map<string, Person> children = 10;
|
||||
}
|
266
gateway/vendor/github.com/nats-io/go-nats/example_test.go
generated
vendored
Normal file
266
gateway/vendor/github.com/nats-io/go-nats/example_test.go
generated
vendored
Normal file
@ -0,0 +1,266 @@
|
||||
package nats_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/nats-io/go-nats"
|
||||
)
|
||||
|
||||
// Shows different ways to create a Conn
|
||||
func ExampleConnect() {
|
||||
|
||||
nc, _ := nats.Connect(nats.DefaultURL)
|
||||
nc.Close()
|
||||
|
||||
nc, _ = nats.Connect("nats://derek:secretpassword@demo.nats.io:4222")
|
||||
nc.Close()
|
||||
|
||||
nc, _ = nats.Connect("tls://derek:secretpassword@demo.nats.io:4443")
|
||||
nc.Close()
|
||||
|
||||
opts := nats.Options{
|
||||
AllowReconnect: true,
|
||||
MaxReconnect: 10,
|
||||
ReconnectWait: 5 * time.Second,
|
||||
Timeout: 1 * time.Second,
|
||||
}
|
||||
|
||||
nc, _ = opts.Connect()
|
||||
nc.Close()
|
||||
}
|
||||
|
||||
// This Example shows an asynchronous subscriber.
|
||||
func ExampleConn_Subscribe() {
|
||||
nc, _ := nats.Connect(nats.DefaultURL)
|
||||
defer nc.Close()
|
||||
|
||||
nc.Subscribe("foo", func(m *nats.Msg) {
|
||||
fmt.Printf("Received a message: %s\n", string(m.Data))
|
||||
})
|
||||
}
|
||||
|
||||
// This Example shows a synchronous subscriber.
|
||||
func ExampleConn_SubscribeSync() {
|
||||
nc, _ := nats.Connect(nats.DefaultURL)
|
||||
defer nc.Close()
|
||||
|
||||
sub, _ := nc.SubscribeSync("foo")
|
||||
m, err := sub.NextMsg(1 * time.Second)
|
||||
if err == nil {
|
||||
fmt.Printf("Received a message: %s\n", string(m.Data))
|
||||
} else {
|
||||
fmt.Println("NextMsg timed out.")
|
||||
}
|
||||
}
|
||||
|
||||
func ExampleSubscription_NextMsg() {
|
||||
nc, _ := nats.Connect(nats.DefaultURL)
|
||||
defer nc.Close()
|
||||
|
||||
sub, _ := nc.SubscribeSync("foo")
|
||||
m, err := sub.NextMsg(1 * time.Second)
|
||||
if err == nil {
|
||||
fmt.Printf("Received a message: %s\n", string(m.Data))
|
||||
} else {
|
||||
fmt.Println("NextMsg timed out.")
|
||||
}
|
||||
}
|
||||
|
||||
func ExampleSubscription_Unsubscribe() {
|
||||
nc, _ := nats.Connect(nats.DefaultURL)
|
||||
defer nc.Close()
|
||||
|
||||
sub, _ := nc.SubscribeSync("foo")
|
||||
// ...
|
||||
sub.Unsubscribe()
|
||||
}
|
||||
|
||||
func ExampleConn_Publish() {
|
||||
nc, _ := nats.Connect(nats.DefaultURL)
|
||||
defer nc.Close()
|
||||
|
||||
nc.Publish("foo", []byte("Hello World!"))
|
||||
}
|
||||
|
||||
func ExampleConn_PublishMsg() {
|
||||
nc, _ := nats.Connect(nats.DefaultURL)
|
||||
defer nc.Close()
|
||||
|
||||
msg := &nats.Msg{Subject: "foo", Reply: "bar", Data: []byte("Hello World!")}
|
||||
nc.PublishMsg(msg)
|
||||
}
|
||||
|
||||
func ExampleConn_Flush() {
|
||||
nc, _ := nats.Connect(nats.DefaultURL)
|
||||
defer nc.Close()
|
||||
|
||||
msg := &nats.Msg{Subject: "foo", Reply: "bar", Data: []byte("Hello World!")}
|
||||
for i := 0; i < 1000; i++ {
|
||||
nc.PublishMsg(msg)
|
||||
}
|
||||
err := nc.Flush()
|
||||
if err == nil {
|
||||
// Everything has been processed by the server for nc *Conn.
|
||||
}
|
||||
}
|
||||
|
||||
func ExampleConn_FlushTimeout() {
|
||||
nc, _ := nats.Connect(nats.DefaultURL)
|
||||
defer nc.Close()
|
||||
|
||||
msg := &nats.Msg{Subject: "foo", Reply: "bar", Data: []byte("Hello World!")}
|
||||
for i := 0; i < 1000; i++ {
|
||||
nc.PublishMsg(msg)
|
||||
}
|
||||
// Only wait for up to 1 second for Flush
|
||||
err := nc.FlushTimeout(1 * time.Second)
|
||||
if err == nil {
|
||||
// Everything has been processed by the server for nc *Conn.
|
||||
}
|
||||
}
|
||||
|
||||
func ExampleConn_Request() {
|
||||
nc, _ := nats.Connect(nats.DefaultURL)
|
||||
defer nc.Close()
|
||||
|
||||
nc.Subscribe("foo", func(m *nats.Msg) {
|
||||
nc.Publish(m.Reply, []byte("I will help you"))
|
||||
})
|
||||
nc.Request("foo", []byte("help"), 50*time.Millisecond)
|
||||
}
|
||||
|
||||
func ExampleConn_QueueSubscribe() {
|
||||
nc, _ := nats.Connect(nats.DefaultURL)
|
||||
defer nc.Close()
|
||||
|
||||
received := 0
|
||||
|
||||
nc.QueueSubscribe("foo", "worker_group", func(_ *nats.Msg) {
|
||||
received++
|
||||
})
|
||||
}
|
||||
|
||||
func ExampleSubscription_AutoUnsubscribe() {
|
||||
nc, _ := nats.Connect(nats.DefaultURL)
|
||||
defer nc.Close()
|
||||
|
||||
received, wanted, total := 0, 10, 100
|
||||
|
||||
sub, _ := nc.Subscribe("foo", func(_ *nats.Msg) {
|
||||
received++
|
||||
})
|
||||
sub.AutoUnsubscribe(wanted)
|
||||
|
||||
for i := 0; i < total; i++ {
|
||||
nc.Publish("foo", []byte("Hello"))
|
||||
}
|
||||
nc.Flush()
|
||||
|
||||
fmt.Printf("Received = %d", received)
|
||||
}
|
||||
|
||||
func ExampleConn_Close() {
|
||||
nc, _ := nats.Connect(nats.DefaultURL)
|
||||
nc.Close()
|
||||
}
|
||||
|
||||
// Shows how to wrap a Conn into an EncodedConn
|
||||
func ExampleNewEncodedConn() {
|
||||
nc, _ := nats.Connect(nats.DefaultURL)
|
||||
c, _ := nats.NewEncodedConn(nc, "json")
|
||||
c.Close()
|
||||
}
|
||||
|
||||
// EncodedConn can publish virtually anything just
|
||||
// by passing it in. The encoder will be used to properly
|
||||
// encode the raw Go type
|
||||
func ExampleEncodedConn_Publish() {
|
||||
nc, _ := nats.Connect(nats.DefaultURL)
|
||||
c, _ := nats.NewEncodedConn(nc, "json")
|
||||
defer c.Close()
|
||||
|
||||
type person struct {
|
||||
Name string
|
||||
Address string
|
||||
Age int
|
||||
}
|
||||
|
||||
me := &person{Name: "derek", Age: 22, Address: "85 Second St"}
|
||||
c.Publish("hello", me)
|
||||
}
|
||||
|
||||
// EncodedConn's subscribers will automatically decode the
|
||||
// wire data into the requested Go type using the Decode()
|
||||
// method of the registered Encoder. The callback signature
|
||||
// can also vary to include additional data, such as subject
|
||||
// and reply subjects.
|
||||
func ExampleEncodedConn_Subscribe() {
|
||||
nc, _ := nats.Connect(nats.DefaultURL)
|
||||
c, _ := nats.NewEncodedConn(nc, "json")
|
||||
defer c.Close()
|
||||
|
||||
type person struct {
|
||||
Name string
|
||||
Address string
|
||||
Age int
|
||||
}
|
||||
|
||||
c.Subscribe("hello", func(p *person) {
|
||||
fmt.Printf("Received a person! %+v\n", p)
|
||||
})
|
||||
|
||||
c.Subscribe("hello", func(subj, reply string, p *person) {
|
||||
fmt.Printf("Received a person on subject %s! %+v\n", subj, p)
|
||||
})
|
||||
|
||||
me := &person{Name: "derek", Age: 22, Address: "85 Second St"}
|
||||
c.Publish("hello", me)
|
||||
}
|
||||
|
||||
// BindSendChan() allows binding of a Go channel to a nats
|
||||
// subject for publish operations. The Encoder attached to the
|
||||
// EncodedConn will be used for marshaling.
|
||||
func ExampleEncodedConn_BindSendChan() {
|
||||
nc, _ := nats.Connect(nats.DefaultURL)
|
||||
c, _ := nats.NewEncodedConn(nc, "json")
|
||||
defer c.Close()
|
||||
|
||||
type person struct {
|
||||
Name string
|
||||
Address string
|
||||
Age int
|
||||
}
|
||||
|
||||
ch := make(chan *person)
|
||||
c.BindSendChan("hello", ch)
|
||||
|
||||
me := &person{Name: "derek", Age: 22, Address: "85 Second St"}
|
||||
ch <- me
|
||||
}
|
||||
|
||||
// BindRecvChan() allows binding of a Go channel to a nats
|
||||
// subject for subscribe operations. The Encoder attached to the
|
||||
// EncodedConn will be used for un-marshaling.
|
||||
func ExampleEncodedConn_BindRecvChan() {
|
||||
nc, _ := nats.Connect(nats.DefaultURL)
|
||||
c, _ := nats.NewEncodedConn(nc, "json")
|
||||
defer c.Close()
|
||||
|
||||
type person struct {
|
||||
Name string
|
||||
Address string
|
||||
Age int
|
||||
}
|
||||
|
||||
ch := make(chan *person)
|
||||
c.BindRecvChan("hello", ch)
|
||||
|
||||
me := &person{Name: "derek", Age: 22, Address: "85 Second St"}
|
||||
c.Publish("hello", me)
|
||||
|
||||
// Receive the publish directly on a channel
|
||||
who := <-ch
|
||||
|
||||
fmt.Printf("%v says hello!\n", who)
|
||||
}
|
146
gateway/vendor/github.com/nats-io/go-nats/examples/nats-bench.go
generated
vendored
Normal file
146
gateway/vendor/github.com/nats-io/go-nats/examples/nats-bench.go
generated
vendored
Normal file
@ -0,0 +1,146 @@
|
||||
// Copyright 2015 Apcera Inc. All rights reserved.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/nats-io/go-nats"
|
||||
"github.com/nats-io/go-nats/bench"
|
||||
)
|
||||
|
||||
// Some sane defaults
|
||||
const (
|
||||
DefaultNumMsgs = 100000
|
||||
DefaultNumPubs = 1
|
||||
DefaultNumSubs = 0
|
||||
DefaultMessageSize = 128
|
||||
)
|
||||
|
||||
func usage() {
|
||||
log.Fatalf("Usage: nats-bench [-s server (%s)] [--tls] [-np NUM_PUBLISHERS] [-ns NUM_SUBSCRIBERS] [-n NUM_MSGS] [-ms MESSAGE_SIZE] [-csv csvfile] <subject>\n", nats.DefaultURL)
|
||||
}
|
||||
|
||||
var benchmark *bench.Benchmark
|
||||
|
||||
func main() {
|
||||
var urls = flag.String("s", nats.DefaultURL, "The nats server URLs (separated by comma)")
|
||||
var tls = flag.Bool("tls", false, "Use TLS Secure Connection")
|
||||
var numPubs = flag.Int("np", DefaultNumPubs, "Number of Concurrent Publishers")
|
||||
var numSubs = flag.Int("ns", DefaultNumSubs, "Number of Concurrent Subscribers")
|
||||
var numMsgs = flag.Int("n", DefaultNumMsgs, "Number of Messages to Publish")
|
||||
var msgSize = flag.Int("ms", DefaultMessageSize, "Size of the message.")
|
||||
var csvFile = flag.String("csv", "", "Save bench data to csv file")
|
||||
|
||||
log.SetFlags(0)
|
||||
flag.Usage = usage
|
||||
flag.Parse()
|
||||
|
||||
args := flag.Args()
|
||||
if len(args) != 1 {
|
||||
usage()
|
||||
}
|
||||
|
||||
if *numMsgs <= 0 {
|
||||
log.Fatal("Number of messages should be greater than zero.")
|
||||
}
|
||||
|
||||
// Setup the option block
|
||||
opts := nats.GetDefaultOptions()
|
||||
opts.Servers = strings.Split(*urls, ",")
|
||||
for i, s := range opts.Servers {
|
||||
opts.Servers[i] = strings.Trim(s, " ")
|
||||
}
|
||||
opts.Secure = *tls
|
||||
|
||||
benchmark = bench.NewBenchmark("NATS", *numSubs, *numPubs)
|
||||
|
||||
var startwg sync.WaitGroup
|
||||
var donewg sync.WaitGroup
|
||||
|
||||
donewg.Add(*numPubs + *numSubs)
|
||||
|
||||
// Run Subscribers first
|
||||
startwg.Add(*numSubs)
|
||||
for i := 0; i < *numSubs; i++ {
|
||||
go runSubscriber(&startwg, &donewg, opts, *numMsgs, *msgSize)
|
||||
}
|
||||
startwg.Wait()
|
||||
|
||||
// Now Publishers
|
||||
startwg.Add(*numPubs)
|
||||
pubCounts := bench.MsgsPerClient(*numMsgs, *numPubs)
|
||||
for i := 0; i < *numPubs; i++ {
|
||||
go runPublisher(&startwg, &donewg, opts, pubCounts[i], *msgSize)
|
||||
}
|
||||
|
||||
log.Printf("Starting benchmark [msgs=%d, msgsize=%d, pubs=%d, subs=%d]\n", *numMsgs, *msgSize, *numPubs, *numSubs)
|
||||
|
||||
startwg.Wait()
|
||||
donewg.Wait()
|
||||
|
||||
benchmark.Close()
|
||||
|
||||
fmt.Print(benchmark.Report())
|
||||
|
||||
if len(*csvFile) > 0 {
|
||||
csv := benchmark.CSV()
|
||||
ioutil.WriteFile(*csvFile, []byte(csv), 0644)
|
||||
fmt.Printf("Saved metric data in csv file %s\n", *csvFile)
|
||||
}
|
||||
}
|
||||
|
||||
func runPublisher(startwg, donewg *sync.WaitGroup, opts nats.Options, numMsgs int, msgSize int) {
|
||||
nc, err := opts.Connect()
|
||||
if err != nil {
|
||||
log.Fatalf("Can't connect: %v\n", err)
|
||||
}
|
||||
defer nc.Close()
|
||||
startwg.Done()
|
||||
|
||||
args := flag.Args()
|
||||
subj := args[0]
|
||||
var msg []byte
|
||||
if msgSize > 0 {
|
||||
msg = make([]byte, msgSize)
|
||||
}
|
||||
|
||||
start := time.Now()
|
||||
|
||||
for i := 0; i < numMsgs; i++ {
|
||||
nc.Publish(subj, msg)
|
||||
}
|
||||
nc.Flush()
|
||||
benchmark.AddPubSample(bench.NewSample(numMsgs, msgSize, start, time.Now(), nc))
|
||||
|
||||
donewg.Done()
|
||||
}
|
||||
|
||||
func runSubscriber(startwg, donewg *sync.WaitGroup, opts nats.Options, numMsgs int, msgSize int) {
|
||||
nc, err := opts.Connect()
|
||||
if err != nil {
|
||||
log.Fatalf("Can't connect: %v\n", err)
|
||||
}
|
||||
|
||||
args := flag.Args()
|
||||
subj := args[0]
|
||||
|
||||
received := 0
|
||||
start := time.Now()
|
||||
nc.Subscribe(subj, func(msg *nats.Msg) {
|
||||
received++
|
||||
if received >= numMsgs {
|
||||
benchmark.AddSubSample(bench.NewSample(numMsgs, msgSize, start, time.Now(), nc))
|
||||
donewg.Done()
|
||||
nc.Close()
|
||||
}
|
||||
})
|
||||
nc.Flush()
|
||||
startwg.Done()
|
||||
}
|
46
gateway/vendor/github.com/nats-io/go-nats/examples/nats-pub.go
generated
vendored
Normal file
46
gateway/vendor/github.com/nats-io/go-nats/examples/nats-pub.go
generated
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
// Copyright 2012-2016 Apcera Inc. All rights reserved.
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"log"
|
||||
|
||||
"github.com/nats-io/go-nats"
|
||||
)
|
||||
|
||||
// NOTE: Use tls scheme for TLS, e.g. nats-pub -s tls://demo.nats.io:4443 foo hello
|
||||
func usage() {
|
||||
log.Fatalf("Usage: nats-pub [-s server (%s)] <subject> <msg> \n", nats.DefaultURL)
|
||||
}
|
||||
|
||||
func main() {
|
||||
var urls = flag.String("s", nats.DefaultURL, "The nats server URLs (separated by comma)")
|
||||
|
||||
log.SetFlags(0)
|
||||
flag.Usage = usage
|
||||
flag.Parse()
|
||||
|
||||
args := flag.Args()
|
||||
if len(args) < 2 {
|
||||
usage()
|
||||
}
|
||||
|
||||
nc, err := nats.Connect(*urls)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer nc.Close()
|
||||
|
||||
subj, msg := args[0], []byte(args[1])
|
||||
|
||||
nc.Publish(subj, msg)
|
||||
nc.Flush()
|
||||
|
||||
if err := nc.LastError(); err != nil {
|
||||
log.Fatal(err)
|
||||
} else {
|
||||
log.Printf("Published [%s] : '%s'\n", subj, msg)
|
||||
}
|
||||
}
|
60
gateway/vendor/github.com/nats-io/go-nats/examples/nats-qsub.go
generated
vendored
Normal file
60
gateway/vendor/github.com/nats-io/go-nats/examples/nats-qsub.go
generated
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
// Copyright 2012-2016 Apcera Inc. All rights reserved.
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"log"
|
||||
"os"
|
||||
"runtime"
|
||||
|
||||
"github.com/nats-io/go-nats"
|
||||
)
|
||||
|
||||
// NOTE: Use tls scheme for TLS, e.g. nats-qsub -s tls://demo.nats.io:4443 foo
|
||||
func usage() {
|
||||
log.Fatalf("Usage: nats-qsub [-s server] [-t] <subject> <queue-group>\n")
|
||||
}
|
||||
|
||||
func printMsg(m *nats.Msg, i int) {
|
||||
log.Printf("[#%d] Received on [%s] Queue[%s] Pid[%d]: '%s'\n", i, m.Subject, m.Sub.Queue, os.Getpid(), string(m.Data))
|
||||
}
|
||||
|
||||
func main() {
|
||||
var urls = flag.String("s", nats.DefaultURL, "The nats server URLs (separated by comma)")
|
||||
var showTime = flag.Bool("t", false, "Display timestamps")
|
||||
|
||||
log.SetFlags(0)
|
||||
flag.Usage = usage
|
||||
flag.Parse()
|
||||
|
||||
args := flag.Args()
|
||||
if len(args) < 2 {
|
||||
usage()
|
||||
}
|
||||
|
||||
nc, err := nats.Connect(*urls)
|
||||
if err != nil {
|
||||
log.Fatalf("Can't connect: %v\n", err)
|
||||
}
|
||||
|
||||
subj, queue, i := args[0], args[1], 0
|
||||
|
||||
nc.QueueSubscribe(subj, queue, func(msg *nats.Msg) {
|
||||
i++
|
||||
printMsg(msg, i)
|
||||
})
|
||||
nc.Flush()
|
||||
|
||||
if err := nc.LastError(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
log.Printf("Listening on [%s]\n", subj)
|
||||
if *showTime {
|
||||
log.SetFlags(log.LstdFlags)
|
||||
}
|
||||
|
||||
runtime.Goexit()
|
||||
}
|
48
gateway/vendor/github.com/nats-io/go-nats/examples/nats-req.go
generated
vendored
Normal file
48
gateway/vendor/github.com/nats-io/go-nats/examples/nats-req.go
generated
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
// Copyright 2012-2016 Apcera Inc. All rights reserved.
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/nats-io/go-nats"
|
||||
)
|
||||
|
||||
// NOTE: Use tls scheme for TLS, e.g. nats-req -s tls://demo.nats.io:4443 foo hello
|
||||
func usage() {
|
||||
log.Fatalf("Usage: nats-req [-s server (%s)] <subject> <msg> \n", nats.DefaultURL)
|
||||
}
|
||||
|
||||
func main() {
|
||||
var urls = flag.String("s", nats.DefaultURL, "The nats server URLs (separated by comma)")
|
||||
|
||||
log.SetFlags(0)
|
||||
flag.Usage = usage
|
||||
flag.Parse()
|
||||
|
||||
args := flag.Args()
|
||||
if len(args) < 2 {
|
||||
usage()
|
||||
}
|
||||
|
||||
nc, err := nats.Connect(*urls)
|
||||
if err != nil {
|
||||
log.Fatalf("Can't connect: %v\n", err)
|
||||
}
|
||||
defer nc.Close()
|
||||
subj, payload := args[0], []byte(args[1])
|
||||
|
||||
msg, err := nc.Request(subj, []byte(payload), 100*time.Millisecond)
|
||||
if err != nil {
|
||||
if nc.LastError() != nil {
|
||||
log.Fatalf("Error in Request: %v\n", nc.LastError())
|
||||
}
|
||||
log.Fatalf("Error in Request: %v\n", err)
|
||||
}
|
||||
|
||||
log.Printf("Published [%s] : '%s'\n", subj, payload)
|
||||
log.Printf("Received [%v] : '%s'\n", msg.Subject, string(msg.Data))
|
||||
}
|
60
gateway/vendor/github.com/nats-io/go-nats/examples/nats-rply.go
generated
vendored
Normal file
60
gateway/vendor/github.com/nats-io/go-nats/examples/nats-rply.go
generated
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
// Copyright 2012-2016 Apcera Inc. All rights reserved.
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"log"
|
||||
"runtime"
|
||||
|
||||
"github.com/nats-io/go-nats"
|
||||
)
|
||||
|
||||
// NOTE: Use tls scheme for TLS, e.g. nats-rply -s tls://demo.nats.io:4443 foo hello
|
||||
func usage() {
|
||||
log.Fatalf("Usage: nats-rply [-s server][-t] <subject> <response>\n")
|
||||
}
|
||||
|
||||
func printMsg(m *nats.Msg, i int) {
|
||||
log.Printf("[#%d] Received on [%s]: '%s'\n", i, m.Subject, string(m.Data))
|
||||
}
|
||||
|
||||
func main() {
|
||||
var urls = flag.String("s", nats.DefaultURL, "The nats server URLs (separated by comma)")
|
||||
var showTime = flag.Bool("t", false, "Display timestamps")
|
||||
|
||||
log.SetFlags(0)
|
||||
flag.Usage = usage
|
||||
flag.Parse()
|
||||
|
||||
args := flag.Args()
|
||||
if len(args) < 2 {
|
||||
usage()
|
||||
}
|
||||
|
||||
nc, err := nats.Connect(*urls)
|
||||
if err != nil {
|
||||
log.Fatalf("Can't connect: %v\n", err)
|
||||
}
|
||||
|
||||
subj, reply, i := args[0], args[1], 0
|
||||
|
||||
nc.Subscribe(subj, func(msg *nats.Msg) {
|
||||
i++
|
||||
printMsg(msg, i)
|
||||
nc.Publish(msg.Reply, []byte(reply))
|
||||
})
|
||||
nc.Flush()
|
||||
|
||||
if err := nc.LastError(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
log.Printf("Listening on [%s]\n", subj)
|
||||
if *showTime {
|
||||
log.SetFlags(log.LstdFlags)
|
||||
}
|
||||
|
||||
runtime.Goexit()
|
||||
}
|
59
gateway/vendor/github.com/nats-io/go-nats/examples/nats-sub.go
generated
vendored
Normal file
59
gateway/vendor/github.com/nats-io/go-nats/examples/nats-sub.go
generated
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
// Copyright 2012-2016 Apcera Inc. All rights reserved.
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"log"
|
||||
"runtime"
|
||||
|
||||
"github.com/nats-io/go-nats"
|
||||
)
|
||||
|
||||
// NOTE: Use tls scheme for TLS, e.g. nats-sub -s tls://demo.nats.io:4443 foo
|
||||
func usage() {
|
||||
log.Fatalf("Usage: nats-sub [-s server] [-t] <subject> \n")
|
||||
}
|
||||
|
||||
func printMsg(m *nats.Msg, i int) {
|
||||
log.Printf("[#%d] Received on [%s]: '%s'\n", i, m.Subject, string(m.Data))
|
||||
}
|
||||
|
||||
func main() {
|
||||
var urls = flag.String("s", nats.DefaultURL, "The nats server URLs (separated by comma)")
|
||||
var showTime = flag.Bool("t", false, "Display timestamps")
|
||||
|
||||
log.SetFlags(0)
|
||||
flag.Usage = usage
|
||||
flag.Parse()
|
||||
|
||||
args := flag.Args()
|
||||
if len(args) < 1 {
|
||||
usage()
|
||||
}
|
||||
|
||||
nc, err := nats.Connect(*urls)
|
||||
if err != nil {
|
||||
log.Fatalf("Can't connect: %v\n", err)
|
||||
}
|
||||
|
||||
subj, i := args[0], 0
|
||||
|
||||
nc.Subscribe(subj, func(msg *nats.Msg) {
|
||||
i += 1
|
||||
printMsg(msg, i)
|
||||
})
|
||||
nc.Flush()
|
||||
|
||||
if err := nc.LastError(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
log.Printf("Listening on [%s]\n", subj)
|
||||
if *showTime {
|
||||
log.SetFlags(log.LstdFlags)
|
||||
}
|
||||
|
||||
runtime.Goexit()
|
||||
}
|
59
gateway/vendor/github.com/nats-io/go-nats/nats.go
generated
vendored
59
gateway/vendor/github.com/nats-io/go-nats/nats.go
generated
vendored
@ -123,6 +123,12 @@ type asyncCB func()
|
||||
// Option is a function on the options for a connection.
|
||||
type Option func(*Options) error
|
||||
|
||||
// CustomDialer can be used to specify any dialer, not necessarily
|
||||
// a *net.Dialer.
|
||||
type CustomDialer interface {
|
||||
Dial(network, address string) (net.Conn, error)
|
||||
}
|
||||
|
||||
// Options can be used to create a customized connection.
|
||||
type Options struct {
|
||||
|
||||
@ -225,9 +231,14 @@ type Options struct {
|
||||
// Token sets the token to be used when connecting to a server.
|
||||
Token string
|
||||
|
||||
// Dialer allows a custom Dialer when forming connections.
|
||||
// Dialer allows a custom net.Dialer when forming connections.
|
||||
// DEPRECATED: should use CustomDialer instead.
|
||||
Dialer *net.Dialer
|
||||
|
||||
// CustomDialer allows to specify a custom dialer (not necessarily
|
||||
// a *net.Dialer).
|
||||
CustomDialer CustomDialer
|
||||
|
||||
// UseOldRequestStyle forces the old method of Requests that utilize
|
||||
// a new Inbox and a new Subscription for each request.
|
||||
UseOldRequestStyle bool
|
||||
@ -450,7 +461,7 @@ func RootCAs(file ...string) Option {
|
||||
if err != nil || rootPEM == nil {
|
||||
return fmt.Errorf("nats: error loading or parsing rootCA file: %v", err)
|
||||
}
|
||||
ok := pool.AppendCertsFromPEM([]byte(rootPEM))
|
||||
ok := pool.AppendCertsFromPEM(rootPEM)
|
||||
if !ok {
|
||||
return fmt.Errorf("nats: failed to parse root certificate from %q", f)
|
||||
}
|
||||
@ -586,6 +597,7 @@ func Token(token string) Option {
|
||||
|
||||
// Dialer is an Option to set the dialer which will be used when
|
||||
// attempting to establish a connection.
|
||||
// DEPRECATED: Should use CustomDialer instead.
|
||||
func Dialer(dialer *net.Dialer) Option {
|
||||
return func(o *Options) error {
|
||||
o.Dialer = dialer
|
||||
@ -593,6 +605,16 @@ func Dialer(dialer *net.Dialer) Option {
|
||||
}
|
||||
}
|
||||
|
||||
// SetCustomDialer is an Option to set a custom dialer which will be
|
||||
// used when attempting to establish a connection. If both Dialer
|
||||
// and CustomDialer are specified, CustomDialer takes precedence.
|
||||
func SetCustomDialer(dialer CustomDialer) Option {
|
||||
return func(o *Options) error {
|
||||
o.CustomDialer = dialer
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// UseOldRequestyStyle is an Option to force usage of the old Request style.
|
||||
func UseOldRequestStyle() Option {
|
||||
return func(o *Options) error {
|
||||
@ -787,7 +809,7 @@ const tlsScheme = "tls"
|
||||
|
||||
// Create the server pool using the options given.
|
||||
// We will place a Url option first, followed by any
|
||||
// Server Options. We will randomize the server pool unlesss
|
||||
// Server Options. We will randomize the server pool unless
|
||||
// the NoRandomize flag is set.
|
||||
func (nc *Conn) setupServerPool() error {
|
||||
nc.srvPool = make([]*srv, 0, srvPoolSize)
|
||||
@ -877,7 +899,13 @@ func (nc *Conn) createConn() (err error) {
|
||||
cur.lastAttempt = time.Now()
|
||||
}
|
||||
|
||||
dialer := nc.Opts.Dialer
|
||||
// CustomDialer takes precedence. If not set, use Opts.Dialer which
|
||||
// is set to a default *net.Dialer (in Connect()) if not explicitly
|
||||
// set by the user.
|
||||
dialer := nc.Opts.CustomDialer
|
||||
if dialer == nil {
|
||||
dialer = nc.Opts.Dialer
|
||||
}
|
||||
nc.conn, err = dialer.Dial("tcp", nc.url.Host)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -1040,7 +1068,7 @@ func (nc *Conn) connect() error {
|
||||
// to connect immediately.
|
||||
nc.mu.Lock()
|
||||
nc.initc = true
|
||||
// The pool may change inside theloop iteration due to INFO protocol.
|
||||
// The pool may change inside the loop iteration due to INFO protocol.
|
||||
for i := 0; i < len(nc.srvPool); i++ {
|
||||
nc.url = nc.srvPool[i].url
|
||||
|
||||
@ -1682,9 +1710,11 @@ slowConsumer:
|
||||
// permissions violation on either publish or subscribe.
|
||||
func (nc *Conn) processPermissionsViolation(err string) {
|
||||
nc.mu.Lock()
|
||||
nc.err = errors.New("nats: " + err)
|
||||
// create error here so we can pass it as a closure to the async cb dispatcher.
|
||||
e := errors.New("nats: " + err)
|
||||
nc.err = e
|
||||
if nc.Opts.AsyncErrorCB != nil {
|
||||
nc.ach <- func() { nc.Opts.AsyncErrorCB(nc, nil, nc.err) }
|
||||
nc.ach <- func() { nc.Opts.AsyncErrorCB(nc, nil, e) }
|
||||
}
|
||||
nc.mu.Unlock()
|
||||
}
|
||||
@ -2248,7 +2278,7 @@ func (nc *Conn) subscribe(subj, queue string, cb MsgHandler, ch chan *Msg) (*Sub
|
||||
// We will send these for all subs when we reconnect
|
||||
// so that we can suppress here.
|
||||
if !nc.isReconnecting() {
|
||||
nc.bw.WriteString(fmt.Sprintf(subProto, subj, queue, sub.sid))
|
||||
fmt.Fprintf(nc.bw, subProto, subj, queue, sub.sid)
|
||||
}
|
||||
return sub, nil
|
||||
}
|
||||
@ -2368,7 +2398,7 @@ func (nc *Conn) unsubscribe(sub *Subscription, max int) error {
|
||||
// We will send these for all subs when we reconnect
|
||||
// so that we can suppress here.
|
||||
if !nc.isReconnecting() {
|
||||
nc.bw.WriteString(fmt.Sprintf(unsubProto, s.sid, maxStr))
|
||||
fmt.Fprintf(nc.bw, unsubProto, s.sid, maxStr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -2670,7 +2700,10 @@ func (nc *Conn) FlushTimeout(timeout time.Duration) (err error) {
|
||||
t := globalTimerPool.Get(timeout)
|
||||
defer globalTimerPool.Put(t)
|
||||
|
||||
ch := make(chan struct{})
|
||||
// Create a buffered channel to prevent chan send to block
|
||||
// in processPong() if this code here times out just when
|
||||
// PONG was received.
|
||||
ch := make(chan struct{}, 1)
|
||||
nc.sendPing(ch)
|
||||
nc.mu.Unlock()
|
||||
|
||||
@ -2732,16 +2765,16 @@ func (nc *Conn) resendSubscriptions() {
|
||||
// reached the max, if so unsubscribe.
|
||||
if adjustedMax == 0 {
|
||||
s.mu.Unlock()
|
||||
nc.bw.WriteString(fmt.Sprintf(unsubProto, s.sid, _EMPTY_))
|
||||
fmt.Fprintf(nc.bw, unsubProto, s.sid, _EMPTY_)
|
||||
continue
|
||||
}
|
||||
}
|
||||
s.mu.Unlock()
|
||||
|
||||
nc.bw.WriteString(fmt.Sprintf(subProto, s.Subject, s.Queue, s.sid))
|
||||
fmt.Fprintf(nc.bw, subProto, s.Subject, s.Queue, s.sid)
|
||||
if adjustedMax > 0 {
|
||||
maxStr := strconv.Itoa(int(adjustedMax))
|
||||
nc.bw.WriteString(fmt.Sprintf(unsubProto, s.sid, maxStr))
|
||||
fmt.Fprintf(nc.bw, unsubProto, s.sid, maxStr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
1177
gateway/vendor/github.com/nats-io/go-nats/nats_test.go
generated
vendored
Normal file
1177
gateway/vendor/github.com/nats-io/go-nats/nats_test.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
19
gateway/vendor/github.com/nats-io/go-nats/scripts/cov.sh
generated
vendored
Executable file
19
gateway/vendor/github.com/nats-io/go-nats/scripts/cov.sh
generated
vendored
Executable file
@ -0,0 +1,19 @@
|
||||
#!/bin/bash -e
|
||||
# Run from directory above via ./scripts/cov.sh
|
||||
|
||||
rm -rf ./cov
|
||||
mkdir cov
|
||||
go test -v -race -covermode=atomic -coverprofile=./cov/nats.out
|
||||
go test -v -race -covermode=atomic -coverprofile=./cov/test.out -coverpkg=github.com/nats-io/go-nats ./test
|
||||
go test -v -race -covermode=atomic -coverprofile=./cov/builtin.out -coverpkg=github.com/nats-io/go-nats/encoders/builtin ./test -run EncBuiltin
|
||||
go test -v -race -covermode=atomic -coverprofile=./cov/protobuf.out -coverpkg=github.com/nats-io/go-nats/encoders/protobuf ./test -run EncProto
|
||||
gocovmerge ./cov/*.out > acc.out
|
||||
rm -rf ./cov
|
||||
|
||||
# If we have an arg, assume travis run and push to coveralls. Otherwise launch browser results
|
||||
if [[ -n $1 ]]; then
|
||||
$HOME/gopath/bin/goveralls -coverprofile=acc.out -service travis-ci
|
||||
rm -rf ./acc.out
|
||||
else
|
||||
go tool cover -html=acc.out
|
||||
fi
|
4
gateway/vendor/github.com/nats-io/go-nats/staticcheck.ignore
generated
vendored
Normal file
4
gateway/vendor/github.com/nats-io/go-nats/staticcheck.ignore
generated
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
github.com/nats-io/go-nats/*_test.go:SA2002
|
||||
github.com/nats-io/go-nats/*/*_test.go:SA2002
|
||||
github.com/nats-io/go-nats/test/context_test.go:SA1012
|
||||
github.com/nats-io/go-nats/nats.go:SA6000
|
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
29
gateway/vendor/github.com/nats-io/go-nats/timer_test.go
generated
vendored
Normal file
29
gateway/vendor/github.com/nats-io/go-nats/timer_test.go
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
package nats
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestTimerPool(t *testing.T) {
|
||||
var tp timerPool
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
tm := tp.Get(time.Millisecond * 20)
|
||||
|
||||
select {
|
||||
case <-tm.C:
|
||||
t.Errorf("Timer already expired")
|
||||
continue
|
||||
default:
|
||||
}
|
||||
|
||||
select {
|
||||
case <-tm.C:
|
||||
case <-time.After(time.Millisecond * 100):
|
||||
t.Errorf("Timer didn't expire in time")
|
||||
}
|
||||
|
||||
tp.Put(tm)
|
||||
}
|
||||
}
|
38
gateway/vendor/github.com/nats-io/go-nats/util/tls.go
generated
vendored
38
gateway/vendor/github.com/nats-io/go-nats/util/tls.go
generated
vendored
@ -1,37 +1,15 @@
|
||||
// Copyright 2016 Apcera Inc. All rights reserved.
|
||||
// +build go1.7
|
||||
// Copyright 2017 Apcera Inc. All rights reserved.
|
||||
// +build go1.8
|
||||
|
||||
package util
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
)
|
||||
import "crypto/tls"
|
||||
|
||||
// CloneTLSConfig returns a copy of c. Only the exported fields are copied.
|
||||
// This is temporary, until this is provided by the language.
|
||||
// https://go-review.googlesource.com/#/c/28075/
|
||||
// CloneTLSConfig returns a copy of c.
|
||||
func CloneTLSConfig(c *tls.Config) *tls.Config {
|
||||
return &tls.Config{
|
||||
Rand: c.Rand,
|
||||
Time: c.Time,
|
||||
Certificates: c.Certificates,
|
||||
NameToCertificate: c.NameToCertificate,
|
||||
GetCertificate: c.GetCertificate,
|
||||
RootCAs: c.RootCAs,
|
||||
NextProtos: c.NextProtos,
|
||||
ServerName: c.ServerName,
|
||||
ClientAuth: c.ClientAuth,
|
||||
ClientCAs: c.ClientCAs,
|
||||
InsecureSkipVerify: c.InsecureSkipVerify,
|
||||
CipherSuites: c.CipherSuites,
|
||||
PreferServerCipherSuites: c.PreferServerCipherSuites,
|
||||
SessionTicketsDisabled: c.SessionTicketsDisabled,
|
||||
SessionTicketKey: c.SessionTicketKey,
|
||||
ClientSessionCache: c.ClientSessionCache,
|
||||
MinVersion: c.MinVersion,
|
||||
MaxVersion: c.MaxVersion,
|
||||
CurvePreferences: c.CurvePreferences,
|
||||
DynamicRecordSizingDisabled: c.DynamicRecordSizingDisabled,
|
||||
Renegotiation: c.Renegotiation,
|
||||
if c == nil {
|
||||
return &tls.Config{}
|
||||
}
|
||||
|
||||
return c.Clone()
|
||||
}
|
||||
|
37
gateway/vendor/github.com/nats-io/go-nats/util/tls_go17.go
generated
vendored
Normal file
37
gateway/vendor/github.com/nats-io/go-nats/util/tls_go17.go
generated
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
// Copyright 2016 Apcera Inc. All rights reserved.
|
||||
// +build go1.7,!go1.8
|
||||
|
||||
package util
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
)
|
||||
|
||||
// CloneTLSConfig returns a copy of c. Only the exported fields are copied.
|
||||
// This is temporary, until this is provided by the language.
|
||||
// https://go-review.googlesource.com/#/c/28075/
|
||||
func CloneTLSConfig(c *tls.Config) *tls.Config {
|
||||
return &tls.Config{
|
||||
Rand: c.Rand,
|
||||
Time: c.Time,
|
||||
Certificates: c.Certificates,
|
||||
NameToCertificate: c.NameToCertificate,
|
||||
GetCertificate: c.GetCertificate,
|
||||
RootCAs: c.RootCAs,
|
||||
NextProtos: c.NextProtos,
|
||||
ServerName: c.ServerName,
|
||||
ClientAuth: c.ClientAuth,
|
||||
ClientCAs: c.ClientCAs,
|
||||
InsecureSkipVerify: c.InsecureSkipVerify,
|
||||
CipherSuites: c.CipherSuites,
|
||||
PreferServerCipherSuites: c.PreferServerCipherSuites,
|
||||
SessionTicketsDisabled: c.SessionTicketsDisabled,
|
||||
SessionTicketKey: c.SessionTicketKey,
|
||||
ClientSessionCache: c.ClientSessionCache,
|
||||
MinVersion: c.MinVersion,
|
||||
MaxVersion: c.MaxVersion,
|
||||
CurvePreferences: c.CurvePreferences,
|
||||
DynamicRecordSizingDisabled: c.DynamicRecordSizingDisabled,
|
||||
Renegotiation: c.Renegotiation,
|
||||
}
|
||||
}
|
35
gateway/vendor/github.com/nats-io/go-nats/util/tls_pre17.go
generated
vendored
35
gateway/vendor/github.com/nats-io/go-nats/util/tls_pre17.go
generated
vendored
@ -1,35 +0,0 @@
|
||||
// Copyright 2016 Apcera Inc. All rights reserved.
|
||||
// +build go1.5,!go1.7
|
||||
|
||||
package util
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
)
|
||||
|
||||
// CloneTLSConfig returns a copy of c. Only the exported fields are copied.
|
||||
// This is temporary, until this is provided by the language.
|
||||
// https://go-review.googlesource.com/#/c/28075/
|
||||
func CloneTLSConfig(c *tls.Config) *tls.Config {
|
||||
return &tls.Config{
|
||||
Rand: c.Rand,
|
||||
Time: c.Time,
|
||||
Certificates: c.Certificates,
|
||||
NameToCertificate: c.NameToCertificate,
|
||||
GetCertificate: c.GetCertificate,
|
||||
RootCAs: c.RootCAs,
|
||||
NextProtos: c.NextProtos,
|
||||
ServerName: c.ServerName,
|
||||
ClientAuth: c.ClientAuth,
|
||||
ClientCAs: c.ClientCAs,
|
||||
InsecureSkipVerify: c.InsecureSkipVerify,
|
||||
CipherSuites: c.CipherSuites,
|
||||
PreferServerCipherSuites: c.PreferServerCipherSuites,
|
||||
SessionTicketsDisabled: c.SessionTicketsDisabled,
|
||||
SessionTicketKey: c.SessionTicketKey,
|
||||
ClientSessionCache: c.ClientSessionCache,
|
||||
MinVersion: c.MinVersion,
|
||||
MaxVersion: c.MaxVersion,
|
||||
CurvePreferences: c.CurvePreferences,
|
||||
}
|
||||
}
|
24
gateway/vendor/github.com/nats-io/nuid/.gitignore
generated
vendored
Normal file
24
gateway/vendor/github.com/nats-io/nuid/.gitignore
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
*.test
|
||||
*.prof
|
16
gateway/vendor/github.com/nats-io/nuid/.travis.yml
generated
vendored
Normal file
16
gateway/vendor/github.com/nats-io/nuid/.travis.yml
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
language: go
|
||||
sudo: false
|
||||
go:
|
||||
- 1.5
|
||||
|
||||
install:
|
||||
- go get -t ./...
|
||||
- go get github.com/mattn/goveralls
|
||||
|
||||
script:
|
||||
- go fmt ./...
|
||||
- go vet ./...
|
||||
- go test -v
|
||||
- go test -v --race
|
||||
- go test -v -covermode=count -coverprofile=coverage.out
|
||||
- $HOME/gopath/bin/goveralls -coverprofile coverage.out -service travis-ci
|
4
gateway/vendor/github.com/nats-io/nuid/README.md
generated
vendored
4
gateway/vendor/github.com/nats-io/nuid/README.md
generated
vendored
@ -35,8 +35,8 @@ NUID needs to be very fast to generate and be truly unique, all while being entr
|
||||
NUID uses 12 bytes of crypto generated data (entropy draining), and 10 bytes of pseudo-random
|
||||
sequential data that increments with a pseudo-random increment.
|
||||
|
||||
Total length of a NUID string is 22 bytes of base 62 ascii text, so 62^22 or
|
||||
2707803647802660400290261537185326956544 possibilities.
|
||||
Total length of a NUID string is 22 bytes of base 36 ascii text, so 36^22 or
|
||||
17324272922341479351919144385642496 possibilities.
|
||||
|
||||
NUID can generate identifiers as fast as 60ns, or ~16 million per second. There is an associated
|
||||
benchmark you can use to test performance on your own hardware.
|
||||
|
79
gateway/vendor/github.com/nats-io/nuid/nuid_test.go
generated
vendored
Normal file
79
gateway/vendor/github.com/nats-io/nuid/nuid_test.go
generated
vendored
Normal file
@ -0,0 +1,79 @@
|
||||
package nuid
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDigits(t *testing.T) {
|
||||
if len(digits) != base {
|
||||
t.Fatalf("digits length does not match base modulo")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGlobalNUIDInit(t *testing.T) {
|
||||
if globalNUID == nil {
|
||||
t.Fatalf("Expected g to be non-nil\n")
|
||||
}
|
||||
if globalNUID.pre == nil || len(globalNUID.pre) != preLen {
|
||||
t.Fatalf("Expected prefix to be initialized\n")
|
||||
}
|
||||
if globalNUID.seq == 0 {
|
||||
t.Fatalf("Expected seq to be non-zero\n")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNUIDRollover(t *testing.T) {
|
||||
globalNUID.seq = maxSeq
|
||||
// copy
|
||||
oldPre := append([]byte{}, globalNUID.pre...)
|
||||
Next()
|
||||
if bytes.Equal(globalNUID.pre, oldPre) {
|
||||
t.Fatalf("Expected new pre, got the old one\n")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGUIDLen(t *testing.T) {
|
||||
nuid := Next()
|
||||
if len(nuid) != totalLen {
|
||||
t.Fatalf("Expected len of %d, got %d\n", totalLen, len(nuid))
|
||||
}
|
||||
}
|
||||
|
||||
func TestProperPrefix(t *testing.T) {
|
||||
min := byte(255)
|
||||
max := byte(0)
|
||||
for i := 0; i < len(digits); i++ {
|
||||
if digits[i] < min {
|
||||
min = digits[i]
|
||||
}
|
||||
if digits[i] > max {
|
||||
max = digits[i]
|
||||
}
|
||||
}
|
||||
total := 100000
|
||||
for i := 0; i < total; i++ {
|
||||
n := New()
|
||||
for j := 0; j < preLen; j++ {
|
||||
if n.pre[j] < min || n.pre[j] > max {
|
||||
t.Fatalf("Iter %d. Valid range for bytes prefix: [%d..%d]\nIncorrect prefix at pos %d: %v (%s)",
|
||||
i, min, max, j, n.pre, string(n.pre))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkNUIDSpeed(b *testing.B) {
|
||||
n := New()
|
||||
b.ReportAllocs()
|
||||
for i := 0; i < b.N; i++ {
|
||||
n.Next()
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkGlobalNUIDSpeed(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
for i := 0; i < b.N; i++ {
|
||||
Next()
|
||||
}
|
||||
}
|
19
gateway/vendor/github.com/nats-io/nuid/unique_test.go
generated
vendored
Normal file
19
gateway/vendor/github.com/nats-io/nuid/unique_test.go
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
// +build !race
|
||||
|
||||
package nuid
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestBasicUniqueness(t *testing.T) {
|
||||
n := 10000000
|
||||
m := make(map[string]struct{}, n)
|
||||
for i := 0; i < n; i++ {
|
||||
n := Next()
|
||||
if _, ok := m[n]; ok {
|
||||
t.Fatalf("Duplicate NUID found: %v\n", n)
|
||||
}
|
||||
m[n] = struct{}{}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user