def get_size(self):
return self.size
def get_status(self):
- return "not impl yet" # TODO
+ # mention all outstanding segment requests
+ outstanding = set()
+ errorful = set()
+ for s_ev in self.segment_events:
+ (etype, segnum, when, segstart, seglen, decodetime) = s_ev
+ if etype == "request":
+ outstanding.add(segnum)
+ elif etype == "delivery":
+ outstanding.remove(segnum)
+ else: # "error"
+ outstanding.remove(segnum)
+ errorful.add(segnum)
+ def join(segnums):
+ if len(segnums) == 1:
+ return "segment %s" % list(segnums)[0]
+ else:
+ return "segments %s" % (",".join([str(i)
+ for i in sorted(segnums)]))
+ error_s = ""
+ if errorful:
+ error_s = "; errors on %s" % join(errorful)
+ if outstanding:
+ s = "fetching %s" % join(outstanding)
+ else:
+ s = "idle"
+ return s + error_s
+
def get_progress(self):
- return 0.1 # TODO
+ # measure all read events that aren't completely done, return the
+ # total percentage complete for them
+ if not self.read_events:
+ return 0.0
+ total_outstanding, total_received = 0, 0
+ for r_ev in self.read_events:
+ (start, length, ign1, finishtime, bytes, ign2, ign3) = r_ev
+ if finishtime is None:
+ total_outstanding += length
+ total_received += bytes
+ # else ignore completed requests
+ if not total_outstanding:
+ return 1.0
+ return 1.0 * total_received / total_outstanding
+
def using_helper(self):
return False
def get_active(self):
from allmydata.interfaces import NotEnoughSharesError, NoSharesError
from allmydata.immutable.downloader.common import BadSegmentNumberError, \
BadCiphertextHashError, DownloadStopped
+from allmydata.immutable.downloader.status import DownloadStatus
from allmydata.codec import CRSDecoder
from foolscap.eventual import fireEventually, flushEventualQueue
return d
d.addCallback(_uploaded)
return d
+
+class Status(unittest.TestCase):
+ def test_status(self):
+ now = 12345.1
+ ds = DownloadStatus("si-1", 123)
+ self.failUnlessEqual(ds.get_status(), "idle")
+ ds.add_segment_request(0, now)
+ self.failUnlessEqual(ds.get_status(), "fetching segment 0")
+ ds.add_segment_delivery(0, now+1, 0, 1000, 2.0)
+ self.failUnlessEqual(ds.get_status(), "idle")
+ ds.add_segment_request(2, now+2)
+ ds.add_segment_request(1, now+2)
+ self.failUnlessEqual(ds.get_status(), "fetching segments 1,2")
+ ds.add_segment_error(1, now+3)
+ self.failUnlessEqual(ds.get_status(),
+ "fetching segment 2; errors on segment 1")
+
+ def test_progress(self):
+ now = 12345.1
+ ds = DownloadStatus("si-1", 123)
+ self.failUnlessEqual(ds.get_progress(), 0.0)
+ e = ds.add_read_event(0, 1000, now)
+ self.failUnlessEqual(ds.get_progress(), 0.0)
+ e.update(500, 2.0, 2.0)
+ self.failUnlessEqual(ds.get_progress(), 0.5)
+ e.finished(now+2)
+ self.failUnlessEqual(ds.get_progress(), 1.0)
+
+ e1 = ds.add_read_event(1000, 2000, now+3)
+ e2 = ds.add_read_event(4000, 2000, now+3)
+ self.failUnlessEqual(ds.get_progress(), 0.0)
+ e1.update(1000, 2.0, 2.0)
+ self.failUnlessEqual(ds.get_progress(), 0.25)
+ e2.update(1000, 2.0, 2.0)
+ self.failUnlessEqual(ds.get_progress(), 0.5)
+ e1.update(1000, 2.0, 2.0)
+ e1.finished(now+4)
+ # now there is only one outstanding read, and it is 50% done
+ self.failUnlessEqual(ds.get_progress(), 0.5)
+ e2.update(1000, 2.0, 2.0)
+ e2.finished(now+5)
+ self.failUnlessEqual(ds.get_progress(), 1.0)