snac_cache_test.go 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. package toc
  2. import (
  3. "testing"
  4. "time"
  5. "github.com/stretchr/testify/assert"
  6. "github.com/mk6i/open-oscar-server/wire"
  7. )
  8. func TestSNACCache_addAndTake(t *testing.T) {
  9. c := newSNACCache()
  10. first := wire.SNACFrame{FoodGroup: wire.Locate, SubGroup: wire.LocateUserInfoQuery}
  11. c.add(&first, getStatusReqCtx{screenName: "them"})
  12. second := wire.SNACFrame{FoodGroup: wire.ICBM, SubGroup: wire.ICBMEvilRequest}
  13. c.add(&second, evilReqCtx{})
  14. assert.Equal(t, uint32(1), first.RequestID)
  15. assert.Equal(t, uint32(2), second.RequestID)
  16. req, ok := c.take(wire.SNACFrame{FoodGroup: wire.Locate, SubGroup: wire.LocateUserInfoReply, RequestID: 1})
  17. assert.True(t, ok)
  18. assert.Equal(t, first, req.frame)
  19. assert.Equal(t, getStatusReqCtx{screenName: "them"}, req.data)
  20. // an entry is removed once taken
  21. _, ok = c.take(wire.SNACFrame{FoodGroup: wire.Locate, RequestID: 1})
  22. assert.False(t, ok)
  23. req, ok = c.take(wire.SNACFrame{FoodGroup: wire.ICBM, SubGroup: wire.ICBMErr, RequestID: 2})
  24. assert.True(t, ok)
  25. assert.Equal(t, evilReqCtx{}, req.data)
  26. }
  27. func TestSNACCache_takeRequiresMatchingFoodGroup(t *testing.T) {
  28. c := newSNACCache()
  29. frame := wire.SNACFrame{FoodGroup: wire.Locate, SubGroup: wire.LocateUserInfoQuery}
  30. c.add(&frame, getStatusReqCtx{screenName: "them"})
  31. // a relayed SNAC that happens to carry the same request ID is not a reply
  32. _, ok := c.take(wire.SNACFrame{FoodGroup: wire.ICBM, SubGroup: wire.ICBMClientEvent, RequestID: 1})
  33. assert.False(t, ok)
  34. // the real reply still finds the request
  35. _, ok = c.take(wire.SNACFrame{FoodGroup: wire.Locate, SubGroup: wire.LocateUserInfoReply, RequestID: 1})
  36. assert.True(t, ok)
  37. }
  38. func TestSNACCache_remove(t *testing.T) {
  39. c := newSNACCache()
  40. frame := wire.SNACFrame{FoodGroup: wire.Locate, SubGroup: wire.LocateUserInfoQuery}
  41. c.add(&frame, nil)
  42. c.remove(frame.RequestID)
  43. _, ok := c.take(wire.SNACFrame{FoodGroup: wire.Locate, RequestID: frame.RequestID})
  44. assert.False(t, ok)
  45. }
  46. func TestSNACCache_sweepsExpiredEntries(t *testing.T) {
  47. now := time.Now()
  48. c := newSNACCache()
  49. c.timeNow = func() time.Time { return now }
  50. old := wire.SNACFrame{FoodGroup: wire.ICBM, SubGroup: wire.ICBMChannelMsgToHost}
  51. c.add(&old, nil)
  52. now = now.Add(snacCacheTTL + time.Second)
  53. fresh := wire.SNACFrame{FoodGroup: wire.ICBM, SubGroup: wire.ICBMChannelMsgToHost}
  54. c.add(&fresh, nil)
  55. _, ok := c.take(wire.SNACFrame{FoodGroup: wire.ICBM, RequestID: old.RequestID})
  56. assert.False(t, ok)
  57. _, ok = c.take(wire.SNACFrame{FoodGroup: wire.ICBM, RequestID: fresh.RequestID})
  58. assert.True(t, ok)
  59. }
  60. func TestSNACCache_requestIDWrapsBeforeServerRange(t *testing.T) {
  61. c := newSNACCache()
  62. c.lastID = wire.ReqIDFromServer - 1
  63. frame := wire.SNACFrame{FoodGroup: wire.ICBM}
  64. c.add(&frame, nil)
  65. assert.Equal(t, uint32(1), frame.RequestID)
  66. }