func Test_persistInbound_pubrel(t *testing.T) { ts := &TestStore{} pub := packets.NewControlPacket(packets.Publish).(*packets.PublishPacket) pub.Qos = 2 pub.TopicName = "/pub2" pub.Payload = []byte{0xCC, 0x06} pub.MessageID = 55 publishKey := inboundKeyFromMID(pub.MessageID) ts.Put(publishKey, pub) m := packets.NewControlPacket(packets.Pubrel).(*packets.PubrelPacket) m.MessageID = 55 persistInbound(ts, m) // will overwrite publish if len(ts.mput) != 2 { t.Fatalf("persistInbound in bad state") } if len(ts.mget) != 0 { t.Fatalf("persistInbound in bad state") } if len(ts.mdel) != 0 { t.Fatalf("persistInbound in bad state") } }
func Test_persistInbound_puback(t *testing.T) { ts := &TestStore{} pub := packets.NewControlPacket(packets.Publish).(*packets.PublishPacket) pub.Qos = 1 pub.TopicName = "/pub1" pub.Payload = []byte{0xCC, 0x04} pub.MessageID = 53 publishKey := inboundKeyFromMID(pub.MessageID) ts.Put(publishKey, pub) m := packets.NewControlPacket(packets.Puback).(*packets.PubackPacket) m.MessageID = 53 persistInbound(ts, m) // "deletes" packets.Publish from store if len(ts.mput) != 1 { // not actually deleted in TestStore t.Fatalf("persistInbound in bad state") } if len(ts.mget) != 0 { t.Fatalf("persistInbound in bad state") } if len(ts.mdel) != 1 || ts.mdel[0] != 53 { t.Fatalf("persistInbound in bad state") } }
func Test_persistInbound_pubrec(t *testing.T) { ts := &TestStore{} pub := packets.NewControlPacket(packets.Publish).(*packets.PublishPacket) pub.Qos = 2 pub.TopicName = "/pub2" pub.Payload = []byte{0xCC, 0x05} pub.MessageID = 54 publishKey := inboundKeyFromMID(pub.MessageID) ts.Put(publishKey, pub) m := packets.NewControlPacket(packets.Pubrec).(*packets.PubrecPacket) m.MessageID = 54 persistInbound(ts, m) if len(ts.mput) != 1 || ts.mput[0] != 54 { t.Fatalf("persistInbound in bad state") } if len(ts.mget) != 0 { t.Fatalf("persistInbound in bad state") } if len(ts.mdel) != 0 { t.Fatalf("persistInbound in bad state") } }
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, nil) msgs <- pub <-calledback stopper <- true select { case msgs <- pub: t.Errorf("msgs should not have a listener") default: } }
// SubscribeMultiple starts a new subscription for multiple topics. Provide a MessageHandler to // be executed when a message is published on one of the topics provided. func (c *Client) SubscribeMultiple(filters map[string]byte, callback MessageHandler) Token { var err error token := newToken(packets.Subscribe).(*SubscribeToken) DEBUG.Println(CLI, "enter SubscribeMultiple") if !c.IsConnected() { token.err = ErrNotConnected token.flowComplete() return token } sub := packets.NewControlPacket(packets.Subscribe).(*packets.SubscribePacket) if sub.Topics, sub.Qoss, err = validateSubscribeMap(filters); err != nil { token.err = err return token } if callback != nil { for topic := range filters { c.msgRouter.addRoute(topic, callback) } } token.subs = make([]string, len(sub.Topics)) copy(token.subs, sub.Topics) //c.oboundP <- &PacketAndToken{p: sub, t: token} sendServer(c, sub, token) DEBUG.Println(CLI, "exit SubscribeMultiple") return token }
// Subscribe starts a new subscription. Provide a MessageHandler to be executed when // a message is published on the topic provided. func (c *Client) Subscribe(topic string, qos byte, callback MessageHandler) Token { token := newToken(packets.Subscribe).(*SubscribeToken) DEBUG.Println(CLI, "enter Subscribe") if !c.IsConnected() { token.err = ErrNotConnected token.flowComplete() return token } sub := packets.NewControlPacket(packets.Subscribe).(*packets.SubscribePacket) if err := validateTopicAndQos(topic, qos); err != nil { token.err = err return token } sub.Topics = append(sub.Topics, topic) sub.Qoss = append(sub.Qoss, qos) DEBUG.Println(sub.String()) if callback != nil { c.msgRouter.addRoute(topic, callback) } token.subs = append(token.subs, topic) //c.oboundP <- &PacketAndToken{p: sub, t: token} sendServer(c, sub, token) DEBUG.Println(CLI, "exit Subscribe") return token }
// Publish will publish a message with the specified QoS // and content to the specified topic. // Returns a read only channel used to track // the delivery of the message. func (c *Client) Publish(topic string, qos byte, retained bool, payload interface{}) Token { token := newToken(packets.Publish).(*PublishToken) DEBUG.Println(CLI, "enter Publish") if !c.IsConnected() { token.err = ErrNotConnected token.flowComplete() return token } pub := packets.NewControlPacket(packets.Publish).(*packets.PublishPacket) pub.Qos = qos pub.TopicName = topic pub.Retain = retained switch payload.(type) { case string: pub.Payload = []byte(payload.(string)) case []byte: pub.Payload = payload.([]byte) default: token.err = errors.New("Unknown payload type") token.flowComplete() return token } DEBUG.Println(CLI, "sending publish message, topic:", topic) c.obound <- &PacketAndToken{p: pub, t: token} return token }
func newConnectMsgFromOptions(options *ClientOptions) *packets.ConnectPacket { m := packets.NewControlPacket(packets.Connect).(*packets.ConnectPacket) m.CleanSession = options.CleanSession m.WillFlag = options.WillEnabled m.WillRetain = options.WillRetained m.ClientIdentifier = options.ClientID if options.WillEnabled { m.WillQos = options.WillQos m.WillTopic = options.WillTopic m.WillMessage = options.WillPayload } if options.Username != "" { m.UsernameFlag = true m.Username = options.Username //mustn't have password without user as well if options.Password != "" { m.PasswordFlag = true m.Password = []byte(options.Password) } } m.KeepaliveTimer = uint16(options.KeepAlive.Seconds()) return m }
func Test_NewPingReqMessage(t *testing.T) { pr := packets.NewControlPacket(packets.Pingreq).(*packets.PingreqPacket) if pr.MessageType != packets.Pingreq { t.Errorf("NewPingReqMessage bad msg type: %v", pr.MessageType) } if pr.RemainingLength != 0 { t.Errorf("NewPingReqMessage bad remlen, expected 0, got %d", pr.RemainingLength) } exp := []byte{ 0xC0, 0x00, } var buf bytes.Buffer pr.Write(&buf) bs := buf.Bytes() if len(bs) != 2 { t.Errorf("NewPingReqMessage.Bytes() wrong length: %d", len(bs)) } if exp[0] != bs[0] || exp[1] != bs[1] { t.Errorf("NewPingMessage.Bytes() wrong") } }
func Test_FileStore_Get(t *testing.T) { storedir := "/tmp/TestStore/_get" f := NewFileStore(storedir) f.Open() pm := packets.NewControlPacket(packets.Publish).(*packets.PublishPacket) pm.Qos = 1 pm.TopicName = "/a/b/c" pm.Payload = []byte{0xBE, 0xEF, 0xED} pm.MessageID = 120 key := outboundKeyFromMID(pm.MessageID) f.Put(key, pm) if !exists(storedir + "/o.120.msg") { t.Fatalf("message not in store") } exp := []byte{ /* msg type */ 0x32, // qos 1 /* remlen */ 0x0d, /* topic, msg id in varheader */ 0x00, // length of topic 0x06, 0x2F, // / 0x61, // a 0x2F, // / 0x62, // b 0x2F, // / 0x63, // c /* msg id (is always 2 bytes) */ 0x00, 0x78, /*payload */ 0xBE, 0xEF, 0xED, } m := f.Get(key) if m == nil { t.Fatalf("message not retreived from store") } var msg bytes.Buffer m.Write(&msg) if !bytes.Equal(exp, msg.Bytes()) { t.Fatal("message from store not same as what went in", msg.Bytes()) } }
func Test_MemoryStore_Get(t *testing.T) { m := NewMemoryStore() m.Open() pm := packets.NewControlPacket(packets.Publish).(*packets.PublishPacket) pm.Qos = 1 pm.TopicName = "/a/b/c" pm.Payload = []byte{0xBE, 0xEF, 0xED} pm.MessageID = 120 key := outboundKeyFromMID(pm.MessageID) m.Put(key, pm) if len(m.messages) != 1 { t.Fatalf("message not in store") } exp := []byte{ /* msg type */ 0x32, // qos 1 /* remlen */ 0x0d, /* topic, msg id in varheader */ 0x00, // length of topic 0x06, 0x2F, // / 0x61, // a 0x2F, // / 0x62, // b 0x2F, // / 0x63, // c /* msg id (is always 2 bytes) */ 0x00, 0x78, /*payload */ 0xBE, 0xEF, 0xED, } msg := m.Get(key) if msg == nil { t.Fatalf("message not retreived from store") } var buf bytes.Buffer msg.Write(&buf) if !bytes.Equal(exp, buf.Bytes()) { t.Fatalf("message from store not same as what went in") } }
// Disconnect will end the connection with the server, but not before waiting // the specified number of milliseconds to wait for existing work to be // completed. func (c *Client) Disconnect(quiesce uint) { if !c.IsConnected() { WARN.Println(CLI, "already disconnected") return } DEBUG.Println(CLI, "disconnecting") c.setConnected(false) dm := packets.NewControlPacket(packets.Disconnect).(*packets.DisconnectPacket) dt := newToken(packets.Disconnect) c.oboundP <- &PacketAndToken{p: dm, t: dt} // wait for work to finish, or quiesce time consumed dt.WaitTimeout(time.Duration(quiesce) * time.Millisecond) c.disconnect() }
func Test_MemoryStore_write(t *testing.T) { m := NewMemoryStore() m.Open() pm := packets.NewControlPacket(packets.Publish).(*packets.PublishPacket) pm.Qos = 1 pm.TopicName = "/a/b/c" pm.Payload = []byte{0xBE, 0xEF, 0xED} pm.MessageID = 91 key := inboundKeyFromMID(pm.MessageID) m.Put(key, pm) if len(m.messages) != 1 { t.Fatalf("message not in store") } }
func Test_persistInbound_connack(t *testing.T) { ts := &TestStore{} m := packets.NewControlPacket(packets.Connack) persistInbound(ts, m) if len(ts.mput) != 0 { t.Fatalf("persistInbound in bad state") } if len(ts.mget) != 0 { t.Fatalf("persistInbound in bad state") } if len(ts.mdel) != 0 { t.Fatalf("persistInbound in bad state") } }
func Test_persistOutbound_disconnect(t *testing.T) { ts := &TestStore{} m := packets.NewControlPacket(packets.Disconnect) persistOutbound(ts, m) if len(ts.mput) != 0 { t.Fatalf("persistOutbound put message it should not have") } if len(ts.mget) != 0 { t.Fatalf("persistOutbound get message it should not have") } if len(ts.mdel) != 0 { t.Fatalf("persistOutbound del message it should not have") } }
func Test_FileStore_write(t *testing.T) { storedir := "/tmp/TestStore/_write" f := NewFileStore(storedir) f.Open() pm := packets.NewControlPacket(packets.Publish).(*packets.PublishPacket) pm.Qos = 1 pm.TopicName = "a/b/c" pm.Payload = []byte{0xBE, 0xEF, 0xED} pm.MessageID = 91 key := inboundKeyFromMID(pm.MessageID) f.Put(key, pm) if !exists(storedir + "/i.91.msg") { t.Fatalf("message not in store") } }
func Test_persistOutbound_pubrel(t *testing.T) { ts := &TestStore{} m := packets.NewControlPacket(packets.Pubrel).(*packets.PubrelPacket) m.MessageID = 43 persistOutbound(ts, m) if len(ts.mput) != 1 || ts.mput[0] != 43 { t.Fatalf("persistOutbound put message it should not have") } if len(ts.mget) != 0 { t.Fatalf("persistOutbound get message it should not have") } if len(ts.mdel) != 0 { t.Fatalf("persistOutbound del message it should not have") } }
func Test_persistOutbound_unsubscribe(t *testing.T) { ts := &TestStore{} m := packets.NewControlPacket(packets.Unsubscribe).(*packets.UnsubscribePacket) m.Topics = []string{"/posub"} m.MessageID = 45 persistOutbound(ts, m) if len(ts.mput) != 1 || ts.mput[0] != 45 { t.Fatalf("persistOutbound put message it should not have") } if len(ts.mget) != 0 { t.Fatalf("persistOutbound get message it should not have") } if len(ts.mdel) != 0 { t.Fatalf("persistOutbound del message it should not have") } }
func Test_persistInbound_unsuback(t *testing.T) { ts := &TestStore{} m := packets.NewControlPacket(packets.Unsuback).(*packets.UnsubackPacket) m.MessageID = 58 persistInbound(ts, m) if len(ts.mput) != 0 { t.Fatalf("persistInbound in bad state") } if len(ts.mget) != 0 { t.Fatalf("persistInbound in bad state") } if len(ts.mdel) != 1 || ts.mdel[0] != 58 { t.Fatalf("persistInbound in bad state") } }
func Test_persistInbound_pubcomp(t *testing.T) { ts := &TestStore{} m := packets.NewControlPacket(packets.Pubcomp).(*packets.PubcompPacket) m.MessageID = 56 persistInbound(ts, m) if len(ts.mput) != 0 { t.Fatalf("persistInbound in bad state") } if len(ts.mget) != 0 { t.Fatalf("persistInbound in bad state") } if len(ts.mdel) != 1 || ts.mdel[0] != 56 { t.Fatalf("persistInbound in bad state") } }
// Unsubscribe will end the subscription from each of the topics provided. // Messages published to those topics from other clients will no longer be // received. func (c *Client) Unsubscribe(topics ...string) Token { token := newToken(packets.Unsubscribe).(*UnsubscribeToken) DEBUG.Println(CLI, "enter Unsubscribe") if !c.IsConnected() { token.err = ErrNotConnected token.flowComplete() return token } unsub := packets.NewControlPacket(packets.Unsubscribe).(*packets.UnsubscribePacket) unsub.Topics = make([]string, len(topics)) copy(unsub.Topics, topics) sendServer(c, unsub, token) //c.oboundP <- &PacketAndToken{p: unsub, t: token} for _, topic := range topics { c.msgRouter.deleteRoute(topic) } DEBUG.Println(CLI, "exit Unsubscribe") return token }
func Test_persistInbound_publish_2(t *testing.T) { ts := &TestStore{} m := packets.NewControlPacket(packets.Publish).(*packets.PublishPacket) m.Qos = 2 m.TopicName = "/pipub2" m.Payload = []byte{0xCC, 0x03} m.MessageID = 52 persistInbound(ts, m) if len(ts.mput) != 1 || ts.mput[0] != 52 { t.Fatalf("persistInbound in bad state") } if len(ts.mget) != 0 { t.Fatalf("persistInbound in bad state") } if len(ts.mdel) != 0 { t.Fatalf("persistInbound in bad state") } }
func Test_persistOutbound_publish_2(t *testing.T) { ts := &TestStore{} m := packets.NewControlPacket(packets.Publish).(*packets.PublishPacket) m.Qos = 2 m.TopicName = "/popub2" m.Payload = []byte{0xBB, 0x00} m.MessageID = 42 persistOutbound(ts, m) if len(ts.mput) != 1 || ts.mput[0] != 42 { t.Fatalf("persistOutbound put message it should not have") } if len(ts.mget) != 0 { t.Fatalf("persistOutbound get message it should not have") } if len(ts.mdel) != 0 { t.Fatalf("persistOutbound del message it should not have") } }
func Test_FileStore_All(t *testing.T) { storedir := "/tmp/TestStore/_all" f := NewFileStore(storedir) f.Open() pm := packets.NewControlPacket(packets.Publish).(*packets.PublishPacket) pm.Qos = 2 pm.TopicName = "/t/r/v" pm.Payload = []byte{0x01, 0x02} pm.MessageID = 121 key := outboundKeyFromMID(pm.MessageID) f.Put(key, pm) keys := f.All() if len(keys) != 1 { t.Fatalf("FileStore.All does not have the messages") } if keys[0] != "o.121" { t.Fatalf("FileStore.All has wrong key") } }
func Test_persistOutbound_connect(t *testing.T) { ts := &TestStore{} m := packets.NewControlPacket(packets.Connect).(*packets.ConnectPacket) m.Qos = 0 m.Username = "******" m.Password = []byte("pass") m.ClientIdentifier = "cid" //m := newConnectMsg(false, false, QOS_ZERO, false, "", nil, "cid", "user", "pass", 10) persistOutbound(ts, m) if len(ts.mput) != 0 { t.Fatalf("persistOutbound put message it should not have") } if len(ts.mget) != 0 { t.Fatalf("persistOutbound get message it should not have") } if len(ts.mdel) != 0 { t.Fatalf("persistOutbound del message it should not have") } }
func Test_MemoryStore_Reset(t *testing.T) { m := NewMemoryStore() m.Open() pm := packets.NewControlPacket(packets.Publish).(*packets.PublishPacket) pm.Qos = 2 pm.TopicName = "/f/r/s" pm.Payload = []byte{0xAB} pm.MessageID = 81 key := outboundKeyFromMID(pm.MessageID) m.Put(key, pm) if len(m.messages) != 1 { t.Fatalf("message not in memstore") } m.Reset() if len(m.messages) != 0 { t.Fatalf("reset did not clear memstore") } }
func Test_MemoryStore_Del(t *testing.T) { m := NewMemoryStore() m.Open() pm := packets.NewControlPacket(packets.Publish).(*packets.PublishPacket) pm.Qos = 1 pm.TopicName = "/a/b/c" pm.Payload = []byte{0xBE, 0xEF, 0xED} pm.MessageID = 17 key := outboundKeyFromMID(pm.MessageID) m.Put(key, pm) if len(m.messages) != 1 { t.Fatalf("message not in store") } m.Del(key) if len(m.messages) != 1 { t.Fatalf("message still exists after deletion") } }
func keepalive(c *Client) { var err error defer func(c *Client) { c.workers.Done() if err != nil { ERROR.Println(NET, c.options.ClientID+":keepalive closed :", err) c.internalConnLost(err) return } if e := recover(); e != nil { ERROR.Println(NET, c.options.ClientID, ":", "keepalive panic closed :", e) c.internalConnLost(fmt.Errorf("读取数据出现严重错误:%v", e)) return } ERROR.Println(NET, c.options.ClientID+":keepalive closed ") }(c) DEBUG.Println(PNG, "keepalive starting") c.pingOutstanding = false waittime := c.options.KeepAlive for { // keeptime := time.Now().Add(c.options.KeepAlive) // keep := uint(time.Since(c.lastContact.get()).Seconds()) // if keep > c.options.KeepAlive.Seconds() { // keeptime = time.Now().Add(c.options.KeepAlive) // } else { // time.Now().Add(c.options.KeepAlive) // } select { case <-c.stop: DEBUG.Println(PNG, "keepalive stopped") //c.workers.Done() return case <-time.After(waittime): last := uint(time.Since(c.lastContact.get()).Seconds()) //DEBUG.Printf("%s last contact: %d (timeout: %d) %b", PNG, last, uint(c.options.KeepAlive.Seconds()), c.pingOutstanding) if last >= uint(c.options.KeepAlive.Seconds()) { if !c.pingOutstanding { //DEBUG.Println(NET, "keepalive sending ping") ping := packets.NewControlPacket(packets.Pingreq).(*packets.PingreqPacket) c.pingOutstanding = true //We don't want to wait behind large messages being sent, the Write call //will block until it it able to send the packet. //ping.Write(c.conn) sendServer(c, ping, nil) waittime = c.options.KeepAlive / 4 if waittime == 0 { waittime = 1 * time.Second } continue } else { //CRITICAL.Println(PNG, "pingresp not received, disconnecting") err = errors.New("pingresp not received, disconnecting") return } } waittime = c.options.KeepAlive - time.Since(c.lastContact.get()) } } }
// receive Message objects on ibound // store messages if necessary // send replies on obound // delete messages from store if necessary func alllogic(c *Client) { var err error defer func(c *Client) { c.workers.Done() if err != nil { ERROR.Println(NET, c.options.ClientID+":alllogic stopped :", err) c.internalConnLost(err) return } if e := recover(); e != nil { ERROR.Println(NET, c.options.ClientID, ":", "alllogic panic closed :", e) c.internalConnLost(fmt.Errorf("处理数据逻辑出现严重错误:%v", e)) return } ERROR.Println(NET, c.options.ClientID+":alllogic closed ") }(c) DEBUG.Println(NET, "logic started") for { DEBUG.Println(NET, "logic waiting for msg on ibound") select { case msg := <-c.ibound: DEBUG.Println(NET, "logic got msg on ibound, type", reflect.TypeOf(msg)) persistInbound(c.persist, msg) switch msg.(type) { case *packets.PingrespPacket: DEBUG.Println(NET, "received pingresp") c.pingOutstanding = false case *packets.SubackPacket: sa := msg.(*packets.SubackPacket) DEBUG.Println(NET, "received suback, id:", sa.MessageID) token := c.getToken(sa.MessageID).(*SubscribeToken) DEBUG.Println(NET, "granted qoss", sa.GrantedQoss) for i, qos := range sa.GrantedQoss { token.subResult[token.subs[i]] = qos } token.flowComplete() go c.freeID(sa.MessageID) case *packets.UnsubackPacket: ua := msg.(*packets.UnsubackPacket) DEBUG.Println(NET, "received unsuback, id:", ua.MessageID) token := c.getToken(ua.MessageID).(*UnsubscribeToken) token.flowComplete() go c.freeID(ua.MessageID) case *packets.PublishPacket: pp := msg.(*packets.PublishPacket) DEBUG.Println(NET, "received publish, msgId:", pp.MessageID) DEBUG.Println(NET, "putting msg on onPubChan") DEBUG.Println(NET, "done putting msg on incomingPubChan") select { case c.incomingPubChan <- pp: case <-c.stop: return } switch pp.Qos { case 2: pr := packets.NewControlPacket(packets.Pubrec).(*packets.PubrecPacket) pr.MessageID = pp.MessageID DEBUG.Println(NET, "putting pubrec msg on obound") if !sendServer(c, pr, nil) { return } DEBUG.Println(NET, "done putting pubrec msg on obound") case 1: pa := packets.NewControlPacket(packets.Puback).(*packets.PubackPacket) pa.MessageID = pp.MessageID DEBUG.Println(NET, "putting puback msg on obound") if !sendServer(c, pa, nil) { return } DEBUG.Println(NET, "done putting puback msg on obound") } case *packets.PubackPacket: pa := msg.(*packets.PubackPacket) DEBUG.Println(NET, "received puback, id:", pa.MessageID) // c.receipts.get(msg.MsgId()) <- Receipt{} // c.receipts.end(msg.MsgId()) c.getToken(pa.MessageID).flowComplete() c.freeID(pa.MessageID) case *packets.PubrecPacket: prec := msg.(*packets.PubrecPacket) DEBUG.Println(NET, "received pubrec, id:", prec.MessageID) prel := packets.NewControlPacket(packets.Pubrel).(*packets.PubrelPacket) prel.MessageID = prec.MessageID if !sendServer(c, prel, nil) { return } case *packets.PubrelPacket: pr := msg.(*packets.PubrelPacket) DEBUG.Println(NET, "received pubrel, id:", pr.MessageID) pc := packets.NewControlPacket(packets.Pubcomp).(*packets.PubcompPacket) pc.MessageID = pr.MessageID if !sendServer(c, pc, nil) { return } case *packets.PubcompPacket: pc := msg.(*packets.PubcompPacket) DEBUG.Println(NET, "received pubcomp, id:", pc.MessageID) c.getToken(pc.MessageID).flowComplete() c.freeID(pc.MessageID) } case <-c.stop: WARN.Println(NET, c.options.ClientID+":logic stopped") return } } }
func Test_FileStore_Reset(t *testing.T) { storedir := "/tmp/TestStore/_reset" f := NewFileStore(storedir) f.Open() pm1 := packets.NewControlPacket(packets.Publish).(*packets.PublishPacket) pm1.Qos = 1 pm1.TopicName = "/q/w/e" pm1.Payload = []byte{0xBB} pm1.MessageID = 71 key1 := inboundKeyFromMID(pm1.MessageID) f.Put(key1, pm1) pm2 := packets.NewControlPacket(packets.Publish).(*packets.PublishPacket) pm2.Qos = 1 pm2.TopicName = "/q/w/e" pm2.Payload = []byte{0xBB} pm2.MessageID = 72 key2 := inboundKeyFromMID(pm2.MessageID) f.Put(key2, pm2) pm3 := packets.NewControlPacket(packets.Publish).(*packets.PublishPacket) pm3.Qos = 1 pm3.TopicName = "/q/w/e" pm3.Payload = []byte{0xBB} pm3.MessageID = 73 key3 := inboundKeyFromMID(pm3.MessageID) f.Put(key3, pm3) pm4 := packets.NewControlPacket(packets.Publish).(*packets.PublishPacket) pm4.Qos = 1 pm4.TopicName = "/q/w/e" pm4.Payload = []byte{0xBB} pm4.MessageID = 74 key4 := inboundKeyFromMID(pm4.MessageID) f.Put(key4, pm4) pm5 := packets.NewControlPacket(packets.Publish).(*packets.PublishPacket) pm5.Qos = 1 pm5.TopicName = "/q/w/e" pm5.Payload = []byte{0xBB} pm5.MessageID = 75 key5 := inboundKeyFromMID(pm5.MessageID) f.Put(key5, pm5) if !exists(storedir + "/i.71.msg") { t.Fatalf("message not in store") } if !exists(storedir + "/i.72.msg") { t.Fatalf("message not in store") } if !exists(storedir + "/i.73.msg") { t.Fatalf("message not in store") } if !exists(storedir + "/i.74.msg") { t.Fatalf("message not in store") } if !exists(storedir + "/i.75.msg") { t.Fatalf("message not in store") } f.Reset() if exists(storedir + "/i.71.msg") { t.Fatalf("message still exists after reset") } if exists(storedir + "/i.72.msg") { t.Fatalf("message still exists after reset") } if exists(storedir + "/i.73.msg") { t.Fatalf("message still exists after reset") } if exists(storedir + "/i.74.msg") { t.Fatalf("message still exists after reset") } if exists(storedir + "/i.75.msg") { t.Fatalf("message still exists after reset") } }