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

Load Generator #5

Merged
merged 9 commits into from
Oct 21, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
docker/wordpress/ephemeral/
docker/wordpress/data/ext
Binary file added docker/.DS_Store
Binary file not shown.
11 changes: 11 additions & 0 deletions docker/wordpress/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
IP=127.0.0.1

# mysql
DB_ROOT_PASSWORD=bKDYgDdJ9A67yZs8
DB_NAME=wp_test

# wordpress
WP_IMAGE_VERSION=php7.3-fpm-alpine

# nginx
# NGINX_VERSION=
13 changes: 13 additions & 0 deletions docker/wordpress/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Load Testing with Wordpress

Simulate real load on a wordpress site, while randomly throwing errors in the wp app.

See: http://127.0.0.1:8000/info.php

## Configuration
Please go to `./data/elasticapm.ini` and add the correct values to point to the APM server (e.g.).

## Run the Simulator
```
docker-compose up
```
14 changes: 14 additions & 0 deletions docker/wordpress/data/elasticapm.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
; configuration for Elastic APM agent
extension = elasticapm.so

; Enable the agent to collect
elasticapm.enable = 0

; APM Server
elasticapm.host = http://localhost:8200

; Secret Token for APM Server auth
elasticapm.secret_token =

; Name for APM UI
elasticapm.service_name = "wordpress-test"
409 changes: 409 additions & 0 deletions docker/wordpress/data/mysql-dump/wp_test.sql

Large diffs are not rendered by default.

24 changes: 24 additions & 0 deletions docker/wordpress/data/nginx/conf.d/default.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
server {
listen 8000;
server_name 127.0.0.1;

root /var/www/html;
index index.php;

access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;

location / {
try_files $uri $uri/ /index.php?$args;
}

location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass wordpress:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
1 change: 1 addition & 0 deletions docker/wordpress/data/pinger/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
requests==2.22.0
15 changes: 15 additions & 0 deletions docker/wordpress/data/pinger/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/sh

echo "starting load generating in 30 seconds .."
sleep 10
echo "> starting load generating in 20 seconds .."
sleep 10
echo "> starting load generating in 10 seconds .."
sleep 7
echo "> starting load generating in 3 seconds .."
sleep 1
echo "> in 2 seconds .."
sleep 1
echo "> in 1 second .."
sleep 1
/usr/local/bin/python /app/runner.py
69 changes: 69 additions & 0 deletions docker/wordpress/data/pinger/runner.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#!/usr/bin/python

import sys
import requests
import random
import logging
import time

from queue import Queue
from threading import Thread

root = logging.getLogger()
root.setLevel(logging.DEBUG)

handler = logging.StreamHandler(sys.stdout)
handler.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
root.addHandler(handler)

_timeout = 0.50
_n_threads = 4
if len(sys.argv) == 2:
_n_threads = int(sys.argv[1])

endpoints = [
'http://nginx:8000/',
'http://nginx:8000/?page_id=2',
'http://nginx:8000/?page_id=16',
'http://nginx:8000/?p=6',
'http://nginx:8000/?p=8',
'http://nginx:8000/?p=10#comments',
'http://nginx:8000/?p=12',
'http://nginx:8000/?p=14',
'http://nginx:8000/?author=1',
'http://nginx:8000/?cat=1',
]

def do_request(q, wid):
while True:
if q.empty() == False:
url = q.get()
headers = {'content-type': 'application/json', 'Accept-Charset': 'UTF-8'}

# Add randomly a dist. tracing header
if random.randint(0, 10) == wid:
a = random.randint(1000, 9999)
b = random.randint(1000, 9999)
headers['elastic-apm-traceparent'] = "00-%da6be83a31fb66a455cbb74ab%d-%dfae6bd7c%d-01" % (a, b, b, a)

# Do Request
r = requests.get(url, headers=headers)
logging.info("[%d] worker %d - %s" % (r.status_code, wid, url))

time.sleep(_timeout)

if __name__ == '__main__':
q = Queue()

for i in range(_n_threads):
worker = Thread(target=do_request, args=(q, i))
worker.setDaemon(True)
worker.start()

while True:
url = random.choice(endpoints)
q.put(url)

q.join()
9 changes: 9 additions & 0 deletions docker/wordpress/data/wordpress/install-ext.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/sh

cd /var/elasticapm

phpize
./configure --enable-elasticapm
make clean
make
make install
3 changes: 3 additions & 0 deletions docker/wordpress/data/wordpress/php/fatal.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<?php

$fatal = 1 / 0;
111 changes: 111 additions & 0 deletions docker/wordpress/data/wordpress/php/wp-config.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
<?php
// agent testing ..
/**
* The base configuration for WordPress
*
* The wp-config.php creation script uses this file during the
* installation. You don't have to use the web site, you can
* copy this file to "wp-config.php" and fill in the values.
*
* This file contains the following configurations:
*
* * MySQL settings
* * Secret keys
* * Database table prefix
* * ABSPATH
*
* @link https://codex.wordpress.org/Editing_wp-config.php
*
* @package WordPress
*/

// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define( 'DB_NAME', 'wp_test');

/** MySQL database username */
define( 'DB_USER', 'root');

/** MySQL database password */
define( 'DB_PASSWORD', 'bKDYgDdJ9A67yZs8');

/** MySQL hostname */
define( 'DB_HOST', 'db:3306');

/** Database Charset to use in creating database tables. */
define( 'DB_CHARSET', 'utf8');

/** The Database Collate type. Don't change this if in doubt. */
define( 'DB_COLLATE', '');

/**#@+
* Authentication Unique Keys and Salts.
*
* Change these to different unique phrases!
* You can generate these using the {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org secret-key service}
* You can change these at any point in time to invalidate all existing cookies. This will force all users to have to log in again.
*
* @since 2.6.0
*/
define( 'AUTH_KEY', 'b21ce659a9b0b45a0a51a16b9bd5850ed8f549a0');
define( 'SECURE_AUTH_KEY', 'd1d64b11960845e1f97317e82829f304a4dd9c44');
define( 'LOGGED_IN_KEY', '622b029b7e6290b8dfa38a07cd646126887aad55');
define( 'NONCE_KEY', '30fb269e23e2a45cdd4755342a065de87b1b5ee1');
define( 'AUTH_SALT', '1ab0ff081770ca4c433a47846152673eb076efa3');
define( 'SECURE_AUTH_SALT', '480566c90374db54ea424cc1119152e4e9320632');
define( 'LOGGED_IN_SALT', '93ae0d32c94fa9b3ed45e2c4c67abb313faa5f55');
define( 'NONCE_SALT', '7ec4a3dfbe9324f617cdc6671e56794bb5085419');

/**#@-*/

/**
* WordPress Database Table prefix.
*
* You can have multiple installations in one database if you give each
* a unique prefix. Only numbers, letters, and underscores please!
*/
$table_prefix = 'wp_';

/**
* For developers: WordPress debugging mode.
*
* Change this to true to enable the display of notices during development.
* It is strongly recommended that plugin and theme developers use WP_DEBUG
* in their development environments.
*
* For information on other constants that can be used for debugging,
* visit the Codex.
*
* @link https://codex.wordpress.org/Debugging_in_WordPress
*/
define( 'WP_DEBUG', false );

// If we're behind a proxy server and using HTTPS, we need to alert Wordpress of that fact
// see also http://codex.wordpress.org/Administration_Over_SSL#Using_a_Reverse_Proxy
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
$_SERVER['HTTPS'] = 'on';
}

/* That's all, stop editing! Happy publishing. */

/** Absolute path to the WordPress directory. */
if ( ! defined( 'ABSPATH' ) ) {
define( 'ABSPATH', dirname( __FILE__ ) . '/' );
}

//
// Simple "Chaos monkey" to introduce random errors
//
if(rand(1, 5) == rand(1, 5)) {
throw new Exception("Random Error by Chaos Monkey.");
}

//
// Throw a FATAL PHP Error @ 1% likelyhood
//
if(rand(1, 10) == rand(1, 10)) {
require_once( ABSPATH . 'fatal.php' );
}

/** Sets up WordPress vars and included files. */
require_once( ABSPATH . 'wp-settings.php' );
65 changes: 65 additions & 0 deletions docker/wordpress/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
version: '3'

services:
wp:
container_name: wordpress
build:
dockerfile: ${PWD}/dockerfiles/wordpress/Dockerfile
context: ${PWD}
volumes:
- wp_app:/var/www/html
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_NAME: "${DB_NAME}"
WORDPRESS_DB_USER: root
WORDPRESS_DB_PASSWORD: "${DB_ROOT_PASSWORD}"
depends_on:
- db
links:
- db
restart: always

db:
image: mysql:5.7
container_name: mysql_57
ports:
- ${IP}:3306:3306
command: [
'--default_authentication_plugin=mysql_native_password',
'--character-set-server=utf8mb4',
'--collation-server=utf8mb4_unicode_ci'
]
volumes:
- ${PWD}/data/mysql-dump:/docker-entrypoint-initdb.d
- db_data:/var/lib/mysql
environment:
MYSQL_DATABASE: "${DB_NAME}"
MYSQL_ROOT_PASSWORD: "${DB_ROOT_PASSWORD}"
restart: always

nginx:
image: nginx:${NGINX_VERSION:-latest}
container_name: nginx
ports:
- '8000:8000'
volumes:
- ${PWD}/data/nginx/conf.d/:/etc/nginx/conf.d
- wp_app:/var/www/html
# - ${PWD}/ephemeral/logs/nginx:/var/log/nginx
depends_on:
- wp
restart: always

pinger:
container_name: pinger
build:
dockerfile: ${PWD}/dockerfiles/pinger/Dockerfile
context: ${PWD}
tty: true
depends_on:
- nginx
command: ['/app/run.sh']

volumes:
db_data: {}
wp_app: {}
13 changes: 13 additions & 0 deletions docker/wordpress/dockerfiles/pinger/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
FROM python:3.7.2-alpine3.9

RUN apk update
RUN apk add curl

WORKDIR /app

COPY ./data/pinger /app
RUN pip install --upgrade pip
RUN pip install -r requirements.txt
RUN chmod +x runner.py

ENTRYPOINT [ "/bin/sh" ]
12 changes: 12 additions & 0 deletions docker/wordpress/dockerfiles/wordpress/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
FROM wordpress:php7.3-fpm-alpine

COPY ./data/wordpress/php/. /var/www/html/.
RUN echo "<?php phpinfo();" > /var/www/html/info.php

# Compile the ext
RUN apk add build-base autoconf curl-dev
COPY ./data/elasticapm.ini /usr/local/etc/php/conf.d/elasticapm.ini
COPY ./data/ext /var/elasticapm
COPY ./data/wordpress/install-ext.sh /var/elasticapm/install-ext.sh
RUN chmod +x /var/elasticapm/install-ext.sh
RUN /var/elasticapm/install-ext.sh