home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / lib / python2.4 / site-packages / BitTorrent / RawServer.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2006-08-31  |  17.9 KB  |  805 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.4)
  3.  
  4. from bisect import insort
  5. import socket
  6. from cStringIO import StringIO
  7. from traceback import print_exc
  8. from errno import EWOULDBLOCK, ENOBUFS
  9.  
  10. try:
  11.     from select import poll, error, POLLIN, POLLOUT, POLLERR, POLLHUP
  12.     timemult = 1000
  13. except ImportError:
  14.     from selectpoll import poll, error, POLLIN, POLLOUT, POLLERR, POLLHUP
  15.     timemult = 1
  16.  
  17. from threading import Thread, Event
  18. from time import time, sleep
  19. import sys
  20. from random import randrange
  21. all = POLLIN | POLLOUT
  22.  
  23. class SingleSocket:
  24.     
  25.     def __init__(self, raw_server, sock, handler):
  26.         self.raw_server = raw_server
  27.         self.socket = sock
  28.         self.handler = handler
  29.         self.buffer = []
  30.         self.last_hit = time()
  31.         self.fileno = sock.fileno()
  32.         self.connected = False
  33.  
  34.     
  35.     def get_ip(self):
  36.         
  37.         try:
  38.             return self.socket.getpeername()[0]
  39.         except socket.error:
  40.             return 'no connection'
  41.  
  42.  
  43.     
  44.     def close(self):
  45.         sock = self.socket
  46.         self.socket = None
  47.         self.buffer = []
  48.         del self.raw_server.single_sockets[self.fileno]
  49.         self.raw_server.poll.unregister(sock)
  50.         sock.close()
  51.  
  52.     
  53.     def shutdown(self, val):
  54.         self.socket.shutdown(val)
  55.  
  56.     
  57.     def is_flushed(self):
  58.         return len(self.buffer) == 0
  59.  
  60.     
  61.     def write(self, s):
  62.         if not self.socket is not None:
  63.             raise AssertionError
  64.         self.buffer.append(s)
  65.         if len(self.buffer) == 1:
  66.             self.try_write()
  67.         
  68.  
  69.     
  70.     def try_write(self):
  71.         if self.connected:
  72.             
  73.             try:
  74.                 while self.buffer != []:
  75.                     amount = self.socket.send(self.buffer[0])
  76.                     if amount != len(self.buffer[0]):
  77.                         if amount != 0:
  78.                             self.buffer[0] = self.buffer[0][amount:]
  79.                         
  80.                         break
  81.                     
  82.                     del self.buffer[0]
  83.             except socket.error:
  84.                 e = None
  85.                 (code, msg) = e
  86.                 if code != EWOULDBLOCK:
  87.                     self.raw_server.dead_from_write.append(self)
  88.                     return None
  89.                 
  90.             except:
  91.                 code != EWOULDBLOCK
  92.             
  93.  
  94.         None<EXCEPTION MATCH>socket.error
  95.         if self.buffer == []:
  96.             self.raw_server.poll.register(self.socket, POLLIN)
  97.         else:
  98.             self.raw_server.poll.register(self.socket, all)
  99.  
  100.  
  101.  
  102. def default_error_handler(x):
  103.     print x
  104.  
  105.  
  106. class RawServer:
  107.     
  108.     def __init__(self, doneflag, timeout_check_interval, timeout, noisy = True, errorfunc = default_error_handler, maxconnects = 55):
  109.         self.timeout_check_interval = timeout_check_interval
  110.         self.timeout = timeout
  111.         self.poll = poll()
  112.         self.single_sockets = { }
  113.         self.dead_from_write = []
  114.         self.doneflag = doneflag
  115.         self.noisy = noisy
  116.         self.errorfunc = errorfunc
  117.         self.maxconnects = maxconnects
  118.         self.funcs = []
  119.         self.unscheduled_tasks = []
  120.         self.add_task(self.scan_for_timeouts, timeout_check_interval)
  121.  
  122.     
  123.     def add_task(self, func, delay):
  124.         self.unscheduled_tasks.append((func, delay))
  125.  
  126.     
  127.     def scan_for_timeouts(self):
  128.         self.add_task(self.scan_for_timeouts, self.timeout_check_interval)
  129.         t = time() - self.timeout
  130.         tokill = []
  131.         for s in self.single_sockets.values():
  132.             if s.last_hit < t:
  133.                 tokill.append(s)
  134.                 continue
  135.         
  136.         for k in tokill:
  137.             if k.socket is not None:
  138.                 self._close_socket(k)
  139.                 continue
  140.         
  141.  
  142.     
  143.     def bind(self, port, bind = '', reuse = False):
  144.         self.bindaddr = bind
  145.         server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  146.         if reuse:
  147.             server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  148.         
  149.         server.setblocking(0)
  150.         
  151.         try:
  152.             server.setsockopt(socket.IPPROTO_IP, socket.IP_TOS, 32)
  153.         except:
  154.             pass
  155.  
  156.         server.bind((bind, port))
  157.         server.listen(5)
  158.         self.poll.register(server, POLLIN)
  159.         self.server = server
  160.  
  161.     
  162.     def start_connection(self, dns, handler = None):
  163.         if handler is None:
  164.             handler = self.handler
  165.         
  166.         sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  167.         sock.setblocking(0)
  168.         
  169.         try:
  170.             sock.setsockopt(socket.IPPROTO_IP, socket.IP_TOS, 32)
  171.         except:
  172.             pass
  173.  
  174.         sock.bind((self.bindaddr, 0))
  175.         
  176.         try:
  177.             sock.connect_ex(dns)
  178.         except socket.error:
  179.             raise 
  180.         except Exception:
  181.             e = None
  182.             raise socket.error(str(e))
  183.  
  184.         self.poll.register(sock, POLLIN)
  185.         s = SingleSocket(self, sock, handler)
  186.         self.single_sockets[sock.fileno()] = s
  187.         return s
  188.  
  189.     
  190.     def handle_events(self, events):
  191.         for sock, event in events:
  192.             if sock == self.server.fileno():
  193.                 pass
  194.             None if event & (POLLHUP | POLLERR) != 0 else None<EXCEPTION MATCH>socket.error
  195.             s = self.single_sockets.get(sock)
  196.             if s is None:
  197.                 continue
  198.             
  199.             s.connected = True
  200.             if event & (POLLHUP | POLLERR) != 0:
  201.                 self._close_socket(s)
  202.                 continue
  203.             
  204.             if event & POLLIN != 0:
  205.                 
  206.                 try:
  207.                     s.last_hit = time()
  208.                     data = s.socket.recv(100000)
  209.                     if data == '':
  210.                         self._close_socket(s)
  211.                     else:
  212.                         s.handler.data_came_in(s, data)
  213.                 except socket.error:
  214.                     e = None
  215.                     (code, msg) = e
  216.                     if code != EWOULDBLOCK:
  217.                         self._close_socket(s)
  218.                         continue
  219.                     
  220.                 except:
  221.                     code != EWOULDBLOCK
  222.                 
  223.  
  224.             None<EXCEPTION MATCH>socket.error
  225.             if event & POLLOUT != 0 and s.socket is not None and not s.is_flushed():
  226.                 s.try_write()
  227.                 if s.is_flushed():
  228.                     s.handler.connection_flushed(s)
  229.                 
  230.             s.is_flushed()
  231.         
  232.  
  233.     
  234.     def pop_unscheduled(self):
  235.         
  236.         try:
  237.             while True:
  238.                 (func, delay) = self.unscheduled_tasks.pop()
  239.                 insort(self.funcs, (time() + delay, func))
  240.         except IndexError:
  241.             pass
  242.  
  243.  
  244.     
  245.     def listen_forever(self, handler):
  246.         self.handler = handler
  247.         
  248.         try:
  249.             while not self.doneflag.isSet():
  250.                 
  251.                 try:
  252.                     self.pop_unscheduled()
  253.                     if len(self.funcs) == 0:
  254.                         period = 2 ** 30
  255.                     else:
  256.                         period = self.funcs[0][0] - time()
  257.                     if period < 0:
  258.                         period = 0
  259.                     
  260.                     events = self.poll.poll(period * timemult)
  261.                     if self.doneflag.isSet():
  262.                         return None
  263.                     
  264.                     while len(self.funcs) > 0 and self.funcs[0][0] <= time():
  265.                         (garbage, func) = self.funcs[0]
  266.                         del self.funcs[0]
  267.                         
  268.                         try:
  269.                             func()
  270.                         continue
  271.                         except KeyboardInterrupt:
  272.                             print_exc()
  273.                             return None
  274.                             continue
  275.                             if self.noisy:
  276.                                 data = StringIO()
  277.                                 print_exc(file = data)
  278.                                 self.errorfunc(data.getvalue())
  279.                             
  280.                         
  281.  
  282.                         None<EXCEPTION MATCH>KeyboardInterrupt
  283.                     self._close_dead()
  284.                     self.handle_events(events)
  285.                     if self.doneflag.isSet():
  286.                         return None
  287.                     
  288.                     self._close_dead()
  289.                 continue
  290.                 except error:
  291.                     e = None
  292.                     if self.doneflag.isSet():
  293.                         return None
  294.                     
  295.                     
  296.                     try:
  297.                         (code, msg, desc) = e
  298.                     except:
  299.                         
  300.                         try:
  301.                             (code, msg) = e
  302.                         code = ENOBUFS
  303.  
  304.  
  305.                     if code == ENOBUFS:
  306.                         self.errorfunc('Have to exit due to the TCP stack flaking out')
  307.                         return None
  308.                     
  309.                     code == ENOBUFS
  310.                     except KeyboardInterrupt:
  311.                         print_exc()
  312.                         return None
  313.                         continue
  314.                         data = StringIO()
  315.                         print_exc(file = data)
  316.                         self.errorfunc(data.getvalue())
  317.                         continue
  318.                     
  319.                     None<EXCEPTION MATCH>KeyboardInterrupt
  320.                 for ss in self.single_sockets.values():
  321.                     ss.close()
  322.                 
  323.  
  324.             self.server.close()
  325.             return None
  326.  
  327.  
  328.     
  329.     def _close_dead(self):
  330.         while len(self.dead_from_write) > 0:
  331.             old = self.dead_from_write
  332.             self.dead_from_write = []
  333.             for s in old:
  334.                 if s.socket is not None:
  335.                     self._close_socket(s)
  336.                     continue
  337.             
  338.  
  339.     
  340.     def _close_socket(self, s):
  341.         sock = s.socket.fileno()
  342.         s.socket.close()
  343.         self.poll.unregister(sock)
  344.         del self.single_sockets[sock]
  345.         s.socket = None
  346.         s.handler.connection_lost(s)
  347.  
  348.  
  349.  
  350. class DummyHandler:
  351.     
  352.     def __init__(self):
  353.         self.external_made = []
  354.         self.data_in = []
  355.         self.lost = []
  356.  
  357.     
  358.     def external_connection_made(self, s):
  359.         self.external_made.append(s)
  360.  
  361.     
  362.     def data_came_in(self, s, data):
  363.         self.data_in.append((s, data))
  364.  
  365.     
  366.     def connection_lost(self, s):
  367.         self.lost.append(s)
  368.  
  369.     
  370.     def connection_flushed(self, s):
  371.         pass
  372.  
  373.  
  374.  
  375. def sl(rs, handler, port):
  376.     rs.bind(port)
  377.     Thread(target = rs.listen_forever, args = [
  378.         handler]).start()
  379.  
  380.  
  381. def loop(rs):
  382.     x = []
  383.     
  384.     def r(rs = rs, x = x):
  385.         rs.add_task(x[0], 0.10000000000000001)
  386.  
  387.     x.append(r)
  388.     rs.add_task(r, 0.10000000000000001)
  389.  
  390. beginport = 5000 + randrange(10000)
  391.  
  392. def test_starting_side_close():
  393.     
  394.     try:
  395.         fa = Event()
  396.         fb = Event()
  397.         da = DummyHandler()
  398.         sa = RawServer(fa, 100, 100)
  399.         loop(sa)
  400.         sl(sa, da, beginport)
  401.         db = DummyHandler()
  402.         sb = RawServer(fb, 100, 100)
  403.         loop(sb)
  404.         sl(sb, db, beginport + 1)
  405.         sleep(0.5)
  406.         ca = sa.start_connection(('127.0.0.1', beginport + 1))
  407.         sleep(1)
  408.         if not da.external_made == []:
  409.             raise AssertionError
  410.         if not da.data_in == []:
  411.             raise AssertionError
  412.         if not da.lost == []:
  413.             raise AssertionError
  414.         if not len(db.external_made) == 1:
  415.             raise AssertionError
  416.         cb = db.external_made[0]
  417.         del db.external_made[:]
  418.         if not db.data_in == []:
  419.             raise AssertionError
  420.         if not db.lost == []:
  421.             raise AssertionError
  422.         ca.write('aaa')
  423.         cb.write('bbb')
  424.         sleep(1)
  425.         if not da.external_made == []:
  426.             raise AssertionError
  427.         if not da.data_in == [
  428.             (ca, 'bbb')]:
  429.             raise AssertionError
  430.         del da.data_in[:]
  431.         if not da.lost == []:
  432.             raise AssertionError
  433.         if not db.external_made == []:
  434.             raise AssertionError
  435.         if not db.data_in == [
  436.             (cb, 'aaa')]:
  437.             raise AssertionError
  438.         del db.data_in[:]
  439.         if not db.lost == []:
  440.             raise AssertionError
  441.         ca.write('ccc')
  442.         cb.write('ddd')
  443.         sleep(1)
  444.         if not da.external_made == []:
  445.             raise AssertionError
  446.         if not da.data_in == [
  447.             (ca, 'ddd')]:
  448.             raise AssertionError
  449.         del da.data_in[:]
  450.         if not da.lost == []:
  451.             raise AssertionError
  452.         if not db.external_made == []:
  453.             raise AssertionError
  454.         if not db.data_in == [
  455.             (cb, 'ccc')]:
  456.             raise AssertionError
  457.         del db.data_in[:]
  458.         if not db.lost == []:
  459.             raise AssertionError
  460.         ca.close()
  461.         sleep(1)
  462.         if not da.external_made == []:
  463.             raise AssertionError
  464.         if not da.data_in == []:
  465.             raise AssertionError
  466.         if not da.lost == []:
  467.             raise AssertionError
  468.         if not db.external_made == []:
  469.             raise AssertionError
  470.         if not db.data_in == []:
  471.             raise AssertionError
  472.         if not db.lost == [
  473.             cb]:
  474.             raise AssertionError
  475.         del db.lost[:]
  476.     finally:
  477.         fa.set()
  478.         fb.set()
  479.  
  480.  
  481.  
  482. def test_receiving_side_close():
  483.     
  484.     try:
  485.         da = DummyHandler()
  486.         fa = Event()
  487.         sa = RawServer(fa, 100, 100)
  488.         loop(sa)
  489.         sl(sa, da, beginport + 2)
  490.         db = DummyHandler()
  491.         fb = Event()
  492.         sb = RawServer(fb, 100, 100)
  493.         loop(sb)
  494.         sl(sb, db, beginport + 3)
  495.         sleep(0.5)
  496.         ca = sa.start_connection(('127.0.0.1', beginport + 3))
  497.         sleep(1)
  498.         if not da.external_made == []:
  499.             raise AssertionError
  500.         if not da.data_in == []:
  501.             raise AssertionError
  502.         if not da.lost == []:
  503.             raise AssertionError
  504.         if not len(db.external_made) == 1:
  505.             raise AssertionError
  506.         cb = db.external_made[0]
  507.         del db.external_made[:]
  508.         if not db.data_in == []:
  509.             raise AssertionError
  510.         if not db.lost == []:
  511.             raise AssertionError
  512.         ca.write('aaa')
  513.         cb.write('bbb')
  514.         sleep(1)
  515.         if not da.external_made == []:
  516.             raise AssertionError
  517.         if not da.data_in == [
  518.             (ca, 'bbb')]:
  519.             raise AssertionError
  520.         del da.data_in[:]
  521.         if not da.lost == []:
  522.             raise AssertionError
  523.         if not db.external_made == []:
  524.             raise AssertionError
  525.         if not db.data_in == [
  526.             (cb, 'aaa')]:
  527.             raise AssertionError
  528.         del db.data_in[:]
  529.         if not db.lost == []:
  530.             raise AssertionError
  531.         ca.write('ccc')
  532.         cb.write('ddd')
  533.         sleep(1)
  534.         if not da.external_made == []:
  535.             raise AssertionError
  536.         if not da.data_in == [
  537.             (ca, 'ddd')]:
  538.             raise AssertionError
  539.         del da.data_in[:]
  540.         if not da.lost == []:
  541.             raise AssertionError
  542.         if not db.external_made == []:
  543.             raise AssertionError
  544.         if not db.data_in == [
  545.             (cb, 'ccc')]:
  546.             raise AssertionError
  547.         del db.data_in[:]
  548.         if not db.lost == []:
  549.             raise AssertionError
  550.         cb.close()
  551.         sleep(1)
  552.         if not da.external_made == []:
  553.             raise AssertionError
  554.         if not da.data_in == []:
  555.             raise AssertionError
  556.         if not da.lost == [
  557.             ca]:
  558.             raise AssertionError
  559.         del da.lost[:]
  560.         if not db.external_made == []:
  561.             raise AssertionError
  562.         if not db.data_in == []:
  563.             raise AssertionError
  564.         if not db.lost == []:
  565.             raise AssertionError
  566.     finally:
  567.         fa.set()
  568.         fb.set()
  569.  
  570.  
  571.  
  572. def test_connection_refused():
  573.     
  574.     try:
  575.         da = DummyHandler()
  576.         fa = Event()
  577.         sa = RawServer(fa, 100, 100)
  578.         loop(sa)
  579.         sl(sa, da, beginport + 6)
  580.         sleep(0.5)
  581.         ca = sa.start_connection(('127.0.0.1', beginport + 15))
  582.         sleep(1)
  583.         if not da.external_made == []:
  584.             raise AssertionError
  585.         if not da.data_in == []:
  586.             raise AssertionError
  587.         if not da.lost == [
  588.             ca]:
  589.             raise AssertionError
  590.         del da.lost[:]
  591.     finally:
  592.         fa.set()
  593.  
  594.  
  595.  
  596. def test_both_close():
  597.     
  598.     try:
  599.         da = DummyHandler()
  600.         fa = Event()
  601.         sa = RawServer(fa, 100, 100)
  602.         loop(sa)
  603.         sl(sa, da, beginport + 4)
  604.         sleep(1)
  605.         db = DummyHandler()
  606.         fb = Event()
  607.         sb = RawServer(fb, 100, 100)
  608.         loop(sb)
  609.         sl(sb, db, beginport + 5)
  610.         sleep(0.5)
  611.         ca = sa.start_connection(('127.0.0.1', beginport + 5))
  612.         sleep(1)
  613.         if not da.external_made == []:
  614.             raise AssertionError
  615.         if not da.data_in == []:
  616.             raise AssertionError
  617.         if not da.lost == []:
  618.             raise AssertionError
  619.         if not len(db.external_made) == 1:
  620.             raise AssertionError
  621.         cb = db.external_made[0]
  622.         del db.external_made[:]
  623.         if not db.data_in == []:
  624.             raise AssertionError
  625.         if not db.lost == []:
  626.             raise AssertionError
  627.         ca.write('aaa')
  628.         cb.write('bbb')
  629.         sleep(1)
  630.         if not da.external_made == []:
  631.             raise AssertionError
  632.         if not da.data_in == [
  633.             (ca, 'bbb')]:
  634.             raise AssertionError
  635.         del da.data_in[:]
  636.         if not da.lost == []:
  637.             raise AssertionError
  638.         if not db.external_made == []:
  639.             raise AssertionError
  640.         if not db.data_in == [
  641.             (cb, 'aaa')]:
  642.             raise AssertionError
  643.         del db.data_in[:]
  644.         if not db.lost == []:
  645.             raise AssertionError
  646.         ca.write('ccc')
  647.         cb.write('ddd')
  648.         sleep(1)
  649.         if not da.external_made == []:
  650.             raise AssertionError
  651.         if not da.data_in == [
  652.             (ca, 'ddd')]:
  653.             raise AssertionError
  654.         del da.data_in[:]
  655.         if not da.lost == []:
  656.             raise AssertionError
  657.         if not db.external_made == []:
  658.             raise AssertionError
  659.         if not db.data_in == [
  660.             (cb, 'ccc')]:
  661.             raise AssertionError
  662.         del db.data_in[:]
  663.         if not db.lost == []:
  664.             raise AssertionError
  665.         ca.close()
  666.         cb.close()
  667.         sleep(1)
  668.         if not da.external_made == []:
  669.             raise AssertionError
  670.         if not da.data_in == []:
  671.             raise AssertionError
  672.         if not da.lost == []:
  673.             raise AssertionError
  674.         if not db.external_made == []:
  675.             raise AssertionError
  676.         if not db.data_in == []:
  677.             raise AssertionError
  678.         if not db.lost == []:
  679.             raise AssertionError
  680.     finally:
  681.         fa.set()
  682.         fb.set()
  683.  
  684.  
  685.  
  686. def test_normal():
  687.     l = []
  688.     f = Event()
  689.     s = RawServer(f, 100, 100)
  690.     loop(s)
  691.     sl(s, DummyHandler(), beginport + 7)
  692.     s.add_task((lambda l = l: l.append('b')), 2)
  693.     s.add_task((lambda l = l: l.append('a')), 1)
  694.     s.add_task((lambda l = l: l.append('d')), 4)
  695.     sleep(1.5)
  696.     s.add_task((lambda l = l: l.append('c')), 1.5)
  697.     sleep(3)
  698.     if not l == [
  699.         'a',
  700.         'b',
  701.         'c',
  702.         'd']:
  703.         raise AssertionError
  704.     f.set()
  705.  
  706.  
  707. def test_catch_exception():
  708.     l = []
  709.     f = Event()
  710.     s = RawServer(f, 100, 100, False)
  711.     loop(s)
  712.     sl(s, DummyHandler(), beginport + 9)
  713.     s.add_task((lambda l = l: l.append('b')), 2)
  714.     s.add_task((lambda : 4 / 0), 1)
  715.     sleep(3)
  716.     if not l == [
  717.         'b']:
  718.         raise AssertionError
  719.     f.set()
  720.  
  721.  
  722. def test_closes_if_not_hit():
  723.     
  724.     try:
  725.         da = DummyHandler()
  726.         fa = Event()
  727.         sa = RawServer(fa, 2, 2)
  728.         loop(sa)
  729.         sl(sa, da, beginport + 14)
  730.         sleep(1)
  731.         db = DummyHandler()
  732.         fb = Event()
  733.         sb = RawServer(fb, 100, 100)
  734.         loop(sb)
  735.         sl(sb, db, beginport + 13)
  736.         sleep(0.5)
  737.         sa.start_connection(('127.0.0.1', beginport + 13))
  738.         sleep(1)
  739.         if not da.external_made == []:
  740.             raise AssertionError
  741.         if not da.data_in == []:
  742.             raise AssertionError
  743.         if not da.lost == []:
  744.             raise AssertionError
  745.         if not len(db.external_made) == 1:
  746.             raise AssertionError
  747.         del db.external_made[:]
  748.         if not db.data_in == []:
  749.             raise AssertionError
  750.         if not db.lost == []:
  751.             raise AssertionError
  752.         sleep(3.1000000000000001)
  753.         if not len(da.lost) == 1:
  754.             raise AssertionError
  755.         if not len(db.lost) == 1:
  756.             raise AssertionError
  757.     finally:
  758.         fa.set()
  759.         fb.set()
  760.  
  761.  
  762.  
  763. def test_does_not_close_if_hit():
  764.     
  765.     try:
  766.         fa = Event()
  767.         fb = Event()
  768.         da = DummyHandler()
  769.         sa = RawServer(fa, 2, 2)
  770.         loop(sa)
  771.         sl(sa, da, beginport + 12)
  772.         sleep(1)
  773.         db = DummyHandler()
  774.         sb = RawServer(fb, 100, 100)
  775.         loop(sb)
  776.         sl(sb, db, beginport + 13)
  777.         sleep(0.5)
  778.         sa.start_connection(('127.0.0.1', beginport + 13))
  779.         sleep(1)
  780.         if not da.external_made == []:
  781.             raise AssertionError
  782.         if not da.data_in == []:
  783.             raise AssertionError
  784.         if not da.lost == []:
  785.             raise AssertionError
  786.         if not len(db.external_made) == 1:
  787.             raise AssertionError
  788.         cb = db.external_made[0]
  789.         del db.external_made[:]
  790.         if not db.data_in == []:
  791.             raise AssertionError
  792.         if not db.lost == []:
  793.             raise AssertionError
  794.         cb.write('bbb')
  795.         sleep(0.5)
  796.         if not da.lost == []:
  797.             raise AssertionError
  798.         if not db.lost == []:
  799.             raise AssertionError
  800.     finally:
  801.         fa.set()
  802.         fb.set()
  803.  
  804.  
  805.