Add tests for logging functionality to ensure the tables are still creating well
authoreileen <emcnaughton@wikimedia.org>
Wed, 9 Mar 2016 03:37:34 +0000 (16:37 +1300)
committereileenmcnaugton <eileen@fuzion.co.nz>
Thu, 21 Apr 2016 22:56:23 +0000 (10:56 +1200)
Change-Id: I6ef4d48d16e25d232b0f46e7ce3cf5d569e7053c

CRM/Logging/Schema.php
tests/phpunit/api/v3/LoggingTest.php [new file with mode: 0644]

index cd3f512164228a2c037cc71907913067252622bd..b64452a270aab7678a6613507b93010adaa440ee 100644 (file)
@@ -662,9 +662,7 @@ COLS;
    * Predicate whether logging is enabled.
    */
   public function isEnabled() {
-    $config = CRM_Core_Config::singleton();
-
-    if ($config->logging) {
+    if (CRM_Core_Config::singleton()->logging) {
       return $this->tablesExist() and $this->triggersExist();
     }
     return FALSE;
@@ -677,6 +675,19 @@ COLS;
     return !empty($this->logs);
   }
 
+  /**
+   * Drop all log tables.
+   *
+   * This does not currently have a usage outside the tests.
+   */
+  public function dropAllLogTables() {
+    if ($this->tablesExist()) {
+      foreach ($this->logs as $log_table) {
+        CRM_Core_DAO::executeQuery("DROP TABLE $log_table");
+      }
+    }
+  }
+
   /**
    * Get an sql clause to find the names of any log tables that do not match the normal pattern.
    *
diff --git a/tests/phpunit/api/v3/LoggingTest.php b/tests/phpunit/api/v3/LoggingTest.php
new file mode 100644 (file)
index 0000000..7e885b0
--- /dev/null
@@ -0,0 +1,149 @@
+<?php
+/*
+ +--------------------------------------------------------------------+
+| CiviCRM version 4.7                                                |
++--------------------------------------------------------------------+
+| Copyright CiviCRM LLC (c) 2004-2015                                |
++--------------------------------------------------------------------+
+| This file is a part of CiviCRM.                                    |
+|                                                                    |
+| CiviCRM is free software; you can copy, modify, and distribute it  |
+| under the terms of the GNU Affero General Public License           |
+| Version 3, 19 November 2007 and the CiviCRM Licensing Exception.   |
+|                                                                    |
+| CiviCRM is distributed in the hope that it will be useful, but     |
+| WITHOUT ANY WARRANTY; without even the implied warranty of         |
+| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.               |
+| See the GNU Affero General Public License for more details.        |
+|                                                                    |
+| You should have received a copy of the GNU Affero General Public   |
+| License and the CiviCRM Licensing Exception along                  |
+| with this program; if not, contact CiviCRM LLC                     |
+| at info[AT]civicrm[DOT]org. If you have questions about the        |
+| GNU Affero General Public License or the licensing of CiviCRM,     |
+| see the CiviCRM license FAQ at http://civicrm.org/licensing        |
++--------------------------------------------------------------------+
+ */
+
+/**
+ * Test class for Logging API.
+ *
+ * @package CiviCRM
+ * @group headless
+ */
+class api_v3_LoggingTest extends CiviUnitTestCase {
+
+  /**
+   * Sets up the fixture, for example, opens a network connection.
+   *
+   * This method is called before a test is executed.
+   */
+  protected function setUp() {
+    parent::setUp();
+  }
+
+  /**
+   * Clean up log tables.
+   */
+  protected function tearDown() {
+    parent::tearDown();
+    $this->callAPISuccess('Setting', 'create', array('logging' => FALSE));
+    $schema = new CRM_Logging_Schema();
+    $schema->dropAllLogTables();
+    CRM_Core_DAO::executeQuery("DELETE FROM civicrm_setting WHERE name LIKE 'logg%'");
+  }
+
+  /**
+   * Test that logging is successfully enabled and disabled.
+   */
+  public function testEnableDisableLogging() {
+    $this->assertEquals(0, $this->callAPISuccessGetValue('Setting', array('name' => 'logging', 'group' => 'core')));
+    $this->assertLoggingEnabled(FALSE);
+
+    $this->callAPISuccess('Setting', 'create', array('logging' => TRUE));
+    $this->assertLoggingEnabled(TRUE);
+    $this->checkLogTableCreated();
+    $this->checkTriggersCreated();
+    // Create a contact to make sure they aren't borked.
+    $this->individualCreate();
+    $this->assertTrue($this->callAPISuccessGetValue('Setting', array('name' => 'logging', 'group' => 'core')));
+
+    $this->callAPISuccess('Setting', 'create', array('logging' => FALSE));
+    $this->assertEquals(0, $this->callAPISuccessGetValue('Setting', array('name' => 'logging', 'group' => 'core')));
+    $this->assertLoggingEnabled(FALSE);
+  }
+
+  /**
+   * Test that logging is successfully enabled and disabled.
+   */
+  public function testEnableDisableLoggingWithTriggerHook() {
+    $this->hookClass->setHook('civicrm_alterLogTables', array($this, 'innodbLogTableSpec'));
+    $this->callAPISuccess('Setting', 'create', array('logging' => TRUE));
+    $this->checkINNODBLogTableCreated();
+    $this->checkTriggersCreated();
+    // Create a contact to make sure they aren't borked.
+    $this->individualCreate();
+    $this->callAPISuccess('Setting', 'create', array('logging' => FALSE));
+  }
+
+  /**
+   * Use a hook to declare an INNODB engine for the contact log table.
+   *
+   * @param array $logTableSpec
+   */
+  public function innodbLogTableSpec(&$logTableSpec) {
+    $logTableSpec['civicrm_contact'] = array(
+      'engine' => 'INNODB',
+      'indexes' => array(
+        'index_id' => 'id',
+        'index_log_conn_id' => 'log_conn_id',
+        'index_log_date' => 'log_date',
+      ),
+    );
+  }
+
+  /**
+   * Check the log tables were created and look OK.
+   */
+  protected function checkLogTableCreated() {
+    $dao = CRM_Core_DAO::executeQuery("SHOW CREATE TABLE log_civicrm_contact");
+    $dao->fetch();
+    $this->assertEquals('log_civicrm_contact', $dao->Table);
+    $tableField = 'Create_Table';
+    $this->assertContains('`log_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,', $dao->$tableField);
+    return $dao->$tableField;
+  }
+
+  /**
+   * Check the log tables were created and reflect the INNODB hook.
+   */
+  protected function checkINNODBLogTableCreated() {
+    $createTableString = $this->checkLogTableCreated();
+    $this->assertContains('ENGINE=InnoDB', $createTableString);
+    $this->assertContains('KEY `index_id` (`id`),', $createTableString);
+  }
+
+  /**
+   * Check the triggers were created and look OK.
+   */
+  protected function checkTriggersCreated() {
+    $dao = CRM_Core_DAO::executeQuery("SHOW TRIGGERS LIKE 'civicrm_contact'");
+    while ($dao->fetch()) {
+      if ($dao->Timing == 'After') {
+        $this->assertContains('@uniqueID', $dao->Statement);
+      }
+    }
+  }
+
+  /**
+   * Assert logging is enabled or disabled as per input parameter.
+   *
+   * @param bool $expected
+   *   Do we expect it to be enabled.
+   */
+  protected function assertLoggingEnabled($expected) {
+    $schema = new CRM_Logging_Schema();
+    $this->assertTrue($schema->isEnabled() === $expected);
+  }
+
+}