source file: /home/buildslave/tahoe/edgy/build/src/allmydata/web/reliability.py
file stats: 85 lines, 82 executed: 96.5% covered
coverage versus previous test: 0 lines added, 0 lines removed
    1. 
    2. from nevow import rend, inevow, tags as T
    3. reliability = None # might not be usable
    4. try:
    5.     from allmydata import reliability # requires NumPy
    6. except ImportError:
    7.     pass
    8. from allmydata.web.common import getxmlfile, get_arg
    9. 
   10. 
   11. DAY=24*60*60
   12. MONTH=31*DAY
   13. YEAR=365*DAY
   14. 
   15. def is_available():
   16.     if reliability:
   17.         return True
   18.     return False
   19. 
   20. def yandm(seconds):
   21.     return "%dy.%dm" % (int(seconds/YEAR), int( (seconds%YEAR)/MONTH))
   22. 
   23. class ReliabilityTool(rend.Page):
   24.     addSlash = True
   25.     docFactory = getxmlfile("reliability.xhtml")
   26. 
   27.     DEFAULT_PARAMETERS = [
   28.         ("drive_lifetime", "8Y", "time",
   29.          "Average drive lifetime"),
   30.         ("k", 3, "int",
   31.          "Minimum number of shares needed to recover the file"),
   32.         ("R", 7, "int",
   33.          "Repair threshold: repair will not occur until fewer than R shares "
   34.          "are left"),
   35.         ("N", 10, "int",
   36.          "Total number of shares of the file generated"),
   37.         ("delta", "1M", "time", "Amount of time between each simulation step"),
   38.         ("check_period", "1M", "time",
   39.          "How often to run the checker and repair if fewer than R shares"),
   40.         ("report_period", "3M", "time",
   41.          "Amount of time between result rows in this report"),
   42.         ("report_span", "5Y", "time",
   43.          "Total amount of time covered by this report"),
   44.         ]
   45. 
   46.     def parse_time(self, s):
   47.         if s.endswith("M"):
   48.             return int(s[:-1]) * MONTH
   49.         if s.endswith("Y"):
   50.             return int(s[:-1]) * YEAR
   51.         return int(s)
   52. 
   53.     def format_time(self, s):
   54.         if s%YEAR == 0:
   55.             return "%dY" % (s/YEAR)
   56.         if s%MONTH == 0:
   57.             return "%dM" % (s/MONTH)
   58.         return "%d" % s
   59. 
   60.     def get_parameters(self, ctx):
   61.         req = inevow.IRequest(ctx)
   62.         parameters = {}
   63.         for (name,default,argtype,description) in self.DEFAULT_PARAMETERS:
   64.             v = get_arg(ctx, name, default)
   65.             if argtype == "time":
   66.                 value = self.parse_time(v)
   67.             else:
   68.                 value = int(v)
   69.             parameters[name] = value
   70.         return parameters
   71. 
   72.     def renderHTTP(self, ctx):
   73.         self.parameters = self.get_parameters(ctx)
   74.         self.results = reliability.ReliabilityModel.run(**self.parameters)
   75.         return rend.Page.renderHTTP(self, ctx)
   76. 
   77.     def make_input(self, name, old_value):
   78.         return T.input(name=name, type="text", size="5",
   79.                        value=self.format_time(old_value))
   80. 
   81.     def render_forms(self, ctx, data):
   82.         f = T.form(action=".", method="get")
   83.         table = []
   84.         for (name,default_value,argtype,description) in self.DEFAULT_PARAMETERS:
   85.             old_value = self.parameters[name]
   86.             i = self.make_input(name, old_value)
   87.             table.append(T.tr[T.td[name+":"], T.td[i], T.td[description]])
   88.         go = T.input(type="submit", value="Recompute")
   89.         return [T.h2["Simulation Parameters:"],
   90.                 f[T.table[table], go],
   91.                 ]
   92. 
   93.     def data_simulation_table(self, ctx, data):
   94.         for row in self.results.samples:
   95.             yield row
   96. 
   97.     def render_simulation_row(self, ctx, row):
   98.         (when, unmaintained_shareprobs, maintained_shareprobs,
   99.          P_repaired_last_check_period,
  100.          cumulative_number_of_repairs,
  101.          cumulative_number_of_new_shares,
  102.          P_dead_unmaintained, P_dead_maintained) = row
  103.         ctx.fillSlots("t", yandm(when))
  104.         ctx.fillSlots("P_repair", "%.6f" % P_repaired_last_check_period)
  105.         ctx.fillSlots("P_dead_unmaintained", "%.6g" % P_dead_unmaintained)
  106.         ctx.fillSlots("P_dead_maintained", "%.6g" % P_dead_maintained)
  107.         return ctx.tag
  108. 
  109.     def render_report_span(self, ctx, row):
  110.         (when, unmaintained_shareprobs, maintained_shareprobs,
  111.          P_repaired_last_check_period,
  112.          cumulative_number_of_repairs,
  113.          cumulative_number_of_new_shares,
  114.          P_dead_unmaintained, P_dead_maintained) = self.results.samples[-1]
  115.         return ctx.tag[yandm(when)]
  116. 
  117.     def render_P_loss_unmaintained(self, ctx, row):
  118.         (when, unmaintained_shareprobs, maintained_shareprobs,
  119.          P_repaired_last_check_period,
  120.          cumulative_number_of_repairs,
  121.          cumulative_number_of_new_shares,
  122.          P_dead_unmaintained, P_dead_maintained) = self.results.samples[-1]
  123.         return ctx.tag["%.6g (%1.8f%%)" % (P_dead_unmaintained,
  124.                                            100*P_dead_unmaintained)]
  125. 
  126.     def render_P_loss_maintained(self, ctx, row):
  127.         (when, unmaintained_shareprobs, maintained_shareprobs,
  128.          P_repaired_last_check_period,
  129.          cumulative_number_of_repairs,
  130.          cumulative_number_of_new_shares,
  131.          P_dead_unmaintained, P_dead_maintained) = self.results.samples[-1]
  132.         return ctx.tag["%.6g (%1.8f%%)" % (P_dead_maintained,
  133.                                            100*P_dead_maintained)]
  134. 
  135.     def render_P_repair_rate(self, ctx, row):
  136.         (when, unmaintained_shareprobs, maintained_shareprobs,
  137.          P_repaired_last_check_period,
  138.          cumulative_number_of_repairs,
  139.          cumulative_number_of_new_shares,
  140.          P_dead_unmaintained, P_dead_maintained) = self.results.samples[-1]
  141.         freq = when / cumulative_number_of_repairs
  142.         return ctx.tag["%.6g" % freq]
  143. 
  144.     def render_P_repair_shares(self, ctx, row):
  145.         (when, unmaintained_shareprobs, maintained_shareprobs,
  146.          P_repaired_last_check_period,
  147.          cumulative_number_of_repairs,
  148.          cumulative_number_of_new_shares,
  149.          P_dead_unmaintained, P_dead_maintained) = self.results.samples[-1]
  150.         generated_shares = cumulative_number_of_new_shares / cumulative_number_of_repairs
  151.         return ctx.tag["%1.2f" % generated_shares]
  152. 
  153.