Command succeeds within docker manually but not through bash script

Viewed 225

The introduction

I am currently trying to build a docker image with all of my node project dependencies, so I can use it to run the tests on Bitbucket Pipelines.

The reason I decided to create an image was due to the fact I want to be in control of what version of the dependencies I have, and to control when to upgrade them accordingly.

The implementation

After having built the image using the following dockerfile:

FROM selenium/standalone-chrome-debug
LABEL name="nodejs-chrome-java"

USER root

# Install Java 8
RUN set -x \
    && apt-get update \
    && apt-get install -y \
        ca-certificates-java \
        openjdk-8-jre-headless \
        openjdk-8-jre \
        openjdk-8-jdk-headless \
        openjdk-8-jdk \
    && apt-get clean

ENV JAVA_HOME /usr/lib/jvm/java-8-openjdk-amd64/
RUN export JAVA_HOME

# Install node 10 and npm
RUN set -x \
    && curl -sL https://deb.nodesource.com/setup_14.x | bash - \
    && apt-get update \
    && apt-get install -y nodejs \
    && npm install -g npm@latest \
    && apt-get clean

# Make node available
RUN set -x \
    && touch ~/.bashrc \
    && echo 'alias nodejs=node' > ~/.bashrc

# Install PhantomJS
RUN set -x \
    && apt-get update \
    && apt-get install -y \
        phantomjs \
    && apt-get clean

# Set PhantomJS to run headless
ENV QT_QPA_PLATFORM offscreen

RUN mkdir /logs
RUN touch /logs/selenium.log

I executed the docker image using the following command:

docker run -it --entrypoint /bin/bash -v /my/project:/project -w /project <DOCKER_IMAGE_ID>

And I realised that in order to have selenium running, I would have to run the following command:

/opt/bin/start-selenium-standalone.sh

Which yields the following output:

22:14:13.034 INFO [GridLauncherV3.parse] - Selenium server version: 3.141.59, revision: e82be7d358
22:14:13.304 INFO [GridLauncherV3.lambda$buildLaunchers$3] - Launching a standalone Selenium Server on port 4444
2020-06-29 22:14:13.466:INFO::main: Logging initialized @1128ms to org.seleniumhq.jetty9.util.log.StdErrLog
22:14:14.228 INFO [WebDriverServlet.<init>] - Initialising WebDriverServlet
22:14:14.547 INFO [SeleniumServer.boot] - Selenium Server is up and running on port 4444

However, because I do not want the command line within the container to get stuck, I tried the following instead:

/opt/bin/start-selenium-standalone.sh > /logs/selenium.log 2>&1 &

Which indeed outputs the same content as stated before, into the log file I defined (/logs/selenium.log) when creating the docker image. So, so far so good

And if I then run my tests using the npm test command, all tests pass successfully.

Given this outcome, and because when I use this image within the Bitbucket Pipelines I wouldn't be able to run this command manually, I decided to include the line that starts the standalone selenium server in the background, on my bash script that gets executed when I call npm test, like so:

#!/bin/bash

printf "Starting Selenium Server"
/opt/bin/start-selenium-standalone.sh > /logs/selenium.log 2>&1 &
PROCESS_ID=$!

retry=0
maxRetries=10

until [ ${retry} -ge ${maxRetries} ]
do
    grep "Selenium Server is up and running on port 4444" /logs/selenium.log > /dev/null \
      && echo \
      && break;
    retry=$[${retry}+1]
    printf . ;
    sleep 1
done

if [ ${retry} -ge ${maxRetries} ]; then
  echo "Failed after ${maxRetries} attempts!"
  exit 1
fi

printf "Running UI tests...\n"
CONFIG_FILE_PATH='../../config_test.json' ./node_modules/.bin/nightwatch

The problem

When the command gets included into the bash script to be executed from there, it seems like the command cannot be executed on the same way as when it's done so manually. And I get the following on the log file:

22:29:12.814 INFO [GridLauncherV3.parse] - Selenium server version: 3.141.59, revision: e82be7d358
22:29:13.093 INFO [GridLauncherV3.lambda$buildLaunchers$3] - Launching a standalone Selenium Server on port 4444
2020-06-30 22:29:13.253:INFO::main: Logging initialized @1602ms to org.seleniumhq.jetty9.util.log.StdErrLog
22:29:14.058 INFO [WebDriverServlet.<init>] - Initialising WebDriverServlet
22:29:14.381 INFO [SeleniumServer.boot] - Selenium Server is up and running on port 4444
22:29:21.121 INFO [ActiveSessionFactory.apply] - Capabilities are: {
  "acceptSslCerts": true,
  "browserName": "chrome",
  "chromeOptions": {
    "w3c": false,
    "args": [
      "headless",
      "no-sandbox"
    ]
  },
  "javascriptEnabled": true,
  "name": "Route Subdomain Dashboard Test"
}
22:29:21.128 INFO [ActiveSessionFactory.lambda$apply$11] - Matched factory org.openqa.selenium.grid.session.remote.ServicedSession$Factory (provider: org.openqa.selenium.chrome.ChromeDriverService)
/my/project/node_modules/chromedriver/lib/chromedriver/chromedriver: 1: /my/project/node_modules/chromedriver/lib/chromedriver/chromedriver: Syntax error: ")" unexpected
22:29:41.214 ERROR [OsProcess.checkForError] - org.apache.commons.exec.ExecuteException: Process exited with an error: 2 (Exit value: 2)

And the following output from my running tests:

⠴ Connecting to 127.0.0.1 on port 4444...
   Response 500 POST /wd/hub/session (20425ms)
   {
     value: {
       error: [
         "Build info: version: '3.141.59', revision: 'e82be7d358', time: '2018-11-14T08:25:53'",
         "System info: host: '75136e9ec116', ip: '172.17.0.2', os.name: 'Linux', os.arch: 'amd64', os.version: '4.19.76-linuxkit', java.version: '1.8.0_252'",
         'Driver info: driver.version: unknown'
       ],
       message: 'Timed out waiting for driver server to start.'
     },
     status: 13
⚠ Error connecting to 127.0.0.1 on port 4444.
_________________________________________________

TEST FAILURE: 1 error during execution; 0 tests failed, 0 passed (24.402s)

 ✖ route-subdomain-dashboard-test
   An error occurred while retrieving a new session: "Timed out waiting for driver server to start."
Error: An error occurred while retrieving a new session: "Timed out waiting for driver server to start."
    at endReadableNT (_stream_readable.js:1224:12)
    at processTicksAndRejections (internal/process/task_queues.js:84:21)

  Error: An error occurred while retrieving a new session: "Timed out waiting for driver server to start."
       at endReadableNT (_stream_readable.js:1224:12)
       at processTicksAndRejections (internal/process/task_queues.js:84:21)

The question

Is there anything I am missing that would allow the command to be successfully executed through the bash script? Why am I seeing such disparate results?

The appreciation

Sorry for the long post, but I think I needed to provide as much context as possible, since it seems a very tricky problem that I've been struggling for quite some time now.

Many thanks in advance


Updates

  • 02/10/2020 - I realised today that once inside the docker image, if I execute the npm test command in order to run the tests, I have the issue described under the section named The problem. However, if I run the bash script that I created and that npm test command is calling under the hood, I have the tests successfully executed. Could it be the way that npm executes the scripts?
0 Answers
Related