Table of Contents

Projects: Speedtest

I'm testing out some new 5G antennas and after experimenting with a number of different ways to measure their performance I decided the most reliable and simplest way was just write a script that repeats a download every minute and then plot the results in a graph. That allows me to average out any atmospheric interference (and more importantly average out all the other activity on my busy network).

Download Speeds

First, create some test files and put them on somewhere with reliable hosting (AWS for example):

dd if=/dev/zero of=/var/www/10mb-test-file bs=1024 count=10240
dd if=/dev/zero of=/var/www/50mb-test-file bs=1024 count=51200

Then write some code that times the download and saves the result to a CSV.

speedtest-download.php
<?php
while(true) {
        $time_start = microtime(true);
        $url = "https://putitonyourowndomain.com/10mb-test-file";
        $data = file_get_contents($url);
        $time_end = microtime(true);
        $download_time = $time_end - $time_start;
        echo date("Y-m-d H:i:s")."\t";
        echo $download_time."\t";
        echo (10/$download_time)."\n";
        sleep(60);
}
?>

Run it (in a screen or in the background) with:

php speedtest.php > results.log

Which gives results like this (datetime, seconds to download, average mb/s):

2022-08-02 20:12:19     24.084804058075 0.41519955802369
2022-08-02 20:13:36     16.985937833786 0.58872227708908
2022-08-02 20:15:09     32.288731813431 0.30970556718615
2022-08-02 20:16:39     30.061086893082 0.33265596934559

Upload Speeds

In order to track this we need two components - first, a form processor on the server (again, somewhere with reliable network, like AWS) that will accept a 4Mb upload file (and just bin it, we are only timing the upload). Put this somewhere on your webspace. You should add some validation and error handling, but this was just a quick test for me, so, meh.

acceptupload.php
<?php
<?php
if(is_array($_FILES['upload_file'])) {
        if(!move_uploaded_file($_FILES['upload_file']['tmp_name'], "/tmp/speedtest")) {
                echo "Error saving uploaded file";
        } else {
                echo "OK";
        }
}
?>
?>

Now write something that can test just the upload:

speedtest-upload.php
<?php
$target_url = "https://www.yourdomain.co.uk/acceptupload.php";
$file_name_with_full_path = "/tmp/4mb-test-file";
while(true) {
        $time_start = microtime(true);
        $cFile = curl_file_create($file_name_with_full_path);
        $post = array('upload_file'=>$cFile);
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL,$target_url);
        curl_setopt($ch, CURLOPT_POST,1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $result=curl_exec ($ch);
        curl_close ($ch);
        if($result == "OK") {
                echo date("Y-m-d H:i:s")."\t";
                $time_end = microtime(true);
                $download_time = $time_end - $time_start;
                echo $download_time."\t";
                echo (4/$download_time)."\n";
                sleep(60);
        } else {
                echo "Error downloading ($result)\n";
        }
}
 
?>

That will return in a format similar to the download test (datetime, seconds to download, average mb/s):

2022-08-02 20:49:44     4.6254539489746 0.86477998573237
2022-08-02 20:49:59     4.9542970657349 0.8073799263401

Upload and Download

This final version tries to download a 10Mb from my server, then tries to upload a 4Mb file to the acceptfile.php file (written above) hosted on my web server. Then it waits a minute and tries it again in a loop.

speedtest.php
<?php
$download_url = "https://www.yourdomain.co.uk/10mb-test-file";
$download_size_mb = 10;
$upload_url = "https://www.yourdomain.co.uk/acceptupload.php";
$upload_size_mb = 4;
$file_to_upload = "/tmp/4mb-test-file";
 
while(true) {
        $time_start = microtime(true);
        $data = file_get_contents($download_url);
        $time_end = microtime(true);
        $download_time = $time_end - $time_start;
        echo date("Y-m-d H:i:s")."\t";
        echo "DOWN\t$download_size_mb\t";
        echo $download_time."\t";
        echo ($download_size_mb/$download_time)."\n";
 
        $time_start = microtime(true);
        $cFile = curl_file_create($file_to_upload);
        $post = array('upload_file'=>$cFile);
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL,$upload_url);
        curl_setopt($ch, CURLOPT_POST,1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $result=curl_exec ($ch);
        curl_close ($ch);
 
        echo date("Y-m-d H:i:s")."\t";
        echo "UP\t$upload_size_mb\t";
        if($result == "OK") {
                $time_end = microtime(true);
                $upload_time = $time_end - $time_start;
                echo $upload_time."\t";
                echo (4/$upload_time)."\n";
        } else {
                echo "Error downloading ($result)\n";
        }
        sleep(60);
}
 
?>