]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#526,!269] - MySQL unit tests now wipe data, instead of schema
authorThomas Markwalder <tmark@isc.org>
Fri, 8 Mar 2019 17:06:38 +0000 (12:06 -0500)
committerThomas Markwalder <tmark@isc.org>
Fri, 8 Mar 2019 17:09:14 +0000 (12:09 -0500)
src/share/database/scripts/mysql/wipe_data.sh.in -
    New shell script which intelligently deletes data from
    the schema IF the schema version matches the expected version

src/lib/mysql/testutils/mysql_schema.*
    destroyMySQLSchema() - modfied to default to calling
    wipeData(), and only destroying the schema if that fails
    or by force flag = true;

    createMySQLSchema() - modified to default to calling
    wipeData(), and only recreating the schema if that
    fails or by force flag = true;

    wipeData() - new method which runs the
    MySQL wipe_data.sh shell script, passing in the expected
    schema version.

src/share/database/scripts/mysql/dhcpdb_create.mysql
    createAuditRevisionDHCP4()
    createAuditEntryDHCP4()
    createAuditRevisionDHCP6()
    createAuditEntryDHCP6() - added session variable,
    @disable_audit, to allow procedures to be "turned
    off" during data wiping.

src/hooks/dhcp/mysql_cb/tests/mysql_cb_dhcp4_mgr_unittest.cc
src/hooks/dhcp/mysql_cb/tests/mysql_cb_dhcp4_unittest.cc
src/lib/dhcpsrv/tests/cfg_db_access_unittest.cc
src/lib/dhcpsrv/tests/host_mgr_unittest.cc
src/lib/dhcpsrv/tests/mysql_host_data_source_unittest.cc
src/lib/dhcpsrv/tests/mysql_lease_mgr_unittest.cc
    Removed calls to destroy schema from test constructors

13 files changed:
configure.ac
src/hooks/dhcp/mysql_cb/tests/mysql_cb_dhcp4_mgr_unittest.cc
src/hooks/dhcp/mysql_cb/tests/mysql_cb_dhcp4_unittest.cc
src/lib/dhcpsrv/tests/cfg_db_access_unittest.cc
src/lib/dhcpsrv/tests/host_mgr_unittest.cc
src/lib/dhcpsrv/tests/mysql_host_data_source_unittest.cc
src/lib/dhcpsrv/tests/mysql_lease_mgr_unittest.cc
src/lib/mysql/testutils/mysql_schema.cc
src/lib/mysql/testutils/mysql_schema.h
src/share/database/scripts/mysql/Makefile.am
src/share/database/scripts/mysql/dhcpdb_create.mysql
src/share/database/scripts/mysql/upgrade_7.0_to_8.0.sh.in
src/share/database/scripts/mysql/wipe_data.sh.in [new file with mode: 0644]

index 5491715675cb2ea91764f9753cf871f03a90c842..69fde01b2b88655543bd062750c503233707b0a8 100644 (file)
@@ -1696,6 +1696,7 @@ AC_CONFIG_FILES([Makefile
                  src/share/database/scripts/mysql/upgrade_5.2_to_6.0.sh
                  src/share/database/scripts/mysql/upgrade_6.0_to_7.0.sh
                  src/share/database/scripts/mysql/upgrade_7.0_to_8.0.sh
+                 src/share/database/scripts/mysql/wipe_data.sh
                  src/share/database/scripts/pgsql/Makefile
                  src/share/database/scripts/pgsql/upgrade_1.0_to_2.0.sh
                  src/share/database/scripts/pgsql/upgrade_2.0_to_3.0.sh
index 8aa67e809a56a4f670f5f10e49f59aaebee9a6fa..ab26ec7d691f3bcb6cf685826afaa51ddaae4086 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2019 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -30,7 +30,6 @@ public:
         ConfigBackendDHCPv4Mgr::create();
 
         // Recreate database schema.
-        destroyMySQLSchema();
         createMySQLSchema();
     }
 
index de1529d3333004634d33dfd82809ed3fdebecdb5..102e521cc8f86148620d507c925fce1819faf087 100644 (file)
@@ -48,7 +48,6 @@ public:
     MySqlConfigBackendDHCPv4Test()
         : test_subnets_(), test_networks_(), timestamps_(), audit_entries_() {
         // Recreate database schema.
-        destroyMySQLSchema();
         createMySQLSchema();
 
         try {
index e57a6793ecd6f42ddaffc64db94583028d066c4d..22ce7306aaff0e514cfe947139215df74f8e1d59 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2016-2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2016-2019 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -148,7 +148,6 @@ public:
     /// @brief Constructor.
     CfgMySQLDbAccessTest() {
         // Ensure schema is the correct one.
-        destroyMySQLSchema();
         createMySQLSchema();
     }
 
index 45091377c2ae2e99ece70ca76e8e4bf31582c8e3..adba8f904e1d25429a1f854696caf251fb3655be 100644 (file)
@@ -258,7 +258,7 @@ void
 HostMgrTest::testGetAll(BaseHostDataSource& data_source1,
                         BaseHostDataSource& data_source2) {
     // Initially, no reservations should be present.
-    ConstHostCollection hosts = 
+    ConstHostCollection hosts =
         HostMgr::instance().getAll(Host::IDENT_HWADDR,
                                    &hwaddrs_[1]->hwaddr_[0],
                                    hwaddrs_[1]->hwaddr_.size());
@@ -863,7 +863,7 @@ public:
     /// appropriate schema and create a basic host manager to
     /// wipe out any prior instance
     virtual void SetUp() {
-        DatabaseConnection::db_lost_callback = 0;  
+        DatabaseConnection::db_lost_callback = 0;
         destroySchema();
         createSchema();
         // Wipe out any pre-existing mgr
@@ -875,7 +875,7 @@ public:
     /// Invoked by gtest upon test exit, we destroy the schema
     /// we created.
     virtual void TearDown() {
-        DatabaseConnection::db_lost_callback = 0;  
+        DatabaseConnection::db_lost_callback = 0;
         destroySchema();
     }
 
@@ -972,7 +972,6 @@ MySQLHostMgrTest::SetUp() {
     HostMgrTest::SetUp();
 
     // Ensure schema is the correct one.
-    db::test::destroyMySQLSchema();
     db::test::createMySQLSchema();
 
     // Connect to the database
index 57c3258d15bdd39b215b200ee930925c9b7beea2..13a8b6320e5c1f3e17d7b7528e3524bc617423b9 100644 (file)
@@ -42,7 +42,6 @@ public:
     /// @brief Clears the database and opens connection to it.
     void initializeTest() {
         // Ensure schema is the correct one.
-        destroyMySQLSchema();
         createMySQLSchema();
 
         // Connect to the database
@@ -158,7 +157,6 @@ public:
 TEST(MySqlHostDataSource, OpenDatabase) {
 
     // Schema needs to be created for the test to work.
-    destroyMySQLSchema();
     createMySQLSchema();
 
     // Check that host manager open the database opens correctly and tidy up.
index 851fbc777a0f1fe412338338e9e164030a87ce81..23abb1d7492255a8528b58c943e7e66c7305713a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2012-2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2012-2019 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -44,7 +44,6 @@ public:
     /// @brief Clears the database and opens connection to it.
     void initializeTest() {
         // Ensure schema is the correct one.
-        destroyMySQLSchema();
         createMySQLSchema();
 
         // Connect to the database
@@ -110,7 +109,6 @@ public:
 /// opened: the fixtures assume that and check basic operations.
 TEST(MySqlOpenTest, OpenDatabase) {
     // Schema needs to be created for the test to work.
-    destroyMySQLSchema(true);
     createMySQLSchema(true);
 
     // Check that lease manager open the database opens correctly and tidy up.
index 93ed9418c2df5600b16b8db8ef94a5fd66c61d76..7d7e9a85904c2531c8714a4572a8cd796a659e7a 100644 (file)
@@ -30,12 +30,40 @@ validMySQLConnectionString() {
                              VALID_USER, VALID_PASSWORD));
 }
 
-void destroyMySQLSchema(bool show_err) {
-    runMySQLScript(DATABASE_SCRIPTS_DIR, "mysql/dhcpdb_drop.mysql", show_err);
+void destroyMySQLSchema(bool show_err, bool force) {
+    // If force is true or wipeData() fails, destory the schema.
+    if (force || wipeData(show_err)) {
+        runMySQLScript(DATABASE_SCRIPTS_DIR, "mysql/dhcpdb_drop.mysql", show_err);
+    }
+}
+
+void createMySQLSchema(bool show_err, bool force) {
+    // If force is true or wipeData() fails, recreate the schema.
+    if (force || wipeData(show_err)) {
+        destroyMySQLSchema(show_err, true);
+        runMySQLScript(DATABASE_SCRIPTS_DIR, "mysql/dhcpdb_create.mysql", show_err);
+    }
 }
 
-void createMySQLSchema(bool show_err) {
-    runMySQLScript(DATABASE_SCRIPTS_DIR, "mysql/dhcpdb_create.mysql", show_err);
+bool wipeData(bool show_err) {
+    std::ostringstream cmd;
+    cmd << "sh " << DATABASE_SCRIPTS_DIR << "/";
+
+    std::ostringstream version;
+    version << MYSQL_SCHEMA_VERSION_MAJOR  << "." << MYSQL_SCHEMA_VERSION_MINOR;
+
+    cmd << "mysql/wipe_data.sh" << " " << version.str()
+        << " -N -B --user=keatest --password=keatest keatest";
+    if (!show_err) {
+        cmd << " 2>/dev/null ";
+    }
+
+    int retval = ::system(cmd.str().c_str());
+    if (retval) {
+        std::cerr << "wipeData failed:[" << cmd.str() << "]" << std::endl;
+    }
+
+    return(retval);
 }
 
 void runMySQLScript(const std::string& path, const std::string& script_name,
index 9457a3341cb5ebfac8ed251f618e6abaed89b99b..fc5bce3146f2f1ef0b3dcf98b49b7c04869f3b2f 100644 (file)
@@ -22,31 +22,58 @@ extern const char* MYSQL_VALID_TYPE;
 /// @return valid MySQL connection string.
 std::string validMySQLConnectionString();
 
-/// @brief Clear everything from the database
+/// @brief Clear the unit test database
 ///
-/// Submits the current schema drop script:
+/// Either calls @c wipeData to wipe the data from the
+/// database /or destroys the database itself by submitting the
+/// SQL script:
 ///
-///  <TEST_ADMIN_SCRIPTS_DIR>/mysql/dhcpdb_drop.mysql
+///  <TEST_ADMIN_SCRIPTS_DIR>/mysql/dhcpdb_drop.sh
 ///
-/// to the unit test MySQL database. If the script fails, the invoking test
-/// will fail. The output of stderr is suppressed unless the parameter,
+/// If wipeData() is called and fails, it will destroy
+/// the schema. If the schema destruction fails, the
+/// invoking test should fail.
+///
+/// The output stderr is suppressed unless the parameter,
 /// show_err is true.
 ///
 /// @param show_err flag which governs whether or not stderr is suppressed.
-void destroyMySQLSchema(bool show_err = false);
+/// @param force if true, the function will simply destroy the schema.
+void destroyMySQLSchema(bool show_err = false, bool force = false);
 
-/// @brief Create the MySQL Schema
+/// @brief Create the unit test MySQL Schema
 ///
-/// Submits the current schema creation script:
+/// Ensures the unit test database is a empty and version-correct.
+/// Unless, the force parameter is true, it will first attempt
+/// to wipe the data from the database by calling @c wipeData.
+/// If this call succeeds the function returns, otherwise it will
+/// will call @c destroyMySQLSchema to forcibly remove the
+/// existing schema and then submits the SQL script:
 ///
 ///  <TEST_ADMIN_SCRIPTS_DIR>/mysql/dhcpdb_create.mysql
 ///
-/// to the unit test MySQL database. If the script fails, the invoking test
-/// will fail. The output of stderr is suppressed unless the parameter,
-/// show_err is true.
+/// to the unit test MySQL database.
+///
+/// @param show_err flag which governs whether or not stderr is suppressed.
+/// @param force flag when true, the function will recreate the database
+/// schema.
+void createMySQLSchema(bool show_err = false, bool force = false);
+
+
+/// @brief Attempts to wipe data from the MySQL unit test database
+///
+/// Runs the shell script
+///
+///  <TEST_ADMIN_SCRIPTS_DIR>/mysql/wipe_data.sh
+///
+/// This will fail if there is no schema, if the existing schema
+/// version is incorrect (i.e. does not match MYSQL_SCHEMA_VERSION_MAJOR
+/// and MYSQL_SCHEMA_VERSION_MINOR), or a SQL error occurs.  Otherwise,
+/// the script is should delete all transient data, leaving intact
+/// reference tables.
 ///
 /// @param show_err flag which governs whether or not stderr is suppressed.
-void createMySQLSchema(bool show_err = false);
+bool wipeData(bool show_err = false);
 
 /// @brief Run a MySQL SQL script against the MySQL unit test database
 ///
index fdf0f41e63eaedbdf6ab9da969a1d02c1afe8ee7..61263c38d2e58f8287b1abc14e7aab08c727d9e6 100644 (file)
@@ -13,6 +13,7 @@ sqlscripts_DATA += upgrade_5.1_to_5.2.sh
 sqlscripts_DATA += upgrade_5.2_to_6.0.sh
 sqlscripts_DATA += upgrade_6.0_to_7.0.sh
 sqlscripts_DATA += upgrade_7.0_to_8.0.sh
+sqlscripts_DATA += wipe_data.sh
 
 DISTCLEANFILES = upgrade_1.0_to_2.0.sh
 DISTCLEANFILES += upgrade_2.0_to_3.0.sh
@@ -24,5 +25,6 @@ DISTCLEANFILES += upgrade_5.1_to_5.2.sh
 DISTCLEANFILES += upgrade_5.2_to_6.0.sh
 DISTCLEANFILES += upgrade_6.0_to_7.0.sh
 DISTCLEANFILES += upgrade_7.0_to_8.0.sh
+DISTCLEANFILES += wipe_data.sh
 
 EXTRA_DIST = ${sqlscripts_DATA}
index 01526513f004eb06ad2f0a8782d63e1d79f385b3..1e01cdcfa124e5c134a384755c11adc37d44d694 100644 (file)
@@ -1543,6 +1543,10 @@ ALTER TABLE dhcp4_audit
 --   hand, if the global option is being added, the
 --   audit entry for the option must be created because
 --   it is the sole object modified in that case.
+--   Session variable disable_audit is used to disable
+--   the procedure when wiping the database during
+--   unit tests.  This avoids issues with revision_id
+--   being null.
 -- -----------------------------------------------------
 DROP PROCEDURE IF EXISTS createAuditRevisionDHCP4;
 DELIMITER $$
@@ -1552,11 +1556,13 @@ CREATE PROCEDURE createAuditRevisionDHCP4(IN audit_ts TIMESTAMP,
                                           IN cascade_transaction TINYINT(1))
 BEGIN
     DECLARE srv_id BIGINT(20);
-    SELECT id INTO srv_id FROM dhcp4_server WHERE tag = server_tag;
-    INSERT INTO dhcp4_audit_revision (modification_ts, server_id, log_message)
-       VALUES (audit_ts, srv_id, audit_log_message);
-    SET @audit_revision_id = LAST_INSERT_ID();
-    SET @cascade_transaction = cascade_transaction;
+    IF @disable_audit IS NULL OR @disable_audit = 0 THEN
+        SELECT id INTO srv_id FROM dhcp4_server WHERE tag = server_tag;
+        INSERT INTO dhcp4_audit_revision (modification_ts, server_id, log_message)
+            VALUES (audit_ts, srv_id, audit_log_message);
+        SET @audit_revision_id = LAST_INSERT_ID();
+        SET @cascade_transaction = cascade_transaction;
+    END IF;
 END $$
 DELIMITER ;
 
@@ -1575,6 +1581,10 @@ DELIMITER ;
 -- - modification_type_val: string value indicating the
 --   type of the change, i.e. "create", "update" or
 --   "delete".
+--   Session variable disable_audit is used to disable
+--   the procedure when wiping the database during
+--   unit tests.  This avoids issues with revision_id
+--   being null.
 -- ----------------------------------------------------
 DROP PROCEDURE IF EXISTS createAuditEntryDHCP4;
 DELIMITER $$
@@ -1582,10 +1592,12 @@ CREATE PROCEDURE createAuditEntryDHCP4(IN object_type_val VARCHAR(256),
                                        IN object_id_val BIGINT(20) UNSIGNED,
                                        IN modification_type_val VARCHAR(32))
 BEGIN
-    INSERT INTO dhcp4_audit (object_type, object_id, modification_type, revision_id)
-        VALUES (object_type_val, object_id_val, \
+    IF @disable_audit IS NULL OR @disable_audit = 0 THEN
+        INSERT INTO dhcp4_audit (object_type, object_id, modification_type, revision_id)
+            VALUES (object_type_val, object_id_val, \
                (SELECT id FROM modification WHERE modification_type = modification_type_val), \
                 @audit_revision_id);
+    END IF;
 END $$
 DELIMITER ;
 
@@ -1955,6 +1967,10 @@ ALTER TABLE dhcp6_audit
 --   hand, if the global option is being added, the
 --   audit entry for the option must be created because
 --   it is the sole object modified in that case.
+--   Session variable disable_audit is used to disable
+--   the procedure when wiping the database during
+--   unit tests.  This avoids issues with revision_id
+--   being null.
 -- -----------------------------------------------------
 DROP PROCEDURE IF EXISTS createAuditRevisionDHCP6;
 DELIMITER $$
@@ -1964,11 +1980,13 @@ CREATE PROCEDURE createAuditRevisionDHCP6(IN audit_ts TIMESTAMP,
                                           IN cascade_transaction TINYINT(1))
 BEGIN
     DECLARE srv_id BIGINT(20);
-    SELECT id INTO srv_id FROM dhcp6_server WHERE tag = server_tag;
-    INSERT INTO dhcp6_audit_revision (modification_ts, server_id, log_message)
-       VALUES (audit_ts, srv_id, audit_log_message);
-    SET @audit_revision_id = LAST_INSERT_ID();
-    SET @cascade_transaction = cascade_transaction;
+    IF @disable_audit IS NULL OR @disable_audit = 0 THEN
+        SELECT id INTO srv_id FROM dhcp6_server WHERE tag = server_tag;
+        INSERT INTO dhcp6_audit_revision (modification_ts, server_id, log_message)
+            VALUES (audit_ts, srv_id, audit_log_message);
+        SET @audit_revision_id = LAST_INSERT_ID();
+        SET @cascade_transaction = cascade_transaction;
+    END IF;
 END $$
 DELIMITER ;
 
@@ -1987,6 +2005,10 @@ DELIMITER ;
 -- - modification_type_val: string value indicating the
 --   type of the change, i.e. "create", "update" or
 --   "delete".
+--   Session variable disable_audit is used to disable
+--   the procedure when wiping the database during
+--   unit tests.  This avoids issues with revision_id
+--   being null.
 -- ----------------------------------------------------
 DROP PROCEDURE IF EXISTS createAuditEntryDHCP6;
 DELIMITER $$
@@ -1994,10 +2016,12 @@ CREATE PROCEDURE createAuditEntryDHCP6(IN object_type_val VARCHAR(256),
                                        IN object_id_val BIGINT(20) UNSIGNED,
                                        IN modification_type_val VARCHAR(32))
 BEGIN
-    INSERT INTO dhcp6_audit (object_type, object_id, modification_type, revision_id)
-        VALUES (object_type_val, object_id_val, \
+    IF @disable_audit IS NULL OR @disable_audit = 0 THEN
+        INSERT INTO dhcp6_audit (object_type, object_id, modification_type, revision_id)
+            VALUES (object_type_val, object_id_val, \
                (SELECT id FROM modification WHERE modification_type = modification_type_val), \
                 @audit_revision_id);
+    END IF;
 END $$
 DELIMITER ;
 
index b574a47ce00d790d00a3c50e169c10f9b919c6a4..c76e94d09385f83e59715ea84dadf3e78d989cda 100644 (file)
@@ -225,6 +225,10 @@ ALTER TABLE dhcp4_audit
 --   hand, if the global option is being added, the
 --   audit entry for the option must be created because
 --   it is the sole object modified in that case.
+--   Session variable disable_audit is used to disable
+--   the procedure when wiping the database during
+--   unit tests.  This avoids issues with revision_id
+--   being null.
 -- -----------------------------------------------------
 DROP PROCEDURE IF EXISTS createAuditRevisionDHCP4;
 DELIMITER $$
@@ -234,11 +238,13 @@ CREATE PROCEDURE createAuditRevisionDHCP4(IN audit_ts TIMESTAMP,
                                           IN cascade_transaction TINYINT(1))
 BEGIN
     DECLARE srv_id BIGINT(20);
-    SELECT id INTO srv_id FROM dhcp4_server WHERE tag = server_tag;
-    INSERT INTO dhcp4_audit_revision (modification_ts, server_id, log_message)
-       VALUES (audit_ts, srv_id, audit_log_message);
-    SET @audit_revision_id = LAST_INSERT_ID();
-    SET @cascade_transaction = cascade_transaction;
+    IF @disable_audit IS NULL OR @disable_audit = 0 THEN
+        SELECT id INTO srv_id FROM dhcp4_server WHERE tag = server_tag;
+        INSERT INTO dhcp4_audit_revision (modification_ts, server_id, log_message)
+            VALUES (audit_ts, srv_id, audit_log_message);
+        SET @audit_revision_id = LAST_INSERT_ID();
+        SET @cascade_transaction = cascade_transaction;
+    END IF;
 END $$
 DELIMITER ;
 
@@ -257,6 +263,10 @@ DELIMITER ;
 -- - modification_type_val: string value indicating the
 --   type of the change, i.e. "create", "update" or
 --   "delete".
+--   Session variable disable_audit is used to disable
+--   the procedure when wiping the database during
+--   unit tests.  This avoids issues with revision_id
+--   being null.
 -- ----------------------------------------------------
 DROP PROCEDURE IF EXISTS createAuditEntryDHCP4;
 DELIMITER $$
@@ -264,10 +274,12 @@ CREATE PROCEDURE createAuditEntryDHCP4(IN object_type_val VARCHAR(256),
                                        IN object_id_val BIGINT(20) UNSIGNED,
                                        IN modification_type_val VARCHAR(32))
 BEGIN
-    INSERT INTO dhcp4_audit (object_type, object_id, modification_type, revision_id)
-        VALUES (object_type_val, object_id_val, \
-               (SELECT id FROM modification WHERE modification_type = modification_type_val), \
-                @audit_revision_id);
+    IF @disable_audit IS NULL OR @disable_audit = 0 THEN
+        INSERT INTO dhcp4_audit (object_type, object_id, modification_type, revision_id)
+            VALUES (object_type_val, object_id_val, \
+                (SELECT id FROM modification WHERE modification_type = modification_type_val), \
+                 @audit_revision_id);
+    END IF;
 END $$
 DELIMITER ;
 
@@ -637,6 +649,10 @@ ALTER TABLE dhcp6_audit
 --   hand, if the global option is being added, the
 --   audit entry for the option must be created because
 --   it is the sole object modified in that case.
+--   Session variable disable_audit is used to disable
+--   the procedure when wiping the database during
+--   unit tests.  This avoids issues with revision_id
+--   being null.
 -- -----------------------------------------------------
 DROP PROCEDURE IF EXISTS createAuditRevisionDHCP6;
 DELIMITER $$
@@ -646,11 +662,13 @@ CREATE PROCEDURE createAuditRevisionDHCP6(IN audit_ts TIMESTAMP,
                                           IN cascade_transaction TINYINT(1))
 BEGIN
     DECLARE srv_id BIGINT(20);
-    SELECT id INTO srv_id FROM dhcp6_server WHERE tag = server_tag;
-    INSERT INTO dhcp6_audit_revision (modification_ts, server_id, log_message)
-       VALUES (audit_ts, srv_id, audit_log_message);
-    SET @audit_revision_id = LAST_INSERT_ID();
-    SET @cascade_transaction = cascade_transaction;
+    IF @disable_audit IS NULL OR @disable_audit = 0 THEN
+        SELECT id INTO srv_id FROM dhcp6_server WHERE tag = server_tag;
+        INSERT INTO dhcp6_audit_revision (modification_ts, server_id, log_message)
+            VALUES (audit_ts, srv_id, audit_log_message);
+        SET @audit_revision_id = LAST_INSERT_ID();
+        SET @cascade_transaction = cascade_transaction;
+    END IF;
 END $$
 DELIMITER ;
 
@@ -669,6 +687,10 @@ DELIMITER ;
 -- - modification_type_val: string value indicating the
 --   type of the change, i.e. "create", "update" or
 --   "delete".
+--   Session variable disable_audit is used to disable
+--   the procedure when wiping the database during
+--   unit tests.  This avoids issues with revision_id
+--   being null.
 -- ----------------------------------------------------
 DROP PROCEDURE IF EXISTS createAuditEntryDHCP6;
 DELIMITER $$
@@ -676,10 +698,12 @@ CREATE PROCEDURE createAuditEntryDHCP6(IN object_type_val VARCHAR(256),
                                        IN object_id_val BIGINT(20) UNSIGNED,
                                        IN modification_type_val VARCHAR(32))
 BEGIN
-    INSERT INTO dhcp6_audit (object_type, object_id, modification_type, revision_id)
-        VALUES (object_type_val, object_id_val, \
+    IF @disable_audit IS NULL OR @disable_audit = 0 THEN
+        INSERT INTO dhcp6_audit (object_type, object_id, modification_type, revision_id)
+            VALUES (object_type_val, object_id_val, \
                (SELECT id FROM modification WHERE modification_type = modification_type_val), \
                 @audit_revision_id);
+    END IF;
 END $$
 DELIMITER ;
 
diff --git a/src/share/database/scripts/mysql/wipe_data.sh.in b/src/share/database/scripts/mysql/wipe_data.sh.in
new file mode 100644 (file)
index 0000000..3b59010
--- /dev/null
@@ -0,0 +1,90 @@
+# Copyright (C) 2019 Internet Systems Consortium, Inc. ("ISC")
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#!/bin/sh
+
+# This script is primarily used for MySQL unit tests, which need to
+# ensure an empty, but schema correct database for each test.  It
+# deletes ALL transient data from an existing Kea MySQL schema,
+# including leases, reservations, etc... Use at your own peril.
+# Reference tables will be left in-tact.
+
+# Include utilities. Use installed version if available and
+# use build version if it isn't.
+if [ -e @datarootdir@/@PACKAGE_NAME@/scripts/admin-utils.sh ]; then
+    . @datarootdir@/@PACKAGE_NAME@/scripts/admin-utils.sh
+else
+    . @abs_top_builddir@/src/bin/admin/admin-utils.sh
+fi
+
+# First argument is must be the expected schema version <major>.<minor>
+exp_version="$1"
+shift;
+
+# Remaining arguments are used as mysql command line arguments
+
+# If the existing schema doesn't match, the fail
+VERSION=`mysql_version "$@"`
+if [ "$VERSION" != "$exp_version" ]; then
+    printf "Reported version is $VERSION is wrong, expected $exp_version.\n"
+    exit 1
+fi
+
+# Delete transient data from tables.  Per MySQL documentation TRUNCATE
+# destroys and there recreates tables.  As schema updates are typically
+# very slow, we're use deletes here.  We turn off foreign key checks to
+# worrying about table order.  We also set the session variable
+# disable_audit to turn off  Back audit procedures, to avoid attempting
+# to create entries for deleted records.
+mysql "$@" <<EOF
+START TRANSACTION;
+SET SESSION FOREIGN_KEY_CHECKS = 0;
+SET @disable_audit = 1;
+
+DELETE FROM dhcp4_global_parameter;
+DELETE FROM dhcp4_global_parameter_server;
+DELETE FROM dhcp4_option_def;
+DELETE FROM dhcp4_option_def_server;
+DELETE FROM dhcp4_options;
+DELETE FROM dhcp4_options_server;
+DELETE FROM dhcp4_pool;
+# preserve special server "all"
+DELETE FROM dhcp4_server WHERE tag != "all";
+DELETE FROM dhcp4_shared_network;
+DELETE FROM dhcp4_shared_network_server;
+DELETE FROM dhcp4_subnet;
+DELETE FROM dhcp4_subnet_server;
+DELETE FROM dhcp4_audit_revision;
+DELETE FROM dhcp4_audit;
+DELETE FROM dhcp6_global_parameter;
+DELETE FROM dhcp6_global_parameter_server;
+DELETE FROM dhcp6_option_def;
+DELETE FROM dhcp6_option_def_server;
+DELETE FROM dhcp6_options;
+DELETE FROM dhcp6_options_server;
+DELETE FROM dhcp6_pd_pool;
+DELETE FROM dhcp6_pool;
+# preserve special server "all"
+DELETE FROM dhcp6_server WHERE tag != "all";
+DELETE FROM dhcp6_shared_network;
+DELETE FROM dhcp6_shared_network_server;
+DELETE FROM dhcp6_subnet;
+DELETE FROM dhcp6_subnet_server;
+DELETE FROM dhcp6_audit;
+DELETE FROM dhcp6_audit_revision;
+DELETE FROM hosts;
+DELETE FROM ipv6_reservations;
+DELETE FROM lease4;
+DELETE FROM lease4_stat;
+DELETE FROM lease6;
+DELETE FROM lease6_stat;
+DELETE FROM logs;
+COMMIT;
+EOF
+
+RESULT=$?
+
+exit $RESULT