Example #1
4
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)
	}
}
Example #2
0
func TestCallbacksOrder(t *testing.T) {
	authS, authSOpts := RunServerWithConfig("./configs/tls.conf")
	defer authS.Shutdown()

	s := RunDefaultServer()
	defer s.Shutdown()

	firstDisconnect := true
	dtime1 := time.Time{}
	dtime2 := time.Time{}
	rtime := time.Time{}
	atime1 := time.Time{}
	atime2 := time.Time{}
	ctime := time.Time{}

	cbErrors := make(chan error, 20)

	reconnected := make(chan bool)
	closed := make(chan bool)
	asyncErr := make(chan bool, 2)
	recvCh := make(chan bool, 2)
	recvCh1 := make(chan bool)
	recvCh2 := make(chan bool)

	dch := func(nc *nats.Conn) {
		if err := isRunningInAsyncCBDispatcher(); err != nil {
			cbErrors <- err
			return
		}
		time.Sleep(100 * time.Millisecond)
		if firstDisconnect {
			firstDisconnect = false
			dtime1 = time.Now()
		} else {
			dtime2 = time.Now()
		}
	}

	rch := func(nc *nats.Conn) {
		if err := isRunningInAsyncCBDispatcher(); err != nil {
			cbErrors <- err
			reconnected <- true
			return
		}
		time.Sleep(50 * time.Millisecond)
		rtime = time.Now()
		reconnected <- true
	}

	ech := func(nc *nats.Conn, sub *nats.Subscription, err error) {
		if err := isRunningInAsyncCBDispatcher(); err != nil {
			cbErrors <- err
			asyncErr <- true
			return
		}
		if sub.Subject == "foo" {
			time.Sleep(20 * time.Millisecond)
			atime1 = time.Now()
		} else {
			atime2 = time.Now()
		}
		asyncErr <- true
	}

	cch := func(nc *nats.Conn) {
		if err := isRunningInAsyncCBDispatcher(); err != nil {
			cbErrors <- err
			closed <- true
			return
		}
		ctime = time.Now()
		closed <- true
	}

	url := net.JoinHostPort(authSOpts.Host, strconv.Itoa(authSOpts.Port))
	url = "nats://" + url + "," + nats.DefaultURL

	nc, err := nats.Connect(url,
		nats.DisconnectHandler(dch),
		nats.ReconnectHandler(rch),
		nats.ClosedHandler(cch),
		nats.ErrorHandler(ech),
		nats.ReconnectWait(50*time.Millisecond),
		nats.DontRandomize())
	if err != nil {
		t.Fatalf("Unable to connect: %v\n", err)
	}
	defer nc.Close()

	ncp, err := nats.Connect(nats.DefaultURL,
		nats.ReconnectWait(50*time.Millisecond))
	if err != nil {
		t.Fatalf("Unable to connect: %v\n", err)
	}
	defer ncp.Close()

	// Wait to make sure that if we have closed (incorrectly) the
	// asyncCBDispatcher during the connect process, this is caught here.
	time.Sleep(time.Second)

	s.Shutdown()

	s = RunDefaultServer()
	defer s.Shutdown()

	if err := Wait(reconnected); err != nil {
		t.Fatal("Did not get the reconnected callback")
	}

	var sub1 *nats.Subscription
	var sub2 *nats.Subscription

	recv := func(m *nats.Msg) {
		// Signal that one message is received
		recvCh <- true

		// We will now block
		if m.Subject == "foo" {
			<-recvCh1
		} else {
			<-recvCh2
		}
		m.Sub.Unsubscribe()
	}

	sub1, err = nc.Subscribe("foo", recv)
	if err != nil {
		t.Fatalf("Unable to create subscription: %v\n", err)
	}
	sub1.SetPendingLimits(1, 100000)

	sub2, err = nc.Subscribe("bar", recv)
	if err != nil {
		t.Fatalf("Unable to create subscription: %v\n", err)
	}
	sub2.SetPendingLimits(1, 100000)

	nc.Flush()

	ncp.Publish("foo", []byte("test"))
	ncp.Publish("bar", []byte("test"))
	ncp.Flush()

	// Wait notification that message were received
	err = Wait(recvCh)
	if err == nil {
		err = Wait(recvCh)
	}
	if err != nil {
		t.Fatal("Did not receive message")
	}

	for i := 0; i < 2; i++ {
		ncp.Publish("foo", []byte("test"))
		ncp.Publish("bar", []byte("test"))
	}
	ncp.Flush()

	if err := Wait(asyncErr); err != nil {
		t.Fatal("Did not get the async callback")
	}
	if err := Wait(asyncErr); err != nil {
		t.Fatal("Did not get the async callback")
	}

	close(recvCh1)
	close(recvCh2)

	nc.Close()

	if err := Wait(closed); err != nil {
		t.Fatal("Did not get the close callback")
	}

	if len(cbErrors) > 0 {
		t.Fatalf("%v", <-cbErrors)
	}

	if (dtime1 == time.Time{}) || (dtime2 == time.Time{}) || (rtime == time.Time{}) || (atime1 == time.Time{}) || (atime2 == time.Time{}) || (ctime == time.Time{}) {
		t.Fatalf("Some callbacks did not fire:\n%v\n%v\n%v\n%v\n%v\n%v", dtime1, rtime, atime1, atime2, dtime2, ctime)
	}

	if rtime.Before(dtime1) || dtime2.Before(rtime) || atime2.Before(atime1) || ctime.Before(atime2) {
		t.Fatalf("Wrong callback order:\n%v\n%v\n%v\n%v\n%v\n%v", dtime1, rtime, atime1, atime2, dtime2, ctime)
	}
}
Example #3
0
// Unsubscribe is to unsubscribe to subject
func Unsubscribe(sub *nats.Subscription) {
	// Unsubscribe
	sub.Unsubscribe()
}
Example #4
0
func TestSetPendingLimits(t *testing.T) {
	s := RunDefaultServer()
	defer s.Shutdown()

	nc := NewDefaultConnection(t)
	defer nc.Close()

	payload := []byte("hello")
	payloadLen := len(payload)
	toSend := 100

	var sub *nats.Subscription

	// Check for invalid values
	invalid := func() error {
		if err := sub.SetPendingLimits(0, 1); err == nil {
			return fmt.Errorf("Setting limit with 0 should fail")
		}
		if err := sub.SetPendingLimits(1, 0); err == nil {
			return fmt.Errorf("Setting limit with 0 should fail")
		}
		return nil
	}
	// function to send messages
	send := func(subject string, count int) {
		for i := 0; i < count; i++ {
			if err := nc.Publish(subject, payload); err != nil {
				t.Fatalf("Unexpected error on publish: %v", err)
			}
		}
		nc.Flush()
	}

	// Check pending vs expected values
	var limitCount, limitBytes int
	var expectedCount, expectedBytes int
	checkPending := func() error {
		lc, lb, err := sub.PendingLimits()
		if err != nil {
			return err
		}
		if lc != limitCount || lb != limitBytes {
			return fmt.Errorf("Unexpected limits, expected %v msgs %v bytes, got %v msgs %v bytes",
				limitCount, limitBytes, lc, lb)
		}
		msgs, bytes, err := sub.Pending()
		if err != nil {
			return fmt.Errorf("Unexpected error getting pending counts: %v", err)
		}
		if (msgs != expectedCount && msgs != expectedCount-1) ||
			(bytes != expectedBytes && bytes != expectedBytes-payloadLen) {
			return fmt.Errorf("Unexpected counts, expected %v msgs %v bytes, got %v msgs %v bytes",
				expectedCount, expectedBytes, msgs, bytes)
		}
		return nil
	}

	recv := make(chan bool)
	block := make(chan bool)
	cb := func(m *nats.Msg) {
		recv <- true
		<-block
		m.Sub.Unsubscribe()
	}
	subj := "foo"
	sub, err := nc.Subscribe(subj, cb)
	if err != nil {
		t.Fatalf("Unexpected error on subscribe: %v", err)
	}
	defer sub.Unsubscribe()
	if err := invalid(); err != nil {
		t.Fatalf("%v", err)
	}
	// Check we apply limit only for size
	limitCount = -1
	limitBytes = (toSend / 2) * payloadLen
	if err := sub.SetPendingLimits(limitCount, limitBytes); err != nil {
		t.Fatalf("Unexpected error setting limits: %v", err)
	}
	// Send messages
	send(subj, toSend)
	// Wait for message to be received
	if err := Wait(recv); err != nil {
		t.Fatal("Did not get our message")
	}
	expectedBytes = limitBytes
	expectedCount = limitBytes / payloadLen
	if err := checkPending(); err != nil {
		t.Fatalf("%v", err)
	}
	// Release callback
	block <- true

	subj = "bar"
	sub, err = nc.Subscribe(subj, cb)
	if err != nil {
		t.Fatalf("Unexpected error on subscribe: %v", err)
	}
	defer sub.Unsubscribe()
	// Check we apply limit only for count
	limitCount = toSend / 4
	limitBytes = -1
	if err := sub.SetPendingLimits(limitCount, limitBytes); err != nil {
		t.Fatalf("Unexpected error setting limits: %v", err)
	}
	// Send messages
	send(subj, toSend)
	// Wait for message to be received
	if err := Wait(recv); err != nil {
		t.Fatal("Did not get our message")
	}
	expectedCount = limitCount
	expectedBytes = limitCount * payloadLen
	if err := checkPending(); err != nil {
		t.Fatalf("%v", err)
	}
	// Release callback
	block <- true

	subj = "baz"
	sub, err = nc.SubscribeSync(subj)
	if err != nil {
		t.Fatalf("Unexpected error on subscribe: %v", err)
	}
	defer sub.Unsubscribe()
	if err := invalid(); err != nil {
		t.Fatalf("%v", err)
	}
	// Check we apply limit only for size
	limitCount = -1
	limitBytes = (toSend / 2) * payloadLen
	if err := sub.SetPendingLimits(limitCount, limitBytes); err != nil {
		t.Fatalf("Unexpected error setting limits: %v", err)
	}
	// Send messages
	send(subj, toSend)
	expectedBytes = limitBytes
	expectedCount = limitBytes / payloadLen
	if err := checkPending(); err != nil {
		t.Fatalf("%v", err)
	}
	sub.Unsubscribe()
	nc.Flush()

	subj = "boz"
	sub, err = nc.SubscribeSync(subj)
	if err != nil {
		t.Fatalf("Unexpected error on subscribe: %v", err)
	}
	defer sub.Unsubscribe()
	// Check we apply limit only for count
	limitCount = toSend / 4
	limitBytes = -1
	if err := sub.SetPendingLimits(limitCount, limitBytes); err != nil {
		t.Fatalf("Unexpected error setting limits: %v", err)
	}
	// Send messages
	send(subj, toSend)
	expectedCount = limitCount
	expectedBytes = limitCount * payloadLen
	if err := checkPending(); err != nil {
		t.Fatalf("%v", err)
	}
	sub.Unsubscribe()
	nc.Flush()
}
Example #5
0
func TestChanSubscriberPendingLimits(t *testing.T) {
	s := RunDefaultServer()
	defer s.Shutdown()

	nc := NewDefaultConnection(t)
	defer nc.Close()

	// There was a defect that prevented to receive more than
	// the default pending message limit. Trying to send more
	// than this limit.
	total := nats.DefaultSubPendingMsgsLimit + 100

	for typeSubs := 0; typeSubs < 3; typeSubs++ {

		func() {
			// Create our own channel.
			ch := make(chan *nats.Msg, total)

			var err error
			var sub *nats.Subscription
			switch typeSubs {
			case 0:
				sub, err = nc.ChanSubscribe("foo", ch)
			case 1:
				sub, err = nc.ChanQueueSubscribe("foo", "bar", ch)
			case 2:
				sub, err = nc.QueueSubscribeSyncWithChan("foo", "bar", ch)
			}
			if err != nil {
				t.Fatalf("Unexpected error on subscribe: %v", err)
			}
			defer sub.Unsubscribe()

			// Send some messages to ourselves.
			go func() {
				for i := 0; i < total; i++ {
					if err := nc.Publish("foo", []byte("Hello")); err != nil {
						t.Fatalf("Unexpected error on publish: %v", err)
					}
				}
			}()

			received := 0
			tm := time.NewTimer(5 * time.Second)
			defer tm.Stop()

			chk := func(ok bool) {
				if !ok {
					t.Fatalf("Got an error reading from channel")
				} else {
					received++
				}
			}

			// Go ahead and receive
			for {
				select {
				case _, ok := <-ch:
					chk(ok)
				case <-tm.C:
					t.Fatalf("Timed out waiting on messages")
				}
				if received >= total {
					return
				}
			}
		}()
	}
}