You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

run.sh 10KB

Update acceptance tests to Selenium 3 The acceptance tests used the last Selenium 2 Docker container available, which provides a rather old Firefox version (Firefox 47). Nevertheless, despite some rendering issues, most things still worked as expected due to the JavaScript files being built with support for older browsers. However, now that support for Internet Explorer 11 and older browsers will be dropped things could start to fail, so a newer browser (and thus a newer Selenium version) should be used in the acceptance tests. Selenium has been standardized by the W3C, and the protocol to communicate between the Selenium server and the browser has changed due to that. Firefox >= 48 only supports the new W3C protocol, but the Selenium driver for Mink does not support it yet. The old protocol can still be used in recent Chromium/Chrome versions by explicitly forcing it, so for the time being the acceptance tests will need to be run on Chrome instead (although Firefox provides some interesting features like the fake streams that would be needed to test calls in Talk, so they should be moved again to Firefox once possible). Finally, the default shm size of Docker is 64 MiB. This does not seem enough to run newer Chrome releases and causes the browser to randomly crash during the tests ("unknown error: session deleted because of page crash" is shown in the logs). Due to this "disable-dev-shm-usage" needs to be used so Chrome writes shared memory files into "/tmp" instead of "/dev/shm" (the default shm size of Docker could have been increased instead using "docker run --shm-size...", but that seems to be problematic when the container is run in current Drone releases). Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
3 years ago
Update acceptance tests to Selenium 3 The acceptance tests used the last Selenium 2 Docker container available, which provides a rather old Firefox version (Firefox 47). Nevertheless, despite some rendering issues, most things still worked as expected due to the JavaScript files being built with support for older browsers. However, now that support for Internet Explorer 11 and older browsers will be dropped things could start to fail, so a newer browser (and thus a newer Selenium version) should be used in the acceptance tests. Selenium has been standardized by the W3C, and the protocol to communicate between the Selenium server and the browser has changed due to that. Firefox >= 48 only supports the new W3C protocol, but the Selenium driver for Mink does not support it yet. The old protocol can still be used in recent Chromium/Chrome versions by explicitly forcing it, so for the time being the acceptance tests will need to be run on Chrome instead (although Firefox provides some interesting features like the fake streams that would be needed to test calls in Talk, so they should be moved again to Firefox once possible). Finally, the default shm size of Docker is 64 MiB. This does not seem enough to run newer Chrome releases and causes the browser to randomly crash during the tests ("unknown error: session deleted because of page crash" is shown in the logs). Due to this "disable-dev-shm-usage" needs to be used so Chrome writes shared memory files into "/tmp" instead of "/dev/shm" (the default shm size of Docker could have been increased instead using "docker run --shm-size...", but that seems to be problematic when the container is run in current Drone releases). Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
3 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. #!/usr/bin/env bash
  2. # @copyright Copyright (c) 2017, Daniel Calviño Sánchez (danxuliu@gmail.com)
  3. #
  4. # @license GNU AGPL version 3 or any later version
  5. #
  6. # This program is free software: you can redistribute it and/or modify
  7. # it under the terms of the GNU Affero General Public License as
  8. # published by the Free Software Foundation, either version 3 of the
  9. # License, or (at your option) any later version.
  10. #
  11. # This program is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. # GNU Affero General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU Affero General Public License
  17. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. # Helper script to run the acceptance tests, which test a running Nextcloud
  19. # instance from the point of view of a real user.
  20. #
  21. # The acceptance tests are run in its own Docker container; the grandparent
  22. # directory of the acceptance tests directory (that is, the root directory of
  23. # the Nextcloud server) is copied to the container and the acceptance tests are
  24. # run inside it. Once the tests end the container is stopped. The acceptance
  25. # tests also use the Selenium server to control a web browser, so the Selenium
  26. # server is also launched before the tests start in its own Docker container (it
  27. # will be stopped automatically too once the tests end).
  28. #
  29. # To perform its job, the script requires the "docker" command to be available.
  30. #
  31. # The Docker Command Line Interface (the "docker" command) requires special
  32. # permissions to talk to the Docker daemon, and those permissions are typically
  33. # available only to the root user. Please see the Docker documentation to find
  34. # out how to give access to a regular user to the Docker daemon:
  35. # https://docs.docker.com/engine/installation/linux/linux-postinstall/
  36. #
  37. # Note, however, that being able to communicate with the Docker daemon is the
  38. # same as being able to get root privileges for the system. Therefore, you must
  39. # give access to the Docker daemon (and thus run this script as) ONLY to trusted
  40. # and secure users:
  41. # https://docs.docker.com/engine/security/security/#docker-daemon-attack-surface
  42. #
  43. # Finally, take into account that this script will automatically remove the
  44. # Docker containers named "selenium-nextcloud-local-test-acceptance" and
  45. # "nextcloud-local-test-acceptance", even if the script did not create them
  46. # (probably you will not have containers nor images with those names, but just
  47. # in case).
  48. # Sets the variables that abstract the differences in command names and options
  49. # between operating systems.
  50. #
  51. # Switches between timeout on GNU/Linux and gtimeout on macOS (same for mktemp
  52. # and gmktemp).
  53. function setOperatingSystemAbstractionVariables() {
  54. case "$OSTYPE" in
  55. darwin*)
  56. if [ "$(which gtimeout)" == "" ]; then
  57. echo "Please install coreutils (brew install coreutils)"
  58. exit 1
  59. fi
  60. MKTEMP=gmktemp
  61. TIMEOUT=gtimeout
  62. DOCKER_OPTIONS="-e no_proxy=localhost "
  63. ;;
  64. linux*)
  65. MKTEMP=mktemp
  66. TIMEOUT=timeout
  67. DOCKER_OPTIONS=" "
  68. ;;
  69. *)
  70. echo "Operating system ($OSTYPE) not supported"
  71. exit 1
  72. ;;
  73. esac
  74. }
  75. # Launches the Selenium server in a Docker container.
  76. #
  77. # The acceptance tests use Firefox by default but, unfortunately, Firefox >= 48
  78. # does not provide yet the same level of support as earlier versions for certain
  79. # features related to automated testing. Therefore, the Docker image used is not
  80. # the latest one, but an older version known to work.
  81. #
  82. # The acceptance tests expect the Selenium server to be accessible at
  83. # "127.0.0.1:4444"; as the Selenium server container and the container in which
  84. # the acceptance tests are run share the same network nothing else needs to be
  85. # done for the acceptance tests to access the Selenium server and for the
  86. # Selenium server to access the Nextcloud server. However, in order to ensure
  87. # from this script that the Selenium server was started the 4444 port of its
  88. # container is mapped to the 4444 port of the host.
  89. #
  90. # Besides the Selenium server, the Docker image also provides a VNC server, so
  91. # the 5900 port of the container is also mapped to the 5900 port of the host.
  92. #
  93. # The Docker container started here will be automatically stopped when the
  94. # script exits (see cleanUp). If the Selenium server can not be started then the
  95. # script will be exited immediately with an error state; the most common cause
  96. # for the Selenium server to fail to start is that another server is already
  97. # using the mapped ports in the host.
  98. #
  99. # As the web browser is run inside the Docker container it is not visible by
  100. # default. However, it can be viewed using VNC (for example,
  101. # "vncviewer 127.0.0.1:5900"); when asked for the password use "secret".
  102. function prepareSelenium() {
  103. SELENIUM_CONTAINER=selenium-nextcloud-local-test-acceptance
  104. echo "Starting Selenium server"
  105. docker run --detach --name=$SELENIUM_CONTAINER --publish 4444:4444 --publish 5900:5900 $DOCKER_OPTIONS selenium/standalone-chrome-debug:3.141.59
  106. echo "Waiting for Selenium server to be ready"
  107. if ! $TIMEOUT 10s bash -c "while ! curl 127.0.0.1:4444 >/dev/null 2>&1; do sleep 1; done"; then
  108. echo "Could not start Selenium server; running" \
  109. "\"docker run --rm --publish 4444:4444 --publish 5900:5900 $DOCKER_OPTIONS selenium/standalone-chrome-debug:3.141.59\"" \
  110. "could give you a hint of the problem"
  111. exit 1
  112. fi
  113. }
  114. # Creates a Docker container to run both the acceptance tests and the Nextcloud
  115. # server used by them.
  116. #
  117. # This function starts a Docker container with a copy the Nextcloud code from
  118. # the grandparent directory, although ignoring any configuration or data that it
  119. # may provide (for example, if that directory was used directly to deploy a
  120. # Nextcloud instance in a web server). As the Nextcloud code is copied to the
  121. # container instead of referenced the original code can be modified while the
  122. # acceptance tests are running without interfering in them.
  123. function prepareDocker() {
  124. NEXTCLOUD_LOCAL_CONTAINER=nextcloud-local-test-acceptance
  125. echo "Starting the Nextcloud container"
  126. # As the Nextcloud server container uses the network of the Selenium server
  127. # container the Nextcloud server can be accessed at "127.0.0.1" from the
  128. # Selenium server.
  129. # The container exits immediately if no command is given, so a Bash session
  130. # is created to prevent that.
  131. docker run --detach --name=$NEXTCLOUD_LOCAL_CONTAINER --network=container:$SELENIUM_CONTAINER --interactive --tty nextcloudci/acceptance-php7.3:acceptance-php7.3-2 bash
  132. # Use the $TMPDIR or, if not set, fall back to /tmp.
  133. NEXTCLOUD_LOCAL_TAR="$($MKTEMP --tmpdir="${TMPDIR:-/tmp}" --suffix=.tar nextcloud-local-XXXXXXXXXX)"
  134. # Setting the user and group of files in the tar would be superfluous, as
  135. # "docker cp" does not take them into account (the extracted files are set
  136. # to root).
  137. echo "Copying local Git working directory of Nextcloud to the container"
  138. tar --create --file="$NEXTCLOUD_LOCAL_TAR" \
  139. --exclude=".git" \
  140. --exclude="./build" \
  141. --exclude="./config/config.php" \
  142. --exclude="./data" \
  143. --exclude="./data-autotest" \
  144. --exclude="./tests" \
  145. --exclude="./apps-extra" \
  146. --exclude="./apps-writable" \
  147. --exclude="node_modules" \
  148. --directory=../../ \
  149. .
  150. tar --append --file="$NEXTCLOUD_LOCAL_TAR" --directory=../../ tests/acceptance/
  151. docker exec $NEXTCLOUD_LOCAL_CONTAINER mkdir /nextcloud
  152. docker cp - $NEXTCLOUD_LOCAL_CONTAINER:/nextcloud/ < "$NEXTCLOUD_LOCAL_TAR"
  153. # run-local.sh expects a Git repository to be available in the root of the
  154. # Nextcloud server, but it was excluded when the Git working directory was
  155. # copied to the container to avoid copying the large and unneeded history of
  156. # the repository.
  157. docker exec $NEXTCLOUD_LOCAL_CONTAINER bash -c "cd nextcloud && git init"
  158. }
  159. # Removes/stops temporal elements created/started by this script.
  160. function cleanUp() {
  161. # Disable (yes, "+" disables) exiting immediately on errors to ensure that
  162. # all the cleanup commands are executed (well, no errors should occur during
  163. # the cleanup anyway, but just in case).
  164. set +o errexit
  165. echo "Cleaning up"
  166. if [ -f "$NEXTCLOUD_LOCAL_TAR" ]; then
  167. echo "Removing $NEXTCLOUD_LOCAL_TAR"
  168. rm $NEXTCLOUD_LOCAL_TAR
  169. fi
  170. # The name filter must be specified as "^/XXX$" to get an exact match; using
  171. # just "XXX" would match every name that contained "XXX".
  172. if [ -n "$(docker ps --all --quiet --filter name="^/$NEXTCLOUD_LOCAL_CONTAINER$")" ]; then
  173. echo "Removing Docker container $NEXTCLOUD_LOCAL_CONTAINER"
  174. docker rm --volumes --force $NEXTCLOUD_LOCAL_CONTAINER
  175. fi
  176. if [ -n "$(docker ps --all --quiet --filter name="^/$SELENIUM_CONTAINER$")" ]; then
  177. echo "Removing Docker container $SELENIUM_CONTAINER"
  178. docker rm --volumes --force $SELENIUM_CONTAINER
  179. fi
  180. }
  181. # Exit immediately on errors.
  182. set -o errexit
  183. # Execute cleanUp when the script exits, either normally or due to an error.
  184. trap cleanUp EXIT
  185. # Ensure working directory is script directory, as some actions (like copying
  186. # the Git working directory to the container) expect that.
  187. cd "$(dirname $0)"
  188. # "--acceptance-tests-dir XXX" option can be provided to set the directory
  189. # (relative to the root directory of the Nextcloud server) used to look for the
  190. # Behat configuration and the Nextcloud installation script.
  191. # By default it is "tests/acceptance", that is, the acceptance tests for the
  192. # Nextcloud server itself.
  193. ACCEPTANCE_TESTS_DIR_OPTION=""
  194. if [ "$1" = "--acceptance-tests-dir" ]; then
  195. ACCEPTANCE_TESTS_DIR_OPTION="--acceptance-tests-dir $2"
  196. shift 2
  197. fi
  198. # "--timeout-multiplier N" option can be provided before the specific scenario
  199. # to run, if any, to set the timeout multiplier to be used in the acceptance
  200. # tests.
  201. TIMEOUT_MULTIPLIER_OPTION=""
  202. if [ "$1" = "--timeout-multiplier" ]; then
  203. if [[ ! "$2" =~ ^[0-9]+$ ]]; then
  204. echo "--timeout-multiplier must be followed by a positive integer"
  205. exit 1
  206. fi
  207. TIMEOUT_MULTIPLIER_OPTION="--timeout-multiplier $2"
  208. shift 2
  209. fi
  210. # If no parameter is provided to this script all the acceptance tests are run.
  211. SCENARIO_TO_RUN=$1
  212. setOperatingSystemAbstractionVariables
  213. prepareSelenium
  214. prepareDocker
  215. echo "Running tests"
  216. docker exec $NEXTCLOUD_LOCAL_CONTAINER bash -c "cd nextcloud && tests/acceptance/run-local.sh $ACCEPTANCE_TESTS_DIR_OPTION $TIMEOUT_MULTIPLIER_OPTION allow-git-repository-modifications $SCENARIO_TO_RUN"