def shcmd(cmd, input=None, check=True, keeperr=True): _, _, _, p = util.popen4(cmd) out, err = p.communicate(input) if check and p.returncode: raise error.Abort(cmd + " error: " + err) elif keeperr: out += err return out
def shcmd(cmd, input=None, check=True, keeperr=True): _, _, _, p = util.popen4(cmd) out, err = p.communicate(input) out = pycompat.decodeutf8(out, errors="replace") err = pycompat.decodeutf8(err, errors="replace") if check and p.returncode: raise error.Abort(cmd + " error: " + err) elif keeperr: out += err return out
def checkhgspeed(ui, url, opts): speedcmd = ui.config("debugnetwork", "speed-test-command") if speedcmd is None: ui.status( _("Not testing connection speed: 'debugnetwork.speed-test-command' is not set" ), component="debugnetwork", ) return True ui.status(_("Testing connection speed to the server\n"), component="debugnetwork") rui = hg.remoteui(ui, opts) sshcmd = rui.config("ui", "ssh") sshaddenv = dict(rui.configitems("sshenv")) sshenv = util.shellenviron(sshaddenv) args = util.sshargs(sshcmd, url.host, url.user, url.port) download = ui.configbytes("debugnetwork", "speed-test-download-size", 10000000) upload = ui.configbytes("debugnetwork", "speed-test-upload-size", 1000000) cmd = "%s %s %s" % (sshcmd, args, util.shellquote(sshpeer._serverquote(speedcmd))) pipeo, pipei, pipee, sub = util.popen4(cmd, bufsize=0, env=sshenv) pipee = sshpeer.threadedstderr(rui, pipee) pipee.start() def latencytest(count): # Use the upload endpoint for the latency test. We will time how long it # takes for the server to return the "upload complete" response for a # single byte upload. latencies = [] with progress.spinner(ui, "testing connection latency"): for i in range(count): pipeo.write(b"upload 1\n") pipeo.flush() l = pipei.readline() if l != b"upload bytes 1\n": raise error.Abort("invalid response from server: %r" % l) starttime = util.timer() pipeo.write(b"\n") pipeo.flush() l = pipei.readline() endtime = util.timer() if l != b"upload complete\n": raise error.Abort("invalid response from server: %r" % l) latencies.append(endtime - starttime) return latencies def downloadtest(description, bytecount): pipeo.write(b"download %i\n" % bytecount) pipeo.flush() l = pipei.readline() if not l or not l.startswith(b"download bytes"): raise error.Abort("invalid response from server: %r" % l) bytecount = int(l.split()[2]) with progress.bar(ui, description, total=bytecount, formatfunc=util.bytecount) as prog: starttime = util.timer() remaining = bytecount while remaining > 0: data = pipei.read(min(remaining, BLOCK_SIZE)) if not data: raise error.Abort( "premature end of speed-test download stream") remaining -= len(data) prog.value = bytecount - remaining l = pipei.readline() if not l or not l.startswith(b"download complete"): raise error.Abort("invalid response from server: %r" % l) endtime = util.timer() return endtime - starttime def uploadtest(description, bytecount): pipeo.write(b"upload %i\n" % bytecount) pipeo.flush() l = pipei.readline() if not l or not l.startswith(b"upload bytes"): raise error.Abort("invalid response from server: %r" % l) bytecount = int(l.split()[2]) with progress.bar(ui, description, total=bytecount, formatfunc=util.bytecount) as prog: starttime = util.timer() remaining = bytecount while remaining > 0: data = os.urandom(min(remaining, BLOCK_SIZE)) remaining -= len(data) pipeo.write(data) prog.value = bytecount - remaining pipeo.flush() l = pipei.readline() if not l or not l.startswith(b"upload complete"): raise error.Abort("invalid response from server: %r" % l) endtime = util.timer() return endtime - starttime return drivespeedtests( ui, (latencytest, 5), (downloadtest, "download", download), (uploadtest, "upload", upload), )
def checkhgspeed(ui, url, opts): speedcmd = ui.config("debugnetwork", "speed-test-command") if speedcmd is None: ui.status( _("Not testing connection speed: 'debugnetwork.speed-test-command' is not set" ), component="debugnetwork", ) return True ui.status(_("Testing connection speed to the server\n"), component="debugnetwork") rui = hg.remoteui(ui, opts) sshcmd = rui.config("ui", "ssh") sshaddenv = dict(rui.configitems("sshenv")) sshenv = util.shellenviron(sshaddenv) args = util.sshargs(sshcmd, url.host, url.user, url.port) download = ui.configbytes("debugnetwork", "speed-test-download-size", 10000000) upload = ui.configbytes("debugnetwork", "speed-test-upload-size", 1000000) cmd = "%s %s %s" % (sshcmd, args, util.shellquote(sshpeer._serverquote(speedcmd))) pipeo, pipei, pipee, sub = util.popen4(cmd, bufsize=0, env=sshenv) pipee = sshpeer.threadedstderr(rui, pipee) pipee.start() def latencytest(count): # Use the upload endpoint for the latency test. We will time how long it # takes for the server to return the "upload complete" response for a # single byte upload. latencies = [] with progress.spinner(ui, "testing connection latency"): for i in range(count): pipeo.write("upload 1\n") pipeo.flush() l = pipei.readline() if l != "upload bytes 1\n": raise error.Abort("invalid response from server: %r" % l) starttime = util.timer() pipeo.write("\n") pipeo.flush() l = pipei.readline() endtime = util.timer() if l != "upload complete\n": raise error.Abort("invalid response from server: %r" % l) latencies.append(endtime - starttime) return latencies def downloadtest(description, bytecount): pipeo.write("download %s\n" % bytecount) pipeo.flush() l = pipei.readline() if not l or not l.startswith("download bytes"): raise error.Abort("invalid response from server: %r" % l) bytecount = int(l.split()[2]) with progress.bar(ui, description, total=bytecount, formatfunc=util.bytecount) as prog: starttime = util.timer() remaining = bytecount while remaining > 0: data = pipei.read(min(remaining, BLOCK_SIZE)) if not data: raise error.Abort( "premature end of speed-test download stream") remaining -= len(data) prog.value = bytecount - remaining l = pipei.readline() if not l or not l.startswith("download complete"): raise error.Abort("invalid response from server: %r" % l) endtime = util.timer() return endtime - starttime def uploadtest(description, bytecount): pipeo.write("upload %s\n" % bytecount) pipeo.flush() l = pipei.readline() if not l or not l.startswith("upload bytes"): raise error.Abort("invalid response from server: %r" % l) bytecount = int(l.split()[2]) with progress.bar(ui, description, total=bytecount, formatfunc=util.bytecount) as prog: starttime = util.timer() remaining = bytecount while remaining > 0: data = os.urandom(min(remaining, BLOCK_SIZE)) remaining -= len(data) pipeo.write(data) prog.value = bytecount - remaining pipeo.flush() l = pipei.readline() if not l or not l.startswith("upload complete"): raise error.Abort("invalid response from server: %r" % l) endtime = util.timer() return endtime - starttime def printresult(testname, bytecount, testtime): byterate = bytecount / testtime ui.status( _("Speed: %s %s in %s (%0.2f Mbit/s, %0.2f MiB/s)\n") % ( testname, util.bytecount(bytecount), util.timecount(testtime), 8 * byterate / 1000000, byterate / (1024 * 1024), ), component="debugnetwork", ) try: latencies = latencytest(5) latency = sum(latencies, 0) / len(latencies) ui.status( _("Latency: %s (average of %s round-trips)\n") % (util.timecount(latency), len(latencies)), component="debugnetwork", ) for testfunc, testname, bytecount in [ (downloadtest, "download", download), (uploadtest, "upload", upload), ]: warmuptime = testfunc("warming up for %s test" % testname, bytecount) if warmuptime < 0.2: # The network is sufficiently fast that we warmed up in <200ms. # To make the test more meaningful, increase the size of data # 25x (which should give a maximum test time of 5s). bytecount *= 25 warmuptime = testfunc( "warming up for large %s test" % testname, bytecount) printresult("(round 1) %sed" % testname, bytecount, warmuptime) testtime = testfunc(testname, bytecount) printresult("(round 2) %sed" % testname, bytecount, testtime) return True except Exception: return False