NextcloudTestServerLocalBuiltInHelper.php 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. <?php
  2. /**
  3. *
  4. * @copyright Copyright (c) 2017, Daniel Calviño Sánchez (danxuliu@gmail.com)
  5. *
  6. * @license GNU AGPL version 3 or any later version
  7. *
  8. * This program is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU Affero General Public License as
  10. * published by the Free Software Foundation, either version 3 of the
  11. * License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU Affero General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Affero General Public License
  19. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. *
  21. */
  22. /**
  23. * Helper to manage a Nextcloud test server started directly by the acceptance
  24. * tests themselves using the PHP built-in web server.
  25. *
  26. * The Nextcloud test server is executed using the PHP built-in web server
  27. * directly from the grandparent directory of the acceptance tests directory
  28. * (that is, the root directory of the Nextcloud server); note that the
  29. * acceptance tests must be run from the acceptance tests directory. The "setUp"
  30. * method resets the Nextcloud server to its initial state and starts it, while
  31. * the "cleanUp" method stops it. To be able to reset the Nextcloud server to
  32. * its initial state a Git repository must be provided in the root directory of
  33. * the Nextcloud server; the last commit in that Git repository must provide the
  34. * initial state for the Nextcloud server expected by the acceptance tests.
  35. *
  36. * The Nextcloud server is available at "$nextcloudServerDomain", which can be
  37. * optionally specified when the NextcloudTestServerLocalBuiltInHelper is
  38. * created; if no value is given "127.0.0.1" is used by default. In any case,
  39. * the value of "$nextcloudServerDomain" must be seen as a trusted domain by the
  40. * Nextcloud server (which would be the case for "127.0.0.1" if it was installed
  41. * by running "occ maintenance:install"). The base URL to access the Nextcloud
  42. * server can be got from "getBaseUrl".
  43. */
  44. class NextcloudTestServerLocalBuiltInHelper implements NextcloudTestServerHelper {
  45. /**
  46. * @var string
  47. */
  48. private $nextcloudServerDomain;
  49. /**
  50. * @var string
  51. */
  52. private $phpServerPid;
  53. /**
  54. * Creates a new NextcloudTestServerLocalBuiltInHelper.
  55. */
  56. public function __construct($nextcloudServerDomain = "127.0.0.1") {
  57. $this->nextcloudServerDomain = $nextcloudServerDomain;
  58. $this->phpServerPid = "";
  59. }
  60. /**
  61. * Sets up the Nextcloud test server.
  62. *
  63. * It resets the Nextcloud test server restoring its last saved Git state
  64. * and then waits for the Nextcloud test server to start again; if the
  65. * server can not be reset or if it does not start again after some time an
  66. * exception is thrown (as it is just a warning for the test runner and
  67. * nothing to be explicitly catched a plain base Exception is used).
  68. *
  69. * @throws \Exception if the Nextcloud test server can not be reset or
  70. * started again.
  71. */
  72. public function setUp(): void {
  73. // Ensure that previous PHP server is not running (as cleanUp may not
  74. // have been called).
  75. $this->killPhpServer();
  76. $this->execOrException("cd ../../ && git reset --hard HEAD");
  77. $this->execOrException("cd ../../ && git clean -d --force");
  78. // execOrException is not used because the server is started in the
  79. // background, so the command will always succeed even if the server
  80. // itself fails.
  81. $this->phpServerPid = exec("php -S " . $this->nextcloudServerDomain . ":80 -t ../../ >/dev/null 2>&1 & echo $!");
  82. $timeout = 60;
  83. if (!Utils::waitForServer($this->getBaseUrl(), $timeout)) {
  84. throw new Exception("Nextcloud test server could not be started");
  85. }
  86. }
  87. /**
  88. * Cleans up the Nextcloud test server.
  89. *
  90. * It kills the running Nextcloud test server, if any.
  91. */
  92. public function cleanUp() {
  93. $this->killPhpServer();
  94. }
  95. /**
  96. * Returns the base URL of the Nextcloud test server.
  97. *
  98. * @return string the base URL of the Nextcloud test server.
  99. */
  100. public function getBaseUrl() {
  101. return "http://" . $this->nextcloudServerDomain . "/index.php";
  102. }
  103. /**
  104. * Executes the given command, throwing an Exception if it fails.
  105. *
  106. * @param string $command the command to execute.
  107. * @throws \Exception if the command fails to execute.
  108. */
  109. private function execOrException($command) {
  110. exec($command . " 2>&1", $output, $returnValue);
  111. if ($returnValue != 0) {
  112. throw new Exception("'$command' could not be executed: " . implode("\n", $output));
  113. }
  114. }
  115. /**
  116. * Kills the PHP built-in web server started in setUp, if any.
  117. */
  118. private function killPhpServer() {
  119. if ($this->phpServerPid == "") {
  120. return;
  121. }
  122. // execOrException is not used because the PID may no longer exist when
  123. // trying to kill it.
  124. exec("kill " . $this->phpServerPid);
  125. $this->phpServerPid = "";
  126. }
  127. }