provision_tests.drush.inc 16.5 KB
Newer Older
1 2 3
<?php
/**
 * @file
helmo's avatar
helmo committed
4
 * Some tests for hostmaster and provison.
5
 *
helmo's avatar
helmo committed
6 7 8
 * These could live in Hostmaster or Provision, and there are advantages and
 * disadvantages to both. But I decided that I'd just get on with it and pop
 * them into Provision.
9 10
 */

11
define('PROVISION_TESTS_BUILDS_REPO', dirname(__FILE__) . '/makes');
12
define('PROVISION_TESTS_DEFAULT_LOCK_WAIT', 60);
ergonlogic's avatar
ergonlogic committed
13
define('PROVISION_TESTS_LOCK_TIMEOUT', 3600.0);
14 15

/**
helmo's avatar
helmo committed
16
 * Implements hook_drush_command().
17 18 19 20 21 22
 */
function provision_tests_drush_command() {
  $items['provision-tests-run'] = array(
    'description' => dt('Runs provision tests'),
    'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_FULL,
    // Although we're a provision command, we require hostmaster to be around to
helmo's avatar
helmo committed
23
    // run the tests correctly.
24 25 26
    'drupal dependencies' => array(
      'hosting',
    ),
27
    'options' => array(
28
      'lock-wait' => dt('Time to wait to acquire a lock on the task queue. Defaults to :wait seconds.', array(':wait' => PROVISION_TESTS_DEFAULT_LOCK_WAIT)),
helmo's avatar
helmo committed
29
      'force' => dt('Continue even if the task queue is still locked.'),
30
    ),
31
  );
32 33 34 35
  $items['provision-tests-new-run'] = array(
    'description' => dt('Runs NEW provision tests'),
    'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_FULL,
    // Although we're a provision command, we require hostmaster to be around to
helmo's avatar
helmo committed
36
    // run the tests correctly.
37 38 39
    'drupal dependencies' => array(
      'hosting',
    ),
40
    'options' => array(
41
      'lock-wait' => dt('Time to wait to acquire a lock on the task queue. Defaults to :wait seconds.', array(':wait' => PROVISION_TESTS_DEFAULT_LOCK_WAIT)),
42
      'force' => dt('Continue even if the task queue is still locked.'),
43
    ),
44
  );
45 46 47 48
  $items['provision-demo-content'] = array(
    'description' => dt('Setup some demo content on a fresh Aegir install'),
    'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_FULL,
    // Although we're a provision command, we require hostmaster to be around to
helmo's avatar
helmo committed
49
    // run the tests correctly.
50 51 52
    'drupal dependencies' => array(
      'hosting',
    ),
53
    'options' => array(
54
      'lock-wait' => dt('Time to wait to acquire a lock on the task queue. Defaults to :wait seconds.', array(':wait' => PROVISION_TESTS_DEFAULT_LOCK_WAIT)),
helmo's avatar
helmo committed
55
      'force' => dt('Continue even if the task queue is still locked.'),
56
    ),
57
  );
58

59 60 61 62 63 64 65 66 67 68
  return $items;
}

/**
 * Drush command to run the provision tests.
 */
function drush_provision_tests_run() {
  if (!drush_confirm(dt('This command should only be run on a clean Aegir install, and data may be lost! Do you want to continue?'))) {
    return drush_user_abort();
  }
69
  // Disable the tasks queue, we run them manually instead.
70 71
  $queue_status_initial = variable_get('hosting_queue_tasks_enabled', '0');
  variable_set('hosting_queue_tasks_enabled', '0');
72
  $lock_wait = drush_get_option('lock-wait', PROVISION_TESTS_DEFAULT_LOCK_WAIT);
ergonlogic's avatar
ergonlogic committed
73 74
  if (!lock_wait('hosting_queue_tasks_running', $lock_wait) || drush_get_option('force', FALSE)) {
    if (lock_acquire('hosting_queue_tasks_running', PROVISION_TESTS_LOCK_TIMEOUT)) {
75
      drush_log('Acquired lock on task queue.');
ergonlogic's avatar
ergonlogic committed
76
    }
77 78 79 80
    elseif (drush_get_option('force', FALSE)) {
      drush_log('Bypassing lock on task queue.', 'warning');
    }
    else {
81 82 83
      drush_die(dt('Cannot acquire lock on task queue.'));
    }
  }
ergonlogic's avatar
ergonlogic committed
84 85 86
  else {
    drush_die(dt("Cannot acquire lock on task queue after waiting :wait seconds. A longer wait time can be set with the --lock-wait option.", array(':wait' => $lock_wait)));
  }
87

88 89
  drush_provision_tests_add_custom_test_task();

90 91
  drush_provision_tests_install_platform('drupal6');
  drush_provision_tests_install_platform('drupal7');
92

93
  // Install some sites.
94 95 96 97
  drush_provision_tests_install_site('drupal6', 'drupal6-default', 'default');
  drush_provision_tests_install_site('drupal7', 'drupal7-standard', 'standard');
  drush_provision_tests_install_site('drupal7', 'drupal7-minimal', 'minimal');

98 99 100 101
  // Remove the sites.
  drush_provision_tests_remove_site('drupal6-default');
  drush_provision_tests_remove_site('drupal7-standard');
  drush_provision_tests_remove_site('drupal7-minimal');
102

103 104
  // Create some sites and migrate them.
  drush_provision_tests_install_platform('drupal7', 'drupal7_other');
105
  drush_provision_tests_install_site('drupal7', 'drupal7-migrate-drupal7-other', 'standard');
106
  drush_provision_tests_dl_module_to_site('token', 'drupal7-migrate-drupal7-other');
107
  drush_provision_tests_migrate_site('drupal7-migrate-drupal7-other', 'drupal7_other');
108
  drush_provision_tests_en_module_on_site('token', 'drupal7-migrate-drupal7-other');
109 110
  drush_provision_tests_remove_site('drupal7-migrate-drupal7-other');
  drush_provision_tests_remove_platform('drupal7_other');
111

helmo's avatar
helmo committed
112
  // Create some sites, and upgrade them.
113
  drush_provision_tests_install_site('drupal6', 'drupal6-upgrade-drupal7', 'default');
114 115
  drush_provision_tests_migrate_site('drupal6-upgrade-drupal7', 'drupal7');
  drush_provision_tests_remove_site('drupal6-upgrade-drupal7');
116

117 118 119
  // Clean up a little.
  drush_provision_tests_remove_platform('drupal6');
  drush_provision_tests_remove_platform('drupal7');
120

helmo's avatar
helmo committed
121
  // Restore the tasks queue status.
122
  variable_set('hosting_queue_tasks_enabled', $queue_status_initial);
ergonlogic's avatar
ergonlogic committed
123
  drush_log(dt('Releasing lock on task queue.'));
ergonlogic's avatar
ergonlogic committed
124
  lock_release('hosting_queue_tasks_running');
125

126
  if (drush_get_error() != DRUSH_SUCCESS) {
127 128
    drush_set_error(drush_get_error(), 'Running tests failed');
    exit(1);
129
  }
130 131

  drush_log(dt('Tests completed successfully'), 'success');
132 133
}

134 135 136 137 138 139 140 141 142 143 144 145

/**
 * Drush command to run the provision tests.
 */
function drush_provision_tests_new_run() {
  if (!drush_confirm(dt('This command should only be run on a clean Aegir install, and data may be lost! Do you want to continue?'))) {
    return drush_user_abort();
  }

  // Disable the tasks queue, we run them manually instead.
  $queue_status_initial = variable_get('hosting_queue_tasks_enabled', '0');
  variable_set('hosting_queue_tasks_enabled', '0');
146 147
  drush_log('Acquiring tasks lock.');
  $lock_wait = drush_get_option('lock-wait', PROVISION_TESTS_DEFAULT_LOCK_WAIT);
ergonlogic's avatar
ergonlogic committed
148 149
  if (!lock_wait('hosting_queue_tasks_running', $lock_wait) || drush_get_option('force', FALSE)) {
    if (lock_acquire('hosting_queue_tasks_running', PROVISION_TESTS_LOCK_TIMEOUT)) {
150
      drush_log('Acquired lock on task queue.');
ergonlogic's avatar
ergonlogic committed
151
    }
152 153 154 155
    elseif (drush_get_option('force', FALSE)) {
      drush_log('Bypassing lock on task queue.', 'warning');
    }
    else {
156 157 158
      drush_die(dt('Cannot acquire lock on task queue.'));
    }
  }
ergonlogic's avatar
ergonlogic committed
159 160 161
  else {
    drush_die(dt("Cannot acquire lock on task queue after waiting :wait seconds. A longer wait time can be set with the --lock-wait option.", array(':wait' => $lock_wait)));
  }
162 163 164

  // 'Stable' D8 e.g. latest (beta) release.
  drush_provision_tests_install_platform('drupal8');
165
  drush_provision_tests_install_site('drupal8', 'drupal8-minimal', 'standard');
166 167 168

  // Dev D8 latest git commit.
  drush_provision_tests_install_platform('drupal8dev');
169
  drush_provision_tests_install_site('drupal8dev', 'drupal8-dev-minimal', 'standard');
170 171

  // Migrate a D8 site from the current release to the latest commit.
172
  drush_provision_tests_install_site('drupal8', 'drupal8-upgrade-d8', 'standard');
173 174 175 176 177 178 179 180 181 182 183
  drush_provision_tests_migrate_site('drupal8-upgrade-d8', 'drupal8dev');

  // Cleanup.
  drush_provision_tests_remove_site('drupal8-upgrade-d8');
  drush_provision_tests_remove_site('drupal8-minimal');
  drush_provision_tests_remove_site('drupal8-dev-minimal');
  drush_provision_tests_remove_platform('drupal8');
  drush_provision_tests_remove_platform('drupal8dev');

  // Restore the tasks queue status:
  variable_set('hosting_queue_tasks_enabled', $queue_status_initial);
184
  drush_log('Releasing tasks lock.');
ergonlogic's avatar
ergonlogic committed
185
  lock_release('hosting_queue_tasks_running');
186 187 188 189 190 191 192 193 194 195

  if (drush_get_error() != DRUSH_SUCCESS) {
    drush_set_error(drush_get_error(), 'Running tests failed');
    exit(1);
  }

  drush_log(dt('Tests completed successfully'), 'success');
}


196 197 198 199 200 201 202 203 204 205 206 207 208 209
/**
 * Drush command to setup some demo platforms and sites.
 *
 * To use these demo sites let names like drupal7-standard.aegir.example.com
 * resolve to the IP of this Aegir server. E.g. in your hosts file.
 */
function drush_provision_tests_provision_demo_content() {
  if (!drush_confirm(dt('This command should only be run on a clean Aegir install, and data may be lost! Do you want to continue?'))) {
    return drush_user_abort();
  }

  // Disable the tasks queue, we run them manually instead.
  $queue_status_initial = variable_get('hosting_queue_tasks_enabled', '0');
  variable_set('hosting_queue_tasks_enabled', '0');
210 211
  drush_log('Acquiring tasks lock.');
  $lock_wait = drush_get_option('lock-wait', PROVISION_TESTS_DEFAULT_LOCK_WAIT);
ergonlogic's avatar
ergonlogic committed
212 213
  if (!lock_wait('hosting_queue_tasks_running', $lock_wait) || drush_get_option('force', FALSE)) {
    if (lock_acquire('hosting_queue)tasks_running', PROVISION_TESTS_LOCK_TIMEOUT)) {
214
      drush_log('Acquired lock on task queue.');
ergonlogic's avatar
ergonlogic committed
215
    }
216 217 218 219
    elseif (drush_get_option('force', FALSE)) {
      drush_log('Bypassing lock on task queue.', 'warning');
    }
    else {
220 221 222
      drush_die(dt('Cannot acquire lock on task queue.'));
    }
  }
ergonlogic's avatar
ergonlogic committed
223 224 225
  else {
    drush_die(dt("Cannot acquire lock on task queue after waiting :wait seconds. A longer wait time can be set with the --lock-wait option.", array(':wait' => $lock_wait)));
  }
226

227 228 229 230
  // Start with D8 as it needs the most work/testing.
  drush_provision_tests_install_platform('drupal8');
  drush_provision_tests_install_site('drupal8', 'drupal8-minimal', 'minimal');

231
  // Prepare some platforms.
232 233
  drush_provision_tests_install_platform('drupal6');
  drush_provision_tests_install_platform('drupal7');
helmo's avatar
helmo committed
234
  drush_provision_tests_install_platform('openatrium2');
235 236 237 238 239 240 241 242 243

  // Install some sites.
  drush_provision_tests_install_site('drupal6', 'drupal6-default', 'default');
  drush_provision_tests_install_site('drupal7', 'drupal7-standard', 'standard');
  drush_provision_tests_install_site('drupal7', 'drupal7-minimal', 'minimal');
  drush_provision_tests_install_site('openatrium2', 'openatrium2-openatrium', 'openatrium');

  // Restore the tasks queue status:
  variable_set('hosting_queue_tasks_enabled', $queue_status_initial);
244
  drush_log('Releasing tasks lock.');
ergonlogic's avatar
ergonlogic committed
245
  lock_release('hosting_queue_tasks_running');
246 247

  if (drush_get_error() != DRUSH_SUCCESS) {
helmo's avatar
typo  
helmo committed
248
    drush_set_error(drush_get_error(), 'Setting up demo content failed');
249 250 251 252 253 254
    exit(1);
  }

  drush_log(dt('Demo content setup successfully'), 'success');
}

255 256 257
/**
 * Helper function to install a platform.
 */
258 259 260 261 262
function drush_provision_tests_install_platform($platform_name, $platform_alias = NULL) {
  if (is_null($platform_alias)) {
    $platform_alias = $platform_name;
  }
  drush_log(dt('Building platform: @platform and adding to hostmaster.', array('@platform' => $platform_alias)), 'ok');
263
  $args = array(
helmo's avatar
helmo committed
264
    PROVISION_TESTS_BUILDS_REPO . "/$platform_name.make",
helmo's avatar
helmo committed
265
    "/var/aegir/platforms/$platform_alias",
266
  );
267 268 269 270
  $opts = array();
  if (version_compare(drush_core_version(), '7', '>=')) {
    $opts[] = '--shallow-clone';
  }
ergonlogic's avatar
ergonlogic committed
271
  drush_invoke_process('@none', 'make', $args, $opts);
272
  $args = array(
273
    "@platform_$platform_alias",
274 275 276
  );
  $options = array(
    'root' => "/var/aegir/platforms/$platform_alias",
277 278
    'context_type' => 'platform',
  );
Steven Jones's avatar
Steven Jones committed
279
  drush_invoke_process('@none', 'provision-save', $args, $options);
helmo's avatar
helmo committed
280
  provision_backend_invoke('@hostmaster', 'hosting-import', array("@platform_$platform_alias"));
281 282 283 284 285 286 287
  drush_provision_tests_run_remaining_tasks();
}

/**
 * Helper function to remove a platform.
 */
function drush_provision_tests_remove_platform($platform_name) {
288
  drush_log(dt('Removing platform: @platform.', array('@platform' => $platform_name)), 'ok');
289
  provision_backend_invoke('@hostmaster', 'hosting-task', array("@platform_$platform_name", 'delete'), array('force' => TRUE));
290 291 292 293 294 295
  drush_provision_tests_run_remaining_tasks();
}

/**
 * Helper function to install a site.
 */
296 297
function drush_provision_tests_install_site($platform_name, $site, $profile_name) {
  drush_log(dt('Installing: @site on platform: @platform with profile: @profile.', array('@site' => "$site.aegir.example.com", '@platform' => $platform_name, '@profile' => $profile_name)), 'ok');
298
  $args = array(
299
    "@$site.aegir.example.com",
Steven Jones's avatar
Steven Jones committed
300 301 302
  );
  $options = array(
    'uri' => "$site.aegir.example.com",
303 304 305 306 307
    'context_type' => 'site',
    'platform' => "@platform_$platform_name",
    'profile' => $profile_name,
    'db_server' => '@server_localhost',
    'root' => "/var/aegir/platforms/$platform_name",
308
    'client_email' => 'this.email@is.invalid',
309
  );
Steven Jones's avatar
Steven Jones committed
310
  drush_invoke_process('@none', 'provision-save', $args, $options);
311 312 313 314 315 316

  $args = array();
  $options = array(
    'client_email' => 'this.email@is.invalid',
  );
  provision_backend_invoke("@$site.aegir.example.com", 'provision-install', $args, $options);
317
  provision_backend_invoke('@hostmaster', 'hosting-task', array("@platform_$platform_name", 'verify'), array('force' => TRUE));
318 319 320
  drush_provision_tests_run_remaining_tasks();
}

321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356
/**
 * Helper function to download a module to a site.
 */
function drush_provision_tests_dl_module_to_site($module, $site) {
  drush_log(dt('Downloading module: @module to site: @site.', array('@site' => "$site.aegir.example.com", '@module' => $module)), 'ok');
  $args = array(
    $module,
  );
  $options = array(
    // Normally 'dl' in a site context should know to put it in the site-
    // specific modules directory, but not through provision_backend_invoke()?
    'destination' => "sites/$site.aegir.example.com/modules",
  );
  provision_backend_invoke("@$site.aegir.example.com", 'dl', $args, $options);
  drush_provision_tests_run_remaining_tasks();
}

/**
 * Helper function to enable a module on a site.
 */
function drush_provision_tests_en_module_on_site($module, $site) {
  drush_log(dt('Enabling module: @module on site: @site.', array('@site' => "$site.aegir.example.com", '@module' => $module)), 'ok');
  $args = array(
    $module,
  );
  provision_backend_invoke("@$site.aegir.example.com", 'en', $args);
  // Failing 'en' only results in a warning, so we need to set our own error.
  $log = array_slice(drush_get_log(), 10);
  foreach ($log as $serial => $entry) {
    if ($entry['type'] == 'warning' && $entry['message'] == "$module was not found and will not be enabled.") {
      drush_set_error('DRUSH_FRAMEWORK_ERROR', "Error enabling module: $module on site: $site.");
    }
  }
  drush_provision_tests_run_remaining_tasks();
}

357 358 359
/**
 * Helper function to delete a site.
 */
360 361 362 363 364 365 366 367 368
function drush_provision_tests_remove_site($site) {
  drush_log(dt('Removing: @site.', array('@site' => "$site.aegir.example.com")), 'ok');
  provision_backend_invoke('@hostmaster', 'hosting-task', array("@$site.aegir.example.com", 'delete'), array('force' => TRUE));
  drush_provision_tests_run_remaining_tasks();
}

/**
 * Migrates a site from one platform to another.
 *
helmo's avatar
helmo committed
369
 * @param string $site
370
 *   The site to migrate.
helmo's avatar
helmo committed
371
 * @param string $target
372 373 374 375 376
 *   The target platform to migrate to.
 */
function drush_provision_tests_migrate_site($site, $target) {
  drush_log(dt('Migrating: @site to platform: @platform.', array('@site' => "$site.aegir.example.com", '@platform' => $target)), 'ok');
  // Do the migrate.
helmo's avatar
helmo committed
377
  provision_backend_invoke("@$site.aegir.example.com", 'provision-migrate', array("@platform_$target"));
378
  // Import the site into the frontend.
helmo's avatar
helmo committed
379
  provision_backend_invoke('@hostmaster', 'hosting-import', array("@$site.aegir.example.com"));
380 381 382
  // Verify the $target platform.
  provision_backend_invoke('@hostmaster', 'hosting-task', array("@platform_$target", 'verify'), array('force' => TRUE));
  // Import and verify the site.
helmo's avatar
helmo committed
383
  provision_backend_invoke('@hostmaster', 'hosting-import', array("@$site.aegir.example.com"));
384
  provision_backend_invoke('@hostmaster', 'hosting-task', array("@$site.aegir.example.com", 'verify'), array('force' => TRUE));
385 386 387
  drush_provision_tests_run_remaining_tasks();
}

388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419
/**
 * Create a custom verify task for the hostmaster site and place it in the queue.
 */
function drush_provision_tests_add_custom_test_task() {
  drush_log(dt("Create a custom verify task for the hostmaster site and place it in the queue."), 'ok');

  $node = new stdClass();

  // Admin
  $node->uid = 1;

  $node->type = 'task';

  // The site, platform or server node ID that is subject to the task.
  // 10 usually is the node ID for the hostmaster site itself.
  $node->rid = 10;

  // Published status == 1
  $node->status = 1;

  $node->task_type = 'verify';

  // Setting status to HOSTING_TASK_QUEUED == 0
  $node->task_status = 0;

  node_save($node);

  drush_provision_tests_run_remaining_tasks(TRUE);

  drush_log(dt("Finished running a custom verify task for the hostmaster site."), 'ok');
}

420 421 422
/**
 * Run all remaining hosting tasks.
 */
423 424
function drush_provision_tests_run_remaining_tasks($debug = FALSE) {
  provision_backend_invoke('@hostmaster', "hosting-tasks", array(), array('force' => TRUE, 'debug' => $debug));
425
}