pf-tools/pf-tools: 6 new changesets

parmelan-guest at users.alioth.debian.org parmelan-guest at users.alioth.debian.org
Mon Sep 20 15:26:48 UTC 2010


details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/ad5d41a3b390
changeset: 792:ad5d41a3b390
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Mon Sep 20 08:44:47 2010 +0200
description:
More robust Get_source(), more tests for __Get_config_path()

* Get_source() uses two configuration parameters from $pf_config, it now checks
  that these exists before using them.

* __Get_config_path() now gets tested against a site-specific file, then a
  global configuration file.

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/1c3539b7571d
changeset: 793:1c3539b7571d
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Mon Sep 20 11:47:19 2010 +0200
description:
Typo (s/CONFIG:/CONF:/) in __Get_config_path()

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/91b422e19b46
changeset: 794:91b422e19b46
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Mon Sep 20 14:44:03 2010 +0200
description:
Fix __Get_config_path() tests, too (s/CONFIG:/CONF:/)

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/d68a60dfe9a9
changeset: 795:d68a60dfe9a9
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Mon Sep 20 14:44:13 2010 +0200
description:
Clean-up after the tests.

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/39c7efe68f59
changeset: 796:39c7efe68f59
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Mon Sep 20 14:52:32 2010 +0200
description:
Fix documentation for Flush2disk_GLOBAL() and Retrieve_GLOBAL()

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/06e6ff6d8686
changeset: 797:06e6ff6d8686
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Mon Sep 20 14:55:48 2010 +0200
description:
Regroup internal (not exported) functions together at the end

diffstat:

1 file changed, 2 insertions(+)
t/13.conf.t |    2 ++

diffs (697 lines):

diff -r 6d007d250b23 -r 06e6ff6d8686 lib/PFTools/Conf.pm
--- a/lib/PFTools/Conf.pm	Mon Sep 20 17:08:34 2010 +0200
+++ b/lib/PFTools/Conf.pm	Mon Sep 20 14:55:48 2010 +0200
@@ -64,7 +64,7 @@
 
 =head1 INTERFACE
 
-This modules defines the following variables and functions:
+This module defines the following variables and functions:
 
 =head2 $PF_CONFIG
 
@@ -288,8 +288,9 @@
     }
 
     my $vcs_work_dir = $pf_config->{'path'}->{'checkout_dir'}
-        || q{};    # FIXME croak?
-    my $module = $pf_config->{'vcs'}->{'module'} || q{};    # FIXME croak?
+        or croak q{ERROR: Undefined configuration parameter: path.checkout_dir};
+    my $module = $pf_config->{'vcs'}->{'module'}
+        or croak q{ERROR: Undefined configuration parameter: vcs.module};
 
     my $result = $source;
 
@@ -317,6 +318,276 @@
     return $result;
 }
 
+sub Load_conf {
+    my ( $file, $hash_subst, $context, $pf_config ) = @_;
+
+    return unless $file and $hash_subst and $context and $pf_config;
+
+    if ( $context !~ m/^$ALLOWED_PARSING_CONTEXT$/ ) {
+        Abort(
+            $CODE->{'INVALID_CONTEXT'},
+            "Context $context for file $file doesn't match $ALLOWED_PARSING_CONTEXT"
+        );
+    }
+
+    my $parsed = Parser_ini($file);
+
+    if ( $context =~ /^(model|host)$/ ) {
+        if ( defined $parsed->{'hostgroup'}->{'model'} ) {
+            $parsed->{'hostgroup'}->{'__model'} = Load_conf(
+                Get_source(
+                    $parsed->{'hostgroup'}->{'model'},
+                    "", $hash_subst, $pf_config
+                ),
+                $hash_subst,
+                'model',
+                $pf_config
+            );
+        }
+    }
+    else {
+        my $select = ( $context eq 'config' ) ? 'action' : 'type';
+        foreach my $section ( keys %{$parsed} ) {
+            next if ( $section =~ /^__/ );
+            if ( !defined $parsed->{$section}->{$select} ) {
+                Abort(
+                    $CODE->{'UNDEF_KEY'},
+                    "Key $select on section $section from file $file MUST BE defined"
+                );
+            }
+            my $sect_type = $parsed->{$section}->{$select};
+            if ( $sect_type eq 'include' ) {
+
+                # We need to dive into deep ...
+                $parsed->{$section}->{'__content'}
+                    = Load_conf(
+                    Get_source( $section, "", $hash_subst, $pf_config ),
+                    $hash_subst, $context, $pf_config
+                    );
+            }
+        }
+    }
+
+    # Merging if needed
+    $parsed = __Merge_conf_includes( $parsed, $hash_subst, $context );
+
+    # Basic checks
+    foreach my $section ( keys %{$parsed} ) {
+        next if $section =~ /^__/;
+        my $sect_type;
+        if ( $context =~ /^(host|model)$/ ) {
+            $section =~ /^([^:]+)(::(.+))?$/;
+            $sect_type = $1;
+
+            # $iface_name = $3;
+        }
+        else {
+            my $select = ( $context eq 'config' ) ? 'action' : 'type';
+            if ( !defined $parsed->{$section}->{$select} ) {
+                Abort(
+                    $CODE->{'UNDEF_KEY'},
+                    "Key  $select on section $section from file $file MUST BE defined"
+                );
+            }
+            $sect_type = $parsed->{$section}->{$select};
+        }
+        my ( $code, $msg )
+            = Chk_section_struct(
+            $section, $sect_type, $parsed->{$section},
+            $context
+            );
+        if ( $code > 1 ) {
+            Warn(
+                $code,
+                "Errors occur during parsing model from file $file"
+            );
+            Abort( $code, $msg );
+        }
+    }
+
+    return $parsed;
+}
+
+sub Init_GLOBAL_NETCONFIG {
+    my ( $start_file, $hash_subst, $pf_config ) = @_;
+
+    return unless $start_file and $hash_subst;
+
+    if ( !defined $pf_config ) {
+        $pf_config = $PF_CONFIG;
+    }
+
+    my $GLOBAL = { 'SITE' => { 'BY_NAME' => {}, } };
+    foreach my $ip_type ( 'ipv4', 'ipv6' ) {
+        next if !$pf_config->{'features'}->{$ip_type};
+        my $zone_key = ( $ip_type eq 'ipv6' ) ? 'ZONE6' : 'ZONE';
+        my $dhcp_key = ( $ip_type eq 'ipv6' ) ? 'DHCP6' : 'DHCP';
+        $GLOBAL->{$zone_key} = {
+            'BY_NAME' => {},
+            'BY_SITE' => {}
+        };
+        $GLOBAL->{$dhcp_key} = { 'BY_SITE' => {} };
+    }
+
+    my $net_parsed
+        = Load_conf( $start_file, $hash_subst, 'network', $pf_config );
+    my @sortnetkeys = sort { __Sort_net_section( $net_parsed, $a, $b ) }
+        @{ $net_parsed->{'__sections_order'} };
+    foreach my $section (@sortnetkeys) {
+        if ( $net_parsed->{$section}->{'type'} eq 'zone' ) {
+            Add_zone(
+                $start_file, $section, $net_parsed->{$section},
+                $GLOBAL, $pf_config
+            );
+        }
+        elsif ( $net_parsed->{$section}->{'type'} eq 'site' ) {
+            Add_site(
+                $start_file, $section, $net_parsed->{$section},
+                $GLOBAL, $pf_config
+            );
+        }
+        elsif ( $net_parsed->{$section}->{'type'} eq 'network' ) {
+            Add_network(
+                $start_file, $section, $net_parsed->{$section},
+                $GLOBAL, $pf_config
+            );
+        }
+        elsif ( $net_parsed->{$section}->{'type'} eq 'server' ) {
+            my $convert = Build_host_from_server(
+                $section,
+                $net_parsed->{$section}
+            );
+            Add_host(
+                $start_file, 'server', $convert,
+                $GLOBAL, $pf_config
+            );
+        }
+        elsif ( $net_parsed->{$section}->{'type'} eq 'service' ) {
+            my $site_list = Get_site_list( $net_parsed->{$section}, $GLOBAL );
+            foreach my $site ( @{$site_list} ) {
+                my $service_part
+                    = $GLOBAL->{'SITE'}->{'BY_NAME'}->{$site}->{'SERVICE'}
+                    ->{'BY_NAME'};
+                foreach my $host ( @{ $net_parsed->{$section}->{'@host'} } ) {
+                    my $hostfile
+                        = Get_source( $host, "", $hash_subst, $pf_config );
+                    my $host_parsed
+                        = Load_conf(
+                        $hostfile, $hash_subst, 'host',
+                        $pf_config
+                        );
+                    Add_host(
+                        $hostfile, 'host', $host_parsed,
+                        $GLOBAL, $pf_config
+                    );
+                    push @{ $service_part->{$section} }, $host;
+                }
+            }
+        }
+    }
+
+    return $GLOBAL;
+}
+
+=head2 Flush2disk_GLOBAL( $global_config, $pf_config, $flush_file )
+
+Stores $global_config on disk in $flush_file (defaults to
+$pf_config->{'path'}->{'global_struct'}).
+
+Returns a true value on success.
+
+=cut
+
+sub Flush2disk_GLOBAL {
+    my ( $global_config, $pf_config, $flush_file ) = @_;
+
+    return unless $global_config and $pf_config;
+
+    $flush_file ||= $pf_config->{'path'}->{'global_struct'};
+
+    my $ret = eval { store( $global_config, $flush_file ); };
+    if ($EVAL_ERROR) {
+        croak "ERROR: $EVAL_ERROR";
+    }
+    if ( !$ret ) {
+        croak "ERROR: unable to flush global structure to $flush_file";
+    }
+
+    return 1;
+}
+
+=head2 Retrieve_GLOBAL($path_global_file)
+
+Retrieves from $path_global_file and returns the stored $global_config.
+
+=cut
+
+sub Retrieve_GLOBAL {
+    my ($path_global_file) = @_;
+
+    return unless $path_global_file;
+
+    my $ret = eval { retrieve($path_global_file); };
+    if ($EVAL_ERROR) {
+        croak "ERROR: $EVAL_ERROR";
+    }
+    if ( !$ret ) {
+        croak
+            "ERROR: unable to retrieve global structure from $path_global_file";
+    }
+
+    return $ret;
+}
+
+sub Get_config_for_hostname_on_site {
+    my ( $hostname, $site, $hash_subst, $global_config, $pf_config ) = @_;
+
+    # Common configuration file e.g. update-common
+    my $global_host_conf = Load_conf(
+        Get_source(
+            'COMMON:/' . $pf_config->{'path'}->{'common_config'},
+            $hostname, $hash_subst, $pf_config
+        ),
+        $hash_subst,
+        'config',
+        $pf_config
+    );
+    my $hosttype
+        = Get_hosttype_from_hostname( $hostname, $global_config, $site );
+    if ( !defined $hosttype ) {
+        Abort(
+            $CODE->{'UNDEF_KEY'},
+            "Unable to get hosttype from hostname $hostname for getting hosttype configuration file"
+        );
+    }
+
+    # Hosttype configuration file e.g. update-<hosttype>
+    my $hosttype_conf_file
+        = __Get_config_path( $hosttype, $pf_config, $site );
+
+    # Hostname configuration file e.g. update-<hostname>
+    my $hostname_conf_file
+        = __Get_config_path( $hostname, $pf_config, $site );
+
+    foreach my $file ( $hosttype_conf_file, $hostname_conf_file ) {
+        next if !defined $file;
+        my $config = Load_conf( $file, $hash_subst, 'config', $pf_config );
+        foreach my $section ( @{ $config->{'__sections_order'} } ) {
+            push @{ $global_host_conf->{'__sections_order'} }, $section
+                if !defined $global_host_conf->{$section};
+            $global_host_conf->{$section} = $config->{$section};
+        }
+    }
+
+    return $global_host_conf;
+}
+
+=head1 INTERNAL INTERFACE
+
+This module defines the following internal (not exported) variables and functions:
+
+=cut
+
 =head2 __Get_config_path( $host_value, $pf_config, $site ) -- NOT EXPORTED
 
 Given a host value (host name or host type) and a site, returns the path to the
@@ -341,7 +612,7 @@
 
     my @sources = (
         "CONFSITE_${site}:/update-${host_value}",
-        "CONFIG:/update-${host_value}",
+        "CONF:/update-${host_value}",
     );
 
     foreach my $source (@sources) {
@@ -448,96 +719,6 @@
     return $global_parsed;
 }
 
-sub Load_conf {
-    my ( $file, $hash_subst, $context, $pf_config ) = @_;
-
-    return unless $file and $hash_subst and $context and $pf_config;
-
-    if ( $context !~ m/^$ALLOWED_PARSING_CONTEXT$/ ) {
-        Abort(
-            $CODE->{'INVALID_CONTEXT'},
-            "Context $context for file $file doesn't match $ALLOWED_PARSING_CONTEXT"
-        );
-    }
-
-    my $parsed = Parser_ini($file);
-
-    if ( $context =~ /^(model|host)$/ ) {
-        if ( defined $parsed->{'hostgroup'}->{'model'} ) {
-            $parsed->{'hostgroup'}->{'__model'} = Load_conf(
-                Get_source(
-                    $parsed->{'hostgroup'}->{'model'},
-                    "", $hash_subst, $pf_config
-                ),
-                $hash_subst,
-                'model',
-                $pf_config
-            );
-        }
-    }
-    else {
-        my $select = ( $context eq 'config' ) ? 'action' : 'type';
-        foreach my $section ( keys %{$parsed} ) {
-            next if ( $section =~ /^__/ );
-            if ( !defined $parsed->{$section}->{$select} ) {
-                Abort(
-                    $CODE->{'UNDEF_KEY'},
-                    "Key $select on section $section from file $file MUST BE defined"
-                );
-            }
-            my $sect_type = $parsed->{$section}->{$select};
-            if ( $sect_type eq 'include' ) {
-
-                # We need to dive into deep ...
-                $parsed->{$section}->{'__content'}
-                    = Load_conf(
-                    Get_source( $section, "", $hash_subst, $pf_config ),
-                    $hash_subst, $context, $pf_config
-                    );
-            }
-        }
-    }
-
-    # Merging if needed
-    $parsed = __Merge_conf_includes( $parsed, $hash_subst, $context );
-
-    # Basic checks
-    foreach my $section ( keys %{$parsed} ) {
-        next if $section =~ /^__/;
-        my $sect_type;
-        if ( $context =~ /^(host|model)$/ ) {
-            $section =~ /^([^:]+)(::(.+))?$/;
-            $sect_type = $1;
-
-            # $iface_name = $3;
-        }
-        else {
-            my $select = ( $context eq 'config' ) ? 'action' : 'type';
-            if ( !defined $parsed->{$section}->{$select} ) {
-                Abort(
-                    $CODE->{'UNDEF_KEY'},
-                    "Key  $select on section $section from file $file MUST BE defined"
-                );
-            }
-            $sect_type = $parsed->{$section}->{$select};
-        }
-        my ( $code, $msg )
-            = Chk_section_struct(
-            $section, $sect_type, $parsed->{$section},
-            $context
-            );
-        if ( $code > 1 ) {
-            Warn(
-                $code,
-                "Errors occur during parsing model from file $file"
-            );
-            Abort( $code, $msg );
-        }
-    }
-
-    return $parsed;
-}
-
 =head2 __Sort_net_section( $net, $a, $b )
 
 This function is used to sort the network configuration sections by section
@@ -565,167 +746,5 @@
     return $net_prio_for{$a_type} <=> $net_prio_for{$b_type};
 }
 
-sub Init_GLOBAL_NETCONFIG {
-    my ( $start_file, $hash_subst, $pf_config ) = @_;
-
-    return unless $start_file and $hash_subst;
-
-    if ( !defined $pf_config ) {
-        $pf_config = $PF_CONFIG;
-    }
-
-    my $GLOBAL = { 'SITE' => { 'BY_NAME' => {}, } };
-    foreach my $ip_type ( 'ipv4', 'ipv6' ) {
-        next if !$pf_config->{'features'}->{$ip_type};
-        my $zone_key = ( $ip_type eq 'ipv6' ) ? 'ZONE6' : 'ZONE';
-        my $dhcp_key = ( $ip_type eq 'ipv6' ) ? 'DHCP6' : 'DHCP';
-        $GLOBAL->{$zone_key} = {
-            'BY_NAME' => {},
-            'BY_SITE' => {}
-        };
-        $GLOBAL->{$dhcp_key} = { 'BY_SITE' => {} };
-    }
-
-    my $net_parsed
-        = Load_conf( $start_file, $hash_subst, 'network', $pf_config );
-    my @sortnetkeys = sort { __Sort_net_section( $net_parsed, $a, $b ) }
-        @{ $net_parsed->{'__sections_order'} };
-    foreach my $section (@sortnetkeys) {
-        if ( $net_parsed->{$section}->{'type'} eq 'zone' ) {
-            Add_zone(
-                $start_file, $section, $net_parsed->{$section},
-                $GLOBAL, $pf_config
-            );
-        }
-        elsif ( $net_parsed->{$section}->{'type'} eq 'site' ) {
-            Add_site(
-                $start_file, $section, $net_parsed->{$section},
-                $GLOBAL, $pf_config
-            );
-        }
-        elsif ( $net_parsed->{$section}->{'type'} eq 'network' ) {
-            Add_network(
-                $start_file, $section, $net_parsed->{$section},
-                $GLOBAL, $pf_config
-            );
-        }
-        elsif ( $net_parsed->{$section}->{'type'} eq 'server' ) {
-            my $convert = Build_host_from_server(
-                $section,
-                $net_parsed->{$section}
-            );
-            Add_host(
-                $start_file, 'server', $convert,
-                $GLOBAL, $pf_config
-            );
-        }
-        elsif ( $net_parsed->{$section}->{'type'} eq 'service' ) {
-            my $site_list = Get_site_list( $net_parsed->{$section}, $GLOBAL );
-            foreach my $site ( @{$site_list} ) {
-                my $service_part
-                    = $GLOBAL->{'SITE'}->{'BY_NAME'}->{$site}->{'SERVICE'}
-                    ->{'BY_NAME'};
-                foreach my $host ( @{ $net_parsed->{$section}->{'@host'} } ) {
-                    my $hostfile
-                        = Get_source( $host, "", $hash_subst, $pf_config );
-                    my $host_parsed
-                        = Load_conf(
-                        $hostfile, $hash_subst, 'host',
-                        $pf_config
-                        );
-                    Add_host(
-                        $hostfile, 'host', $host_parsed,
-                        $GLOBAL, $pf_config
-                    );
-                    push @{ $service_part->{$section} }, $host;
-                }
-            }
-        }
-    }
-
-    return $GLOBAL;
-}
-
-# store $global_config in $flush_file
-# $flush_file defaults to $pf_config->{'path'}->{'global_struct'}
-sub Flush2disk_GLOBAL {
-    my ( $global_config, $pf_config, $flush_file ) = @_;
-
-    return unless $global_config and $pf_config;
-
-    $flush_file ||= $pf_config->{'path'}->{'global_struct'};
-
-    my $ret = eval { store( $global_config, $flush_file ); };
-    if ($EVAL_ERROR) {
-        croak "ERROR: $EVAL_ERROR";
-    }
-    if ( !$ret ) {
-        croak "ERROR: unable to flush global structure to $flush_file";
-    }
-
-    return 1;
-}
-
-# retrieve and return $global_config from $path_global_file
-sub Retrieve_GLOBAL {
-    my ($path_global_file) = @_;
-
-    return unless $path_global_file;
-
-    my $ret = eval { retrieve($path_global_file); };
-    if ($EVAL_ERROR) {
-        croak "ERROR: $EVAL_ERROR";
-    }
-    if ( !$ret ) {
-        croak
-            "ERROR: unable to retrieve global structure from $path_global_file";
-    }
-
-    return $ret;
-}
-
-sub Get_config_for_hostname_on_site {
-    my ( $hostname, $site, $hash_subst, $global_config, $pf_config ) = @_;
-
-    # Common configuration file e.g. update-common
-    my $global_host_conf = Load_conf(
-        Get_source(
-            'COMMON:/' . $pf_config->{'path'}->{'common_config'},
-            $hostname, $hash_subst, $pf_config
-        ),
-        $hash_subst,
-        'config',
-        $pf_config
-    );
-    my $hosttype
-        = Get_hosttype_from_hostname( $hostname, $global_config, $site );
-    if ( !defined $hosttype ) {
-        Abort(
-            $CODE->{'UNDEF_KEY'},
-            "Unable to get hosttype from hostname $hostname for getting hosttype configuration file"
-        );
-    }
-
-    # Hosttype configuration file e.g. update-<hosttype>
-    my $hosttype_conf_file
-        = __Get_config_path( $hosttype, $pf_config, $site );
-
-    # Hostname configuration file e.g. update-<hostname>
-    my $hostname_conf_file
-        = __Get_config_path( $hostname, $pf_config, $site );
-
-    foreach my $file ( $hosttype_conf_file, $hostname_conf_file ) {
-        next if !defined $file;
-        my $config = Load_conf( $file, $hash_subst, 'config', $pf_config );
-        foreach my $section ( @{ $config->{'__sections_order'} } ) {
-            push @{ $global_host_conf->{'__sections_order'} }, $section
-                if !defined $global_host_conf->{$section};
-            $global_host_conf->{$section} = $config->{$section};
-        }
-    }
-
-    return $global_host_conf;
-}
-
 1;    # Magic true value required at end of module
 
diff -r 6d007d250b23 -r 06e6ff6d8686 t/12.storable.t
--- a/t/12.storable.t	Mon Sep 20 17:08:34 2010 +0200
+++ b/t/12.storable.t	Mon Sep 20 14:55:48 2010 +0200
@@ -51,6 +51,7 @@
 $result = Flush2disk_GLOBAL($global_config, $pf_config, $store2);
 ok $result && -s $store2
     => 'Stores something in explicit path';
+unlink $store2;
 
 $result = Flush2disk_GLOBAL($global_config, {}, $store2);
 ok $result && -s $store2
@@ -75,8 +76,10 @@
 $result = Retrieve_GLOBAL($store1);
 is_deeply $result, $global_config
     => 'Store1 retrieval';
+unlink $store1;
 
 $result = Retrieve_GLOBAL($store2);
 is_deeply $result, $global_config
     => 'Store2 retrieval';
+unlink $store2;
 
diff -r 6d007d250b23 -r 06e6ff6d8686 t/13.conf.t
--- a/t/13.conf.t	Mon Sep 20 17:08:34 2010 +0200
+++ b/t/13.conf.t	Mon Sep 20 14:55:48 2010 +0200
@@ -4,6 +4,10 @@
 use warnings;
 
 use English qw( -no_match_vars );    # Avoids regex performance penalty
+use File::Copy;
+use File::Path qw( make_path remove_tree );
+use Hash::Merge::Simple qw( clone_merge merge );
+use IO::File;
 use Test::Exception;
 use Test::More qw( no_plan );
 
@@ -89,7 +93,6 @@
 ok ref $parsed_configuration eq 'HASH' && keys %{$parsed_configuration}
     => 'Returns a non-empty hashref';
 
-use Hash::Merge::Simple qw( merge );
 my $expected_configuration = merge( $default_pf_config, $test_configuration );
 is_deeply $parsed_configuration, $expected_configuration
     => 'Correctly merges with the default configuration'
@@ -182,12 +185,27 @@
     => 'Returns empty string if $text is empty';
 
 throws_ok { Get_source( q{foo bar baz}, undef, q{non-hashref $hash_subst} ) }
-    qr{ \A ERROR: [ ] Invalid [ ] non-href [ ] [\$] hash_subst }xms
+qr{ \A ERROR: [ ] Invalid [ ] non-href [ ] [\$] hash_subst }xms
     => q{Dies on non-hashref $hash_subst};
 
-throws_ok { Get_source( q{foo bar baz}, undef, undef, q{non-hashref $pf_config} ) }
-    qr{ \A ERROR: [ ] Invalid [ ] non-href [ ] [\$] pf_config }xms
+throws_ok {
+    Get_source( q{foo bar baz}, undef, undef, q{non-hashref $pf_config} );
+}
+qr{ \A ERROR: [ ] Invalid [ ] non-href [ ] [\$] pf_config }xms
     => q{Dies on non-hashref $pf_config};
+
+throws_ok {
+    Get_source( q{foo bar baz}, undef, undef, { missing => 'checkout_dir' } );
+}
+qr{ \A ERROR: [ ] Undefined [ ] configuration [ ] parameter: [ ] path.checkout_dir}xms
+    => q{Dies on invalid $pf_config (no path.checkout_dir)};
+
+throws_ok {
+    Get_source( q{foo bar baz}, undef, undef,
+        { path => { checkout_dir => '/tmp/co_dir' } } );
+}
+qr{ \A ERROR: [ ] Undefined [ ] configuration [ ] parameter: [ ] vcs.module}xms
+    => q{Dies on invalid $pf_config (no vcs.module)};
 
 is Get_source( q{MODSITE_FOOBAR:/my/path/to/file} ),
     q{/var/lib/cvsguest/config/SITE/FOOBAR/MODEL/my/path/to/file}
@@ -264,8 +282,44 @@
     qr{ \A ERROR: }xms
     => q{Dies if non-href $pf_config};
 
-ok !defined PFTools::Conf::__Get_config_path( 'unknown-host', {}, 'unknown-site' )
+my $pf_config_overrides = {
+    path => {
+        status_dir => '/tmp/pftools-conf-test/status_dir',
+        checkout_dir => '/tmp/pftools-conf-test/checkout_dir',
+    },
+    location => {
+        site => 'test-site',
+    },
+};
+my $pf_config = clone_merge( $default_pf_config, $pf_config_overrides );
+ok !defined PFTools::Conf::__Get_config_path( 'unknown-host', $pf_config, 'unknown-site' )
     => q{Returns undef if no matching file found};
 
-diag( 'FIXME: add the two good cases!' );
+make_path( qw(
+    /tmp/pftools-conf-test/checkout_dir/config/SITE/test-site/CONFIG
+    /tmp/pftools-conf-test/checkout_dir/config/CONFIG
+) );
+my $site_config_file = q{/tmp/pftools-conf-test/checkout_dir/config/SITE/test-site/CONFIG/update-mytest};
+$fh = IO::File->new( $site_config_file, '>' )
+    or die "open $site_config_file: $OS_ERROR";
+$fh->print( <<'EOT' )
+[mytest%%]
+fake = value
+foo = bar
+EOT
+    or die "print $site_config_file: $OS_ERROR";
+$fh->close
+    or die "close $site_config_file: $OS_ERROR";
 
+is PFTools::Conf::__Get_config_path( 'mytest', $pf_config, 'test-site' ),
+    $site_config_file
+    => q{Returns the site specific file if it exists};
+
+my $global_config_file = q{/tmp/pftools-conf-test/checkout_dir/config/CONFIG/update-mytest};
+move( $site_config_file, $global_config_file );
+is PFTools::Conf::__Get_config_path( 'mytest', $pf_config, 'test-site' ),
+    $global_config_file
+    => q{Returns the global file if no site-specific file found};
+unlink $global_config_file;
+remove_tree( qw( /tmp/pftools-conf-test/ ) );
+



More information about the pf-tools-commits mailing list