From c0d844184af9edd9c67eb419460e319659089605 Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Mon, 27 Jan 2020 15:59:41 -0800 Subject: [PATCH] Civi\Test - Allow `headless()->apply()` (etc) to execute without setup.sh Before ------ If you have a copy of the `git` codebase and wish to run any of the headless test suites, you *must* run `setup.sh` aka `GenCode` beforehand. This is because certain files - `sql/civicrm.mysql` and `sql/civicrm_data.mysql` - are used in the headless suite. As large auto-generated files, they are not provided in git. After ----- The files `sql/civicrm.mysql` and `sql/civicrm_data.mysql` are no longer required by the test suite -- the headless tests will directly use the `GenCode` classes to produce the needful. Comments -------- The general thrust of this commit is to find spots which read an SQL file, e.g. ```php \Civi\Test::execute(file_get_contents("foobar.mysql")); ``` and instead call the generator for that file, e.g.: ```php $schema = new \CRM_Core_CodeGen_Schema(\Civi\Test::codeGen()); $result = $schema->generateFooBar(); \Civi\Test::execute($result['foobar.mysql']); }); ``` In doing so, we incorporate a couple tricks: * The SQL content is cached for the duration of the test-run (`Civi\Test::$statics`). Generating the SQL is not super expensive... but `Civi\Test::headless()->...apply()` may be called thousands of times, so it could add-up. Just cache it. * Most of the `generateFooBar()` functions depend in some fashion on `ts()`. This commit depends on a preceding commit to make `ts()` more amenable to execution during early stages of the test. * Related discussion: https://chat.civicrm.org/civicrm/pl/ehohytqkf7bd5prg9w75dq4qqw --- CRM/Core/CodeGen/Main.php | 6 ++- Civi/Test.php | 15 ++++++- Civi/Test/CiviEnvBuilder.php | 10 +++++ Civi/Test/CiviEnvBuilder/CoreSchemaStep.php | 50 +++++++++++++++++++++ Civi/Test/Data.php | 7 ++- 5 files changed, 85 insertions(+), 3 deletions(-) create mode 100644 Civi/Test/CiviEnvBuilder/CoreSchemaStep.php diff --git a/CRM/Core/CodeGen/Main.php b/CRM/Core/CodeGen/Main.php index 4ea9ba8934..88a31222d6 100644 --- a/CRM/Core/CodeGen/Main.php +++ b/CRM/Core/CodeGen/Main.php @@ -151,13 +151,17 @@ Alternatively you can get a version of CiviCRM that matches your PHP version return $this->sourceDigest; } - protected function init() { + /** + * @return static + */ + public function init() { if (!$this->database || !$this->tables) { $specification = new CRM_Core_CodeGen_Specification(); $specification->parse($this->schemaPath, $this->buildVersion); $this->database = $specification->database; $this->tables = $specification->tables; } + return $this; } } diff --git a/Civi/Test.php b/Civi/Test.php index f1c787f9f1..7eb83cade1 100644 --- a/Civi/Test.php +++ b/Civi/Test.php @@ -119,7 +119,7 @@ class Test { echo "Installing {$dbName} schema\n"; \Civi\Test::schema()->dropAll(); }, 'headless-drop') - ->sqlFile($civiRoot . "/sql/civicrm.mysql") + ->coreSchema() ->sql("DELETE FROM civicrm_extension") ->callback(function ($ctx) { \Civi\Test::data()->populate(); @@ -158,6 +158,19 @@ class Test { return self::$singletons['schema']; } + /** + * @return \CRM_Core_CodeGen_Main + */ + public static function codeGen() { + if (!isset(self::$singletons['codeGen'])) { + $civiRoot = dirname(__DIR__); + $codeGen = new \CRM_Core_CodeGen_Main("$civiRoot/CRM/Core/DAO", "$civiRoot/sql", $civiRoot, "$civiRoot/templates", NULL, "UnitTests", NULL, "$civiRoot/xml/schema/Schema.xml", NULL); + $codeGen->init(); + self::$singletons['codeGen'] = $codeGen; + } + return self::$singletons['codeGen']; + } + /** * @return \Civi\Test\Data */ diff --git a/Civi/Test/CiviEnvBuilder.php b/Civi/Test/CiviEnvBuilder.php index 3a6ab88393..8bce9d1fbf 100644 --- a/Civi/Test/CiviEnvBuilder.php +++ b/Civi/Test/CiviEnvBuilder.php @@ -2,6 +2,7 @@ namespace Civi\Test; use Civi\Test\CiviEnvBuilder\CallbackStep; +use Civi\Test\CiviEnvBuilder\CoreSchemaStep; use Civi\Test\CiviEnvBuilder\ExtensionsStep; use Civi\Test\CiviEnvBuilder\SqlFileStep; use Civi\Test\CiviEnvBuilder\SqlStep; @@ -41,6 +42,15 @@ class CiviEnvBuilder { return $this->addStep(new CallbackStep($callback, $signature)); } + /** + * Generate the core SQL tables. + * + * @return \Civi\Test\CiviEnvBuilder + */ + public function coreSchema() { + return $this->addStep(new CoreSchemaStep()); + } + public function sql($sql) { return $this->addStep(new SqlStep($sql)); } diff --git a/Civi/Test/CiviEnvBuilder/CoreSchemaStep.php b/Civi/Test/CiviEnvBuilder/CoreSchemaStep.php new file mode 100644 index 0000000000..5f8e56abf9 --- /dev/null +++ b/Civi/Test/CiviEnvBuilder/CoreSchemaStep.php @@ -0,0 +1,50 @@ +generateCreateSql(); + \Civi\Test::$statics['core_schema_sql'] = [ + 'digest' => md5($files['civicrm.mysql']), + 'content' => $files['civicrm.mysql'], + ]; + } + return \Civi\Test::$statics['core_schema_sql']; + } + + public function getSig() { + return $this->getSql()['digest']; + } + + public function isValid() { + return TRUE; + } + + /** + * @param \Civi\Test\CiviEnvBuilder $ctx + */ + public function run($ctx) { + $sql = $this->getSql(); + if (\Civi\Test::execute($sql['content']) === FALSE) { + throw new \RuntimeException("Cannot execute SQL"); + } + } + +} diff --git a/Civi/Test/Data.php b/Civi/Test/Data.php index afa377febd..8cada62629 100644 --- a/Civi/Test/Data.php +++ b/Civi/Test/Data.php @@ -21,7 +21,12 @@ class Data { \Civi\Test::execute('SET NAMES utf8'); $sqlDir = dirname(dirname(__DIR__)) . "/sql"; - $query2 = file_get_contents("$sqlDir/civicrm_data.mysql"); + if (!isset(\Civi\Test::$statics['locale_data'])) { + $schema = new \CRM_Core_CodeGen_Schema(\Civi\Test::codeGen()); + \Civi\Test::$statics['locale_data'] = $schema->generateLocaleDataSql('en_US'); + } + + $query2 = \Civi\Test::$statics['locale_data']["civicrm_data.mysql"]; $query3 = file_get_contents("$sqlDir/test_data.mysql"); $query4 = file_get_contents("$sqlDir/test_data_second_domain.mysql"); if (\Civi\Test::execute($query2) === FALSE) { -- 2.25.1