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)