Problem/Motivation

Hi, I'm using the Configuration Management heavily for Development. In order to test some Views and Forms, I wrote a Simpletest base test class, which runs a configuration synchronization within its setUp() method:

abstract class OWSConfigBaseTestCase extends DrupalWebTestCase {

    protected $profile = 'minimal';



    /* (non-PHPdoc)
     * @see drupal/modules/simpletest/DrupalWebTestCase#setUp()
     */
    public function setUp() {
        $modules = func_get_args();
        if (isset($modules[0]) && is_array($modules[0])) {
            $modules = $modules[0];
        }
        array_unshift($modules, 'configuration');
        parent::setUp($modules);

        // somehow adding those modules to the setUp-array doesn't work :(
        // It produces about 1k debug messages and results in corrupted or not even existing views ... dunno why
        module_enable(array('ows_commons'), true);


        //
        // import our data structure
        // read tracking file
        $tracking_file = ConfigurationManagement::readTrackingFile();

        // load required modules
        $to_track = array_keys($tracking_file['tracked']);
        $modules_results = ConfigurationManagement::discoverRequiredModules($tracking_file['modules']);
        $missing_modules = $modules_results->getInfo('missing_modules');

        if (!empty($missing_modules)) {
            $this->error(t('Configurations cannot be synchronized because the following modules are not available to install: %modules', array('%modules' => implode(', ', $missing_modules))));
            // TODO: stop test right here
            return;
        }

        $modules_to_install = $modules_results->getInfo('modules_to_install');
        debug(t("Enabling additional modules for config-import: %modules", array('%modules' => implode(', ', $modules_to_install))));

        if (!empty($modules_to_install)) {
            module_enable($modules_to_install, TRUE);
        }

        debug(t("All modules enabled before config import: %modules", array('%modules' => implode(', ', module_list()))));


        //
        // finally import data
        $results = ConfigurationManagement::importToActiveStore($to_track, false, false, false);
        foreach ($results->getInfo('no_handler') as $failed) {
            $this->error(t('%config could be imported because there is no module that can handle that configuration.', array('%config' => $failed)));
            // TODO: stop test right here
        }
    }
}

With the module "ows_commons" all the required modules for the synchronization are already enabled. However, I get tons of debug-Messages, exceptions and errors like this:

Undefined index: relation	Notice	views_handler_field_field.inc	127	views_handler_field_field->access()
Undefined index: entity keys	Notice	views_handler_field_field.inc	198	views_handler_field_field->query()
'Exception in Gast Schnupperwochen[gast_schnupperwochen]: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AS relation_, relation.rid AS rid, field_data_field_start_date.field_start_date_' at line 1'
Debug	views.module	1697
'Missing handler: relation relation_base_hat_eine_schnupperwoche_mit_user relationship' Debug	views.module	1697

They all seem to be related to view-handlers. Apparently (at least some) views and contents of views are created correctly, since my tests do not fail (check if view url exists, if fields are there, if user has access etc). When I run the Synchronisation via UI or drush within the normal site environment, I don't get any of those. Only within Simpletest environment. Are the modules not setup the correct way, is something missing in the test environment?

Comments

Anonymous’s picture

Status: Active » Closed (fixed)

fixed it! The views cache was the problem. After enabling all required modules and before the import you need to call _views_fetch_data_build(). For the views to be registered correcly call views_invalidate_cache() and views_invalidate_cache().


use Drupal\configuration\Config\ConfigurationManagement;


/**
 * Class OWSConfigBaseTestCase
 *
 * This is a base class for Tests, that need our configuration to be imported beforehand. The setUp method
 * will trigger a synchronization similar to running 'drush csyn', just without starting tracking.
 *
 */
abstract class OWSConfigBaseTestCase extends DrupalWebTestCase {

    protected $profile = 'minimal';



    /* (non-PHPdoc)
     * @see drupal/modules/simpletest/DrupalWebTestCase#setUp()
     */
    public function setUp() {
        $modules = func_get_args();
        if (isset($modules[0]) && is_array($modules[0])) {
            $modules = $modules[0];
        }
        array_unshift($modules, 'ows_commons');
        array_unshift($modules, 'configuration');
        parent::setUp($modules);


        //
        // import our data structure
        // read tracking file
        $tracking_file = ConfigurationManagement::readTrackingFile();


        // load required modules
        $tracked_configs = array_keys($tracking_file['tracked']);
        $modules_results = ConfigurationManagement::discoverRequiredModules($tracking_file['modules']);
        $missing_modules = $modules_results->getInfo('missing_modules');

        if (!empty($missing_modules)) {
            $this->error(t('Configurations cannot be synchronized because the following modules are not available to install: %modules', array('%modules' => implode(', ', $missing_modules))));
            // TODO: stop test right here
            return;
        }

        $modules_to_install = $modules_results->getInfo('modules_to_install');
        if (!empty($modules_to_install)) {
            debug(t("Enabling additional modules for config-import: %modules", array('%modules' => implode(', ', $modules_to_install))));
            module_enable($modules_to_install, TRUE);
            $this->resetAll();
        }

        // for whatever reason necessary after $this->resetAll (called in setup). apparently the reset makes views forget some of the handlers
        views_invalidate_cache();
        _views_fetch_data_build();

        // FIXME 'relation' and 'views_conditional' view handlers are not registered correctly and produce
        // broken/missing handlers (even after _views_fetch_data_build()). Getting rid of the error
        // output is not a fix ... :/
        debug(t('Disabling debug messages while Configuration Management import due to unfixed broken handler. If your views test fails due to those broken handlers, fix them here ;)'));
        $error_reporting_default = error_reporting();
        error_reporting(E_USER_WARNING);


        //
        // finally import data, but do not track! and do not write anything to the config files!
        $results = ConfigurationManagement::importToActiveStore($tracked_configs, false, false, false);
        foreach ($results->getInfo('no_handler') as $failed) {
            $this->error(t('%config could be imported because there is no module that can handle that configuration.', array('%config' => $failed)));
            // TODO: stop test right here
        }


        // soft reset in order to update the caches
        drupal_flush_all_caches();
        drupal_static_reset();
        // rebuild views cache, otherwise the views will not be accessible
        views_invalidate_cache();
        views_get_all_views(true);

        // re-enable debug messages
        error_reporting($error_reporting_default);
    }
}