class _TestError:

    def _main_loop(self):
        return time.time() + 100, []

    def _very_long_callback(self):
        time.sleep(tc.TASK_INTERVAL*15)
        return time.time() + 100, []

    def _on_datagram_received(self, datagram):
        return time.time() + 100, []

    def _crashing_callback(self):
        raise Exception, 'Crash testing'

    def test_failed_join(self):
        self.lock = threading.RLock()
        self.reactor = ThreadedReactor(self._main_loop,
                                       tc.CLIENT_PORT,
                                       self._on_datagram_received,
                                       task_interval=tc.TASK_INTERVAL)
        self.reactor.s = _SocketMock(tc.TASK_INTERVAL)
#        self.reactor.start()
        self.reactor.call_asap(self._very_long_callback)
        time.sleep(tc.TASK_INTERVAL*2)
        assert_raises(Exception, self.reactor.stop)
Exemple #2
0
class TestSend:
    def _main_loop(self):
        return time.time() + 100, [DATAGRAM1]

    def _callback(self, value):
        with self.lock:
            self.callback_values.append(value)
        return time.time() + 100, [DATAGRAM2]

    def _on_datagram_received(self, datagram):
        with self.lock:
            self.datagrams_received.append(datagram)
        return time.time() + 100, [DATAGRAM3]

    def _crashing_callback(self):
        raise Exception, "Crash testing"

    def setup(self):
        self.main_loop_call_counter = 0
        self.callback_values = []
        self.datagrams_received = []

        self.lock = threading.RLock()
        self.reactor = ThreadedReactor(
            self._main_loop, tc.CLIENT_PORT, self._on_datagram_received, task_interval=tc.TASK_INTERVAL
        )
        self.reactor.s = _SocketMock()
        self.s = self.reactor.s
        self.reactor.start()

    def test_main_loop_send_data(self):
        time.sleep(tc.TASK_INTERVAL)
        eq_(self.s.get_datagrams_sent(), [DATAGRAM1])
        return

    def test_call_asap_send_data(self):
        time.sleep(tc.TASK_INTERVAL)
        eq_(self.s.get_datagrams_sent(), [DATAGRAM1])
        self.reactor.call_asap(self._callback, 1)
        time.sleep(tc.TASK_INTERVAL * 2)
        eq_(self.s.get_datagrams_sent(), [DATAGRAM1, DATAGRAM2])

    def test_on_datagram_received_send_data(self):
        time.sleep(tc.TASK_INTERVAL)
        eq_(self.s.get_datagrams_sent(), [DATAGRAM1])
        self.s.put_datagram_received(Datagram(DATA1, tc.SERVER_ADDR))
        time.sleep(tc.TASK_INTERVAL / 2)
        eq_(self.s.get_datagrams_sent(), [DATAGRAM1, DATAGRAM3])

    def teardown(self):
        self.reactor.stop()
class TestMinitwisted:

    def _main_loop(self):
        print 'main loop call'
        self.main_loop_call_counter += 1
        return time.time() + self.main_loop_delay, []

    def _main_loop_return_datagrams(self):
        return time.time() + self.main_loop_delay, [DATAGRAM1]

    def _callback(self, value):
        self.callback_values.append(value)
        return []

    def _very_long_callback(self, value):
        time.sleep(tc.TASK_INTERVAL*11)
        return []

    def _on_datagram_received(self, datagram):
        print 'on_datagram', datagram, datagram.data, datagram.addr
        self.datagrams_received.append(datagram)
        return time.time() + 100, []

    def _crashing_callback(self):
        raise CrashError, 'Crash testing'

    def setup(self):
        time.mock_mode()
        self.main_loop_call_counter = 0
        self.callback_values = []
        self.datagrams_received = []
        
        self.main_loop_delay = MAIN_LOOP_DELAY
        self.reactor = ThreadedReactor(self._main_loop,
                                       tc.CLIENT_PORT,
                                       self._on_datagram_received,
                                       task_interval=tc.TASK_INTERVAL)
        self.reactor.s = _SocketMock()
        #self.reactor.start() >> instead of usint start(), we use run_one_step()

    def test_call_main_loop(self):
        eq_(self.main_loop_call_counter, 0)
        self.reactor.run_one_step()
        # main_loop is called right away
        eq_(self.main_loop_call_counter, 1)
        self.reactor.run_one_step()
        # no events
        eq_(self.main_loop_call_counter, 1)
        time.sleep(self.main_loop_delay)
        self.reactor.run_one_step()
        # main_loop is called again after 
        eq_(self.main_loop_call_counter, 2)
        
    def test_call_asap(self):
        eq_(self.callback_values, [])
        self.reactor.call_asap(self._callback, 0)
        eq_(self.callback_values, []) # stil nothing
        self.reactor.run_one_step()
        eq_(self.callback_values, [0]) #callback triggered
        for i in xrange(1, 5):
            self.reactor.call_asap(self._callback, i)
            self.reactor.run_one_step()
            eq_(self.callback_values, range(i + 1))
    
    def test_minitwisted_crashed(self):
        self.reactor.call_asap(self._crashing_callback)
        assert_raises(CrashError, self.reactor.run_one_step)

    def test_on_datagram_received_callback(self):
        eq_(self.datagrams_received, [])
        self.reactor.run_one_step()
        eq_(self.datagrams_received, [])
        datagram = Datagram(DATA1, tc.SERVER_ADDR)
        # This is equivalent to sending a datagram to reactor
        self.reactor.s.put_datagram_received(datagram)
        self.reactor.run_one_step()
        eq_(len(self.datagrams_received), 1)
        eq_(self.datagrams_received[0], datagram)

    def test_block_flood(self):
        from floodbarrier import MAX_PACKETS_PER_PERIOD as FLOOD_LIMIT
        for _ in xrange(FLOOD_LIMIT * 2):
            self.reactor.s.put_datagram_received(Datagram(DATA1, tc.SERVER_ADDR))
        for i in xrange(FLOOD_LIMIT): 
            eq_(len(self.datagrams_received), i)
            self.reactor.run_one_step()
        eq_(len(self.datagrams_received), FLOOD_LIMIT)
        for i in xrange(FLOOD_LIMIT):
            eq_(len(self.datagrams_received), FLOOD_LIMIT)
            logger.warning(
                "TESTING LOGS ** IGNORE EXPECTED WARNING **")
            self.reactor.run_one_step()
        eq_(len(self.datagrams_received), FLOOD_LIMIT)

    def test_network_and_callback(self):
        self.reactor.call_asap(self._callback, 1)
        eq_(self.main_loop_call_counter, 0)
        eq_(self.callback_values, [])
        time.sleep(.1)
        self.reactor.run_one_step()
        # call_asap and main_loop triggered
        eq_(self.callback_values, [1])
        eq_(self.main_loop_call_counter, 1)

        self.reactor.s.put_datagram_received(DATAGRAM1)
        eq_(self.datagrams_received, [])
        self.reactor.run_one_step()
        eq_(self.datagrams_received, [DATAGRAM1])

        self.reactor.call_asap(self._callback, 2)
        self.reactor.s.put_datagram_received(DATAGRAM3)
        self.reactor.run_one_step() # receive AND call_asap
        eq_(self.datagrams_received, [DATAGRAM1, DATAGRAM3])
        eq_(self.callback_values, [1, 2])

        
    def teardown(self):
        #self.reactor.stop() >> reactor is not really running
        time.normal_mode()
class TestSend:
    
    def _main_loop(self):
        return time.time() + MAIN_LOOP_DELAY, [DATAGRAM1]

    def _callback(self, value):
        self.callback_values.append(value)
        return [DATAGRAM2]

    def _on_datagram_received(self, datagram):
        self.datagrams_received.append(datagram)
        return time.time() + MAIN_LOOP_DELAY, [DATAGRAM3]

    def _crashing_callback(self):
        raise CrashError, 'Crash testing'

    def setup(self):
        self.main_loop_call_counter = 0
        self.callback_values = []
        self.datagrams_received = []
        
        self.reactor = ThreadedReactor(self._main_loop,
                                       tc.CLIENT_PORT,
                                       self._on_datagram_received,
                                       task_interval=tc.TASK_INTERVAL)
        self.reactor.s = _SocketMock()
        
    def test_main_loop_send_data(self):
        eq_(self.reactor.s.get_datagrams_sent(), [])
        self.reactor.run_one_step()
        # main_loop sends DATAGRAM1
        eq_(self.reactor.s.get_datagrams_sent(), [DATAGRAM1])
    
    def test_call_asap_send_data(self):
        self.reactor.run_one_step()
        eq_(self.reactor.s.get_datagrams_sent(), [DATAGRAM1])
        self.reactor.call_asap(self._callback, 1)
        self.reactor.run_one_step()
        eq_(self.reactor.s.get_datagrams_sent(), [DATAGRAM1, DATAGRAM2])
        
    def test_on_datagram_received_send_data(self): 
        self.reactor.run_one_step()
        eq_(self.reactor.s.get_datagrams_sent(), [DATAGRAM1])
        self.reactor.s.put_datagram_received(Datagram(DATA1, tc.SERVER_ADDR))
        self.reactor.run_one_step()
        eq_(self.reactor.s.get_datagrams_sent(), [DATAGRAM1, DATAGRAM3])
        
    def test_capture(self):
        self.reactor.start_capture()
        ts1 = time.time()
        time.sleep(tc.TASK_INTERVAL/2)
        # out > DATAGRAM1 (main_loop)
        self.reactor.run_one_step()
        ts2 = time.time()
        incoming_datagram = Datagram(DATA1, tc.SERVER_ADDR)
        self.reactor.s.put_datagram_received(incoming_datagram)
        time.sleep(tc.TASK_INTERVAL/2)
        self.reactor.run_one_step() 
        # in < incoming_datagram (socket)
        # out > DATAGRAM3 (on_datagram_received)
        captured_msgs = self.reactor.stop_and_get_capture()

        eq_(len(captured_msgs), 3)
        for msg in  captured_msgs:
            print msg
        assert ts1 < captured_msgs[0][0] < ts2
        eq_(captured_msgs[0][1], tc.SERVER_ADDR)
        eq_(captured_msgs[0][2], True) #outgoing
        eq_(captured_msgs[0][3], DATA1)
        assert captured_msgs[1][0] > ts2
        eq_(captured_msgs[1][1], DATAGRAM1.addr)
        eq_(captured_msgs[1][2], False) #incoming
        eq_(captured_msgs[1][3], DATAGRAM1.data)
        assert captured_msgs[2][0] > captured_msgs[1][0]
        eq_(captured_msgs[2][1], DATAGRAM3.addr)
        eq_(captured_msgs[2][2], True) #outgoing
        eq_(captured_msgs[2][3], DATAGRAM3.data)
        
    def teardown(self):

        return
Exemple #5
0
class TestMinitwisted:
    def _main_loop(self):
        with self.lock:
            self.main_loop_call_counter += 1
        return time.time() + tc.TASK_INTERVAL * 10, []

    def _main_loop_return_datagrams(self):
        return time.time() + tc.TASK_INTERVAL * 10, [DATAGRAM1]

    def _callback(self, value):
        with self.lock:
            self.callback_values.append(value)
        return time.time() + 100, []

    def _very_long_callback(self, value):
        time.sleep(tc.TASK_INTERVAL * 11)

    def _on_datagram_received(self, datagram):
        print "on_datagram", datagram, datagram.data, datagram.addr
        with self.lock:
            self.datagrams_received.append(datagram)
        return time.time() + 100, []

    def _crashing_callback(self):
        raise Exception, "Crash testing"

    def setup(self):
        self.main_loop_call_counter = 0
        self.callback_values = []
        self.datagrams_received = []

        self.lock = threading.RLock()
        self.reactor = ThreadedReactor(
            self._main_loop, tc.CLIENT_PORT, self._on_datagram_received, task_interval=tc.TASK_INTERVAL
        )
        self.reactor.s = _SocketMock()
        self.s = self.reactor.s
        self.reactor.start()

    def test_call_main_loop(self):
        time.sleep(tc.TASK_INTERVAL)
        # main_loop is called right away
        with self.lock:
            # FIXME: this assert fails sometimes!!!!
            eq_(self.main_loop_call_counter, 1)
        time.sleep(0.1 + tc.TASK_INTERVAL)
        with self.lock:
            # FIXME: this crashes when recompiling
            eq_(self.main_loop_call_counter, 2)

    def test_call_asap(self):
        with self.lock:
            eq_(self.callback_values, [])
        self.reactor.call_asap(self._callback, 0)
        time.sleep(tc.TASK_INTERVAL * 2)
        with self.lock:
            eq_(self.callback_values, [0])

        for i in xrange(1, 5):
            self.reactor.call_asap(self._callback, i)
            time.sleep(tc.TASK_INTERVAL * 3)
            with self.lock:
                eq_(self.callback_values, range(i + 1))

    def test_minitwisted_crashed(self):
        self.reactor.call_asap(self._crashing_callback)
        time.sleep(tc.TASK_INTERVAL * 3)
        # from now on, the minitwisted thread is dead
        ok_(not self.reactor.running)

    def test_on_datagram_received_callback(self):
        # This is equivalent to sending a datagram to reactor
        self.s.put_datagram_received(Datagram(DATA1, tc.SERVER_ADDR))
        datagram = Datagram(DATA1, tc.SERVER_ADDR)
        print "--------------", datagram, datagram.data, datagram.addr
        time.sleep(tc.TASK_INTERVAL * 1)
        with self.lock:
            datagram = self.datagrams_received.pop(0)
            print "popped>>>>>>>>>>>>>>>", datagram
            eq_(datagram.data, DATA1)
            eq_(datagram.addr, tc.SERVER_ADDR)

    def test_block_flood(self):
        from floodbarrier import MAX_PACKETS_PER_PERIOD as FLOOD_LIMIT

        for _ in xrange(FLOOD_LIMIT):
            self.s.put_datagram_received(Datagram(DATA1, tc.SERVER_ADDR))
        time.sleep(tc.TASK_INTERVAL * 5)
        with self.lock:
            eq_(len(self.datagrams_received), FLOOD_LIMIT)
        for _ in xrange(10):
            self.s.put_datagram_received(Datagram(DATA1, tc.SERVER_ADDR))
            time.sleep(tc.TASK_INTERVAL * 3)
            with self.lock:
                eq_(len(self.datagrams_received), FLOOD_LIMIT)
                logger.warning("TESTING LOGS ** IGNORE EXPECTED WARNING **")

    def _test_network_and_delayed(self):
        # TODO
        self.client_r.call_later(0.2, self.callback_f, 0)
        self.client_r.call_asap(self.callback_f, 1)
        task2 = self.client_r.call_later(0.2, self.callback_f, 2)
        with self.lock:
            eq_(self.callback_order, [])
        time.sleep(0.1)

        with self.lock:
            logger.debug("callback_order: %s" % self.callback_order)
            assert self.callback_order == [1]
            self.callback_order = []
            assert not self.datagrams_received
        self.server_r.sendto(DATA, tc.CLIENT_PORT)
        time.sleep(0.02)  # wait for network interruption
        with self.lock:
            logger.debug("callback_order: %s" % self.callback_order)
            assert self.callback_order == []
            logger.debug("callback_order: %s" % self.callback_order)
            datagram = self.datagrams_received.pop(0)
            eq_(datagram.data, DATA)
            eq_(datagram.addr, tc.SERVER_ADDR)
            task2.cancel()  # inside critical region??
        time.sleep(0.1)  # wait for task 0 (task 2 should be cancelled)
        with self.lock:
            assert self.callback_order == [0]
            assert not self.datagrams_received

    def teardown(self):
        self.reactor.stop()