| # Net::ZooKeeper - Perl extension for Apache ZooKeeper |
| # |
| # Licensed to the Apache Software Foundation (ASF) under one |
| # or more contributor license agreements. See the NOTICE file |
| # distributed with this work for additional information |
| # regarding copyright ownership. The ASF licenses this file |
| # to you under the Apache License, Version 2.0 (the |
| # "License"); you may not use this file except in compliance |
| # with the License. You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| |
| use File::Spec; |
| use Test::More tests => 66; |
| |
| BEGIN { use_ok('Net::ZooKeeper', qw(:all)) }; |
| |
| |
| my $test_dir; |
| (undef, $test_dir, undef) = File::Spec->splitpath($0); |
| require File::Spec->catfile($test_dir, 'util.pl'); |
| |
| my($hosts, $root_path, $node_path) = zk_test_setup(0); |
| |
| |
| SKIP: { |
| my $zkh = Net::ZooKeeper->new($hosts); |
| my $stat = $zkh->stat() if (defined($zkh)); |
| |
| skip 'no valid stat handle', 4 unless (defined($stat)); |
| |
| |
| ## DESTROY() |
| |
| my $attr = tied(%{$stat}); |
| |
| my $ret = $attr->DESTROY(); |
| ok($ret, |
| 'stat DESTROY(): destroyed inner stat hash'); |
| |
| $ret = $attr->DESTROY(); |
| ok(!$ret, |
| 'stat DESTROY(): no action on destroyed inner stat hash'); |
| |
| $ret = $stat->DESTROY(); |
| ok(!$ret, |
| 'stat DESTROY(): no action on stat handle with destroyed inner hash'); |
| |
| undef $stat; |
| ok(!defined($stat), |
| 'undef: released stat handle with destroyed inner hash'); |
| } |
| |
| SKIP: { |
| my $zkh = Net::ZooKeeper->new($hosts); |
| my $stat = $zkh->stat() if (defined($zkh)); |
| |
| skip 'no valid stat handle', 61 unless (defined($stat)); |
| |
| |
| ## TIEHASH(), UNTIE() |
| |
| eval { |
| tie(%{$stat}, 'Net::ZooKeeper::Stat'); |
| }; |
| like($@, qr/tying hashes of class Net::ZooKeeper::Stat not supported/, |
| 'tie(): tying stat hashes not supported'); |
| |
| eval { |
| Net::ZooKeeper::Stat::TIEHASH('Net::ZooKeeper::Stat'); |
| }; |
| like($@, qr/tying hashes of class Net::ZooKeeper::Stat not supported/, |
| 'stat TIEHASH(): tying stat hashes not supported'); |
| |
| eval { |
| untie(%{$stat}); |
| }; |
| like($@, qr/untying hashes of class Net::ZooKeeper::Stat not supported/, |
| 'untie(): untying stat hashes not supported'); |
| |
| my $attr = tied(%{$stat}); |
| |
| eval { |
| $attr->UNTIE(0); |
| }; |
| like($@, qr/untying hashes of class Net::ZooKeeper::Stat not supported/, |
| 'stat UNTIE(): untying stat hashes not supported'); |
| |
| |
| ## FIRSTKEY(), NEXTKEY(), SCALAR() |
| |
| my $copy_stat; |
| { |
| my %copy_stat = %{$stat}; |
| $copy_stat = \%copy_stat; |
| } |
| bless($copy_stat, 'Net::ZooKeeper::Stat'); |
| is(ref($copy_stat), 'Net::ZooKeeper::Stat', |
| 'stat FIRSTKEY(), NEXTKEY(): copied dereferenced stat handle'); |
| |
| eval { |
| my $val = $copy_stat->FIRSTKEY(); |
| }; |
| like($@, qr/invalid handle/, |
| 'stat FETCHKEY(): invalid stat handle'); |
| |
| eval { |
| my $val = $copy_stat->NEXTKEY('czxid'); |
| }; |
| like($@, qr/invalid handle/, |
| 'stat NEXTKEY(): invalid stat handle'); |
| |
| my @keys = keys(%{$stat}); |
| is(scalar(@keys), 11, |
| 'keys(): count of keys from stat handle'); |
| |
| @keys = keys(%{$copy_stat}); |
| is(scalar(@keys), 11, |
| 'keys(): count of keys from copied dereferenced stat handle'); |
| |
| is($attr->FIRSTKEY(), 'czxid', |
| 'stat FIRSTKEY(): retrieved first key using inner stat hash'); |
| |
| is($attr->NEXTKEY('num_children'), 'children_zxid', |
| 'stat NEXTKEY(): retrieved last key using inner stat hash'); |
| |
| is($attr->NEXTKEY('children_zxid'), undef, |
| 'NEXTKEY(): undef returned after last key using inner stat hash'); |
| |
| ok(scalar(%{$stat}), |
| 'scalar(): true value returned for dereferenced stat handle'); |
| |
| ok($stat->SCALAR(), |
| 'stat SCALAR(): true value returned'); |
| |
| |
| ## FETCH() |
| |
| eval { |
| my $val = $copy_stat->FETCH('version'); |
| }; |
| like($@, qr/invalid handle/, |
| 'stat FETCH(): invalid stat handle'); |
| |
| { |
| my $msg; |
| |
| $SIG{'__WARN__'} = sub { $msg = $_[0]; }; |
| |
| my $val = $stat->{'foo'}; |
| ok(!defined($val), |
| 'stat FETCH(): undef returned for invalid element'); |
| |
| like($msg, qr/invalid element/, |
| 'stat FETCH(): invalid element'); |
| } |
| |
| is($stat->{'czxid'}, 0, |
| 'stat FETCH(): default node creation ZooKeeper transaction ID'); |
| |
| is($stat->{'mzxid'}, 0, |
| 'stat FETCH(): default data last-modified ZooKeeper transaction ID'); |
| |
| is($stat->{'ctime'}, 0, |
| 'stat FETCH(): default node creation time'); |
| |
| is($stat->{'mtime'}, 0, |
| 'stat FETCH(): default data last-modified time'); |
| |
| is($stat->{'version'}, 0, |
| 'stat FETCH(): default data version'); |
| |
| is($stat->{'children_version'}, 0, |
| 'stat FETCH(): default child node list version'); |
| |
| is($stat->{'acl_version'}, 0, |
| 'stat FETCH(): default ACL version'); |
| |
| is($stat->{'ephemeral_owner'}, 0, |
| 'stat FETCH(): ephemeral node owner session ID'); |
| |
| is($stat->{'data_len'}, 0, |
| 'stat FETCH(): default data length'); |
| |
| is($stat->{'num_children'}, 0, |
| 'stat FETCH(): default child node list length'); |
| |
| is($stat->{'children_zxid'}, 0, |
| 'stat FETCH(): default child node list last-modified ' . |
| 'ZooKeeper transaction ID'); |
| |
| is($attr->FETCH('version'), 0, |
| 'stat FETCH(): default data version using inner stat hash'); |
| |
| |
| ## STORE() |
| |
| eval { |
| my $val = $copy_stat->STORE('version', 'foo'); |
| }; |
| like($@, qr/invalid handle/, |
| 'stat STORE(): invalid stat handle'); |
| |
| { |
| my $msg; |
| |
| $SIG{'__WARN__'} = sub { $msg = $_[0]; }; |
| |
| $stat->{'foo'} = 'foo'; |
| like($msg, qr/invalid element/, |
| 'stat STORE(): invalid element'); |
| } |
| |
| { |
| my $msg; |
| |
| $SIG{'__WARN__'} = sub { $msg = $_[0]; }; |
| |
| $stat->{'czxid'} = 'foo'; |
| like($msg, qr/read-only element: czxid/, |
| 'stat STORE(): read-only node creation ' . |
| 'ZooKeeper transaction ID element'); |
| } |
| |
| { |
| my $msg; |
| |
| $SIG{'__WARN__'} = sub { $msg = $_[0]; }; |
| |
| $stat->{'mzxid'} = 'foo'; |
| like($msg, qr/read-only element: mzxid/, |
| 'stat STORE(): read-only data last-modified ' . |
| 'ZooKeeper transaction ID element'); |
| } |
| |
| { |
| my $msg; |
| |
| $SIG{'__WARN__'} = sub { $msg = $_[0]; }; |
| |
| $stat->{'ctime'} = 'foo'; |
| like($msg, qr/read-only element: ctime/, |
| 'stat STORE(): read-only node creation time element'); |
| } |
| |
| { |
| my $msg; |
| |
| $SIG{'__WARN__'} = sub { $msg = $_[0]; }; |
| |
| $stat->{'mtime'} = 'foo'; |
| like($msg, qr/read-only element: mtime/, |
| 'stat STORE(): read-only data last-modified time element'); |
| } |
| |
| { |
| my $msg; |
| |
| $SIG{'__WARN__'} = sub { $msg = $_[0]; }; |
| |
| $stat->{'version'} = 'foo'; |
| like($msg, qr/read-only element: version/, |
| 'stat STORE(): read-only data version element'); |
| } |
| |
| { |
| my $msg; |
| |
| $SIG{'__WARN__'} = sub { $msg = $_[0]; }; |
| |
| $stat->{'children_version'} = 'foo'; |
| like($msg, qr/read-only element: children_version/, |
| 'stat STORE(): read-only child node list version element'); |
| } |
| |
| { |
| my $msg; |
| |
| $SIG{'__WARN__'} = sub { $msg = $_[0]; }; |
| |
| $stat->{'acl_version'} = 'foo'; |
| like($msg, qr/read-only element: acl_version/, |
| 'stat STORE(): read-only ACL version element'); |
| } |
| |
| { |
| my $msg; |
| |
| $SIG{'__WARN__'} = sub { $msg = $_[0]; }; |
| |
| $stat->{'ephemeral_owner'} = 'foo'; |
| like($msg, qr/read-only element: ephemeral_owner/, |
| 'stat STORE(): read-only ephemeral node owner ' . |
| 'session ID element'); |
| } |
| |
| { |
| my $msg; |
| |
| $SIG{'__WARN__'} = sub { $msg = $_[0]; }; |
| |
| $stat->{'data_len'} = 'foo'; |
| like($msg, qr/read-only element: data_len/, |
| 'stat STORE(): read-only data length element'); |
| } |
| |
| { |
| my $msg; |
| |
| $SIG{'__WARN__'} = sub { $msg = $_[0]; }; |
| |
| $stat->{'num_children'} = 'foo'; |
| like($msg, qr/read-only element: num_children/, |
| 'stat STORE(): read-only child node list length element'); |
| } |
| |
| { |
| my $msg; |
| |
| $SIG{'__WARN__'} = sub { $msg = $_[0]; }; |
| |
| $stat->{'children_zxid'} = 'foo'; |
| like($msg, qr/read-only element: children_zxid/, |
| 'stat STORE(): read-only child node list last-modified ' . |
| 'ZooKeeper transaction ID element'); |
| } |
| |
| { |
| my $msg; |
| |
| $SIG{'__WARN__'} = sub { $msg = $_[0]; }; |
| |
| $attr->STORE('version', 'foo'); |
| like($msg, qr/read-only element: version/, |
| 'stat STORE(): read-only data version element using ' . |
| 'inner stat hash'); |
| } |
| |
| |
| ## EXISTS() |
| |
| eval { |
| my $val = $copy_stat->EXISTS('version'); |
| }; |
| like($@, qr/invalid handle/, |
| 'stat EXISTS(): invalid stat handle'); |
| |
| ok(!exists($stat->{'foo'}), |
| 'exists(): invalid element of stat handle'); |
| |
| ok(exists($stat->{'czxid'}), |
| 'exists(): node creation ZooKeeper transaction ID'); |
| |
| ok(exists($stat->{'mzxid'}), |
| 'exists(): data last-modified ZooKeeper transaction ID'); |
| |
| ok(exists($stat->{'ctime'}), |
| 'exists(): node creation time'); |
| |
| ok(exists($stat->{'mtime'}), |
| 'exists(): data last-modified time'); |
| |
| ok(exists($stat->{'version'}), |
| 'exists(): data version'); |
| |
| ok(exists($stat->{'children_version'}), |
| 'exists(): child node list version'); |
| |
| ok(exists($stat->{'acl_version'}), |
| 'exists(): ACL version'); |
| |
| ok(exists($stat->{'ephemeral_owner'}), |
| 'exists(): ephemeral node owner session ID'); |
| |
| ok(exists($stat->{'data_len'}), |
| 'exists(): data length'); |
| |
| ok(exists($stat->{'num_children'}), |
| 'exists(): child node list length'); |
| |
| ok(exists($stat->{'children_zxid'}), |
| 'exists(): child node list last-modified ZooKeeper transaction ID'); |
| |
| ok($attr->EXISTS('version'), |
| 'stat EXISTS(): data version using inner stat hash'); |
| |
| |
| ## DELETE(), CLEAR() |
| |
| { |
| my $msg; |
| |
| $SIG{'__WARN__'} = sub { $msg = $_[0]; }; |
| |
| delete($stat->{'version'}); |
| like($msg, |
| qr/deleting elements from hashes of class Net::ZooKeeper::Stat not supported/, |
| 'delete(): deleting stat hash elements not supported'); |
| } |
| |
| { |
| my $msg; |
| |
| $SIG{'__WARN__'} = sub { $msg = $_[0]; }; |
| |
| $stat->DELETE({'version'}); |
| like($msg, |
| qr/deleting elements from hashes of class Net::ZooKeeper::Stat not supported/, |
| 'stat DELETE(): deleting stat hash elements not supported'); |
| } |
| |
| { |
| my $msg; |
| |
| $SIG{'__WARN__'} = sub { $msg = $_[0]; }; |
| |
| %{$stat} = (); |
| like($msg, qr/clearing hashes of class Net::ZooKeeper::Stat not supported/, |
| 'assign: clearing stat hashes not supported'); |
| } |
| |
| { |
| my $msg; |
| |
| $SIG{'__WARN__'} = sub { $msg = $_[0]; }; |
| |
| $stat->CLEAR(); |
| like($msg, qr/clearing hashes of class Net::ZooKeeper::Stat not supported/, |
| 'stat CLEAR(): clearing stat hashes not supported'); |
| } |
| } |
| |