web download-status: tolerate DYHBs that haven't retired yet. Fixes #1160.
authorBrian Warner <warner@lothar.com>
Mon, 9 Aug 2010 22:03:42 +0000 (15:03 -0700)
committerBrian Warner <warner@lothar.com>
Mon, 9 Aug 2010 22:51:00 +0000 (15:51 -0700)
Also add a better unit test for it.

src/allmydata/test/test_web.py
src/allmydata/web/status.py

index e2bd985072c037b73fb1b51b747aa85b80eee2b1..dfaaabda84485e8a5a8dd3a4a5bd9b3a73ec062f 100644 (file)
@@ -1,5 +1,5 @@
 
-import os.path, re, urllib
+import os.path, re, urllib, time
 import simplejson
 from StringIO import StringIO
 from twisted.application import service
@@ -74,9 +74,40 @@ class FakeUploader(service.Service):
     def get_helper_info(self):
         return (None, False)
 
+def build_one_ds():
+    ds = DownloadStatus("storage_index", 1234)
+    now = time.time()
+
+    ds.add_segment_request(0, now)
+    # segnum, when, start,len, decodetime
+    ds.add_segment_delivery(0, now+1, 0, 100, 0.5)
+    ds.add_segment_request(1, now+2)
+    ds.add_segment_error(1, now+3)
+
+    e = ds.add_dyhb_sent("serverid_a", now)
+    e.finished([1,2], now+1)
+    e = ds.add_dyhb_sent("serverid_b", now+2) # left unfinished
+
+    e = ds.add_read_event(0, 120, now)
+    e.update(60, 0.5, 0.1) # bytes, decrypttime, pausetime
+    e.finished(now+1)
+    e = ds.add_read_event(120, 30, now+2) # left unfinished
+
+    e = ds.add_request_sent("serverid_a", 1, 100, 20, now)
+    e.finished(20, now+1)
+    e = ds.add_request_sent("serverid_a", 1, 120, 30, now+1) # left unfinished
+
+    # make sure that add_read_event() can come first too
+    ds1 = DownloadStatus("storage_index", 1234)
+    e = ds1.add_read_event(0, 120, now)
+    e.update(60, 0.5, 0.1) # bytes, decrypttime, pausetime
+    e.finished(now+1)
+
+    return ds
+
 class FakeHistory:
     _all_upload_status = [upload.UploadStatus()]
-    _all_download_status = [DownloadStatus("storage_index", 1234)]
+    _all_download_status = [build_one_ds()]
     _all_mapupdate_statuses = [servermap.UpdateStatus()]
     _all_publish_statuses = [publish.PublishStatus()]
     _all_retrieve_statuses = [retrieve.RetrieveStatus()]
@@ -516,6 +547,11 @@ class Web(WebMixin, WebErrorMixin, testutil.StallMixin, testutil.ReallyEqualMixi
         def _check_dl(res):
             self.failUnless("File Download Status" in res, res)
         d.addCallback(_check_dl)
+        d.addCallback(lambda res: self.GET("/status/down-%d?t=json" % dl_num))
+        def _check_dl_json(res):
+            data = simplejson.loads(res)
+            self.failUnless(isinstance(data, dict))
+        d.addCallback(_check_dl_json)
         d.addCallback(lambda res: self.GET("/status/up-%d" % ul_num))
         def _check_ul(res):
             self.failUnless("File Upload Status" in res, res)
index 636a2db91f63709d1eb75440d60ff6ab7a352e3a..8af453c633f66398d22bd78c734089e083d2d74a 100644 (file)
@@ -413,7 +413,11 @@ class DownloadStatusPage(DownloadResultsRendererMixin, rend.Page):
         for d_ev in dyhb_events:
             (serverid, sent, shnums, received) = d_ev
             serverid_s = idlib.shortnodeid_b2a(serverid)
-            rtt = received - sent
+            rtt = None
+            if received is not None:
+                rtt = received - sent
+            if not shnums:
+                shnums = []
             t[T.tr(style="background: %s" % self.color(serverid))[
                 [T.td[serverid_s], T.td[srt(sent)], T.td[srt(received)],
                  T.td[",".join([str(shnum) for shnum in shnums])],
@@ -427,7 +431,6 @@ class DownloadStatusPage(DownloadResultsRendererMixin, rend.Page):
                T.td["speed"]]]
         for r_ev in self.download_status.read_events:
             (start, length, requesttime, finishtime, bytes, decrypt, paused) = r_ev
-            #print r_ev
             if finishtime is not None:
                 rtt = finishtime - requesttime - paused
                 speed = self.render_rate(None, 1.0 * bytes / rtt)