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 readCodeLine(t testing.TB, conn *textproto.Conn, code int) string {
26 _, message, err := conn.ReadCodeLine(code)
28 t.Errorf("%s ReadCodeLine error: %v", _fl(1), err)
33 // runServer creates a TCP socket, runs a listening server, and returns the connection.
34 // The server exits when the Conn is closed.
35 func runServer(t *testing.T, server Server) net.Listener {
36 l, err := net.Listen("tcp", "localhost:0")
44 conn, err := l.Accept()
48 go AcceptConnection(conn, server)
55 type testServer struct {
60 func (s *testServer) Name() string {
64 func (s *testServer) VerifyAddress(addr mail.Address) ReplyLine {
65 for _, block := range s.blockList {
66 if block == addr.Address {
67 return ReplyBadMailbox
73 func createClient(t *testing.T, addr net.Addr) *textproto.Conn {
74 conn, err := textproto.Dial(addr.Network(), addr.String())
83 func TestScenarioTypical(t *testing.T) {
85 blockList: []string{"Green@foo.com"},
90 conn := createClient(t, l.Addr())
92 message := readCodeLine(t, conn, 220)
93 if !strings.HasPrefix(message, s.Name()) {
94 t.Errorf("Greeting does not have server name, got %q", message)
97 greet := "greeting.TestScenarioTypical"
98 ok(t, conn.PrintfLine("EHLO "+greet))
100 _, message, err := conn.ReadResponse(250)
102 if !strings.Contains(message, greet) {
103 t.Errorf("EHLO response does not contain greeting, got %q", message)
106 ok(t, conn.PrintfLine("MAIL FROM:<Smith@bar.com>"))
107 readCodeLine(t, conn, 250)
109 ok(t, conn.PrintfLine("RCPT TO:<Jones@foo.com>"))
110 readCodeLine(t, conn, 250)
112 ok(t, conn.PrintfLine("RCPT TO:<Green@foo.com>"))
113 readCodeLine(t, conn, 550)
115 ok(t, conn.PrintfLine("RCPT TO:<Brown@foo.com>"))
116 readCodeLine(t, conn, 250)
118 ok(t, conn.PrintfLine("DATA"))
119 readCodeLine(t, conn, 354)
121 ok(t, conn.PrintfLine("Blah blah blah..."))
122 ok(t, conn.PrintfLine("...etc. etc. etc."))
123 ok(t, conn.PrintfLine("."))
124 readCodeLine(t, conn, 250)
126 ok(t, conn.PrintfLine("QUIT"))
127 readCodeLine(t, conn, 221)