2001-09-25 23:35:17 +02:00
|
|
|
local sent = {}
|
|
|
|
|
2003-03-20 01:24:44 +01:00
|
|
|
local from = "diego@localhost"
|
|
|
|
local server = "localhost"
|
|
|
|
local rcpt = "luasocket@localhost"
|
|
|
|
|
|
|
|
local files = {
|
|
|
|
"/var/spool/mail/luasocket",
|
|
|
|
"/var/spool/mail/luasock1",
|
|
|
|
"/var/spool/mail/luasock2",
|
|
|
|
"/var/spool/mail/luasock3",
|
|
|
|
}
|
2001-09-25 23:35:17 +02:00
|
|
|
|
2003-05-25 03:54:13 +02:00
|
|
|
local t = socket.time()
|
2001-09-25 23:35:17 +02:00
|
|
|
local err
|
|
|
|
|
2003-03-20 01:24:44 +01:00
|
|
|
dofile("mbox.lua")
|
|
|
|
local parse = mbox.parse
|
2004-03-22 05:15:03 +01:00
|
|
|
dofile("testsupport.lua")
|
2001-09-25 23:35:17 +02:00
|
|
|
|
|
|
|
local total = function()
|
|
|
|
local t = 0
|
2003-03-20 01:24:44 +01:00
|
|
|
for i = 1, table.getn(sent) do
|
|
|
|
t = t + sent[i].count
|
2001-09-25 23:35:17 +02:00
|
|
|
end
|
|
|
|
return t
|
|
|
|
end
|
|
|
|
|
|
|
|
local similar = function(s1, s2)
|
2003-03-20 01:24:44 +01:00
|
|
|
return
|
|
|
|
string.lower(string.gsub(s1, "%s", "")) ==
|
|
|
|
string.lower(string.gsub(s2, "%s", ""))
|
2001-09-25 23:35:17 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
local fail = function(s)
|
|
|
|
s = s or "failed!"
|
|
|
|
print(s)
|
2003-03-20 01:24:44 +01:00
|
|
|
os.exit()
|
2001-09-25 23:35:17 +02:00
|
|
|
end
|
|
|
|
|
2003-03-20 01:24:44 +01:00
|
|
|
local readfile = function(name)
|
|
|
|
local f = io.open(name, "r")
|
|
|
|
if not f then
|
|
|
|
fail("unable to open file!")
|
|
|
|
return nil
|
|
|
|
end
|
|
|
|
local s = f:read("*a")
|
|
|
|
f:close()
|
|
|
|
return s
|
2001-09-25 23:35:17 +02:00
|
|
|
end
|
|
|
|
|
2003-03-20 01:24:44 +01:00
|
|
|
local empty = function()
|
|
|
|
for i,v in ipairs(files) do
|
|
|
|
local f = io.open(v, "w")
|
|
|
|
if not f then
|
|
|
|
fail("unable to open file!")
|
|
|
|
end
|
|
|
|
f:close()
|
|
|
|
end
|
2001-09-25 23:35:17 +02:00
|
|
|
end
|
|
|
|
|
2003-03-20 01:24:44 +01:00
|
|
|
local get = function()
|
2003-03-28 22:08:50 +01:00
|
|
|
local s = ""
|
2003-03-20 01:24:44 +01:00
|
|
|
for i,v in ipairs(files) do
|
|
|
|
s = s .. "\n" .. readfile(v)
|
|
|
|
end
|
|
|
|
return s
|
2001-09-25 23:35:17 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
local check_headers = function(sent, got)
|
|
|
|
sent = sent or {}
|
|
|
|
got = got or {}
|
|
|
|
for i,v in sent do
|
2003-03-20 01:24:44 +01:00
|
|
|
if not similar(v, got[i]) then fail("header " .. v .. "failed!") end
|
2001-09-25 23:35:17 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
local check_body = function(sent, got)
|
|
|
|
sent = sent or ""
|
|
|
|
got = got or ""
|
2003-03-20 01:24:44 +01:00
|
|
|
if not similar(sent, got) then fail("bodies differ!") end
|
2001-09-25 23:35:17 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
local check = function(sent, m)
|
2003-03-20 01:24:44 +01:00
|
|
|
io.write("checking ", m.headers.title, ": ")
|
|
|
|
for i = 1, table.getn(sent) do
|
2001-09-25 23:35:17 +02:00
|
|
|
local s = sent[i]
|
|
|
|
if s.title == m.headers.title and s.count > 0 then
|
2003-03-20 01:24:44 +01:00
|
|
|
check_headers(s.headers, m.headers)
|
|
|
|
check_body(s.body, m.body)
|
2001-09-25 23:35:17 +02:00
|
|
|
s.count = s.count - 1
|
|
|
|
print("ok")
|
|
|
|
return
|
|
|
|
end
|
|
|
|
end
|
2003-03-20 01:24:44 +01:00
|
|
|
fail("not found")
|
2001-09-25 23:35:17 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
local insert = function(sent, message)
|
|
|
|
if type(message.rcpt) == "table" then
|
2003-03-20 01:24:44 +01:00
|
|
|
message.count = table.getn(message.rcpt)
|
2001-09-25 23:35:17 +02:00
|
|
|
else message.count = 1 end
|
|
|
|
message.headers = message.headers or {}
|
|
|
|
message.headers.title = message.title
|
2003-03-20 01:24:44 +01:00
|
|
|
table.insert(sent, message)
|
2001-09-25 23:35:17 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
local mark = function()
|
2003-05-25 03:54:13 +02:00
|
|
|
local time = socket.time()
|
2001-09-25 23:35:17 +02:00
|
|
|
return { time = time }
|
|
|
|
end
|
|
|
|
|
|
|
|
local wait = function(sentinel, n)
|
|
|
|
local to
|
2003-03-20 01:24:44 +01:00
|
|
|
io.write("waiting for ", n, " messages: ")
|
2001-09-25 23:35:17 +02:00
|
|
|
while 1 do
|
2003-03-20 01:24:44 +01:00
|
|
|
local mbox = parse(get())
|
|
|
|
if n == table.getn(mbox) then break end
|
2003-05-25 03:54:13 +02:00
|
|
|
if socket.time() - sentinel.time > 50 then
|
2001-09-25 23:35:17 +02:00
|
|
|
to = 1
|
|
|
|
break
|
|
|
|
end
|
2003-05-25 03:54:13 +02:00
|
|
|
socket.sleep(1)
|
2003-03-20 01:24:44 +01:00
|
|
|
io.write(".")
|
|
|
|
io.stdout:flush()
|
2001-09-25 23:35:17 +02:00
|
|
|
end
|
2003-03-20 01:24:44 +01:00
|
|
|
if to then fail("timeout")
|
2001-09-25 23:35:17 +02:00
|
|
|
else print("ok") end
|
|
|
|
end
|
|
|
|
|
|
|
|
local stuffed_body = [[
|
|
|
|
This message body needs to be
|
|
|
|
stuffed because it has a dot
|
|
|
|
.
|
|
|
|
by itself on a line.
|
|
|
|
Otherwise the mailer would
|
|
|
|
think that the dot
|
|
|
|
.
|
|
|
|
is the end of the message
|
2003-03-20 01:24:44 +01:00
|
|
|
and the remaining text would cause
|
2001-09-25 23:35:17 +02:00
|
|
|
a lot of trouble.
|
|
|
|
]]
|
|
|
|
|
|
|
|
insert(sent, {
|
|
|
|
from = from,
|
|
|
|
rcpt = {
|
2003-03-20 01:24:44 +01:00
|
|
|
"luasocket@localhost",
|
|
|
|
"luasock3@dell-diego.cs.princeton.edu",
|
|
|
|
"luasock1@dell-diego.cs.princeton.edu"
|
2001-09-25 23:35:17 +02:00
|
|
|
},
|
|
|
|
body = "multiple rcpt body",
|
|
|
|
title = "multiple rcpt",
|
|
|
|
})
|
|
|
|
|
|
|
|
insert(sent, {
|
|
|
|
from = from,
|
|
|
|
rcpt = {
|
2003-03-20 01:24:44 +01:00
|
|
|
"luasock2@localhost",
|
|
|
|
"luasock3",
|
2001-09-25 23:35:17 +02:00
|
|
|
"luasock1"
|
|
|
|
},
|
|
|
|
headers = {
|
|
|
|
header1 = "header 1",
|
|
|
|
header2 = "header 2",
|
|
|
|
header3 = "header 3",
|
|
|
|
header4 = "header 4",
|
|
|
|
header5 = "header 5",
|
|
|
|
header6 = "header 6",
|
|
|
|
},
|
|
|
|
body = stuffed_body,
|
|
|
|
title = "complex message",
|
|
|
|
})
|
|
|
|
|
|
|
|
insert(sent, {
|
|
|
|
from = from,
|
|
|
|
rcpt = rcpt,
|
|
|
|
server = server,
|
|
|
|
body = "simple message body",
|
|
|
|
title = "simple message"
|
|
|
|
})
|
|
|
|
|
|
|
|
insert(sent, {
|
|
|
|
from = from,
|
|
|
|
rcpt = rcpt,
|
|
|
|
server = server,
|
|
|
|
body = stuffed_body,
|
|
|
|
title = "stuffed message body"
|
|
|
|
})
|
|
|
|
|
|
|
|
insert(sent, {
|
|
|
|
from = from,
|
|
|
|
rcpt = rcpt,
|
|
|
|
headers = {
|
|
|
|
header1 = "header 1",
|
|
|
|
header2 = "header 2",
|
|
|
|
header3 = "header 3",
|
|
|
|
header4 = "header 4",
|
|
|
|
header5 = "header 5",
|
|
|
|
header6 = "header 6",
|
|
|
|
},
|
|
|
|
title = "multiple headers"
|
|
|
|
})
|
|
|
|
|
|
|
|
insert(sent, {
|
|
|
|
from = from,
|
|
|
|
rcpt = rcpt,
|
|
|
|
title = "minimum message"
|
|
|
|
})
|
|
|
|
|
2003-03-20 01:24:44 +01:00
|
|
|
io.write("testing host not found: ")
|
|
|
|
local c, e = socket.connect("wrong.host", 25)
|
2003-08-16 02:06:04 +02:00
|
|
|
local ret, err = socket.smtp.mail{
|
2001-09-25 23:35:17 +02:00
|
|
|
from = from,
|
|
|
|
rcpt = rcpt,
|
|
|
|
server = "wrong.host"
|
|
|
|
}
|
2003-08-16 02:06:04 +02:00
|
|
|
if ret or e ~= err then fail("wrong error message")
|
2001-09-25 23:35:17 +02:00
|
|
|
else print("ok") end
|
|
|
|
|
2003-03-20 01:24:44 +01:00
|
|
|
io.write("testing invalid from: ")
|
2003-08-16 02:06:04 +02:00
|
|
|
local ret, err = socket.smtp.mail{
|
2001-09-25 23:35:17 +02:00
|
|
|
from = ' " " (( _ * ',
|
|
|
|
rcpt = rcpt,
|
|
|
|
}
|
2003-08-16 02:06:04 +02:00
|
|
|
if ret or not err then fail("wrong error message")
|
2001-09-25 23:35:17 +02:00
|
|
|
else print(err) end
|
|
|
|
|
2003-03-20 01:24:44 +01:00
|
|
|
io.write("testing no rcpt: ")
|
2003-08-16 02:06:04 +02:00
|
|
|
local ret, err = socket.smtp.mail{
|
2001-09-25 23:35:17 +02:00
|
|
|
from = from,
|
|
|
|
}
|
2003-08-16 02:06:04 +02:00
|
|
|
if ret or not err then fail("wrong error message")
|
2001-09-25 23:35:17 +02:00
|
|
|
else print(err) end
|
|
|
|
|
2003-03-20 01:24:44 +01:00
|
|
|
io.write("clearing mailbox: ")
|
2001-09-25 23:35:17 +02:00
|
|
|
empty()
|
|
|
|
print("ok")
|
|
|
|
|
2003-03-20 01:24:44 +01:00
|
|
|
io.write("sending messages: ")
|
|
|
|
for i = 1, table.getn(sent) do
|
2003-08-16 02:06:04 +02:00
|
|
|
ret, err = socket.smtp.mail(sent[i])
|
|
|
|
if not ret then fail(err) end
|
2003-03-20 01:24:44 +01:00
|
|
|
io.write("+")
|
|
|
|
io.stdout:flush()
|
2001-09-25 23:35:17 +02:00
|
|
|
end
|
|
|
|
print("ok")
|
|
|
|
|
|
|
|
wait(mark(), total())
|
|
|
|
|
2003-03-20 01:24:44 +01:00
|
|
|
io.write("parsing mailbox: ")
|
|
|
|
local mbox = parse(get())
|
|
|
|
print(table.getn(mbox) .. " messages found!")
|
2001-09-25 23:35:17 +02:00
|
|
|
|
2003-03-20 01:24:44 +01:00
|
|
|
for i = 1, table.getn(mbox) do
|
2001-09-25 23:35:17 +02:00
|
|
|
check(sent, mbox[i])
|
|
|
|
end
|
|
|
|
|
|
|
|
print("passed all tests")
|
2003-05-25 03:54:13 +02:00
|
|
|
print(string.format("done in %.2fs", socket.time() - t))
|