123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- // Copyright (c) 2020 Shivaram Lingamneni <slingamn@cs.stanford.edu>
- // released under the MIT license
-
- package irc
-
- import (
- "io"
- "math/rand"
- "net"
- "reflect"
- "testing"
- "time"
-
- "github.com/oragono/oragono/irc/utils"
- )
-
- // mockConn is a fake net.Conn / io.Reader that yields len(counts) lines,
- // each consisting of counts[i] 'a' characters and a terminating '\n'
- type mockConn struct {
- counts []int
- }
-
- func min(i, j int) (m int) {
- if i < j {
- return i
- } else {
- return j
- }
- }
-
- func (c *mockConn) Read(b []byte) (n int, err error) {
- for len(b) > 0 {
- if len(c.counts) == 0 {
- return n, io.EOF
- }
- if c.counts[0] == 0 {
- b[0] = '\n'
- c.counts = c.counts[1:]
- b = b[1:]
- n += 1
- continue
- }
- size := min(c.counts[0], len(b))
- for i := 0; i < size; i++ {
- b[i] = 'a'
- }
- c.counts[0] -= size
- b = b[size:]
- n += size
- }
- return n, nil
- }
-
- func (c *mockConn) Write(b []byte) (n int, err error) {
- return
- }
-
- func (c *mockConn) Close() error {
- c.counts = nil
- return nil
- }
-
- func (c *mockConn) LocalAddr() net.Addr {
- return nil
- }
-
- func (c *mockConn) RemoteAddr() net.Addr {
- return nil
- }
-
- func (c *mockConn) SetDeadline(t time.Time) error {
- return nil
- }
-
- func (c *mockConn) SetReadDeadline(t time.Time) error {
- return nil
- }
-
- func (c *mockConn) SetWriteDeadline(t time.Time) error {
- return nil
- }
-
- func newMockConn(counts []int) *utils.WrappedConn {
- cpCounts := make([]int, len(counts))
- copy(cpCounts, counts)
- c := &mockConn{
- counts: cpCounts,
- }
- return &utils.WrappedConn{
- Conn: c,
- }
- }
-
- // construct a mock reader with some number of \n-terminated lines,
- // verify that IRCStreamConn can read and split them as expected
- func doLineReaderTest(counts []int, t *testing.T) {
- c := newMockConn(counts)
- r := NewIRCStreamConn(c)
- var readCounts []int
- for {
- line, err := r.ReadLine()
- if err == nil {
- readCounts = append(readCounts, len(line))
- } else if err == io.EOF {
- break
- } else {
- panic(err)
- }
- }
-
- if !reflect.DeepEqual(counts, readCounts) {
- t.Errorf("expected %#v, got %#v", counts, readCounts)
- }
- }
-
- const (
- maxMockReaderLen = 100
- maxMockReaderLineLen = 4096 + 511
- )
-
- func TestLineReader(t *testing.T) {
- counts := []int{44, 428, 3, 0, 200, 2000, 0, 4044, 33, 3, 2, 1, 0, 1, 2, 3, 48, 555}
- doLineReaderTest(counts, t)
-
- // fuzz
- r := rand.New(rand.NewSource(time.Now().UnixNano()))
- for i := 0; i < 1000; i++ {
- countsLen := r.Intn(maxMockReaderLen) + 1
- counts := make([]int, countsLen)
- for i := 0; i < countsLen; i++ {
- counts[i] = r.Intn(maxMockReaderLineLen)
- }
- doLineReaderTest(counts, t)
- }
- }
|