github.com/la5nta/wl2k-go@v0.11.8/tests/session_test.go (about) 1 package tests 2 3 import ( 4 "io/ioutil" 5 "math/rand" 6 "os" 7 "testing" 8 "time" 9 10 "github.com/la5nta/wl2k-go/fbb" 11 "github.com/la5nta/wl2k-go/mailbox" 12 "github.com/la5nta/wl2k-go/transport/telnet" 13 ) 14 15 type Station struct { 16 Callsign string 17 MBox *mailbox.DirHandler 18 path string 19 } 20 21 func (s *Station) Cleanup() { 22 os.Remove(s.path) 23 } 24 25 func (s *Station) ListenTelnet() (string, <-chan error, error) { 26 errors := make(chan error, 10) 27 28 ln, err := telnet.Listen("localhost:0") 29 if err != nil { 30 return "", nil, err 31 } 32 33 go func() { 34 defer ln.Close() 35 conn, err := ln.Accept() 36 if err != nil { 37 errors <- err 38 return 39 } 40 defer conn.Close() 41 42 conn.SetDeadline(time.Now().Add(time.Minute)) 43 s := fbb.NewSession(s.Callsign, conn.(*telnet.Conn).RemoteCall(), "", s.MBox) 44 s.IsMaster(true) 45 if _, err := s.Exchange(conn); err != nil { 46 errors <- err 47 return 48 } 49 close(errors) 50 }() 51 52 return ln.Addr().String(), errors, nil 53 } 54 55 func NewTempStation(callsign string) (*Station, error) { 56 path, err := ioutil.TempDir("", callsign) 57 if err != nil { 58 return nil, err 59 } 60 61 mbox := mailbox.NewDirHandler(path, false) 62 mbox.Prepare() 63 64 return &Station{ 65 Callsign: callsign, 66 MBox: mbox, 67 path: path, 68 }, nil 69 } 70 71 func TestMultiBlockAllDeferred(t *testing.T) { 72 alice, _ := NewTempStation("N0DE1") 73 defer alice.Cleanup() 74 75 bob, _ := NewTempStation("N0DE2") 76 defer bob.Cleanup() 77 78 // Add 6 outbound messages 79 msgs := NewRandomMessages(6, alice.Callsign, bob.Callsign) 80 for _, msg := range msgs { 81 alice.MBox.AddOut(msg) 82 } 83 84 // Fake msgs already delivered 85 bob.MBox.ProcessInbound(msgs...) 86 87 // Start alice as telnet listener 88 addr, errors, err := alice.ListenTelnet() 89 if err != nil { 90 t.Fatalf("Unable to start listener: %s", err) 91 } 92 93 // Connect to alice from bob via telnet 94 conn, err := telnet.Dial(addr, bob.Callsign, "") 95 if err != nil { 96 t.Fatalf("Unable to connect to listener: %s", err) 97 } 98 defer conn.Close() 99 100 conn.SetDeadline(time.Now().Add(time.Minute)) 101 s := fbb.NewSession(bob.Callsign, bob.Callsign, "", bob.MBox) 102 if _, err := s.Exchange(conn); err != nil { 103 t.Fatalf("Exchange failed at connecting node: %s", err) 104 } 105 106 select { 107 case err, ok := <-errors: 108 if !ok { 109 break // No error occurred 110 } 111 t.Fatalf("Exchange failed at listening node: %s", err) 112 case <-time.After(time.Minute): 113 t.Fatalf("Test timeout!") 114 } 115 116 if alice.MBox.OutboxCount() != 0 { 117 t.Errorf("Unexpected QTC in %s's mailbox. Expected 0.", alice.Callsign) 118 } 119 } 120 121 func NewRandomMessages(n int, from, to string) []*fbb.Message { 122 msgs := make([]*fbb.Message, n) 123 for i := 0; i < n; i++ { 124 msgs[i] = NewRandomMessage(from, to) 125 } 126 return msgs 127 } 128 129 func NewRandomMessage(from, to string) *fbb.Message { 130 msg := fbb.NewMessage(fbb.Private, from) 131 132 msg.AddTo(to) 133 msg.SetSubject(RandStringRunes(10)) 134 msg.SetBody(RandStringRunes(100)) 135 136 return msg 137 } 138 139 func init() { 140 rand.Seed(time.Now().UnixNano()) 141 } 142 143 var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") 144 145 func RandStringRunes(n int) string { 146 b := make([]rune, n) 147 for i := range b { 148 b[i] = letterRunes[rand.Intn(len(letterRunes))] 149 } 150 return string(b) 151 }