mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2025-01-30 16:13:58 +00:00
Get rid of check_speed
The motivation and justification here are roughly the same as for `check_memory`.
This commit is contained in:
parent
347377aaab
commit
1b8e013991
28
Makefile
28
Makefile
@ -142,31 +142,6 @@ count-lines:
|
||||
# src/allmydata/test/bench_dirnode.py
|
||||
|
||||
|
||||
# The check-speed and check-grid targets are disabled, since they depend upon
|
||||
# the pre-located $(TAHOE) executable that was removed when we switched to
|
||||
# tox. They will eventually be resurrected as dedicated tox environments.
|
||||
|
||||
# The check-speed target uses a pre-established client node to run a canned
|
||||
# set of performance tests against a test network that is also
|
||||
# pre-established (probably on a remote machine). Provide it with the path to
|
||||
# a local directory where this client node has been created (and populated
|
||||
# with the necessary FURLs of the test network). This target will start that
|
||||
# client with the current code and then run the tests. Afterwards it will
|
||||
# stop the client.
|
||||
#
|
||||
# The 'sleep 5' is in there to give the new client a chance to connect to its
|
||||
# storageservers, since check_speed.py has no good way of doing that itself.
|
||||
|
||||
##.PHONY: check-speed
|
||||
##check-speed: .built
|
||||
## if [ -z '$(TESTCLIENTDIR)' ]; then exit 1; fi
|
||||
## @echo "stopping any leftover client code"
|
||||
## -$(TAHOE) stop $(TESTCLIENTDIR)
|
||||
## $(TAHOE) start $(TESTCLIENTDIR)
|
||||
## sleep 5
|
||||
## $(TAHOE) @src/allmydata/test/check_speed.py $(TESTCLIENTDIR)
|
||||
## $(TAHOE) stop $(TESTCLIENTDIR)
|
||||
|
||||
# The check-grid target also uses a pre-established client node, along with a
|
||||
# long-term directory that contains some well-known files. See the docstring
|
||||
# in src/allmydata/test/check_grid.py to see how to set this up.
|
||||
@ -195,12 +170,11 @@ test-clean:
|
||||
# Use 'make distclean' instead to delete all generated files.
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -rf build _trial_temp _test_memory .built
|
||||
rm -rf build _trial_temp .built
|
||||
rm -f `find src *.egg -name '*.so' -or -name '*.pyc'`
|
||||
rm -rf support dist
|
||||
rm -rf `ls -d *.egg | grep -vEe"setuptools-|setuptools_darcs-|darcsver-"`
|
||||
rm -rf *.pyc
|
||||
rm -f bin/tahoe bin/tahoe.pyscript
|
||||
rm -f *.pkg
|
||||
|
||||
.PHONY: distclean
|
||||
|
@ -1,234 +0,0 @@
|
||||
from __future__ import print_function
|
||||
|
||||
import os, sys
|
||||
from twisted.internet import reactor, defer
|
||||
from twisted.python import log
|
||||
from twisted.application import service
|
||||
from foolscap.api import Tub, fireEventually
|
||||
|
||||
MB = 1000000
|
||||
|
||||
class SpeedTest(object):
|
||||
DO_IMMUTABLE = True
|
||||
DO_MUTABLE_CREATE = True
|
||||
DO_MUTABLE = True
|
||||
|
||||
def __init__(self, test_client_dir):
|
||||
#self.real_stderr = sys.stderr
|
||||
log.startLogging(open("st.log", "a"), setStdout=False)
|
||||
f = open(os.path.join(test_client_dir, "private", "control.furl"), "r")
|
||||
self.control_furl = f.read().strip()
|
||||
f.close()
|
||||
self.base_service = service.MultiService()
|
||||
self.failed = None
|
||||
self.upload_times = {}
|
||||
self.download_times = {}
|
||||
|
||||
def run(self):
|
||||
print("STARTING")
|
||||
d = fireEventually()
|
||||
d.addCallback(lambda res: self.setUp())
|
||||
d.addCallback(lambda res: self.do_test())
|
||||
d.addBoth(self.tearDown)
|
||||
def _err(err):
|
||||
self.failed = err
|
||||
log.err(err)
|
||||
print(err)
|
||||
d.addErrback(_err)
|
||||
def _done(res):
|
||||
reactor.stop()
|
||||
return res
|
||||
d.addBoth(_done)
|
||||
reactor.run()
|
||||
if self.failed:
|
||||
print("EXCEPTION")
|
||||
print(self.failed)
|
||||
sys.exit(1)
|
||||
|
||||
def setUp(self):
|
||||
self.base_service.startService()
|
||||
self.tub = Tub()
|
||||
self.tub.setOption("expose-remote-exception-types", False)
|
||||
self.tub.setServiceParent(self.base_service)
|
||||
d = self.tub.getReference(self.control_furl)
|
||||
def _gotref(rref):
|
||||
self.client_rref = rref
|
||||
print("Got Client Control reference")
|
||||
return self.stall(5)
|
||||
d.addCallback(_gotref)
|
||||
return d
|
||||
|
||||
def stall(self, delay, result=None):
|
||||
d = defer.Deferred()
|
||||
reactor.callLater(delay, d.callback, result)
|
||||
return d
|
||||
|
||||
def record_times(self, times, key):
|
||||
print("TIME (%s): %s up, %s down" % (key, times[0], times[1]))
|
||||
self.upload_times[key], self.download_times[key] = times
|
||||
|
||||
def one_test(self, res, name, count, size, mutable):
|
||||
# values for 'mutable':
|
||||
# False (upload a different CHK file for each 'count')
|
||||
# "create" (upload different contents into a new SSK file)
|
||||
# "upload" (upload different contents into the same SSK file. The
|
||||
# time consumed does not include the creation of the file)
|
||||
d = self.client_rref.callRemote("speed_test", count, size, mutable)
|
||||
d.addCallback(self.record_times, name)
|
||||
return d
|
||||
|
||||
def measure_rtt(self, res):
|
||||
# use RIClient.get_nodeid() to measure the foolscap-level RTT
|
||||
d = self.client_rref.callRemote("measure_peer_response_time")
|
||||
def _got(res):
|
||||
assert len(res) # need at least one peer
|
||||
times = res.values()
|
||||
self.total_rtt = sum(times)
|
||||
self.average_rtt = sum(times) / len(times)
|
||||
self.max_rtt = max(times)
|
||||
print("num-peers: %d" % len(times))
|
||||
print("total-RTT: %f" % self.total_rtt)
|
||||
print("average-RTT: %f" % self.average_rtt)
|
||||
print("max-RTT: %f" % self.max_rtt)
|
||||
d.addCallback(_got)
|
||||
return d
|
||||
|
||||
def do_test(self):
|
||||
print("doing test")
|
||||
d = defer.succeed(None)
|
||||
d.addCallback(self.one_test, "startup", 1, 1000, False) #ignore this one
|
||||
d.addCallback(self.measure_rtt)
|
||||
|
||||
if self.DO_IMMUTABLE:
|
||||
# immutable files
|
||||
d.addCallback(self.one_test, "1x 200B", 1, 200, False)
|
||||
d.addCallback(self.one_test, "10x 200B", 10, 200, False)
|
||||
def _maybe_do_100x_200B(res):
|
||||
if self.upload_times["10x 200B"] < 5:
|
||||
print("10x 200B test went too fast, doing 100x 200B test")
|
||||
return self.one_test(None, "100x 200B", 100, 200, False)
|
||||
return
|
||||
d.addCallback(_maybe_do_100x_200B)
|
||||
d.addCallback(self.one_test, "1MB", 1, 1*MB, False)
|
||||
d.addCallback(self.one_test, "10MB", 1, 10*MB, False)
|
||||
def _maybe_do_100MB(res):
|
||||
if self.upload_times["10MB"] > 30:
|
||||
print("10MB test took too long, skipping 100MB test")
|
||||
return
|
||||
return self.one_test(None, "100MB", 1, 100*MB, False)
|
||||
d.addCallback(_maybe_do_100MB)
|
||||
|
||||
if self.DO_MUTABLE_CREATE:
|
||||
# mutable file creation
|
||||
d.addCallback(self.one_test, "10x 200B SSK creation", 10, 200,
|
||||
"create")
|
||||
|
||||
if self.DO_MUTABLE:
|
||||
# mutable file upload/download
|
||||
d.addCallback(self.one_test, "10x 200B SSK", 10, 200, "upload")
|
||||
def _maybe_do_100x_200B_SSK(res):
|
||||
if self.upload_times["10x 200B SSK"] < 5:
|
||||
print("10x 200B SSK test went too fast, doing 100x 200B SSK")
|
||||
return self.one_test(None, "100x 200B SSK", 100, 200,
|
||||
"upload")
|
||||
return
|
||||
d.addCallback(_maybe_do_100x_200B_SSK)
|
||||
d.addCallback(self.one_test, "1MB SSK", 1, 1*MB, "upload")
|
||||
|
||||
d.addCallback(self.calculate_speeds)
|
||||
return d
|
||||
|
||||
def calculate_speeds(self, res):
|
||||
# time = A*size+B
|
||||
# we assume that A*200bytes is negligible
|
||||
|
||||
if self.DO_IMMUTABLE:
|
||||
# upload
|
||||
if "100x 200B" in self.upload_times:
|
||||
B = self.upload_times["100x 200B"] / 100
|
||||
else:
|
||||
B = self.upload_times["10x 200B"] / 10
|
||||
print("upload per-file time: %.3fs" % B)
|
||||
print("upload per-file times-avg-RTT: %f" % (B / self.average_rtt))
|
||||
print("upload per-file times-total-RTT: %f" % (B / self.total_rtt))
|
||||
A1 = 1*MB / (self.upload_times["1MB"] - B) # in bytes per second
|
||||
print("upload speed (1MB):", self.number(A1, "Bps"))
|
||||
A2 = 10*MB / (self.upload_times["10MB"] - B)
|
||||
print("upload speed (10MB):", self.number(A2, "Bps"))
|
||||
if "100MB" in self.upload_times:
|
||||
A3 = 100*MB / (self.upload_times["100MB"] - B)
|
||||
print("upload speed (100MB):", self.number(A3, "Bps"))
|
||||
|
||||
# download
|
||||
if "100x 200B" in self.download_times:
|
||||
B = self.download_times["100x 200B"] / 100
|
||||
else:
|
||||
B = self.download_times["10x 200B"] / 10
|
||||
print("download per-file time: %.3fs" % B)
|
||||
print("download per-file times-avg-RTT: %f" % (B / self.average_rtt))
|
||||
print("download per-file times-total-RTT: %f" % (B / self.total_rtt))
|
||||
A1 = 1*MB / (self.download_times["1MB"] - B) # in bytes per second
|
||||
print("download speed (1MB):", self.number(A1, "Bps"))
|
||||
A2 = 10*MB / (self.download_times["10MB"] - B)
|
||||
print("download speed (10MB):", self.number(A2, "Bps"))
|
||||
if "100MB" in self.download_times:
|
||||
A3 = 100*MB / (self.download_times["100MB"] - B)
|
||||
print("download speed (100MB):", self.number(A3, "Bps"))
|
||||
|
||||
if self.DO_MUTABLE_CREATE:
|
||||
# SSK creation
|
||||
B = self.upload_times["10x 200B SSK creation"] / 10
|
||||
print("create per-file time SSK: %.3fs" % B)
|
||||
|
||||
if self.DO_MUTABLE:
|
||||
# upload SSK
|
||||
if "100x 200B SSK" in self.upload_times:
|
||||
B = self.upload_times["100x 200B SSK"] / 100
|
||||
else:
|
||||
B = self.upload_times["10x 200B SSK"] / 10
|
||||
print("upload per-file time SSK: %.3fs" % B)
|
||||
A1 = 1*MB / (self.upload_times["1MB SSK"] - B) # in bytes per second
|
||||
print("upload speed SSK (1MB):", self.number(A1, "Bps"))
|
||||
|
||||
# download SSK
|
||||
if "100x 200B SSK" in self.download_times:
|
||||
B = self.download_times["100x 200B SSK"] / 100
|
||||
else:
|
||||
B = self.download_times["10x 200B SSK"] / 10
|
||||
print("download per-file time SSK: %.3fs" % B)
|
||||
A1 = 1*MB / (self.download_times["1MB SSK"] - B) # in bytes per
|
||||
# second
|
||||
print("download speed SSK (1MB):", self.number(A1, "Bps"))
|
||||
|
||||
def number(self, value, suffix=""):
|
||||
scaling = 1
|
||||
if value < 1:
|
||||
fmt = "%1.2g%s"
|
||||
elif value < 100:
|
||||
fmt = "%.1f%s"
|
||||
elif value < 1000:
|
||||
fmt = "%d%s"
|
||||
elif value < 1e6:
|
||||
fmt = "%.2fk%s"; scaling = 1e3
|
||||
elif value < 1e9:
|
||||
fmt = "%.2fM%s"; scaling = 1e6
|
||||
elif value < 1e12:
|
||||
fmt = "%.2fG%s"; scaling = 1e9
|
||||
elif value < 1e15:
|
||||
fmt = "%.2fT%s"; scaling = 1e12
|
||||
elif value < 1e18:
|
||||
fmt = "%.2fP%s"; scaling = 1e15
|
||||
else:
|
||||
fmt = "huge! %g%s"
|
||||
return fmt % (value / scaling, suffix)
|
||||
|
||||
def tearDown(self, res):
|
||||
d = self.base_service.stopService()
|
||||
d.addCallback(lambda ignored: res)
|
||||
return d
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_client_dir = sys.argv[1]
|
||||
st = SpeedTest(test_client_dir)
|
||||
st.run()
|
Loading…
x
Reference in New Issue
Block a user