PageRenderTime 42ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/t/14-dock-heyu.t

http://github.com/beanz/xpl-perl
Perl | 331 lines | 297 code | 29 blank | 5 comment | 13 complexity | ae33ce18f357b9d61d985078c133b45b MD5 | raw file
  1. #!/usr/bin/perl -w
  2. #
  3. # Copyright (C) 2009 by Mark Hindess
  4. use strict;
  5. use IO::Socket::INET;
  6. use IO::Select;
  7. use Socket;
  8. use Test::More tests => 27;
  9. use t::Helpers qw/test_warn test_error test_output/;
  10. no warnings qw/deprecated/;
  11. $|=1;
  12. $ENV{PATH} = 't/bin:blib/script:'.$ENV{PATH};
  13. use_ok('xPL::Dock','Heyu');
  14. my @msg;
  15. sub xPL::Dock::send_aux {
  16. my $self = shift;
  17. my $sin = shift;
  18. push @msg, [@_];
  19. }
  20. $ENV{XPL_HOSTNAME} = 'mytestid';
  21. my $xpl;
  22. {
  23. local $0 = 'dingus';
  24. local @ARGV = ('--verbose',
  25. '--heyu-verbose', '--heyu-verbose',
  26. '--define', 'ip=127.0.0.1',
  27. '--define', 'broadcast=127.0.0.1',
  28. '--define', 'hubless=1',
  29. #'--', '-v',
  30. );
  31. $xpl = xPL::Dock->new(port => 0);
  32. }
  33. ok($xpl, 'created dock client');
  34. my $plugin = ($xpl->plugins)[0];
  35. ok($plugin, 'plugin exists');
  36. is(ref $plugin, 'xPL::Dock::Heyu', 'plugin has correct type');
  37. my $out = '';
  38. while (!$plugin->{_monitor_ready}) {
  39. $out .= test_output(sub { $xpl->main_loop(1) }, \*STDERR);
  40. }
  41. ok(1, 'monitor ready');
  42. my $sel = IO::Select->new($plugin->{_monitor_fh});
  43. while ($sel->can_read(0.1)) {
  44. $out .= test_output(sub { $xpl->main_loop(1) }, \*STDERR);
  45. }
  46. is($out,
  47. q{Sending x10.basic a0 on
  48. Sending x10.basic a2 bright 8
  49. Sending x10.confirm a3,10 on
  50. Sending x10.basic l6 xfunc data1=49 data2=63
  51. Sending x10.basic a4,5,6,10 on
  52. Sending x10.basic l6 xfunc data1=49 data2=63
  53. monitor reported unsupported line:
  54. testing unsupported line
  55. },
  56. 'unsupported line output');
  57. is(test_output(sub {
  58. $xpl->dispatch_xpl_message(
  59. xPL::Message->new(message_type => 'xpl-cmnd',
  60. head =>
  61. {
  62. source => 'acme-heyu.test',
  63. },
  64. schema=> 'x10.basic',
  65. body =>
  66. [
  67. 'command' => 'on',
  68. 'device' => 'a3',
  69. ])); }, \*STDOUT),
  70. ("queued: 00000000 on a3\n".
  71. "sending: 00000000 on a3\n"),
  72. 'x10.basic command=extended output');
  73. my $count = $xpl->input_callback_count($plugin->{_io}->{_input_handle});
  74. $out = '';
  75. while ($count == $xpl->input_callback_count($plugin->{_io}->{_input_handle})) {
  76. $out = test_output(sub { $xpl->main_loop(1); }, \*STDERR);
  77. }
  78. is($out, "Acknowledged 00000000 on a3\n", 'helper ack 0');
  79. check_sent_msg({
  80. message_type => 'xpl-trig',
  81. schema => 'x10.basic',
  82. body => [
  83. 'command' => 'on',
  84. 'device' => 'a0',
  85. ],
  86. }, 'monitor: a0 on');
  87. check_sent_msg({
  88. message_type => 'xpl-trig',
  89. schema => 'x10.basic',
  90. body => [
  91. command => 'bright',
  92. device => 'a2',
  93. level => 36,
  94. ],
  95. }, 'monitor: a2 bright');
  96. check_sent_msg({
  97. message_type => 'xpl-trig',
  98. schema => 'x10.confirm',
  99. body => [
  100. command => 'on',
  101. device => 'a3,a10',
  102. ],
  103. }, 'monitor: a3 on');
  104. check_sent_msg({
  105. message_type => 'xpl-trig',
  106. schema => 'x10.basic',
  107. body => [
  108. command => 'extended',
  109. device => 'l6',
  110. data1 => 49,
  111. data2 => 63,
  112. ],
  113. }, 'monitor: l6 xfunc 49 63');
  114. check_sent_msg({
  115. message_type => 'xpl-trig',
  116. schema => 'x10.basic',
  117. body => [
  118. command => 'on',
  119. device => 'a4,a5,a6,a10',
  120. ],
  121. }, 'monitor: a4,a5,a6,a10');
  122. check_sent_msg({
  123. message_type => 'xpl-trig',
  124. schema => 'x10.basic',
  125. body => [
  126. command => 'extended',
  127. device => 'l6',
  128. data1 => 49,
  129. data2 => 63,
  130. ],
  131. }, 'monitor: l6 xfunc 49 63');
  132. is(test_output(sub {
  133. $xpl->dispatch_xpl_message(
  134. xPL::Message->new(message_type => 'xpl-cmnd',
  135. head =>
  136. {
  137. source => 'acme-heyu.test',
  138. },
  139. schema=> 'x10.basic',
  140. body =>
  141. [
  142. 'command' => 'dim',
  143. 'level' => 10,
  144. 'house' => 'a',
  145. ])); }, \*STDOUT),
  146. ("queued: 00000001 dim a1 2\n".
  147. "sending: 00000001 dim a1 2\n"),
  148. 'x10.basic command=dim output');
  149. $count = $xpl->input_callback_count($plugin->{_io}->{_input_handle});
  150. $out = '';
  151. while ($count == $xpl->input_callback_count($plugin->{_io}->{_input_handle})) {
  152. $out = test_output(sub { $xpl->main_loop(1); }, \*STDERR);
  153. }
  154. is($out, "Acknowledged 00000001 dim a1 2\n", 'helper ack 1');
  155. is(test_output(sub {
  156. $xpl->dispatch_xpl_message(
  157. xPL::Message->new(message_type => 'xpl-cmnd',
  158. head =>
  159. {
  160. source => 'acme-heyu.test',
  161. },
  162. schema=> 'x10.basic',
  163. body =>
  164. [
  165. command => 'extended',
  166. device => 'a10,a12',
  167. data1 => 49,
  168. data2 => 63,
  169. ])); }, \*STDOUT),
  170. ("queued: 00000002 xfunc 31 a10,12 3f\n".
  171. "sending: 00000002 xfunc 31 a10,12 3f\n"),
  172. 'x10.basic command=extended output');
  173. $count = $xpl->input_callback_count($plugin->{_io}->{_input_handle});
  174. $out = '';
  175. while ($count == $xpl->input_callback_count($plugin->{_io}->{_input_handle})) {
  176. $out = test_output(sub { $xpl->main_loop(1); }, \*STDERR);
  177. }
  178. is($out, "Helper wrote: Testing error case\n", 'helper output');
  179. $count = $xpl->input_callback_count($plugin->{_io}->{_input_handle});
  180. $out = '';
  181. while ($count ==
  182. $xpl->input_callback_count($plugin->{_io}->{_input_handle})) {
  183. $out = test_output(sub { $xpl->main_loop(1); }, \*STDERR);
  184. }
  185. is($out, "Received 00000002: 65280 65280\n", 'helper error');
  186. is(test_output(sub {
  187. $xpl->dispatch_xpl_message(
  188. xPL::Message->new(message_type => 'xpl-cmnd',
  189. head =>
  190. {
  191. source => 'acme-heyu.test',
  192. },
  193. schema=> 'x10.basic',
  194. body =>
  195. [
  196. command => 'extended',
  197. device => 'a10,a12',
  198. data2 => 63,
  199. ])); }, \*STDOUT),
  200. '',
  201. 'x10.basic command=extended missing data1');
  202. is(test_output(sub {
  203. $xpl->dispatch_xpl_message(
  204. xPL::Message->new(message_type => 'xpl-cmnd',
  205. head =>
  206. {
  207. source => 'acme-heyu.test',
  208. },
  209. schema=> 'x10.basic',
  210. body =>
  211. [
  212. command => 'extended',
  213. device => 'a10,a12',
  214. data1 => 49,
  215. ])); }, \*STDOUT),
  216. '',
  217. 'x10.basic command=extended missing data2');
  218. is(test_output(sub {
  219. $xpl->dispatch_xpl_message(
  220. xPL::Message->new(message_type => 'xpl-cmnd',
  221. head =>
  222. {
  223. source => 'acme-heyu.test',
  224. },
  225. schema=> 'x10.basic',
  226. body =>
  227. [
  228. command => 'invalid',
  229. device => 'a10',
  230. ])); }, \*STDOUT),
  231. '',
  232. 'x10.basic command=invalid');
  233. is(test_output(sub {
  234. $xpl->dispatch_xpl_message(
  235. xPL::Message->new(message_type => 'xpl-cmnd',
  236. head =>
  237. {
  238. source => 'acme-heyu.test',
  239. },
  240. schema=> 'x10.basic',
  241. body =>
  242. [
  243. command => 'bright',
  244. device => 'a10',
  245. ])); }, \*STDOUT),
  246. "queued: 00000003 bright a10\nsending: 00000003 bright a10\n",
  247. 'x10.basic command=bright no level');
  248. is(test_output(
  249. sub {
  250. $plugin->read_helper(
  251. $plugin->{_io},
  252. xPL::IORecord::ZeroSplitLine->new(fields => ['00000001', 0 ]),
  253. xPL::IORecord::ZeroSplitLine->new(fields => ['00000002']),
  254. );
  255. }, \*STDERR),
  256. "Received 00000001: 0 \n",
  257. 'ack with wrong sequence number');
  258. is(test_output(
  259. sub {
  260. $plugin->read_helper(
  261. $plugin->{_io},
  262. xPL::IORecord::ZeroSplitLine->new(fields => ['00000002', 1, "err" ]),
  263. xPL::IORecord::ZeroSplitLine->new(fields => ['00000002']),
  264. );
  265. }, \*STDERR),
  266. "Received 00000002: 1 err\n",
  267. 'ack with non-zero return code');
  268. is(test_output(sub { $plugin->send_xpl('x10.basic', 'a1', 'invalid'); },
  269. \*STDERR),
  270. '', 'no message sent for invalid command');
  271. {
  272. local $0 = 'dingus';
  273. local @ARGV = ('--verbose',
  274. '--heyu-verbose', '--heyu-verbose',
  275. '--define', 'ip=127.0.0.1',
  276. '--define', 'broadcast=127.0.0.1',
  277. '--define', 'hubless=1',
  278. #'--', '-v',
  279. );
  280. no strict;
  281. no warnings;
  282. *IO::Pipe::reader = sub { $@ = '$@'; return 0 };
  283. use warnings;
  284. use strict;
  285. like(test_error(sub { $xpl = xPL::Dock->new(port => 0); }),
  286. qr/xPL::Dock::Heyu->init: 'heyu monitor\|' failed:/,
  287. 'heyu monitor pipe failure');
  288. }
  289. sub check_sent_msg {
  290. my ($expected, $desc) = @_;
  291. my $msg = shift @msg;
  292. while ($msg->[0] && ref $msg->[0] eq 'xPL::Message' &&
  293. $msg->[0]->schema =~ /^hbeat\./) {
  294. $msg = shift @msg; # skip hbeat.* message
  295. }
  296. if (defined $expected) {
  297. my %m = @{$msg};
  298. is_deeply(\%m, $expected, 'message as expected - '.$desc);
  299. } else {
  300. is(scalar @msg, 0, 'message not expected - '.$desc);
  301. }
  302. }