123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318 |
- /*
- * Copyright (c) 2013 IBM Corp.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Seth Hoenig
- * Allan Stockdill-Mander
- * Mike Robertson
- */
- package mqtt
- import (
- "testing"
- "github.com/eclipse/paho.mqtt.golang/packets"
- )
- func Test_newRouter(t *testing.T) {
- router, stop := newRouter()
- if router == nil {
- t.Fatalf("router is nil")
- }
- if stop == nil {
- t.Fatalf("stop is nil")
- }
- if router.routes.Len() != 0 {
- t.Fatalf("router.routes was not empty")
- }
- }
- func Test_AddRoute(t *testing.T) {
- router, _ := newRouter()
- cb := func(client Client, msg Message) {
- }
- router.addRoute("/alpha", cb)
- if router.routes.Len() != 1 {
- t.Fatalf("router.routes was wrong")
- }
- }
- func Test_Match(t *testing.T) {
- router, _ := newRouter()
- router.addRoute("/alpha", nil)
- if !router.routes.Front().Value.(*route).match("/alpha") {
- t.Fatalf("match function is bad")
- }
- if router.routes.Front().Value.(*route).match("alpha") {
- t.Fatalf("match function is bad")
- }
- }
- func Test_match(t *testing.T) {
- check := func(route, topic string, exp bool) {
- result := routeIncludesTopic(route, topic)
- if exp != result {
- t.Errorf("match was bad R: %v, T: %v, EXP: %v", route, topic, exp)
- }
- }
- // ** Basic **
- R := ""
- T := ""
- check(R, T, true)
- R = "x"
- T = ""
- check(R, T, false)
- R = ""
- T = "x"
- check(R, T, false)
- R = "x"
- T = "x"
- check(R, T, true)
- R = "x"
- T = "X"
- check(R, T, false)
- R = "alpha"
- T = "alpha"
- check(R, T, true)
- R = "alpha"
- T = "beta"
- check(R, T, false)
- // ** / **
- R = "/"
- T = "/"
- check(R, T, true)
- R = "/one"
- T = "/one"
- check(R, T, true)
- R = "/"
- T = "/two"
- check(R, T, false)
- R = "/two"
- T = "/"
- check(R, T, false)
- R = "/two"
- T = "two"
- check(R, T, false) // a leading "/" creates a different topic
- R = "/a/"
- T = "/a"
- check(R, T, false)
- R = "/a/"
- T = "/a/b"
- check(R, T, false)
- R = "/a/b"
- T = "/a/b"
- check(R, T, true)
- R = "/a/b/"
- T = "/a/b"
- check(R, T, false)
- R = "/a/b"
- T = "/R/b"
- check(R, T, false)
- // ** + **
- R = "/a/+/c"
- T = "/a/b/c"
- check(R, T, true)
- R = "/+/b/c"
- T = "/a/b/c"
- check(R, T, true)
- R = "/a/b/+"
- T = "/a/b/c"
- check(R, T, true)
- R = "/a/+/+"
- T = "/a/b/c"
- check(R, T, true)
- R = "/+/+/+"
- T = "/a/b/c"
- check(R, T, true)
- R = "/+/+/c"
- T = "/a/b/c"
- check(R, T, true)
- R = "/a/b/c/+" // different number of levels
- T = "/a/b/c"
- check(R, T, false)
- R = "+"
- T = "a"
- check(R, T, true)
- R = "/+"
- T = "a"
- check(R, T, false)
- R = "+/+"
- T = "/a"
- check(R, T, true)
- R = "+/+"
- T = "a"
- check(R, T, false)
- // ** # **
- R = "#"
- T = "/a/b/c"
- check(R, T, true)
- R = "/#"
- T = "/a/b/c"
- check(R, T, true)
- // R = "/#/" // not valid
- // T = "/a/b/c"
- // check(R, T, true)
- R = "/#"
- T = "/a/b/c"
- check(R, T, true)
- R = "/a/#"
- T = "/a/b/c"
- check(R, T, true)
- R = "/a/#"
- T = "/a/b/c"
- check(R, T, true)
- R = "/a/b/#"
- T = "/a/b/c"
- check(R, T, true)
- // ** unicode **
- R = "☃"
- T = "☃"
- check(R, T, true)
- R = "✈"
- T = "☃"
- check(R, T, false)
- R = "/☃/✈"
- T = "/☃/ッ"
- check(R, T, false)
- R = "#"
- T = "/☃/ッ"
- check(R, T, true)
- R = "/☃/+"
- T = "/☃/ッ/♫/ø/☹☹☹"
- check(R, T, false)
- R = "/☃/#"
- T = "/☃/ッ/♫/ø/☹☹☹"
- check(R, T, true)
- R = "/☃/ッ/♫/ø/+"
- T = "/☃/ッ/♫/ø/☹☹☹"
- check(R, T, true)
- R = "/☃/ッ/+/ø/☹☹☹"
- T = "/☃/ッ/♫/ø/☹☹☹"
- check(R, T, true)
- R = "/+/a/ッ/+/ø/☹☹☹"
- T = "/b/♫/ッ/♫/ø/☹☹☹"
- check(R, T, false)
- R = "/+/♫/ッ/+/ø/☹☹☹"
- T = "/b/♫/ッ/♫/ø/☹☹☹"
- check(R, T, true)
- }
- func Test_MatchAndDispatch(t *testing.T) {
- calledback := make(chan bool)
- cb := func(c Client, m Message) {
- calledback <- true
- }
- pub := packets.NewControlPacket(packets.Publish).(*packets.PublishPacket)
- pub.Qos = 2
- pub.TopicName = "a"
- pub.Payload = []byte("foo")
- msgs := make(chan *packets.PublishPacket)
- router, stopper := newRouter()
- router.addRoute("a", cb)
- router.matchAndDispatch(msgs, true, &client{oboundP: make(chan *PacketAndToken, 100)})
- msgs <- pub
- <-calledback
- stopper <- true
- select {
- case msgs <- pub:
- t.Errorf("msgs should not have a listener")
- default:
- }
- }
- func Test_SharedSubscription_MatchAndDispatch(t *testing.T) {
- calledback := make(chan bool)
- cb := func(c Client, m Message) {
- calledback <- true
- }
- pub := packets.NewControlPacket(packets.Publish).(*packets.PublishPacket)
- pub.Qos = 2
- pub.TopicName = "a"
- pub.Payload = []byte("foo")
- msgs := make(chan *packets.PublishPacket)
- router, stopper := newRouter()
- router.addRoute("$share/az1/a", cb)
- router.matchAndDispatch(msgs, true, &client{oboundP: make(chan *PacketAndToken, 100)})
- msgs <- pub
- <-calledback
- stopper <- true
- select {
- case msgs <- pub:
- t.Errorf("msgs should not have a listener")
- default:
- }
- }
|