1
0
mirror of https://github.com/jhillyerd/inbucket.git synced 2025-12-18 10:07:02 +00:00
Files
go-inbucket/smtpd/handler_test.go
2013-10-29 13:58:21 -07:00

134 lines
2.9 KiB
Go

package smtpd
import (
"github.com/jhillyerd/inbucket/config"
"io/ioutil"
"net"
"net/textproto"
"os"
"testing"
"time"
)
type scriptStep struct {
send string
expect int
}
func TestHelo(t *testing.T) {
server := setupSmtpServer()
defer teardownSmtpServer(server)
// Test out some manged HELOs
playSession(t, server, []scriptStep{
{"HELLO", 500},
})
playSession(t, server, []scriptStep{
{"HELL", 500},
})
playSession(t, server, []scriptStep{
{"hello", 500},
})
// Valid HELOs
playSession(t, server, []scriptStep{
{"HELO", 250},
})
playSession(t, server, []scriptStep{
{"HELO mydomain", 250},
})
playSession(t, server, []scriptStep{
{"HELO mydom.com", 250},
})
playSession(t, server, []scriptStep{
{"HelO mydom.com", 250},
})
}
// playSession creates a new session, reads the greeting and then plays the script
func playSession(t *testing.T, server *Server, script []scriptStep) {
pipe := setupSmtpSession(server)
c := textproto.NewConn(pipe)
if code, _, err := c.ReadCodeLine(220); err != nil {
t.Fatalf("Expected a 220 greeting, got %v", code)
return
}
playScriptAgainst(t, c, script)
c.Cmd("QUIT")
c.ReadCodeLine(221)
}
// playScriptAgainst an existing connection, does not handle server greeting
func playScriptAgainst(t *testing.T, c *textproto.Conn, script []scriptStep) {
for i, step := range script {
id, err := c.Cmd(step.send)
if err != nil {
t.Fatalf("Step %d, failed to send %q: %v", i, step.send, err)
return
}
c.StartResponse(id)
if code, msg, err := c.ReadCodeLine(step.expect); err != nil {
t.Errorf("Step %d, sent %q, expected %v, got %v: %q",
i, step.send, step.expect, code, msg)
}
defer c.EndResponse(id)
}
}
// net.Pipe does not implement deadlines
type mockConn struct {
net.Conn
}
func (m *mockConn) SetDeadline(t time.Time) error { return nil }
func (m *mockConn) SetReadDeadline(t time.Time) error { return nil }
func (m *mockConn) SetWriteDeadline(t time.Time) error { return nil }
func setupSmtpServer() *Server {
// Setup datastore
path, err := ioutil.TempDir("", "inbucket")
if err != nil {
panic(err)
}
ds := NewFileDataStore(path)
// Test Server Config
cfg := config.SmtpConfig{
Ip4address: net.IPv4(127, 0, 0, 1),
Ip4port: 2500,
Domain: "inbucket.local",
DomainNoStore: "bitbucket.local",
MaxRecipients: 5,
MaxIdleSeconds: 5,
MaxMessageBytes: 5000,
StoreMessages: true,
}
// Create a server, don't start it
return NewSmtpServer(cfg, ds)
}
var sessionNum int
func setupSmtpSession(server *Server) net.Conn {
// Pair of pipes to communicate
serverConn, clientConn := net.Pipe()
// Start the session
server.waitgroup.Add(1)
sessionNum++
go server.startSession(sessionNum, &mockConn{serverConn})
return clientConn
}
func teardownSmtpServer(server *Server) {
ds := server.dataStore.(*FileDataStore)
if err := os.RemoveAll(ds.path); err != nil {
panic(err)
}
}