Esempio n. 1
0
class TestChat(DCSATestCase):
    ###################################################################################################################
    # BASIC TESTS
    def test_should_start(self):
        self.c.start()
        self._registerStartedChatSession(self.c)

    def test_should_stop_if_started(self):
        self.test_should_start()
        self.c.stop()

    def test_should_raise_exception_if_not_started(self):
        self.assertRaises(Exception, self.c.stop)


    def test_should_open_listen_socket_on_start(self):
        self.test_should_start()
        self._try_to_connect(self.c.getListenAddress())


    def test_should_not_have_open_socket_until_start(self):
        self.assertRaises(socket.error, self._try_to_connect, self.c.getListenAddress())


    def test_should_close_socket_on_chat_stop(self):
        self.test_should_stop_if_started()
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.assertRaises(socket.error, s.connect, self.c.getListenAddress())

    def test_stop_should_reset_connected_status(self):
        self.c.start()
        assert(self.c._startComplete)
        time.sleep(0.1)
        self.c.stop()
        assert(not self.c._startComplete)

    def test_shouldnt_allow_multiple_instances_with_same_listen_address(self):
        self.test_should_start()
        self.c2 = Chat((Chat.DEFAULT_LISTEN_IP, getUnusedListenPort()))
        self.assertRaises(Exception, self.c2.start())

    def test_shouldnt_create_group_if_not_started(self):
        self.assertRaises(Exception, self.c.createGroup)

    def test_should_allow_multiple_instances_with_different_listen_address(self):
        self.test_should_start()
        self.c2 = Chat((Chat.DEFAULT_LISTEN_IP, getUnusedListenPort()))
        self.c2.start() 
        self._registerStartedChatSession(self.c2)
        self._try_to_connect(self.c2.getListenAddress())


    def test_should_be_able_to_create_group_if_not_already_in_a_group(self):
        self.test_should_start()
        self.c.createGroup()


    def test_shouldnt_allow_to_create_group_if_already_joined_a_group(self):
        self.test_agent_who_added_someone_should_turn_on_active_flag_if_new_user_receives_the_initial_updated_groupview_from_him()
        self.assertRaises(Exception, self.c2.createGroup())


    def test_shouldnt_be_able_to_create_group_if_already_created_a_group(self):
        self.test_should_be_able_to_create_group_if_not_already_in_a_group()
        self.assertRaises(Exception, self.c.createGroup())


    def test_should_be_able_to_join_group_if_not_already_in_a_group(self):
        self.test_should_allow_multiple_instances_with_different_listen_address()
        # Both "c" and "c2" are listening now
        self.c.createGroup()
        self.c.addUser(self.c2.getListenAddress())

    def test_new_user_should_initially_appear_offline_in_groupview_of_agent_that_added_him(self):
        self.test_should_allow_multiple_instances_with_different_listen_address()
        # Both "c" and "c2" are listening now
        self.c2.stop()
        self.assertRaises(socket.error, self._try_to_connect, self.c2.getListenAddress())
        time.sleep(0.1)
        self.c.createGroup()
        self.c.addUser(self.c2.getListenAddress())
        time.sleep(0.1)
        self.assertEqual(Chat.OFFLINE, self.c.userStatus(self.c2.getListenAddress()))


    def test_new_user_should_initially_appear_online_in_groupview_of_agent_that_added_him_if_online(self):
        self.test_should_be_able_to_join_group_if_not_already_in_a_group()
        time.sleep(0.1)
        self.assertEqual(Chat.ONLINE, self.c.userStatus(self.c2.getListenAddress()))
        
        
    def test_user_should_be_able_to_permanently_leave_the_group(self):
        self.test_new_user_should_initially_appear_online_in_groupview_of_agent_that_added_him_if_online()
        time.sleep(0.1)
        self.c2.leaveGroup()
        time.sleep(0.1)
        self.assertFalse(self.c2.getListenAddress() in self.c.groupView.getGroup())
        
    def test_should_log_at_leavers_log_when_user_leaves_group(self):
        self.test_user_should_be_able_to_permanently_leave_the_group()
        self.assertLogEntryContains('Left the group', self.c2._logfile)
    
    def test_should_log_at_others_log_when_user_leaves_group(self):
        self.test_user_should_be_able_to_permanently_leave_the_group()
        self.assertLogEntryContains('Member %s left the group' % str(self.c2.getListenAddress()), self.c._logfile)
        
    def test_new_user_should_receive_updated_groupview_command_from_agent_who_added_him(self):
        self.test_should_be_able_to_join_group_if_not_already_in_a_group()
        time.sleep(0.1)
        self.assertLogEntryContains('InitialGroupView received from %s' % str(self.c.getListenAddress()), self.c2._logfile)
        self.assertEqual(2, len(self.c2.groupView.getGroup()))        
        
            
    def test_agent_who_added_someone_should_turn_on_active_flag_if_new_user_receives_the_initial_updated_groupview_from_him(self):
        self.test_new_user_should_receive_updated_groupview_command_from_agent_who_added_him()
        self.assertEqual(Chat.ONLINE, self.c.userStatus(self.c2.getListenAddress()))
        
    
    def test_someone_who_is_logged_on_should_appear_as_online_in_other_agents_lists(self):
        self.test_agent_who_added_someone_should_turn_on_active_flag_if_new_user_receives_the_initial_updated_groupview_from_him()
        self.c3 = Chat((Chat.DEFAULT_LISTEN_IP, getUnusedListenPort()))
        self.c3.start()
        self._registerStartedChatSession(self.c3)
        self.c.addUser(self.c3.getListenAddress())
        time.sleep(0.5)
        assert(self.c3.address in self.c.getOnlineUsers())
        assert(self.c3.address in self.c2.getOnlineUsers())
    
    
    def test_should_periodically_ping_everyone_on_the_list_and_dont_notify_if_no_changes(self):
        self.test_agent_who_added_someone_should_turn_on_active_flag_if_new_user_receives_the_initial_updated_groupview_from_him()
        count = len(self.c.sentPackets)
        self.c.setPeriodicPingSleep(0.3)
        time.sleep(0.2 + PeriodicPingThread.POLL_INTERVAL)
        self.assertEqual(count, len(self.c.sentPackets))
    
    
    def test_should_periodically_ping_everyone_on_the_list_and_notify_if_changes(self):
        self._startThreeAgents()
        
        count = len(self.c.sentPackets)
        self.c3.logout()
        time.sleep(0.1)
        
        assert(self.c3.getListenAddress() in self.c.getOfflineUsers())
        assert(self.c3.getListenAddress() in self.c2.getOfflineUsers())
        
        self.c3.silentStart()
        
        self.c.setPeriodicPingSleep(0.3)
        time.sleep(0.5 + PeriodicPingThread.POLL_INTERVAL)
        
        self.c.setPeriodicPingSleep(60.0)
        
        assert(self.c3.getListenAddress() in self.c.getOnlineUsers())
        assert(self.c3.getListenAddress() in self.c2.getOnlineUsers())
        self.assertEqual('InitialGroupView', self.c3.receivedPackets()[-3].__class__.__name__)
        assert(len(self.c.sentPackets) > count)
        
        
    def test_should_properly_log_offline_members_that_are_now_online_at_others(self):
        self.test_should_periodically_ping_everyone_on_the_list_and_notify_if_changes()
        self.assertLogEntryContains('Member %s is online' % self.c3.getNick(), self.c._logfile)
        self.assertLogEntryContains('Member %s is online' % self.c3.getNick(), self.c2._logfile)
    
    
    def test_offline_agent_with_copy_of_groupview_should_try_connecting_to_everybody_in_his_list_after_logging_in(self):
        self._startThreeAgents()
        self.c.logout()
        time.sleep(0.1)
        self.c.silentStart() # don't try to connect to anyone but do open your listen port
        self.c2.logout()
        # now c3 is online and thinks c2 and c are both offline
        time.sleep(0.1)
        count1 = len(self.c.receivedPackets())
        count2 = len(self.c2.receivedPackets())
        count3 = len(self.c3.receivedPackets())
        
        self.c2.start()
        self._registerStartedChatSession(self.c2)
        time.sleep(0.1)
        assert((len(self.c.receivedPackets()) == count1 + 1) or (len(self.c3.receivedPackets()) == count3 + 1))
        

    def test_agent_should_list_online_agents(self):
        self.test_agent_who_added_someone_should_turn_on_active_flag_if_new_user_receives_the_initial_updated_groupview_from_him()
        assert(self.c2.getListenAddress() in self.c.getOnlineUsers())
        assert(self.c2.getListenAddress() not in self.c.getOfflineUsers())
    
    def test_agent_should_list_offline_agents(self):
        self.test_agent_who_added_someone_should_turn_on_active_flag_if_new_user_receives_the_initial_updated_groupview_from_him()
        self.c2.logout()
        time.sleep(0.1)
        assert(self.c2.getListenAddress() in self.c.getOfflineUsers())
        assert(self.c2.getListenAddress() not in self.c.getOnlineUsers())
    
    def test_should_ignore_messages_from_someone_not_in_the_group(self):
        self.test_should_be_able_to_create_group_if_not_already_in_a_group()
        self.c2 = Chat((Chat.DEFAULT_LISTEN_IP, getUnusedListenPort()))
        
        # send a message from c2 to c
        c1msgs = len(self.c.messages)
        c2rcv = len(self.c2.receivedPackets())
        c2nick = GroupView.defaultNickFromAddress(self.c2.getListenAddress())
        net.send(Message('hi', c2nick, 'lobby'), self.c2.getListenAddress(), self.c.getListenAddress())
        time.sleep(0.1)
        self.assertEqual(c1msgs, len(self.c.messages))
        self.assertEqual(c2rcv, len(self.c2.receivedPackets()))
        

    def test_shouldnt_be_able_to_create_group_if_already_joined_a_group(self):
        self.test_should_be_able_to_join_group_if_not_already_in_a_group()
        self.assertRaises(Exception, self.c2.createGroup())


    def test_should_send_updated_groupview_if_error_when_sending_message_to_supposedly_online_agent(self):
        self.test_someone_who_is_logged_on_should_appear_as_online_in_other_agents_lists()
        self.c3.stop()        
        self.c.sendMessage('hello world', 'lobby')
        time.sleep(0.1)

        assert(self.c3.getListenAddress() in self.c.getOfflineUsers())
        assert(self.c3.getListenAddress() in self.c2.getOfflineUsers())


    def test_broadcast_message_should_arrive_to_all_online_agents(self):
        self._startThreeAgents()
        time.sleep(0.1)
        self.c.sendMessage('hello world')
        time.sleep(0.1)
        self.assertEqual(1, len(self.c.messages))
        self.assertEqual(1, len(self.c2.messages))
        self.assertEqual(1, len(self.c3.messages))


    # LOGGING TESTS
    def test_should_log_chat_started(self):
        self.test_should_start()
        a = self.c.getListenAddress()
        self.assertLastLogEntryContains('Client started', self.c._logfile)
            
    def test_should_log_new_member_added(self):
        self.test_should_be_able_to_join_group_if_not_already_in_a_group()
        self.assertLogEntryContains('New member added %s' % str(self.c2.getListenAddress()), self.c._logfile)
    
    
    def test_should_log_joined_group(self):
        self.test_should_be_able_to_join_group_if_not_already_in_a_group()
        self.assertLogEntryContains('Joined Group through %s' % str(self.c.getListenAddress()), self.c2._logfile)
    
    def test_should_log_when_member_comes_online_at_others_log(self):
        self.test_new_user_should_receive_updated_groupview_command_from_agent_who_added_him()
        a = self.c2.getListenAddress()
        self.c3 = Chat((Chat.DEFAULT_LISTEN_IP, getUnusedListenPort()))
        self.c3.start()
        self._registerStartedChatSession(self.c3)
        time.sleep(0.1)
        self.c.addUser(self.c3.getListenAddress())
        time.sleep(0.1)
        self.assertLogEntryContains('New member added %s' % str(self.c3.getListenAddress()), self.c._logfile)
        

    def test_should_log_when_member_logs_out_at_members_log(self):
        self.test_agent_should_list_offline_agents()
        self.assertLogEntryContains('Logged out', self.c2._logfile)
        
    def test_should_log_when_member_logs_out_at_others_log(self):
        self.test_agent_should_list_offline_agents()
        self.assertLastLogEntryContains('Member %s logged out' % self.c2.getNick(), self.c._logfile)
        
    def test_should_log_updated_groupview_received(self):
        self.test_should_send_updated_groupview_if_error_when_sending_message_to_supposedly_online_agent()
        self.assertLogEntryContains('GroupUpdate received from %s' % self.c.getNick(), self.c2._logfile)
        
    def test_should_log_updated_groupview_sent(self):
        self.test_should_send_updated_groupview_if_error_when_sending_message_to_supposedly_online_agent()
        self.assertLogEntryContains('GroupUpdate sent', self.c._logfile)
        
        
    def test_should_log_member_turns_offline_violently(self):
        self.test_should_send_updated_groupview_if_error_when_sending_message_to_supposedly_online_agent()
        self.assertLogEntryContains('Member %s disconnected' % str(self.c3.getListenAddress()), self.c._logfile)
        
    
    def test_should_log_command_reception_from_unknown_agents(self):
        self.test_should_ignore_messages_from_someone_not_in_the_group()
        self.assertLogEntryContains('Packet received from unauthorized agent %s' % str(self.c2.getListenAddress()), self.c._logfile)
    
    
    def test_should_log_message_received(self):
        self.test_broadcast_message_should_arrive_to_all_online_agents()
        self.assertLogEntryContains('Message delivered from %s (#lobby): hello world' % self.c2.getNickOfAddress(self.c.getListenAddress()), self.c2._logfile)
        self.assertLogEntryContains('Message delivered from %s (#lobby): hello world' % self.c3.getNickOfAddress(self.c.getListenAddress()), self.c3._logfile)