Bläddra i källkod

add a fuzz test for IRCStreamConn changes

tags/v2.5.0-rc1
Shivaram Lingamneni 3 år sedan
förälder
incheckning
a34918e729
1 ändrade filer med 135 tillägg och 0 borttagningar
  1. 135
    0
      irc/ircconn_test.go

+ 135
- 0
irc/ircconn_test.go Visa fil

@@ -0,0 +1,135 @@
1
+// Copyright (c) 2020 Shivaram Lingamneni <slingamn@cs.stanford.edu>
2
+// released under the MIT license
3
+
4
+package irc
5
+
6
+import (
7
+	"io"
8
+	"math/rand"
9
+	"net"
10
+	"reflect"
11
+	"testing"
12
+	"time"
13
+
14
+	"github.com/oragono/oragono/irc/utils"
15
+)
16
+
17
+// mockConn is a fake net.Conn / io.Reader that yields len(counts) lines,
18
+// each consisting of counts[i] 'a' characters and a terminating '\n'
19
+type mockConn struct {
20
+	counts []int
21
+}
22
+
23
+func min(i, j int) (m int) {
24
+	if i < j {
25
+		return i
26
+	} else {
27
+		return j
28
+	}
29
+}
30
+
31
+func (c *mockConn) Read(b []byte) (n int, err error) {
32
+	for len(b) > 0 {
33
+		if len(c.counts) == 0 {
34
+			return n, io.EOF
35
+		}
36
+		if c.counts[0] == 0 {
37
+			b[0] = '\n'
38
+			c.counts = c.counts[1:]
39
+			b = b[1:]
40
+			n += 1
41
+			continue
42
+		}
43
+		size := min(c.counts[0], len(b))
44
+		for i := 0; i < size; i++ {
45
+			b[i] = 'a'
46
+		}
47
+		c.counts[0] -= size
48
+		b = b[size:]
49
+		n += size
50
+	}
51
+	return n, nil
52
+}
53
+
54
+func (c *mockConn) Write(b []byte) (n int, err error) {
55
+	return
56
+}
57
+
58
+func (c *mockConn) Close() error {
59
+	c.counts = nil
60
+	return nil
61
+}
62
+
63
+func (c *mockConn) LocalAddr() net.Addr {
64
+	return nil
65
+}
66
+
67
+func (c *mockConn) RemoteAddr() net.Addr {
68
+	return nil
69
+}
70
+
71
+func (c *mockConn) SetDeadline(t time.Time) error {
72
+	return nil
73
+}
74
+
75
+func (c *mockConn) SetReadDeadline(t time.Time) error {
76
+	return nil
77
+}
78
+
79
+func (c *mockConn) SetWriteDeadline(t time.Time) error {
80
+	return nil
81
+}
82
+
83
+func newMockConn(counts []int) *utils.WrappedConn {
84
+	cpCounts := make([]int, len(counts))
85
+	copy(cpCounts, counts)
86
+	c := &mockConn{
87
+		counts: cpCounts,
88
+	}
89
+	return &utils.WrappedConn{
90
+		Conn: c,
91
+	}
92
+}
93
+
94
+// construct a mock reader with some number of \n-terminated lines,
95
+// verify that IRCStreamConn can read and split them as expected
96
+func doLineReaderTest(counts []int, t *testing.T) {
97
+	c := newMockConn(counts)
98
+	r := NewIRCStreamConn(c)
99
+	var readCounts []int
100
+	for {
101
+		line, err := r.ReadLine()
102
+		if err == nil {
103
+			readCounts = append(readCounts, len(line))
104
+		} else if err == io.EOF {
105
+			break
106
+		} else {
107
+			panic(err)
108
+		}
109
+	}
110
+
111
+	if !reflect.DeepEqual(counts, readCounts) {
112
+		t.Errorf("expected %#v, got %#v", counts, readCounts)
113
+	}
114
+}
115
+
116
+const (
117
+	maxMockReaderLen     = 100
118
+	maxMockReaderLineLen = 4096 + 511
119
+)
120
+
121
+func TestLineReader(t *testing.T) {
122
+	counts := []int{44, 428, 3, 0, 200, 2000, 0, 4044, 33, 3, 2, 1, 0, 1, 2, 3, 48, 555}
123
+	doLineReaderTest(counts, t)
124
+
125
+	// fuzz
126
+	r := rand.New(rand.NewSource(time.Now().UnixNano()))
127
+	for i := 0; i < 1000; i++ {
128
+		countsLen := r.Intn(maxMockReaderLen) + 1
129
+		counts := make([]int, countsLen)
130
+		for i := 0; i < countsLen; i++ {
131
+			counts[i] = r.Intn(maxMockReaderLineLen)
132
+		}
133
+		doLineReaderTest(counts, t)
134
+	}
135
+}

Laddar…
Avbryt
Spara