Skip to content

Commit a328437

Browse files
authored
Merge pull request #773 from SeleniumHQ/wait-for-it
Adding info on how to wait for the Grid to be ready
2 parents 505d0bb + 3c9a273 commit a328437

File tree

6 files changed

+154
-3
lines changed

6 files changed

+154
-3
lines changed

.github/ISSUE_TEMPLATE.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
## Meta -
2+
3+
<!-- Please fill out the whole template so we have enough information to help you fix
4+
the issue as fast as possible. -->
5+
6+
<!-- If the template is not complete or deleted, we might close the issue right away
7+
since we will lack the needed information to troubleshoot it. -->
8+
29
Image(s):
310
<!-- node-chrome? hub? standalone-firefox? -->
411
Docker-Selenium Image Version(s):
@@ -21,3 +28,9 @@ https://bugzilla.mozilla.org/buglist.cgi?product=Testing&component=Marionette
2128
## Expected Behavior -
2229

2330
## Actual Behavior -
31+
32+
## Steps to reproduce -
33+
<!--
34+
Please be sure to include an SSCCE (Short, Self Contained, Correct [compilable] example) http://sscce.org/
35+
If you can't provide a link to the page, consider creating a reproducible page on https://jsfiddle.net/
36+
-->

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
1+
<!-- Thanks for sending us a PR to improve this project! If you are adding a
2+
feature or fixing a bug, and this needs more documentation, please add it to your PR. -->
3+
4+
15
- [ ] By placing an `X` in the preceding checkbox, I verify that I have signed the [Contributor License Agreement](https://github.com/SeleniumHQ/docker-selenium/blob/master/CONTRIBUTING.md#contributing-code-to-selenium)

Base/Dockerfile

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ RUN apt-get -qqy update \
2525
sudo \
2626
unzip \
2727
wget \
28+
jq \
29+
curl \
2830
&& rm -rf /var/lib/apt/lists/* /var/cache/apt/* \
2931
&& sed -i 's/securerandom\.source=file:\/dev\/random/securerandom\.source=file:\/dev\/urandom/' ./usr/lib/jvm/java-8-openjdk-amd64/jre/lib/security/java.security
3032

@@ -46,6 +48,18 @@ RUN useradd seluser \
4648
&& echo 'ALL ALL = (ALL) NOPASSWD: ALL' >> /etc/sudoers \
4749
&& echo 'seluser:secret' | chpasswd
4850

51+
#=======================================
52+
# Create shared / common bin directory
53+
#=======================================
54+
RUN mkdir -p /opt/bin
55+
56+
#======================================
57+
# Add intermediate service discovery
58+
#======================================
59+
COPY check-grid.sh \
60+
/opt/bin/
61+
RUN chmod +x /opt/bin/check-grid.sh
62+
4963
#===================================================
5064
# Run the following commands as non-privileged user
5165
#===================================================

Base/check-grid.sh

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#!/usr/bin/env bash
2+
# check-grid.sh
3+
4+
set -e
5+
6+
HOST="localhost"
7+
PORT="4444"
8+
9+
# process arguments
10+
while [[ $# -gt 0 ]]
11+
do
12+
case "$1" in
13+
--host)
14+
HOST=${2:-"localhost"}
15+
shift 2
16+
;;
17+
--port)
18+
PORT=${2:-"4444"}
19+
shift 2
20+
;;
21+
*)
22+
echoerr "Unknown argument: $1"
23+
;;
24+
esac
25+
done
26+
27+
curl -sSL http://${HOST}:${PORT}/wd/hub/status | jq -r '.value.ready' | grep "true" || exit 1

Hub/Dockerfile.txt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,7 @@ ENV GRID_HUB_HOST "0.0.0.0"
3030
COPY generate_config \
3131
entry_point.sh \
3232
/opt/bin/
33-
# Running this command as sudo just to avoid the message:
34-
# To run a command as administrator (user "root"), use "sudo <command>". See "man sudo_root" for details.
35-
# When logging into the container
33+
3634
RUN /opt/bin/generate_config > /opt/selenium/config.json
3735

3836
CMD ["/opt/bin/entry_point.sh"]

README.md

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,101 @@ $ FF=$(docker run --rm --name=fx \
269269

270270
_Note: Since a Docker container is not meant to preserve state and spawning a new one takes less than 3 seconds you will likely want to remove containers after each end-to-end test with_ `--rm` _command. You need to think of your Docker containers as single processes, not as running virtual machines, in case you are familiar with [Vagrant](https://www.vagrantup.com/)._
271271

272+
## Waiting for the Grid to be ready
273+
274+
It is a good practice to check first if the Grid is up and ready to receive requests, this can be done by checking the `/wd/hub/status` endpoint.
275+
276+
A Grid that is ready, composed by a hub and a node, could look like this:
277+
278+
```json
279+
{
280+
"status": 0,
281+
"value": {
282+
"ready": true,
283+
"message": "Hub has capacity",
284+
"build": {
285+
"revision": "aacccce0",
286+
"time": "2018-08-02T20:13:22.693Z",
287+
"version": "3.14.0"
288+
},
289+
"os": {
290+
"arch": "amd64",
291+
"name": "Linux",
292+
"version": "4.9.93-linuxkit-aufs"
293+
},
294+
"java": {
295+
"version": "1.8.0_181"
296+
}
297+
}
298+
}
299+
```
300+
301+
The `"ready": true` value indicates that the Grid is ready to receive requests. This status can be polled through a
302+
script before running any test, or it can be added as a [HEALTHCHECK](https://docs.docker.com/engine/reference/run/#healthcheck)
303+
when the docker container is started.
304+
305+
### Adding a [HEALTHCHECK](https://docs.docker.com/engine/reference/run/#healthcheck) to the Grid
306+
307+
The script [check-grid.sh](Base/check-grid.sh), which is included in the images, can be used to poll the Grid status.
308+
309+
This example checks the status of the Grid every 15 seconds, it has a timeout of 30 seconds when the check is done,
310+
and it retries up to 5 times until the container is marked as unhealthy. Please use adjusted values to fit your needs,
311+
(if needed) replace the `--host` and `--port` parameters for the ones used in your environment.
312+
313+
``` bash
314+
$ docker network create grid
315+
$ docker run -d -p 4444:4444 --net grid --name selenium-hub \
316+
--health-cmd='/opt/bin/check-grid.sh --host 0.0.0.0 --port 4444' \
317+
--health-interval=15s --health-timeout=30s --health-retries=5 \
318+
selenium/hub:3.14.0-arsenic
319+
$ docker run -d --net grid -e HUB_HOST=selenium-hub -v /dev/shm:/dev/shm selenium/node-chrome:3.14.0-arsenic
320+
$ docker run -d --net grid -e HUB_HOST=selenium-hub -v /dev/shm:/dev/shm selenium/node-firefox:3.14.0-arsenic
321+
```
322+
**Note:** The `\` line delimiter won't work on Windows based terminals, try either `^` or a backtick.
323+
324+
The container health status can be checked by doing `docker ps` and verifying the `(healthy)|(unhealthy)` status or by
325+
inspecting it in the following way:
326+
327+
```bash
328+
$ docker inspect --format='{{json .State.Health.Status}}' selenium-hub
329+
"healthy"
330+
```
331+
332+
### Using a bash script to wait for the Grid
333+
334+
A common problem known in docker is that a running container does not always mean that the application inside it is ready.
335+
A simple way to tackle this is by using a "wait-for-it" script, more information can be seen [here](https://docs.docker.com/compose/startup-order/).
336+
337+
The following script is an example of how this can be done using bash, but the same principle applies if you want to do this with the programming language used to write the tests.
338+
339+
```bash
340+
#!/bin/bash
341+
# wait-for-grid.sh
342+
343+
set -e
344+
345+
cmd="$@"
346+
347+
while ! curl -sSL "http://localhost:4444/wd/hub/status" 2>&1 \
348+
| jq -r '.value.ready' 2>&1 | grep "true" >/dev/null; do
349+
echo 'Waiting for the Grid'
350+
sleep 1
351+
done
352+
353+
>&2 echo "Selenium Grid is up - executing tests"
354+
exec $cmd
355+
```
356+
**Note:** If needed, replace `localhost` and `4444` for the correct values in your environment. Also, this script is polling indefinitely, you might want
357+
to tweak it and establish a timeout.
358+
359+
Let's say that the normal command to execute your tests is `mvn clean test`. Here is a way to use the above script and execute your tests:
360+
361+
```bash
362+
$ ./wait-for-grid.sh mvn clean test
363+
```
364+
365+
Like this, the script will poll until the Grid is ready, and then your tests will start.
366+
272367
## Debugging
273368

274369
In the event you wish to visually see what the browser is doing you will want to run the `debug` variant of node or standalone images. A VNC server will run on port 5900. You are free to map that to any free external port that you wish. Keep in mind that you will only be able to run one node per port so if you wish to include a second node, or more, you will have to use different ports, the 5900 as the internal port will have to remain the same though as thats the VNC service on the node. The second example below shows how to run multiple nodes and with different VNC ports open:

0 commit comments

Comments
 (0)