From 84c158f02db265828ae7dbae75e3c11d56f1c18b Mon Sep 17 00:00:00 2001 From: Maxime Besson Date: Tue, 7 Jan 2020 19:07:30 +0100 Subject: [PATCH 1/9] Isolate unit test configuration (#2048) --- lemonldap-ng-portal/t/32-OIDC-Register.t | 5 ++--- lemonldap-ng-portal/t/test-lib.pm | 13 ++++++------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/lemonldap-ng-portal/t/32-OIDC-Register.t b/lemonldap-ng-portal/t/32-OIDC-Register.t index e4825ccc2..2e3a696f9 100644 --- a/lemonldap-ng-portal/t/32-OIDC-Register.t +++ b/lemonldap-ng-portal/t/32-OIDC-Register.t @@ -48,7 +48,7 @@ ok( defined $register_answer->{client_id}, "Client ID found in answer: " . $register_answer->{client_id} ); # New configuration registered -my $confFile = "t/lmConf-2.json"; +my $confFile = "$main::tmpDir/lmConf-2.json"; my $conf = JSON::from_json(`cat $confFile`); # Check saved data @@ -74,8 +74,7 @@ clean_sessions(); done_testing(); sub op { - return LLNG::Manager::Test->new( - { + return LLNG::Manager::Test->new( { ini => { logLevel => $debug, domain => 'idp.com', diff --git a/lemonldap-ng-portal/t/test-lib.pm b/lemonldap-ng-portal/t/test-lib.pm index 04b4482fb..bd291edd8 100644 --- a/lemonldap-ng-portal/t/test-lib.pm +++ b/lemonldap-ng-portal/t/test-lib.pm @@ -76,11 +76,13 @@ $Data::Dumper::Useperl = 1; my $ini; use File::Temp 'tempfile', 'tempdir'; +use File::Copy 'copy'; our $tmpDir = $LLNG::TMPDIR || tempdir( 'tmpSessionXXXXX', DIR => 't/sessions', CLEANUP => 1 ); mkdir "$tmpDir/lock"; mkdir "$tmpDir/saml"; mkdir "$tmpDir/saml/lock"; +copy( "t/lmConf-1.json", "$tmpDir/lmConf-1.json" ); =head4 count($inc) @@ -141,8 +143,7 @@ sub count_sessions { sub getCache { require Cache::FileCache; - return Cache::FileCache->new( - { + return Cache::FileCache->new( { namespace => 'lemonldap-ng-session', cache_root => $tmpDir, cache_depth => 0, @@ -515,7 +516,7 @@ extends 'Lemonldap::NG::Common::PSGI::Cli::Lib'; our $defaultIni = { configStorage => { type => 'File', - dirName => 't', + dirName => "$tmpDir", }, localSessionStorage => 'Cache::FileCache', localSessionStorageOptions => { @@ -705,8 +706,7 @@ to test content I<(to launch a C for example)>. sub _get { my ( $self, $path, %args ) = @_; - my $res = $self->app->( - { + my $res = $self->app->( { 'HTTP_ACCEPT' => $args{accept} || 'application/json, text/plain, */*', 'HTTP_ACCEPT_LANGUAGE' => 'fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3', @@ -758,8 +758,7 @@ sub _post { my ( $self, $path, $body, %args ) = @_; die "$body must be a IO::Handle" unless ( ref($body) and $body->can('read') ); - my $res = $self->app->( - { + my $res = $self->app->( { 'HTTP_ACCEPT' => $args{accept} || 'application/json, text/plain, */*', 'HTTP_ACCEPT_LANGUAGE' => 'fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3', From b65dac6b9541a9cbbeab6d9932aa605945998cf9 Mon Sep 17 00:00:00 2001 From: Christophe Maudoux Date: Mon, 6 Jan 2020 21:34:09 +0100 Subject: [PATCH 2/9] Improve unit test --- lemonldap-ng-portal/t/41-Token.t | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lemonldap-ng-portal/t/41-Token.t b/lemonldap-ng-portal/t/41-Token.t index 0b80ac7e0..bf945fbd1 100644 --- a/lemonldap-ng-portal/t/41-Token.t +++ b/lemonldap-ng-portal/t/41-Token.t @@ -1,6 +1,8 @@ use Test::More; use strict; use IO::String; +use JSON; +use Lemonldap::NG::Portal::Main::Constants 'PE_NOTOKEN'; require 't/test-lib.pm'; @@ -42,6 +44,13 @@ ok( count(1); expectReject($res); +my $json; +ok( $json = eval { from_json( $res->[2]->[0] ) }, 'Response is JSON' ) + or print STDERR "$@\n" . Dumper($res); +ok( $json->{error} == PE_NOTOKEN, 'Response is PE_NOTOKEN' ) + or explain( $json, "error => 81" ); +count(2); + # Try to auth with token $query .= '&user=dwho&password=dwho'; ok( From 94cefa3ef4709de32ae598fef8c5afb3da7bee80 Mon Sep 17 00:00:00 2001 From: Christophe Maudoux Date: Tue, 7 Jan 2020 22:38:08 +0100 Subject: [PATCH 3/9] Typo --- .../lib/Lemonldap/NG/Handler/Main/Reload.pm | 2 +- .../lib/Lemonldap/NG/Portal/CertificateResetByMail/LDAP.pm | 3 +-- .../Lemonldap/NG/Portal/Plugins/CertificateResetByMail.pm | 7 ++++--- .../lib/Lemonldap/NG/Portal/Register/Base.pm | 1 + 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Main/Reload.pm b/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Main/Reload.pm index bb15de248..bc83dc1b9 100644 --- a/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Main/Reload.pm +++ b/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Main/Reload.pm @@ -326,7 +326,7 @@ sub locationRulesInit { ## @imethod protected void sessionStorageInit(hashRef args) # Initialize the Apache::Session::* module choosed to share user's variables -# and the Cache::Cache module choosed to cache sessions +# and the Cache::Cache module chosen to cache sessions # @param $args reference to the configuration hash sub sessionStorageInit { my ( $class, $conf ) = @_; diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/CertificateResetByMail/LDAP.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/CertificateResetByMail/LDAP.pm index 0183a2c82..b52df7b6f 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/CertificateResetByMail/LDAP.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/CertificateResetByMail/LDAP.pm @@ -15,7 +15,7 @@ our $VERSION = '2.0.8'; # PRIVATE METHOD sub modifCertificate { - my ( $self, $newcertif, $usercertif, $req ) = @_; + my ( $self, $req, $newcertif, $usercertif ) = @_; my $ceaAttribute = $self->conf->{certificateResetByMailCeaAttribute} || "description"; my $certificateAttribute = @@ -58,7 +58,6 @@ sub modifCertificate { $self->logger->debug("$ceaAttribute set to $newcertif"); return PE_OK; - } 1; diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/CertificateResetByMail.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/CertificateResetByMail.pm index 1b5e7d081..97cc36a54 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/CertificateResetByMail.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/CertificateResetByMail.pm @@ -394,7 +394,8 @@ sub _certificateReset { # Send mail unless ( $self->send_mail( - $req->data->{mailAddress}, $subject, $body, $html + $req->data->{mailAddress}, + $subject, $body, $html ) ) { @@ -525,8 +526,8 @@ sub modifyCertificate { # Modify ldap certificate attribute $req->user( $req->{sessionInfo}->{_user} ); my $result = - $self->registerModule->modifCertificate( $certificatExactAssertion, - $cert, $req ); + $self->registerModule->modifCertificate( $req, $certificatExactAssertion, + $cert ); $self->{user} = undef; # Mail token can be used only one time, delete the session if all is ok diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Register/Base.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Register/Base.pm index 1aacfe461..8de74fd46 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Register/Base.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Register/Base.pm @@ -32,4 +32,5 @@ sub applyLoginRule { # For now, get first letter of firstname and lastname return substr( $firstname, 0, 1 ) . $lastname; } + 1; From 6b4e1203e5a9f07399e70e6ae1f37d65de629923 Mon Sep 17 00:00:00 2001 From: Christophe Maudoux Date: Wed, 8 Jan 2020 23:05:19 +0100 Subject: [PATCH 4/9] Append logger (#2059) --- .../lib/Lemonldap/NG/Manager/Cli.pm | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Cli.pm b/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Cli.pm index f9c8e52ec..8a18e9577 100644 --- a/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Cli.pm +++ b/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Cli.pm @@ -6,7 +6,7 @@ use Mouse; use Data::Dumper; use Lemonldap::NG::Common::Conf::ReConstants; -our $VERSION = '2.0.6'; +our $VERSION = '2.0.8'; $Data::Dumper::Useperl = 1; extends('Lemonldap::NG::Manager::Cli::Lib'); @@ -21,17 +21,15 @@ has cfgNum => ( } ); -has sep => ( is => 'rw', isa => 'Str', default => '/' ); - -has req => ( is => 'ro' ); - +has log => ( is => 'rw' ); +has req => ( is => 'ro' ); +has sep => ( is => 'rw', isa => 'Str', default => '/' ); has format => ( is => 'rw', isa => 'Str', default => "%-25s | %-25s | %-25s" ); - -has yes => ( is => 'rw', isa => 'Bool', default => 0 ); - -has force => ( is => 'rw', isa => 'Bool', default => 0 ); - -has log => ( is => 'rw' ); +has yes => ( is => 'rw', isa => 'Bool', default => 0 ); +has force => ( is => 'rw', isa => 'Bool', default => 0 ); +has logger => ( is => 'ro', lazy => 1, builder => sub { $_[0]->mgr->logger } ); +has userLogger => + ( is => 'ro', lazy => 1, builder => sub { $_[0]->mgr->userLogger } ); sub get { my ( $self, @keys ) = @_; From d7cee58edf84789cb73752b012cc799a2526b1ad Mon Sep 17 00:00:00 2001 From: Christophe Maudoux Date: Wed, 8 Jan 2020 23:05:43 +0100 Subject: [PATCH 5/9] Improve log --- .../lib/Lemonldap/NG/Handler/Main/Reload.pm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Main/Reload.pm b/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Main/Reload.pm index bc83dc1b9..0d98b1471 100644 --- a/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Main/Reload.pm +++ b/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Main/Reload.pm @@ -1,6 +1,6 @@ package Lemonldap::NG::Handler::Main::Reload; -our $VERSION = '2.0.7'; +our $VERSION = '2.0.8'; package Lemonldap::NG::Handler::Main; @@ -214,7 +214,7 @@ sub defaultValuesInit { # Override with vhost options if ( $conf->{vhostOptions} ) { my $name = 'vhost' . ucfirst($opt); - foreach my $vhost ( keys %{ $conf->{vhostOptions} } ) { + foreach my $vhost ( sort keys %{ $conf->{vhostOptions} } ) { $conf->{vhostOptions}->{$vhost} ||= {}; my $val = $conf->{vhostOptions}->{$vhost}->{$name}; @@ -228,7 +228,7 @@ sub defaultValuesInit { } } if ( $conf->{vhostOptions} ) { - foreach my $vhost ( keys %{ $conf->{vhostOptions} } ) { + foreach my $vhost ( sort keys %{ $conf->{vhostOptions} } ) { $class->tsv->{type}->{$vhost} = $conf->{vhostOptions}->{$vhost}->{vhostType}; $class->tsv->{authnLevel}->{$vhost} = From b28a9d148eae8aaea5e626ae1f4fb6bbaf3b3bb1 Mon Sep 17 00:00:00 2001 From: Christophe Maudoux Date: Wed, 8 Jan 2020 23:06:49 +0100 Subject: [PATCH 6/9] Modify log level --- lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Run.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Run.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Run.pm index 8850b5acf..2e999d1f9 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Run.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Run.pm @@ -64,7 +64,7 @@ sub handler { and $req->{env}->{HTTP_COOKIE} and $req->{env}->{HTTP_COOKIE} =~ /$url64/ ) { - $self->logger->debug("Force cleaning pdata"); + $self->logger->info("Force cleaning pdata"); $self->logger->warn("pdata cookie domain must be set") unless ( $self->conf->{pdataDomain} ); $req->pdata( {} ); From eba6ae01039c95e2f7c20d49cbd4eef2fb33a3c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20OUDOT?= Date: Thu, 9 Jan 2020 18:08:31 +0100 Subject: [PATCH 7/9] Hide action buttons with waiting message (#2064) --- lemonldap-ng-portal/site/templates/bootstrap/standardform.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lemonldap-ng-portal/site/templates/bootstrap/standardform.tpl b/lemonldap-ng-portal/site/templates/bootstrap/standardform.tpl index 00a7d8485..078406562 100644 --- a/lemonldap-ng-portal/site/templates/bootstrap/standardform.tpl +++ b/lemonldap-ng-portal/site/templates/bootstrap/standardform.tpl @@ -36,7 +36,6 @@ Connect -
@@ -60,3 +59,4 @@
+ From bb53c5c42080788feb2b34cc5b08a33e58872b68 Mon Sep 17 00:00:00 2001 From: Christophe Maudoux Date: Thu, 9 Jan 2020 22:22:03 +0100 Subject: [PATCH 8/9] Append log & Improve unit test (#2059) --- .../lib/Lemonldap/NG/Manager/Cli.pm | 18 +++++-- lemonldap-ng-manager/t/16-cli.t | 54 +++++++++++++++---- 2 files changed, 59 insertions(+), 13 deletions(-) diff --git a/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Cli.pm b/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Cli.pm index 8a18e9577..12d429cfe 100644 --- a/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Cli.pm +++ b/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Cli.pm @@ -58,6 +58,7 @@ sub set { die "$key seems to be a hash, modification refused"; } $oldValue //= ''; + $self->logger->info("CLI: Set key $key with $pairs{$key}"); push @list, [ $key, $oldValue, $pairs{$key} ]; } unless ( $self->yes ) { @@ -94,6 +95,7 @@ sub addKey { unless ( $root =~ /$simpleHashKeys$/o or $root =~ /$sep/o ) { die "$root is not a simple hash. Aborting"; } + $self->logger->info("CLI: Append key $root/$newKey $value"); push @list, [ $root, $newKey, $value ]; } require Clone; @@ -134,6 +136,7 @@ sub delKey { unless ( $root =~ /$simpleHashKeys$/o or $root =~ /$sep/o ) { die "$root is not a simple hash. Aborting"; } + $self->logger->info("CLI: Remove key $root/$key"); push @list, [ $root, $key ]; } require Clone; @@ -189,6 +192,7 @@ sub delKey { sub lastCfg { my ($self) = @_; + $self->logger->info("CLI: Retrieve last conf."); return $self->jsonResponse('/confs/latest')->{cfgNum}; } @@ -216,6 +220,7 @@ sub restore { close $f; die "Empty or malformed file $file" unless ( $conf =~ /\w/s ); } + $self->logger->info("CLI: Restore conf."); my $res = $self->_post( '/confs/raw', '', IO::String->new($conf), 'application/json', length($conf) ); use Data::Dumper; @@ -271,29 +276,34 @@ sub _save { } ); unless ( $parser->testNewConf() ) { + $self->logger->error("CLI: Configuration rejected with message: $parser->{message}"); printf STDERR "Modifications rejected: %s:\n", $parser->{message}; } my $saveParams = { force => $self->force }; if ( $self->force and $self->cfgNum ) { + $self->logger->debug("CLI: cfgNum forced with $self->cfgNum()"); $saveParams->{cfgNum} = $self->cfgNum; $saveParams->{cfgNumFixed} = 1; } - $new->{cfgAuthor} = scalar( getpwuid $< ) . '(command-line)'; + $new->{cfgAuthor} = scalar( getpwuid $< ) . '(command-line-interface)'; chomp $new->{cfgAuthor}; $new->{cfgAuthorIP} = '127.0.0.1'; $new->{cfgDate} = time; $new->{cfgVersion} = $Lemonldap::NG::Manager::VERSION; - $new->{cfgLog} = $self->log // 'Modified using LLNG cli'; + $new->{cfgLog} = $self->log // 'Modified with LL::NG CLI'; $new->{key} ||= join( '', map { chr( int( ord( Crypt::URandom::urandom(1) ) * 94 / 256 ) + 33 ) } ( 1 .. 16 ) ); my $s = $self->mgr->confAcc->saveConf( $new, %$saveParams ); if ( $s > 0 ) { + $self->logger->debug("CLI: Configuration $s has been saved by $new->{cfgAuthor}"); + $self->logger->info("CLI: Configuration $s saved"); print STDERR "Saved under number $s\n"; $parser->{status} = [ $self->mgr->applyConf($new) ]; } else { + $self->logger->error("CLI: Configuration not saved!"); printf STDERR "Modifications rejected: %s:\n", $parser->{message}; print STDERR Dumper($parser); } @@ -334,8 +344,9 @@ sub run { my $action = shift; unless ( $action =~ /^(?:get|set|addKey|delKey|save|restore)$/ ) { die -"unknown action $action. Only get, set, addKey or delKey are accepted"; +"Unknown action $action. Only get, set, addKey or delKey allowed"; } + $self->$action(@_); } @@ -344,7 +355,6 @@ package Lemonldap::NG::Manager::Cli::Request; use Mouse; has cfgNum => ( is => 'rw' ); - has error => ( is => 'rw' ); sub params { diff --git a/lemonldap-ng-manager/t/16-cli.t b/lemonldap-ng-manager/t/16-cli.t index c4bb9ad79..a3c33097c 100644 --- a/lemonldap-ng-manager/t/16-cli.t +++ b/lemonldap-ng-manager/t/16-cli.t @@ -1,10 +1,10 @@ -my $tests; - -BEGIN { $tests = 5 } - -use Test::More tests => $tests; +use Test::More; use JSON; use strict; +require 't/test-lib.pm'; + +my $tests = 9; + use_ok('Lemonldap::NG::Common::Cli'); use_ok('Lemonldap::NG::Manager::Cli'); @@ -15,20 +15,56 @@ SKIP: { if ($@) { skip 'Test::Output is missing, skipping', $tests - 2; } - my @cmd; - @cmd = ('save'); my $client = Lemonldap::NG::Manager::Cli->new( iniFile => 't/lemonldap-ng.ini' ); - my $res = Capture::Tiny::capture_stdout( sub { $client->run(@cmd) } ); + my @cmd; + my $res; + + # Test 'set' command + @cmd = qw(-yes 1 set notification 1); + $res = Capture::Tiny::capture_stdout( sub { $client->run(@cmd) } ); + + # Test 'get' command + @cmd = qw(get notification); + $res = Capture::Tiny::capture_stdout( sub { $client->run(@cmd) } ); + ok( $res =~ /^notification\s+=\s+1$/, '"get notification" OK' ) + or diag " $res"; + + # Test 'addKey' command + @cmd = qw(-yes 1 addKey locationRules/test1.example.com ^/reject deny); + Test::Output::combined_like( sub { $client->run(@cmd) }, + qr#'\^/reject' => 'deny'#s, '"addKey" OK' ); + + # Test 'delKey' command + @cmd = qw(-yes 1 delKey locationRules/test1.example.com ^/reject); + Test::Output::combined_unlike( sub { $client->run(@cmd) }, + qr#'\^/reject' => 'deny'#s, '"delKey" OK' ); + + # Test 'get' command + @cmd = qw(get locationRules/test1.example.com); + $res = Capture::Tiny::capture_stdout( sub { $client->run(@cmd) } ); + ok( $res =~ m#(?:/logout|default)#, '"get key/subkey" OK' ) + or diag "$res"; + + # Test 'save' command + @cmd = ('save'); + $res = Capture::Tiny::capture_stdout( sub { $client->run(@cmd) } ); ok( $res =~ /^\s*(\{.*\})\s*$/s, '"save" result looks like JSON' ); eval { JSON::from_json($res) }; ok( not($@), ' result is JSON' ) or diag "error: $@"; + + # Test 'restore' command close STDIN; open STDIN, '<', \$res; @cmd = ( 'restore', '-' ); Test::Output::combined_like( sub { $client->run(@cmd) }, - qr/"cfgNum"\s*:\s*"2"/s, 'New config: 2' ); + qr/"cfgNum"\s*:\s*"3"/s, 'New config: 3' ); + + count($tests); + + done_testing( count() ); } + &cleanConfFiles; sub cleanConfFiles { From 54d21780fea208e7ea95f321e1b9e28ff424454b Mon Sep 17 00:00:00 2001 From: Christophe Maudoux Date: Fri, 10 Jan 2020 09:25:56 +0100 Subject: [PATCH 9/9] Fix TAP plan --- lemonldap-ng-manager/t/16-cli.t | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/lemonldap-ng-manager/t/16-cli.t b/lemonldap-ng-manager/t/16-cli.t index a3c33097c..629a8cbfa 100644 --- a/lemonldap-ng-manager/t/16-cli.t +++ b/lemonldap-ng-manager/t/16-cli.t @@ -5,7 +5,6 @@ require 't/test-lib.pm'; my $tests = 9; - use_ok('Lemonldap::NG::Common::Cli'); use_ok('Lemonldap::NG::Manager::Cli'); &cleanConfFiles; @@ -32,13 +31,19 @@ SKIP: { # Test 'addKey' command @cmd = qw(-yes 1 addKey locationRules/test1.example.com ^/reject deny); - Test::Output::combined_like( sub { $client->run(@cmd) }, - qr#'\^/reject' => 'deny'#s, '"addKey" OK' ); + Test::Output::combined_like( + sub { $client->run(@cmd) }, + qr#'\^/reject' => 'deny'#s, + '"addKey" OK' + ); # Test 'delKey' command @cmd = qw(-yes 1 delKey locationRules/test1.example.com ^/reject); - Test::Output::combined_unlike( sub { $client->run(@cmd) }, - qr#'\^/reject' => 'deny'#s, '"delKey" OK' ); + Test::Output::combined_unlike( + sub { $client->run(@cmd) }, + qr#'\^/reject' => 'deny'#s, + '"delKey" OK' + ); # Test 'get' command @cmd = qw(get locationRules/test1.example.com); @@ -59,12 +64,10 @@ SKIP: { @cmd = ( 'restore', '-' ); Test::Output::combined_like( sub { $client->run(@cmd) }, qr/"cfgNum"\s*:\s*"3"/s, 'New config: 3' ); - - count($tests); - - done_testing( count() ); } +count($tests); +done_testing( count() ); &cleanConfFiles; sub cleanConfFiles {