Skip to content

momiller121/yet-another-speed-test

Repository files navigation

yet-another-speed-test

NOTICE: This was a learning experiment. It's not likely what you are looking for. :)


Simple Node.js based network speed test with support for IE6

The primary goal of the project is to create a simple (perhaps, even naive) speed test that is suitable to run within an an internal network. Instead of focusing on the validity of the numeric data produced by the client(s) the focus is to support the ability to trend (over time) the relative client perspective of network performance. We also wanted to be able to support old browsers (as far back as IE6) and other standalone HTTP client test clients (bash, python, etc.). The test client is bound to a standard request proceedure and then submits it's experience back to the server. The results log is intended to be fed to something like LogStash to get some data visualization running. We've deliberately avoided the Navigation Timing API to meet our client support goals in the browser.

To install:

(assuming Node.js and npm are installed and on your path...)

git clone (or download zip) then cd into yet-another-speed-test

$ npm install

To Run

$ npm start

To Use

Browse to http://127.0.0.1:5000 (before you can reach the test from elsewhere, edit authorizedRanges in config.js)

Client Request Behaviour

Again, the design intention is to be able to trend the client experience of performing a series of HTTP requests. We recognize that there are a myriad of factors (including the network) that can influence the client experience of the 'speed'. The default browser based JavaScript client is influenced by the browser it's running on and the machine specs. Therefore it is recognized that the numeric data generated by this method is not necessarily comparable between clients. However, given stability of client behaviours and request metrics collected over time, patterns may emerge.

The 'Latency' Test

The improvised 'latency' test requires the client to request a 37 byte 1x1 pixel transparant gif image. On the browser client, this is done by defining a new Image object and measurung the interval from setting the src attribute to triggering the image's onLoad event. This is repeated 12 times with this idea that DNS caching following the initial request speeds things up. The slowest and the fastest single timings are discarded and the remaining 10 are averaged to provide this 'latency' value.

The Download Test

The download test is conducted through a series of requests for increasingly large binary payloads of (somewhat) random bytes. The client's goal is to meet a data transit threshold time greater than 8 seconds. It is considered good and desirable client behavior to conduct the entire series of requests on the same HTTP connection using HTTP keep-alive.

Once the server reaches the upper limit of the package sizes it is willing to serve (or the client measures the 8 second threshold, all but the two longest running requests are discarded and the longest are averaged.

The Upload Test

The upload test operates in a similar pattern to the download test with a similar goal of 8 seconds of transit time. In the case of upload, it is the client constructing large payloads of random string data. The server measures what is sent and black-holes the data. The client, again, discards all but the two longest running uploads and averages those.

Logging

The tool uses Bunyan to log JSON data to disk. Our intent is to run that data into logstash and visualize in Kabana. The tool creates a familiar access.log and a very basic server.log. The main trending value comes from the results.log which is populated with data submitted by the clients upon completion of the tests.

A Valid Speed Testing Scenario

In order for a speed testing scenario to have any validity several things need to be true:

  • The server needs to be able to spew and eat data at rates that prevent it from being the limiting factor
  • The client needs to be able to eat and spew data at rates that prevent it from being the limiting factor

In a perfect world, this might mean:

Server Capability Validation

Using the most efficient http client on the speedtest server, request a large download payload and demonstrate the maximum potential data generation rate of the server. For example:

-bash-4.1$ time curl http://localhost:5000/download/256Mb > /dev/null
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  256M  100  256M    0     0   724M      0 --:--:-- --:--:-- --:--:--  731M
0.04user 0.09system 0:00.35elapsed 38%CPU (0avgtext+0avgdata 8736maxresident)k
0inputs+0outputs (0major+609minor)pagefaults 0swaps

In this case we can say we have evidence that our server is capable or serving >700Mb/second. We're not going to see a transfer rate like that on our network so we'll call that valid.

Client Capability Validation

The next question is the client. Using JavaScript in a browser as our test client leaves us exposed to the possibility that the machine, the browser, the browser's JavaScript implementation, and the efficiency of our JavaScript speedtest client code could (easily) become the least capable link.

The process for client validation is nearly the same as the server validation - we just need to use the most efficient http client from the client host while targeting the previously validated speedtest server:

$ sudo time curl http://ops01:5000/download/256Mb > /dev/null
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  256M  100  256M    0     0  10.6M      0  0:00:24  0:00:24 --:--:-- 10.5M
       24.14 real         0.16 user         0.44 sys

This time, the same payload took 24 seconds in transit on the network. If I now point a browser on this same client host to the same speedtest server, I would hope to get a result that is basically equivalent.

The ideal way to prove the potential capabilities of the client browser is to install the speedtest server on the same host. This won't often be practical or possible.

In our case, we can prove that a fast Macbook Pro (and modern Chrome browser) calling the speedtest server on the localhost can produce results approaching 90MB/second. In our network scenario this represents ample capacity to demonstrater accurate results. When we point this client across the network it generates results showing ~10MB/second.

However, performing the same test on an older Windows laptop (using IE9) showed a 50% (~5MB/second) reduced value on the download test compared to the Mac (using the same network port). Such a result suggests that the browser based client on that windows host may be an invalid client (bottlenecking the results).

About

Simple Node.js based network speed test with support for IE6

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published