Skip to content

Commit

Permalink
Made it use Mbit by default.
Browse files Browse the repository at this point in the history
Added -mib option that allows switching back to mebabits.
Added -s option to suppress stderr output.
Implemented -w option to show CSV output in stdout at the end of the test.
Made some print functions.
Feel free to tidy it up. :)
  • Loading branch information
Janhouse committed Nov 10, 2012
1 parent ed592da commit 81d53ea
Showing 1 changed file with 93 additions and 40 deletions.
133 changes: 93 additions & 40 deletions tespeed.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@ def read(self, n=10240):
if self.num==0:
percent = float(down) / (self.total)
percent = round(percent*100, 2)
sys.stderr.write("Uploaded %d of %d bytes (%0.2f%%) in %d threads\r" %
print_debug("Uploaded %d of %d bytes (%0.2f%%) in %d threads\r" %
(down, self.total, percent, self.th))

#if down >= self.total:
# sys.stderr.write('\n')
# print_debug('\n')
# self.d['done']=1

return next
Expand All @@ -59,7 +59,7 @@ def __len__(self):

class TeSpeed:

def __init__(self, server = "", numTop = 0, store = False):
def __init__(self, server = "", numTop = 0, store = False, suppress = False, unit = False):

self.headers = {
'Accept' : 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
Expand All @@ -71,12 +71,22 @@ def __init__(self, server = "", numTop = 0, store = False):
}

self.server=server
#print >> sys.stderr, "Getting ready"
self.down_speed=-1
self.up_speed=-1
self.latencycount=10
self.bestServers=5

self.units="Mbit"
self.unit=0

if unit:
self.units="MiB"
self.unit=1

self.store=store
self.suppress=suppress
if store:
print >> sys.stderr, "Printing CSV formated results to STDOUT."
print_debug("Printing CSV formated results to STDOUT.\n")
self.numTop=int(numTop)
self.downList=['350x350', '500x500', '750x750', '1000x1000',
'1500x1500', '2000x2000', '2000x2000', '2500x2500', '3000x3000',
Expand Down Expand Up @@ -129,21 +139,23 @@ def Closest(self, center, points, num=5):

def TestLatency(self, servers):
# Finding the server with lowest latency
print >> sys.stderr, "Testing latency..."
print_debug("Testing latency...\n")
shortest = -1.0
po = []
for server in servers:
now=self.TestSingleLatency(server['url']+"latency.txt?x=" + str( time.time() ))*1000
now=now/2 # Evil hack or just pure stupidity? Nobody knows...
if now == -1 or now == 0:
continue
print >> sys.stderr, "%0.0f ms latency for %s (%s, %s, %s) [%0.2f km]" % (now, server['url'], server['sponsor'], server['name'], server['country'], server['distance'])
print_debug("%0.0f ms latency for %s (%s, %s, %s) [%0.2f km]\n" %
(now, server['url'], server['sponsor'], server['name'], server['country'], server['distance']))

if (now < shortest and shortest > 0) or shortest < 0:
shortest = now
po = server

print >> sys.stderr, "Best server with average latency %0.0fms - %s, %s, %s" % (shortest, po['sponsor'], po['name'], po['country'])
print_debug("Best server with average latency %0.0fms - %s, %s, %s\n" %
(shortest, po['sponsor'], po['name'], po['country']))

return po

Expand Down Expand Up @@ -200,15 +212,15 @@ def ChunkReport(self, bytes_so_far, chunk_size, total_size, num, th, d, w):
percent = float(down) / (total_size*th)
percent = round(percent*100, 2)

sys.stderr.write("Downloaded %d of %d bytes (%0.2f%%) in %d threads\r" %
print_debug("Downloaded %d of %d bytes (%0.2f%%) in %d threads\r" %
(down, total_size*th, percent, th))

#if down >= total_size*th:
# sys.stderr.write('\n')
# print_debug('\n')


def ChunkRead(self, response, num, th, d, w=0, chunk_size=10240, report_hook=None):
#print >> sys.stderr, "Thread num ", th, num, d, " starting to report\n"
#print_debug("Thread num %d %d %d starting to report\n" % (th, num, d))
if(w==1):
return [0,0,0]

Expand All @@ -220,7 +232,7 @@ def ChunkRead(self, response, num, th, d, w=0, chunk_size=10240, report_hook=Non
while 1:
chunk=0
if start == 0:
#print >> sys.stderr, "Started receiving data"
#print_debug("Started receiving data\n")
chunk = response.read(1)
start = time.time()

Expand Down Expand Up @@ -248,10 +260,10 @@ def AsyncGet(self, conn, uri, num, th, d):
response = urllib2.urlopen(request, timeout = 30);
size, start, end=self.ChunkRead(response, num, th, d, report_hook=self.ChunkReport)
#except urllib2.URLError, e:
# print >> sys.stderr, "Failed downloading."
# print_debug("Failed downloading.\n")
except:
sys.stderr.write(' \r')
print >> sys.stderr, "Failed downloading."
print_debug(' \r')
print_debug("Failed downloading.\n")
conn.send([0, 0, False])
conn.close()
return
Expand All @@ -272,10 +284,10 @@ def AsyncPost(self, conn, uri, num, th, d):
response = urllib2.urlopen(request, timeout = 30);
size, start, end=self.ChunkRead(response, num, th, d, 1, report_hook=self.ChunkReport)
#except urllib2.URLError, e:
# print >> sys.stderr, "Failed uploading."
# print_debug("Failed uploading.\n")
except:
sys.stderr.write(' \r')
print >> sys.stderr, "Failed uploading."
print_debug(' \r')
print_debug("Failed uploading.\n")
conn.send([0, 0, False])
conn.close()
return
Expand All @@ -286,7 +298,7 @@ def AsyncPost(self, conn, uri, num, th, d):

def LoadConfig(self):
# Load the configuration file
print >> sys.stderr, "Loading speedtest configuration..."
print_debug("Loading speedtest configuration...\n")
uri = "http://speedtest.net/speedtest-config.php?x=" + str( time.time() )
request=self.GetRequest(uri)
response = urllib2.urlopen(request)
Expand All @@ -300,14 +312,14 @@ def LoadConfig(self):
lat=float(config.find("client").attrib['lat'])
lon=float(config.find("client").attrib['lon'])

print >> sys.stderr, "IP: %s; Lat: %f; Lon: %f; ISP: %s" % (ip, lat, lon, isp)
print_debug("IP: %s; Lat: %f; Lon: %f; ISP: %s\n" % (ip, lat, lon, isp))

return { 'ip': ip, 'lat': lat, 'lon': lon, 'isp': isp }


def LoadServers(self):
# Load server list
print >> sys.stderr, "Loading server list..."
print_debug("Loading server list...\n")
uri = "http://speedtest.net/speedtest-servers.php?x=" + str( time.time() )
request=self.GetRequest(uri)
response = urllib2.urlopen(request);
Expand Down Expand Up @@ -340,10 +352,10 @@ def DecompressResponse(sefl, response):


def FindBestServer(self):
print >> sys.stderr, "Looking for closest and best server..."
print_debug("Looking for closest and best server...\n")
best=self.TestLatency(self.Closest([self.config['lat'], self.config['lon']], self.server_list, self.bestServers))
self.server=best['url']
print >> sys.stderr, "\033[94mBest server: ", self.server, "\033[0m"
#print_debug("\033[94mBest server: %s\033[0m\n" % (self.server))


def AsyncRequest(self, url, num, upload=0):
Expand All @@ -367,7 +379,7 @@ def AsyncRequest(self, url, num, upload=0):

end=time.time()

sys.stderr.write(' \r')
print_debug(' \r')

sizes=0
#tspeed=0
Expand Down Expand Up @@ -400,40 +412,62 @@ def TestUpload(self):
data=""
for i in range(0, len(self.upSizes)):
if len(data) == 0 or self.upSizes[i] != self.upSizes[i-1]:
#print >> sys.stderr, "Generating new string to upload. Length: ", self.upSizes[i]
#print_debug("Generating new string to upload. Length: %d\n" % (self.upSizes[i]))
data=''.join("1" for x in xrange(self.upSizes[i]))
self.postData=urllib.urlencode({'upload6': data })

sizes, took=self.AsyncRequest(url, (i<4 and 1 or (i<6 and 2 or (i<6 and 4 or 8))), 1)
if sizes==0:
continue
print >> sys.stderr, "Upload size: %0.2f MiB; Uploaded in %0.2f s" % (float(sizes)/1024/1024, took)
print >> sys.stderr, "\033[92mUpload speed: %0.2f MiB/s\033[0m" % ((float(sizes)/1024/1024)/took)

size=self.SpeedConversion(sizes)
speed=size/took
print_debug("Upload size: %0.2f MiB; Uploaded in %0.2f s\n" %
(size, took))
print_debug("\033[92mUpload speed: %0.2f %s/s\033[0m\n" %
(speed, self.units))

if self.up_speed<speed:
self.up_speed=speed

if took>5:
break

#print >> sys.stderr, "Upload size: %0.2f MiB; Uploaded in %0.2f s" % (float(sizes)/1024/1024, took)
#print >> sys.stderr, "Upload speed: %0.2f MiB/s" % ((float(sizes)/1024/1024)/took)
#print_debug("Upload size: %0.2f MiB; Uploaded in %0.2f s\n" % (self.SpeedConversion(sizes), took))
#print_debug("Upload speed: %0.2f MiB/s\n" % (self.SpeedConversion(sizes)/took))

def SpeedConversion(self, data):
if self.unit==1:
result=(float(data)/1024/1024)
else:
result=(float(data)/1024/1024)*1.048576*8
return result

def TestDownload(self):
# Testing download speed
sizes, took=[0,0]
for i in range(0, len(self.downList)):
url=self.server+"random"+self.downList[i]+".jpg?x=" + str( time.time() ) + "&y=3"
#print >> sys.stderr, url

sizes, took=self.AsyncRequest(url, (i<1 and 2 or (i<6 and 4 or (i<10 and 6 or 8))) )
if sizes==0:
continue
print >> sys.stderr, ("Download size: %0.2f MiB; Downloaded in %0.2f s") % (float(sizes)/1024/1024, took)
print >> sys.stderr, ("\033[91mDownload speed: %0.2f MiB/s\033[0m") % ((float(sizes)/1024/1024)/took)

size=self.SpeedConversion(sizes)
speed=size/took
print_debug("Download size: %0.2f MiB; Downloaded in %0.2f s\n" %
(size, took))
print_debug("\033[91mDownload speed: %0.2f %s/s\033[0m\n" %
(speed, self.units))

if self.down_speed<speed:
self.down_speed=speed

if took>5:
break

#print >> sys.stderr, "Download size: %0.2f MiB; Downloaded in %0.2f s" % (float(sizes)/1024/1024, took)
#print >> sys.stderr, "Download speed: %0.2f MiB/s" % ((float(sizes)/1024/1024)/took)
#print_debug("Download size: %0.2f MiB; Downloaded in %0.2f s\n" % (self.SpeedConversion(sizes), took))
#print_debug("Download speed: %0.2f %s/s\n" % (self.SpeedConversion(sizes)/took, self.units))

def TestSpeed(self):

Expand All @@ -451,30 +485,49 @@ def TestSpeed(self):
self.TestDownload()
self.TestUpload()

print_result("%0.2f,%0.2f,\"%s\",\"%s\"\n" % (self.down_speed, self.up_speed, self.units, self.server))

def ListServers(self, num=0):

allSorted=self.Closest([self.config['lat'], self.config['lon']], self.server_list, num)

for i in range(0, len(allSorted)):
print "%s. %s (%s, %s, %s) [%0.2f km]" % (i+1, allSorted[i]['url'], allSorted[i]['sponsor'], allSorted[i]['name'], allSorted[i]['country'], allSorted[i]['distance'])
print_result("%s. %s (%s, %s, %s) [%0.2f km]\n" %
(i+1, allSorted[i]['url'], allSorted[i]['sponsor'], allSorted[i]['name'], allSorted[i]['country'], allSorted[i]['distance']))

def print_debug(string):
if args.suppress!=True:
sys.stderr.write(string)
#return

def print_result(string):
if args.store==True:
sys.stdout.write(string)
#return

def main(args):

if args.listservers:
args.store=True

if args.listservers!=True and args.server=='' and args.store!=True:
print >> sys.stderr, "Getting ready. Use parameter -h or --help to see available features."
print_debug("Getting ready. Use parameter -h or --help to see available features.\n")
else:
print >> sys.stderr, "Getting ready"
print_debug("Getting ready\n")
try:
t=TeSpeed(args.listservers and 'list-servers' or args.server, args.listservers, args.store and True or False)
t=TeSpeed(args.listservers and 'list-servers' or args.server, args.listservers, args.store and True or False, args.suppress and True or False, args.unit and True or False)
except (KeyboardInterrupt, SystemExit):
print >> sys.stderr, "\nTesting stopped."
print_debug("\nTesting stopped.\n")
#raise

if __name__ == '__main__':
parser = argparse.ArgumentParser(description='TeSpeed, CLI SpeedTest.net')

parser.add_argument('server', nargs='?', type=str, default='', help='Use the specified server for testing (skip checking for location and closest server).')
parser.add_argument('-ls', '--list-servers', dest='listservers', nargs='?', default=0, const=10, help='List the servers sorted by distance, nearest first. Optionally specify number of servers to show.')
parser.add_argument('-w', '--csv', dest='store', action='store_const', const=True, help='Print CSV formated output to STDOUT')
parser.add_argument('-w', '--csv', dest='store', action='store_const', const=True, help='Print CSV formated output to STDOUT.')
parser.add_argument('-s', '--suppress', dest='suppress', action='store_const', const=True, help='Suppress debugging (STDERR) output.')
parser.add_argument('-mib', '--mebibit', dest='unit', action='store_const', const=True, help='Show results in mebibits.')

args = parser.parse_args()
main(args)

0 comments on commit 81d53ea

Please sign in to comment.