Parcourir la source

[master] Merge branch 'trac3884'

    Adds kea-admin unit tests for PosgreSQL lease-dump
Thomas Markwalder il y a 10 ans
Parent
commit
0772b7df2a

+ 34 - 13
doc/guide/admin.xml

@@ -366,12 +366,14 @@ $
 
             <listitem>
               <para>
-                Create the database tables using the new user's
-                credentials and the dhcpdb_create.pgsql script supplied
-                with Kea.  After entering the following command, you
-                will be prompted for the new user's password. When the
-                command completes you will be returned to the shell
-                prompt. You should see output similar to following:
+                At this point you are ready to create the database tables.
+                This can be done using the <command>kea-admin</command> tool
+                as explained in the next section (recommended), or manually.
+                To create the tables manually enter the following command.
+                Note that PostgreSQL will prompt you to enter the new user's
+                password you specified in Step 3. When the command completes
+                you will be returned to the shell prompt. You should see output
+                similar to following:
 <screen>
 $ <userinput>psql -d <replaceable>database-name</replaceable> -U <replaceable>user-name</replaceable> -f <replaceable>path-to-kea</replaceable>/share/kea/scripts/pgsql/dhcpdb_create.pgsql</userinput>
 Password for user <replaceable>user-name</replaceable>:
@@ -423,9 +425,12 @@ host    <replaceable>database-name</replaceable>    <replaceable>user-name</repl
               </para>
 
               <para>
-                Please consult your PostgreSQL user manual before making
-                these changes as they may expose your other databases
-                that you run on the same system.
+                These edits are primarily intended as a starting point
+                not a definitive reference on PostgreSQL administration or
+                database security.  Please consult your PostgreSQL user
+                manual before making these changes as they may expose
+                other databases that you run.  It may be necessary to
+                restart PostgreSQL in order for these changes to take effect.
               </para>
             </listitem>
           </orderedlist>
@@ -434,12 +439,28 @@ host    <replaceable>database-name</replaceable>    <replaceable>user-name</repl
 
       <section>
         <title>Initialize the PostgreSQL Database Using kea-admin</title>
-
         <para>
-          Support for PostgreSQL in <command>kea-admin</command> is
-          currently not implemented.
+          If you elected not to create the tables manually, you can do
+          so now by running the <command>kea-admin</command> tool:
+<screen>
+$ <userinput>kea-admin lease-init pgsql -u <replaceable>database-user</replaceable> -p <replaceable>database-password</replaceable> -n <replaceable>database-name</replaceable></userinput>
+</screen>
+          Do not do this if you already created the tables in manually.
+          <command>kea-admin</command> implements rudimentary checks:
+          it will refuse to initialize a database that contains any
+          existing tables. If you want to start from scratch, you
+          must remove all data manually. (This process is a manual
+          operation on purpose to avoid possibly irretrievable mistakes
+          by <command>kea-admin</command>.)
+        </para>
+      </section>
+      <section id="pgsql-upgrade">
+        <title>Upgrading a PostgreSQL Database from an Earlier Version of Kea</title>
+        <para>
+          Currently, PostgreSQL only supports Kea schema version 1.0 so no upgrades
+          are available.  As upgrades become available, <command>kea-admin</command>
+          will support them.
         </para>
-        <!-- @todo: document PgSQL upgrade once they are implemented in kea-admin -->
       </section>
     </section> <!-- end of PostgreSQL sections -->
     <section>

+ 29 - 19
src/bin/admin/admin-utils.sh

@@ -16,23 +16,21 @@
 
 # There are two ways of calling this method.
 # mysql_execute SQL_QUERY - This call is simpler, but requires db_user,
-#     db_password and db_name variables to be bet.
+#     db_password and db_name variables to be set.
 # mysql_execute SQL_QUERY PARAM1 PARAM2 .. PARAMN - Additional parameters
 #     may be specified. They are passed directly to mysql. This one is
 #     more convenient to use if the script didn't parse db_user db_password
 #     and db_name.
 #
-# It saves mysql command exit status both to the env variable _ADMIN_STATUS
-# as well as returning it as $? to the caller.
-
+# It returns the mysql command exit status to the caller as $?
 mysql_execute() {
+    QUERY=$1
+    shift
     if [ $# -gt 1 ]; then
-        QUERY="$1"
-        shift
         mysql -N -B  $* -e "${QUERY}"
         retcode=$?
     else
-        mysql -N -B --user=$db_user --password=$db_password -e "${1}" $db_name
+        mysql -N -B --user=$db_user --password=$db_password -e "${QUERY}" $db_name
         retcode="$?"
     fi
 
@@ -44,43 +42,55 @@ mysql_version() {
     return $?
 }
 
+# Submits given SQL text to PostgreSQL
+# There are two ways of calling this method.
+# pgsql_execute SQL_QUERY - This call is simpler, but requires db_user,
+#     db_password and db_name variables to be set.
+# pgsql_execute SQL_QUERY PARAM1 PARAM2 .. PARAMN - Additional parameters
+#     may be specified. They are passed directly to pgsql. This one is
+#     more convenient to use if the script didn't parse db_user db_password
+#     and db_name.
+#
+# It returns the pgsql command exit status to the caller as $?
 pgsql_execute() {
     QUERY=$1
     shift
     if [ $# -gt 0 ]; then
-        _RESULT=$(echo $QUERY | psql --set ON_ERROR_STOP=1 -A -t -q $*)
+        echo $QUERY | psql --set ON_ERROR_STOP=1 -A -t -q $*
         retcode=$?
     else
         export PGPASSWORD=$db_password
-        _RESULT=$(echo $QUERY | psql --set ON_ERROR_STOP=1 -A -t -q -U $db_user -d $db_name)
+        echo $QUERY | psql --set ON_ERROR_STOP=1 -A -t -q -U $db_user -d $db_name
         retcode=$?
     fi
     return $retcode
 }
 
+# Submits SQL in a given file to PostgreSQL
+# There are two ways of calling this method.
+# pgsql_execute SQL_FILE - This call is simpler, but requires db_user,
+#     db_password and db_name variables to be set.
+# pgsql_execute SQL_FILE PARAM1 PARAM2 .. PARAMN - Additional parameters
+#     may be specified. They are passed directly to pgsql. This one is
+#     more convenient to use if the script didn't parse db_user db_password
+#     and db_name.
+#
+# It returns the pgsql command exit status to the caller as $?
 pgsql_execute_script() {
     file=$1
     shift
     if [ $# -gt 0 ]; then
-        _RESULT=$(psql --set ON_ERROR_STOP=1 -A -t -q -f $file $*)
+        psql --set ON_ERROR_STOP=1 -A -t -q -f $file $*
         retcode=$?
     else
         export PGPASSWORD=$db_password
-        _RESULT=$(psql --set ON_ERROR_STOP=1 -A -t -q -U $db_user -d $db_name -f $file)
+        psql --set ON_ERROR_STOP=1 -A -t -q -U $db_user -d $db_name -f $file
         retcode=$?
     fi
     return $retcode
 }
 
-
 pgsql_version() {
     pgsql_execute "SELECT version || '.' || minor FROM schema_version" "$@"
     return $?
 }
-
-pgsql_version_print() {
-    pgsql_version "$@"
-    retcode=$?
-    printf "%s" $_RESULT
-    return $?
-}

+ 18 - 18
src/bin/admin/kea-admin.in

@@ -180,26 +180,31 @@ pgsql_init() {
 
     # Let's try to count the number of tables. Anything above 0 means that there
     # is some database in place. If there is anything, we abort.
-    pgsql_execute "\d"
-    COUNT=`echo "$_RESULT" | wc -w`
+    RESULT=`pgsql_execute "\d"`
+    ERRCODE=$?
+    if [ "$ERRCODE" -ne 0 ]; then
+        log_error "pgsql_init: table query failed, status code: $ERRCODE?"
+        exit 1
+    fi
+
+    COUNT=`echo "$RESULT" | wc -w`
     if [ $COUNT -gt 0 ]; then
         printf "\n"
-        log_error "Expected empty database $db_name, but the following tables are present \n$_RESULT. Aborting."
+        log_error "Expected empty database $db_name, but the following tables are present \n$RESULT. Aborting."
         exit 2
     fi
 
     init_script="$scripts_dir/pgsql/dhcpdb_create.pgsql"
     printf "Initializing database using script %s\n" $init_script
-    pgsql_execute_script $init_script
+    RESULT=`pgsql_execute_script $init_script`
     ERRCODE=$?
     if [ "$ERRCODE" -ne 0 ]; then
         log_error "Database initialization failed, status code: $ERRCODE?"
         exit 1
     fi
 
-    printf "Lease DB version reported after initialization: "
-    pgsql_version_print
-    printf "\n"
+    version=`pgsql_version`
+    printf "Lease DB version reported after initialization: $version\n"
     exit 0
 }
 
@@ -254,10 +259,8 @@ mysql_upgrade() {
 }
 
 pgsql_upgrade() {
-    # @todo - When PostgreSQL has a schema greater than 1.0, this will need
-    # to be implemented. See ticket #3600
-    pgsql_version_print
-    printf "\n"
+    version=`pgsql_version`
+    printf "Lease DB version reported before upgrade: $version\n"
 
     # Check if the scripts directory exists at all.
     if [ ! -d ${scripts_dir}/pgsql ]; then
@@ -278,9 +281,8 @@ pgsql_upgrade() {
         sh ${script} --user=${db_user} --password=${db_password} ${db_name}
     done
 
-    printf "Lease DB version reported after upgrade: "
-    pgsql_version_print
-    printf "\n"
+    version=`pgsql_version`
+    printf "Lease DB version reported after upgrade: $version\n"
     exit 0
 }
 
@@ -410,9 +412,7 @@ mysql_dump() {
 
 ### Functions used for dump
 pgsql_dump() {
-
-    # @todo use pgsql_version once implemented. See #3883
-    version='1.0'
+    version=`pgsql_version`
     get_dump_query $version
 
     # Make sure they specified a file
@@ -579,7 +579,7 @@ case ${command} in
                 printf "\n"
                 ;;
             pgsql)
-                pgsql_version_print
+                pgsql_version
                 ;;
             esac
         ;;

+ 3 - 3
src/bin/admin/tests/data/mysql.lease4_dump_test.reference.csv

@@ -1,4 +1,4 @@
 address,hwaddr,client_id,valid_lifetime,expire,subnet_id,fqdn_fwd,fqdn_rev,hostname
-0.0.0.10,3230,3330,40,0000-00-00 00:00:00,50,1,1,one.example.com
-0.0.0.11,,313233,40,0000-00-00 00:00:00,50,1,1,
-0.0.0.12,3232,,40,0000-00-00 00:00:00,50,1,1,three.example.com
+0.0.0.10,3230,3330,40,2015-01-01 01:15:30,50,1,1,one.example.com
+0.0.0.11,,313233,40,2015-02-02 02:30:45,50,1,1,
+0.0.0.12,3232,,40,2015-03-03 11:01:07,50,1,1,three.example.com

+ 3 - 3
src/bin/admin/tests/data/mysql.lease6_dump_test.reference.csv

@@ -1,4 +1,4 @@
 address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,hwaddr,hwtype,hwaddr_source
-10,3230,30,0000-00-00 00:00:00,40,50,IA_TA,60,70,1,1,one.example.com,3830,90,100
-11,,30,0000-00-00 00:00:00,40,50,IA_TA,60,70,1,1,,3830,90,100
-12,3231,30,0000-00-00 00:00:00,40,50,IA_TA,60,70,1,1,three.example.com,3830,90,100
+10,3230,30,2015-04-04 01:15:30,40,50,IA_TA,60,70,1,1,one.example.com,3830,90,100
+11,,30,2015-05-05 02:30:45,40,50,IA_TA,60,70,1,1,,3830,90,100
+12,3231,30,2015-06-06 11:01:07,40,50,IA_TA,60,70,1,1,three.example.com,3830,90,100

+ 4 - 0
src/bin/admin/tests/data/pgsql.lease4_dump_test.reference.csv

@@ -0,0 +1,4 @@
+address,hwaddr,client_id,valid_lifetime,expire,subnet_id,fqdn_fwd,fqdn_rev,hostname
+0.0.0.10,20,30,40,<timestamp1>,50,1,1,one.example.com
+0.0.0.11,,013233,40,<timestamp2>,50,1,1,
+0.0.0.12,22,,40,<timestamp3>,50,1,1,three.example.com

+ 4 - 0
src/bin/admin/tests/data/pgsql.lease6_dump_test.reference.csv

@@ -0,0 +1,4 @@
+address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname
+12,21,30,<timestamp3>,40,50,IA_TA,60,70,t,t,three.example.com
+11,,30,<timestamp2>,40,50,IA_TA,60,70,t,t,
+10,20,30,<timestamp1>,40,50,IA_TA,60,70,t,t,one.example.com

+ 17 - 17
src/bin/admin/tests/mysql_tests.sh.in

@@ -274,8 +274,8 @@ mysql_lease4_dump_test() {
 
     test_dir="@abs_top_srcdir@/src/bin/admin/tests"
     script_dir="@abs_top_srcdir@/src/bin/admin/scripts"
-    output_file="$test_dir/data/lease4_dump_test.output.csv"
-    tmp_file="$test_dir/data/lease4_dump_test.output.csv.tmp"
+    output_file="$test_dir/data/mysql.lease4_dump_test.output.csv"
+    tmp_file="$output_file.tmp"
     ref_file="$test_dir/data/mysql.lease4_dump_test.reference.csv"
 
     # wipe out any residuals from prior failed runs
@@ -295,27 +295,27 @@ mysql_lease4_dump_test() {
     # Ok, now let's initalize the database
     ${keaadmin} lease-init mysql -u $db_user -p $db_password -n $db_name -d $script_dir
     ERRCODE=$?
-    assert_eq 0 $ERRCODE "could not create database,  status code %d"
+    assert_eq 0 $ERRCODE "could not create database, expected exit code %d, actual %d"
 
     # Insert the reference record
     insert_sql="\
-insert into lease4 values(10,20,30,40,0,50,1,1,\"one.example.com\");\
-insert into lease4 values(11,NULL,123,40,0,50,1,1,\"\");\
-insert into lease4 values(12,22,NULL,40,0,50,1,1,\"three.example.com\");"
+insert into lease4 values(10,20,30,40,\"2015-01-01 01:15:30\",50,1,1,\"one.example.com\");\
+insert into lease4 values(11,NULL,123,40,\"2015-02-02 02:30:45\",50,1,1,\"\");\
+insert into lease4 values(12,22,NULL,40,\"2015-03-03 11:01:07\",50,1,1,\"three.example.com\");"
 
     mysql_execute "$insert_sql"
     ERRCODE=$?
-    assert_eq 0 $ERRCODE "insert into lease4 failed, status code %d"
+    assert_eq 0 $ERRCODE "insert into lease4 failed, expected exit code %d, actual %d"
 
     # Dump lease4 to output_file
     ${keaadmin} lease-dump mysql -4 -u $db_user -p $db_password -n $db_name -d $script_dir -o $output_file
     ERRCODE=$?
-    assert_eq 0 $ERRCODE "kea-admin lease-dump -4 failed,  status code %d"
+    assert_eq 0 $ERRCODE "kea-admin lease-dump -4 failed, expected exit code %d, actual %d"
 
     # Compare the dump output to reference file, they should be identical
     cmp -s $output_file  $ref_file
     ERRCODE=$?
-    assert_eq 0 $ERRCODE "dump file does not match reference file"
+    assert_eq 0 $ERRCODE "dump file does not match reference file, expected exit code %d, actual %d"
 
     # remove the output file
     rm $output_file
@@ -331,8 +331,8 @@ mysql_lease6_dump_test() {
 
     test_dir="@abs_top_srcdir@/src/bin/admin/tests"
     script_dir="@abs_top_srcdir@/src/bin/admin/scripts"
-    output_file="$test_dir/data/lease6_dump_test.output.csv"
-    tmp_file="$test_dir/data/lease6_dump_test.output.csv.tmp"
+    output_file="$test_dir/data/mysql.lease6_dump_test.output.csv"
+    tmp_file="$output_file.tmp"
     ref_file="$test_dir/data/mysql.lease6_dump_test.reference.csv"
 
     # wipe out any residuals from prior failed runs
@@ -352,17 +352,17 @@ mysql_lease6_dump_test() {
     # Ok, now let's initalize the database
     ${keaadmin} lease-init mysql -u $db_user -p $db_password -n $db_name -d $script_dir
     ERRCODE=$?
-    assert_eq 0 $ERRCODE "could not create database,  status code %d"
+    assert_eq 0 $ERRCODE "could not create database, expected exit code %d, actual %d"
 
     # Insert the reference record
     insert_sql="\
-insert into lease6 values(10,20,30,0,40,50,1,60,70,1,1,\"one.example.com\",80,90,100);\
-insert into lease6 values(11,NULL,30,0,40,50,1,60,70,1,1,\"\",80,90,100);\
-insert into lease6 values(12,21,30,0,40,50,1,60,70,1,1,\"three.example.com\",80,90,100);"
+insert into lease6 values(10,20,30,\"2015-04-04 01:15:30\",40,50,1,60,70,1,1,\"one.example.com\",80,90,100);\
+insert into lease6 values(11,NULL,30,\"2015-05-05 02:30:45\",40,50,1,60,70,1,1,\"\",80,90,100);\
+insert into lease6 values(12,21,30,\"2015-06-06 11:01:07\",40,50,1,60,70,1,1,\"three.example.com\",80,90,100);"
 
     mysql_execute "$insert_sql"
     ERRCODE=$?
-    assert_eq 0 $ERRCODE "insert into lease6 failed, status code %d"
+    assert_eq 0 $ERRCODE "insert into lease6 failed, expected exit code %d, actual %d"
 
     # Dump lease4 to output_file
     ${keaadmin} lease-dump mysql -6 -u $db_user -p $db_password -n $db_name -d $script_dir -o $output_file
@@ -372,7 +372,7 @@ insert into lease6 values(12,21,30,0,40,50,1,60,70,1,1,\"three.example.com\",80,
     # Compare the dump output to reference file, they should be identical
     cmp -s $output_file  $ref_file
     ERRCODE=$?
-    assert_eq 0 $ERRCODE "dump file does not match reference file"
+    assert_eq 0 $ERRCODE "dump file does not match reference file, expected exit code %d, actual %d"
 
     # remove the output file
     rm $output_file

+ 208 - 7
src/bin/admin/tests/pgsql_tests.sh.in

@@ -43,10 +43,11 @@ pgsql_wipe() {
     export PGPASSWORD=$db_password
 
     # Make a set of drop commands, one for each table owned by keatest
-    pgsql_execute "SELECT 'drop table if exists '||t.tablename || ' cascade;' as dcmd FROM pg_catalog.pg_tables t WHERE t.tableowner = 'keatest';"
+    RESULT=`pgsql_execute "SELECT 'drop table if exists '||t.tablename || ' cascade;' as dcmd FROM pg_catalog.pg_tables t WHERE t.tableowner = 'keatest';"`
     assert_eq 0 $? "pgsql_wipe select failed, expected exit code: %d, actual: %d"
+
     # Now execute the set of drop commands from the result set returned
-    pgsql_execute "$_RESULT"
+    RESULT=`pgsql_execute "$RESULT"`
     assert_eq 0 $? "pgsql_wipe drop failed, expected exit code: %d, actual: %d"
 }
 
@@ -63,19 +64,19 @@ pgsql_lease_init_test() {
     # Verify that all the expected tables exist
 
     # Check schema_version table
-    pgsql_execute "SELECT version, minor FROM schema_version;"
-    assert_eq 0 $? "schema_vesion table check failed, expected exit code: %d, actual: %d"
+    RESULT=`pgsql_execute "SELECT version, minor FROM schema_version;"`
+    assert_eq 0 $? "schema_version table check failed, expected exit code: %d, actual: %d"
 
     # Check lease4 table
-    pgsql_execute "SELECT address, hwaddr, client_id, valid_lifetime, expire, subnet_id, fqdn_fwd, fqdn_rev, hostname FROM lease4;"
+    RESULT=`pgsql_execute "SELECT address, hwaddr, client_id, valid_lifetime, expire, subnet_id, fqdn_fwd, fqdn_rev, hostname FROM lease4;"`
     assert_eq 0 $? "lease4 table check failed, expected exit code: %d, actual: %d"
 
     # Check lease6 table
-    pgsql_execute "SELECT address, duid, valid_lifetime, expire, subnet_id, pref_lifetime, lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname FROM lease6;"
+    RESULT=`pgsql_execute "SELECT address, duid, valid_lifetime, expire, subnet_id, pref_lifetime, lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname FROM lease6;"`
     assert_eq 0 $? "lease6 table check failed, expected exit code: %d, actual: %d"
 
     # Check lease6_types table
-    pgsql_execute "SELECT lease_type, name FROM lease6_types;"
+    RESULT=`pgsql_execute "SELECT lease_type, name FROM lease6_types;"`
     assert_eq 0 $? "lease6_types table check failed, expected exit code: %d, actual: %d"
 
     # Trying to create it again should fail.  This verifies the db present
@@ -130,6 +131,206 @@ pgsql_upgrade_test() {
     test_finish 0
 }
 
+# Given a valid timestamp string, returns a timestamp with timezone string
+# for the give time localized by the PostgreSQL server.
+get_local_time() {
+    timestamp="$1"
+
+    # Expiration field is a "timestamp with timezone" so we need a reference
+    # time for the machine/DB this test is running upon.
+    ref_timestamp=`pgsql_execute "SELECT timestamptz '$1';"`
+    ERRCODE=$?
+    assert_eq 0 $ERRCODE "reference time query failed for [$timestamp], expected exit code %d, actual %d"
+    echo $ref_timestamp
+}
+
+
+# Test verifies the ability to dump lease4 data to CSV file
+# The dump output file is compared against a reference file.
+# If the dump is successful, the file contents will be the
+# same.  Note that the expire field in the lease4 table
+# is of data type "timestamp with timezone". This means that
+# the dumped file content is dependent upon the timezone
+# setting the PostgreSQL server is using.  To account for
+# this the reference data contains a tag, "<timestamp>"
+# where the expire column's data would normally be. This
+# tag is replaced during text execution with a value
+# determined by querying the PostgreSQL server.  This
+# updated reference data is captured in a temporary file
+# which is used for the actual comparison.
+pgsql_lease4_dump_test() {
+    test_start "pgsql.lease4_dump_test"
+
+    test_dir="@abs_top_srcdir@/src/bin/admin/tests"
+    script_dir="@abs_top_srcdir@/src/bin/admin/scripts"
+    output_file="$test_dir/data/pgsql.lease4_dump_test.output.csv"
+    ref_file="$test_dir/data/pgsql.lease4_dump_test.reference.csv"
+    ref_file_tmp=$ref_file.tmp
+
+    # wipe out any residuals from prior failed runs
+    if [ -e $output_file ]
+    then
+        rm $output_file
+    fi
+
+    if [ -e $ref_file_tmp ]
+    then
+        rm $ref_file_tmp
+    fi
+
+    # Let's wipe the whole database
+    pgsql_wipe
+
+    # Ok, now let's initalize the database
+    ${keaadmin} lease-init pgsql -u $db_user -p $db_password -n $db_name -d $script_dir
+    ERRCODE=$?
+    assert_eq 0 $ERRCODE "could not create database, expected exit code %d, actual %d"
+
+    timestamp1="2015-01-01 01:15:30"
+    timestamp2="2015-02-02 02:30:45"
+    timestamp3="2015-03-03 11:01:07"
+
+    # Insert the reference records
+    insert_sql="\
+insert into lease4 values(10,E'\\x20',E'\\x30',40,'$timestamp1',50,'t','t','one.example.com');\
+insert into lease4 values(11,'',E'\\x0123',40,'$timestamp2',50,'t','t','');\
+insert into lease4 values(12,E'\\x22','',40,'$timestamp3',50,'t','t','three.example.com');"
+
+    pgsql_execute "$insert_sql"
+    ERRCODE=$?
+    assert_eq 0 $ERRCODE "insert into lease4 failed, expected exit code %d, actual %d"
+
+    # Dump lease4 to output_file
+    ${keaadmin} lease-dump pgsql -4 -u $db_user -p $db_password -n $db_name -d $script_dir -o $output_file
+    ERRCODE=$?
+    assert_eq 0 $ERRCODE "kea-admin lease-dump -4 failed,  status code %d"
+
+    # Expiration field is a "timestamp with timezone" so we need a localized reference
+    # times for the machine/DB this test is running upon.
+    local_timestamp1=`get_local_time "$timestamp1"`
+    local_timestamp2=`get_local_time "$timestamp2"`
+    local_timestamp3=`get_local_time "$timestamp3"`
+
+    # Create the comparison file by replacing the <timestamp> tags
+    # with the local reference timestamp
+    sedstr="\
+sed 's/<timestamp1>/$local_timestamp1/g' $ref_file | \
+sed 's/<timestamp2>/$local_timestamp2/g' | \
+sed 's/<timestamp3>/$local_timestamp3/g' "
+
+    eval $sedstr >$ref_file_tmp
+    ERRCODE=$?
+    assert_eq 0 $ERRCODE "timestamp replacement failed, expected exit code %d, actual %d"
+
+    # Compare the dump output to reference file, they should be identical
+    cmp -s $output_file  $ref_file_tmp
+    ERRCODE=$?
+    assert_eq 0 $ERRCODE "dump file does not match reference file, expected exit code %d, actual %d"
+
+    # Remove the output file and temporary reference file
+    rm $output_file
+    rm $ref_file_tmp
+
+    # Let's wipe the whole database
+    pgsql_wipe
+
+    test_finish 0
+}
+
+# Test verifies the ability to dump lease6 data to CSV file
+# The dump output file is compared against a reference file.
+# If the dump is successful, the file contents will be the
+# same.  Note that the expire field in the lease6 table
+# is of data type "timestamp with timezone". This means that
+# the dumped file content is dependent upon the timezone
+# setting the PostgreSQL server is using.  To account for
+# this the reference data contains a tag, "<timestamp>"
+# where the expire column's data would normally be. This
+# tag is replaced during text execution with a value
+# determined by querying the PostgreSQL server.  This
+# updated reference data is captured in a temporary file
+# which is used for the actual comparison.
+pgsql_lease6_dump_test() {
+    test_start "pgsql.lease6_dump_test"
+
+    test_dir="@abs_top_srcdir@/src/bin/admin/tests"
+    script_dir="@abs_top_srcdir@/src/bin/admin/scripts"
+    output_file="$test_dir/data/pgsql.lease6_dump_test.output.csv"
+    ref_file="$test_dir/data/pgsql.lease6_dump_test.reference.csv"
+    ref_file_tmp=$ref_file.tmp
+
+    # wipe out any residuals from prior failed runs
+    if [ -e $output_file ]
+    then
+        rm $output_file
+    fi
+
+    if [ -e $ref_file_tmp ]
+    then
+        rm $ref_file_tmp
+    fi
+
+    # Let's wipe the whole database
+    pgsql_wipe
+
+    # Ok, now let's initalize the database
+    ${keaadmin} lease-init pgsql -u $db_user -p $db_password -n $db_name -d $script_dir
+    ERRCODE=$?
+    assert_eq 0 $ERRCODE "could not create database,  status code %d"
+
+    timestamp1="2015-04-04 01:15:30"
+    timestamp2="2015-02-02 02:30:45"
+    timestamp3="2015-06-06 11:01:07"
+
+    # Insert the reference records
+    insert_sql="\
+insert into lease6 values(10,E'\\x20',30,'$timestamp1',40,50,1,60,70,'t','t','one.example.com');\
+insert into lease6 values(11,'',30,'$timestamp2',40,50,1,60,70,'t','t','');\
+insert into lease6 values(12,E'\\x21',30,'$timestamp3',40,50,1,60,70,'t','t','three.example.com');"
+
+    pgsql_execute "$insert_sql"
+    ERRCODE=$?
+    assert_eq 0 $ERRCODE "insert into lease6 failed, status code %d"
+
+    # Dump lease6 to output_file
+    ${keaadmin} lease-dump pgsql -6 -u $db_user -p $db_password -n $db_name -d $script_dir -o $output_file
+    ERRCODE=$?
+    assert_eq 0 $ERRCODE "kea-admin lease-dump -6 failed, status code %d"
+
+    # Expiration field is a "timestamp with timezone" so we need a localized reference
+    # times for the machine/DB this test is running upon.
+    local_timestamp1=`get_local_time "$timestamp1"`
+    local_timestamp2=`get_local_time "$timestamp2"`
+    local_timestamp3=`get_local_time "$timestamp3"`
+
+    # Create the comparison file by replacing the <timestamp> tags
+    # with the local reference timestamp
+    sedstr="\
+sed 's/<timestamp1>/$local_timestamp1/g' $ref_file | \
+sed 's/<timestamp2>/$local_timestamp2/g' | \
+sed 's/<timestamp3>/$local_timestamp3/g' "
+
+    eval $sedstr >$ref_file_tmp
+    ERRCODE=$?
+    assert_eq 0 $ERRCODE "timestamp replacement failed, expected exit code %d, actual %d"
+
+    # Compare the dump output to reference file, they should be identical
+    cmp -s $output_file  $ref_file_tmp
+    ERRCODE=$?
+    assert_eq 0 $ERRCODE "dump file does not match reference file"
+
+    # Remove the output file and temporary reference file
+    rm $output_file
+    rm $ref_file_tmp
+
+    # Let's wipe the whole database
+    pgsql_wipe
+
+    test_finish 0
+}
+
 pgsql_lease_init_test
 pgsql_lease_version_test
 pgsql_upgrade_test
+pgsql_lease4_dump_test
+pgsql_lease6_dump_test