From 0c550ed10620bea2caf881dc4cfb04f62abdcc6d Mon Sep 17 00:00:00 2001 From: Peter Hedenskog Date: Tue, 12 Dec 2017 10:21:52 +0100 Subject: [PATCH] Add Dockerfile for WebPageReplay fun (#1849) --- .eslintrc.json | 37 +++++++-------- Dockerfile.wpr | 51 ++++++++++++++++++++ bin/browsertimeWebPageReplay.js | 62 +++++++++++++++++++++++++ docker/scripts/start.sh | 82 ++++++++++++++++++++++++--------- release.sh | 3 ++ 5 files changed, 196 insertions(+), 39 deletions(-) create mode 100644 Dockerfile.wpr create mode 100755 bin/browsertimeWebPageReplay.js diff --git a/.eslintrc.json b/.eslintrc.json index 5d2f7439f..6b4532414 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,21 +1,22 @@ { - "root": true, - "env": { - "node": true, - "es6": true - }, - "plugins": [ - "prettier" + "root": true, + "env": { + "node": true, + "es6": true + }, + "parserOptions": { + "ecmaVersion": 8 + }, + "plugins": ["prettier"], + "extends": "eslint:recommended", + "rules": { + "prettier/prettier": [ + "error", + { + "singleQuote": true + } ], - "extends": "eslint:recommended", - "rules": { - "prettier/prettier": [ - "error", - { - "singleQuote": true - } - ], - "no-extra-semi": 0, - "no-mixed-spaces-and-tabs": 0 - } + "no-extra-semi": 0, + "no-mixed-spaces-and-tabs": 0 + } } diff --git a/Dockerfile.wpr b/Dockerfile.wpr new file mode 100644 index 000000000..cb8b11825 --- /dev/null +++ b/Dockerfile.wpr @@ -0,0 +1,51 @@ +FROM sitespeedio/webbrowsers:firefox-57.0-chrome-63.0 + +ENV SITESPEED_IO_BROWSERTIME__XVFB true +ENV SITESPEED_IO_BROWSERTIME__DOCKER true +ENV SITESPEED_IO_BROWSERTIME__VIDEO true +ENV SITESPEED_IO_BROWSERTIME__speedIndex true + +# Install Go, WebPageReplay and the webpagereplay wrapper + +WORKDIR /work +RUN sudo apt-get update && sudo apt-get install libnss3-tools \ + curl \ + git \ + build-essential \ + iproute2 -y && \ + mkdir -p $HOME/.pki/nssdb && \ + certutil -d $HOME/.pki/nssdb -N && \ + curl -O https://storage.googleapis.com/golang/go1.9.linux-amd64.tar.gz && \ + tar -xvf go1.9.linux-amd64.tar.gz && \ + sudo mv go /usr/local + +ENV PATH="/usr/local/go/bin:${PATH}" + +RUN go get github.com/urfave/cli && \ + go get golang.org/x/net/http2 && \ + go get github.com/catapult-project/catapult/web_page_replay_go/src/webpagereplay && \ + npm install webpagereplaywrapper -g + +WORKDIR /root/go/src/github.com/catapult-project/catapult/web_page_replay_go +RUN go run src/wpr.go installroot + +RUN mkdir -p /usr/src/app +WORKDIR /usr/src/app + +VOLUME /sitespeed.io + +COPY package.* /usr/src/app/ +RUN npm install --production +COPY . /usr/src/app + +## This is to avoid click the OK button +RUN mkdir -m 0750 /root/.android +ADD docker/adb/insecure_shared_adbkey /root/.android/adbkey +ADD docker/adb/insecure_shared_adbkey.pub /root/.android/adbkey.pub + +VOLUME /sitespeed.io +WORKDIR /sitespeed.io + +COPY docker/scripts/start.sh /start.sh + +ENTRYPOINT ["/start.sh"] diff --git a/bin/browsertimeWebPageReplay.js b/bin/browsertimeWebPageReplay.js new file mode 100755 index 000000000..c8d8812c3 --- /dev/null +++ b/bin/browsertimeWebPageReplay.js @@ -0,0 +1,62 @@ +#!/usr/bin/env node + +'use strict'; + +let yargs = require('yargs'), + browsertime = require('browsertime'), + merge = require('lodash.merge'), + getURLs = require('../lib/cli/util').getURLs, + browsertimeConfig = require('../lib/plugins/browsertime/index').config; + +async function testURL(engine, url) { + await engine + .start() + .then(() => engine.run(url)) + .finally(() => engine.stop()); +} + +async function runBrowsertime() { + let parsed = yargs + .env('SITESPEED_IO') + .require(1, 'urlOrFile') + .option('browsertime.browser', { + alias: ['b', 'browser'], + default: browsertimeConfig.browser, + describe: 'Choose which Browser to use when you test.', + choices: ['chrome', 'firefox'], + group: 'Browser' + }) + .option('browsertime.viewPort', { + default: browsertimeConfig.viewPort, + describe: 'The browser view port size WidthxHeight like 400x300', + group: 'Browser' + }); + + const defaultConfig = { + iterations: 1, + connectivity: { + profile: 'native', + downstreamKbps: undefined, + upstreamKbps: undefined, + latency: undefined, + engine: 'external' + }, + viewPort: '1366x708', + delay: 0, + video: false, + speedIndex: false, + resultDir: '/tmp/browsertime' + }; + + const btOptions = merge({}, parsed.argv.browsertime, defaultConfig); + browsertime.logging.configure(parsed.argv); + + const engine = new browsertime.Engine(btOptions); + const urls = getURLs(parsed.argv._); + + for (let url of urls) { + await testURL(engine, url); + } +} + +runBrowsertime(); diff --git a/docker/scripts/start.sh b/docker/scripts/start.sh index ba2863403..e9db8acc1 100755 --- a/docker/scripts/start.sh +++ b/docker/scripts/start.sh @@ -4,33 +4,73 @@ set -e google-chrome --version firefox --version +BROWSERTIME=/usr/src/app/bin/browsertimeWebPageReplay.js +SITESPEEDIO=/usr/src/app/bin/sitespeed.js + # Here's a hack for fixing the problem with Chrome not starting in time # See https://github.com/SeleniumHQ/docker-selenium/issues/87#issuecomment-250475864 +function chromeSetup() { + sudo rm -f /var/lib/dbus/machine-id + sudo mkdir -p /var/run/dbus + sudo service dbus restart > /dev/null + service dbus status > /dev/null + export $(dbus-launch) + export NSS_USE_SHARED_DB=ENABLED +} -sudo rm -f /var/lib/dbus/machine-id -sudo mkdir -p /var/run/dbus -sudo service dbus restart > /dev/null -service dbus status > /dev/null -export $(dbus-launch) -export NSS_USE_SHARED_DB=ENABLED +# If we run Chrome on Android, we need to start the ADB server +function setupADB(){ + # Start adb server and list connected devices + if [ -n "$START_ADB_SERVER" ] ; then + sudo adb start-server + sudo adb devices + fi +} -# Start adb server and list connected devices -if [ -n "$START_ADB_SERVER" ] ; then - sudo adb start-server - sudo adb devices -fi +function runWebPageReplay() { -# Inspired by docker-selenium way of shutting down -function shutdown { - kill -s SIGTERM $PID + LATENCY=${LATENCY:-100} + HTTP_PORT=80 + HTTPS_PORT=443 + WPR_PATH=/root/go/src/github.com/catapult-project/catapult/web_page_replay_go + WPR_PARAMS="--path $WPR_PATH --http $HTTP_PORT --https $HTTPS_PORT" + + webpagereplaywrapper record --start $WPR_PARAMS + + $BROWSERTIME --browsertime.chrome.args host-resolver-rules="MAP *:$HTTP_PORT 127.0.0.1:$HTTP_PORT,MAP *:$HTTPS_PORT 127.0.0.1:$HTTPS_PORT,EXCLUDE localhost" --browsertime.firefox.preference network.dns.forceResolve:127.0.0.1 --browsertime.firefox.acceptInsecureCerts --browsertime.skipHar --browsertime.pageCompleteCheck "return true;" "$@" + + webpagereplaywrapper record --stop $WPR_PARAMS + + webpagereplaywrapper replay --start $WPR_PARAMS + + $SITESPEEDIO --browsertime.firefox.acceptInsecureCerts --browsertime.firefox.preference network.dns.forceResolve:127.0.0.1 --browsertime.chrome.args host-resolver-rules="MAP *:$HTTP_PORT 127.0.0.1:$HTTP_PORT,MAP *:$HTTPS_PORT 127.0.0.1:$HTTPS_PORT,EXCLUDE localhost" --video --speedIndex --browsertime.pageCompleteCheck "return true;" --browsertime.connectivity.engine throttle --browsertime.connectivity.throttle.localhost --browsertime.connectivity.profile custom --browsertime.connectivity.latency $LATENCY "$@" + + webpagereplaywrapper replay --stop $WPR_PARAMS +} + + +function runSitespeedio(){ + + # Inspired by docker-selenium way of shutting down + function shutdown { + kill -s SIGTERM ${PID} + wait $PID + } + + exec $SITESPEEDIO "$@" & + + PID=$! + + trap shutdown SIGTERM SIGINT wait $PID } -MAX_OLD_SPACE_SIZE="${MAX_OLD_SPACE_SIZE:-2048}" +chromeSetup +setupADB -exec node --max-old-space-size=$MAX_OLD_SPACE_SIZE /usr/src/app/bin/sitespeed.js "$@" & - -PID=$! - -trap shutdown SIGTERM SIGINT -wait $PID +if [ $REPLAY ] +then + runWebPageReplay $@ +else + runSitespeedio $@ +fi diff --git a/release.sh b/release.sh index 4cc1284b2..e049c1e6b 100755 --- a/release.sh +++ b/release.sh @@ -25,3 +25,6 @@ bin/sitespeed.js --version > docs/version/sitespeed.io.txt # Generate the help for the docs bin/sitespeed.js --help > docs/documentation/sitespeed.io/configuration/config.md + +docker build -f Dockerfile.wpr --no-cache -t sitespeedio/sitespeed.io:${PACKAGE_VERSION}-wpr . +docker push sitespeedio/sitespeed.io:${PACKAGE_VERSION}-wpr \ No newline at end of file