]>
src.bluestatic.org Git - mailpopbox.git/blob - pop3/conn_test.go
06c68bfa73c95cf566cbb9a05b8733f775358a45
14 func _fl(depth
int) string {
15 _
, file
, line
, _
:= runtime
.Caller(depth
+ 1)
16 return fmt
.Sprintf("[%s:%d]", filepath
.Base(file
), line
)
19 func ok(t testing
.TB
, err error
) {
21 t
.Errorf("%s unexpected error: %v", _fl(1), err
)
25 func responseOK(t testing
.TB
, conn
*textproto
.Conn
) string {
26 line
, err
:= conn
.ReadLine()
28 t
.Errorf("%s responseOK: %v", _fl(1), err
)
30 if !strings
.HasPrefix(line
, "+OK") {
31 t
.Errorf("%s expected +OK, got %q", _fl(1), line
)
36 func responseERR(t testing
.TB
, conn
*textproto
.Conn
) string {
37 line
, err
:= conn
.ReadLine()
39 t
.Errorf("%s responseERR: %v", _fl(1), err
)
41 if !strings
.HasPrefix(line
, "-ERR") {
42 t
.Errorf("%s expected -ERR, got %q", _fl(1), line
)
47 func runServer(t
*testing
.T
, po PostOffice
) net
.Listener
{
48 l
, err
:= net
.Listen("tcp", "localhost:0")
56 conn
, err
:= l
.Accept()
60 go AcceptConnection(conn
, po
)
66 type testServer
struct {
71 func (s
*testServer
) Name() string {
75 func (s
*testServer
) OpenMailbox(user
, pass
string) (Mailbox
, error
) {
76 if s
.user
== user
&& s
.pass
== pass
{
79 return nil, fmt
.Errorf("bad username/pass")
82 type testMailbox
struct {
83 msgs
map[int]*testMessage
86 func (mb
*testMailbox
) ListMessages() ([]Message
, error
) {
87 msgs
:= make([]Message
, 0, len(mb
.msgs
))
88 for i
, _
:= range mb
.msgs
{
89 msgs
= append(msgs
, mb
.msgs
[i
])
94 func (mb
*testMailbox
) GetMessage(id
int) Message
{
98 func (mb
*testMailbox
) Retrieve(msg Message
) (io
.ReadCloser
, error
) {
102 func (mb
*testMailbox
) Delete(msg Message
) error
{
103 msg
.(*testMessage
).deleted
= true
107 func (mb
*testMailbox
) Close() error
{
111 func (mb
*testMailbox
) Reset() {
112 for _
, msg
:= range mb
.msgs
{
117 type testMessage
struct {
123 func (m
*testMessage
) ID() int {
126 func (m
*testMessage
) Size() int {
129 func (m
*testMessage
) Deleted() bool {
133 func newTestServer() *testServer
{
138 msgs
: make(map[int]*testMessage
),
144 func TestExampleSession(t
*testing
.T
) {
149 s
.mb
.msgs
[1] = &testMessage
{1, 120, false}
150 s
.mb
.msgs
[2] = &testMessage
{2, 200, false}
152 conn
, err
:= textproto
.Dial(l
.Addr().Network(), l
.Addr().String())
155 line
:= responseOK(t
, conn
)
156 if !strings
.Contains(line
, s
.Name()) {
157 t
.Errorf("POP greeting did not include server name, got %q", line
)
160 ok(t
, conn
.PrintfLine("USER u"))
163 ok(t
, conn
.PrintfLine("PASS p"))
166 ok(t
, conn
.PrintfLine("STAT"))
167 line
= responseOK(t
, conn
)
168 expected
:= "+OK 2 320"
169 if line
!= expected
{
170 t
.Errorf("STAT expected %q, got %q", expected
, line
)
173 ok(t
, conn
.PrintfLine("LIST"))
175 lines
, err
:= conn
.ReadDotLines()
178 t
.Errorf("LIST expected 2 lines, got %d", len(lines
))
181 if lines
[0] != expected
{
182 t
.Errorf("LIST line 0 expected %q, got %q", expected
, lines
[0])
185 if lines
[1] != expected
{
186 t
.Errorf("LIST line 1 expected %q, got %q", expected
, lines
[1])
189 ok(t
, conn
.PrintfLine("QUIT"))
193 type requestResponse
struct {
195 expecter
func(testing
.TB
, *textproto
.Conn
) string
198 func expectOKResponse(predicate
func(string) bool) func(testing
.TB
, *textproto
.Conn
) string {
199 return func(t testing
.TB
, conn
*textproto
.Conn
) string {
200 line
:= responseOK(t
, conn
)
201 if !predicate(line
) {
202 t
.Errorf("%s Predicate failed, got %q", _fl(1), line
)
208 func clientServerTest(t
*testing
.T
, s
*testServer
, sequence
[]requestResponse
) {
212 conn
, err
:= textproto
.Dial(l
.Addr().Network(), l
.Addr().String())
217 for _
, pair
:= range sequence
{
218 ok(t
, conn
.PrintfLine(pair
.command
))
219 pair
.expecter(t
, conn
)
221 t
.Logf("command %q", pair
.command
)
226 func TestAuthStates(t
*testing
.T
) {
227 clientServerTest(t
, newTestServer(), []requestResponse
{
228 {"STAT", responseERR
},
229 {"NOOP", responseOK
},
230 {"USER bad", responseOK
},
231 {"PASS bad", responseERR
},
232 {"LIST", responseERR
},
233 {"USER u", responseOK
},
234 {"PASS bad", responseERR
},
235 {"STAT", responseERR
},
236 {"PASS p", responseOK
},
237 {"QUIT", responseOK
},
241 func TestDeleted(t
*testing
.T
) {
243 s
.mb
.msgs
[1] = &testMessage
{1, 999, false}
244 s
.mb
.msgs
[2] = &testMessage
{2, 10, false}
246 clientServerTest(t
, s
, []requestResponse
{
247 {"USER u", responseOK
},
248 {"PASS p", responseOK
},
249 {"STAT", expectOKResponse(func(s
string) bool {
250 return s
== "+OK 2 1009"
252 {"DELE 1", responseOK
},
253 {"RETR 1", responseERR
},
254 {"DELE 1", responseERR
},
255 {"STAT", expectOKResponse(func(s
string) bool {
256 return s
== "+OK 1 10"
258 {"RSET", responseOK
},
259 {"STAT", expectOKResponse(func(s
string) bool {
260 return s
== "+OK 2 1009"
262 {"QUIT", responseOK
},