2008-02-08 15:38:31 -07:00
|
|
|
open Unixqueue
|
|
|
|
open OUnit
|
|
|
|
open Chat
|
2008-02-27 22:50:27 -07:00
|
|
|
open Irc
|
2008-02-08 15:38:31 -07:00
|
|
|
|
2008-03-07 13:52:13 -07:00
|
|
|
let ues = Unixqueue.create_unix_event_system ()
|
2008-02-08 15:38:31 -07:00
|
|
|
|
2008-03-10 23:57:07 -06:00
|
|
|
let int_of_file_descr fd = (Obj.magic fd) + 0
|
|
|
|
|
|
|
|
let rec epollevents_as_list events =
|
|
|
|
match events with
|
|
|
|
| [] ->
|
2008-03-14 21:28:22 -06:00
|
|
|
[]
|
2008-03-10 23:57:07 -06:00
|
|
|
| Epoll.In :: tl ->
|
2008-03-14 21:28:22 -06:00
|
|
|
"POLLIN" :: (epollevents_as_list tl)
|
2008-03-10 23:57:07 -06:00
|
|
|
| Epoll.Priority :: tl ->
|
2008-03-14 21:28:22 -06:00
|
|
|
"POLLPRI" :: (epollevents_as_list tl)
|
2008-03-10 23:57:07 -06:00
|
|
|
| Epoll.Out :: tl ->
|
2008-03-14 21:28:22 -06:00
|
|
|
"POLLOUT" :: (epollevents_as_list tl)
|
2008-03-10 23:57:07 -06:00
|
|
|
| Epoll.Error :: tl ->
|
2008-03-14 21:28:22 -06:00
|
|
|
"POLLERR" :: (epollevents_as_list tl)
|
2008-03-10 23:57:07 -06:00
|
|
|
| Epoll.Hangup :: tl ->
|
2008-03-14 21:28:22 -06:00
|
|
|
"POLLHUP" :: (epollevents_as_list tl)
|
2008-03-10 23:57:07 -06:00
|
|
|
|
|
|
|
let rec epollfds_as_list pfds =
|
|
|
|
match pfds with
|
|
|
|
| [] ->
|
2008-03-14 21:28:22 -06:00
|
|
|
[]
|
2008-03-10 23:57:07 -06:00
|
|
|
| (fd, events) :: tl ->
|
2008-03-14 21:28:22 -06:00
|
|
|
(Printf.sprintf "{fd=%d; events=%s}"
|
|
|
|
(int_of_file_descr fd)
|
|
|
|
(String.concat "|" (epollevents_as_list events))) ::
|
|
|
|
epollfds_as_list tl
|
2008-03-10 23:57:07 -06:00
|
|
|
|
|
|
|
let epollfds_as_string pfds =
|
|
|
|
"[" ^ (String.concat ", " (epollfds_as_list pfds)) ^ "]"
|
|
|
|
|
2008-03-14 21:28:22 -06:00
|
|
|
let epoll_expect e ?(n=3) l =
|
|
|
|
let m = Epoll.wait e n 0 in
|
|
|
|
assert_equal
|
|
|
|
~printer:epollfds_as_string
|
|
|
|
(List.sort compare l)
|
|
|
|
(List.sort compare m)
|
|
|
|
|
2008-02-27 22:50:27 -07:00
|
|
|
let unit_tests =
|
2008-03-14 21:28:22 -06:00
|
|
|
"Unit tests" >::: [
|
|
|
|
"epoll" >::
|
|
|
|
(fun () ->
|
|
|
|
let a,b = Unix.socketpair Unix.PF_UNIX Unix.SOCK_STREAM 0 in
|
|
|
|
let e = Epoll.create 1 in
|
|
|
|
let expect = epoll_expect e in
|
|
|
|
Epoll.ctl e Epoll.Add (a, [Epoll.Out; Epoll.In]);
|
|
|
|
expect [(a, [Epoll.Out])];
|
|
|
|
|
|
|
|
Epoll.ctl e Epoll.Modify (a, [Epoll.In; Epoll.Priority]);
|
|
|
|
expect [];
|
|
|
|
|
|
|
|
Epoll.ctl e Epoll.Add (b, [Epoll.Out; Epoll.In]);
|
|
|
|
expect [(b, [Epoll.Out])];
|
|
|
|
|
|
|
|
Epoll.ctl e Epoll.Modify (a, [Epoll.Out; Epoll.In]);
|
|
|
|
expect [(a, [Epoll.Out]); (b, [Epoll.Out])];
|
|
|
|
assert_equal
|
|
|
|
1
|
|
|
|
(List.length (Epoll.wait e 1 0));
|
|
|
|
|
|
|
|
Epoll.ctl e Epoll.Modify (a, [Epoll.Out; Epoll.In]);
|
|
|
|
expect [(a, [Epoll.Out]); (b, [Epoll.Out])];
|
|
|
|
|
|
|
|
assert_equal
|
|
|
|
2
|
|
|
|
(Unix.write a "hi" 0 2);
|
|
|
|
expect [(a, [Epoll.Out]); (b, [Epoll.In; Epoll.Out])];
|
|
|
|
|
|
|
|
Epoll.ctl e Epoll.Delete (a, []);
|
|
|
|
expect [(b, [Epoll.In; Epoll.Out])];
|
|
|
|
assert_raises
|
|
|
|
(Failure "ocaml_epoll_ctl: No such file or directory")
|
|
|
|
(fun () ->
|
|
|
|
Epoll.ctl e Epoll.Modify (a, [Epoll.In; Epoll.Priority]));
|
|
|
|
assert_raises
|
|
|
|
(Failure "ocaml_epoll_ctl: File exists")
|
|
|
|
(fun () ->
|
|
|
|
Epoll.ctl e Epoll.Add (b, [Epoll.In; Epoll.Priority]));
|
|
|
|
expect [(b, [Epoll.In; Epoll.Out])];
|
|
|
|
|
|
|
|
Unix.close a;
|
|
|
|
expect [(b, [Epoll.In; Epoll.Out; Epoll.Hangup])];
|
|
|
|
assert_raises
|
|
|
|
(Failure "ocaml_epoll_ctl: Bad file descriptor")
|
|
|
|
(fun () ->
|
|
|
|
Epoll.ctl e Epoll.Modify (a, [Epoll.In; Epoll.Priority]));
|
|
|
|
|
|
|
|
Unix.close b;
|
|
|
|
Epoll.destroy e
|
|
|
|
);
|
2008-03-10 23:57:07 -06:00
|
|
|
|
2008-02-27 22:50:27 -07:00
|
|
|
"command_of_string" >::
|
2008-03-14 21:28:22 -06:00
|
|
|
(fun () ->
|
|
|
|
assert_equal
|
|
|
|
~printer:Command.as_string
|
|
|
|
(Command.create None "NICK" ["name"] None)
|
|
|
|
(Command.from_string "NICK name");
|
|
|
|
assert_equal
|
|
|
|
~printer:Command.as_string
|
|
|
|
(Command.create None "NICK" ["name"] None)
|
|
|
|
(Command.from_string "nick name");
|
|
|
|
assert_equal
|
|
|
|
~printer:Command.as_string
|
|
|
|
(Command.create (Some "foo") "NICK" ["name"] None)
|
|
|
|
(Command.from_string ":foo NICK name");
|
|
|
|
assert_equal
|
|
|
|
~printer:Command.as_string
|
|
|
|
(Command.create (Some "foo.bar") "PART" ["#foo"; "#bar"]
|
|
|
|
(Some "ta ta"))
|
|
|
|
(Command.from_string ":foo.bar PART #foo #bar :ta ta");
|
|
|
|
)
|
2008-02-27 22:50:27 -07:00
|
|
|
]
|
|
|
|
|
|
|
|
|
2008-03-07 13:52:13 -07:00
|
|
|
|
2008-03-02 21:30:37 -07:00
|
|
|
let do_login nick =
|
|
|
|
[
|
|
|
|
Send ("USER " ^ nick ^ " +iw " ^ nick ^ " :gecos\r\n");
|
|
|
|
Send ("NICK " ^ nick ^ "\r\n");
|
|
|
|
Recv (":testserver.test 001 " ^ nick ^ " :Welcome to IRC.\r\n");
|
2008-03-05 17:51:13 -07:00
|
|
|
Recv (":testserver.test 002 " ^ nick ^ " :I am testserver.test Running version " ^ Irc.version ^ "\r\n");
|
2008-03-02 21:30:37 -07:00
|
|
|
Recv (":testserver.test 003 " ^ nick ^ " :This server was created sometime\r\n");
|
|
|
|
Recv (":testserver.test 004 " ^ nick ^ " :testserver.test 0.1 l t\r\n");
|
|
|
|
]
|
|
|
|
|
2008-02-27 22:50:27 -07:00
|
|
|
let regression_tests =
|
2008-03-02 21:30:37 -07:00
|
|
|
"Regression tests" >:::
|
2008-02-08 15:38:31 -07:00
|
|
|
[
|
2008-03-02 21:30:37 -07:00
|
|
|
"Simple connection" >::
|
2008-03-07 13:52:13 -07:00
|
|
|
(fun () ->
|
|
|
|
let script =
|
|
|
|
(do_login "nick") @
|
2008-03-14 21:28:22 -06:00
|
|
|
[
|
2008-03-07 13:52:13 -07:00
|
|
|
Send "BLARGH\r\n";
|
|
|
|
Recv ":testserver.test 421 nick BLARGH :Unknown or misconstructed command\r\n";
|
|
|
|
Send "MOTD\r\n";
|
2008-03-14 21:28:22 -06:00
|
|
|
Recv ":testserver.test 422 nick :MOTD File is missing\r\n";
|
2008-03-07 13:52:13 -07:00
|
|
|
Send "TIME\r\n";
|
|
|
|
Regex ":testserver\\.test 391 nick testserver\\.test :[-0-9]+T[:0-9]+Z\r\n";
|
|
|
|
Send "VERSION\r\n";
|
|
|
|
Recv ":testserver.test 351 nick 0.1 testserver.test :\r\n";
|
|
|
|
Send "PING snot\r\n";
|
|
|
|
Recv ":testserver.test PONG testserver.test :snot\r\n";
|
|
|
|
Send "PING :snot\r\n";
|
|
|
|
Recv ":testserver.test PONG testserver.test :snot\r\n";
|
2008-03-14 21:28:22 -06:00
|
|
|
Send "ISON nick otherguy\r\n";
|
|
|
|
Recv ":testserver.test 303 nick :nick\r\n";
|
|
|
|
Send "ISON otherguy thirdguy\r\n";
|
|
|
|
Recv ":testserver.test 303 nick :\r\n";
|
2008-03-07 13:52:13 -07:00
|
|
|
Send "PRIVMSG nick :hello\r\n";
|
|
|
|
Recv ":nick!nick@UDS PRIVMSG nick :hello\r\n";
|
|
|
|
Send "NOTICE nick :hello\r\n";
|
|
|
|
Recv ":nick!nick@UDS NOTICE nick :hello\r\n";
|
|
|
|
Send "PRIVMSG otherguy :hello\r\n";
|
|
|
|
Recv ":testserver.test 401 nick otherguy :No such nick/channel\r\n";
|
|
|
|
]
|
|
|
|
in
|
|
|
|
let g = Unixqueue.new_group ues in
|
|
|
|
let a,b = Unix.socketpair Unix.PF_UNIX Unix.SOCK_STREAM 0 in
|
|
|
|
Unixqueue.add_handler ues g Iobuf.handle_event;
|
|
|
|
Client.handle_connection ues g a;
|
|
|
|
ignore (new chat_handler script ues b);
|
|
|
|
chat_run ues);
|
2008-03-06 21:30:49 -07:00
|
|
|
|
|
|
|
"Second connection" >::
|
2008-03-14 21:28:22 -06:00
|
|
|
(fun () ->
|
2008-03-07 13:52:13 -07:00
|
|
|
let script =
|
|
|
|
(do_login "otherguy") @
|
2008-03-14 21:28:22 -06:00
|
|
|
[
|
|
|
|
Send "ISON nick otherguy\r\n";
|
|
|
|
Recv ":testserver.test 303 otherguy :otherguy\r\n";
|
|
|
|
]
|
2008-03-07 13:52:13 -07:00
|
|
|
in
|
|
|
|
let g = Unixqueue.new_group ues in
|
|
|
|
let a,b = Unix.socketpair Unix.PF_UNIX Unix.SOCK_STREAM 0 in
|
|
|
|
Unixqueue.add_handler ues g Iobuf.handle_event;
|
|
|
|
Client.handle_connection ues g a;
|
|
|
|
ignore (new chat_handler script ues b);
|
|
|
|
chat_run ues);
|
|
|
|
|
|
|
|
"Simultaneous connections" >::
|
|
|
|
(fun () ->
|
|
|
|
let script1 =
|
|
|
|
(do_login "alice") @
|
|
|
|
[
|
|
|
|
Send "ISON bob\r\n";
|
|
|
|
Recv ":testserver.test 303 alice :bob\r\n";
|
|
|
|
Send "PRIVMSG bob :Hi Bob!\r\n";
|
|
|
|
Send "PING :foo\r\n"; (* Make sure we don't disconnect too soon *)
|
|
|
|
Recv ":testserver.test PONG testserver.test :foo\r\n";
|
|
|
|
]
|
|
|
|
in
|
|
|
|
let script2 =
|
|
|
|
(do_login "bob") @
|
|
|
|
[
|
|
|
|
Send "ISON alice\r\n";
|
|
|
|
Recv ":testserver.test 303 bob :alice\r\n";
|
|
|
|
Recv ":alice!alice@UDS PRIVMSG bob :Hi Bob!\r\n";
|
|
|
|
]
|
|
|
|
in
|
|
|
|
let g = Unixqueue.new_group ues in
|
|
|
|
let aa,ab = Unix.socketpair Unix.PF_UNIX Unix.SOCK_STREAM 0 in
|
|
|
|
let ba,bb = Unix.socketpair Unix.PF_UNIX Unix.SOCK_STREAM 0 in
|
|
|
|
Unixqueue.add_handler ues g Iobuf.handle_event;
|
|
|
|
Client.handle_connection ues g aa;
|
|
|
|
Client.handle_connection ues g ba;
|
|
|
|
ignore (new chat_handler script1 ues ab);
|
|
|
|
ignore (new chat_handler script2 ues bb);
|
|
|
|
chat_run ues);
|
2008-02-08 15:38:31 -07:00
|
|
|
]
|
|
|
|
|
|
|
|
let _ =
|
2008-02-28 22:24:52 -07:00
|
|
|
Irc.name := "testserver.test";
|
2008-03-14 21:28:22 -06:00
|
|
|
run_test_tt_main (TestList [Dispatch_tests.unit; unit_tests; regression_tests])
|
2008-02-08 15:38:31 -07:00
|
|
|
|
|
|
|
|