Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Go live on agents #664

Merged
merged 47 commits into from
Apr 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
1e28661
Update hosts.txt
stoyan May 5, 2023
92db26f
Dockerfile completed
FedericoMulas Aug 1, 2023
05bcf0e
merged with master (that had the fix)
FedericoMulas Aug 1, 2023
8cebfb8
restored README and moved to docker.md
FedericoMulas Aug 1, 2023
831f053
fixed typo
FedericoMulas Aug 2, 2023
d71e2b4
Apply suggestions from code review
FedericoMulas Aug 2, 2023
bee08d6
ensure that sh files have lf ending even when workin on windows
FedericoMulas Aug 2, 2023
1899be1
Merge branch 'docker-debug' of github.com:FedericoMulas/wptagent into…
FedericoMulas Aug 2, 2023
95a6108
Added docker build timezone example
FedericoMulas Aug 2, 2023
54a05f0
Added rfc5424logging and integrated it into wptagent with the new opt…
FedericoMulas Sep 5, 2023
6ec19a1
Added new requirementes for rfc5424logging to requirements.txt
FedericoMulas Sep 6, 2023
4d42209
Added and changed wptagent new logging transport RotatedFileTransport…
FedericoMulas Sep 6, 2023
3cce3ee
Apply suggestions from code review
FedericoMulas Sep 6, 2023
b29b689
Merge pull request #636 from FedericoMulas/docker-debug
mjkozicki Sep 13, 2023
b3ef321
Merge branch 'master' into rfc5424-logging
FedericoMulas Sep 22, 2023
62e8314
addressed review comment: removed loglevel and added logformat and re…
FedericoMulas Sep 22, 2023
075ca79
Merge pull request #638 from FedericoMulas/rfc5424-logging
mjkozicki Sep 22, 2023
9a73380
Logging fixes
pmeenan Sep 26, 2023
ca301f1
Added pytz
pmeenan Sep 27, 2023
465638a
Merge pull request #640 from HTTPArchive/logging
mjkozicki Sep 27, 2023
1fc2900
Fixed the lighthouse user agent string
pmeenan Oct 10, 2023
acdd3ed
Merge pull request #641 from HTTPArchive/lighthouse
mjkozicki Oct 25, 2023
4ac1576
Merge pull request #615 from catchpoint/stoyan-patch-2
mjkozicki Oct 25, 2023
020b4ec
Improve stability of benchmark-based CPU throttle scaling
pmeenan Nov 8, 2023
704ec25
Use a fast 4G profile when running desktop lighthouse tests
pmeenan Nov 21, 2023
f8dff57
Use 4G desktop config when dtshaper is enabled
pmeenan Nov 21, 2023
f904e55
Fixed devtools throttle speeds
pmeenan Nov 22, 2023
cf370bc
Disabling noisy Edge features
vibaldem Mar 19, 2024
ad42151
Merge pull request #652 from vibaldem/patch-1
mjkozicki Mar 26, 2024
b0abeda
Fixed DNS time processing from the netlog
pmeenan Apr 9, 2024
a5682db
Force selenium version to fix failing firefox tests
lbartoli79 Apr 17, 2024
4536ff0
Merge pull request #653 from HTTPArchive/dns
mjkozicki Apr 17, 2024
0521863
Merge pull request #645 from HTTPArchive/lightrider
mjkozicki Apr 17, 2024
9c0c533
Merge pull request #644 from HTTPArchive/throttle
mjkozicki Apr 17, 2024
7efb2d8
Updated driver_set_pref to work on newer firefox versions
lbartoli79 Apr 18, 2024
2fce1dd
Merge pull request #658 from catchpoint/fix_firefox_set_pref
mjkozicki Apr 18, 2024
9615d2e
Merge branch 'master' of github.com:catchpoint/WebPageTest.agent into…
lbartoli79 Apr 18, 2024
89be4e1
Resolved conflicts
lbartoli79 Apr 18, 2024
6676d42
Added back setup_logging
lbartoli79 Apr 18, 2024
f3a29e4
Removed newline
lbartoli79 Apr 18, 2024
330cc0a
Merge pull request #655 from catchpoint/firefox_fix
claud-io Apr 18, 2024
d2c9b7b
Revert "Fix selenium version"
claud-io Apr 18, 2024
5052c1b
Merge pull request #660 from catchpoint/revert-655-firefox_fix
lbartoli79 Apr 18, 2024
4cc6fa7
Revert "Revert "Fix selenium version""
lbartoli79 Apr 18, 2024
5830f47
Merge pull request #661 from catchpoint/revert-660-revert-655-firefox…
claud-io Apr 18, 2024
2af8dc5
Restore lighthouse fix
lbartoli79 Apr 18, 2024
5ef2c87
Merge pull request #662 from catchpoint/restore_lighthouse_fix
claud-io Apr 18, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1 +1,19 @@
# hidden unused files
.git
.vscode
.gitignore
.travis.yml

# unused folders
docs
test

# unused script and files
README.md
alive.bat
browsers.ini.sample
centos_install.sh
ios_install.sh
ubuntu_install.sh
windows_install.ps1
windows_post_reboot.ps1
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Ensure that linux files have lf endings even when working on windows
*.sh text eol=lf
2 changes: 2 additions & 0 deletions .github/workflows/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,5 @@ brotli
xvfbwrapper
google-cloud-storage
google-cloud-pubsub
pytz
tzlocal
77 changes: 34 additions & 43 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,74 +7,65 @@
### docker run -it -d TAGNAME /bin/bash - Runs bash
### docker exec -it <IMAGE ID> /bin/bash - Connects to bash for terminal execution (Needs to be running first)

### EXAMPLE DOCKER COMMANDS FOR RUNNING SERVER & AGENT

### docker run -d -p 4000:80 <IMAGE ID || <IMAGE TAG>
### docker run -d -p 4001:80 --network="host" -e "SERVER_URL=http://localhost:4000/work/" -e "LOCATION=Test" -e "-v" <IMAGE ID || <IMAGE TAG>

### INSTALLING METHOD ###

### Recommend to install with "docker build <GITHUB-REPO-LINK> -t TAGNAME",
### grabs the latest copy of WPT and build time on average takes 10 minutes.

FROM ubuntu:22.04

### PREVENTs INTERACTIVE PROMPTS WHILE INSTALLING ###
ARG DEBIAN_FRONTEND=noninteractive

### COPYING ENTIRE DIR TO LOCAL DOCKER /wptagent
COPY / /wptagent
RUN apt-get update
FROM ubuntu:22.04 as production

# Git Clone Install
# RUN apt-get install -y git
# RUN git clone -b dockerfile https://github.com/sammeboy635/wptagent.git

RUN curl -sL https://deb.nodesource.com/setup_16.x | bash -
### TIMEZONE INSIDE THE CONTAINER ###
ARG TIMEZONE=UTC

### UPDATE ###
RUN apt-get update
RUN curl -sL https://deb.nodesource.com/setup_16.x | bash -
RUN apt update

### INSTALL APT-GET LIBS ###
RUN apt-get install -y \
# DEBIAN_FRONTEND prevents interactive prompts while installing
# set default timezone beforehand to avoid user interaction for tzdata package
RUN ln -fs /usr/share/zoneinfo/$TIMEZONE /etc/localtime && DEBIAN_FRONTEND=noninteractive apt install -y \
python3 python3-pip python3-ujson \
imagemagick dbus-x11 traceroute software-properties-common psmisc libnss3-tools iproute2 net-tools openvpn \
libtiff5-dev libjpeg-dev zlib1g-dev libfreetype6-dev liblcms2-dev libwebp-dev tcl8.6-dev tk8.6-dev python3-tk \
python3-dev libavutil-dev libmp3lame-dev libx264-dev yasm autoconf automake build-essential libass-dev libfreetype6-dev libtheora-dev \
libtool libvorbis-dev pkg-config texi2html libtext-unidecode-perl python3-numpy python3-scipy perl \
adb ethtool nodejs cmake git-core libsdl2-dev libva-dev libvdpau-dev libxcb1-dev libxcb-shm0-dev libxcb-xfixes0-dev texinfo wget \
ttf-mscorefonts-installer fonts-noto fonts-roboto fonts-open-sans ffmpeg npm
ttf-mscorefonts-installer fonts-noto fonts-roboto fonts-open-sans ffmpeg npm sudo curl xvfb

### Update the font cache
### UPDATE FONT CACHE ###
RUN fc-cache -f -v

### UPGRADING PIP AND INSTALLING REQUIRED PACKAGES ###
RUN python3 -m pip install --upgrade --user pip && \
python3 -m pip install --user -r /wptagent/.github/workflows/requirements.txt

### INSTALLING LIGHTHOUSE FROM NPM ###
RUN npm install -g lighthouse

### INSTALLING CHROME BROWSER ###
### Fails to Find all libs needed to run
# RUN wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb && \
# dpkg -i google-chrome-stable_current_amd64.deb; exit 0 && \
# apt -f install -y && \
# apt-get install google-chrome-stable
RUN curl -o /tmp/google-chrome-stable_current_amd64.deb https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb && \
apt install -y /tmp/google-chrome-stable_current_amd64.deb && rm /tmp/google-chrome-stable_current_amd64.deb

### BETTER INSTALLING CHROME BROWSER METHOD ###
### Better Installing method but would like to change this to something less complex.
RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \
&& echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list
RUN apt-get update && apt-get -y install google-chrome-stable ; exit 0
RUN apt-get update --fix-missing -y
RUN apt-get install -f -y
### UPGRADING PIP AND INSTALLING REQUIRED PACKAGES ###
COPY /.github/workflows/requirements.txt /tmp/agent_requirements.txt
RUN python3 -m pip install --upgrade --user pip && \
python3 -m pip install --user -r /tmp/agent_requirements.txt && \
rm /tmp/agent_requirements.txt

### CLEAN UP ###
# We could add some clean up here but in testing it was negotiable
### COPYING ENTIRE DIR TO LOCAL DOCKER /wptagent ###
# see .dockerignore for filterd out folders
# source copy last so we don't need to rebuild all the other layers
COPY / /wptagent
WORKDIR /wptagent

ENTRYPOINT ["/bin/sh", "/wptagent/docker/linux-headless/entrypoint.sh"]

WORKDIR /wptagent
### DEBUG CONTAINER ###
FROM production as debug

### INSTALLING DEBUG DEPENDENCIES ###
RUN pip install debugpy

### COPY DEBUG AGENT AND MOVE REAL ONE ###
RUN mv wptagent.py wptagent_starter.py
COPY wptagent_debug.py wptagent.py

### /bin/bash LOCATION OF COMMAND EXECUTION ###
CMD ["/bin/bash", "/wptagent/docker/linux-headless/entrypoint.sh"]
### SETTING PRODUCTION BUILD AS DEFAULT ###
FROM production
2 changes: 1 addition & 1 deletion docker/linux-headless/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@ fi

# exec replaces the shell process by the python process and is required to
# propagate signals (i.e. SIGTERM)
exec python3 /wptagent/wptagent.py --server "${SERVER_URL}" --location "${LOCATION}" ${EXTRA_ARGS} --xvfb --dockerized -vvvv
exec python3 /wptagent/wptagent.py --server "${SERVER_URL}" --location "${LOCATION}" ${EXTRA_ARGS} --xvfb --dockerized -vvvv "@"
78 changes: 59 additions & 19 deletions docs/docker.md
Original file line number Diff line number Diff line change
@@ -1,45 +1,85 @@
# Linux Headless Agent
# Docker Linux Headless Agent

To run the agent, simply specify a few environment variables with docker:
The `Dockerfile` has multi-stage definition:
* **production**: Default stage, produce a image without debug features;
* **debug**: When running the produced image the wptagent script will wait for a debugger to.attach

## Build the Image

Arguments can be passed at build time:
* **TIMEZONE**: to set the timezone inside the container. Default `UTC.`

To build the production container with UTC timezone
```bash
docker build --tag wptagent .
```

* `SERVER_URL`: will be passed as `--server` (note: it must end with '/work/')
* `LOCATION`: will be passed as `--location`
* `KEY`: will be passed as `--key`
* `NAME`: will be passed as `--name` (optional)
* `SHAPER`: will be passed as `--shaper` (optional)
* `EXTRA_ARGS`: extra command-line options that will be passed through verbatim (optional)
changing the timezone at build time
```bash
docker build --build-arg TIMEZONE=EST .
```

To build the debug container
```bash
docker build --target debug --tag wptagent-debug .
```

## Prerequisites to use traffic shaping in docker
**Experimental**: Running the agent with traffic shaping is experimental. It might
have influence on the host system network. Running multiple agents on the
same host might result in incorrect traffic shaping.

For traffic shaping to work correctly, you need to load the ifb module on the **host**:

```bash
sudo modprobe ifb numifbs=1
```

Also, the container needs `NET_ADMIN` capabilities, so run the container with
`--cap-add=NET_ADMIN`.

To disable traffic-shaping, pass SHAPER="none".

## Container Disk Space Fills Up Quickly
To disable traffic-shaping, pass environment variable at docker un `SHAPER="none"`.

If you see disk space within the container filling up rapidly and you notice
core dump files in the /wptagent folder, try adding `--shm-size=1g` to your Docker run
command. This can help resolve an issue with shared memory and headless Chrome in Docker.
## Run the container
To run the agent, simply specify a few environment variables with docker:

## Example
- `SERVER_URL`: will be passed as `--server` (note: it must end with '/work/')
- `LOCATION`: will be passed as `--location`
- `KEY`: will be passed as `--key`
- `NAME`: will be passed as `--name` (optional)
- `SHAPER`: will be passed as `--shaper` (optional)
- `EXTRA_ARGS`: extra command-line options that will be passed through verbatim (optional)

Build the image first (from project root), load ifb and start it the container:
Build the image first (from project root), load ifb and start it the container.

sudo docker build --tag wptagent .
A typical run :
```bash
sudo modprobe ifb numifbs=1
sudo docker run -d \
docker build --tag wptagent .
docker run -d \
-e SERVER_URL="http://my-wpt-server.org/work/" \
-e LOCATION="docker-location" \
-e NAME="Docker Test" \
--cap-add=NET_ADMIN \
--init \
wptagent
```

Additional parameters can be also passed as additional commands.
A typical run in debug mode, note that we need to expose the port as `50000`:
```bash
sudo modprobe ifb numifbs=1
docker run -d \
-e SERVER_URL=http://127.0.0.1:80/work/ \
-e LOCATION=Test \
--init \
--cap-add=NET_ADMIN \
-p 50000:50000 \
wptagent-debug
--key 123456789
```

## Container Disk Space Fills Up Quickly

If you see disk space within the container filling up rapidly and you notice
core dump files in the /wptagent folder, try adding `--shm-size=1g` to your Docker run
command. This can help resolve an issue with shared memory and headless Chrome in Docker.
7 changes: 7 additions & 0 deletions internal/chrome_desktop.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,13 @@
'OfflinePagesPrefetching',
'OptimizationHints',
'Translate',
# Disable noisy Edge features
'msAutofillEdgeCoupons',
'msShoppingTrigger',
'msEdgeShoppingUI',
'msEntityExtraction',
'msEntityExtractionProactive',
'msWebAssist',
]

ENABLE_BLINK_FEATURES = [
Expand Down
9 changes: 7 additions & 2 deletions internal/devtools_browser.py
Original file line number Diff line number Diff line change
Expand Up @@ -854,7 +854,12 @@ def run_lighthouse_test(self, task):
else:
cpu_throttle = '{:.3f}'.format(self.job['throttle_cpu']) if 'throttle_cpu' in self.job else '1'
if self.job['dtShaper']:
command.extend(['--throttling-method', 'devtools', '--throttling.requestLatencyMs', '150', '--throttling.downloadThroughputKbps', '1600', '--throttling.uploadThroughputKbps', '768', '--throttling.cpuSlowdownMultiplier', cpu_throttle])
if self.options.android or ('mobile' in self.job and self.job['mobile']):
# 1.6Mbps down, 750Kbps up, 150ms RTT
command.extend(['--throttling-method', 'devtools', '--throttling.requestLatencyMs', '150', '--throttling.downloadThroughputKbps', '1600', '--throttling.uploadThroughputKbps', '750', '--throttling.cpuSlowdownMultiplier', cpu_throttle])
else:
# 10Mbps, 40ms RTT
command.extend(['--throttling-method', 'devtools', '--throttling.requestLatencyMs', '40', '--throttling.downloadThroughputKbps', '10240', '--throttling.uploadThroughputKbps', '10240', '--throttling.cpuSlowdownMultiplier', cpu_throttle])
elif 'throttle_cpu_requested' in self.job and self.job['throttle_cpu_requested'] > 1:
command.extend(['--throttling-method', 'devtools', '--throttling.requestLatencyMs', '0', '--throttling.downloadThroughputKbps', '0', '--throttling.uploadThroughputKbps', '0', '--throttling.cpuSlowdownMultiplier', cpu_throttle])
else:
Expand All @@ -874,7 +879,7 @@ def run_lighthouse_test(self, task):
command.extend(['--screenEmulation.disabled'])
if 'user_agent_string' in self.job:
sanitized_user_agent = re.sub(r'[^a-zA-Z0-9_\-.;:/()\[\] ]+', '', self.job['user_agent_string'])
command.append('--chrome-flags="--user-agent=\'{0}\'"'.format(sanitized_user_agent))
command.extend(['--emulatedUserAgent', "'" + sanitized_user_agent + "'"])
if len(task['block']):
for pattern in task['block']:
pattern = "'" + pattern.replace("'", "'\\''") + "'"
Expand Down
16 changes: 4 additions & 12 deletions internal/firefox.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,20 +261,12 @@ def driver_set_pref(self, key, value):
"""Set a Firefox pref at runtime"""
if self.driver is not None:
try:
script = 'const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");'
script += 'Services.prefs.'
if isinstance(value, bool):
script += 'setBoolPref'
elif isinstance(value, (str, unicode)):
script += 'setStringPref'
else:
script += 'setIntPref'
script += '({0}, {1});'.format(json.dumps(key), json.dumps(value))
logging.debug(script)
script = 'const { Preferences } = ChromeUtils.importESModule("resource://gre/modules/Preferences.sys.mjs");'
script += f'Preferences.set({json.dumps(key)}, {json.dumps(value)});'
self.driver.set_context(self.driver.CONTEXT_CHROME)
self.driver.execute_script(script)
except Exception:
logging.exception("Error setting pref")
except Exception as err:
logging.exception("Error setting pref %s => %s: %s", key, value, err)
finally:
self.driver.set_context(self.driver.CONTEXT_CONTENT)

Expand Down
10 changes: 10 additions & 0 deletions internal/rfc5424logging/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
"""
This library offers an logging in rfc5424 format.

Is based on https://github.com/jobec/rfc5424-logging-handler that is not currently maintained.

A few changes needed to be implemented anyway to tailor the logging to wptagent, hence the hard copy.
"""

from .handler import Rfc5424SysLogHandler
from .rfc5424logging_context import logging_context
Loading
Loading