Browse Source

[963] Changes after review.

Stephen Morris 13 years ago
parent
commit
d85eda60ea

+ 1 - 0
configure.ac

@@ -996,6 +996,7 @@ AC_CONFIG_FILES([Makefile
                  src/bin/cfgmgr/tests/Makefile
                  src/bin/dbutil/Makefile
                  src/bin/dbutil/tests/Makefile
+                 src/bin/dbutil/tests/testdata/Makefile
                  src/bin/host/Makefile
                  src/bin/loadzone/Makefile
                  src/bin/loadzone/tests/correct/Makefile

+ 10 - 0
src/bin/dbutil/Makefile.am

@@ -1,11 +1,21 @@
 SUBDIRS = . tests
 
 bin_SCRIPTS = b10-dbutil
+man_MANS = b10-dbutil.8
+
+EXTRA_DIST = $(man_MANS) b10-dbutil.xml
 
 noinst_SCRIPTS = run_dbutil.sh
 
 CLEANFILES = b10-dbutil b10-dbutil.pyc
 
+if ENABLE_MAN
+
+b10-dbutil.8: b10-dbutil.xml
+	xsltproc --novalid --xinclude --nonet -o $@ http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $(srcdir)/bindctl.xml
+
+endif
+
 b10-dbutil: dbutil.py
 	$(SED) -e "s|@@PYTHONPATH@@|@pyexecdir@|" \
 	       -e "s|@@SYSCONFDIR@@|@sysconfdir@|" \

+ 174 - 0
src/bin/dbutil/b10-dbutil.xml

@@ -0,0 +1,174 @@
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+               "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
+	       [<!ENTITY mdash "&#8212;">]>
+<!--
+ - Copyright (C) 2012  Internet Systems Consortium, Inc. ("ISC")
+ -
+ - Permission to use, copy, modify, and/or distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ - AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ - PERFORMANCE OF THIS SOFTWARE.
+-->
+
+<refentry>
+
+  <refentryinfo>
+    <date>March 20, 2012</date>
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>b10-dbutil</refentrytitle>
+    <manvolnum>8</manvolnum>
+    <refmiscinfo>BIND10</refmiscinfo>
+  </refmeta>
+
+  <refnamediv>
+    <refname>b10-dbutil</refname>
+    <refpurpose>Zone Database Maintenance Utility</refpurpose>
+  </refnamediv>
+
+  <docinfo>
+    <copyright>
+      <year>2012</year>
+      <holder>Internet Systems Consortium, Inc. ("ISC")</holder>
+    </copyright>
+  </docinfo>
+
+  <refsynopsisdiv>
+    <cmdsynopsis>
+      <command>b10-dbutil --check</command>
+        <arg>--verbose</arg>
+        <arg><replaceable choice='req'>dbfile</replaceable></arg>
+    </cmdsynopsis>
+    <cmdsynopsis>
+      <command>b10-dbutil --upgrade</command>
+        <arg>--noconfirm</arg>
+        <arg>--verbose</arg>
+        <arg><replaceable choice='req'>dbfile</replaceable></arg>
+    </cmdsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>DESCRIPTION</title>
+    <para>
+      The <command>b10-dbutil</command> utility is a general administration
+      utility for SQL databases. (Currently only SQLite is supported by
+      BIND 10.)  It can report the current verion of the schema, and upgrade
+      an existing database to the latest version of the schema.
+    </para>
+
+    <para>
+      <command>b10-dbutil</command> operates in one of two modes, check mode
+      or upgrade mode.
+    </para>
+
+    <para>
+      In check mode (<command>b10-dbutil --check</command>), the
+      utility reads the version of the database schema from the database
+      and prints it.  It will tell you whether the schema is at the latest
+      version supported by BIND 10.
+    </para>
+
+    <para>
+      When the upgrade function is selected
+      (<command>b10-dbutil --upgrade</command>), the
+      utility takes a copy of the database, then upgrades it to the latest
+      version of the schema.  The contents of the database remain intact.
+      (The backup file is a file in the same directory as the database
+      file.  It has the same name, with ".backup" appended to it.  If a
+      file of that name already exists, the file will have the suffix
+      ".backup-1".  If that exists, the file will be suffixed ".backup-2",
+      and so on.)
+    </para>
+
+    <para>
+    When upgrading the database, it is <emphasis>strongly</emphasis>
+    recommended that BIND 10 not be running while the upgrade is in
+    progress.
+    </para>
+
+  </refsect1>
+
+  <refsect1>
+    <title>ARGUMENTS</title>
+
+    <para>The arguments are as follows:</para>
+
+    <variablelist>
+      <varlistentry>
+        <term>
+         <option>--check</option>
+        </term>
+        <listitem>
+          <para>Selects the version check function, which reports the
+          current version of the database.  This is incompatible
+          with the --upgrade option.
+          </para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>
+         <option>--noconfirm</option>
+        </term>
+        <listitem>
+          <para>Only valid with --upgrade, this disables the prompt.
+          Normally the utility will print a warning that an upgrade is
+          about to take place and request that you type "Yes" to continue.
+          If this switch is given on the command line, no prompt will
+          be issued: the utility will just perform the upgrade.
+          </para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>
+         <option>--upgrade</option>
+        </term>
+        <listitem>
+          <para>Selects the upgrade function, which upgrades the database
+          to the latest version of the schema.  This is incompatible
+          with the --upgrade option.
+          </para>
+          <para>
+          The upgrade function will upgrade a BIND 10 database - no matter how
+          old the schema - preserving all data.  A backup file is created
+          before the upgrade (with the same name as the database, but with
+          ".backup" suffixed to it).  If the upgrade fails, this file can
+          be copied back to restore the original database.
+          </para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>
+         <option>--verbose</option>
+        </term>
+        <listitem>
+          <para>Enable verbose mode.  Each SQL command issued by the
+          utility will be printed to before it is executed.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>
+        <option><replaceable choice='req'>dbfile</replaceable></option>
+        </term>
+        <listitem>
+          <para>
+          Name of the database file to check of upgrade.
+          </para>
+        </listitem>
+      </varlistentry>
+
+
+    </variablelist>
+  </refsect1>
+</refentry>

+ 103 - 84
src/bin/dbutil/dbutil.py.in

@@ -15,23 +15,24 @@
 # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-# @file Dabase Utilities
-#
-# This file holds the "dbutil" program, a general utility program for doing
-# management of the BIND 10 database.  There are two modes of operation:
-#
-#       b10-dbutil --check [database]
-#       b10-dbutil --upgrade [--noconfirm] [database]
-#
-# The first form checks the version of the given database.  The second form
-# upgrades the database to the latest version of the schema, omitting the
-# warning prompt if --noconfirm is given.  In both cases, if the databas
-# file is not given on the command line, the default database will be accessed.
-#
-# For maximum safety, prior to the upgrade a backup database is created.
-# The is the database name with ".backup" appended to it (or ".backup-n" if
-# ".backup" already exists).  This is used to restore the database if the
-# upgrade fails.
+"""
+@file Dabase Utilities
+
+This file holds the "dbutil" program, a general utility program for doing
+management of the BIND 10 database.  There are two modes of operation:
+
+      b10-dbutil --check [--verbose] database
+      b10-dbutil --upgrade [--noconfirm] [--verbose] database
+
+The first form checks the version of the given database.  The second form
+upgrades the database to the latest version of the schema, omitting the
+warning prompt if --noconfirm is given.
+
+For maximum safety, prior to the upgrade a backup database is created.
+The is the database name with ".backup" appended to it (or ".backup-n" if
+".backup" already exists).  This is used to restore the database if the
+upgrade fails.
+"""
 
 import sys; sys.path.append("@@PYTHONPATH@@")
 import os, sqlite3, shutil
@@ -40,17 +41,13 @@ import isc.util.process
 
 isc.util.process.rename()
 
-# Default database to use if the database is not given on the command line.
-# (This is the same string as in "auth.spec.pre.in".)
-DEFAULT_DATABASE_FILE = "@@LOCALSTATEDIR@@/@PACKAGE@/zone.sqlite3"
-
+# @brief Version String
 # This is the version displayed to the user.  It comprises the module name,
 # the module version number, and the overall BIND 10 version number (set in
 # configure.ac)
 VERSION = "b10-dbutil 20120319 (BIND 10 @PACKAGE_VERSION@)"
 
-# Statements to update the database.
-#
+# @brief Statements to Update the Database
 # These are in the form of a list of dictionaries, each of which contains the
 # information to perform an incremental upgrade from one version of the
 # database to the next.  The information is:
@@ -70,8 +67,7 @@ VERSION = "b10-dbutil 20120319 (BIND 10 @PACKAGE_VERSION@)"
 # Note that apart from the 1.0 to 2.0 upgrade, no upgrade need alter the
 # schema_version table: that is done by the upgrade process using the
 # information in the "to" field.
-
-upgrades = [
+UPGRADES = [
     {'from': (1, 0), 'to': (2, 0),
         'statements': [
 
@@ -179,8 +175,10 @@ upgrades = [
 # program will be able to upgrade both a V1.0 and a V2.0 database.
 ]
 
-# Exception class to indicate error exit
 class DbutilException(Exception):
+    """
+    @brief Exception class to indicate error exit
+    """
     pass
 
 # Functions for outputting messages in a consistent format.  As this is intended
@@ -232,11 +230,13 @@ def info(text, ex = None):
     output(sys.stdout.write, "INFO", text, ex)
 
 
-# @brief Database Encapsulation
-#
-# Encapsulates the SQL database, both the connection and the cursor.  The
-# methods will cause a program exit on any error.
 class Database:
+    """
+    @brief Database Encapsulation
+
+    Encapsulates the SQL database, both the connection and the cursor.  The
+    methods will cause a program exit on any error.
+    """
     def __init__(self, db_file, verbose = False):
         """
         @brief Constructor
@@ -376,13 +376,37 @@ def version_string(version):
     return "V" + str(version[0]) + "." + str(version[1])
 
 
+def compare_versions(first, second):
+    """
+    @brief Compare Versions
+
+    Compares two database version numbers.
+
+    @param first First version number to check (in the form of a
+           "(major, minor)" tuple).
+    @param second Second version number to check (in the form of a
+           "(major, minor)" tuple).
+
+    @return -1, 0, +1 if "first" is <, ==, > "second"
+    """
+    if first == second:
+        return 0
+
+    elif ((first[0] < second[0]) or
+          ((first[0] == second[0]) and (first[1] < second[1]))):
+        return -1
+
+    else:
+        return 1
+
+
 def get_latest_version():
     """
-    @brief Returns the latest version of the database
+    @brief Returns the version to which this utility can upgrade the database
 
     This is the 'to' version held in the last element of the upgrades list
     """
-    return upgrades[-1]['to']
+    return UPGRADES[-1]['to']
 
 
 def get_version(db):
@@ -392,19 +416,12 @@ def get_version(db):
     @return Version of database in form (major version, minor version)
     """
 
-    # Check only one row of data in the version table.
-    db.execute("SELECT COUNT(*) FROM schema_version")
-    result = db.result()
-    if result[0] == 0:
-        raise DbutilException("unable to determine database version - " +
-                              "nothing in schema_version table")
-    elif result[0] > 1:
-        raise DbutilException("unable to determine database version - " +
-                              "too many rows in schema_version table")
-
     # Get the version information.
     db.execute("SELECT * FROM schema_version")
     result = db.result()
+    if result is None:
+        raise DbutilException("nothing in schema_version table")
+
     major = result[0]
     if (major == 1):
         # If the version number is 1, there will be no "minor" column, so
@@ -413,23 +430,41 @@ def get_version(db):
     else:
         minor = result[1]
 
+    result = db.result()
+    if result is not None:
+        raise DbutilException("too many rows in schema_version table")
+
     return (major, minor)
 
 
-def match_version(db, expected):
+def check_version(db):
     """
-    @brief Check database version against that expected
-
-    Checks whether the version of the database matches that expected for
-    the upgrade.  Both the major and minor versions must match.
+    @brief Check the version
 
-    @param db Database
-    @param expected Expected version of the database in form (major, minor)
+    Checks the version of the database and the latest version, and advises if
+    an upgrade is needed.
 
-    @return True if the versions match, false if they don't.
+    @param db Database object
     """
     current = get_version(db)
-    return expected == current
+    latest = get_latest_version()
+
+    match = compare_versions(current, latest)
+    if match == 0:
+        info("database version " + version_string(current))
+        info("this is the latest version of the database schema, " +
+             "no upgrade is required")
+
+    elif match < 0:
+        info("database version " + version_string(current) +
+             ", latest version is " + version_string(latest))
+        info("re-run this program with the --upgrade switch to upgrade")
+
+    else:
+        warn("database is at a later version (" + version_string(current) +
+             ") than this program can cope with (" +
+             version_string(get_latest_version()) + ")")
+        info("please get the latest version of b10-dbutil and re-run")
 
 
 def perform_upgrade(db, upgrade):
@@ -464,14 +499,18 @@ def perform_all_upgrades(db):
     For each upgrade, checks that the database is at the expected version.
     If so, calls perform_upgrade to update the database.
     """
-    if match_version(db, get_latest_version()):
+    match = compare_versions(get_version(db), get_latest_version())
+    if match == 0:
         info("database already at latest version, no upgrade necessary")
 
+    elif match > 0:
+        warn("database at a later version than this utility can support")
+
     else:
         # Work our way through all upgrade increments
         count = 0
-        for upgrade in upgrades:
-            if match_version(db, upgrade['from']):
+        for upgrade in UPGRADES:
+            if compare_versions(get_version(db), upgrade['from']) == 0:
                 perform_upgrade(db, upgrade)
                 count = count + 1
 
@@ -480,33 +519,9 @@ def perform_all_upgrades(db):
         else:
             # Should not get here, as we established earlier that the database
             # was not at the latest version so we should have upgraded.
-            # (Although it is possible that as version checks are for equality,
-            # an older version of dbutil was being run against a newer version
-            # of the database.)
-            raise DbutilException("database not at latest version but no " +
-                                  "upgrade was performed")
-
-
-def check_version(db):
-    """
-    @brief Check the version
-
-    Checks the version of the database and the latest version, and advises if
-    an upgrade is needed.
-
-    @param db Database object
-    """
-    current = get_version(db);
-    latest = get_latest_version()
-
-    if current == latest:
-        info("database version " + version_string(current))
-        info("this is the latest version of the database schema, " +
-             "no upgrade is required")
-    else:
-        info("database version " + version_string(current) +
-             ", latest version is " + version_string(latest))
-        info("re-run this program with the --upgrade switch to upgrade")
+            raise DbutilException("internal error in upgrade tool - no " +
+                                  "upgrade was performed on an old version " +
+                                  "the database")
 
 
 def parse_command():
@@ -517,8 +532,8 @@ def parse_command():
 
     @return Tuple of parser options and parser arguments
     """
-    usage = ("usage: %prog --check [options] [db_file]\n" +
-             "       %prog --upgrade [--noconfirm] [options] [db_file]")
+    usage = ("usage: %prog --check [options] db_file\n" +
+             "       %prog --upgrade [--noconfirm] [options] db_file")
     parser = OptionParser(usage = usage, version = VERSION)
     parser.add_option("-c", "--check", action="store_true",
                       dest="check", default=False,
@@ -541,7 +556,9 @@ def parse_command():
         parser.print_usage()
         sys.exit(1)
     elif len(args) == 0:
-        args.append(DEFAULT_DATABASE_FILE)
+        error("must supply name of the database file to upgrade")
+        parser.print_usage()
+        sys.exit(1)
 
     # Check for conflicting options.  If some are found, output a suitable
     # error message and print the usage.
@@ -600,3 +617,5 @@ if __name__ == "__main__":
     else:
         error("internal error, neither --check nor --upgrade selected")
         sys.exit(1)
+
+    sys.exit(0)

+ 1 - 1
src/bin/dbutil/tests/Makefile.am

@@ -1,4 +1,4 @@
-SUBDIRS = .
+SUBDIRS = . testdata
 
 # Tests of the update script.
 

+ 105 - 40
src/bin/dbutil/tests/dbutil_test.sh.in

@@ -35,7 +35,7 @@ succeed() {
 #
 # @param $1 Optional additional reason to output
 fail() {
-    if [ "x$1" != "x" ]
+    if [ "$1" != "" ]
     then
         echo "ERROR: $1"
     fi
@@ -68,6 +68,19 @@ failzero() {
 }
 
 
+# @brief Copy File
+#
+# Executes a "cp" operation followed by a "chmod" to make the target writeable.
+#
+# @param $1 Source file
+# @param $2 Target file
+copy_file () {
+    cp $1 $2
+    chmod a+w $2
+}
+
+
+
 # @brief Check backup file
 #
 # Record a failure if the backup file does not exist or if it is different
@@ -125,7 +138,7 @@ check_no_backup() {
 # @param $1 Database for which the schema is required
 get_schema() {
     db1=@abs_builddir@/dbutil_test_schema_$$
-    cp $1 $db1
+    copy_file $1 $db1
 
     db_schema=`sqlite3 $db1 '.schema' | \
                awk '{line = line $0} END {print line}' | \
@@ -145,8 +158,9 @@ get_schema() {
 #       on entry, and is responsible for removing them afterwards.
 #
 # @param $1 Database to upgrade
+# @param $2 Expected backup file
 upgrade_ok_test() {
-    cp $1 $tempfile
+    copy_file $1 $tempfile
     ../run_dbutil.sh --upgrade --noconfirm $tempfile
     if [ $? -eq 0 ]
     then
@@ -155,15 +169,18 @@ upgrade_ok_test() {
         expected_schema=$db_schema
         get_schema $tempfile
         actual_schema=$db_schema
-        if [ x$expected_schema = x$actual_schema ]
+        if [ "$expected_schema" = "$actual_schema" ]
         then
             succeed
         else
             fail "upgraded schema not as expected"
         fi
 
-        # and check the version is set correctly
+        # Check the version is set correctly
         check_version $tempfile "V2.0"
+
+        # Check that a backup was made
+        check_backup $1 $2
     else
         # Error should have been output already
         fail
@@ -171,6 +188,23 @@ upgrade_ok_test() {
 }
 
 
+# @brief Unsuccessful Upgrade Test
+#
+# Checks that an upgrade of the specified database fails.
+#
+# Note: the caller must ensure that $tempfile and $backupfile do not exist
+#       on entry, and is responsible for removing them afterwards.
+#
+# @param $1 Database to upgrade
+# @param $2 Expected backup file
+upgrade_fail_test() {
+    copy_file $1 $tempfile
+    ../run_dbutil.sh --upgrade --noconfirm $tempfile
+    failzero $?
+    check_backup $1 $backupfile
+}
+
+
 # @brief Record Count Test
 #
 # Checks that the count of records in each table is preserved in the upgrade.
@@ -181,7 +215,7 @@ upgrade_ok_test() {
 #
 # @brief $1 Database to upgrade
 record_count_test() {
-    cp $1 $tempfile
+    copy_file $1 $tempfile
 
     diffs_count=`sqlite3 $tempfile 'select count(*) from diffs'`
     nsec3_count=`sqlite3 $tempfile 'select count(*) from nsec3'`
@@ -233,7 +267,7 @@ record_count_test() {
 # @param $1 Database to check
 # @param $2 Expected version string
 check_version() {
-    cp $1 $verfile
+    copy_file $1 $verfile
     ../run_dbutil.sh --check $verfile
     if [ $? -ne 0 ]
     then
@@ -251,6 +285,20 @@ check_version() {
 }
 
 
+# @brief Version Check Fail
+#
+# Does a version check but expected the check to fail
+#
+# @param $1 Database to check
+# @param $2 Backup file
+check_version_fail() {
+    copy_file $1 $verfile
+    ../run_dbutil.sh --check $verfile
+    failzero $?
+    check_no_backup $tempfile $backupfile
+}
+
+
 # Main test sequence
 
 rm -f $tempfile $backupfile
@@ -271,9 +319,7 @@ rm -f $tempfile $backupfile
 # Test 2 - should fail to check an empty file and fail to upgrade it
 echo "2.1. Database is an empty file - check"
 touch $tempfile
-../run_dbutil.sh --check $tempfile
-failzero $?
-check_no_backup $tempfile $backupfile
+check_version_fail $tempfile $backupfile
 rm -f $tempfile $backupfile
 
 echo "2.2. Database is an empty file - upgrade"
@@ -287,11 +333,11 @@ rm -f $tempfile $backupfile
 
 echo "3.1. Database is not an SQLite file - check"
 echo "This is not an sqlite3 database" > $tempfile
-../run_dbutil.sh --check $tempfile
-failzero $?
-check_no_backup $tempfile $backupfile
+check_version_fail $tempfile $backupfile
+rm -f $tempfile $backupfile
 
 echo "3.2. Database is not an SQLite file - upgrade"
+echo "This is not an sqlite3 database" > $tempfile
 ../run_dbutil.sh --upgrade --noconfirm $tempfile
 failzero $?
 # ...and as before, a backup should have been created
@@ -300,17 +346,11 @@ rm -f $tempfile $backupfile
 
 
 echo "4.1. Database is an SQLite3 file without the schema table - check"
-cp $testdata/no_schema.sqlite3 $tempfile
-../run_dbutil.sh --check $tempfile
-failzero $?
-check_no_backup $tempfile $backupfile
+check_version_fail $testdata/no_schema.sqlite3 $backupfile
 rm -f $tempfile $backupfile
 
 echo "4.1. Database is an SQLite3 file without the schema table - upgrade"
-cp $testdata/no_schema.sqlite3 $tempfile
-../run_dbutil.sh --upgrade --noconfirm $tempfile
-failzero $?
-check_backup $testdata/no_schema.sqlite3 $backupfile
+upgrade_fail_test $testdata/no_schema.sqlite3 $backupfile
 rm -f $tempfile $backupfile
 
 
@@ -320,8 +360,7 @@ check_no_backup $tempfile $backupfile
 rm -f $tempfile $backupfile
 
 echo "5.2. Database is an old V1 database - upgrade"
-upgrade_ok_test $testdata/old_v1.sqlite3
-check_backup $testdata/old_v1.sqlite3 $backupfile
+upgrade_ok_test $testdata/old_v1.sqlite3 $backupfile
 rm -f $tempfile $backupfile
 
 
@@ -331,8 +370,7 @@ check_no_backup $tempfile $backupfile
 rm -f $tempfile $backupfile
 
 echo "6.2. Database is a new V1 database - upgrade"
-upgrade_ok_test $testdata/new_v1.sqlite3
-check_backup $testdata/new_v1.sqlite3 $backupfile
+upgrade_ok_test $testdata/new_v1.sqlite3 $backupfile
 rm -f $tempfile $backupfile
 
 
@@ -342,44 +380,71 @@ check_no_backup $tempfile $backupfile
 rm -f $tempfile $backupfile
 
 echo "7.2. Database is a V2.0 database - upgrade"
-upgrade_ok_test $testdata/v2_0.sqlite3
-check_backup $testdata/v2_0.sqlite3 $backupfile
+upgrade_ok_test $testdata/v2_0.sqlite3 $backupfile
 rm -f $tempfile $backupfile
 
 
-echo "8. Record count test"
-record_count_test testdata/new_v1.sqlite3
+echo "8.1. Database is V2.0 database with empty schema table - check"
+check_version_fail $testdata/empty_version.sqlite3 $backupfile
+rm -f $tempfile $backupfile
+
+echo "8.2. Database is V2.0 database with empty schema table - upgrade"
+upgrade_fail_test $testdata/empty_version.sqlite3 $backupfile
 rm -f $tempfile $backupfile
 
 
-echo "9. Backup file already exists"
+echo "9.1. Database is V2.0 database with over-full schema table - check"
+check_version_fail $testdata/too_many_version.sqlite3 $backupfile
+rm -f $tempfile $backupfile
+
+echo "9.2. Database is V2.0 database with over-full schema table - upgrade"
+upgrade_fail_test $testdata/too_many_version.sqlite3 $backupfile
+rm -f $tempfile $backupfile
+
+
+echo "10.0. Upgrade corrupt database"
+upgrade_fail_test $testdata/corrupt.sqlite3 $backupfile
+rm -f $tempfile $backupfile
+
+
+echo "11. Record count test"
+record_count_test $testdata/new_v1.sqlite3
+rm -f $tempfile $backupfile
+
+
+echo "12. Backup file already exists"
 touch $backupfile
 touch ${backupfile}-1
-upgrade_ok_test $testdata/v2_0.sqlite3
-check_backup $testdata/v2_0.sqlite3 ${backupfile}-2
+upgrade_ok_test $testdata/v2_0.sqlite3 ${backupfile}-2
 rm -f $tempfile $backupfile ${backupfile}-1 ${backupfile}-2
 
 
-echo "10.1 Command-line errors"
-cp $testdata/old_v1.sqlite3 $tempfile
+echo "13.1 Command-line errors"
+copy_file $testdata/old_v1.sqlite3 $tempfile
 ../run_dbutil.sh $tempfile
 failzero $?
 ../run_dbutil.sh --upgrade --check $tempfile
 failzero $?
 ../run_dbutil.sh --noconfirm --check $tempfile
 failzero $?
+../run_dbutil.sh --check
+failzero $?
+../run_dbutil.sh --upgrade --noconfirm
+failzero $?
 ../run_dbutil.sh --check $tempfile $backupfile
 failzero $?
+../run_dbutil.sh --upgrade --noconfirm $tempfile $backupfile
+failzero $?
 rm -f $tempfile $backupfile
 
-echo "10.2 verbose flag"
-cp $testdata/old_v1.sqlite3 $tempfile
+echo "13.2 verbose flag"
+copy_file $testdata/old_v1.sqlite3 $tempfile
 ../run_dbutil.sh --upgrade --noconfirm --verbose $tempfile
 passzero $?
 rm -f $tempfile $backupfile
 
-echo "10.3 Interactive prompt - yes"
-cp $testdata/old_v1.sqlite3 $tempfile
+echo "13.3 Interactive prompt - yes"
+copy_file $testdata/old_v1.sqlite3 $tempfile
 ../run_dbutil.sh --upgrade $tempfile << .
 Yes
 .
@@ -387,8 +452,8 @@ passzero $?
 check_version $tempfile "V2.0"
 rm -f $tempfile $backupfile
 
-echo "10.4 Interactive prompt - no"
-cp $testdata/old_v1.sqlite3 $tempfile
+echo "13.4 Interactive prompt - no"
+copy_file $testdata/old_v1.sqlite3 $tempfile
 ../run_dbutil.sh --upgrade $tempfile << .
 no
 .

+ 12 - 0
src/bin/dbutil/tests/testdata/Makefile.am

@@ -0,0 +1,12 @@
+EXTRA_DIST =
+EXTRA_DIST += corrupt.sqlite3
+EXTRA_DIST += empty_schema.sqlite3
+EXTRA_DIST += empty_v1.sqlite3
+EXTRA_DIST += empty_version.sqlite3
+EXTRA_DIST += invalid_v1.sqlite3
+EXTRA_DIST += new_v1.sqlite3
+EXTRA_DIST += no_schema.sqlite3
+EXTRA_DIST += old_v1.sqlite3
+EXTRA_DIST += README
+EXTRA_DIST += too_many_version.sqlite3
+EXTRA_DIST += v2_0.sqlite3

+ 6 - 0
src/bin/dbutil/tests/testdata/README

@@ -21,6 +21,9 @@ empty_v1.sqlite3: A database conforming to the new V1 schema.
 The database is empty, except for the schema_version table, where the
 "version" column is set to 1.
 
+empty_version.sqlite3: A database conforming to the V2.0 schema but without
+anything in the schema_version table.
+
 no_schema.sqlite3: A valid SQLite3 database, but without a schema_version
 table.
 
@@ -33,3 +36,6 @@ is marked as V1, does not have the nsec3 table.
 new_v1.sqlite3: A valid SQLite3 database with data in all the tables
 (although the single rows in both the nsec3 and diffs table make no
 sense, but are valid).
+
+too_many_version.sqlite3: A database conforming to the V2.0 schema but with
+too many rows of data.

BIN
src/bin/dbutil/tests/testdata/corrupt.sqlite3


BIN
src/bin/dbutil/tests/testdata/empty_version.sqlite3


BIN
src/bin/dbutil/tests/testdata/too_many_version.sqlite3