예제 #1
0
class AbstractDB(AbstractServer):
    def setUp(self):
        super(AbstractDB, self).setUp()

        # dummy session
        self.config = SessionStartupConfig()
        self.config.set_state_dir(self.getStateDir())
        self.config.set_torrent_checking(False)
        self.config.set_multicast_local_peer_discovery(False)
        self.config.set_megacache(False)
        self.config.set_dispersy(False)
        self.config.set_mainline_dht(False)
        self.config.set_torrent_collecting(False)
        self.config.set_libtorrent(False)
        self.config.set_dht_torrent_collecting(False)
        self.config.set_videoplayer(False)
        self.config.set_torrent_store(False)
        self.session = Session(self.config, ignore_singleton=True)

        dbpath = init_bak_tribler_sdb('bak_new_tribler.sdb',
                                      destination_path=self.getStateDir(),
                                      overwrite=True)
        self.sqlitedb = SQLiteCacheDB(self.session, busytimeout=BUSYTIMEOUT)
        self.sqlitedb.initialize(dbpath)
        self.session.sqlite_db = self.sqlitedb

    @blocking_call_on_reactor_thread
    def tearDown(self):
        self.sqlitedb.close()
        self.sqlitedb = None
        self.session.del_instance()
        self.session = None

        super(AbstractDB, self).tearDown(self)
    def setup_session_config(self):
        from Tribler.Core.SessionConfig import SessionStartupConfig

        config = SessionStartupConfig()
        config.set_install_dir(
            os.path.abspath(os.path.join(BASE_DIR, "tribler")))
        config.set_state_dir(
            os.path.abspath(
                os.path.join(BASE_DIR, "output", ".Tribler-%d") % getpid()))
        config.set_torrent_checking(False)
        config.set_multicast_local_peer_discovery(False)
        config.set_megacache(False)
        config.set_dispersy(True)
        config.set_mainline_dht(False)
        config.set_torrent_collecting(False)
        config.set_libtorrent(False)
        config.set_dht_torrent_collecting(False)
        config.set_enable_torrent_search(False)
        config.set_enable_channel_search(False)
        config.set_videoserver_enabled(False)
        config.set_http_api_enabled(False)
        config.set_upgrader_enabled(False)
        config.set_listen_port(20000 + self.scenario_runner._peernumber)

        if self.dispersy_port is None:
            self.dispersy_port = 21000 + self.scenario_runner._peernumber
        config.set_dispersy_port(self.dispersy_port)
        logging.error("Dispersy port set to %d" % self.dispersy_port)
        return config
예제 #3
0
class AbstractDB(AbstractServer):

    def setUp(self):
        super(AbstractDB, self).setUp()

        # dummy session
        self.config = SessionStartupConfig()
        self.config.set_state_dir(self.getStateDir())
        self.config.set_torrent_checking(False)
        self.config.set_multicast_local_peer_discovery(False)
        self.config.set_megacache(False)
        self.config.set_dispersy(False)
        self.config.set_mainline_dht(False)
        self.config.set_torrent_collecting(False)
        self.config.set_libtorrent(False)
        self.config.set_dht_torrent_collecting(False)
        self.config.set_videoplayer(False)
        self.config.set_torrent_store(False)
        self.session = Session(self.config, ignore_singleton=True)

        dbpath = init_bak_tribler_sdb('bak_new_tribler.sdb', destination_path=self.getStateDir(), overwrite=True)
        self.sqlitedb = SQLiteCacheDB(self.session, busytimeout=BUSYTIMEOUT)
        self.sqlitedb.initialize(dbpath)
        self.session.sqlite_db = self.sqlitedb

    @blocking_call_on_reactor_thread
    def tearDown(self):
        self.sqlitedb.close()
        self.sqlitedb = None
        self.session.del_instance()
        self.session = None

        super(AbstractDB, self).tearDown(self)
예제 #4
0
class TestSqliteCacheDB(AbstractServer):
    def setUp(self):
        super(TestSqliteCacheDB, self).setUp()
        self.config = SessionStartupConfig()
        self.config.set_state_dir(self.getStateDir())
        self.config.set_torrent_checking(False)
        self.config.set_multicast_local_peer_discovery(False)
        self.config.set_megacache(False)
        self.config.set_dispersy(False)
        self.config.set_mainline_dht(False)
        self.config.set_torrent_collecting(False)
        self.config.set_libtorrent(False)
        self.config.set_dht_torrent_collecting(False)
        self.config.set_videoplayer(False)
        self.session = Session(self.config, ignore_singleton=True)
        self.sqlitedb = None

    def tearDown(self):
        super(TestSqliteCacheDB, self).tearDown()
        if self.sqlitedb:
            self.sqlitedb.close()
        self.sqlitedb = None
        self.session.del_instance()
        self.session = None

    def test_upgrade_from_obsolete_version(self):
        """We no longer support DB versions older than 17 (Tribler 6.0)"""
        dbpath = init_bak_tribler_sdb(u"bak_old_tribler.sdb",
                                      destination_path=self.getStateDir(),
                                      overwrite=True)

        self.sqlitedb = SQLiteCacheDB(self.session)
        self.sqlitedb.initialize(dbpath)

        class MockTorrentStore(object):
            def flush():
                pass

            def close():
                pass

        db_migrator = DBUpgrader(self.session,
                                 self.sqlitedb,
                                 torrent_store=MockTorrentStore())
        self.assertRaises(VersionNoLongerSupportedError,
                          db_migrator.start_migrate)

    def test_upgrade_from_17(self):
        pass
예제 #5
0
class TestSqliteCacheDB(AbstractServer):

    def setUp(self):
        super(TestSqliteCacheDB, self).setUp()
        self.config = SessionStartupConfig()
        self.config.set_state_dir(self.getStateDir())
        self.config.set_torrent_checking(False)
        self.config.set_multicast_local_peer_discovery(False)
        self.config.set_megacache(False)
        self.config.set_dispersy(False)
        self.config.set_mainline_dht(False)
        self.config.set_torrent_collecting(False)
        self.config.set_libtorrent(False)
        self.config.set_dht_torrent_collecting(False)
        self.config.set_videoplayer(False)
        self.session = Session(self.config, ignore_singleton=True)
        self.sqlitedb = None

    def tearDown(self):
        super(TestSqliteCacheDB, self).tearDown()
        if self.sqlitedb:
            self.sqlitedb.close()
        self.sqlitedb = None
        self.session.del_instance()
        self.session = None

    def test_upgrade_from_obsolete_version(self):
        """We no longer support DB versions older than 17 (Tribler 6.0)"""
        dbpath = init_bak_tribler_sdb(u"bak_old_tribler.sdb", destination_path=self.getStateDir(), overwrite=True)

        self.sqlitedb = SQLiteCacheDB(self.session)
        self.sqlitedb.initialize(dbpath)

        class MockTorrentStore(object):

            def flush():
                pass

            def close():
                pass

        db_migrator = DBUpgrader(self.session, self.sqlitedb, torrent_store=MockTorrentStore())
        self.assertRaises(VersionNoLongerSupportedError, db_migrator.start_migrate)

    def test_upgrade_from_17(self):
        pass
예제 #6
0
class AbstractDB(TriblerCoreTest):
    def setUpPreSession(self):
        self.config = SessionStartupConfig()
        self.config.set_state_dir(self.getStateDir())
        self.config.set_torrent_checking(False)
        self.config.set_multicast_local_peer_discovery(False)
        self.config.set_megacache(False)
        self.config.set_dispersy(False)
        self.config.set_mainline_dht(False)
        self.config.set_torrent_collecting(False)
        self.config.set_libtorrent(False)
        self.config.set_dht_torrent_collecting(False)
        self.config.set_videoserver_enabled(False)
        self.config.set_torrent_store(False)

    @blocking_call_on_reactor_thread
    @inlineCallbacks
    def setUp(self):
        yield super(AbstractDB, self).setUp()

        self.setUpPreSession()
        self.session = Session(self.config, ignore_singleton=True)

        tar = tarfile.open(
            os.path.join(TESTS_DATA_DIR, 'bak_new_tribler.sdb.tar.gz'), 'r|gz')
        tar.extractall(self.session_base_dir)

        db_path = os.path.join(self.session_base_dir, 'bak_new_tribler.sdb')
        db_script_path = os.path.join(get_lib_path(), DB_SCRIPT_NAME)

        self.sqlitedb = SQLiteCacheDB(db_path,
                                      db_script_path,
                                      busytimeout=BUSYTIMEOUT)
        self.sqlitedb.initialize()
        self.session.sqlite_db = self.sqlitedb

    def tearDown(self):
        self.sqlitedb.close()
        self.sqlitedb = None
        self.session.del_instance()
        self.session = None

        super(AbstractDB, self).tearDown(self)
예제 #7
0
class TriblerSession(BaseManager):
    _sconfig = None
    _dispersy = None

    _running = False

    def _connect(self):
        """
        Copies the libswift and ffmpeg binaries when on Android.
        :return:
        """

        if not self._connected:
            self._connected = True

            # Copy the swift and ffmpeg binaries
            if is_android(strict=True):
                binaries = ['swift', 'ffmpeg']

                for binary in binaries:
                    _logger.info("Setting up the %s binary.." % binary)

                    if not self._copy_binary(binary):
                        _logger.error("Unable to find or copy the %s binary!" %
                                      binary)
        else:
            raise RuntimeError('TriblerSession already connected')

    def _xmlrpc_register(self, xmlrpc):
        """
        Register the public functions in this manager with an XML-RPC Manager.
        :param xmlrpc: The XML-RPC Manager it should register to.
        :return: Nothing.
        """
        xmlrpc.register_function(self.start_session, "tribler.start_session")
        xmlrpc.register_function(self.stop_session, "tribler.stop_session")

    def _copy_binary(self, binary_name):
        """
        Copy a binary, such as swift, from the sdcard (which is mounted with noexec) to the ANDROID_PRIVATE folder which
        does allow it. If the binary already exists, do nothing.
        :param binary_name: The name of the binary that should be copied.
        :return: Boolean indicating success.
        """
        # We are on android, setup the swift binary!
        sdcard_path = os.getcwd()
        binary_source = os.path.join(sdcard_path, binary_name)
        binary_dest = os.path.join(os.environ['ANDROID_PRIVATE'], binary_name)

        if not os.path.exists(binary_dest):
            if not os.path.exists(binary_source):
                _logger.error(
                    "Looked at %s and %s, but couldn't find a '%s' binary!" %
                    (binary_source, binary_dest, binary_name))
                return False

            _logger.warn("Copy '%s' binary (%s -> %s)" %
                         (binary_name, binary_source, binary_dest))
            shutil.copy2(binary_source, binary_dest)
            # TODO: Set a more conservative permission
            os.chmod(binary_dest, 0777)

        return True

    def get_session(self):
        """
        Get the current Tribler session.
        :return: Tribler session, or None if no session is started yet.
        """
        return self._session

    def start_session(self):
        """
        This function loads any previous configuration files from the TRIBLER_STATE_DIR environment variable and then
        starts a Tribler session.
        :return: Nothing.
        """
        if self._running:
            return False

        _logger.info("Set tribler_state_dir to %s" %
                     os.environ['TRIBLER_STATE_DIR'])

        # Load configuration file (if exists)
        cfgfilename = Session.get_default_config_filename(
            os.environ['TRIBLER_STATE_DIR'])
        try:
            self._sconfig = SessionStartupConfig.load(cfgfilename)
            _logger.info("Loaded previous configuration file from %s" %
                         cfgfilename)
        except:
            self._sconfig = SessionStartupConfig()
            self._sconfig.set_state_dir(os.environ['TRIBLER_STATE_DIR'])
            _logger.info(
                "No previous configuration file found, creating one in %s" %
                os.environ['TRIBLER_STATE_DIR'])

        # Set torrent collecting directory:
        dlcfgfilename = get_default_dscfg_filename(
            self._sconfig.get_state_dir())
        _logger.debug("main: Download config %s", dlcfgfilename)
        try:
            defaultDLConfig = DefaultDownloadStartupConfig.load(dlcfgfilename)
        except:
            defaultDLConfig = DefaultDownloadStartupConfig.getInstance()
        if not defaultDLConfig.get_dest_dir():
            defaultDLConfig.set_dest_dir(os.environ['TRIBLER_DOWNLOAD_DIR'])
            self._sconfig.set_torrent_collecting_dir(
                os.path.join(os.environ['TRIBLER_DOWNLOAD_DIR']))

        # Create download directory:
        if not os.path.isdir(defaultDLConfig.get_dest_dir()):
            try:
                _logger.info("Creating download directory: %s" %
                             defaultDLConfig.get_dest_dir())
                os.makedirs(defaultDLConfig.get_dest_dir())
            except:
                _logger.error("Couldn't create download directory! (%s)" %
                              defaultDLConfig.get_dest_dir())

        # TODO: This is temporary for testing:
        from jnius import autoclass
        python_activity = autoclass('org.renpy.android.PythonActivity')
        files_dir = python_activity.mActivity.getFilesDir().getAbsolutePath()
        install_dir = files_dir + u'/lib/python2.7/site-packages'
        _logger.info("Set tribler_install_dir to %s" % install_dir)
        self._sconfig.set_install_dir(install_dir)
        # TODO: ^End of temporary test.

        # Disable unwanted dependencies:
        self._sconfig.set_torrent_store(True)
        self._sconfig.set_torrent_checking(True)
        self._sconfig.set_multicast_local_peer_discovery(False)
        self._sconfig.set_mainline_dht(True)
        self._sconfig.set_dht_torrent_collecting(True)
        self._sconfig.set_torrent_collecting_max_torrents(5000)

        _logger.info("Starting Tribler session..")
        self._session = Session(self._sconfig)
        upgrader = self._session.prestart()
        while not upgrader.is_done:
            time.sleep(0.1)
        self._session.start()
        _logger.info("Tribler session started!")

        self._dispersy = self._session.get_dispersy_instance()
        self.define_communities()

    # Dispersy init communitites callback function
    @call_on_reactor_thread
    def define_communities(self):
        """
        Load the dispersy communities. This function must be run on the Twisted reactor thread.
        :return: Nothing.
        """
        integrate_with_tribler = True
        comm_args = {'integrate_with_tribler': integrate_with_tribler}

        from Tribler.community.search.community import SearchCommunity
        from Tribler.community.allchannel.community import AllChannelCommunity
        from Tribler.community.channel.community import ChannelCommunity
        from Tribler.community.channel.preview import PreviewChannelCommunity
        from Tribler.community.metadata.community import MetadataCommunity

        _logger.info("Preparing to load dispersy communities...")

        comm = self._dispersy.define_auto_load(SearchCommunity,
                                               self._session.dispersy_member,
                                               load=True,
                                               kargs=comm_args)
        _logger.debug("Currently loaded dispersy communities: %s" % comm)
        #comm = self._dispersy.define_auto_load(AllChannelCommunity, self._session.dispersy_member, load=True,
        #                                       kargs=comm_args)
        #_logger.debug("Currently loaded dispersy communities: %s" % comm)

        # load metadata community
        #comm = self._dispersy.define_auto_load(MetadataCommunity, self._session.dispersy_member, load=True,
        #                                      kargs=comm_args) # TODO: used to be kargs=comm_args, but MetadataCommunity uses _integrate_with_tribler (notice lower dash) and even that won't work
        _logger.info("@@@@@@@@@@ Loaded dispersy communities: %s" % comm)

        # 17/07/13 Boudewijn: the missing-member message send by the BarterCommunity on the swift port is crashing
        # 6.1 clients.  We will disable the BarterCommunity for version 6.2, giving people some time to upgrade
        # their version before enabling it again.
        # if swift_process:
        #     dispersy.define_auto_load(BarterCommunity,
        #                               s.dispersy_member,
        #                               (swift_process,),
        #                               load=True)

        #comm = self._dispersy.define_auto_load(ChannelCommunity, self._session.dispersy_member, load=True,
        #                                       kargs=comm_args)
        #_logger.debug("Currently loaded dispersy communities: %s" % comm)
        #comm = self._dispersy.define_auto_load(PreviewChannelCommunity, self._session.dispersy_member, kargs=comm_args)
        #_logger.debug("Currently loaded dispersy communities: %s" % comm)

        self._running = True

    def is_running(self):
        return self._running

    def stop_session(self):
        """
        Unloads the Tribler session.
        :return: Nothing.
        """
        _logger.info("Create checkpoint..")
        self._session.checkpoint()

        _logger.info("Shutting down Tribler..")
        self._session.shutdown()

        # Just a tad of extra time
        time.sleep(1)

        self._running = False
        _logger.info("Bye bye")

        return True
예제 #8
0
class TestLibtorrentDownloadImpl(TestAsServer):
    """
    This class provides unit tests that test the LibtorrentDownloadImpl class.
    """
    def setUpPreSession(self):
        super(TestLibtorrentDownloadImpl, self).setUpPreSession()
        self.config = SessionStartupConfig()
        self.config.set_state_dir(self.getStateDir())
        self.config.set_multicast_local_peer_discovery(False)
        self.config.set_megacache(True)
        self.config.set_dispersy(False)
        self.config.set_tunnel_community_enabled(False)
        self.config.set_mainline_dht(False)
        self.config.set_torrent_collecting(False)
        self.config.set_libtorrent(True)
        self.config.set_dht_torrent_collecting(False)
        self.config.set_videoserver_enabled(False)
        self.config.set_torrent_collecting_dir(
            os.path.join(self.session_base_dir, 'torrent_collecting_dir'))

    def create_tdef(self):
        """
        create and save torrent definition used in this test file
        """
        tdef = TorrentDef()
        sourcefn = os.path.join(TESTS_DATA_DIR, 'video.avi')
        tdef.add_content(sourcefn)
        tdef.set_tracker("http://localhost/announce")
        tdef.finalize()

        torrentfn = os.path.join(self.session.get_state_dir(), "gen.torrent")
        tdef.save(torrentfn)

        return tdef

    @deferred(timeout=10)
    def test_can_create_engine_wrapper(self):
        impl = LibtorrentDownloadImpl(self.session, None)
        impl.cew_scheduled = False
        self.session.lm.ltmgr.is_dht_ready = lambda: True
        return impl.can_create_engine_wrapper()

    @deferred(timeout=15)
    def test_can_create_engine_wrapper_retry(self):
        impl = LibtorrentDownloadImpl(self.session, None)
        impl.cew_scheduled = True

        def set_cew_false():
            self.session.lm.ltmgr.is_dht_ready = lambda: True
            impl.cew_scheduled = False

        # Simulate Tribler changing the cew, the calllater should have fired by now
        # and before it executed the cew is false, firing the deferred.
        reactor.callLater(2, set_cew_false)
        return impl.can_create_engine_wrapper()

    def test_get_magnet_link_none(self):
        tdef = self.create_tdef()

        impl = LibtorrentDownloadImpl(self.session, tdef)
        link = impl.get_magnet_link()
        self.assertEqual(None, link,
                         "Magnet link was not none while it should be!")

    def test_get_tdef(self):
        tdef = self.create_tdef()

        impl = LibtorrentDownloadImpl(self.session, None)
        impl.set_def(tdef)
        self.assertEqual(impl.tdef, tdef,
                         "Torrent definitions were not equal!")

    @deferred(timeout=20)
    def test_setup(self):
        tdef = self.create_tdef()

        impl = LibtorrentDownloadImpl(self.session, tdef)

        def callback(_):
            impl.cancel_all_pending_tasks()

        deferred = impl.setup(None, None, 0)
        deferred.addCallback(callback)
        return deferred.addCallback(lambda _: impl.stop())

    def test_restart(self):
        tdef = self.create_tdef()

        impl = LibtorrentDownloadImpl(self.session, tdef)
        impl.handle = MockObject()
        impl.handle.set_priority = lambda _: None
        impl.handle.set_sequential_download = lambda _: None
        impl.handle.resume = lambda: None
        impl.handle.status = lambda: fake_status
        fake_status = MockObject()
        fake_status.share_mode = False
        # Create a dummy download config
        impl.dlconfig = DownloadStartupConfig().dlconfig.copy()
        impl.session.lm.on_download_wrapper_created = lambda _: True
        impl.restart()

    @deferred(timeout=20)
    def test_restart_no_handle(self):
        test_deferred = Deferred()
        tdef = self.create_tdef()
        impl = LibtorrentDownloadImpl(self.session, tdef)
        impl.session.lm.on_download_handle_created = lambda _: test_deferred.callback(
            None)
        impl.restart()
        return test_deferred

    @deferred(timeout=20)
    def test_multifile_torrent(self):
        tdef = TorrentDef()

        dn = os.path.join(TESTS_DATA_DIR, "contentdir")
        tdef.add_content(dn, "dirintorrent")

        fn = os.path.join(TESTS_DATA_DIR, "video.avi")
        tdef.add_content(fn, os.path.join("dirintorrent", "video.avi"))

        tdef.set_tracker("http://tribler.org/announce")
        tdef.finalize()

        impl = LibtorrentDownloadImpl(self.session, tdef)
        # Override the add_torrent because it will be called
        impl.ltmgr = MockObject()
        impl.ltmgr.add_torrent = lambda _, _dummy2: fake_handler
        impl.set_selected_files = lambda: None
        fake_handler = MockObject()
        fake_handler.is_valid = lambda: True
        fake_handler.status = lambda: fake_status
        fake_handler.set_share_mode = lambda _: None
        fake_handler.resume = lambda: None
        fake_handler.resolve_countries = lambda _: None
        fake_status = MockObject()
        fake_status.share_mode = False
        # Create a dummy download config
        impl.dlconfig = DownloadStartupConfig().dlconfig.copy()
        # Create a dummy pstate
        pstate = CallbackConfigParser()
        pstate.add_section("state")
        test_dict = dict()
        test_dict["a"] = "b"
        pstate.set("state", "engineresumedata", test_dict)
        return impl.network_create_engine_wrapper(pstate)

    @deferred(timeout=10)
    def test_save_resume(self):
        """
        testing call resume data alert
        """
        tdef = self.create_tdef()

        impl = LibtorrentDownloadImpl(self.session, tdef)

        def resume_ready(_):
            """
            check if resume data is ready
            """
            basename = binascii.hexlify(tdef.get_infohash()) + '.state'
            filename = os.path.join(self.session.get_downloads_pstate_dir(),
                                    basename)

            engine_data = CallbackConfigParser()
            engine_data.read_file(filename)

            self.assertEqual(
                tdef.get_infohash(),
                engine_data.get('state', 'engineresumedata').get('info-hash'))

        def callback(_):
            """
            callback after finishing setup in LibtorrentDownloadImpl
            """
            defer_alert = impl.save_resume_data()
            defer_alert.addCallback(resume_ready)
            return defer_alert

        result_deferred = impl.setup(None, None, 0)
        result_deferred.addCallback(callback)

        return result_deferred.addCallback(lambda _: impl.stop())
예제 #9
0
class TestAsServer(AbstractServer):

    """
    Parent class for testing the server-side of Tribler
    """

    def setUp(self):
        super(TestAsServer, self).setUp(annotate=False)
        self.setUpPreSession()

        self.quitting = False

        self.session = Session(self.config)
        upgrader = self.session.prestart()
        while not upgrader.is_done:
            time.sleep(0.1)
        assert not upgrader.failed, upgrader.current_status
        self.session.start()

        self.hisport = self.session.get_listen_port()

        while not self.session.lm.initComplete:
            time.sleep(1)

        self.annotate(self._testMethodName, start=True)

    def setUpPreSession(self):
        """ Should set self.config_path and self.config """
        self.config = SessionStartupConfig()
        self.config.set_state_dir(self.getStateDir())
        self.config.set_torrent_checking(False)
        self.config.set_multicast_local_peer_discovery(False)
        self.config.set_megacache(False)
        self.config.set_dispersy(False)
        self.config.set_mainline_dht(False)
        self.config.set_torrent_store(False)
        self.config.set_enable_torrent_search(False)
        self.config.set_enable_channel_search(False)
        self.config.set_torrent_collecting(False)
        self.config.set_libtorrent(False)
        self.config.set_dht_torrent_collecting(False)
        self.config.set_videoplayer(False)
        self.config.set_enable_metadata(False)
        self.config.set_upgrader_enabled(False)

    def tearDown(self):
        self.annotate(self._testMethodName, start=False)

        """ unittest test tear down code """
        if self.session is not None:
            self._shutdown_session(self.session)
            Session.del_instance()

        time.sleep(10)
        gc.collect()

        ts = enumerate_threads()
        self._logger.debug("test_as_server: Number of threads still running %d", len(ts))
        for t in ts:
            self._logger.debug("Thread still running %s, daemon: %s, instance: %s", t.getName(), t.isDaemon(), t)

        super(TestAsServer, self).tearDown(annotate=False)

    def _shutdown_session(self, session):
        session_shutdown_start = time.time()
        waittime = 60

        session.shutdown()
        while not session.has_shutdown():
            diff = time.time() - session_shutdown_start
            assert diff < waittime, "test_as_server: took too long for Session to shutdown"

            self._logger.debug(
                "Waiting for Session to shutdown, will wait for an additional %d seconds", (waittime - diff))

            wx.SafeYield()
            time.sleep(1)

        self._logger.debug("Session has shut down")

    def assert_(self, boolean, reason=None, do_assert=True, tribler_session=None, dump_statistics=False):
        if not boolean:
            # print statistics if needed
            if tribler_session and dump_statistics:
                self._print_statistics(tribler_session.get_statistics())

            self.quit()
            assert boolean, reason

    @blocking_call_on_reactor_thread
    def _print_statistics(self, statistics_dict):
        def _print_data_dict(data_dict, level):
            for k, v in data_dict.iteritems():
                indents = u'-' + u'-' * 2 * level

                if isinstance(v, basestring):
                    self._logger.debug(u"%s %s: %s", indents, k, v)
                elif isinstance(v, dict):
                    self._logger.debug(u"%s %s:", indents, k)
                    _print_data_dict(v, level + 1)
                else:
                    # ignore other types for the moment
                    continue
        self._logger.debug(u"========== Tribler Statistics BEGIN ==========")
        _print_data_dict(statistics_dict, 0)
        self._logger.debug(u"========== Tribler Statistics END ==========")

    def startTest(self, callback):
        self.quitting = False
        callback()

    def callLater(self, seconds, callback):
        if not self.quitting:
            if seconds:
                time.sleep(seconds)
            callback()

    def CallConditional(self, timeout, condition, callback, assert_message=None, assert_callback=None,
                        tribler_session=None, dump_statistics=False):
        t = time.time()

        def DoCheck():
            if not self.quitting:
                # only use the last two parts as the ID because the full name is too long
                test_id = self.id()
                test_id = '.'.join(test_id.split('.')[-2:])

                if time.time() - t < timeout:
                    try:
                        if condition():
                            self._logger.debug("%s - condition satisfied after %d seconds, calling callback '%s'",
                                               test_id, time.time() - t, callback.__name__)
                            callback()
                        else:
                            self.callLater(0.5, DoCheck)

                    except:
                        print_exc()
                        self.assert_(False, '%s - Condition or callback raised an exception, quitting (%s)' %
                                     (test_id, assert_message or "no-assert-msg"), do_assert=False)
                else:
                    self._logger.debug("%s - %s, condition was not satisfied in %d seconds (%s)",
                                       test_id,
                                       ('calling callback' if assert_callback else 'quitting'),
                                       timeout,
                                       assert_message or "no-assert-msg")
                    assertcall = assert_callback if assert_callback else self.assert_
                    kwargs = {}
                    if assertcall == self.assert_:
                        kwargs = {'tribler_session': tribler_session, 'dump_statistics': dump_statistics}

                    assertcall(False, "%s - %s - Condition was not satisfied in %d seconds" %
                               (test_id, assert_message, timeout), do_assert=False, **kwargs)
        self.callLater(0, DoCheck)

    def quit(self):
        self.quitting = True
예제 #10
0
class TriblerSession(BaseManager):
    _sconfig = None
    _dispersy = None

    _running = False

    def _connect(self):
        """
        Copies the libswift and ffmpeg binaries when on Android.
        :return:
        """

        if not self._connected:
            self._connected = True

            # Copy the swift and ffmpeg binaries
            if is_android(strict=True):
                binaries = ["swift", "ffmpeg"]

                for binary in binaries:
                    _logger.info("Setting up the %s binary.." % binary)

                    if not self._copy_binary(binary):
                        _logger.error("Unable to find or copy the %s binary!" % binary)
        else:
            raise RuntimeError("TriblerSession already connected")

    def _xmlrpc_register(self, xmlrpc):
        """
        Register the public functions in this manager with an XML-RPC Manager.
        :param xmlrpc: The XML-RPC Manager it should register to.
        :return: Nothing.
        """
        xmlrpc.register_function(self.start_session, "tribler.start_session")
        xmlrpc.register_function(self.stop_session, "tribler.stop_session")

    def _copy_binary(self, binary_name):
        """
        Copy a binary, such as swift, from the sdcard (which is mounted with noexec) to the ANDROID_PRIVATE folder which
        does allow it. If the binary already exists, do nothing.
        :param binary_name: The name of the binary that should be copied.
        :return: Boolean indicating success.
        """
        # We are on android, setup the swift binary!
        sdcard_path = os.getcwd()
        binary_source = os.path.join(sdcard_path, binary_name)
        binary_dest = os.path.join(os.environ["ANDROID_PRIVATE"], binary_name)

        if not os.path.exists(binary_dest):
            if not os.path.exists(binary_source):
                _logger.error(
                    "Looked at %s and %s, but couldn't find a '%s' binary!" % (binary_source, binary_dest, binary_name)
                )
                return False

            _logger.warn("Copy '%s' binary (%s -> %s)" % (binary_name, binary_source, binary_dest))
            shutil.copy2(binary_source, binary_dest)
            # TODO: Set a more conservative permission
            os.chmod(binary_dest, 0777)

        return True

    def get_session(self):
        """
        Get the current Tribler session.
        :return: Tribler session, or None if no session is started yet.
        """
        return self._session

    def start_session(self):
        """
        This function loads any previous configuration files from the TRIBLER_STATE_DIR environment variable and then
        starts a Tribler session.
        :return: Nothing.
        """
        if self._running:
            return False

        _logger.info("Set tribler_state_dir to %s" % os.environ["TRIBLER_STATE_DIR"])

        # Load configuration file (if exists)
        cfgfilename = Session.get_default_config_filename(os.environ["TRIBLER_STATE_DIR"])
        try:
            self._sconfig = SessionStartupConfig.load(cfgfilename)
            _logger.info("Loaded previous configuration file from %s" % cfgfilename)
        except:
            self._sconfig = SessionStartupConfig()
            self._sconfig.set_state_dir(os.environ["TRIBLER_STATE_DIR"])
            _logger.info("No previous configuration file found, creating one in %s" % os.environ["TRIBLER_STATE_DIR"])

        # Set torrent collecting directory:
        dlcfgfilename = get_default_dscfg_filename(self._sconfig.get_state_dir())
        _logger.debug("main: Download config %s", dlcfgfilename)
        try:
            defaultDLConfig = DefaultDownloadStartupConfig.load(dlcfgfilename)
        except:
            defaultDLConfig = DefaultDownloadStartupConfig.getInstance()
        if not defaultDLConfig.get_dest_dir():
            defaultDLConfig.set_dest_dir(os.environ["TRIBLER_DOWNLOAD_DIR"])
            self._sconfig.set_torrent_collecting_dir(os.path.join(os.environ["TRIBLER_DOWNLOAD_DIR"]))

        # Create download directory:
        if not os.path.isdir(defaultDLConfig.get_dest_dir()):
            try:
                _logger.info("Creating download directory: %s" % defaultDLConfig.get_dest_dir())
                os.makedirs(defaultDLConfig.get_dest_dir())
            except:
                _logger.error("Couldn't create download directory! (%s)" % defaultDLConfig.get_dest_dir())

        # TODO: This is temporary for testing:
        from jnius import autoclass

        python_activity = autoclass("org.renpy.android.PythonActivity")
        files_dir = python_activity.mActivity.getFilesDir().getAbsolutePath()
        install_dir = files_dir + u"/lib/python2.7/site-packages"
        _logger.info("Set tribler_install_dir to %s" % install_dir)
        self._sconfig.set_install_dir(install_dir)
        # TODO: ^End of temporary test.

        # Disable unwanted dependencies:
        self._sconfig.set_torrent_store(True)
        self._sconfig.set_torrent_checking(True)
        self._sconfig.set_multicast_local_peer_discovery(False)
        self._sconfig.set_mainline_dht(True)
        self._sconfig.set_dht_torrent_collecting(True)
        self._sconfig.set_torrent_collecting_max_torrents(5000)

        _logger.info("Starting Tribler session..")
        self._session = Session(self._sconfig)
        upgrader = self._session.prestart()
        while not upgrader.is_done:
            time.sleep(0.1)
        self._session.start()
        _logger.info("Tribler session started!")

        self._dispersy = self._session.get_dispersy_instance()
        self.define_communities()

    # Dispersy init communitites callback function
    @call_on_reactor_thread
    def define_communities(self):
        """
        Load the dispersy communities. This function must be run on the Twisted reactor thread.
        :return: Nothing.
        """
        integrate_with_tribler = True
        comm_args = {"integrate_with_tribler": integrate_with_tribler}

        from Tribler.community.search.community import SearchCommunity
        from Tribler.community.allchannel.community import AllChannelCommunity
        from Tribler.community.channel.community import ChannelCommunity
        from Tribler.community.channel.preview import PreviewChannelCommunity
        from Tribler.community.metadata.community import MetadataCommunity

        _logger.info("Preparing to load dispersy communities...")

        comm = self._dispersy.define_auto_load(
            SearchCommunity, self._session.dispersy_member, load=True, kargs=comm_args
        )
        _logger.debug("Currently loaded dispersy communities: %s" % comm)
        # comm = self._dispersy.define_auto_load(AllChannelCommunity, self._session.dispersy_member, load=True,
        #                                       kargs=comm_args)
        # _logger.debug("Currently loaded dispersy communities: %s" % comm)

        # load metadata community
        # comm = self._dispersy.define_auto_load(MetadataCommunity, self._session.dispersy_member, load=True,
        #                                      kargs=comm_args) # TODO: used to be kargs=comm_args, but MetadataCommunity uses _integrate_with_tribler (notice lower dash) and even that won't work
        _logger.info("@@@@@@@@@@ Loaded dispersy communities: %s" % comm)

        # 17/07/13 Boudewijn: the missing-member message send by the BarterCommunity on the swift port is crashing
        # 6.1 clients.  We will disable the BarterCommunity for version 6.2, giving people some time to upgrade
        # their version before enabling it again.
        # if swift_process:
        #     dispersy.define_auto_load(BarterCommunity,
        #                               s.dispersy_member,
        #                               (swift_process,),
        #                               load=True)

        # comm = self._dispersy.define_auto_load(ChannelCommunity, self._session.dispersy_member, load=True,
        #                                       kargs=comm_args)
        # _logger.debug("Currently loaded dispersy communities: %s" % comm)
        # comm = self._dispersy.define_auto_load(PreviewChannelCommunity, self._session.dispersy_member, kargs=comm_args)
        # _logger.debug("Currently loaded dispersy communities: %s" % comm)

        self._running = True

    def is_running(self):
        return self._running

    def stop_session(self):
        """
        Unloads the Tribler session.
        :return: Nothing.
        """
        _logger.info("Create checkpoint..")
        self._session.checkpoint()

        _logger.info("Shutting down Tribler..")
        self._session.shutdown()

        # Just a tad of extra time
        time.sleep(1)

        self._running = False
        _logger.info("Bye bye")

        return True
예제 #11
0
class TestAsServer(AbstractServer):
    """
    Parent class for testing the server-side of Tribler
    """
    @blocking_call_on_reactor_thread
    @inlineCallbacks
    def setUp(self, autoload_discovery=True):
        yield super(TestAsServer, self).setUp(annotate=False)
        self.setUpPreSession()

        self.quitting = False
        self.seeding_deferred = Deferred()
        self.seeder_session = None

        self.session = Session(self.config)

        self.tribler_started_deferred = self.session.start()
        yield self.tribler_started_deferred

        self.assertTrue(self.session.lm.initComplete)

        self.hisport = self.session.get_listen_port()

        self.annotate(self._testMethodName, start=True)

    def setUpPreSession(self):
        """ Should set self.config_path and self.config """
        self.config = SessionStartupConfig()
        self.config.set_state_dir(self.getStateDir())
        self.config.set_torrent_checking(False)
        self.config.set_multicast_local_peer_discovery(False)
        self.config.set_megacache(False)
        self.config.set_dispersy(False)
        self.config.set_mainline_dht(False)
        self.config.set_torrent_store(False)
        self.config.set_enable_torrent_search(False)
        self.config.set_enable_channel_search(False)
        self.config.set_torrent_collecting(False)
        self.config.set_libtorrent(False)
        self.config.set_dht_torrent_collecting(False)
        self.config.set_videoserver_enabled(False)
        self.config.set_enable_metadata(False)
        self.config.set_upgrader_enabled(False)
        self.config.set_http_api_enabled(False)
        self.config.set_tunnel_community_enabled(False)
        self.config.set_creditmining_enable(False)
        self.config.set_enable_multichain(False)

    @blocking_call_on_reactor_thread
    @inlineCallbacks
    def tearDown(self, annotate=True):
        self.annotate(self._testMethodName, start=False)
        """ unittest test tear down code """
        if self.session is not None:
            assert self.session is Session.get_instance()
            yield self.session.shutdown()
            assert self.session.has_shutdown()
            Session.del_instance()

        yield self.stop_seeder()

        ts = enumerate_threads()
        self._logger.debug(
            "test_as_server: Number of threads still running %d", len(ts))
        for t in ts:
            self._logger.debug(
                "Thread still running %s, daemon: %s, instance: %s",
                t.getName(), t.isDaemon(), t)

        yield super(TestAsServer, self).tearDown(annotate=False)

    def create_local_torrent(self, source_file):
        '''
        This method creates a torrent from a local file and saves the torrent in the session state dir.
        Note that the source file needs to exist.
        '''
        self.assertTrue(os.path.exists(source_file))

        tdef = TorrentDef()
        tdef.add_content(source_file)
        tdef.set_tracker("http://localhost/announce")
        tdef.finalize()

        torrent_path = os.path.join(self.session.get_state_dir(),
                                    "seed.torrent")
        tdef.save(torrent_path)

        return tdef, torrent_path

    def setup_seeder(self, tdef, seed_dir):
        self.seed_config = SessionStartupConfig()
        self.seed_config.set_torrent_checking(False)
        self.seed_config.set_multicast_local_peer_discovery(False)
        self.seed_config.set_megacache(False)
        self.seed_config.set_dispersy(False)
        self.seed_config.set_mainline_dht(False)
        self.seed_config.set_torrent_store(False)
        self.seed_config.set_enable_torrent_search(False)
        self.seed_config.set_enable_channel_search(False)
        self.seed_config.set_torrent_collecting(False)
        self.seed_config.set_libtorrent(True)
        self.seed_config.set_dht_torrent_collecting(False)
        self.seed_config.set_videoserver_enabled(False)
        self.seed_config.set_enable_metadata(False)
        self.seed_config.set_upgrader_enabled(False)
        self.seed_config.set_tunnel_community_enabled(False)
        self.seed_config.set_state_dir(self.getStateDir(2))

        def start_seed_download(_):
            self.dscfg_seed = DownloadStartupConfig()
            self.dscfg_seed.set_dest_dir(seed_dir)
            d = self.seeder_session.start_download_from_tdef(
                tdef, self.dscfg_seed)
            d.set_state_callback(self.seeder_state_callback)

        self._logger.debug(
            "starting to wait for download to reach seeding state")

        self.seeder_session = Session(self.seed_config, ignore_singleton=True)
        self.seeder_session.start().addCallback(start_seed_download)

        return self.seeding_deferred

    def stop_seeder(self):
        if self.seeder_session is not None:
            return self.seeder_session.shutdown()
        return succeed(None)

    def seeder_state_callback(self, ds):
        d = ds.get_download()
        self._logger.debug("seeder status: %s %s %s",
                           repr(d.get_def().get_name()),
                           dlstatus_strings[ds.get_status()],
                           ds.get_progress())

        if ds.get_status() == DLSTATUS_SEEDING:
            self.seeding_deferred.callback(None)
            return 0.0, False

        return 1.0, False
예제 #12
0
class TestSqliteCacheDB(AbstractServer):

    def setUp(self):
        super(TestSqliteCacheDB, self).setUp()
        self.config = SessionStartupConfig()
        self.config.set_state_dir(self.getStateDir())
        self.config.set_torrent_checking(False)
        self.config.set_multicast_local_peer_discovery(False)
        self.config.set_megacache(False)
        self.config.set_dispersy(False)
        self.config.set_mainline_dht(False)
        self.config.set_torrent_collecting(False)
        self.config.set_libtorrent(False)
        self.config.set_dht_torrent_collecting(False)
        self.config.set_videoplayer(False)
        self.session = Session(self.config, ignore_singleton=True)

        self.sqlite_test = SQLiteCacheDB(self.session)
        self.db_path = u":memory:"
        self.sqlite_test.initialize(self.db_path)

    def tearDown(self):
        super(TestSqliteCacheDB, self).tearDown()
        self.sqlite_test.close()
        self.sqlite_test = None
        self.session.del_instance()
        self.session = None

    @blocking_call_on_reactor_thread
    def test_create_db(self):
        sql = u"CREATE TABLE person(lastname, firstname);"
        self.sqlite_test.execute(sql)

    @blocking_call_on_reactor_thread
    def test_insert(self):
        self.test_create_db()

        self.sqlite_test.insert('person', lastname='a', firstname='b')
        assert self.sqlite_test.size('person') == 1

    @blocking_call_on_reactor_thread
    def test_fetchone(self):
        self.test_insert()
        one = self.sqlite_test.fetchone(u"SELECT * FROM person")
        assert one == ('a', 'b')

        one = self.sqlite_test.fetchone(u"SELECT lastname FROM person WHERE firstname == 'b'")
        assert one == 'a'

        one = self.sqlite_test.fetchone(u"SELECT lastname FROM person WHERE firstname == 'c'")
        assert one is None

    @blocking_call_on_reactor_thread
    def test_insertmany(self):
        self.test_create_db()

        values = []
        for i in range(100):
            value = (str(i), str(i ** 2))
            values.append(value)
        self.sqlite_test.insertMany('person', values)
        assert self.sqlite_test.size('person') == 100

    @blocking_call_on_reactor_thread
    def test_fetchall(self):
        self.test_insertmany()

        all = self.sqlite_test.fetchall('select * from person')
        assert len(all) == 100

        all = self.sqlite_test.fetchall("select * from person where lastname=='101'")
        assert all == []

    @blocking_call_on_reactor_thread
    def test_insertorder(self):
        self.test_insertmany()

        self.sqlite_test.insert('person', lastname='1', firstname='abc')
        one = self.sqlite_test.fetchone("select firstname from person where lastname == '1'")
        assert one == '1' or one == 'abc'

        all = self.sqlite_test.fetchall("select firstname from person where lastname == '1'")
        assert len(all) == 2

    @blocking_call_on_reactor_thread
    def test_update(self):
        self.test_insertmany()

        self.sqlite_test.update('person', "lastname == '2'", firstname='56')
        one = self.sqlite_test.fetchone("select firstname from person where lastname == '2'")
        assert one == '56', one

        self.sqlite_test.update('person', "lastname == '3'", firstname=65)
        one = self.sqlite_test.fetchone("select firstname from person where lastname == '3'")
        assert one == 65, one

        self.sqlite_test.update('person', "lastname == '4'", firstname=654, lastname=44)
        one = self.sqlite_test.fetchone("select firstname from person where lastname == 44")
        assert one == 654, one
예제 #13
0
class TestSqliteCacheDB(AbstractServer):
    def setUp(self):
        super(TestSqliteCacheDB, self).setUp()
        self.config = SessionStartupConfig()
        self.config.set_state_dir(self.getStateDir())
        self.config.set_torrent_checking(False)
        self.config.set_multicast_local_peer_discovery(False)
        self.config.set_megacache(False)
        self.config.set_dispersy(False)
        self.config.set_mainline_dht(False)
        self.config.set_torrent_collecting(False)
        self.config.set_libtorrent(False)
        self.config.set_dht_torrent_collecting(False)
        self.config.set_videoplayer(False)
        self.session = Session(self.config, ignore_singleton=True)

        self.sqlite_test = SQLiteCacheDB(self.session)
        self.db_path = u":memory:"
        self.sqlite_test.initialize(self.db_path)

    def tearDown(self):
        super(TestSqliteCacheDB, self).tearDown()
        self.sqlite_test.close()
        self.sqlite_test = None
        self.session.del_instance()
        self.session = None

    @blocking_call_on_reactor_thread
    def test_create_db(self):
        sql = u"CREATE TABLE person(lastname, firstname);"
        self.sqlite_test.execute(sql)

    @blocking_call_on_reactor_thread
    def test_insert(self):
        self.test_create_db()

        self.sqlite_test.insert('person', lastname='a', firstname='b')
        assert self.sqlite_test.size('person') == 1

    @blocking_call_on_reactor_thread
    def test_fetchone(self):
        self.test_insert()
        one = self.sqlite_test.fetchone(u"SELECT * FROM person")
        assert one == ('a', 'b')

        one = self.sqlite_test.fetchone(
            u"SELECT lastname FROM person WHERE firstname == 'b'")
        assert one == 'a'

        one = self.sqlite_test.fetchone(
            u"SELECT lastname FROM person WHERE firstname == 'c'")
        assert one is None

    @blocking_call_on_reactor_thread
    def test_insertmany(self):
        self.test_create_db()

        values = []
        for i in range(100):
            value = (str(i), str(i**2))
            values.append(value)
        self.sqlite_test.insertMany('person', values)
        assert self.sqlite_test.size('person') == 100

    @blocking_call_on_reactor_thread
    def test_fetchall(self):
        self.test_insertmany()

        all = self.sqlite_test.fetchall('select * from person')
        assert len(all) == 100

        all = self.sqlite_test.fetchall(
            "select * from person where lastname=='101'")
        assert all == []

    @blocking_call_on_reactor_thread
    def test_insertorder(self):
        self.test_insertmany()

        self.sqlite_test.insert('person', lastname='1', firstname='abc')
        one = self.sqlite_test.fetchone(
            "select firstname from person where lastname == '1'")
        assert one == '1' or one == 'abc'

        all = self.sqlite_test.fetchall(
            "select firstname from person where lastname == '1'")
        assert len(all) == 2

    @blocking_call_on_reactor_thread
    def test_update(self):
        self.test_insertmany()

        self.sqlite_test.update('person', "lastname == '2'", firstname='56')
        one = self.sqlite_test.fetchone(
            "select firstname from person where lastname == '2'")
        assert one == '56', one

        self.sqlite_test.update('person', "lastname == '3'", firstname=65)
        one = self.sqlite_test.fetchone(
            "select firstname from person where lastname == '3'")
        assert one == 65, one

        self.sqlite_test.update('person',
                                "lastname == '4'",
                                firstname=654,
                                lastname=44)
        one = self.sqlite_test.fetchone(
            "select firstname from person where lastname == 44")
        assert one == 654, one