utestclnt.lua 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644
  1. local socket = require"socket"
  2. socket.unix = require"socket.unix"
  3. host = host or "luasocket"
  4. function pass(...)
  5. local s = string.format(...)
  6. io.stderr:write(s, "\n")
  7. end
  8. function fail(...)
  9. local s = string.format(...)
  10. io.stderr:write("ERROR: ", s, "!\n")
  11. socket.sleep(3)
  12. os.exit()
  13. end
  14. function warn(...)
  15. local s = string.format(...)
  16. io.stderr:write("WARNING: ", s, "\n")
  17. end
  18. function remote(...)
  19. local s = string.format(...)
  20. s = string.gsub(s, "\n", ";")
  21. s = string.gsub(s, "%s+", " ")
  22. s = string.gsub(s, "^%s*", "")
  23. control:send(s .. "\n")
  24. control:receive()
  25. end
  26. function test(test)
  27. io.stderr:write("----------------------------------------------\n",
  28. "testing: ", test, "\n",
  29. "----------------------------------------------\n")
  30. end
  31. function uconnect(path)
  32. local u = assert(socket.unix())
  33. assert(u:connect(path))
  34. return u
  35. end
  36. function ubind(path)
  37. local u = assert(socket.unix())
  38. assert(u:bind(path))
  39. assert(u:listen(5))
  40. return u
  41. end
  42. function check_timeout(tm, sl, elapsed, err, opp, mode, alldone)
  43. if tm < sl then
  44. if opp == "send" then
  45. if not err then warn("must be buffered")
  46. elseif err == "timeout" then pass("proper timeout")
  47. else fail("unexpected error '%s'", err) end
  48. else
  49. if err ~= "timeout" then fail("should have timed out")
  50. else pass("proper timeout") end
  51. end
  52. else
  53. if mode == "total" then
  54. if elapsed > tm then
  55. if err ~= "timeout" then fail("should have timed out")
  56. else pass("proper timeout") end
  57. elseif elapsed < tm then
  58. if err then fail(err)
  59. else pass("ok") end
  60. else
  61. if alldone then
  62. if err then fail("unexpected error '%s'", err)
  63. else pass("ok") end
  64. else
  65. if err ~= "timeout" then fail(err)
  66. else pass("proper timeoutk") end
  67. end
  68. end
  69. else
  70. if err then fail(err)
  71. else pass("ok") end
  72. end
  73. end
  74. end
  75. if not socket._DEBUG then
  76. fail("Please define LUASOCKET_DEBUG and recompile LuaSocket")
  77. end
  78. io.stderr:write("----------------------------------------------\n",
  79. "LuaSocket Test Procedures\n",
  80. "----------------------------------------------\n")
  81. start = socket.gettime()
  82. function reconnect()
  83. io.stderr:write("attempting data connection... ")
  84. if data then data:close() end
  85. remote [[
  86. i = i or 1
  87. if data then data:close() data = nil end
  88. print("accepting")
  89. data = server:accept()
  90. i = i + 1
  91. print("done " .. i)
  92. ]]
  93. data, err = uconnect(host, port)
  94. if not data then fail(err)
  95. else pass("connected!") end
  96. end
  97. pass("attempting control connection...")
  98. control, err = uconnect(host, port)
  99. if err then fail(err)
  100. else pass("connected!") end
  101. ------------------------------------------------------------------------
  102. function test_methods(sock, methods)
  103. for _, v in pairs(methods) do
  104. if type(sock[v]) ~= "function" then
  105. fail(sock.class .. " method '" .. v .. "' not registered")
  106. end
  107. end
  108. pass(sock.class .. " methods are ok")
  109. end
  110. ------------------------------------------------------------------------
  111. function test_mixed(len)
  112. reconnect()
  113. local inter = math.ceil(len/4)
  114. local p1 = "unix " .. string.rep("x", inter) .. "line\n"
  115. local p2 = "dos " .. string.rep("y", inter) .. "line\r\n"
  116. local p3 = "raw " .. string.rep("z", inter) .. "bytes"
  117. local p4 = "end" .. string.rep("w", inter) .. "bytes"
  118. local bp1, bp2, bp3, bp4
  119. remote (string.format("str = data:receive(%d)",
  120. string.len(p1)+string.len(p2)+string.len(p3)+string.len(p4)))
  121. sent, err = data:send(p1..p2..p3..p4)
  122. if err then fail(err) end
  123. remote "data:send(str); data:close()"
  124. bp1, err = data:receive()
  125. if err then fail(err) end
  126. bp2, err = data:receive()
  127. if err then fail(err) end
  128. bp3, err = data:receive(string.len(p3))
  129. if err then fail(err) end
  130. bp4, err = data:receive("*a")
  131. if err then fail(err) end
  132. if bp1.."\n" == p1 and bp2.."\r\n" == p2 and bp3 == p3 and bp4 == p4 then
  133. pass("patterns match")
  134. else fail("patterns don't match") end
  135. end
  136. ------------------------------------------------------------------------
  137. function test_asciiline(len)
  138. reconnect()
  139. local str, str10, back, err
  140. str = string.rep("x", math.mod(len, 10))
  141. str10 = string.rep("aZb.c#dAe?", math.floor(len/10))
  142. str = str .. str10
  143. remote "str = data:receive()"
  144. sent, err = data:send(str.."\n")
  145. if err then fail(err) end
  146. remote "data:send(str ..'\\n')"
  147. back, err = data:receive()
  148. if err then fail(err) end
  149. if back == str then pass("lines match")
  150. else fail("lines don't match") end
  151. end
  152. ------------------------------------------------------------------------
  153. function test_rawline(len)
  154. reconnect()
  155. local str, str10, back, err
  156. str = string.rep(string.char(47), math.mod(len, 10))
  157. str10 = string.rep(string.char(120,21,77,4,5,0,7,36,44,100),
  158. math.floor(len/10))
  159. str = str .. str10
  160. remote "str = data:receive()"
  161. sent, err = data:send(str.."\n")
  162. if err then fail(err) end
  163. remote "data:send(str..'\\n')"
  164. back, err = data:receive()
  165. if err then fail(err) end
  166. if back == str then pass("lines match")
  167. else fail("lines don't match") end
  168. end
  169. ------------------------------------------------------------------------
  170. function test_raw(len)
  171. reconnect()
  172. local half = math.floor(len/2)
  173. local s1, s2, back, err
  174. s1 = string.rep("x", half)
  175. s2 = string.rep("y", len-half)
  176. remote (string.format("str = data:receive(%d)", len))
  177. sent, err = data:send(s1)
  178. if err then fail(err) end
  179. sent, err = data:send(s2)
  180. if err then fail(err) end
  181. remote "data:send(str)"
  182. back, err = data:receive(len)
  183. if err then fail(err) end
  184. if back == s1..s2 then pass("blocks match")
  185. else fail("blocks don't match") end
  186. end
  187. ------------------------------------------------------------------------
  188. function test_totaltimeoutreceive(len, tm, sl)
  189. reconnect()
  190. local str, err, partial
  191. pass("%d bytes, %ds total timeout, %ds pause", len, tm, sl)
  192. remote (string.format ([[
  193. data:settimeout(%d)
  194. str = string.rep('a', %d)
  195. data:send(str)
  196. print('server: sleeping for %ds')
  197. socket.sleep(%d)
  198. print('server: woke up')
  199. data:send(str)
  200. ]], 2*tm, len, sl, sl))
  201. data:settimeout(tm, "total")
  202. local t = socket.gettime()
  203. str, err, partial, elapsed = data:receive(2*len)
  204. check_timeout(tm, sl, elapsed, err, "receive", "total",
  205. string.len(str or partial) == 2*len)
  206. end
  207. ------------------------------------------------------------------------
  208. function test_totaltimeoutsend(len, tm, sl)
  209. reconnect()
  210. local str, err, total
  211. pass("%d bytes, %ds total timeout, %ds pause", len, tm, sl)
  212. remote (string.format ([[
  213. data:settimeout(%d)
  214. str = data:receive(%d)
  215. print('server: sleeping for %ds')
  216. socket.sleep(%d)
  217. print('server: woke up')
  218. str = data:receive(%d)
  219. ]], 2*tm, len, sl, sl, len))
  220. data:settimeout(tm, "total")
  221. str = string.rep("a", 2*len)
  222. total, err, partial, elapsed = data:send(str)
  223. check_timeout(tm, sl, elapsed, err, "send", "total",
  224. total == 2*len)
  225. end
  226. ------------------------------------------------------------------------
  227. function test_blockingtimeoutreceive(len, tm, sl)
  228. reconnect()
  229. local str, err, partial
  230. pass("%d bytes, %ds blocking timeout, %ds pause", len, tm, sl)
  231. remote (string.format ([[
  232. data:settimeout(%d)
  233. str = string.rep('a', %d)
  234. data:send(str)
  235. print('server: sleeping for %ds')
  236. socket.sleep(%d)
  237. print('server: woke up')
  238. data:send(str)
  239. ]], 2*tm, len, sl, sl))
  240. data:settimeout(tm)
  241. str, err, partial, elapsed = data:receive(2*len)
  242. check_timeout(tm, sl, elapsed, err, "receive", "blocking",
  243. string.len(str or partial) == 2*len)
  244. end
  245. ------------------------------------------------------------------------
  246. function test_blockingtimeoutsend(len, tm, sl)
  247. reconnect()
  248. local str, err, total
  249. pass("%d bytes, %ds blocking timeout, %ds pause", len, tm, sl)
  250. remote (string.format ([[
  251. data:settimeout(%d)
  252. str = data:receive(%d)
  253. print('server: sleeping for %ds')
  254. socket.sleep(%d)
  255. print('server: woke up')
  256. str = data:receive(%d)
  257. ]], 2*tm, len, sl, sl, len))
  258. data:settimeout(tm)
  259. str = string.rep("a", 2*len)
  260. total, err, partial, elapsed = data:send(str)
  261. check_timeout(tm, sl, elapsed, err, "send", "blocking",
  262. total == 2*len)
  263. end
  264. ------------------------------------------------------------------------
  265. function empty_connect()
  266. reconnect()
  267. if data then data:close() data = nil end
  268. remote [[
  269. if data then data:close() data = nil end
  270. data = server:accept()
  271. ]]
  272. data, err = socket.connect("", port)
  273. if not data then
  274. pass("ok")
  275. data = socket.connect(host, port)
  276. else
  277. pass("gethostbyname returns localhost on empty string...")
  278. end
  279. end
  280. ------------------------------------------------------------------------
  281. function isclosed(c)
  282. return c:getfd() == -1 or c:getfd() == (2^32-1)
  283. end
  284. function active_close()
  285. reconnect()
  286. if isclosed(data) then fail("should not be closed") end
  287. data:close()
  288. if not isclosed(data) then fail("should be closed") end
  289. data = nil
  290. local udp = socket.udp()
  291. if isclosed(udp) then fail("should not be closed") end
  292. udp:close()
  293. if not isclosed(udp) then fail("should be closed") end
  294. pass("ok")
  295. end
  296. ------------------------------------------------------------------------
  297. function test_closed()
  298. local back, partial, err
  299. local str = 'little string'
  300. reconnect()
  301. pass("trying read detection")
  302. remote (string.format ([[
  303. data:send('%s')
  304. data:close()
  305. data = nil
  306. ]], str))
  307. -- try to get a line
  308. back, err, partial = data:receive()
  309. if not err then fail("should have gotten 'closed'.")
  310. elseif err ~= "closed" then fail("got '"..err.."' instead of 'closed'.")
  311. elseif str ~= partial then fail("didn't receive partial result.")
  312. else pass("graceful 'closed' received") end
  313. reconnect()
  314. pass("trying write detection")
  315. remote [[
  316. data:close()
  317. data = nil
  318. ]]
  319. total, err, partial = data:send(string.rep("ugauga", 100000))
  320. if not err then
  321. pass("failed: output buffer is at least %d bytes long!", total)
  322. elseif err ~= "closed" then
  323. fail("got '"..err.."' instead of 'closed'.")
  324. else
  325. pass("graceful 'closed' received after %d bytes were sent", partial)
  326. end
  327. end
  328. ------------------------------------------------------------------------
  329. function test_selectbugs()
  330. local r, s, e = socket.select(nil, nil, 0.1)
  331. assert(type(r) == "table" and type(s) == "table" and
  332. (e == "timeout" or e == "error"))
  333. pass("both nil: ok")
  334. local udp = socket.udp()
  335. udp:close()
  336. r, s, e = socket.select({ udp }, { udp }, 0.1)
  337. assert(type(r) == "table" and type(s) == "table" and
  338. (e == "timeout" or e == "error"))
  339. pass("closed sockets: ok")
  340. e = pcall(socket.select, "wrong", 1, 0.1)
  341. assert(e == false)
  342. e = pcall(socket.select, {}, 1, 0.1)
  343. assert(e == false)
  344. pass("invalid input: ok")
  345. end
  346. ------------------------------------------------------------------------
  347. function accept_timeout()
  348. io.stderr:write("accept with timeout (if it hangs, it failed): ")
  349. local s, e = socket.bind("*", 0, 0)
  350. assert(s, e)
  351. local t = socket.gettime()
  352. s:settimeout(1)
  353. local c, e = s:accept()
  354. assert(not c, "should not accept")
  355. assert(e == "timeout", string.format("wrong error message (%s)", e))
  356. t = socket.gettime() - t
  357. assert(t < 2, string.format("took to long to give up (%gs)", t))
  358. s:close()
  359. pass("good")
  360. end
  361. ------------------------------------------------------------------------
  362. function connect_timeout()
  363. io.stderr:write("connect with timeout (if it hangs, it failed!): ")
  364. local t = socket.gettime()
  365. local c, e = socket.tcp()
  366. assert(c, e)
  367. c:settimeout(0.1)
  368. local t = socket.gettime()
  369. local r, e = c:connect("127.0.0.2", 80)
  370. assert(not r, "should not connect")
  371. assert(socket.gettime() - t < 2, "took too long to give up.")
  372. c:close()
  373. print("ok")
  374. end
  375. ------------------------------------------------------------------------
  376. function accept_errors()
  377. io.stderr:write("not listening: ")
  378. local d, e = socket.bind("*", 0)
  379. assert(d, e);
  380. local c, e = socket.tcp();
  381. assert(c, e);
  382. d:setfd(c:getfd())
  383. d:settimeout(2)
  384. local r, e = d:accept()
  385. assert(not r and e)
  386. print("ok: ", e)
  387. io.stderr:write("not supported: ")
  388. local c, e = socket.udp()
  389. assert(c, e);
  390. d:setfd(c:getfd())
  391. local r, e = d:accept()
  392. assert(not r and e)
  393. print("ok: ", e)
  394. end
  395. ------------------------------------------------------------------------
  396. function connect_errors()
  397. io.stderr:write("connection refused: ")
  398. local c, e = socket.connect("localhost", 1);
  399. assert(not c and e)
  400. print("ok: ", e)
  401. io.stderr:write("host not found: ")
  402. local c, e = socket.connect("host.is.invalid", 1);
  403. assert(not c and e, e)
  404. print("ok: ", e)
  405. end
  406. ------------------------------------------------------------------------
  407. function rebind_test()
  408. local c = socket.bind("localhost", 0)
  409. local i, p = c:getsockname()
  410. local s, e = socket.tcp()
  411. assert(s, e)
  412. s:setoption("reuseaddr", false)
  413. r, e = s:bind("localhost", p)
  414. assert(not r, "managed to rebind!")
  415. assert(e)
  416. print("ok: ", e)
  417. end
  418. ------------------------------------------------------------------------
  419. function getstats_test()
  420. reconnect()
  421. local t = 0
  422. for i = 1, 25 do
  423. local c = math.random(1, 100)
  424. remote (string.format ([[
  425. str = data:receive(%d)
  426. data:send(str)
  427. ]], c))
  428. data:send(string.rep("a", c))
  429. data:receive(c)
  430. t = t + c
  431. local r, s, a = data:getstats()
  432. assert(r == t, "received count failed" .. tostring(r)
  433. .. "/" .. tostring(t))
  434. assert(s == t, "sent count failed" .. tostring(s)
  435. .. "/" .. tostring(t))
  436. end
  437. print("ok")
  438. end
  439. ------------------------------------------------------------------------
  440. function test_nonblocking(size)
  441. reconnect()
  442. print("Testing " .. 2*size .. " bytes")
  443. remote(string.format([[
  444. data:send(string.rep("a", %d))
  445. socket.sleep(0.5)
  446. data:send(string.rep("b", %d) .. "\n")
  447. ]], size, size))
  448. local err = "timeout"
  449. local part = ""
  450. local str
  451. data:settimeout(0)
  452. while 1 do
  453. str, err, part = data:receive("*l", part)
  454. if err ~= "timeout" then break end
  455. end
  456. assert(str == (string.rep("a", size) .. string.rep("b", size)))
  457. reconnect()
  458. remote(string.format([[
  459. str = data:receive(%d)
  460. socket.sleep(0.5)
  461. str = data:receive(%d, str)
  462. data:send(str)
  463. ]], size, size))
  464. data:settimeout(0)
  465. local start = 0
  466. while 1 do
  467. ret, err, start = data:send(str, start+1)
  468. if err ~= "timeout" then break end
  469. end
  470. data:send("\n")
  471. data:settimeout(-1)
  472. local back = data:receive(2*size)
  473. assert(back == str, "'" .. back .. "' vs '" .. str .. "'")
  474. print("ok")
  475. end
  476. ------------------------------------------------------------------------
  477. test("method registration")
  478. test_methods(socket.unix(), {
  479. "accept",
  480. "bind",
  481. "close",
  482. "connect",
  483. "dirty",
  484. "getfd",
  485. "getstats",
  486. "setstats",
  487. "listen",
  488. "receive",
  489. "send",
  490. "setfd",
  491. "setoption",
  492. "setpeername",
  493. "setsockname",
  494. "settimeout",
  495. "shutdown",
  496. })
  497. test("connect function")
  498. --connect_timeout()
  499. --empty_connect()
  500. --connect_errors()
  501. --test("rebinding: ")
  502. --rebind_test()
  503. test("active close: ")
  504. active_close()
  505. test("closed connection detection: ")
  506. test_closed()
  507. test("accept function: ")
  508. accept_timeout()
  509. accept_errors()
  510. test("getstats test")
  511. getstats_test()
  512. test("character line")
  513. test_asciiline(1)
  514. test_asciiline(17)
  515. test_asciiline(200)
  516. test_asciiline(4091)
  517. test_asciiline(80199)
  518. test_asciiline(8000000)
  519. test_asciiline(80199)
  520. test_asciiline(4091)
  521. test_asciiline(200)
  522. test_asciiline(17)
  523. test_asciiline(1)
  524. test("mixed patterns")
  525. test_mixed(1)
  526. test_mixed(17)
  527. test_mixed(200)
  528. test_mixed(4091)
  529. test_mixed(801990)
  530. test_mixed(4091)
  531. test_mixed(200)
  532. test_mixed(17)
  533. test_mixed(1)
  534. test("binary line")
  535. test_rawline(1)
  536. test_rawline(17)
  537. test_rawline(200)
  538. test_rawline(4091)
  539. test_rawline(80199)
  540. test_rawline(8000000)
  541. test_rawline(80199)
  542. test_rawline(4091)
  543. test_rawline(200)
  544. test_rawline(17)
  545. test_rawline(1)
  546. test("raw transfer")
  547. test_raw(1)
  548. test_raw(17)
  549. test_raw(200)
  550. test_raw(4091)
  551. test_raw(80199)
  552. test_raw(8000000)
  553. test_raw(80199)
  554. test_raw(4091)
  555. test_raw(200)
  556. test_raw(17)
  557. test_raw(1)
  558. test("non-blocking transfer")
  559. test_nonblocking(1)
  560. test_nonblocking(17)
  561. test_nonblocking(200)
  562. test_nonblocking(4091)
  563. test_nonblocking(80199)
  564. test_nonblocking(8000000)
  565. test_nonblocking(80199)
  566. test_nonblocking(4091)
  567. test_nonblocking(200)
  568. test_nonblocking(17)
  569. test_nonblocking(1)
  570. test("total timeout on send")
  571. test_totaltimeoutsend(800091, 1, 3)
  572. test_totaltimeoutsend(800091, 2, 3)
  573. test_totaltimeoutsend(800091, 5, 2)
  574. test_totaltimeoutsend(800091, 3, 1)
  575. test("total timeout on receive")
  576. test_totaltimeoutreceive(800091, 1, 3)
  577. test_totaltimeoutreceive(800091, 2, 3)
  578. test_totaltimeoutreceive(800091, 3, 2)
  579. test_totaltimeoutreceive(800091, 3, 1)
  580. test("blocking timeout on send")
  581. test_blockingtimeoutsend(800091, 1, 3)
  582. test_blockingtimeoutsend(800091, 2, 3)
  583. test_blockingtimeoutsend(800091, 3, 2)
  584. test_blockingtimeoutsend(800091, 3, 1)
  585. test("blocking timeout on receive")
  586. test_blockingtimeoutreceive(800091, 1, 3)
  587. test_blockingtimeoutreceive(800091, 2, 3)
  588. test_blockingtimeoutreceive(800091, 3, 2)
  589. test_blockingtimeoutreceive(800091, 3, 1)
  590. test(string.format("done in %.2fs", socket.gettime() - start))