All Posts by Tsahi Levent-Levi

What are the test profile configurations?

testRTC offers firewall profiles to check TURN connectivity. Below are the details of each firewall profile configuration and the ports it keeps open.

Note that you can use .rtcSetNetwork() and .rtcSetNetworkProfile() to dynamically change the network configuration.

No Firewall

All ports are open

FW – HTTP and HTTPS Allowed

Management ports 
Secured remote connection to the machineTCP 22
Agents’ management portTCP 2376
VNC connection for tests scripts’ debuggingTCP 5900-5904
Activity ports 
DNS outboundTCP and UDP 53
Browsing and WebRTC communication trafficHTTPS: TCP 443
  HTTP: TCP 80

FW – HTTPS Allowed

Management ports 
Secured remote connection to the machineTCP 22
Agents’ management portTCP 2376
VNC connection for tests scripts’ debuggingTCP 5900-5904
Activity ports 
DNS outboundTCP and UDP 53
Browsing and WebRTC communication trafficHTTPS: TCP 443

FW – Baseline

In this profile, only ports that are required for the agent operation are open.

Management ports 
Secured remote connection to the machineTCP 22
Agents’ management portTCP 2376
VNC connection for tests scripts’ debuggingTCP 5900-5904
Activity ports 
DNS outboundTCP and UDP 53

Network profiles

ProfileBandwidth
Latency
Packet loss 
No throttlingNo limitation00% 
Call Drop50 Kbps500ms20% 
DSL8 Mbps40ms0.5% 
Very Bad Network1 Mbps500ms10% 
Wifi30 Mbps40ms0.2% 
Wifi High packet loss30 Mbps40ms5% 
Regular 2.5G150 Kbps200ms3% 
Regular 3G750 Kbps250ms1.5% 
Poor 3G400 Kbps350ms5% 
Regular 4G4 Mbps02% 
Poor 4G4 Mbps350ms5% 
Unstable 4G4 Mbps500ms10% 
High Latency 4G4 Mbps600ms0.2% 
High Packet Loss 4G4 Mbps 5ms20% 
50% Packet Loss40 Mbps10ms50% 

How can you test high load?

testRTC can get to high number of probes count for its testing service. That said, since we use real browsers that require multiple CPU cores to work effectively at large scale, this becomes expensive at times.

There are two ways to scale beyond a few 1,000’s of probes in a single test efficiently:

  1. Voice only. For voice only tests, you can open multiple tabs in the browser of each probe, getting more density. From our experience, you can expect anywhere between 4-8 tabs to be opened in parallel per probe before the audio bitrate becomes a bit unstable
  2. Video testing. For video testing at higher scales, our suggestion is to use testRTC with anywhere between 100-1,000 probes while running synthetically generated traffic towards your media servers using other tools. For more on how to achieve that, contact us directly

Check out our checklist for preparing a test script for WebRTC stress testing.

Why does testRTC rely on real browsers in its WebRTC testing service?

There are several reasons why we’ve decided in testRTC to rely on real browsers for our testing and monitoring products:

  1. Applications using WebRTC are more likely than not to work inside web browsers. While they may have native applications as well, browsers seem to be the common denominator. Using it gives us a universal “language” for our products
  2. WebRTC changes rapidly. New features are added while others are deprecated with every browser release. This means that you (and us) need to keep updating at the pace of browsers. The best way to do that is relying on browsers
  3. WebRTC doesn’t force any signaling protocol. To be able to easily support your signaling protocol of choice, we simply let your application dictate it to us the way you would dictate it to a browser. This removes the need for lengthy and complex integration effort on your side when starting to use testRTC

Stress testing checklist

Before scaling your WebRTC test to 100’s of probes to make sure it works well under stress, there are a couple of things you might want to take care of when using testRTC. These will improve your chances of success and will make sure that you are testing the right things in your service.

1. Use Chrome

For stress make sure to use Chrome.

your focus is on the server infrastructure, and Chrome allows much better support for the data collected as well as the bitrates supported. This makes it more suitable for such tests.

2. Monitor your own servers

Make sure you turn on monitoring on your own servers. This will enable you to correlate the test behavior and results to your server’s behavior a lot better.

At the very least, monitor CPU, memory and network traffic for your media servers and TURN servers. You should also monitor your signaling and application servers.

Note that the machines used by testRTC are all synchronized and the logs are stored in UTC time format, so you can correlate them to your server logs.

If you don’t have a solid monitoring solution, you can use some basic Linux commands to capture CPU, memory and network usage:

top -n 1 -b > top-output.txtCode language: Bash (bash)

For our own internal testing, we sometimes use the below script and then analyze the data collected as graphs on Google Sheet or Excel:

top -d 0.3 -n 3000 -b | grep Cpu | awk '{print $2}' > tp.txt

top -d 0.3 -n 3000 -b | grep buffers | awk '{print $5}' >Mem.txt

ifstat -T -l -a -q -n -b 0.3 > ifstat.txt
awk '{print $(NF)}' ifstat.txt > ifstatOut.txt
awk '{print $(NF-1)}' ifstat.txt > ifstatIn.txtCode language: Bash (bash)

3. Ramp up slowly by staggering/pacing the probes

In load tests with WebRTC, the concurrent execution of our probes may lead to server failures at the client’s end. This can happen due to slow web servers or signaling servers that aren’t designed to handle the load of hundreds of users trying to reach the same resources at the exact same time.

Assuming this isn’t the specific use case you are trying to solve, then it would be preferable to add a small delay between the probes that are joining the test.

var agentNumber = process.env.RTC_AGENT_NUM;
client.pause(agentNumber * 200);Code language: JavaScript (javascript)

Using the above snippet close to the beginning of your test script will add 200 milliseconds delay between the actions taken by each of the probes in the test. Be sure to do that prior to calling the .url() script command.

A fancier approach is suggested below.

var agentId = Number(process.env.RTC_IN_SESSION_ID);
var sessionIDX = Number(process.env.RTC_SESSION_IDX);
var sessionJoinRate = 3000; //milliseconds
var sessionRate = 200; //milliseconds
var pace = (sessionRate * (sessionIDX-1)) + (sessionJoinRate * (agentId-1));
client.pause(pace+1); // Staggering Code language: JavaScript (javascript)

Here, you can (and should play around with the sessionRate and sessionJoinRate variables).

  • sessionRate indicates how much time to wait between each session/room that you have in the test
  • sessionJoinRate indicates how much time to wait between each probe that joins the session

Assuming a test with 100 probes, split into sessions/rooms of 5 users each – the sample snippet above will have each room start at a delay of 3 seconds from the previous room and each user joining a room will join at a delay of 200 milliseconds from the previous user.

4. Have all probes running the test

Since you are pacing the probes into the service, you may end up with probes leaving before all probes joined the session. The bigger the test, the more this is likely to happen.

If we build on the ramp up logic in the first suggestion in this list, then this is how we need to think about getting all the probes to stay in the session long enough:

  • Assume we have a test with 5 people, each joining every 1 second
  • First person joins. He needs to stay in call for 4 more seconds than all the rest
  • Second person joins. he needs to stay in call for 3 more seconds than those coming after him
  • Last person joins. He needs to stay the allotted time you need them all to stay in the call

To implement such logic with our sessionRate and sessionJoinRate variables used above, we can add the following pause to the test duration where media is flowing:

var sessionCount = Math.ceil(Number(process.env.RTC_AGENT_COUNT)/Number(process.env.RTC_SESSION_SIZE));
var sessionSize = Number(process.env.RTC_SESSION_SIZE);
var totalWaitTime = sessionRate*(sessionCount-1)+sessionJoinRate*(sessionSize-1);
client.pause(totalWaitTime-pace+1);Code language: JavaScript (javascript)

The above should reverse the effect we get from staggering the probes into the session to even it out.

Add additional pause() afterwards for the actual amount of time you want all probes to stay inside the test together.

5. Add events sensibly

Now that you’ve got pacing correctly, you may want to look at how events occurring in your test are spread over time. This can give you a nice view into what is going on in the test.

Events can be added using .rtcEvent(). This adds vertical lines on the metric graphs which can help understanding how actions taken in your application (or the network) changes the behavior of media flows.

In a large test, putting a lot of global events can clutter the view. You can sparse them out a bit using the following:

var probeId = Number(process.env.RTC_AGENT_NUM);
client.rtcEvent("User " + probeId, ((probeId % 100) == 0) ? "global" : "local");Code language: JavaScript (javascript)

The above will make sure that only one of every 100 probes will make its event a global one and the others will have their event as a local one. Global events show up in the high level aggregate graph in the main test results.

6. Configure the test timeout

WebRTC load tests are large and collect a lot of metrics, log files and screenshots. When these tests complete, our machines start uploading the results to the main data center for storage and analysis. This takes a bit of time and needs to be factored in with your test’s total run time.

Make sure to use the #timeout run option, keeping the following rule of thumb in mind:

#timeout = Call Set up time + Call time + 15 minutesCode language: PHP (php)
  • Call set up time – the time required to set the call by the script (make sure to factor in any pacing logic you’ve added)
  • Call time – the call duration
  • 15 minutes – typically we should take just 3-4 minutes extra but 15 minutes is an extra provision

In the run options, check that you have a line similar to this, based on the number of minutes needed:

#timeout:20Code language: CSS (css)

The above will make sure the test can last as long as 20 minutes. After that time, testRTC will kill the test due to timeout. The timeout won’t affect how many minutes your test will use – just define a maximum threshold to that time.

7. Use waitForElementVisible() instead of pause()

This is just best practices in writing automation scripts, but it is doubly important in WebRTC stress testing, where processing time can stretch a bit longer than usual.

When waiting for an element prior to clicking it, don’t use a .pause() statement with the intent of letting the browser load the new page or show the button it needs to – wait for that button to appear using .waitForElementVisible().

client
    .waitForElementVisible('#login', 30000)
    .click('#login);Code language: JavaScript (javascript)

The above code snippet will wait up to 30 seconds for the #login button to appear on the screen and then click on it.

8. Use pause() after waitForElementVisible()

Now that you are using .waitForElementVisible(), here’s a non-obvious suggestion – add a pause() after it. Specifically when you are running a load test. The reason for it is that sometimes, with slow servers and high CPU load, there can be delays between the changes in the DOM to the screen rendering.

In such cases, .waitForElementVisible() will return but it might be too early for the .click() command.

Here’s how to add that .pause():

client
    .waitForElementVisible('#login', 30000)
    .pause(1000)
    .click('#login);Code language: JavaScript (javascript)

9. Use expectations

Setting up a few quality checks via our .rtcSetTestExpectations() script command. These will give you some amazing insights in your stress tests.

Add a few test ranges, checking for bitrate and packetloss values.

client
    .rtcSetTestExpectation("audio.in.channel.bitrate >= 24")
    .rtcSetTestExpectation("audio.in.channel.bitrate <= 32")
    .rtcSetTestExpectation("audio.in.bitrate.max <= 36", "warn")
    .rtcSetTestExpectation("audio.in.bitrate.max <= 20", "warn")
    .rtcSetTestExpectation("audio.out.channel.bitrate >= 24")
    .rtcSetTestExpectation("audio.out.channel.bitrate <= 32")
    .rtcSetTestExpectation("audio.out.bitrate.max <= 36", "warn")
    .rtcSetTestExpectation("audio.out.bitrate.max <= 20", "warn");Code language: JavaScript (javascript)

For Opus, we’re assuming here a 28kbps bitrate on the payload. So we’re putting some thresholds of 4-8kbps for the errors and warnings to deal with fluctuations.

Here are expectations for packetloss:

client
    .rtcSetTestExpectation("audio.in.packetloss  <= 0.5")
    .rtcSetTestExpectation("audio.out.packetloss  <= 0.5")Code language: JavaScript (javascript)

The above will throw an error if packet loss percentage will get above 0.5%.

Since we use machines in data centers that have a good network, it isn’t often that you’ll experience high packet loss due to our network. Setting an expectation to 0.5% is something you should do in large stress tests of WebRTC applications, as when it fails it tends to point towards a congestion issue in your service.

Another expectation to consider adding is connectionDuration:

client.rtcSetTestExpectation("connectionDuration >= 60");Code language: JavaScript (javascript)

The example above will help analyze that your calls duration is at least 60 seconds in length. If the sessions get dropped prematurely, you will know about it. This will not guarantee a stable flow of bitrate, but if the peer connection closes, it will detect it and raise an error.

Here is another useful expectation to add:

client
    .rtcSetTestExpectation("callSetupTime < 20 ", "warn");
    .rtcSetTestExpectation("callSetupTime < 50 ");Code language: JavaScript (javascript)

Typically in load conditions, new WebRTC sessions takes forever to connect. The call set up time expectation can surface warnings and errors for this. Our recommendation – have 2 of these set to warning and error level, so you can find more problematic cases easily. Typically, allow +/- 5-10% range for your expectations to throw a warning and +/- 10-20% range for your expectations to throw an error.

10. Pace the script ending

Similarly, at the end of test you should have add some delay between the probes as they leave the test. This will help the cleanup, uploading and analysis processes that takes place by testRTC at that point in time – otherwise, they might just fail due to high load.

This is especially important in tests with long duration.

var agentNumber = process.env.RTC_AGENT_NUM;
client.pause(agentNumber * 100);Code language: JavaScript (javascript)

Add the code snippet above at the end of your test script to add a 100 millisecond delay between each probe that is leaving the test.

11. Understand our “best effort” mode

In large stress tests, we automatically configure best effort mode.

In this mode, if not all the probes that were required for the test can be successfully allocated and used, the test will still proceed as planned, just with less probes.

Learn more about best effort.

12. Collect less in longer tests

If you are running a test that is planned to be longer than 20 minutes, then add the run option #webrtc-internals:false. Collecting webrtc-internals is useless in such cases, as it only stores the last 15 minutes of metrics. Removing this will alleviate some of the strain of the data that needs to be collected during the test.

It is also advisable to set #webrtc-internals:false for stress tests where there are more than 4 incoming video media streams per probe (mainly in large group calls).

13. Baseline and increment

The larger the test you are conducting the more time consuming it will be and the more expensive. In many cases, you can find the bugs lurking in your application by running smaller tests. That means:

  • You will find the bugs sooner
  • It will take you less time to debug and figure out the root causes for them
  • You will end up finishing your tests faster
  • And it will cost you less

Here are two things you should do:

a. Baseline your stress test

Create a baseline for your comparison.

If you are running a scenario of multiple 1:1 sessions, then your baseline would be 2 probes.

If you are running a scenario of multiple group rooms, then your baseline would be the number of participants in a single room.

For live broadcast, you may want to pick a number of 2-10 probes.

Once you have that test run, check the results and learn them. Get a feeling of the metrics you get at the ribbon at the top of the results as well as how the graphs for bitrate, packet loss, jitter and round trip behave.

Your expectation should be that as you scale, you will see as little divergence as possible from this baseline of yours.

b. Increment slowing the test size

Don’t immediately move from your baseline to the full scale stress test.

If you are aiming for 2,000 probes for example, then run scenarios with these number of probes: 4 – 16 – 64 – 160 – 300 – 500 – 1000 – 2000

Pick similar numbers/scales based on the size of your baseline test.

After each such test, compare the results and behavior to your baseline (and check your server stats as well).

The reason for this slow increment is that often times you can catch issues more efficiently with a smaller run size.

14. Long stress test preparations

Planning to run a long stress test? Something longer than 15 minutes?

In such a case, be sure to go over the long running test checklist as well.

15. Understand minutes use

Running large tests comes at a higher minutes use of our service. You will be running more probes, probably pacing them as they enter your service.

Be sure to go over our minutes calculation explanation.

16. Contact us

Running a test with 200 or more probes? Let us know. We’ll take a look at your script and see if there are any additional useful suggestions we can make so that your WebRTC stress testing session will be… less stressful.

Using VNC

VNC can be used as an additional debugging tool that testRTC offers. It enables you to view how the browsers in a running test behave and to fix the test script accordingly.

What is VNC?

VNC stands for Virtual Network Computing. It is a desktop sharing system that is platform independent and mostly free to use.

You can setup a machine with a VNC server, and then using a VNC client connect to it remotely to control it as if you were sitting on that same machine.

Luckily for you, testRTC has support for VNC. Our testing probes can be configured to run with a VNC server, letting you connect to them remotely as a test is running and see firsthand what is going on. This is useful when troublehsooting the scripts while writing them or figuring out what is going on in your application in certain scenarios.

Using VNC in testRTC

Install VNC

You will need to have a VNC viewer installed on your machine. There are multiple such applications available in the web, and it would be best if you search on your own and find a VNC viewer you are comfortable with.

TightVNC and RealVNC are both good alternatives, although there are others as well.

Enable support for VNC

VNC isn’t enabled by default. The reason for that is that running it takes up resources from the probes – resources that are better used for your application testing when it is not needed.

To enable VNC support, you will first need to add #vnc as one of the run options of the test.

Run a test and find the VNC server

When a test is running, if VNC is enabled, then testRTC will try as best effort to run a VNC server on some of the machines in the test. If this is successful, then the Test Execution Status of the test itself will show something similar to this:

Note the blue VNC buttons next to some of the probes – if you click them, then the IP address of the VNC server for that probe will be stored in your PC’s clipboard and you will be able to use it in your VNC client.

The VNC session has by a password. The password is ‘secret’.

Important rules of thumb when using VNC

As a rule of thumb, don’t expect to see a VNC button in the following cases:

  • If #vnc isn’t set in the run options
  • If this is a scheduled monitor run
  • If there are multiple probes running concurrently in this test you will see VNC on just two probes
  • If VNC port resources on the physical machine are already allocated to other running tests – this may happen from time to time

Please Note that VNC takes up resources, and we can’t make it available on all running agents at once. Due to that, you may find that sometimes the VNC button doesn’t appear.

Q: Why isn’t there a VNC button when I run my test script?

A: VNC takes up resources, and we can’t make it available on all running agents at once. Due to that, you may find that sometimes the VNC button doesn’t exist.

Q: Why VNC stutters and disconnects for me

A: VNC is used for debugging purposes, so we don’t really optimize its use.

That said, there is one specific scenario in which you can expect VNC to work really bad – and that’s if you set the network configuration in a test to introduce packet loss. Since we configure the whole machine to simulate packet loss, the VNC connection on that machine suffers from the same problem.

Configure Monitor Frequency with Cron

When scheduling a monitor, besides picking one of the simple alternatives testRTC offers “out of the box”, you can express your own monitor’s frequency by using a cron expression.

A cron expression is a string consisting of six or seven subexpressions (fields) that describe individual details of the schedule.

These fields, separated by white space, can contain any of the allowed values with various combinations of the allowed characters for that field.

Cron syntax:

 ┌───────────── min (0 - 59)
 │ ┌────────────── hour (0 - 23)
 │ │ ┌─────────────── day of month (1 - 31)
 │ │ │ ┌──────────────── month (1 - 12)
 │ │ │ │ ┌───────────────── day of week (0 - 6) (0 to 6 are Sunday to
 │ │ │ │ │                  Saturday, or use names; 7 is also Sunday)
 │ │ │ │ │
 │ │ │ │ │
 * * * * *  command to execute

Examples:

*/30 * * * * Every 30 minutes

1 0 * * * Every day, at 00:01 AM

0 * * * * Every hour

*/5 * * * * Every 30 minutes

Online generator

You can use an online cron expression descriptor to create these expressions in a way that is more human readable. We recommend using this Cron Expression Generator. Take into account the following:

  • Time is adjusted to UTC on our service
  • Remove the 1st 0 as we don’t use seconds
  • Remove the last * as we don’t use years

How to use external parameters in the test script

From time to time we see a need to use parameters that should be received from an external source and/or to be shared with other systems. The following code sample demonstrates how we read a URL from external DB and use it in the test script.

For this sample, we use Firebase DB with an entry called ‘url’.

client.rtcActivateWebhook("https://[Firebase-account].firebaseio.com/url.json", function(url) {
    // Remove quotes from the url string 
    url = url.substr(1,url.length -2);

    client.rtcInfo('Received URL using rtcActivateWebhook. url = ' + url);

    // Go to the received URL
    client.url(url);
})Code language: JavaScript (javascript)

Analyze WebRTC Dump

You can use testRTC to analyze WebRTC dump files taken from your real devices.

How to download a webrtc-internals dump file

In order to obtain a webrtc-internals dump file, please perform the following steps:

  1. In your local browser, open a new tab and go to chrome://webrtc-internals/
  2. In a separate browser tab, start a WebRTC session and while in the session (don’t close the WebRTC session)
  3. Click on ‘Create Dump’
  4. Click on the ‘Download the PeerConnection updates and stats data’ button
  5. Choose a location and filename for the WebRTC Dump file
  6. At this point you can close the WebRTC session

Here’s a quick video explainer for this:

Using analyzeRTC to view webrtc-internals dump file

testRTC offers a tool called analyzeRTC which lets you drag and drop a webrtc-internals dump file and visually review it. For that:

  1. In testRTC, click on the analyzeRTC menu item in the left-hand sidebar in the testRTC dashboard
  2. Drag the stored webrtc-internals dump file to the large icon area or use the UPLOAD button
  3. After the analysis is completed, click on the ‘RESULTS’ button

Specify Chrome command line switches in testRTC

You can direct testRTC to execute its Chrome browsers with specific command line switches. This is done via the run options of the test script.

The full list of command line switches is available online.

A few notable switches:

  • ignore-certificate-errors – indicate Chrome to ignore any TLS certificate errors. This is useful when testing a service under development with self-signed certificates
  • disable-background-timer-throttling – webrtc-internals metrics collection can falter after ~5 minutes or so. If you aren’t using getstats collection and are using webrtc-internals only for some reason, then using this switch can be useful
  • auto-select-desktop-capture-source=Entire screen – makes Chrome auto-select the provided choice when an extension asks permission to start the desktop capture
  • enable-features=WebRtc-ExposeNonStandardStats – exposes non-standard WebRTC statistics that are automatically collected and visualized by our services

You can concatenate switches in the following way:

#chrome-cli:disable-notifications,disable-desktop-notifications,allow-silent-push,ignore-certificate-errorsCode language: Bash (bash)

Our OpenAPI documentation for continuous integration

testRTC exposes an API for WebRTC service monitoring and testing automation in order to enable programmatic access for developers to our service.

Please perform the following steps in order to view our API documentation:

  1. In order to see the API, you will need your account’s private API Key. The API key can be found in the dashboard under Settings. If you can’t find the API Key, please contact us.
  2. Go to https://apidoc.testrtc.com
  3. Click on ‘Authorize’, enter your API Key, and click on ‘Authorize’
  4. Click on the endpoints to extend the endpoint’s documentation

API parameters

In the API endpoints you will need to use few parameters. Please perform the following steps in order to retrieve the needed parameters:

testId

  1. In testRTC web console, click on ‘Tests’ in the left menu bar and click on the relevant test name
  2. In the ‘Test Configuration’ page, extract the testId from your web browser’s link

testRunId

  1. In testRTC web console, click on ‘Test Run History’
  2. Select a test run
  3. In the ‘Test Run History – Test Results’ page, extract the testRunId from your web browser’s link

testAgentId

  1. In testRTC web console, click on ‘Test Run History’
  2. Select a test run
  3. Select a machine/iteration from the Test Sessions / Groups
  4. In the ‘Test Iteration Results’ page, extract the testAgentId from your web browser’s link
1 25 26 27 28 29 32