45_class.t 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. # Net::ZooKeeper - Perl extension for Apache ZooKeeper
  2. #
  3. # Licensed to the Apache Software Foundation (ASF) under one
  4. # or more contributor license agreements. See the NOTICE file
  5. # distributed with this work for additional information
  6. # regarding copyright ownership. The ASF licenses this file
  7. # to you under the Apache License, Version 2.0 (the
  8. # "License"); you may not use this file except in compliance
  9. # with the License. You may obtain a copy of the License at
  10. #
  11. # http://www.apache.org/licenses/LICENSE-2.0
  12. #
  13. # Unless required by applicable law or agreed to in writing, software
  14. # distributed under the License is distributed on an "AS IS" BASIS,
  15. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. # See the License for the specific language governing permissions and
  17. # limitations under the License.
  18. use File::Spec;
  19. use Test::More tests => 47;
  20. BEGIN { use_ok('Net::ZooKeeper', qw(:all)) };
  21. my $test_dir;
  22. (undef, $test_dir, undef) = File::Spec->splitpath($0);
  23. require File::Spec->catfile($test_dir, 'util.pl');
  24. my($hosts, $root_path, $node_path) = zk_test_setup(0);
  25. SKIP: {
  26. my $zkh = Net::ZooKeeper->new($hosts);
  27. skip 'no valid handle', 15 unless (defined($zkh));
  28. my $stat = $zkh->stat();
  29. my $watch = $zkh->watch();
  30. ## DESTROY() on reblessed handle
  31. bless($zkh, 'My::ZooKeeper');
  32. is(ref($zkh), 'My::ZooKeeper',
  33. 'bless(): reblessed handle');
  34. eval {
  35. $zkh->EXISTS();
  36. };
  37. like($@, qr/Can't locate object method "EXISTS" via package "My::ZooKeeper"/,
  38. 'EXISTS(): not defined on reblessed handle');
  39. my $attr = tied(%{$zkh});
  40. my $ret = $attr->DESTROY();
  41. ok($ret,
  42. 'DESTROY(): destroyed inner hash of reblessed handle');
  43. $ret = $attr->DESTROY();
  44. ok(!$ret,
  45. 'DESTROY(): no action on destroyed inner hash of reblessed handle');
  46. undef $zkh;
  47. ok(!defined($zkh),
  48. 'undef: released reblessed handle');
  49. ## DESTROY() on reblessed stat handle
  50. bless($stat, 'My::ZooKeeper::Stat');
  51. is(ref($stat), 'My::ZooKeeper::Stat',
  52. 'bless(): reblessed stat handle');
  53. eval {
  54. $stat->EXISTS(1);
  55. };
  56. like($@, qr/Can't locate object method "EXISTS" via package "My::ZooKeeper::Stat"/,
  57. 'stat EXISTS(): not defined on reblessed stat handle');
  58. $attr = tied(%{$stat});
  59. $ret = $attr->DESTROY();
  60. ok($ret,
  61. 'stat DESTROY(): destroyed inner hash of reblessed stat handle');
  62. $ret = $attr->DESTROY();
  63. ok(!$ret,
  64. 'stat DESTROY(): no action on destroyed inner hash of ' .
  65. 'reblessed stat handle');
  66. undef $stat;
  67. ok(!defined($stat),
  68. 'undef: released reblessed stat handle');
  69. ## DESTROY() on reblessed watch handle
  70. bless($watch, 'My::ZooKeeper::Watch');
  71. is(ref($watch), 'My::ZooKeeper::Watch',
  72. 'bless(): reblessed watch handle');
  73. eval {
  74. $watch->EXISTS(1);
  75. };
  76. like($@, qr/Can't locate object method "EXISTS" via package "My::ZooKeeper::Watch"/,
  77. 'watch EXISTS(): not defined on reblessed watch handle');
  78. $attr = tied(%{$watch});
  79. $ret = $attr->DESTROY();
  80. ok($ret,
  81. 'watch DESTROY(): destroyed inner hash of reblessed watch handle');
  82. $ret = $attr->DESTROY();
  83. ok(!$ret,
  84. 'watch DESTROY(): no action on destroyed inner hash of ' .
  85. 'reblessed watch handle');
  86. undef $watch;
  87. ok(!defined($watch),
  88. 'undef: released reblessed watch handle');
  89. }
  90. SKIP: {
  91. my $zkh = Net::ZooKeeper->new($hosts);
  92. skip 'no valid handle', 9 unless (defined($zkh));
  93. my $stat = $zkh->stat();
  94. my $watch = $zkh->watch();
  95. ## UNTIE() on reblessed handle
  96. bless($zkh, 'My::ZooKeeper');
  97. is(ref($zkh), 'My::ZooKeeper',
  98. 'bless(): reblessed handle');
  99. eval {
  100. untie(%{$zkh});
  101. };
  102. like($@, qr/untying hashes of class Net::ZooKeeper not supported/,
  103. 'untie(): untying hashes from reblessed handle not supported');
  104. my $attr = tied(%{$zkh});
  105. eval {
  106. $attr->UNTIE(0);
  107. };
  108. like($@, qr/untying hashes of class Net::ZooKeeper not supported/,
  109. 'UNTIE(): untying hashes from reblessed handle not supported');
  110. ## UNTIE() on reblessed stat handle
  111. bless($stat, 'My::ZooKeeper::Stat');
  112. is(ref($stat), 'My::ZooKeeper::Stat',
  113. 'bless(): reblessed stat handle');
  114. eval {
  115. untie(%{$stat});
  116. };
  117. like($@, qr/untying hashes of class Net::ZooKeeper::Stat not supported/,
  118. 'untie(): untying hashes from reblessed stat handle not supported');
  119. $attr = tied(%{$stat});
  120. eval {
  121. $attr->UNTIE(0);
  122. };
  123. like($@, qr/untying hashes of class Net::ZooKeeper::Stat not supported/,
  124. 'stat UNTIE(): untying hashes from reblessed stat handle ' .
  125. 'not supported');
  126. ## UNTIE() on reblessed watch handle
  127. bless($watch, 'My::ZooKeeper::Watch');
  128. is(ref($watch), 'My::ZooKeeper::Watch',
  129. 'bless(): reblessed watch handle');
  130. eval {
  131. untie(%{$watch});
  132. };
  133. like($@, qr/untying hashes of class Net::ZooKeeper::Watch not supported/,
  134. 'untie(): untying hashes from reblessed watch handle not supported');
  135. $attr = tied(%{$watch});
  136. eval {
  137. $attr->UNTIE(0);
  138. };
  139. like($@, qr/untying hashes of class Net::ZooKeeper::Watch not supported/,
  140. 'watch UNTIE(): untying hashes from reblessed watch handle ' .
  141. 'not supported');
  142. }
  143. package Net::ZooKeeper::Test;
  144. use Net::ZooKeeper qw(:acls);
  145. our @ISA = qw(Net::ZooKeeper);
  146. sub create
  147. {
  148. my($self, $path, $buf) = @_;
  149. return $self->SUPER::create($path, $buf,
  150. 'path_read_len' => length($path),
  151. 'acl' => ZOO_OPEN_ACL_UNSAFE);
  152. }
  153. sub get_first_child
  154. {
  155. my($self, $path) = @_;
  156. my @child_paths = $self->get_children($path);
  157. if (@child_paths > 0) {
  158. return $path . (($path =~ /\/$/) ? '' : '/') . $child_paths[0];
  159. }
  160. return undef;
  161. }
  162. sub stat
  163. {
  164. my $self = shift;
  165. my $stat = $self->SUPER::stat();
  166. return bless($stat, 'Net::ZooKeeper::Test::Stat');
  167. }
  168. sub watch
  169. {
  170. my $self = shift;
  171. my $watch = $self->SUPER::watch();
  172. return bless($watch, 'Net::ZooKeeper::Test::Watch');
  173. }
  174. package Net::ZooKeeper::Test::Stat;
  175. our @ISA = qw(Net::ZooKeeper::Stat);
  176. sub get_ctime
  177. {
  178. my $self = shift;
  179. return $self->{'ctime'};
  180. }
  181. package Net::ZooKeeper::Test::Watch;
  182. our @ISA = qw(Net::ZooKeeper::Watch);
  183. sub get_timeout
  184. {
  185. my $self = shift;
  186. return $self->{'timeout'};
  187. }
  188. package main;
  189. my $sub_zkh = Net::ZooKeeper::Test->new($hosts);
  190. isa_ok($sub_zkh, 'Net::ZooKeeper::Test',
  191. 'new(): created subclassed handle');
  192. SKIP: {
  193. skip 'no valid subclassed handle', 21 unless (defined($sub_zkh));
  194. is($sub_zkh->{'data_read_len'}, 1023,
  195. 'FETCH(): default data read length using subclassed handle');
  196. my $path;
  197. SKIP: {
  198. my $ret = $sub_zkh->exists($root_path);
  199. skip 'no connection to ZooKeeper', 1 unless
  200. (defined($ret) and $ret);
  201. $path = $sub_zkh->create($node_path, 'foo',
  202. 'acl' => ZOO_OPEN_ACL_UNSAFE);
  203. is($path, $node_path,
  204. 'create(): created node with subclassed handle');
  205. }
  206. SKIP: {
  207. skip 'no connection to ZooKeeper', 1 unless
  208. (defined($path) and $path eq $node_path);
  209. my $child_path = $sub_zkh->get_first_child($root_path);
  210. is($child_path, $node_path,
  211. 'get_first_child(): retrieved first child with subclassed handle');
  212. }
  213. my $sub_stat = $sub_zkh->stat();
  214. isa_ok($sub_stat, 'Net::ZooKeeper::Test::Stat',
  215. 'stat(): created subclassed stat handle');
  216. SKIP: {
  217. skip 'no valid subclassed stat handle', 6 unless
  218. (defined($sub_stat));
  219. is($sub_stat->{'ctime'}, 0,
  220. 'stat FETCH(): default ctime using subclassed stat handle');
  221. SKIP: {
  222. my $ret = $sub_zkh->exists($node_path, 'stat' => $sub_stat) if
  223. (defined($path) and $path eq $node_path);
  224. skip 'no connection to ZooKeeper', 2 unless
  225. (defined($ret) and $ret);
  226. my $ctime = $sub_stat->get_ctime();
  227. ok($ctime > 0,
  228. 'get_ctime(): retrieved ctime with subclassed stat handle');
  229. is($sub_stat->{'ctime'}, $ctime,
  230. 'stat FETCH(): ctime using subclassed stat handle');
  231. }
  232. my $ret = $sub_stat->DESTROY();
  233. ok($ret,
  234. 'stat DESTROY(): destroyed subclassed stat handle');
  235. $ret = $sub_stat->DESTROY();
  236. ok(!$ret,
  237. 'stat DESTROY(): no action on destroyed subclassed stat handle');
  238. undef $sub_stat;
  239. ok(!defined($sub_stat),
  240. 'undef: released subclassed stat handle');
  241. }
  242. my $sub_watch = $sub_zkh->watch();
  243. isa_ok($sub_watch, 'Net::ZooKeeper::Test::Watch',
  244. 'watch(): created subclassed watch handle');
  245. SKIP: {
  246. skip 'no valid subclassed watch handle', 6 unless
  247. (defined($sub_watch));
  248. SKIP: {
  249. my $ret = $sub_zkh->exists($root_path, 'watch' => $sub_watch);
  250. skip 'no connection to ZooKeeper', 3 unless
  251. (defined($ret) and $ret);
  252. $sub_watch->{'timeout'} = 50;
  253. is($sub_watch->get_timeout(), 50,
  254. 'get_timeout(): retrieved timeout with subclassed ' .
  255. 'watch handle');
  256. is($sub_watch->{'timeout'}, 50,
  257. 'watch FETCH(): timeout using subclassed stat handle');
  258. $ret = $sub_watch->wait();
  259. ok(!$ret,
  260. 'wait(): watch after checking node existence timed out with ' .
  261. 'subclassed watch handle');
  262. }
  263. my $ret = $sub_watch->DESTROY();
  264. ok($ret,
  265. 'watch DESTROY(): destroyed subclassed watch handle');
  266. $ret = $sub_watch->DESTROY();
  267. ok(!$ret,
  268. 'watch DESTROY(): no action on destroyed subclassed watch handle');
  269. undef $sub_watch;
  270. ok(!defined($sub_watch),
  271. 'undef: released subclassed watch handle');
  272. }
  273. SKIP: {
  274. skip 'no connection to ZooKeeper', 1 unless
  275. (defined($path) and $path eq $node_path);
  276. my $ret = $sub_zkh->delete($node_path);
  277. ok($ret,
  278. 'delete(): deleted node with subclassed handle');
  279. }
  280. my $ret = $sub_zkh->DESTROY();
  281. ok($ret,
  282. 'DESTROY(): destroyed subclassed handle');
  283. $ret = $sub_zkh->DESTROY();
  284. ok(!$ret,
  285. 'DESTROY(): no action on destroyed subclassed handle');
  286. undef $sub_zkh;
  287. ok(!defined($sub_zkh),
  288. 'undef: released subclassed handle');
  289. }