backendTest.php 3.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. <?php
  2. /*
  3. * @file
  4. * We choose to test the backend system in two parts.
  5. * - Origin. These tests assure that we are generate a proper ssh command
  6. * when a backend invoke is needed.
  7. * - Target. These tests assure that drush generates a delimited JSON array
  8. * when called with --backend option.
  9. *
  10. * Advantages of this approach:
  11. * - No network calls and thus more robust.
  12. * - No network calls and thus faster.
  13. */
  14. class backendCase extends Drush_TestCase {
  15. const DRUSH_BACKEND_OUTPUT_DELIMITER = 'DRUSH_BACKEND_OUTPUT_START>>>%s<<<DRUSH_BACKEND_OUTPUT_END';
  16. /*
  17. * Covers the following origin responsibilities.
  18. * - A remote host is recognized in site specification.
  19. * - Generates expected ssh command.
  20. *
  21. * General handling of site aliases will be in sitealiasTest.php.
  22. */
  23. function testOrigin() {
  24. $exec = sprintf('%s %s version --simulate --ssh-options=%s | grep ssh', self::escapeshellarg(UNISH_DRUSH), self::escapeshellarg('user@server/path/to/drupal#sitename'), self::escapeshellarg('-i mysite_dsa'));
  25. $this->execute($exec);
  26. // $expected might be different on non unix platforms. We shall see.
  27. $expected = "proc_open: ssh -i mysite_dsa 'user'@'server' 'drush --uri='\''sitename'\'' --root='\''/path/to/drupal'\'' --simulate version --backend 2>&1' 2>&1";
  28. $output = $this->getOutput();
  29. $this->assertEquals($expected, $output, 'Expected ssh command was built');
  30. }
  31. /*
  32. * Covers the following target responsibilities.
  33. * - Interpret stdin as options as per REST API.
  34. * - Successfully execute specified command.
  35. * - JSON object has expected contents (including errors).
  36. * - JSON object is wrapped in expected delimiters.
  37. */
  38. function testTarget() {
  39. $stdin = json_encode(array('filter'=>'sql'));
  40. $exec = sprintf('echo %s | %s help --backend', self::escapeshellarg($stdin), self::escapeshellarg(UNISH_DRUSH));
  41. $this->execute($exec);
  42. $parsed = $this->parse($this->getOutput());
  43. $this->assertTrue((bool) $parsed, 'Successfully parsed backend output');
  44. $this->assertArrayHasKey('log', $parsed);
  45. $this->assertArrayHasKey('output', $parsed);
  46. $this->assertArrayHasKey('object', $parsed);
  47. $this->assertEquals(self::EXIT_SUCCESS, $parsed['error_status']);
  48. // This assertion shows that `help` was called and that stdin options were respected.
  49. $this->assertStringStartsWith('SQL commands', $parsed['output']);
  50. $this->assertEquals('Bootstrap to phase 0.', $parsed['log'][0]['message']);
  51. // Check error propogation by requesting an invalid command (missing Drupal site).
  52. $exec = sprintf('%s core-cron --backend 2>/dev/null', self::escapeshellarg(UNISH_DRUSH));
  53. $this->execute($exec, self::EXIT_ERROR);
  54. $parsed = $this->parse($this->getOutput());
  55. $this->assertEquals(1, $parsed['error_status']);
  56. $this->assertArrayHasKey('DRUSH_NO_DRUPAL_ROOT', $parsed['error_log']);
  57. }
  58. /*
  59. * A slightly less functional copy of drush_backend_parse_output().
  60. */
  61. function parse($string) {
  62. $regex = sprintf(self::DRUSH_BACKEND_OUTPUT_DELIMITER, '(.*)');
  63. preg_match("/$regex/s", $string, $match);
  64. if ($match[1]) {
  65. // we have our JSON encoded string
  66. $output = $match[1];
  67. // remove the match we just made and any non printing characters
  68. $string = trim(str_replace(sprintf(self::DRUSH_BACKEND_OUTPUT_DELIMITER, $match[1]), '', $string));
  69. }
  70. if ($output) {
  71. $data = json_decode($output, TRUE);
  72. if (is_array($data)) {
  73. return $data;
  74. }
  75. }
  76. return $string;
  77. }
  78. }