mirrortest 3.51 KB
Newer Older
1 2
#!/usr/bin/env python3
import threading, queue, time, re, os, tempfile
3 4
import aptsources.sourceslist
import aptsources.distro
5
from timeit import Timer
6
import urllib.request, urllib.parse, urllib.error
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
import socket
import random
socket.setdefaulttimeout(2)

class MirrorTest:
    class PingWorker(threading.Thread):
        def __init__(self, jobs, results, id):
            self.id = id
            self.jobs = jobs
            self.results = results
            self.match_result = re.compile(r"^rtt .* = [\.\d]+/([\.\d]+)/.*")
            threading.Thread.__init__(self)
        def run(self):
            result = None
            while MirrorTest.completed_pings < MirrorTest.todo:
                try:
                    mirror = self.jobs.get(True, 1)
                    host = mirror.hostname
                except:
                    continue
27
                print("Pinging (Worker %s) %s (%s) ..." % (self.id,
Ben Finney's avatar
Ben Finney committed
28
                                                           host,
29
                                                           MirrorTest.completed_pings))
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
                commando = os.popen("ping -q -c 4 -W 2 -i 0.3 %s" % host,
                                    "r")
                while True:
                    line = commando.readline()
                    if not line:
                        break
                    result = re.findall(self.match_result, line)
                MirrorTest.completed_pings_lock.acquire()
                MirrorTest.completed_pings += 1
                if result:
                    self.results.append([float(result[0]), host, mirror])
                MirrorTest.completed_pings_lock.release()

    def speed_test(self, mirror):
        url = "%s/%s" % (mirror.get_repo_urls()[0],
                         self.test_file)
46
        print("Downloading %s ..." % url)
47 48
        start = time.time()
        try:
49
            data = urllib.request.urlopen(url).read(51200)
50 51 52 53 54 55
            return 50 / (time.time() - start)
        except:
            return 0

    def __init__(self, hosts, test_file):
        self.test_file = test_file
56
        jobs = queue.Queue()
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
        results = []
        for h in hosts:
            jobs.put(h)
        self.threads = []
        MirrorTest.completed_pings = 0
        MirrorTest.completed_pings_lock = threading.Lock()
        MirrorTest.todo = len(hosts)

        for i in range(10):
            t = MirrorTest.PingWorker(jobs, results, i)
            self.threads.append(t)
            t.start()

        for t in self.threads:
            t.join()

        results.sort()
74
        print("\n\nTop ten RTTs:")
75
        for r in results[0:10]:
76 77
            print("%s: %s" % (r[1], r[0]))
        print("\n\n")
78 79 80 81

        results.insert(0, [0, "rand", hosts[random.randint(1, len(hosts))]])
        results.insert(0, [0, "rand", hosts[random.randint(1, len(hosts))]])

82
        final = [(self.speed_test(r[2]), r[2]) for r in results[0:12]]
83 84
        final.sort()
        final.reverse()
85
        print("\n\nBest mirrors:")
86
        for f in final:
87
            print("%s: %s KByte/s" % (f[1].hostname, int(f[0])))
88 89

if __name__ == "__main__":
90 91
    distro = aptsources.distro.get_distro()
    distro.get_sources(aptsources.sourceslist.SourcesList())
92 93 94 95 96 97 98 99
    pipe = os.popen("dpkg --print-architecture")
    arch = pipe.read().strip()
    test_file = "dists/%s/%s/binary-%s/Packages.gz" % \
                (distro.source_template.name,
                 distro.source_template.components[0].name,
                 arch)
    app = MirrorTest(distro.source_template.mirror_set.values(),
                     test_file)