class ServerTest(unittest.TestCase, AsynchroneMixin):

    def __init__(self):
        AsynchroneMixin.__init__(self)
        
    def setUp(self):
        # import here not to get twisted.internet.reactor imported too soon
        from solipsis.services.profile.network.manager import NetworkManager
        self.network = NetworkManager()
        self.network.on_new_peer(FakePeer("boby"))
        self.network.on_service_data("boby", "HELLO 127.0.0.1:1111")
        self.network.peers.start()
        
    def tearDown(self):
        self.network.peers.stop()

    def test_server(self):
        deferred = self.network.server.start_listening()
        ## TESTS ##
        def _on_test(result):
            # values set
            self.assertEquals(True, result)
            self.assertNotEquals(None, self.network.server.listener)
            self.assertNotEquals(None, self.network.server.public_ip)
            self.assertNotEquals(None, self.network.server.public_port)
            self.assertNotEquals(self.network.server.public_ip, self.network.server.local_ip)
            self.network.server.stop_listening()
        deferred.addCallbacks(_on_test, on_error)
        return deferred
    test_server.timeout = 10

    def test_connection(self):
        util.wait(self.network.server.start_listening(), timeout=10)
        # start client
        from twisted.internet import reactor
        factory = ReconnectingFactory(self.deferreds)
        connector = reactor.connectTCP("localhost",
                                       self.network.server.local_port,
                                       factory)
        # send ping
        self.wait(1)
        deferred = self.send(connector, "ping")
        ## TESTS ##
        def _on_test(result):
            self.assertEquals("pong", result)
            self.network.server.stop_listening()
            factory.stopTrying()
            factory.stopFactory()
            connector.disconnect()
            self.wait(1)
        deferred.addCallbacks(_on_test, on_error)
        return deferred
    test_connection.timeout = 10
class NetworkTest(unittest.TestCase, AsynchroneMixin):

    def __init__(self):
        AsynchroneMixin.__init__(self)
        
    def setUp(self):
        from solipsis.services.profile.network.manager import NetworkManager
        self.network = NetworkManager()
        util.wait(self.network.start(), timeout=10)
    setUp.timeout = 10
        
    def tearDown(self):
        del SecurityWarnings.instance()["boby"]
        self.network.stop()

    def test_intrusion(self):
        self.assert_(not SecurityWarnings.instance().has_key("boby"))
        self.network.get_profile("boby")
        self.network.get_blog_file("boby")
        self.network.get_shared_files("boby")
        self.network.get_files("boby", ["whatever"])
        self.assertEquals(4, SecurityWarnings.instance().count("boby"))
        self.network.on_service_data("boby", "HELLO 127.0.0.1:1111")
        self.assertEquals(4, SecurityWarnings.instance().count("boby"))

    def test_bad_init(self):
        self.assert_(not SecurityWarnings.instance().has_key("boby"))
        self.network.on_new_peer(FakePeer("boby"))
        self.network.on_service_data("boby", "bf 127.0.0.1:1111")
        self.network.on_service_data("boby", "REQUEST_PROFILE 127.0.0.1:1111")
        self.assertEquals(2, SecurityWarnings.instance().count("boby"))
        self.network.get_profile("boby")
        self.network.get_blog_file("boby")
        self.network.get_shared_files("boby")
        self.network.get_files("boby", ["whatever"])
        self.assertEquals(6, SecurityWarnings.instance().count("boby"))
class NetworkTest(BaseTest):

    def setUp(self):
        # create manager with small timeout (not to slow down test)
        self.network = NetworkManager()
        self.manager = self.network.peers
        self.manager.CHECKING_FREQUENCY = 0.2
        self.network.peers.start()

    def tearDown(self):
        # stop manager
        self.network.peers.stop()
        
    def test_network_manager(self):
        peer = peer_node.Peer("toto")
        self.assert_no_peer()
        # add peer
        self.network.on_new_peer(peer)
        self.assert_new_peer()
        # set peer information
        self.network.on_service_data("toto",
                                     "HELLO 127.0.0.1:23501 data youpi")
        self.assert_peer()
        # change peer
        self.network.on_change_peer(peer, "profile")
        self.assertEquals(True, self.manager.assert_id("toto"))
        self.assertEquals(True, self.manager.assert_ip("127.0.0.1"))
        self.network.on_service_data("toto",
                                     "HELLO 127.0.0.1:23501 data youpi")
        self.assert_peer()
        # lose peer
        self.manager.remote_ids["toto"].PEER_TIMEOUT = 0.5
        self.network.on_lost_peer("toto")
        self.assert_peer_lost()
        time.sleep(1)
        self.assert_no_peer()
class ClientTest(unittest.TestCase):

    def __init__(self, *args, **kwargs):
        write_test_profile()
        create_facade(PROFILE_TEST).load(directory=PROFILE_DIR)
        
    def setUp(self):
        # import here not to get twisted.internet.reactor imported too soon
        from solipsis.services.profile.network.manager import NetworkManager
        self.network = NetworkManager()
        util.wait(self.network.start(), timeout=10)
        self.network.on_new_peer(FakePeer("boby"))
        self.network.on_service_data(
            "boby", "HELLO 127.0.0.1:%s"% str(self.network.server.local_port))
        
    def tearDown(self):
        self.network.stop()

    def assert_profile(self, doc):
        """check validity of content"""
        self.assertEquals(u"atao", doc.get_pseudo())
        self.assertEquals(u"Mr", doc.get_title())
        self.assertEquals(u"manu", doc.get_firstname())
        self.assertEquals(u"breton", doc.get_lastname())
        self.assertEquals(QUESTION_MARK(), doc.get_photo())
        self.assertEquals(u"*****@*****.**", doc.get_email())
        self.assertEquals({'City': u'', 'color': u'blue', 'Country': u'',
                           'Favourite Book': u'', 'homepage': u'manu.com',
                           'Favourite Movie': u'', 'Studies': u''},
                          doc.get_custom_attributes())
        # peers
        peers = doc.get_peers()
        self.assertEquals(peers.has_key(PROFILE_BRUCE), True)
        self.assertEquals(peers[PROFILE_BRUCE].state, PeerDescriptor.FRIEND)
        self.assertEquals(peers[PROFILE_BRUCE].connected, False)

    def assert_blog(self, blog):
        self.assertEquals(blog.count_blogs(), 1)
        self.assertEquals(blog.get_blog(0).text, u"This is a test")
        self.assertEquals(blog.get_blog(0).count_blogs(), 0)

    def assert_files(self, files):
        shared_files = ["date.doc", "routage", "null", "TOtO.txt", "dummy.txt"]
        for container in files[TEST_DIR]:
            self.assert_(container.name in shared_files)
            if container.name == "date.txt":
                self.assertEquals("tagos", container._tag)

    def test_downloads(self):
        def _on_test_profile(result):
            self.assert_(result)
            self.assert_profile(result)
        deferred = self.network.get_profile("boby")
        util.wait(deferred.addCallbacks(_on_test_profile, on_error))
        def _on_test_blog(result):
            self.assert_(result)
            self.assert_blog(result)
        deferred = self.network.get_blog_file("boby")
        util.wait(deferred.addCallbacks(_on_test_blog, on_error))
        def _on_test_shared_files(result):
            self.assert_(result)
            self.assert_files(result)
        deferred = self.network.get_shared_files("boby")
        util.wait(deferred.addCallbacks(_on_test_shared_files, on_error))
        def _on_test_files(result):
            file_name = os.path.join(GENERATED_DIR, "arc en ciel 6.gif")
            self.assert_(os.path.exists(file_name))
            self.assertEquals(163564, os.stat(file_name)[6])
            file_name = os.path.join(GENERATED_DIR, "02_b_1280x1024.jpg")
            self.assert_(os.path.exists(file_name))
            self.assertEquals(629622, os.stat(file_name)[6])
            file_name = os.path.join(GENERATED_DIR, "pywin32-203.win32-py2.3.exe")
            self.assert_(os.path.exists(file_name))
            self.assertEquals(3718120, os.stat(file_name)[6])
            file_name = os.path.join(GENERATED_DIR, "Python-2.3.5.zip")
            self.assert_(os.path.exists(file_name))
            self.assertEquals(9769010, os.stat(file_name)[6])
        get_facade().share_files(DATA_DIR,
                                 ["arc en ciel 6.gif",
                                  "02_b_1280x1024.jpg",
                                  "pywin32-203.win32-py2.3.exe",
                                  "Python-2.3.5.zip"],
                                 share=True)
        set_prefs("download_repo", GENERATED_DIR)
        deferred = self.network.get_files("boby", [
            (DATA_DIR.split(os.sep) + ["arc en ciel 6.gif"], 163564),
            (DATA_DIR.split(os.sep) + ["02_b_1280x1024.jpg"], 629622),
            (DATA_DIR.split(os.sep) + ["pywin32-203.win32-py2.3.exe"], 3718120),
            (DATA_DIR.split(os.sep) + ["Python-2.3.5.zip"], 9769010)])
        return deferred.addCallbacks(_on_test_files, on_error)
    test_downloads.timeout = 15
Example #5
0
class Plugin(ServicePlugin):
    """This the working class for services plugins."""
    
    # Define 'service_api' as a CLASS attribute
    service_api = ClassAttribute()
    
    def Init(self, local_ip):
        """
        This method does any kind of concrete initialization stuff,
        rather than doing it in __init__.  Especially, the service_api
        must *not* be used in __init__, since all data relating to the
        plugin may not have been initialized on the API side.
        """
        self.host = local_ip
        self.port = random.randrange(7000, 7100)
        self.network = None
        self.editor_frame = None
        self.viewer_frame = None
        self.filter_frame = None
        self.peer_services = {}
        # declare actions
        self.MAIN_ACTION = {_("Edit Profile..."): self.modify_profile,
                            _("Filter Profiles..."): self.filter_profile,
                            }
        self.POINT_ACTIONS = {#"View all...": self.show_profile,
                              _("View profile..."): self.get_profile,
                              _("View blog..."): self.get_blog_file,
                              _("Get files..."): self.select_files,}

    # Service setup

    # FIXME: need to abstract action layer of plugins so that it does
    # not depend on navigator mode (in our case: netclient or
    # wxclient)
    def EnableBasic(self):
        """enable non graphic part"""
        set_solipsis_dir(self.service_api.GetDirectory())
        self.network = NetworkManager()
        self.activate(True)
        
    def Enable(self):
        """
        All real actions involved in initializing the service should
        be defined here, not in the constructor.  This includes
        e.g. opening sockets, collecting data from directories, etc.
        """
        import wx
        from solipsis.services.profile.gui.EditorFrame import EditorFrame
        from solipsis.services.profile.gui.ViewerFrame import ViewerFrame
        from solipsis.services.profile.gui.FilterFrame import FilterFrame
        set_solipsis_dir(self.service_api.GetDirectory())
        # init windows
        main_window = self.service_api.GetMainWindow()
        options = {}
        options["standalone"] = False
        self.editor_frame = EditorFrame(options, main_window, -1, "",
                                          plugin=self)
        self.viewer_frame = ViewerFrame(options, main_window, -1, "",
                                          plugin=self)
        self.filter_frame = FilterFrame(options, main_window, -1, "",
                                          plugin=self)
        # Set up main GUI hooks
        menu = wx.Menu()
        for action, method in self.MAIN_ACTION.iteritems():
            item_id = wx.NewId()
            menu.Append(item_id, _(action))
            wx.EVT_MENU(main_window, item_id, method)
        self.service_api.SetMenu(self.GetTitle(), menu)
        # launch network
        self.network = NetworkManager()
        self.activate(True)
    
    def Disable(self):
        """It is called when the user chooses to disable the service."""
        # ask for saving (ca not simply call Close() on editor frame
        # method because of multithreading and the frame is destroyed
        # before the user actually answer to the popup
        if self.editor_frame and self.editor_frame.modified:
            import wx
            self.editor_frame.do_modified(False)
            dlg = wx.MessageDialog(
                self.editor_frame,
                'Your profile has been modified. Do you want to save it?',
                'Saving Profile',
                wx.YES_NO | wx.ICON_INFORMATION)
            if dlg.ShowModal() == wx.ID_YES:
                get_facade()._desc.save()
        if self.filter_frame and self.filter_frame.modified:
            import wx
            self.filter_frame.do_modified(False)
            dlg = wx.MessageDialog(
                self.filter_frame,
                'Your filters have been modified. Do you want to save them?',
                'Saving Filters',
                wx.YES_NO | wx.ICON_INFORMATION)
            if dlg.ShowModal() == wx.ID_YES:
                get_filter_facade().save()
        self.activate(False)

    def activate(self, active=True):
        """eable/disable service"""
        if not active:
            self.network.stop()
            for peer_id in self.peer_services.keys():
                self.LostPeer(peer_id)
        else:
            self.network.start()
            for peer_id in self.peer_services.keys():
                self.NewPeer(*self.peer_services[peer_id])

    # Service methods
    def modify_profile(self, evt):
        """display profile once loaded"""
        if not self.editor_frame is None:
            self.editor_frame.Show()
            
    def filter_profile(self, evt):
        """display profile once loaded"""
        if not self.filter_frame is None:
            self.filter_frame.Show()
            
#     def show_profile(self, evt):
#         """display profile once loaded"""
#         if self.viewer_frame:
#             self.viewer_frame.Show()

    def get_profile(self, peer_id, deferred=None):
        """request downwload of profile"""
        on_done = self.network.get_profile(peer_id)
        if on_done != None:
            on_done.addCallback(self._on_new_profile, peer_id)
            on_done.addErrback(lambda x: display_error("Could not get profile: " + str(x)))
            deferred and on_done.chainDeferred(deferred)

    def get_blog_file(self, peer_id, deferred=None):
        """request downwload of blog"""
        on_done = self.network.get_blog_file(peer_id)
        if on_done != None:
            on_done.addCallback(self._on_new_blog, peer_id)
            on_done.addErrback(lambda x: display_error("Could not get blog: " + str(x)))
            deferred and on_done.chainDeferred(deferred)

    def select_files(self, peer_id, deferred=None):
        """request downwload of list of shared files"""
        on_done = self.network.get_shared_files(peer_id)
        if on_done != None:
            on_done.addCallback(self._on_shared_files, peer_id)
            on_done.addErrback(lambda x: display_error("Could not get shared files: " + str(x)))
            deferred and on_done.chainDeferred(deferred)

    def get_files(self, peer_id, file_descriptors):
        """request downwload of given files.

        file_descriptor is a list: [ [split path], size ]"""
        self.network.get_files(peer_id, file_descriptors)

    # callbacks methods
    def _on_new_profile(self, document, peer_id):
        """store and display file object corresponding to profile"""
        get_facade().fill_data(peer_id, document)
        return str(document)
            
    def _on_new_blog(self, blog, peer_id):
        """store and display file object corresponding to blog"""
        get_facade().fill_blog(peer_id, blog)
        return str(blog)
    
    def _on_shared_files(self, files, peer_id):
        """store and display file object corresponding to blog"""
        get_facade().fill_shared_files(peer_id, files)
        return str(files)

    # Service description methods
    def GetTitle(self):
        """Returns a short title of the plugin."""
        return _("Profile")

    def GetDescription(self):
        """Returns a short description of the plugin. """
        return _("Manage personal information and share it with people")

    def GetActions(self):
        """Returns an array of strings advertising possible actions
        with all peers, or None if no such action is allowed.
        """
        return [_(desc) for desc in self.MAIN_ACTION]

    def GetPointToPointActions(self):
        """Returns an array of strings advertising point-to-point
        actions with another peer, or None if point-to-point actions
        are not allowed.
        """
        return [_(desc) for desc in self.POINT_ACTIONS]

    def DescribeService(self, service):
        """
        Fills the Service object used to describe the service to other peers.
        """
        service.address = "%s:%d" % (self.host, self.port)

    # UI event responses
    def DoAction(self, it, deferred=None):
        """Called when the general action is invoked, if available."""
        # retreive corect method
        actions = self.MAIN_ACTION.values()
        # call method on peer
        actions[it](deferred)

    def DoPointToPointAction(self, it, peer, deferred=None):
        """Called when a point-to-point action is invoked, if available."""
        if get_facade() and get_facade()._activated:
            # retreive corect method
            actions = self.POINT_ACTIONS.values()
            # call method on peer
            actions[it](peer.id_, deferred)
        # service not activated, do nothing
        else:
            print "service not activated"
            

    # Peer management
    # FIXME: check really need to call network method
    def NewPeer(self, peer, service):
        """delegate to network"""
        self.peer_services[peer.id_] = (peer, service)
        if get_facade() and get_facade()._activated:
            self.network.on_new_peer(peer)

    def ChangedPeer(self, peer, service):
        """delegate to network"""
        self.peer_services[peer.id_] = (peer, service)
        if get_facade() and get_facade()._activated:
            self.network.on_change_peer(peer, service)

    def LostPeer(self, peer_id):
        """delegate to network"""
        del self.peer_services[peer_id]
        if get_facade() and get_facade()._activated:
            self.network.on_lost_peer(peer_id)
            get_facade().set_connected(peer_id, False)

    def GotServiceData(self, peer_id, data):
        """delegate to network"""
        if get_facade() and get_facade()._activated:
            self.network.on_service_data(peer_id, data)

    def ChangedNode(self, node):
        """need to update node_id"""
        # ChangedNode is call more than one time on change. Thus, be
        # careful not to do the job every time
        log("ChangedNode", node.pseudo)
        if get_facade() is None or get_facade()._desc.document.get_pseudo() != node.pseudo:
            # creation
            facade = create_facade(node.id_)
            filter_facade = create_filter_facade(node.id_)
            if not facade.load():
                log(
                    _(u"You have no profile yet for pseudo %s."% node.pseudo))
            if not filter_facade.load():
                log(
                    _(u"You have no filters defined yet for pseudo %s."% node.pseudo))
            facade.change_pseudo(node.pseudo)
            # updating views
            if self.editor_frame:
                facade.add_view(EditorView(facade._desc,
                                           self.editor_frame))
                self.editor_frame.on_change_facade()
                facade.add_view(ViewerView(facade._desc,
                                           self.viewer_frame))
                self.viewer_frame.on_change_facade()
            if self.filter_frame:
                filter_facade.add_view(FilterView(filter_facade._desc,
                                                  self.filter_frame))
                self.filter_frame.on_change_facade()
            log(_("Loaded data for %s"% node.pseudo))