SlideShare a Scribd company logo
Load Testingwith Jason Lotito
“Guaranteed to be the best talk on load testing
with PHP @ MidwestPHP 2016 during that time
slot in that room with me as the speaker"
Jason Lotito
• DevOps Lead Architect
• MeetMe.com
• @jasonlotito
• jasonlotito.com
• jlotito@meetme.com
Lorem Ipsum Dolor
meetme.com/apps/careers
Load Testing
Not Unit Testing, Integration Testing, Acceptance
Testings, manual Testing, or Standardized Testing
Jason Lotito
Load test, or your users will do it for you.
Load test, or your users will do it for you.
Your Servers
Load test, or your users will do it for you.
And if they do, you won’t have any users.
You can use load testing to practice
dealing with lots of requests
What is Load Testing?
Load Testing
• Putting demand on a system
• Determine behavior under
load
• Determine maximum operating
capacity
• Discover Bottlenecks
• Determining steps to increase
operating capacity
• Optimize for costs
Other Load Testing Tools
• ApacheBench (ab)
• Apache JMeter
• siege
• BlazeMeter
• and many more…
The Basics of Load Testing
The Basics of Load Testing
Why RedLine13?
• Simple, up and running in little time
• Freemium, free level you only pay AWS
• Scriptable (PHP, Node.js)
• AWS for Infinite Scalability™
• I know Rich, one of the founders
RedLine13 has a bunch of features you can read
about on the website. I’m really here to talk to
you about the cool stuff I do with RedLine13.
Let’s walk through a
Custom Load Test
CustomTest.php
The class that actually runs the test.
In our example, we’ll use sleep to
simulate performing actions such as
making HTTP requests to an API
<?php



require_once( 'LoadTestingTest.class.php' );



class CustomTest extends LoadTestingTest

{

public function startTest()

{

for ( $x = 1; $x <= 100; $x++ )

{

$startTime = microtime(true);

sleep( mt_rand( 2, 5 ) );

$diff = microtime( true ) - $startTime;

recordPageTime( $startTime, $diff );

recordURLPageLoad( $x, $startTime, $diff );

}



return true;

}

}
CustomTest.php
This is
where your
code goes
<?php



require_once( 'LoadTestingTest.class.php' );



class CustomTest extends LoadTestingTest

{

public function startTest()

{

for ( $x = 1; $x <= 100; $x++ )

{

$startTime = microtime(true);

sleep( mt_rand( 2, 5 ) );

$diff = microtime( true ) - $startTime;

recordPageTime( $startTime, $diff );

recordURLPageLoad( $x, $startTime, $diff );

}



return true;

}

}
CustomTest.php
<?php



require_once( 'LoadTestingTest.class.php' );



class CustomTest extends LoadTestingTest

{

public function startTest()

{

for ( $x = 1; $x <= 100; $x++ )

{

$startTime = microtime(true);

sleep( mt_rand( 2, 5 ) );

$diff = microtime( true ) - $startTime;

recordPageTime( $startTime, $diff );

recordURLPageLoad( $x, $startTime, $diff );

}



return true;

}

}
CustomTest.php
<?php



require_once( 'LoadTestingTest.class.php' );



class CustomTest extends LoadTestingTest

{

public function startTest()

{

for ( $x = 1; $x <= 100; $x++ )

{

$startTime = microtime(true);

sleep( mt_rand( 2, 5 ) );

$diff = microtime( true ) - $startTime;

recordPageTime( $startTime, $diff );

recordURLPageLoad( $x, $startTime, $diff );

}



return true;

}

}
CustomTest.php
<?php



require_once( 'LoadTestingTest.class.php' );



class CustomTest extends LoadTestingTest

{

public function startTest()

{

for ( $x = 1; $x <= 100; $x++ )

{

$startTime = microtime(true);

sleep( mt_rand( 2, 5 ) );

$diff = microtime( true ) - $startTime;

recordPageTime( $startTime, $diff );

recordURLPageLoad( $x, $startTime, $diff );

}



return true;

}

}
CustomTest.php
<?php



require_once( 'LoadTestingTest.class.php' );



class CustomTest extends LoadTestingTest

{

public function startTest()

{

for ( $x = 1; $x <= 100; $x++ )

{

$startTime = microtime(true);

sleep( mt_rand( 2, 5 ) );

$diff = microtime( true ) - $startTime;

recordPageTime( $startTime, $diff );

recordURLPageLoad( $x, $startTime, $diff );

}



return true;

}

}
CustomTest.php
<?php



require_once( 'LoadTestingTest.class.php' );



class CustomTest extends LoadTestingTest

{

public function startTest()

{

for ( $x = 1; $x <= 100; $x++ )

{

$startTime = microtime(true);

sleep( mt_rand( 2, 5 ) );

$diff = microtime( true ) - $startTime;

recordPageTime( $startTime, $diff );

recordURLPageLoad( $x, $startTime, $diff );

}



return true;

}

}
CustomTest.php
Start Time
Start/End Time
Difference
<?php



require_once( 'LoadTestingTest.class.php' );



class CustomTest extends LoadTestingTest

{

public function startTest()

{

for ( $x = 1; $x <= 100; $x++ )

{

$startTime = microtime(true);

sleep( mt_rand( 2, 5 ) );

$diff = microtime( true ) - $startTime;

recordPageTime( $startTime, $diff );

recordURLPageLoad( $x, $startTime, $diff );

}



return true;

}

}
CustomTest.php
URL/String
These next two files
help us test locally
redline.php
Mock Redline functions to
test load test locally
<?php

/**

* @return bool

*/

function isRedlineVerbose()

{

return (int) getenv( 'REDLINE_VERBOSE' ) === 1;

}



/**

* @param int $timestamp

* @param int $elapsedTime

*/

function recordPageTime( $timestamp, $elapsedTime )

{

isRedlineVerbose() && output( "Record Page Time: timestamp
$timestamp; elapsed time: $elapsedTime" );

}



/**

redline.php
<?php

/**

* @return bool

*/

function isRedlineVerbose()

{

return (int) getenv( 'REDLINE_VERBOSE' ) === 1;

}



/**

* @param int $timestamp

* @param int $elapsedTime

*/

function recordPageTime( $timestamp, $elapsedTime )

{

isRedlineVerbose() && output( "Record Page Time: timestamp
$timestamp; elapsed time: $elapsedTime" );

}



/**

redline.php
<?php

/**

* @return bool

*/

function isRedlineVerbose()

{

return (int) getenv( 'REDLINE_VERBOSE' ) === 1;

}



/**

* @param int $timestamp

* @param int $elapsedTime

*/

function recordPageTime( $timestamp, $elapsedTime )

{

isRedlineVerbose() && output( "Record Page Time: timestamp
$timestamp; elapsed time: $elapsedTime" );

}



/**

* @param string $url

* @param int $timestamp

* @param int $elapsedTime

*/

function recordURLPageLoad( $url, $timestamp, $elapsedTime )

{

output( "$url -> $elapsedTime seconds" );

}

redline.php
* @param int $elapsedTime

*/

function recordPageTime( $timestamp, $elapsedTime )

{

isRedlineVerbose() && output( "Record Page Time: timestamp
$timestamp; elapsed time: $elapsedTime" );

}



/**

* @param string $url

* @param int $timestamp

* @param int $elapsedTime

*/

function recordURLPageLoad( $url, $timestamp, $elapsedTime )

{

output( "$url -> $elapsedTime seconds" );

}



/**

* @param int $kilobytes

*/

function recordDownloadSize( $kilobytes )

{

isRedlineVerbose() && output( sprintf( "Download Size: %dkb",
$kilobytes ) );

}



redline.php
* @param string $url

* @param int $timestamp

* @param int $elapsedTime

*/

function recordURLPageLoad( $url, $timestamp, $elapsedTime )

{

output( "$url -> $elapsedTime seconds" );

}



/**

* @param int $kilobytes

*/

function recordDownloadSize( $kilobytes )

{

isRedlineVerbose() && output( sprintf( "Download Size: %dkb",
$kilobytes ) );

}



/**

* @param string $error

*/

function recordError( $error )

{

output( "Error: $error" );

}



/**

* @param string $msg

redline.php
/**

* @param int $kilobytes

*/

function recordDownloadSize( $kilobytes )

{

isRedlineVerbose() && output( sprintf( "Download Size: %dkb",
$kilobytes ) );

}



/**

* @param string $error

*/

function recordError( $error )

{

output( "Error: $error" );

}



/**

* @param string $msg

* @return bool

*/

function output( $msg )

{

echo sprintf( "[%s] %s]n", getmypid(), $msg );



return true;

}
redline.php
}



/**

* @param string $error

*/

function recordError( $error )

{

output( "Error: $error" );

}



/**

* @param string $msg

* @return bool

*/

function output( $msg )

{

echo sprintf( "[%s] %s]n", getmypid(), $msg );



return true;

}
redline.php
run.php
The script we create to
test CustomTest.php locally
<?php

require_once('redline.php');

require_once('CustomTest.php');



$customTest = new CustomTest(1, mt_rand(1000000,9999999));

$customTest->startTest();
run.php
<?php

require_once('redline.php');

require_once('CustomTest.php');



$customTest = new CustomTest(1, mt_rand(1000000,9999999));

$customTest->startTest();
run.php
<?php

require_once('redline.php');

require_once('CustomTest.php');



$customTest = new CustomTest(1, mt_rand(1000000,9999999));

$customTest->startTest();
run.php
<?php

require_once('redline.php');

require_once('CustomTest.php');



$customTest = new CustomTest(1, mt_rand(1000000,9999999));

$customTest->startTest();
run.php
Instance
Number
<?php

require_once('redline.php');

require_once('CustomTest.php');



$customTest = new CustomTest(1, mt_rand(1000000,9999999));

$customTest->startTest();
run.php
User
Number
Random
Number
What does a result look like?
You can use error reporting to
simulate real time logging
Errors show up in real time, logs show up after
the test is completed. Use error reports to let you
know if you should stop your load test.
Sample App: Chat Service
Sample App: Chat Service
• 1-on-1 Chat
• Group Chat
• Browse Chat Rooms
• Search for Chat Room Topics
Why split 1-on-1 and group
chat into separate tests?
Multiple tests can be run at
the same time.
1-on-1
Group
30-40%
60-70%
30-40%
60-70% 60-70%
30-40%
Time
Start at the
same time
Increase
group chat %
Could mean just more group chat or
both more group and less 1-on-1
Revert to
normal ratio
20:00 40:000:00
1-on-1
Group
30-40%
60-70%
30-40%
60-70% 60-70%
30-40%
Time
Could be done in your
script or in RedLine13
How?
• Start 4 tests:
• For both group and 1-on-1:
• 350 users
• 300 users
1-on-1
Group
350
350+300
350
350+300 350
350
Time
300 test sleeps
for 20 minutes
After 20 minutes,
it stops.
Or, instead of timers,
just do it manually.
Usually the easiest on the day of.
The point is, you can adjust
your load test as needed.
Performing Load Tests
Things You Need
• Production-level systems to test against
• Monitoring
• Automated systems to deploy changes
• Dedicated people
• A time to test (load testing day!)
Things You Need
• Goals, such as
• 500 requests per second
• 90th percentile @ 50ms
Planning the Load Test
• Start at what you expect normal traffic to be
• 500rps
• Start a second test that is just the burst traffic
• 900rps
• Ramps up over 20 mins
• Lasts 40 mins at peak
• Ramps down over 20 mins
Learning
• Is proper monitoring setup?
• Is a scaling plan in place? Can you scale?
• What happens to the app under load?
• What slows down first?
• Are things alerting as expected?
As Load Tester, you are responsible for…
• Ensuring those involved with the system under test are
aware and available
• Putting the system under test under load
• Completely destroying the system under load
• Providing a clear and concise write up of exactly what
occurred
• Take charge! It’s fun!
Reporting
Reporting Results: Shortest Version
• 99% @ 59ms
Reporting Results: Short Version
• Short version: During an hour starting with 0rps to 1400 rps
in the first 10 minutes....
• ...when starting with 5 instances and scaling to 11
instances, the response times were: 50% 23ms, 75% 54ms,
95% 303ms, and 99% 1069ms.
• ...when starting with 11 instances, the response times
were: 50% 16ms, 75% 24ms, 95% 45ms, and 99% 59ms.
Reporting Results: Detailed Version
• Provide more information
• Results
• Story driven
• Have data supporting results prepared in case
• Account for changes such as auto-scaling
• With auto-scaling: 99% at 1069ms
• Without auto-scaling: 99% at 59ms
Testing elasticsearch on c3.4xlarge
Detailed Reporting
Also included in this report
was a link to the actual
GitHub repository. Make sure
you are keeping your load
tests in version control!
Tag your load test in git
Associate the tag with a Load Test,
so you can replay any load test easily
Lessons Learned
Things to Keep In Mind
• Understand expected usage
• X% of users using the app while
• Y% are chatting with one another
• Users are logging in
• Creating accounts
• Backend systems
• Determine what’s important
Things to Keep In Mind
• User input
• Random filters
• Weighted filters
• Cached results are expected
• Client constraints
Things to Keep In Mind
• User flow through service
• Try to understand how users use the app
• Script should try to mimic
Things to Keep In Mind
• Be careful about testing a single system
• System will have logging
• System will have backend services
• You’d be surprised what can cause failure
• A load test helps you learn before it’s in production
Things to Keep In Mind
• User interaction
• MeetMe is social, so we’ve load tested chatting
• 1 test per 2 users, both chatting with one another
Things to Keep In Mind
• Have developers available
• Better, have developers with you when load testing
Things to Keep In Mind
• Find a problem, Fix it, Reroll app, Rerun test
• FFRR, or F2R2
• I just made that up
• Don’t use it.
Things to Keep In Mind
• Start testing from your laptop
• Seriously, my MacBook Air could bring down Erlang
services
• Database indexes are a thing
• While running a load test, you can run a single client form
your laptop
Things to Keep In Mind
• Someone should be testing the app/service as well
• Response times are only a number
• What does 50ms vs 300ms response times feel to the user
• What impact does 2x/3x/4x load have
• When auto-scaling, how does the client handle
Things to Keep In Mind
• Review how the client is using the API
• Review how the API developer expects the client to use the
API
• Model after what the client is doing
• Call out differences early
Learn
Most importantly…
Thanks!
• @jasonlotito
• jasonlotito.com
• jlotito@meetme.com
• https://joind.in/talk/80910

More Related Content

What's hot

Asynchronous programming done right - Node.js
Asynchronous programming done right - Node.jsAsynchronous programming done right - Node.js
Asynchronous programming done right - Node.jsPiotr Pelczar
 
Unit Testing Express Middleware
Unit Testing Express MiddlewareUnit Testing Express Middleware
Unit Testing Express MiddlewareMorris Singer
 
Stress test your backend with Gatling
Stress test your backend with GatlingStress test your backend with Gatling
Stress test your backend with GatlingAndrzej Ludwikowski
 
Java profiling Do It Yourself
Java profiling Do It YourselfJava profiling Do It Yourself
Java profiling Do It Yourselfaragozin
 
Performance tests with Gatling (extended)
Performance tests with Gatling (extended)Performance tests with Gatling (extended)
Performance tests with Gatling (extended)Andrzej Ludwikowski
 
node.js practical guide to serverside javascript
node.js practical guide to serverside javascriptnode.js practical guide to serverside javascript
node.js practical guide to serverside javascriptEldar Djafarov
 
Test driven development with react
Test driven development with reactTest driven development with react
Test driven development with reactLeon Bezuidenhout
 
Java black box profiling JUG.EKB 2016
Java black box profiling JUG.EKB 2016Java black box profiling JUG.EKB 2016
Java black box profiling JUG.EKB 2016aragozin
 
Understanding Asynchronous JavaScript
Understanding Asynchronous JavaScriptUnderstanding Asynchronous JavaScript
Understanding Asynchronous JavaScriptjnewmanux
 
Real Time Event Dispatcher
Real Time Event DispatcherReal Time Event Dispatcher
Real Time Event DispatcherPeter Dietrich
 
Using Node.js to Build Great Streaming Services - HTML5 Dev Conf
Using Node.js to  Build Great  Streaming Services - HTML5 Dev ConfUsing Node.js to  Build Great  Streaming Services - HTML5 Dev Conf
Using Node.js to Build Great Streaming Services - HTML5 Dev ConfTom Croucher
 
Virtualizing Java in Java (jug.ru)
Virtualizing Java in Java (jug.ru)Virtualizing Java in Java (jug.ru)
Virtualizing Java in Java (jug.ru)aragozin
 
Monitoring patterns for mitigating technical risk
Monitoring patterns for  mitigating technical riskMonitoring patterns for  mitigating technical risk
Monitoring patterns for mitigating technical riskItai Frenkel
 
Painless JavaScript Testing with Jest
Painless JavaScript Testing with JestPainless JavaScript Testing with Jest
Painless JavaScript Testing with JestMichał Pierzchała
 
Jan Stępień - GraalVM: Fast, Polyglot, Native - Codemotion Berlin 2018
Jan Stępień - GraalVM: Fast, Polyglot, Native - Codemotion Berlin 2018Jan Stępień - GraalVM: Fast, Polyglot, Native - Codemotion Berlin 2018
Jan Stępień - GraalVM: Fast, Polyglot, Native - Codemotion Berlin 2018Codemotion
 
Binary Studio Academy: Concurrency in C# 5.0
Binary Studio Academy: Concurrency in C# 5.0Binary Studio Academy: Concurrency in C# 5.0
Binary Studio Academy: Concurrency in C# 5.0Binary Studio
 

What's hot (20)

Asynchronous programming done right - Node.js
Asynchronous programming done right - Node.jsAsynchronous programming done right - Node.js
Asynchronous programming done right - Node.js
 
Unit Testing Express Middleware
Unit Testing Express MiddlewareUnit Testing Express Middleware
Unit Testing Express Middleware
 
Stress test your backend with Gatling
Stress test your backend with GatlingStress test your backend with Gatling
Stress test your backend with Gatling
 
Java profiling Do It Yourself
Java profiling Do It YourselfJava profiling Do It Yourself
Java profiling Do It Yourself
 
Performance tests with Gatling (extended)
Performance tests with Gatling (extended)Performance tests with Gatling (extended)
Performance tests with Gatling (extended)
 
Full Stack Unit Testing
Full Stack Unit TestingFull Stack Unit Testing
Full Stack Unit Testing
 
node.js practical guide to serverside javascript
node.js practical guide to serverside javascriptnode.js practical guide to serverside javascript
node.js practical guide to serverside javascript
 
Performance tests with Gatling
Performance tests with GatlingPerformance tests with Gatling
Performance tests with Gatling
 
Test driven development with react
Test driven development with reactTest driven development with react
Test driven development with react
 
Tdd iPhone For Dummies
Tdd iPhone For DummiesTdd iPhone For Dummies
Tdd iPhone For Dummies
 
Java black box profiling JUG.EKB 2016
Java black box profiling JUG.EKB 2016Java black box profiling JUG.EKB 2016
Java black box profiling JUG.EKB 2016
 
Understanding Asynchronous JavaScript
Understanding Asynchronous JavaScriptUnderstanding Asynchronous JavaScript
Understanding Asynchronous JavaScript
 
Android dev 3
Android dev 3Android dev 3
Android dev 3
 
Real Time Event Dispatcher
Real Time Event DispatcherReal Time Event Dispatcher
Real Time Event Dispatcher
 
Using Node.js to Build Great Streaming Services - HTML5 Dev Conf
Using Node.js to  Build Great  Streaming Services - HTML5 Dev ConfUsing Node.js to  Build Great  Streaming Services - HTML5 Dev Conf
Using Node.js to Build Great Streaming Services - HTML5 Dev Conf
 
Virtualizing Java in Java (jug.ru)
Virtualizing Java in Java (jug.ru)Virtualizing Java in Java (jug.ru)
Virtualizing Java in Java (jug.ru)
 
Monitoring patterns for mitigating technical risk
Monitoring patterns for  mitigating technical riskMonitoring patterns for  mitigating technical risk
Monitoring patterns for mitigating technical risk
 
Painless JavaScript Testing with Jest
Painless JavaScript Testing with JestPainless JavaScript Testing with Jest
Painless JavaScript Testing with Jest
 
Jan Stępień - GraalVM: Fast, Polyglot, Native - Codemotion Berlin 2018
Jan Stępień - GraalVM: Fast, Polyglot, Native - Codemotion Berlin 2018Jan Stępień - GraalVM: Fast, Polyglot, Native - Codemotion Berlin 2018
Jan Stępień - GraalVM: Fast, Polyglot, Native - Codemotion Berlin 2018
 
Binary Studio Academy: Concurrency in C# 5.0
Binary Studio Academy: Concurrency in C# 5.0Binary Studio Academy: Concurrency in C# 5.0
Binary Studio Academy: Concurrency in C# 5.0
 

Viewers also liked

How we killed our process, technology stack, and assumptions – and survived
How we killed our process, technology stack, and assumptions – and survivedHow we killed our process, technology stack, and assumptions – and survived
How we killed our process, technology stack, and assumptions – and survivedJason Lotito
 
Twitter Bootstrap, or why being a PHP Developer is a bad idea
Twitter Bootstrap, or why being a PHP Developer is a bad ideaTwitter Bootstrap, or why being a PHP Developer is a bad idea
Twitter Bootstrap, or why being a PHP Developer is a bad ideaJason Lotito
 
A Presentation on Presenting
A Presentation on PresentingA Presentation on Presenting
A Presentation on PresentingJason Lotito
 
Social Media and ADHD – Turning Distractions Into Directions
Social Media and ADHD – Turning Distractions Into DirectionsSocial Media and ADHD – Turning Distractions Into Directions
Social Media and ADHD – Turning Distractions Into DirectionsGrant Crowell
 
Getting Things Done - Tips from someone with ADHD and OCD
Getting Things Done - Tips from someone with ADHD and OCDGetting Things Done - Tips from someone with ADHD and OCD
Getting Things Done - Tips from someone with ADHD and OCDJason Lotito
 
Performance and load testing
Performance and load testingPerformance and load testing
Performance and load testingsonukalpana
 

Viewers also liked (12)

Open source load testing
Open source load testingOpen source load testing
Open source load testing
 
tmux
tmuxtmux
tmux
 
Requirejs
RequirejsRequirejs
Requirejs
 
How we killed our process, technology stack, and assumptions – and survived
How we killed our process, technology stack, and assumptions – and survivedHow we killed our process, technology stack, and assumptions – and survived
How we killed our process, technology stack, and assumptions – and survived
 
Twitter Bootstrap, or why being a PHP Developer is a bad idea
Twitter Bootstrap, or why being a PHP Developer is a bad ideaTwitter Bootstrap, or why being a PHP Developer is a bad idea
Twitter Bootstrap, or why being a PHP Developer is a bad idea
 
Tmux
TmuxTmux
Tmux
 
A Presentation on Presenting
A Presentation on PresentingA Presentation on Presenting
A Presentation on Presenting
 
ADHD in Adults
ADHD in AdultsADHD in Adults
ADHD in Adults
 
SSH
SSHSSH
SSH
 
Social Media and ADHD – Turning Distractions Into Directions
Social Media and ADHD – Turning Distractions Into DirectionsSocial Media and ADHD – Turning Distractions Into Directions
Social Media and ADHD – Turning Distractions Into Directions
 
Getting Things Done - Tips from someone with ADHD and OCD
Getting Things Done - Tips from someone with ADHD and OCDGetting Things Done - Tips from someone with ADHD and OCD
Getting Things Done - Tips from someone with ADHD and OCD
 
Performance and load testing
Performance and load testingPerformance and load testing
Performance and load testing
 

Similar to Load Testing with PHP and RedLine13

Building Testable PHP Applications
Building Testable PHP ApplicationsBuilding Testable PHP Applications
Building Testable PHP Applicationschartjes
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11Michelangelo van Dam
 
Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Michelangelo van Dam
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxMichelangelo van Dam
 
Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Michelangelo van Dam
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐいHisateru Tanaka
 
Getting started with TDD - Confoo 2014
Getting started with TDD - Confoo 2014Getting started with TDD - Confoo 2014
Getting started with TDD - Confoo 2014Eric Hogue
 
Creating "Secure" PHP Applications, Part 1, Explicit Code & QA
Creating "Secure" PHP Applications, Part 1, Explicit Code & QACreating "Secure" PHP Applications, Part 1, Explicit Code & QA
Creating "Secure" PHP Applications, Part 1, Explicit Code & QAarchwisp
 
Workshop quality assurance for php projects - ZendCon 2013
Workshop quality assurance for php projects - ZendCon 2013Workshop quality assurance for php projects - ZendCon 2013
Workshop quality assurance for php projects - ZendCon 2013Michelangelo van Dam
 
EPHPC Webinar Slides: Unit Testing by Arthur Purnama
EPHPC Webinar Slides: Unit Testing by Arthur PurnamaEPHPC Webinar Slides: Unit Testing by Arthur Purnama
EPHPC Webinar Slides: Unit Testing by Arthur PurnamaEnterprise PHP Center
 
Unlock The Mystery Of PHPUnit (Wave PHP 2018)
Unlock The Mystery Of PHPUnit (Wave PHP 2018)Unlock The Mystery Of PHPUnit (Wave PHP 2018)
Unlock The Mystery Of PHPUnit (Wave PHP 2018)ENDelt260
 
Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8Michelangelo van Dam
 
Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Elena Kolevska
 
Decoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICDecoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICKonstantin Kudryashov
 

Similar to Load Testing with PHP and RedLine13 (20)

Building Testable PHP Applications
Building Testable PHP ApplicationsBuilding Testable PHP Applications
Building Testable PHP Applications
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11
 
Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBenelux
 
Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12
 
Solid principles
Solid principlesSolid principles
Solid principles
 
PHP Unit Testing
PHP Unit TestingPHP Unit Testing
PHP Unit Testing
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい
 
Unit testing zend framework apps
Unit testing zend framework appsUnit testing zend framework apps
Unit testing zend framework apps
 
Getting started with TDD - Confoo 2014
Getting started with TDD - Confoo 2014Getting started with TDD - Confoo 2014
Getting started with TDD - Confoo 2014
 
Postman On Steroids
Postman On SteroidsPostman On Steroids
Postman On Steroids
 
PHPUnit testing to Zend_Test
PHPUnit testing to Zend_TestPHPUnit testing to Zend_Test
PHPUnit testing to Zend_Test
 
Creating "Secure" PHP Applications, Part 1, Explicit Code & QA
Creating "Secure" PHP Applications, Part 1, Explicit Code & QACreating "Secure" PHP Applications, Part 1, Explicit Code & QA
Creating "Secure" PHP Applications, Part 1, Explicit Code & QA
 
Unittests für Dummies
Unittests für DummiesUnittests für Dummies
Unittests für Dummies
 
Workshop quality assurance for php projects - ZendCon 2013
Workshop quality assurance for php projects - ZendCon 2013Workshop quality assurance for php projects - ZendCon 2013
Workshop quality assurance for php projects - ZendCon 2013
 
EPHPC Webinar Slides: Unit Testing by Arthur Purnama
EPHPC Webinar Slides: Unit Testing by Arthur PurnamaEPHPC Webinar Slides: Unit Testing by Arthur Purnama
EPHPC Webinar Slides: Unit Testing by Arthur Purnama
 
Unlock The Mystery Of PHPUnit (Wave PHP 2018)
Unlock The Mystery Of PHPUnit (Wave PHP 2018)Unlock The Mystery Of PHPUnit (Wave PHP 2018)
Unlock The Mystery Of PHPUnit (Wave PHP 2018)
 
Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8
 
Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5
 
Decoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICDecoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DIC
 

Recently uploaded

A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1
A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1
A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1KnowledgeSeed
 
Advanced Flow Concepts Every Developer Should Know
Advanced Flow Concepts Every Developer Should KnowAdvanced Flow Concepts Every Developer Should Know
Advanced Flow Concepts Every Developer Should KnowPeter Caitens
 
Cyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdfCyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdfCyanic lab
 
De mooiste recreatieve routes ontdekken met RouteYou en FME
De mooiste recreatieve routes ontdekken met RouteYou en FMEDe mooiste recreatieve routes ontdekken met RouteYou en FME
De mooiste recreatieve routes ontdekken met RouteYou en FMEJelle | Nordend
 
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...Anthony Dahanne
 
Breaking the Code : A Guide to WhatsApp Business API.pdf
Breaking the Code : A Guide to WhatsApp Business API.pdfBreaking the Code : A Guide to WhatsApp Business API.pdf
Breaking the Code : A Guide to WhatsApp Business API.pdfMeon Technology
 
SOCRadar Research Team: Latest Activities of IntelBroker
SOCRadar Research Team: Latest Activities of IntelBrokerSOCRadar Research Team: Latest Activities of IntelBroker
SOCRadar Research Team: Latest Activities of IntelBrokerSOCRadar
 
Agnieszka Andrzejewska - BIM School Course in Kraków
Agnieszka Andrzejewska - BIM School Course in KrakówAgnieszka Andrzejewska - BIM School Course in Kraków
Agnieszka Andrzejewska - BIM School Course in Krakówbim.edu.pl
 
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoamOpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoamtakuyayamamoto1800
 
top nidhi software solution freedownload
top nidhi software solution freedownloadtop nidhi software solution freedownload
top nidhi software solution freedownloadvrstrong314
 
Using IESVE for Room Loads Analysis - Australia & New Zealand
Using IESVE for Room Loads Analysis - Australia & New ZealandUsing IESVE for Room Loads Analysis - Australia & New Zealand
Using IESVE for Room Loads Analysis - Australia & New ZealandIES VE
 
Facemoji Keyboard released its 2023 State of Emoji report, outlining the most...
Facemoji Keyboard released its 2023 State of Emoji report, outlining the most...Facemoji Keyboard released its 2023 State of Emoji report, outlining the most...
Facemoji Keyboard released its 2023 State of Emoji report, outlining the most...rajkumar669520
 
AI/ML Infra Meetup | ML explainability in Michelangelo
AI/ML Infra Meetup | ML explainability in MichelangeloAI/ML Infra Meetup | ML explainability in Michelangelo
AI/ML Infra Meetup | ML explainability in MichelangeloAlluxio, Inc.
 
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.ILBeyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.ILNatan Silnitsky
 
GraphAware - Transforming policing with graph-based intelligence analysis
GraphAware - Transforming policing with graph-based intelligence analysisGraphAware - Transforming policing with graph-based intelligence analysis
GraphAware - Transforming policing with graph-based intelligence analysisNeo4j
 
A Comprehensive Appium Guide for Hybrid App Automation Testing.pdf
A Comprehensive Appium Guide for Hybrid App Automation Testing.pdfA Comprehensive Appium Guide for Hybrid App Automation Testing.pdf
A Comprehensive Appium Guide for Hybrid App Automation Testing.pdfkalichargn70th171
 
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume MontevideoVitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume MontevideoVitthal Shirke
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2
 

Recently uploaded (20)

A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1
A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1
A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1
 
Advanced Flow Concepts Every Developer Should Know
Advanced Flow Concepts Every Developer Should KnowAdvanced Flow Concepts Every Developer Should Know
Advanced Flow Concepts Every Developer Should Know
 
Cyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdfCyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdf
 
De mooiste recreatieve routes ontdekken met RouteYou en FME
De mooiste recreatieve routes ontdekken met RouteYou en FMEDe mooiste recreatieve routes ontdekken met RouteYou en FME
De mooiste recreatieve routes ontdekken met RouteYou en FME
 
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
 
Breaking the Code : A Guide to WhatsApp Business API.pdf
Breaking the Code : A Guide to WhatsApp Business API.pdfBreaking the Code : A Guide to WhatsApp Business API.pdf
Breaking the Code : A Guide to WhatsApp Business API.pdf
 
SOCRadar Research Team: Latest Activities of IntelBroker
SOCRadar Research Team: Latest Activities of IntelBrokerSOCRadar Research Team: Latest Activities of IntelBroker
SOCRadar Research Team: Latest Activities of IntelBroker
 
Agnieszka Andrzejewska - BIM School Course in Kraków
Agnieszka Andrzejewska - BIM School Course in KrakówAgnieszka Andrzejewska - BIM School Course in Kraków
Agnieszka Andrzejewska - BIM School Course in Kraków
 
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoamOpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
 
top nidhi software solution freedownload
top nidhi software solution freedownloadtop nidhi software solution freedownload
top nidhi software solution freedownload
 
Using IESVE for Room Loads Analysis - Australia & New Zealand
Using IESVE for Room Loads Analysis - Australia & New ZealandUsing IESVE for Room Loads Analysis - Australia & New Zealand
Using IESVE for Room Loads Analysis - Australia & New Zealand
 
Facemoji Keyboard released its 2023 State of Emoji report, outlining the most...
Facemoji Keyboard released its 2023 State of Emoji report, outlining the most...Facemoji Keyboard released its 2023 State of Emoji report, outlining the most...
Facemoji Keyboard released its 2023 State of Emoji report, outlining the most...
 
AI/ML Infra Meetup | ML explainability in Michelangelo
AI/ML Infra Meetup | ML explainability in MichelangeloAI/ML Infra Meetup | ML explainability in Michelangelo
AI/ML Infra Meetup | ML explainability in Michelangelo
 
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.ILBeyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
 
GraphAware - Transforming policing with graph-based intelligence analysis
GraphAware - Transforming policing with graph-based intelligence analysisGraphAware - Transforming policing with graph-based intelligence analysis
GraphAware - Transforming policing with graph-based intelligence analysis
 
A Comprehensive Appium Guide for Hybrid App Automation Testing.pdf
A Comprehensive Appium Guide for Hybrid App Automation Testing.pdfA Comprehensive Appium Guide for Hybrid App Automation Testing.pdf
A Comprehensive Appium Guide for Hybrid App Automation Testing.pdf
 
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume MontevideoVitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume Montevideo
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
 
Top Mobile App Development Companies 2024
Top Mobile App Development Companies 2024Top Mobile App Development Companies 2024
Top Mobile App Development Companies 2024
 
Corporate Management | Session 3 of 3 | Tendenci AMS
Corporate Management | Session 3 of 3 | Tendenci AMSCorporate Management | Session 3 of 3 | Tendenci AMS
Corporate Management | Session 3 of 3 | Tendenci AMS
 

Load Testing with PHP and RedLine13

  • 1. Load Testingwith Jason Lotito “Guaranteed to be the best talk on load testing with PHP @ MidwestPHP 2016 during that time slot in that room with me as the speaker"
  • 2. Jason Lotito • DevOps Lead Architect • MeetMe.com • @jasonlotito • jasonlotito.com • jlotito@meetme.com
  • 4. Load Testing Not Unit Testing, Integration Testing, Acceptance Testings, manual Testing, or Standardized Testing
  • 5. Jason Lotito Load test, or your users will do it for you.
  • 6. Load test, or your users will do it for you. Your Servers
  • 7. Load test, or your users will do it for you. And if they do, you won’t have any users.
  • 8. You can use load testing to practice dealing with lots of requests
  • 9. What is Load Testing?
  • 10. Load Testing • Putting demand on a system • Determine behavior under load • Determine maximum operating capacity • Discover Bottlenecks • Determining steps to increase operating capacity • Optimize for costs
  • 11. Other Load Testing Tools • ApacheBench (ab) • Apache JMeter • siege • BlazeMeter • and many more…
  • 12. The Basics of Load Testing
  • 13. The Basics of Load Testing
  • 14. Why RedLine13? • Simple, up and running in little time • Freemium, free level you only pay AWS • Scriptable (PHP, Node.js) • AWS for Infinite Scalability™ • I know Rich, one of the founders
  • 15. RedLine13 has a bunch of features you can read about on the website. I’m really here to talk to you about the cool stuff I do with RedLine13.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20. Let’s walk through a Custom Load Test
  • 21. CustomTest.php The class that actually runs the test.
  • 22. In our example, we’ll use sleep to simulate performing actions such as making HTTP requests to an API
  • 23. <?php
 
 require_once( 'LoadTestingTest.class.php' );
 
 class CustomTest extends LoadTestingTest
 {
 public function startTest()
 {
 for ( $x = 1; $x <= 100; $x++ )
 {
 $startTime = microtime(true);
 sleep( mt_rand( 2, 5 ) );
 $diff = microtime( true ) - $startTime;
 recordPageTime( $startTime, $diff );
 recordURLPageLoad( $x, $startTime, $diff );
 }
 
 return true;
 }
 } CustomTest.php This is where your code goes
  • 24. <?php
 
 require_once( 'LoadTestingTest.class.php' );
 
 class CustomTest extends LoadTestingTest
 {
 public function startTest()
 {
 for ( $x = 1; $x <= 100; $x++ )
 {
 $startTime = microtime(true);
 sleep( mt_rand( 2, 5 ) );
 $diff = microtime( true ) - $startTime;
 recordPageTime( $startTime, $diff );
 recordURLPageLoad( $x, $startTime, $diff );
 }
 
 return true;
 }
 } CustomTest.php
  • 25. <?php
 
 require_once( 'LoadTestingTest.class.php' );
 
 class CustomTest extends LoadTestingTest
 {
 public function startTest()
 {
 for ( $x = 1; $x <= 100; $x++ )
 {
 $startTime = microtime(true);
 sleep( mt_rand( 2, 5 ) );
 $diff = microtime( true ) - $startTime;
 recordPageTime( $startTime, $diff );
 recordURLPageLoad( $x, $startTime, $diff );
 }
 
 return true;
 }
 } CustomTest.php
  • 26. <?php
 
 require_once( 'LoadTestingTest.class.php' );
 
 class CustomTest extends LoadTestingTest
 {
 public function startTest()
 {
 for ( $x = 1; $x <= 100; $x++ )
 {
 $startTime = microtime(true);
 sleep( mt_rand( 2, 5 ) );
 $diff = microtime( true ) - $startTime;
 recordPageTime( $startTime, $diff );
 recordURLPageLoad( $x, $startTime, $diff );
 }
 
 return true;
 }
 } CustomTest.php
  • 27. <?php
 
 require_once( 'LoadTestingTest.class.php' );
 
 class CustomTest extends LoadTestingTest
 {
 public function startTest()
 {
 for ( $x = 1; $x <= 100; $x++ )
 {
 $startTime = microtime(true);
 sleep( mt_rand( 2, 5 ) );
 $diff = microtime( true ) - $startTime;
 recordPageTime( $startTime, $diff );
 recordURLPageLoad( $x, $startTime, $diff );
 }
 
 return true;
 }
 } CustomTest.php
  • 28. <?php
 
 require_once( 'LoadTestingTest.class.php' );
 
 class CustomTest extends LoadTestingTest
 {
 public function startTest()
 {
 for ( $x = 1; $x <= 100; $x++ )
 {
 $startTime = microtime(true);
 sleep( mt_rand( 2, 5 ) );
 $diff = microtime( true ) - $startTime;
 recordPageTime( $startTime, $diff );
 recordURLPageLoad( $x, $startTime, $diff );
 }
 
 return true;
 }
 } CustomTest.php
  • 29. <?php
 
 require_once( 'LoadTestingTest.class.php' );
 
 class CustomTest extends LoadTestingTest
 {
 public function startTest()
 {
 for ( $x = 1; $x <= 100; $x++ )
 {
 $startTime = microtime(true);
 sleep( mt_rand( 2, 5 ) );
 $diff = microtime( true ) - $startTime;
 recordPageTime( $startTime, $diff );
 recordURLPageLoad( $x, $startTime, $diff );
 }
 
 return true;
 }
 } CustomTest.php Start Time Start/End Time Difference
  • 30. <?php
 
 require_once( 'LoadTestingTest.class.php' );
 
 class CustomTest extends LoadTestingTest
 {
 public function startTest()
 {
 for ( $x = 1; $x <= 100; $x++ )
 {
 $startTime = microtime(true);
 sleep( mt_rand( 2, 5 ) );
 $diff = microtime( true ) - $startTime;
 recordPageTime( $startTime, $diff );
 recordURLPageLoad( $x, $startTime, $diff );
 }
 
 return true;
 }
 } CustomTest.php URL/String
  • 31. These next two files help us test locally
  • 32. redline.php Mock Redline functions to test load test locally
  • 33. <?php
 /**
 * @return bool
 */
 function isRedlineVerbose()
 {
 return (int) getenv( 'REDLINE_VERBOSE' ) === 1;
 }
 
 /**
 * @param int $timestamp
 * @param int $elapsedTime
 */
 function recordPageTime( $timestamp, $elapsedTime )
 {
 isRedlineVerbose() && output( "Record Page Time: timestamp $timestamp; elapsed time: $elapsedTime" );
 }
 
 /**
 redline.php
  • 34. <?php
 /**
 * @return bool
 */
 function isRedlineVerbose()
 {
 return (int) getenv( 'REDLINE_VERBOSE' ) === 1;
 }
 
 /**
 * @param int $timestamp
 * @param int $elapsedTime
 */
 function recordPageTime( $timestamp, $elapsedTime )
 {
 isRedlineVerbose() && output( "Record Page Time: timestamp $timestamp; elapsed time: $elapsedTime" );
 }
 
 /**
 redline.php
  • 35. <?php
 /**
 * @return bool
 */
 function isRedlineVerbose()
 {
 return (int) getenv( 'REDLINE_VERBOSE' ) === 1;
 }
 
 /**
 * @param int $timestamp
 * @param int $elapsedTime
 */
 function recordPageTime( $timestamp, $elapsedTime )
 {
 isRedlineVerbose() && output( "Record Page Time: timestamp $timestamp; elapsed time: $elapsedTime" );
 }
 
 /**
 * @param string $url
 * @param int $timestamp
 * @param int $elapsedTime
 */
 function recordURLPageLoad( $url, $timestamp, $elapsedTime )
 {
 output( "$url -> $elapsedTime seconds" );
 }
 redline.php
  • 36. * @param int $elapsedTime
 */
 function recordPageTime( $timestamp, $elapsedTime )
 {
 isRedlineVerbose() && output( "Record Page Time: timestamp $timestamp; elapsed time: $elapsedTime" );
 }
 
 /**
 * @param string $url
 * @param int $timestamp
 * @param int $elapsedTime
 */
 function recordURLPageLoad( $url, $timestamp, $elapsedTime )
 {
 output( "$url -> $elapsedTime seconds" );
 }
 
 /**
 * @param int $kilobytes
 */
 function recordDownloadSize( $kilobytes )
 {
 isRedlineVerbose() && output( sprintf( "Download Size: %dkb", $kilobytes ) );
 }
 
 redline.php
  • 37. * @param string $url
 * @param int $timestamp
 * @param int $elapsedTime
 */
 function recordURLPageLoad( $url, $timestamp, $elapsedTime )
 {
 output( "$url -> $elapsedTime seconds" );
 }
 
 /**
 * @param int $kilobytes
 */
 function recordDownloadSize( $kilobytes )
 {
 isRedlineVerbose() && output( sprintf( "Download Size: %dkb", $kilobytes ) );
 }
 
 /**
 * @param string $error
 */
 function recordError( $error )
 {
 output( "Error: $error" );
 }
 
 /**
 * @param string $msg
 redline.php
  • 38. /**
 * @param int $kilobytes
 */
 function recordDownloadSize( $kilobytes )
 {
 isRedlineVerbose() && output( sprintf( "Download Size: %dkb", $kilobytes ) );
 }
 
 /**
 * @param string $error
 */
 function recordError( $error )
 {
 output( "Error: $error" );
 }
 
 /**
 * @param string $msg
 * @return bool
 */
 function output( $msg )
 {
 echo sprintf( "[%s] %s]n", getmypid(), $msg );
 
 return true;
 } redline.php
  • 39. }
 
 /**
 * @param string $error
 */
 function recordError( $error )
 {
 output( "Error: $error" );
 }
 
 /**
 * @param string $msg
 * @return bool
 */
 function output( $msg )
 {
 echo sprintf( "[%s] %s]n", getmypid(), $msg );
 
 return true;
 } redline.php
  • 40. run.php The script we create to test CustomTest.php locally
  • 41. <?php
 require_once('redline.php');
 require_once('CustomTest.php');
 
 $customTest = new CustomTest(1, mt_rand(1000000,9999999));
 $customTest->startTest(); run.php
  • 42. <?php
 require_once('redline.php');
 require_once('CustomTest.php');
 
 $customTest = new CustomTest(1, mt_rand(1000000,9999999));
 $customTest->startTest(); run.php
  • 43. <?php
 require_once('redline.php');
 require_once('CustomTest.php');
 
 $customTest = new CustomTest(1, mt_rand(1000000,9999999));
 $customTest->startTest(); run.php
  • 44. <?php
 require_once('redline.php');
 require_once('CustomTest.php');
 
 $customTest = new CustomTest(1, mt_rand(1000000,9999999));
 $customTest->startTest(); run.php Instance Number
  • 45. <?php
 require_once('redline.php');
 require_once('CustomTest.php');
 
 $customTest = new CustomTest(1, mt_rand(1000000,9999999));
 $customTest->startTest(); run.php User Number Random Number
  • 46. What does a result look like?
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55. You can use error reporting to simulate real time logging Errors show up in real time, logs show up after the test is completed. Use error reports to let you know if you should stop your load test.
  • 56. Sample App: Chat Service
  • 57. Sample App: Chat Service • 1-on-1 Chat • Group Chat • Browse Chat Rooms • Search for Chat Room Topics
  • 58. Why split 1-on-1 and group chat into separate tests?
  • 59. Multiple tests can be run at the same time.
  • 60. 1-on-1 Group 30-40% 60-70% 30-40% 60-70% 60-70% 30-40% Time Start at the same time Increase group chat % Could mean just more group chat or both more group and less 1-on-1 Revert to normal ratio 20:00 40:000:00
  • 62. How? • Start 4 tests: • For both group and 1-on-1: • 350 users • 300 users
  • 63. 1-on-1 Group 350 350+300 350 350+300 350 350 Time 300 test sleeps for 20 minutes After 20 minutes, it stops.
  • 64. Or, instead of timers, just do it manually. Usually the easiest on the day of.
  • 65. The point is, you can adjust your load test as needed.
  • 67. Things You Need • Production-level systems to test against • Monitoring • Automated systems to deploy changes • Dedicated people • A time to test (load testing day!)
  • 68. Things You Need • Goals, such as • 500 requests per second • 90th percentile @ 50ms
  • 69. Planning the Load Test • Start at what you expect normal traffic to be • 500rps • Start a second test that is just the burst traffic • 900rps • Ramps up over 20 mins • Lasts 40 mins at peak • Ramps down over 20 mins
  • 70. Learning • Is proper monitoring setup? • Is a scaling plan in place? Can you scale? • What happens to the app under load? • What slows down first? • Are things alerting as expected?
  • 71. As Load Tester, you are responsible for… • Ensuring those involved with the system under test are aware and available • Putting the system under test under load • Completely destroying the system under load • Providing a clear and concise write up of exactly what occurred • Take charge! It’s fun!
  • 73. Reporting Results: Shortest Version • 99% @ 59ms
  • 74. Reporting Results: Short Version • Short version: During an hour starting with 0rps to 1400 rps in the first 10 minutes.... • ...when starting with 5 instances and scaling to 11 instances, the response times were: 50% 23ms, 75% 54ms, 95% 303ms, and 99% 1069ms. • ...when starting with 11 instances, the response times were: 50% 16ms, 75% 24ms, 95% 45ms, and 99% 59ms.
  • 75. Reporting Results: Detailed Version • Provide more information • Results • Story driven • Have data supporting results prepared in case • Account for changes such as auto-scaling • With auto-scaling: 99% at 1069ms • Without auto-scaling: 99% at 59ms
  • 76. Testing elasticsearch on c3.4xlarge Detailed Reporting Also included in this report was a link to the actual GitHub repository. Make sure you are keeping your load tests in version control!
  • 77. Tag your load test in git Associate the tag with a Load Test, so you can replay any load test easily
  • 79. Things to Keep In Mind • Understand expected usage • X% of users using the app while • Y% are chatting with one another • Users are logging in • Creating accounts • Backend systems • Determine what’s important
  • 80. Things to Keep In Mind • User input • Random filters • Weighted filters • Cached results are expected • Client constraints
  • 81. Things to Keep In Mind • User flow through service • Try to understand how users use the app • Script should try to mimic
  • 82. Things to Keep In Mind • Be careful about testing a single system • System will have logging • System will have backend services • You’d be surprised what can cause failure • A load test helps you learn before it’s in production
  • 83. Things to Keep In Mind • User interaction • MeetMe is social, so we’ve load tested chatting • 1 test per 2 users, both chatting with one another
  • 84. Things to Keep In Mind • Have developers available • Better, have developers with you when load testing
  • 85. Things to Keep In Mind • Find a problem, Fix it, Reroll app, Rerun test • FFRR, or F2R2 • I just made that up • Don’t use it.
  • 86. Things to Keep In Mind • Start testing from your laptop • Seriously, my MacBook Air could bring down Erlang services • Database indexes are a thing • While running a load test, you can run a single client form your laptop
  • 87. Things to Keep In Mind • Someone should be testing the app/service as well • Response times are only a number • What does 50ms vs 300ms response times feel to the user • What impact does 2x/3x/4x load have • When auto-scaling, how does the client handle
  • 88. Things to Keep In Mind • Review how the client is using the API • Review how the API developer expects the client to use the API • Model after what the client is doing • Call out differences early
  • 90. Thanks! • @jasonlotito • jasonlotito.com • jlotito@meetme.com • https://joind.in/talk/80910