You are here

monitoring.core.test in Monitoring 7

File

test/tests/monitoring.core.test
View source
<?php

/**
 * @file
 * Contains \MonitoringCoreTest.
 */

/**
 * Tests for cron sensor.
 */
class MonitoringCoreTest extends MonitoringTestBase {
  public static function getInfo() {
    return array(
      'name' => 'Monitoring Drupal core',
      'description' => 'Drupal core sensors tests.',
      'group' => 'Monitoring',
    );
  }

  /**
   * {@inheritdoc}
   */
  public function setUp() {
    parent::setUp(array(
      'dblog',
      'image',
      'taxonomy',
    ));
  }

  /**
   * Tests individual sensors.
   */
  function testSensors() {

    // ======= SensorCronLastRunAge tests ======= //
    $time_shift = 60 * 60 * 24 + 1;
    variable_set('cron_last', REQUEST_TIME - $time_shift);
    $result = $this
      ->runSensor('core_cron_last_run_age');
    $this
      ->assertTrue($result
      ->isWarning());
    $this
      ->assertEqual($result
      ->getValue(), $time_shift);
    $time_shift = 60 * 60 * 24 * 3 + 1;
    variable_set('cron_last', REQUEST_TIME - $time_shift);
    $result = $this
      ->runSensor('core_cron_last_run_age');
    $this
      ->assertTrue($result
      ->isCritical());
    $this
      ->assertEqual($result
      ->getValue(), $time_shift);
    drupal_cron_run();
    $result = $this
      ->runSensor('core_cron_last_run_age');
    $this
      ->assertTrue($result
      ->isOk());
    $this
      ->assertEqual($result
      ->getValue(), 0);

    // ======= Cron safe threshold (poormanscron) tests ======= //
    $result = $this
      ->runSensor('core_cron_safe_threshold');
    $this
      ->assertTrue($result
      ->isCritical());
    variable_set('cron_safe_threshold', '0');
    $result = $this
      ->runSensor('core_cron_safe_threshold');
    $this
      ->assertTrue($result
      ->isOk());

    // ======= SensorQueue tests ======= //

    /** @var DrupalQueueInterface $queue */
    $queue = DrupalQueue::get('monitoring_test');
    $queue
      ->createItem(array());
    $queue
      ->createItem(array());
    $result = $this
      ->runSensor('core_queue_monitoring_test');
    $this
      ->assertEqual($result
      ->getValue(), 2);

    // ======= SensorCoreRequirements tests ======= //
    $result = $this
      ->runSensor('core_requirements_monitoring_test');
    $this
      ->assertTrue($result
      ->isOk());
    $this
      ->assertEqual($result
      ->getMessage(), 'Requirements check OK');

    // Set basic requirements saying that all is ok.
    $requirements = array(
      'requirement1' => array(
        'title' => 'requirement1',
        'description' => 'requirement1 description',
        'severity' => REQUIREMENT_OK,
      ),
      'requirement_excluded' => array(
        'title' => 'excluded requirement',
        'description' => 'requirement that should be excluded from monitoring by the sensor',
        // Set the severity to ERROR to test if the sensor result is not
        // affected by this requirement.
        'severity' => REQUIREMENT_ERROR,
      ),
    );
    variable_set('monitoring_test_requirements', $requirements);

    // Set requirements exclude keys into the sensor settings.
    $settings = monitoring_sensor_settings_get('core_requirements_monitoring_test');
    $settings['exclude keys'] = array(
      'requirement_excluded',
    );
    monitoring_sensor_settings_save('core_requirements_monitoring_test', $settings);

    // We still should have OK status but with different message
    $result = $this
      ->runSensor('core_requirements_monitoring_test');

    // We expect OK status as REQUIREMENT_ERROR is set by excluded requirement.
    $this
      ->assertTrue($result
      ->isOk());
    $this
      ->assertEqual($result
      ->getMessage(), 'requirement1, requirement1 description');

    // Add warning state.
    $requirements['requirement2'] = array(
      'title' => 'requirement2',
      'description' => 'requirement2 description',
      'severity' => REQUIREMENT_WARNING,
    );
    variable_set('monitoring_test_requirements', $requirements);

    // Now the sensor should have escalated to the requirement in warning state.
    $result = $this
      ->runSensor('core_requirements_monitoring_test');
    $this
      ->assertTrue($result
      ->isWarning());
    $this
      ->assertEqual($result
      ->getMessage(), 'requirement2, requirement2 description');

    // Add error state.
    $requirements['requirement3'] = array(
      'title' => 'requirement3',
      'description' => 'requirement3 description',
      'severity' => REQUIREMENT_ERROR,
    );
    variable_set('monitoring_test_requirements', $requirements);

    // Now the sensor should have escalated to the requirement in critical state.
    $result = $this
      ->runSensor('core_requirements_monitoring_test');
    $this
      ->assertTrue($result
      ->isCritical());
    $this
      ->assertEqual($result
      ->getMessage(), 'requirement3, requirement3 description');

    // ======= Watchdog 404 in last 24 hours tests ======= //
    watchdog('page not found', 'not/found');
    $result = $this
      ->runSensor('dblog_404');
    $this
      ->assertTrue($result
      ->isOk());
    $this
      ->assertEqual($result
      ->getMessage(), '1 watchdog events in 1 day, not/found');
    $this
      ->assertEqual($result
      ->getValue(), 1);
    for ($i = 1; $i <= 20; $i++) {
      watchdog('page not found', 'not/found');
    }
    $result = $this
      ->runSensor('dblog_404');
    $this
      ->assertEqual($result
      ->getValue(), 21);
    $this
      ->assertTrue($result
      ->isWarning());
    for ($i = 0; $i <= 100; $i++) {
      watchdog('page not found', 'not/found/another');
    }
    $result = $this
      ->runSensor('dblog_404');
    $this
      ->assertEqual($result
      ->getValue(), 101);
    $this
      ->assertTrue($result
      ->isCritical());

    // ======= SensorImageMissingStyle tests ======= //
    for ($i = 0; $i <= 5; $i++) {
      watchdog('image', 'Source image at %source_image_path not found while trying to generate derivative image at %derivative_path.', array(
        '%source_image_path' => 'public://portrait-pictures/redmouse.jpeg',
        '%derivative_path' => 'hash://styles/preview/1234.jpeg',
      ));
    }
    watchdog('image', 'Source image at %source_image_path not found while trying to generate derivative image at %derivative_path.', array(
      '%source_image_path' => 'public://portrait-pictures/bluemouse.jpeg',
      '%derivative_path' => 'hash://styles/preview/5678.jpeg',
    ));
    $result = $this
      ->runSensor('dblog_image_missing_style');
    $this
      ->assertEqual(6, $result
      ->getValue());
    $this
      ->assertTrue(strpos($result
      ->getMessage(), 'public://portrait-pictures/redmouse.jpeg') !== FALSE);
    $this
      ->assertTrue($result
      ->isWarning());

    // ======= Watchdog sensor tests ======= //
    // Create watchdog entry with severity alert.
    watchdog('test', 'test message', array(), WATCHDOG_ALERT);

    // Run sensor and test the output.
    $severities = monitoring_event_severities();
    $result = $this
      ->runSensor('dblog_event_severity_' . $severities[WATCHDOG_ALERT]);
    $this
      ->assertEqual($result
      ->getValue(), 1);

    // ======= SensorUserFailedLogins tests ======= //
    watchdog('user', 'Login attempt failed for %user.', array(
      '%user' => 'user1',
    ), WATCHDOG_NOTICE);
    watchdog('user', 'Login attempt failed for %user.', array(
      '%user' => 'user1',
    ), WATCHDOG_NOTICE);
    watchdog('user', 'Login attempt failed for %user.', array(
      '%user' => 'user2',
    ), WATCHDOG_NOTICE);
    $result = $this
      ->runSensor('user_failed_logins');
    $this
      ->assertEqual($result
      ->getValue(), 3);
    $this
      ->assertTrue(strpos($result
      ->getMessage(), 'user1: 2') !== FALSE);
    $this
      ->assertTrue(strpos($result
      ->getMessage(), 'user2: 1') !== FALSE);

    // ======= Sensor user_session_logouts tests ======= //
    watchdog('user', 'Session closed for %name.', array(
      '%user' => 'user1',
    ), WATCHDOG_NOTICE);
    watchdog('user', 'Session closed for %name.', array(
      '%user' => 'user1',
    ), WATCHDOG_NOTICE);
    watchdog('user', 'Session closed for %name.', array(
      '%user' => 'user2',
    ), WATCHDOG_NOTICE);
    $result = $this
      ->runSensor('user_session_logouts');
    $this
      ->assertEqual($result
      ->getValue(), 3);
    $this
      ->assertEqual($result
      ->getMessage(), '3 logouts in 1 day');

    // ======= SensorGitDirtyTree tests ======= //
    // Enable the sensor and set cmd to output something
    monitoring_sensor_settings_save('monitoring_git_dirty_tree', array(
      'enabled' => TRUE,
      'status_cmd' => 'printf "A addedfile.txt\\nM sites/all/modules/monitoring/test/tests/monitoring.core.test\\nD deleted file.txt"',
      'ahead_cmd' => 'true',
      'submodules_cmd' => 'true',
    ));
    $result = monitoring_sensor_run('monitoring_git_dirty_tree', TRUE, TRUE);
    $this
      ->assertTrue($result
      ->isCritical());

    // The verbose output should contain the cmd output.
    $verboseOutput = $result
      ->getVerboseOutput();
    $this
      ->assertTrue(strpos($verboseOutput['status']['output']['#markup'], "<pre>A addedfile.txt\nM sites/all/modules/monitoring/test/tests/monitoring.core.test\nD deleted file.txt</pre>") !== FALSE);

    // Check if the sensor message has the expected value.
    $this
      ->assertEqual($result
      ->getMessage(), "3 files in unexpected state: A addedfile.txt, M …modules/monitoring/test/tests/monitoring.core.test");

    // Now echo empty string
    monitoring_sensor_settings_save('monitoring_git_dirty_tree', array(
      'enabled' => TRUE,
      'status_cmd' => 'true',
      'ahead_cmd' => 'true',
      'submodules_cmd' => 'true',
    ));
    $result = monitoring_sensor_run('monitoring_git_dirty_tree', TRUE, TRUE);
    $this
      ->assertTrue($result
      ->isOk());

    // The message should say that it is ok.
    $this
      ->assertTrue(strpos($result
      ->getMessage(), 'Git repository clean') !== FALSE);

    // Test 2 commits ahead of origin.
    monitoring_sensor_settings_save('monitoring_git_dirty_tree', array(
      'enabled' => TRUE,
      'status_cmd' => 'true',
      'ahead_cmd' => 'printf "a4ea5e3ac5b7cca0c96aee4d00447c36121bd128\\n299d85344fab9befbf6a275a4b64bda7b464b493"',
      'submodules_cmd' => 'true',
    ));
    $result = monitoring_sensor_run('monitoring_git_dirty_tree', TRUE, TRUE);
    $this
      ->assertTrue($result
      ->isWarning());
    $verboseOutput = $result
      ->getVerboseOutput();
    $this
      ->assertTrue(strpos($verboseOutput['ahead']['output']['#markup'], "<pre>a4ea5e3ac5b7cca0c96aee4d00447c36121bd128\n299d85344fab9befbf6a275a4b64bda7b464b493</pre>") !== FALSE);

    // Test not in main branch.
    monitoring_sensor_settings_save('monitoring_git_dirty_tree', array(
      'enabled' => TRUE,
      'check_branch' => TRUE,
      'status_cmd' => 'true',
      'ahead_cmd' => 'true',
      'actual_branch_cmd' => 'printf "7.0.x"',
      'expected_branch' => '8.0.x',
      'submodules_cmd' => 'true',
    ));
    $result = monitoring_sensor_run('monitoring_git_dirty_tree', TRUE, TRUE);
    $this
      ->assertTrue($result
      ->isWarning());
    $verboseOutput = $result
      ->getVerboseOutput();
    $this
      ->assertTrue(strpos($verboseOutput['check_branch']['output']['#markup'], '7.0.x') !== FALSE);
    $this
      ->assertEqual($result
      ->getMessage(), 'Active branch 7.0.x, expected 8.0.x');

    // Test same as main branch.
    monitoring_sensor_settings_save('monitoring_git_dirty_tree', array(
      'enabled' => TRUE,
      'check_branch' => TRUE,
      'status_cmd' => 'true',
      'ahead_cmd' => 'true',
      'actual_branch_cmd' => 'printf "8.0.x"',
      'expected_branch' => '8.0.x',
      'submodules_cmd' => 'true',
    ));
    $result = monitoring_sensor_run('monitoring_git_dirty_tree', TRUE, TRUE);
    $this
      ->assertTrue($result
      ->isOk());
    $this
      ->assertEqual($result
      ->getMessage(), 'Git repository clean');

    // Test submodule not initialized.
    monitoring_sensor_settings_save('monitoring_git_dirty_tree', array(
      'enabled' => TRUE,
      'status_cmd' => 'true',
      'ahead_cmd' => 'true',
      'submodules_cmd' => 'printf -- "-a5066d1778b9ec7c86631234ff2795e777bdff12 test"',
    ));
    $result = monitoring_sensor_run('monitoring_git_dirty_tree', TRUE, TRUE);
    $this
      ->assertTrue($result
      ->isCritical());
    debug($result
      ->getVerboseOutput());
    $verboseOutput = $result
      ->getVerboseOutput();
    $this
      ->assertTrue(strpos($verboseOutput['submodules']['output']['#markup'], "<pre>-a5066d1778b9ec7c86631234ff2795e777bdff12 test</pre>") !== FALSE);
    $this
      ->assertEqual($result
      ->getMessage(), '1 submodules in unexpected state: -a5066d1778b9ec7c86631234ff2795e777bdff12 test');

    // Test submodule with uncommitted changes.
    monitoring_sensor_settings_save('monitoring_git_dirty_tree', array(
      'enabled' => TRUE,
      'status_cmd' => 'true',
      'ahead_cmd' => 'true',
      'submodules_cmd' => 'printf "+156fff6ee58497fa22b57c32e22e3f13377b4120 test (8.x-1.0-240-g156fff6)"',
    ));
    $result = monitoring_sensor_run('monitoring_git_dirty_tree', TRUE, TRUE);
    $this
      ->assertTrue($result
      ->isCritical());
    debug($result
      ->getVerboseOutput());
    $verboseOutput = $result
      ->getVerboseOutput();
    $this
      ->assertTrue(strpos($verboseOutput['submodules']['output']['#markup'], "<pre>+156fff6ee58497fa22b57c32e22e3f13377b4120 test (8.x-1.0-240-g156fff6)</pre>") !== FALSE);
    $this
      ->assertEqual($result
      ->getMessage(), '1 submodules in unexpected state: +156fff6ee58497fa22b57c32e22e3f13377b4120 test (8.x-1.0-240-g156fff6)');

    // Test submodules in expected state.
    monitoring_sensor_settings_save('monitoring_git_dirty_tree', array(
      'enabled' => TRUE,
      'status_cmd' => 'true',
      'ahead_cmd' => 'true',
      'submodules_cmd' => 'printf "a5066d1778b9ec7c86631234ff2795e777bdff12 test\\n156fff6ee58497fa22b57c32e22e3f13377b4120 test (8.x-1.0-240-g156fff6)"',
    ));
    $result = monitoring_sensor_run('monitoring_git_dirty_tree', TRUE, TRUE);
    $this
      ->assertTrue($result
      ->isOk());
    $this
      ->assertEqual($result
      ->getMessage(), 'Git repository clean');

    // ======= Active sessions count tests ======= //
    // Create and login a user to have data in the sessions table.
    $test_user = $this
      ->drupalCreateUser();
    $this
      ->drupalLogin($test_user);
    $result = $this
      ->runSensor('user_sessions_authenticated');
    $this
      ->assertEqual($result
      ->getValue(), 1);
    $result = $this
      ->runSensor('user_sessions_all');
    $this
      ->assertEqual($result
      ->getValue(), 1);

    // Logout the user to see if sensors responded to the change.
    $this
      ->drupalLogout();
    $result = $this
      ->runSensor('user_sessions_authenticated');
    $this
      ->assertEqual($result
      ->getValue(), 0);
    $result = $this
      ->runSensor('user_sessions_all');
    $this
      ->assertEqual($result
      ->getValue(), 0);

    // ======= node sensors tests ======= //
    $type1 = $this
      ->drupalCreateContentType();
    $type2 = $this
      ->drupalCreateContentType();
    $this
      ->drupalCreateNode(array(
      'type' => $type1->type,
    ));
    $this
      ->drupalCreateNode(array(
      'type' => $type1->type,
    ));
    $this
      ->drupalCreateNode(array(
      'type' => $type2->type,
    ));

    // Make sure that sensors for the new node types are available.
    $this->sensorManager
      ->resetCache();
    $result = $this
      ->runSensor('node_new_' . $type1->type);
    $this
      ->assertEqual($result
      ->getValue(), 2);

    // Test for the SensorDatabaseAggregator custom message.
    $this
      ->assertEqual($result
      ->getMessage(), format_string('@count @unit in @time_interval', array(
      '@count' => $result
        ->getValue(),
      '@unit' => strtolower($result
        ->getSensorInfo()
        ->getValueLabel()),
      '@time_interval' => format_interval($result
        ->getSensorInfo()
        ->getTimeIntervalValue()),
    )));
    $result = $this
      ->runSensor('node_new_all');
    $this
      ->assertEqual($result
      ->getValue(), 3);
    variable_set('theme_default', 'bartik');
    $result = $this
      ->runSensor('core_theme_default');
    $this
      ->assertTrue($result
      ->isOk());
    variable_set('theme_default', 'garland');
    $result = $this
      ->runSensor('core_theme_default');
    $this
      ->assertTrue($result
      ->isCritical());
  }

  /**
   * Tests for SensorDisappearedSensors.
   *
   * We provide a separate test method for the SensorDisappearedSensors as we
   * need to enable and disable additional modules.
   */
  function testSensorDisappearedSensors() {

    // Enable the comment module.
    module_enable(array(
      'comment',
    ));

    // Run the disappeared sensor - it should not report any problems.
    $result = $this
      ->runSensor('monitoring_disappeared_sensors');
    $this
      ->assertTrue($result
      ->isOk());
    $log = $this
      ->loadWatchdog();
    $this
      ->assertEqual(count($log), 1, 'There should be one log entry: all sensors enabled by default added.');
    $sensor_info = monitoring_sensor_manager()
      ->getSensorInfo();
    $this
      ->assertEqual(format_string($log[0]->message, unserialize($log[0]->variables)), format_string('@count new sensor/s added: @names', array(
      '@count' => count($sensor_info),
      '@names' => implode(', ', array_keys($sensor_info)),
    )));

    // Disable the comment module so that the comment_new sensor goes away.
    module_disable(array(
      'comment',
    ));

    // The comment_new sensor has gone away and therefore we should have the
    // critical status.
    $result = $this
      ->runSensor('monitoring_disappeared_sensors');
    $this
      ->assertTrue($result
      ->isCritical());
    $this
      ->assertEqual($result
      ->getMessage(), 'Missing sensor comment_new');

    // There should be no new logs.
    $this
      ->assertEqual(count($this
      ->loadWatchdog()), 1);

    // Enable the comment module to test the correct procedure of removing
    // sensors.
    module_enable(array(
      'comment',
    ));

    // Now we should be back to normal.
    $result = $this
      ->runSensor('monitoring_disappeared_sensors');
    $this
      ->assertTrue($result
      ->isOk());
    $this
      ->assertEqual(count($this
      ->loadWatchdog()), 1);

    // Do the correct procedure to remove a sensor - first disable the sensor
    // and then disable the comment module.
    $this->sensorManager
      ->disableSensor('comment_new');
    module_disable(array(
      'comment',
    ));

    // The sensor should not report any problem this time.
    $result = $this
      ->runSensor('monitoring_disappeared_sensors');
    $this
      ->assertTrue($result
      ->isOk());
    $log = $this
      ->loadWatchdog();
    $this
      ->assertEqual(count($log), 2, 'Removal of comment_new sensor should be logged.');
    $this
      ->assertEqual(format_string($log[1]->message, unserialize($log[1]->variables)), format_string('@count new sensor/s removed: @names', array(
      '@count' => 1,
      '@names' => 'comment_new',
    )));

    // === Test the UI === //
    $account = $this
      ->drupalCreateUser(array(
      'administer monitoring',
    ));
    $this
      ->drupalLogin($account);

    // Enable comment module and the comment_new sensor.
    module_enable(array(
      'comment',
    ));
    $this->sensorManager
      ->enableSensor('comment_new');

    // We should have the message that no sensors are missing.
    $this
      ->drupalGet('admin/config/system/monitoring/sensors/monitoring_disappeared_sensors');
    $this
      ->assertNoText(t('This action will clear the missing sensors and the critical sensor status will go away.'));

    // Disable sensor and the comment module. This is the correct procedure and
    // therefore there should be no missing sensors.
    $this->sensorManager
      ->disableSensor('comment_new');
    $this
      ->drupalGet('admin/config/system/monitoring/sensors/monitoring_disappeared_sensors');
    $this
      ->assertNoText(t('This action will clear the missing sensors and the critical sensor status will go away.'));

    // Enable comment module and the comment_new sensor.
    module_enable(array(
      'comment',
    ));
    $this->sensorManager
      ->enableSensor('comment_new');

    // Now disable the comment module to have the comment_new sensor disappear.
    module_disable(array(
      'comment',
    ));

    // Run the monitoring_disappeared_sensors sensor to get the status message that should
    // be found in the settings form.
    $this
      ->drupalGet('admin/config/system/monitoring/sensors/monitoring_disappeared_sensors');
    $this
      ->assertText('Missing sensor comment_new');

    // Now reset the sensor list - we should get the "no missing sensors"
    // message.
    $this
      ->drupalPost(NULL, array(), t('Clear missing sensors'));
    $this
      ->assertText(t('All missing sensors have been cleared.'));
    $this
      ->drupalGet('admin/config/system/monitoring/sensors/monitoring_disappeared_sensors');
    $this
      ->assertNoText('Missing sensor comment_new');
  }

  /**
   * Tests the UI/settings of the enabled modules sensor.
   */
  function testSensorEnabledModulesUI() {
    $account = $this
      ->drupalCreateUser(array(
      'administer monitoring',
    ));
    $this
      ->drupalLogin($account);
    $form_key = monitoring_sensor_settings_key('monitoring_enabled_modules');

    // Test submitting the defaults and enabling the sensor.
    $this
      ->drupalPost('admin/config/system/monitoring/sensors/monitoring_enabled_modules', array(
      $form_key . '[enabled]' => TRUE,
    ), t('Save'));

    // Reset the sensor info so that it reflects changes done via POST.
    $this->sensorManager
      ->resetCache();

    // The sensor should now be OK.
    $result = $this
      ->runSensor('monitoring_enabled_modules');
    $this
      ->assertTrue($result
      ->isOk());

    // Expect the contact and book modules to be installed.
    $this
      ->drupalPost('admin/config/system/monitoring/sensors/monitoring_enabled_modules', array(
      $form_key . '[modules][contact]' => TRUE,
      $form_key . '[modules][book]' => TRUE,
    ), t('Save'));

    // Reset the sensor info so that it reflects changes done via POST.
    $this->sensorManager
      ->resetCache();

    // The sensor should escalate to CRITICAL.
    $result = $this
      ->runSensor('monitoring_enabled_modules');
    $this
      ->assertTrue($result
      ->isCritical());
    $this
      ->assertEqual($result
      ->getMessage(), '2 modules delta, expected 0, Following modules are expected to be installed: Book (book), Contact (contact)');
    $this
      ->assertEqual($result
      ->getValue(), 2);

    // The default setting is not to allow additional modules. Enable comment
    // and the sensor should escalate to CRITICAL.
    $this
      ->drupalPost('admin/config/system/monitoring/sensors/monitoring_enabled_modules', array(
      // Do not require contact and book as they are not installed.
      $form_key . '[modules][contact]' => FALSE,
      $form_key . '[modules][book]' => FALSE,
    ), t('Save'));

    // Reset the sensor info so that it reflects changes done via POST.
    $this->sensorManager
      ->resetCache();
    module_enable(array(
      'comment',
    ));
    $result = $this
      ->runSensor('monitoring_enabled_modules');
    $this
      ->assertTrue($result
      ->isCritical());
    $this
      ->assertEqual($result
      ->getMessage(), '1 modules delta, expected 0, Following modules are NOT expected to be installed: Comment (comment)');
    $this
      ->assertEqual($result
      ->getValue(), 1);

    // Allow additional, the sensor should not escalate.
    $this
      ->drupalPost('admin/config/system/monitoring/sensors/monitoring_enabled_modules', array(
      // Do not require contact and book as they are not installed.
      $form_key . '[allow_additional]' => TRUE,
    ), t('Save'));
    $this->sensorManager
      ->resetCache();
    $result = $this
      ->runSensor('monitoring_enabled_modules');
    $this
      ->assertTrue($result
      ->isOk());
  }

  /**
   * Test cases for SensorEnabledModules sensor.
   *
   * We use separate test method as we need to enable/disable modules.
   */
  function testSensorEnabledModulesAPI() {

    // The initial run of the sensor will acknowledge all installed modules as
    // expected and so the status should be OK.
    $result = $this
      ->runSensor('monitoring_enabled_modules');
    $this
      ->assertTrue($result
      ->isOk());

    // Install additional module. As the setting "allow_additional" is not
    // enabled by default this should result in sensor escalation to critical.
    module_enable(array(
      'comment',
    ));
    $result = $this
      ->runSensor('monitoring_enabled_modules');
    $this
      ->assertTrue($result
      ->isCritical());
    $this
      ->assertEqual($result
      ->getMessage(), '1 modules delta, expected 0, Following modules are NOT expected to be installed: Comment (comment)');
    $this
      ->assertEqual($result
      ->getValue(), 1);

    // Allow additional modules and run the sensor - it should not escalate now.
    $settings = monitoring_sensor_settings_get('monitoring_enabled_modules');
    $settings['allow_additional'] = TRUE;
    monitoring_sensor_settings_save('monitoring_enabled_modules', $settings);
    $result = $this
      ->runSensor('monitoring_enabled_modules');
    $this
      ->assertTrue($result
      ->isOk());

    // Add comment module to be expected and disable the module. The sensor
    // should escalate to critical.
    $settings = monitoring_sensor_settings_get('monitoring_enabled_modules');
    $settings['modules']['comment'] = 'comment';
    monitoring_sensor_settings_save('monitoring_enabled_modules', $settings);
    module_disable(array(
      'comment',
    ));
    $result = $this
      ->runSensor('monitoring_enabled_modules');
    $this
      ->assertTrue($result
      ->isCritical());
    $this
      ->assertEqual($result
      ->getMessage(), '1 modules delta, expected 0, Following modules are expected to be installed: Comment (comment)');
    $this
      ->assertEqual($result
      ->getValue(), 1);
  }

  /**
   * Tests the watchdog entries aggregator.
   */
  function testGenericDBAggregate() {

    // Aggregate by watchdog type.
    monitoring_sensor_settings_save('watchdog_aggregate_test', array(
      'conditions' => array(
        array(
          'field' => 'type',
          'value' => 'test_type',
        ),
      ),
    ));
    watchdog('test_type', $this
      ->randomName());
    watchdog('test_type', $this
      ->randomName());
    watchdog('other_test_type', $this
      ->randomName());
    $result = $this
      ->runSensor('watchdog_aggregate_test');
    $this
      ->assertEqual($result
      ->getValue(), 2);

    // Aggregate by watchdog message.
    monitoring_sensor_settings_save('watchdog_aggregate_test', array(
      'conditions' => array(
        array(
          'field' => 'message',
          'value' => 'test_message',
        ),
      ),
    ));
    watchdog($this
      ->randomName(), 'test_message');
    watchdog($this
      ->randomName(), 'another_test_message');
    watchdog($this
      ->randomName(), 'another_test_message');
    $result = $this
      ->runSensor('watchdog_aggregate_test');
    $this
      ->assertEqual($result
      ->getValue(), 1);

    // Aggregate by watchdog severity.
    monitoring_sensor_settings_save('watchdog_aggregate_test', array(
      'conditions' => array(
        array(
          'field' => 'severity',
          'value' => WATCHDOG_CRITICAL,
        ),
      ),
    ));
    watchdog($this
      ->randomName(), $this
      ->randomName(), array(), WATCHDOG_CRITICAL);
    watchdog($this
      ->randomName(), $this
      ->randomName(), array(), WATCHDOG_CRITICAL);
    watchdog($this
      ->randomName(), $this
      ->randomName(), array(), WATCHDOG_CRITICAL);
    watchdog($this
      ->randomName(), $this
      ->randomName(), array(), WATCHDOG_CRITICAL);
    $result = $this
      ->runSensor('watchdog_aggregate_test');
    $this
      ->assertEqual($result
      ->getValue(), 4);

    // Aggregate by watchdog location.
    monitoring_sensor_settings_save('watchdog_aggregate_test', array(
      'conditions' => array(
        array(
          'field' => 'location',
          'value' => 'http://some.url.dev',
        ),
      ),
    ));

    // Update the two test_type watchdog entries with a custom location.
    db_update('watchdog')
      ->fields(array(
      'location' => 'http://some.url.dev',
    ))
      ->condition('type', 'test_type')
      ->execute();
    $result = $this
      ->runSensor('watchdog_aggregate_test');
    $this
      ->assertEqual($result
      ->getValue(), 2);

    // Filter for time period.
    monitoring_sensor_settings_save('watchdog_aggregate_test', array(
      'time_interval_value' => 10,
      'time_interval_field' => 'timestamp',
    ));

    // Make all system watchdog messages older than the configured time period.
    db_update('watchdog')
      ->fields(array(
      'timestamp' => REQUEST_TIME - 20,
    ))
      ->condition('type', 'system')
      ->execute();
    $count_latest = db_query('SELECT COUNT(*) FROM {watchdog} WHERE timestamp > :timestamp', array(
      ':timestamp' => REQUEST_TIME - 10,
    ))
      ->fetchField();
    $result = $this
      ->runSensor('watchdog_aggregate_test');
    $this
      ->assertEqual($result
      ->getValue(), $count_latest);

    // Test for thresholds and statuses.
    monitoring_sensor_settings_save('watchdog_aggregate_test', array(
      'conditions' => array(
        array(
          'field' => 'type',
          'value' => 'test_watchdog_aggregate_sensor',
        ),
      ),
    ));
    $result = $this
      ->runSensor('watchdog_aggregate_test');
    $this
      ->assertTrue($result
      ->isOk());
    $this
      ->assertEqual($result
      ->getValue(), 0);
    watchdog('test_watchdog_aggregate_sensor', 'testing');
    watchdog('test_watchdog_aggregate_sensor', 'testing');
    $result = $this
      ->runSensor('watchdog_aggregate_test');
    $this
      ->assertTrue($result
      ->isWarning());
    $this
      ->assertEqual($result
      ->getValue(), 2);
    watchdog('test_watchdog_aggregate_sensor', 'testing');
    $result = $this
      ->runSensor('watchdog_aggregate_test');
    $this
      ->assertTrue($result
      ->isCritical());
    $this
      ->assertEqual($result
      ->getValue(), 3);

    // Test with different db table.
    $info = $this->sensorManager
      ->getSensorInfoByName('db_aggregate_test');
    $this
      ->drupalCreateNode(array(
      'promote' => '1',
    ));
    $this
      ->drupalCreateNode(array(
      'promote' => '0',
    ));
    $this
      ->drupalCreateNode(array(
      'promote' => '0',
    ));

    // Create one node that should not meet the time_interval condition.
    $node = $this
      ->drupalCreateNode(array(
      'promote' => '0',
    ));
    db_update('node')
      ->fields(array(
      'created' => REQUEST_TIME - ($info
        ->getTimeIntervalValue() + 10),
    ))
      ->condition('nid', $node->nid)
      ->execute();

    // Based on default sensor settings we should get the promoted node.
    $result = $this
      ->runSensor('db_aggregate_test');
    $this
      ->assertEqual($result
      ->getValue(), 1);

    // Test with settings updated.
    $settings = monitoring_sensor_settings_get('db_aggregate_test');
    $settings['conditions'] = array(
      'test' => array(
        'field' => 'promote',
        'value' => '0',
      ),
    );
    monitoring_sensor_settings_save('db_aggregate_test', $settings);
    $result = $this
      ->runSensor('db_aggregate_test');

    // There should be two nodes with promote 0 and created in last 24 hours.
    $this
      ->assertEqual($result
      ->getValue(), 2);

    // Test support for configurable fields, create a taxonomy reference field.
    $type = $this
      ->drupalCreateContentType();
    $vocabulary = $this
      ->createVocabulary();
    $field = array(
      'field_name' => 'term_reference',
      'type' => 'taxonomy_term_reference',
      'cardinality' => FIELD_CARDINALITY_UNLIMITED,
      'settings' => array(
        'allowed_values' => array(
          array(
            'vocabulary' => $vocabulary->machine_name,
            'parent' => 0,
          ),
        ),
      ),
    );
    field_create_field($field);

    // Create a second field.
    $instance = array(
      'field_name' => 'term_reference',
      'bundle' => $type->type,
      'entity_type' => 'node',
      'widget' => array(
        'type' => 'options_select',
      ),
      'display' => array(
        'default' => array(
          'type' => 'taxonomy_term_reference_link',
        ),
      ),
    );
    field_create_instance($instance);
    $field = array(
      'field_name' => 'term_reference2',
      'type' => 'taxonomy_term_reference',
      'cardinality' => FIELD_CARDINALITY_UNLIMITED,
      'settings' => array(
        'allowed_values' => array(
          array(
            'vocabulary' => $vocabulary->machine_name,
            'parent' => 0,
          ),
        ),
      ),
    );
    field_create_field($field);
    $instance = array(
      'field_name' => 'term_reference2',
      'bundle' => $type->type,
      'entity_type' => 'node',
      'widget' => array(
        'type' => 'options_select',
      ),
      'display' => array(
        'default' => array(
          'type' => 'taxonomy_term_reference_link',
        ),
      ),
    );
    field_create_instance($instance);

    // Create some terms.
    $term1 = $this
      ->createTerm($vocabulary);
    $term2 = $this
      ->createTerm($vocabulary);

    // Create node that only references the first term.
    $node1 = $this
      ->drupalCreateNode(array(
      'created' => REQUEST_TIME,
      'type' => $type->type,
      'term_reference' => array(
        LANGUAGE_NONE => array(
          array(
            'tid' => $term1->tid,
          ),
        ),
      ),
    ));

    // Create node that only references both terms.
    $node2 = $this
      ->drupalCreateNode(array(
      'created' => REQUEST_TIME,
      'type' => $type->type,
      'term_reference' => array(
        LANGUAGE_NONE => array(
          array(
            'tid' => $term1->tid,
          ),
          array(
            'tid' => $term2->tid,
          ),
        ),
      ),
    ));

    // Create a third node that references both terms but in different fields.
    $node2 = $this
      ->drupalCreateNode(array(
      'created' => REQUEST_TIME,
      'type' => $type->type,
      'term_reference' => array(
        LANGUAGE_NONE => array(
          array(
            'tid' => $term1->tid,
          ),
        ),
      ),
      'term_reference2' => array(
        LANGUAGE_NONE => array(
          array(
            'tid' => $term2->tid,
          ),
        ),
      ),
    ));

    // Update the sensor to look for nodes with a reference to term1 in the
    // first field.
    $settings = monitoring_sensor_settings_get('db_aggregate_test');
    $settings['conditions'] = array(
      'test' => array(
        'field' => 'term_reference.tid',
        'value' => $term1->tid,
      ),
    );
    monitoring_sensor_settings_save('db_aggregate_test', $settings);
    $result = $this
      ->runSensor('db_aggregate_test');

    // There should be three nodes with that reference.
    $this
      ->assertEqual($result
      ->getValue(), 3);

    // Update the sensor to look for nodes with a reference to term1 in the
    // first field and term2 in the second.
    $settings = monitoring_sensor_settings_get('db_aggregate_test');
    $settings['conditions'] = array(
      'test' => array(
        'field' => 'term_reference.tid',
        'value' => $term1->tid,
      ),
      'test2' => array(
        'field' => 'term_reference2.tid',
        'value' => $term2->tid,
      ),
    );
    monitoring_sensor_settings_save('db_aggregate_test', $settings);
    $result = $this
      ->runSensor('db_aggregate_test');

    // There should be one nodes with those references.
    $this
      ->assertEqual($result
      ->getValue(), 1);
  }

  /**
   * Returns a new vocabulary with random properties.
   *
   * @return object
   *   Vocabulary object.
   */
  function createVocabulary() {

    // Create a vocabulary.
    $vocabulary = new stdClass();
    $vocabulary->name = $this
      ->randomName();
    $vocabulary->description = $this
      ->randomName();
    $vocabulary->machine_name = drupal_strtolower($this
      ->randomName());
    $vocabulary->help = '';
    $vocabulary->weight = mt_rand(0, 10);
    taxonomy_vocabulary_save($vocabulary);
    return $vocabulary;
  }

  /**
   * Returns a new term with random properties in vocabulary $vid.
   *
   * @return object
   *   Term object.
   */
  function createTerm($vocabulary) {
    $term = new stdClass();
    $term->name = $this
      ->randomName();
    $term->description = $this
      ->randomName();

    // Use the first available text format.
    $term->format = db_query_range('SELECT format FROM {filter_format}', 0, 1)
      ->fetchField();
    $term->vid = $vocabulary->vid;
    taxonomy_term_save($term);
    return $term;
  }

  /**
   * Loads watchdog entries by type.
   *
   * @param string $type
   *   Watchdog type.
   *
   * @return array
   *   List of dblog entries.
   */
  function loadWatchdog($type = 'monitoring') {
    return db_query("SELECT * FROM {watchdog} WHERE type = :type", array(
      ':type' => $type,
    ))
      ->fetchAll();
  }

}

Classes

Namesort descending Description
MonitoringCoreTest Tests for cron sensor.