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).
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.
<?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
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.
<?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:
<?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
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.
<?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); } ?>